diff --git a/dist/demo-browser-index.js b/dist/demo-browser-index.js index 5cae9a39..bb4a6112 100644 --- a/dist/demo-browser-index.js +++ b/dist/demo-browser-index.js @@ -4771,7 +4771,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`,nv={};Sr(nv,{author:()=>uv,browser:()=>lv,bugs:()=>cv,default:()=>qae,dependencies:()=>mv,description:()=>av,devDependencies:()=>yv,engines:()=>pv,homepage:()=>hv,keywords:()=>xv,license:()=>dv,main:()=>iv,module:()=>ov,name:()=>rv,peerDependencies:()=>Av,repository:()=>fv,scripts:()=>gv,sideEffects:()=>sv,version:()=>T2});var rv="@vladmandic/human",T2="0.20.2",av="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",sv=!1,iv="dist/human.node.js",ov="dist/human.esm.js",lv="dist/human.esm.js",uv="Vladimir Mandic ",cv={url:"https://github.com/vladmandic/human/issues"},hv="https://github.com/vladmandic/human#readme",dv="MIT",pv={node:">=12.0.0"},fv={type:"git",url:"git+https://github.com/vladmandic/human.git"},mv={},Av={},yv={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},gv={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},xv=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],qae={name:rv,version:T2,description:av,sideEffects:sv,main:iv,module:ov,browser:lv,author:uv,bugs:cv,homepage:hv,license:dv,engines:pv,repository:fv,dependencies:mv,peerDependencies:Av,devDependencies:yv,scripts:gv,keywords:xv},ft=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function zl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=zl(s,i):n[a]=i}),n),{})}var wv=class{constructor(e={}){this.tf=L2,this.package=nv,this.version=T2,this.config=zl(Gae,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=N6,this.age=C6,this.gender=R6,this.emotion=F6,this.body=O6,this.hand=q6}profile(){return this.config.profile?E6:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let t=pn().state.numTensors,n=this.numTensors;this.numTensors=t;let r=t-n;r!==0&&Ue(...e,r)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(kn.flags.IS_NODE&&!(e instanceof Qe))return"input must be a tensor";try{Jh()}catch(t){return"backend not loaded"}return null}simmilarity(e,t){return this.config.face.embedding.enabled?nae(e,t):0}async load(e=null){this.state="load";let t=ft();e&&(this.config=zl(this.config,e)),this.firstRun&&(Ue(`version: ${this.version} TensorFlow/JS version: ${X2}`),await this.checkBackend(!0),kn.flags.IS_BROWSER&&(Ue("configuration:",this.config),Ue("tf flags:",kn.flags)));let n=this.config.face.detector.modelPath.includes("faceboxes")?S6:N6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?n.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?s2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?o2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?d2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?$6(this.config):null),this.models.posenet||(this.config.body.enabled?A2(this.config):null),this.models.handpose||(this.config.hand.enabled?_2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await n.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await s2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await o2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await d2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await $6(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await A2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await _2(this.config))),this.firstRun&&(Ue("tf engine state:",pn().state.numBytes,"bytes",pn().state.numTensors,"tensors"),this.firstRun=!1);let r=Math.trunc(ft()-t);r>(this.perf.load||0)&&(this.perf.load=r)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||Jh()!==this.config.backend){let t=ft();this.state="backend",Ue("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Ue("settings wasm path:",this.config.wasmPath),F0(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Ue("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&Rre();try{await Z2(this.config.backend)}catch(n){Ue("error: cannot set backend:",this.config.backend,n)}if(K2(),Jh()==="webgl"){this.config.deallocate&&(Ue("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),kn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),kn.set("WEBGL_FORCE_F16_TEXTURES",!0),kn.set("WEBGL_PACK_DEPTHWISECONV",!0);let n=await Of().getGPGPUContext().gl;Ue(`gl version:${n.getParameter(n.VERSION)} renderer:${n.getParameter(n.RENDERER)}`)}await J2(),this.perf.backend=Math.trunc(ft()-t)}}async detectFace(e){var t,n,r,a,s,i;let o,l,c,u,h,d=[];this.state="run:face",o=ft();let p=await((t=this.models.face)==null?void 0:t.estimateFaces(e,this.config));this.perf.face=Math.trunc(ft()-o);for(let f of p){if(this.analyze("Get Face"),!f.image||f.image.isDisposedInternal){Ue("Face object is disposed:",f.image);continue}this.analyze("Start Age:"),this.config.async?l=this.config.face.age.enabled?i2(f.image,this.config):{}:(this.state="run:age",o=ft(),l=this.config.face.age.enabled?await i2(f.image,this.config):{},this.perf.age=Math.trunc(ft()-o)),this.analyze("Start Gender:"),this.config.async?c=this.config.face.gender.enabled?l2(f.image,this.config):{}:(this.state="run:gender",o=ft(),c=this.config.face.gender.enabled?await l2(f.image,this.config):{},this.perf.gender=Math.trunc(ft()-o)),this.analyze("Start Emotion:"),this.config.async?u=this.config.face.emotion.enabled?p2(f.image,this.config):{}:(this.state="run:emotion",o=ft(),u=this.config.face.emotion.enabled?await p2(f.image,this.config):{},this.perf.emotion=Math.trunc(ft()-o)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?h=this.config.face.embedding.enabled?D6(f.image,this.config):{}:(this.state="run:embedding",o=ft(),h=this.config.face.embedding.enabled?await D6(f.image,this.config):{},this.perf.embedding=Math.trunc(ft()-o)),this.analyze("End Emotion:"),this.config.async&&([l,c,u,h]=await Promise.all([l,c,u,h])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((n=f==null?void 0:f.annotations)==null?void 0:n.leftEyeIris)&&((r=f==null?void 0:f.annotations)==null?void 0:r.rightEyeIris)&&(delete f.annotations.leftEyeIris,delete f.annotations.rightEyeIris);let m=((a=f.annotations)==null?void 0:a.leftEyeIris)&&((s=f.annotations)==null?void 0:s.rightEyeIris)?11.7*Math.max(Math.abs(f.annotations.leftEyeIris[3][0]-f.annotations.leftEyeIris[1][0]),Math.abs(f.annotations.rightEyeIris[4][1]-f.annotations.rightEyeIris[2][1])):0;d.push({confidence:f.confidence,box:f.box,mesh:f.mesh,boxRaw:f.boxRaw,meshRaw:f.meshRaw,annotations:f.annotations,age:l.age,gender:c.gender,genderConfidence:c.confidence,emotion:u,embedding:h,iris:m!==0?Math.trunc(m)/100:0}),(i=f.image)==null||i.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),d}async image(e,t={}){var n;this.state="image",this.config=zl(this.config,t);let r=tv(e,this.config);return(n=r==null?void 0:r.tensor)==null||n.dispose(),r==null?void 0:r.canvas}async detect(e,t={}){return new Promise(async n=>{var r,a,s,i;this.state="config";let o;this.config=zl(this.config,t),this.state="check";let l=this.sanity(e);l&&(Ue(l,e),n({error:l}));let c,u,h,d=ft();await this.checkBackend(),await this.load(),this.config.scoped&&pn().startScope(),this.analyze("Start Scope:"),o=ft();let p=tv(e,this.config);if(!p||!p.tensor){Ue("could not convert input to tensor"),n({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(ft()-o),this.analyze("Get Image:"),this.config.async?(h=this.config.face.enabled?this.detectFace(p.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",o=ft(),h=this.config.face.enabled?await this.detectFace(p.tensor):[],this.perf.face=Math.trunc(ft()-o)),this.analyze("Start Body:"),this.config.async?(c=this.config.body.enabled?(r=this.models.posenet)==null?void 0:r.estimatePoses(p.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",o=ft(),c=this.config.body.enabled?await((a=this.models.posenet)==null?void 0:a.estimatePoses(p.tensor,this.config)):[],this.perf.body=Math.trunc(ft()-o)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(s=this.models.handpose)==null?void 0:s.estimateHands(p.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",o=ft(),u=this.config.hand.enabled?await((i=this.models.handpose)==null?void 0:i.estimateHands(p.tensor,this.config)):[],this.perf.hand=Math.trunc(ft()-o)),this.analyze("End Hand:"),this.config.async&&([h,c,u]=await Promise.all([h,c,u])),p.tensor.dispose(),this.config.scoped&&pn().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(o=ft(),f=[...Vae(h),...Bae(c),...Hae(u),...Uae(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(ft()-o)),this.perf.total=Math.trunc(ft()-d),this.state="idle",n({face:h,body:c,hand:u,gesture:f,performance:this.perf,canvas:p.canvas})})}async warmupBitmap(){let e=(r,a="application/octet-stream")=>fetch(`data:${a};base64,${r}`).then(s=>s.blob()),t,n;switch(this.config.warmup){case"face":t=await e(N2);break;case"full":t=await e(S2);break;default:t=null}if(t){let r=await createImageBitmap(t);n=await this.detect(r,this.config),r.close()}return n}async warmupCanvas(){return new Promise(e=>{let t,n=0;switch(this.config.warmup){case"face":n=256,t="data:image/jpeg;base64,"+N2;break;case"full":n=1200,t="data:image/jpeg;base64,"+S2;break;default:t=null}let r=new Image(n,n);r.onload=()=>{let a=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(n,n):document.createElement("canvas");a.width=n,a.height=n;let s=a.getContext("2d");s==null||s.drawImage(r,0,0);let i=s==null?void 0:s.getImageData(0,0,n,n);this.detect(i,this.config).then(o=>e(o))},t?r.src=t:e(null)})}async warmupNode(){let e=s=>Buffer.from(s,"base64"),t=this.config.warmup==="face"?e(N2):e(S2),n=(void 0).decodeJpeg(t),r=n.expandDims(0);Ce(n);let a=await this.detect(r,this.config);return Ce(r),a}async warmup(e){let t=ft();e&&(this.config=zl(this.config,e));let n=this.config.videoOptimized;this.config.videoOptimized=!1;let r;typeof createImageBitmap=="function"?r=await this.warmupBitmap():typeof Image!="undefined"?r=await this.warmupCanvas():r=await this.warmupNode(),this.config.videoOptimized=n;let a=ft();return Ue("Warmup",this.config.warmup,Math.round(a-t),"ms",r),r}};async function Xae(e,t,n){if(!e)return;let r=t.getContext("2d");r.font=n.baseFont,r.fillStyle=n.baseLabel;let a=1;for(let s=0;s1&&o[1].length>0){let l=i[1]>0?`#${i[1]}`:"",c=`${i[0]} ${l}: ${o[1]}`;r.fillStyle="black",r.fillText(c,8,2+a*n.baseLineHeight),r.fillStyle=n.baseLabel,r.fillText(c,6,0+a*n.baseLineHeight),a+=1}}}async function Kae(e,t,n,r){if(!e)return;let a=t.getContext("2d");for(let s of e){a.font=n.baseFont,a.strokeStyle=n.baseColor,a.fillStyle=n.baseColor,a.lineWidth=n.baseLineWidth,a.beginPath(),n.drawBoxes&&a.rect(s.box[0],s.box[1],s.box[2],s.box[3]);let i=[];if(s.genderConfidence&&i.push(`${s.gender||""} ${Math.trunc(100*s.genderConfidence)}% confident`),s.age&&i.push(`age: ${s.age||""}`),s.iris&&i.push(`iris distance: ${s.iris}`),s.emotion&&s.emotion.length>0){let o=s.emotion.map(l=>`${Math.trunc(100*l.score)}% ${l.emotion}`);i.push(o.join(" "))}i.length===0&&i.push("face"),a.fillStyle=n.baseLabel;for(let o=0;os.mesh[u]),c=new Path2D;c.moveTo(l[0][0],l[0][1]);for(let u of l)c.lineTo(u[0],u[1]);c.closePath(),a.strokeStyle=n.useDepth?`rgba(${127.5+2*l[0][2]}, ${127.5-2*l[0][2]}, 255, 0.3)`:n.baseColor,a.stroke(c),n.fillPolygons&&(a.fillStyle=n.useDepth?`rgba(${127.5+2*l[0][2]}, ${127.5-2*l[0][2]}, 255, 0.3)`:n.baseColor,a.fill(c))}if(s.annotations&&s.annotations.leftEyeIris){a.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.baseColor,a.beginPath();let o=Math.abs(s.annotations.leftEyeIris[3][0]-s.annotations.leftEyeIris[1][0])/2,l=Math.abs(s.annotations.leftEyeIris[4][1]-s.annotations.leftEyeIris[2][1])/2;a.ellipse(s.annotations.leftEyeIris[0][0],s.annotations.leftEyeIris[0][1],o,l,0,0,2*Math.PI),a.stroke(),n.fillPolygons&&(a.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.baseColor,a.fill())}if(s.annotations&&s.annotations.rightEyeIris){a.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.baseColor,a.beginPath();let o=Math.abs(s.annotations.rightEyeIris[3][0]-s.annotations.rightEyeIris[1][0])/2,l=Math.abs(s.annotations.rightEyeIris[4][1]-s.annotations.rightEyeIris[2][1])/2;a.ellipse(s.annotations.rightEyeIris[0][0],s.annotations.rightEyeIris[0][1],o,l,0,0,2*Math.PI),a.stroke(),n.fillPolygons&&(a.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.baseColor,a.fill())}}}}}var Ba=[];async function Zae(e,t,n){if(!e)return;let r=t.getContext("2d");r.lineJoin="round";for(let a=0;al.part==="leftShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightShoulder"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightHip"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftHip"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftShoulder"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="leftHip"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="leftKnee"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftAnkle"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="rightHip"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightKnee"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightAnkle"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="leftShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="leftElbow"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftWrist"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="rightShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightElbow"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightWrist"),o&&s.lineTo(o.position.x,o.position.y)),r.stroke(s)}}}async function Jae(e,t,n){if(!e)return;let r=t.getContext("2d");r.lineJoin="round";for(let a of e){if(r.font=n.baseFont,r.lineWidth=n.baseLineWidth,n.drawBoxes&&(r.lineWidth=n.baseLineWidth,r.beginPath(),r.strokeStyle=n.baseColor,r.fillStyle=n.baseColor,r.rect(a.box[0],a.box[1],a.box[2],a.box[3]),r.fillStyle="black",r.fillText("hand",a.box[0]+3,1+a.box[1]+n.baseLineHeight,a.box[2]),r.fillStyle=n.baseLabel,r.fillText("hand",a.box[0]+2,0+a.box[1]+n.baseLineHeight,a.box[2]),r.stroke()),n.drawPoints&&a.landmarks&&a.landmarks.length>0)for(let s of a.landmarks)r.fillStyle=n.useDepth?`rgba(${127.5+2*s[2]}, ${127.5-2*s[2]}, 255, 0.5)`:n.baseColor,r.beginPath(),r.arc(s[0],s[1],2,0,2*Math.PI),r.fill();if(n.drawPolygons){let s=i=>{if(!!i)for(let o=0;o0?o-1:0][0],i[o>0?o-1:0][1]),r.lineTo(i[o][0],i[o][1]),r.stroke()};s(a.annotations.indexFinger),s(a.annotations.middleFinger),s(a.annotations.ringFinger),s(a.annotations.pinky),s(a.annotations.thumb)}}}var Bc={face:Kae,body:Zae,hand:Jae,gesture:Xae};var Vc=0,_v=!1,wt={background:"darkslategray",hover:"lightgray",itemBackground:"black",itemColor:"white",buttonBackground:"lightblue",buttonHover:"lightgreen",checkboxOn:"lightgreen",checkboxOff:"lightcoral",rangeBackground:"lightblue",rangeLabel:"white",chartColor:"lightblue"};function Yae(){if(_v)return;let e=` +2Q==`,nv={};Sr(nv,{author:()=>uv,browser:()=>lv,bugs:()=>cv,default:()=>qae,dependencies:()=>mv,description:()=>av,devDependencies:()=>yv,engines:()=>pv,homepage:()=>hv,keywords:()=>xv,license:()=>dv,main:()=>iv,module:()=>ov,name:()=>rv,peerDependencies:()=>Av,repository:()=>fv,scripts:()=>gv,sideEffects:()=>sv,version:()=>T2});var rv="@vladmandic/human",T2="0.20.3",av="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",sv=!1,iv="dist/human.node.js",ov="dist/human.esm.js",lv="dist/human.esm.js",uv="Vladimir Mandic ",cv={url:"https://github.com/vladmandic/human/issues"},hv="https://github.com/vladmandic/human#readme",dv="MIT",pv={node:">=12.0.0"},fv={type:"git",url:"git+https://github.com/vladmandic/human.git"},mv={},Av={},yv={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},gv={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},xv=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],qae={name:rv,version:T2,description:av,sideEffects:sv,main:iv,module:ov,browser:lv,author:uv,bugs:cv,homepage:hv,license:dv,engines:pv,repository:fv,dependencies:mv,peerDependencies:Av,devDependencies:yv,scripts:gv,keywords:xv},ft=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function zl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=zl(s,i):n[a]=i}),n),{})}var wv=class{constructor(e={}){this.tf=L2,this.package=nv,this.version=T2,this.config=zl(Gae,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=N6,this.age=C6,this.gender=R6,this.emotion=F6,this.body=O6,this.hand=q6}profile(){return this.config.profile?E6:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let t=pn().state.numTensors,n=this.numTensors;this.numTensors=t;let r=t-n;r!==0&&Ue(...e,r)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(kn.flags.IS_NODE&&!(e instanceof Qe))return"input must be a tensor";try{Jh()}catch(t){return"backend not loaded"}return null}simmilarity(e,t){return this.config.face.embedding.enabled?nae(e,t):0}async load(e=null){this.state="load";let t=ft();e&&(this.config=zl(this.config,e)),this.firstRun&&(Ue(`version: ${this.version} TensorFlow/JS version: ${X2}`),await this.checkBackend(!0),kn.flags.IS_BROWSER&&(Ue("configuration:",this.config),Ue("tf flags:",kn.flags)));let n=this.config.face.detector.modelPath.includes("faceboxes")?S6:N6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?n.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?s2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?o2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?d2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?$6(this.config):null),this.models.posenet||(this.config.body.enabled?A2(this.config):null),this.models.handpose||(this.config.hand.enabled?_2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await n.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await s2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await o2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await d2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await $6(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await A2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await _2(this.config))),this.firstRun&&(Ue("tf engine state:",pn().state.numBytes,"bytes",pn().state.numTensors,"tensors"),this.firstRun=!1);let r=Math.trunc(ft()-t);r>(this.perf.load||0)&&(this.perf.load=r)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||Jh()!==this.config.backend){let t=ft();this.state="backend",Ue("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Ue("settings wasm path:",this.config.wasmPath),F0(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Ue("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&Rre();try{await Z2(this.config.backend)}catch(n){Ue("error: cannot set backend:",this.config.backend,n)}if(K2(),Jh()==="webgl"){this.config.deallocate&&(Ue("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),kn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),kn.set("WEBGL_FORCE_F16_TEXTURES",!0),kn.set("WEBGL_PACK_DEPTHWISECONV",!0);let n=await Of().getGPGPUContext().gl;Ue(`gl version:${n.getParameter(n.VERSION)} renderer:${n.getParameter(n.RENDERER)}`)}await J2(),this.perf.backend=Math.trunc(ft()-t)}}async detectFace(e){var t,n,r,a,s,i;let o,l,c,u,h,d=[];this.state="run:face",o=ft();let p=await((t=this.models.face)==null?void 0:t.estimateFaces(e,this.config));this.perf.face=Math.trunc(ft()-o);for(let f of p){if(this.analyze("Get Face"),!f.image||f.image.isDisposedInternal){Ue("Face object is disposed:",f.image);continue}this.analyze("Start Age:"),this.config.async?l=this.config.face.age.enabled?i2(f.image,this.config):{}:(this.state="run:age",o=ft(),l=this.config.face.age.enabled?await i2(f.image,this.config):{},this.perf.age=Math.trunc(ft()-o)),this.analyze("Start Gender:"),this.config.async?c=this.config.face.gender.enabled?l2(f.image,this.config):{}:(this.state="run:gender",o=ft(),c=this.config.face.gender.enabled?await l2(f.image,this.config):{},this.perf.gender=Math.trunc(ft()-o)),this.analyze("Start Emotion:"),this.config.async?u=this.config.face.emotion.enabled?p2(f.image,this.config):{}:(this.state="run:emotion",o=ft(),u=this.config.face.emotion.enabled?await p2(f.image,this.config):{},this.perf.emotion=Math.trunc(ft()-o)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?h=this.config.face.embedding.enabled?D6(f.image,this.config):{}:(this.state="run:embedding",o=ft(),h=this.config.face.embedding.enabled?await D6(f.image,this.config):{},this.perf.embedding=Math.trunc(ft()-o)),this.analyze("End Emotion:"),this.config.async&&([l,c,u,h]=await Promise.all([l,c,u,h])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((n=f==null?void 0:f.annotations)==null?void 0:n.leftEyeIris)&&((r=f==null?void 0:f.annotations)==null?void 0:r.rightEyeIris)&&(delete f.annotations.leftEyeIris,delete f.annotations.rightEyeIris);let m=((a=f.annotations)==null?void 0:a.leftEyeIris)&&((s=f.annotations)==null?void 0:s.rightEyeIris)?11.7*Math.max(Math.abs(f.annotations.leftEyeIris[3][0]-f.annotations.leftEyeIris[1][0]),Math.abs(f.annotations.rightEyeIris[4][1]-f.annotations.rightEyeIris[2][1])):0;d.push({confidence:f.confidence,box:f.box,mesh:f.mesh,boxRaw:f.boxRaw,meshRaw:f.meshRaw,annotations:f.annotations,age:l.age,gender:c.gender,genderConfidence:c.confidence,emotion:u,embedding:h,iris:m!==0?Math.trunc(m)/100:0}),(i=f.image)==null||i.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),d}async image(e,t={}){var n;this.state="image",this.config=zl(this.config,t);let r=tv(e,this.config);return(n=r==null?void 0:r.tensor)==null||n.dispose(),r==null?void 0:r.canvas}async detect(e,t={}){return new Promise(async n=>{var r,a,s,i;this.state="config";let o;this.config=zl(this.config,t),this.state="check";let l=this.sanity(e);l&&(Ue(l,e),n({error:l}));let c,u,h,d=ft();await this.checkBackend(),await this.load(),this.config.scoped&&pn().startScope(),this.analyze("Start Scope:"),o=ft();let p=tv(e,this.config);if(!p||!p.tensor){Ue("could not convert input to tensor"),n({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(ft()-o),this.analyze("Get Image:"),this.config.async?(h=this.config.face.enabled?this.detectFace(p.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",o=ft(),h=this.config.face.enabled?await this.detectFace(p.tensor):[],this.perf.face=Math.trunc(ft()-o)),this.analyze("Start Body:"),this.config.async?(c=this.config.body.enabled?(r=this.models.posenet)==null?void 0:r.estimatePoses(p.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",o=ft(),c=this.config.body.enabled?await((a=this.models.posenet)==null?void 0:a.estimatePoses(p.tensor,this.config)):[],this.perf.body=Math.trunc(ft()-o)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(u=this.config.hand.enabled?(s=this.models.handpose)==null?void 0:s.estimateHands(p.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",o=ft(),u=this.config.hand.enabled?await((i=this.models.handpose)==null?void 0:i.estimateHands(p.tensor,this.config)):[],this.perf.hand=Math.trunc(ft()-o)),this.analyze("End Hand:"),this.config.async&&([h,c,u]=await Promise.all([h,c,u])),p.tensor.dispose(),this.config.scoped&&pn().endScope(),this.analyze("End Scope:");let f=[];this.config.gesture.enabled&&(o=ft(),f=[...Vae(h),...Bae(c),...Hae(u),...Uae(h)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(ft()-o)),this.perf.total=Math.trunc(ft()-d),this.state="idle",n({face:h,body:c,hand:u,gesture:f,performance:this.perf,canvas:p.canvas})})}async warmupBitmap(){let e=(r,a="application/octet-stream")=>fetch(`data:${a};base64,${r}`).then(s=>s.blob()),t,n;switch(this.config.warmup){case"face":t=await e(N2);break;case"full":t=await e(S2);break;default:t=null}if(t){let r=await createImageBitmap(t);n=await this.detect(r,this.config),r.close()}return n}async warmupCanvas(){return new Promise(e=>{let t,n=0;switch(this.config.warmup){case"face":n=256,t="data:image/jpeg;base64,"+N2;break;case"full":n=1200,t="data:image/jpeg;base64,"+S2;break;default:t=null}let r=new Image(n,n);r.onload=()=>{let a=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(n,n):document.createElement("canvas");a.width=n,a.height=n;let s=a.getContext("2d");s==null||s.drawImage(r,0,0);let i=s==null?void 0:s.getImageData(0,0,n,n);this.detect(i,this.config).then(o=>e(o))},t?r.src=t:e(null)})}async warmupNode(){let e=s=>Buffer.from(s,"base64"),t=this.config.warmup==="face"?e(N2):e(S2),n=(void 0).decodeJpeg(t),r=n.expandDims(0);Ce(n);let a=await this.detect(r,this.config);return Ce(r),a}async warmup(e){let t=ft();e&&(this.config=zl(this.config,e));let n=this.config.videoOptimized;this.config.videoOptimized=!1;let r;typeof createImageBitmap=="function"?r=await this.warmupBitmap():typeof Image!="undefined"?r=await this.warmupCanvas():r=await this.warmupNode(),this.config.videoOptimized=n;let a=ft();return Ue("Warmup",this.config.warmup,Math.round(a-t),"ms",r),r}};async function Xae(e,t,n){if(!e)return;let r=t.getContext("2d");r.font=n.baseFont,r.fillStyle=n.baseLabel;let a=1;for(let s=0;s1&&o[1].length>0){let l=i[1]>0?`#${i[1]}`:"",c=`${i[0]} ${l}: ${o[1]}`;r.fillStyle="black",r.fillText(c,8,2+a*n.baseLineHeight),r.fillStyle=n.baseLabel,r.fillText(c,6,0+a*n.baseLineHeight),a+=1}}}async function Kae(e,t,n,r){if(!e)return;let a=t.getContext("2d");for(let s of e){a.font=n.baseFont,a.strokeStyle=n.baseColor,a.fillStyle=n.baseColor,a.lineWidth=n.baseLineWidth,a.beginPath(),n.drawBoxes&&a.rect(s.box[0],s.box[1],s.box[2],s.box[3]);let i=[];if(s.genderConfidence&&i.push(`${s.gender||""} ${Math.trunc(100*s.genderConfidence)}% confident`),s.age&&i.push(`age: ${s.age||""}`),s.iris&&i.push(`iris distance: ${s.iris}`),s.emotion&&s.emotion.length>0){let o=s.emotion.map(l=>`${Math.trunc(100*l.score)}% ${l.emotion}`);i.push(o.join(" "))}i.length===0&&i.push("face"),a.fillStyle=n.baseLabel;for(let o=0;os.mesh[u]),c=new Path2D;c.moveTo(l[0][0],l[0][1]);for(let u of l)c.lineTo(u[0],u[1]);c.closePath(),a.strokeStyle=n.useDepth?`rgba(${127.5+2*l[0][2]}, ${127.5-2*l[0][2]}, 255, 0.3)`:n.baseColor,a.stroke(c),n.fillPolygons&&(a.fillStyle=n.useDepth?`rgba(${127.5+2*l[0][2]}, ${127.5-2*l[0][2]}, 255, 0.3)`:n.baseColor,a.fill(c))}if(s.annotations&&s.annotations.leftEyeIris){a.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.baseColor,a.beginPath();let o=Math.abs(s.annotations.leftEyeIris[3][0]-s.annotations.leftEyeIris[1][0])/2,l=Math.abs(s.annotations.leftEyeIris[4][1]-s.annotations.leftEyeIris[2][1])/2;a.ellipse(s.annotations.leftEyeIris[0][0],s.annotations.leftEyeIris[0][1],o,l,0,0,2*Math.PI),a.stroke(),n.fillPolygons&&(a.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.baseColor,a.fill())}if(s.annotations&&s.annotations.rightEyeIris){a.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.baseColor,a.beginPath();let o=Math.abs(s.annotations.rightEyeIris[3][0]-s.annotations.rightEyeIris[1][0])/2,l=Math.abs(s.annotations.rightEyeIris[4][1]-s.annotations.rightEyeIris[2][1])/2;a.ellipse(s.annotations.rightEyeIris[0][0],s.annotations.rightEyeIris[0][1],o,l,0,0,2*Math.PI),a.stroke(),n.fillPolygons&&(a.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.baseColor,a.fill())}}}}}var Ba=[];async function Zae(e,t,n){if(!e)return;let r=t.getContext("2d");r.lineJoin="round";for(let a=0;al.part==="leftShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightShoulder"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightHip"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftHip"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftShoulder"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="leftHip"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="leftKnee"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftAnkle"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="rightHip"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightKnee"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightAnkle"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="leftShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="leftElbow"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="leftWrist"),o&&s.lineTo(o.position.x,o.position.y)),i=e[a].keypoints.find(l=>l.part==="rightShoulder"),i&&(s.moveTo(i.position.x,i.position.y),o=e[a].keypoints.find(l=>l.part==="rightElbow"),o&&s.lineTo(o.position.x,o.position.y),o=e[a].keypoints.find(l=>l.part==="rightWrist"),o&&s.lineTo(o.position.x,o.position.y)),r.stroke(s)}}}async function Jae(e,t,n){if(!e)return;let r=t.getContext("2d");r.lineJoin="round";for(let a of e){if(r.font=n.baseFont,r.lineWidth=n.baseLineWidth,n.drawBoxes&&(r.lineWidth=n.baseLineWidth,r.beginPath(),r.strokeStyle=n.baseColor,r.fillStyle=n.baseColor,r.rect(a.box[0],a.box[1],a.box[2],a.box[3]),r.fillStyle="black",r.fillText("hand",a.box[0]+3,1+a.box[1]+n.baseLineHeight,a.box[2]),r.fillStyle=n.baseLabel,r.fillText("hand",a.box[0]+2,0+a.box[1]+n.baseLineHeight,a.box[2]),r.stroke()),n.drawPoints&&a.landmarks&&a.landmarks.length>0)for(let s of a.landmarks)r.fillStyle=n.useDepth?`rgba(${127.5+2*s[2]}, ${127.5-2*s[2]}, 255, 0.5)`:n.baseColor,r.beginPath(),r.arc(s[0],s[1],2,0,2*Math.PI),r.fill();if(n.drawPolygons){let s=i=>{if(!!i)for(let o=0;o0?o-1:0][0],i[o>0?o-1:0][1]),r.lineTo(i[o][0],i[o][1]),r.stroke()};s(a.annotations.indexFinger),s(a.annotations.middleFinger),s(a.annotations.ringFinger),s(a.annotations.pinky),s(a.annotations.thumb)}}}var Bc={face:Kae,body:Zae,hand:Jae,gesture:Xae};var Vc=0,_v=!1,wt={background:"darkslategray",hover:"lightgray",itemBackground:"black",itemColor:"white",buttonBackground:"lightblue",buttonHover:"lightgreen",checkboxOn:"lightgreen",checkboxOff:"lightcoral",rangeBackground:"lightblue",rangeLabel:"white",chartColor:"lightblue"};function Yae(){if(_v)return;let e=` :root { --rounded: 0.2rem; } .menu { position: absolute; top: 0rem; right: 0; width: max-content; padding: 0 0.2rem 0 0.2rem; line-height: 1.8rem; z-index: 10; box-shadow: 0 0 8px dimgrey; background: ${wt.background}; border-radius: var(--rounded); border-color: black; border-style: solid; border-width: thin; } diff --git a/dist/human.esm-nobundle.js b/dist/human.esm-nobundle.js index 6e6f475d..7573b788 100644 --- a/dist/human.esm-nobundle.js +++ b/dist/human.esm-nobundle.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var j1={};J(j1,{author:()=>L0,browser:()=>X0,bugs:()=>H0,default:()=>a5,dependencies:()=>J0,description:()=>I0,devDependencies:()=>K0,engines:()=>Y0,homepage:()=>F0,keywords:()=>C0,license:()=>q0,main:()=>V0,module:()=>k0,name:()=>O0,peerDependencies:()=>U0,repository:()=>B0,scripts:()=>D0,sideEffects:()=>Z0,version:()=>W1});var O0="@vladmandic/human",W1="0.20.2",I0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",Z0=!1,V0="dist/human.node.js",k0="dist/human.esm.js",X0="dist/human.esm.js",L0="Vladimir Mandic ",H0={url:"https://github.com/vladmandic/human/issues"},F0="https://github.com/vladmandic/human#readme",q0="MIT",Y0={node:">=12.0.0"},B0={type:"git",url:"git+https://github.com/vladmandic/human.git"},J0={},U0={},K0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},D0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},C0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],a5={name:O0,version:W1,description:I0,sideEffects:Z0,main:V0,module:k0,browser:X0,author:L0,bugs:H0,homepage:F0,license:q0,engines:Y0,repository:B0,dependencies:J0,peerDependencies:U0,devDependencies:K0,scripts:D0,keywords:C0};var v=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function _e(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=_e(c,_):n[A]=_}),n),{})}var Q0=class{constructor(e={}){this.tf=R,this.package=j1,this.version=W1,this.config=_e(N0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=G0,this.age=Be,this.gender=Ke,this.emotion=e1,this.body=m1,this.hand=P1}profile(){return this.config.profile?Fe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=R.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(R.ENV.flags.IS_NODE&&!(e instanceof R.Tensor))return"input must be a tensor";try{R.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?Q1(e,n):0}async load(e=null){this.state="load";let n=v();e&&(this.config=_e(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${R.version_core}`),await this.checkBackend(!0),R.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",R.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?qe:G0;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Je(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Qe(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?r1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?c1(this.config):null),this.models.posenet||(this.config.body.enabled?u1(this.config):null),this.models.handpose||(this.config.hand.enabled?M1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Je(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Qe(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await r1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await c1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await u1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await M1(this.config))),this.firstRun&&(u("tf engine state:",R.engine().state.numBytes,"bytes",R.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||R.getBackend()!==this.config.backend){let n=v();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),R.setWasmPaths(this.config.wasmPath),await R.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&V1();try{await R.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(R.enableProdMode(),R.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),R.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),R.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),R.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await R.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await R.ready(),this.perf.backend=Math.trunc(v()-n)}}async detectFace(e){var o,i,d,w,s,m;let n,r,A,c,_,h=[];this.state="run:face",n=v();let x=await((o=this.models.face)==null?void 0:o.estimateFaces(e,this.config));this.perf.face=Math.trunc(v()-n);for(let l of x){if(this.analyze("Get Face"),!l.image||l.image.isDisposedInternal){u("Face object is disposed:",l.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ue(l.image,this.config):{}:(this.state="run:age",n=v(),r=this.config.face.age.enabled?await Ue(l.image,this.config):{},this.perf.age=Math.trunc(v()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?$e(l.image,this.config):{}:(this.state="run:gender",n=v(),A=this.config.face.gender.enabled?await $e(l.image,this.config):{},this.perf.gender=Math.trunc(v()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?A1(l.image,this.config):{}:(this.state="run:emotion",n=v(),c=this.config.face.emotion.enabled?await A1(l.image,this.config):{},this.perf.emotion=Math.trunc(v()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?_1(l.image,this.config):{}:(this.state="run:embedding",n=v(),_=this.config.face.embedding.enabled?await _1(l.image,this.config):{},this.perf.embedding=Math.trunc(v()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((i=l==null?void 0:l.annotations)==null?void 0:i.leftEyeIris)&&((d=l==null?void 0:l.annotations)==null?void 0:d.rightEyeIris)&&(delete l.annotations.leftEyeIris,delete l.annotations.rightEyeIris);let V=((w=l.annotations)==null?void 0:w.leftEyeIris)&&((s=l.annotations)==null?void 0:s.rightEyeIris)?11.7*Math.max(Math.abs(l.annotations.leftEyeIris[3][0]-l.annotations.leftEyeIris[1][0]),Math.abs(l.annotations.rightEyeIris[4][1]-l.annotations.rightEyeIris[2][1])):0;h.push({confidence:l.confidence,box:l.box,mesh:l.mesh,boxRaw:l.boxRaw,meshRaw:l.meshRaw,annotations:l.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:V!==0?Math.trunc(V)/100:0}),(m=l.image)==null||m.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=_e(this.config,n);let r=S1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var w,s,m,l;this.state="config";let A;this.config=_e(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,o=v();await this.checkBackend(),await this.load(),this.config.scoped&&R.engine().startScope(),this.analyze("Start Scope:"),A=v();let i=S1(e,this.config);if(!i||!i.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(i.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=v(),x=this.config.face.enabled?await this.detectFace(i.tensor):[],this.perf.face=Math.trunc(v()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(w=this.models.posenet)==null?void 0:w.estimatePoses(i.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=v(),_=this.config.body.enabled?await((s=this.models.posenet)==null?void 0:s.estimatePoses(i.tensor,this.config)):[],this.perf.body=Math.trunc(v()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(m=this.models.handpose)==null?void 0:m.estimateHands(i.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=v(),h=this.config.hand.enabled?await((l=this.models.handpose)==null?void 0:l.estimateHands(i.tensor,this.config)):[],this.perf.hand=Math.trunc(v()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),i.tensor.dispose(),this.config.scoped&&R.engine().endScope(),this.analyze("End Scope:");let d=[];this.config.gesture.enabled&&(A=v(),d=[...E0(x),...R0(_),...M0(h),...z0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-A)),this.perf.total=Math.trunc(v()-o),this.state="idle",r({face:x,body:_,hand:h,gesture:d,performance:this.perf,canvas:i.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(Me);break;case"full":n=await e(Se);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+Me;break;case"full":r=1200,n="data:image/jpeg;base64,"+Se;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(Me):e(Se),r=R.node.decodeJpeg(n),A=r.expandDims(0);R.dispose(r);let c=await this.detect(A,this.config);return R.dispose(A),c}async warmup(e){let n=v();e&&(this.config=_e(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=v();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}};export{Q0 as default}; +2Q==`;var j1={};J(j1,{author:()=>L0,browser:()=>X0,bugs:()=>H0,default:()=>a5,dependencies:()=>J0,description:()=>I0,devDependencies:()=>K0,engines:()=>Y0,homepage:()=>F0,keywords:()=>C0,license:()=>q0,main:()=>V0,module:()=>k0,name:()=>O0,peerDependencies:()=>U0,repository:()=>B0,scripts:()=>D0,sideEffects:()=>Z0,version:()=>W1});var O0="@vladmandic/human",W1="0.20.3",I0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",Z0=!1,V0="dist/human.node.js",k0="dist/human.esm.js",X0="dist/human.esm.js",L0="Vladimir Mandic ",H0={url:"https://github.com/vladmandic/human/issues"},F0="https://github.com/vladmandic/human#readme",q0="MIT",Y0={node:">=12.0.0"},B0={type:"git",url:"git+https://github.com/vladmandic/human.git"},J0={},U0={},K0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},D0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},C0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],a5={name:O0,version:W1,description:I0,sideEffects:Z0,main:V0,module:k0,browser:X0,author:L0,bugs:H0,homepage:F0,license:q0,engines:Y0,repository:B0,dependencies:J0,peerDependencies:U0,devDependencies:K0,scripts:D0,keywords:C0};var v=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function _e(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=_e(c,_):n[A]=_}),n),{})}var Q0=class{constructor(e={}){this.tf=R,this.package=j1,this.version=W1,this.config=_e(N0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=G0,this.age=Be,this.gender=Ke,this.emotion=e1,this.body=m1,this.hand=P1}profile(){return this.config.profile?Fe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=R.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(R.ENV.flags.IS_NODE&&!(e instanceof R.Tensor))return"input must be a tensor";try{R.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?Q1(e,n):0}async load(e=null){this.state="load";let n=v();e&&(this.config=_e(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${R.version_core}`),await this.checkBackend(!0),R.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",R.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?qe:G0;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Je(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?Qe(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?r1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?c1(this.config):null),this.models.posenet||(this.config.body.enabled?u1(this.config):null),this.models.handpose||(this.config.hand.enabled?M1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Je(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await Qe(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await r1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await c1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await u1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await M1(this.config))),this.firstRun&&(u("tf engine state:",R.engine().state.numBytes,"bytes",R.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(v()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||R.getBackend()!==this.config.backend){let n=v();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),R.setWasmPaths(this.config.wasmPath),await R.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&V1();try{await R.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(R.enableProdMode(),R.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),R.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),R.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),R.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await R.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await R.ready(),this.perf.backend=Math.trunc(v()-n)}}async detectFace(e){var o,i,d,w,s,m;let n,r,A,c,_,h=[];this.state="run:face",n=v();let x=await((o=this.models.face)==null?void 0:o.estimateFaces(e,this.config));this.perf.face=Math.trunc(v()-n);for(let l of x){if(this.analyze("Get Face"),!l.image||l.image.isDisposedInternal){u("Face object is disposed:",l.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ue(l.image,this.config):{}:(this.state="run:age",n=v(),r=this.config.face.age.enabled?await Ue(l.image,this.config):{},this.perf.age=Math.trunc(v()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?$e(l.image,this.config):{}:(this.state="run:gender",n=v(),A=this.config.face.gender.enabled?await $e(l.image,this.config):{},this.perf.gender=Math.trunc(v()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?A1(l.image,this.config):{}:(this.state="run:emotion",n=v(),c=this.config.face.emotion.enabled?await A1(l.image,this.config):{},this.perf.emotion=Math.trunc(v()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?_1(l.image,this.config):{}:(this.state="run:embedding",n=v(),_=this.config.face.embedding.enabled?await _1(l.image,this.config):{},this.perf.embedding=Math.trunc(v()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((i=l==null?void 0:l.annotations)==null?void 0:i.leftEyeIris)&&((d=l==null?void 0:l.annotations)==null?void 0:d.rightEyeIris)&&(delete l.annotations.leftEyeIris,delete l.annotations.rightEyeIris);let V=((w=l.annotations)==null?void 0:w.leftEyeIris)&&((s=l.annotations)==null?void 0:s.rightEyeIris)?11.7*Math.max(Math.abs(l.annotations.leftEyeIris[3][0]-l.annotations.leftEyeIris[1][0]),Math.abs(l.annotations.rightEyeIris[4][1]-l.annotations.rightEyeIris[2][1])):0;h.push({confidence:l.confidence,box:l.box,mesh:l.mesh,boxRaw:l.boxRaw,meshRaw:l.meshRaw,annotations:l.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:V!==0?Math.trunc(V)/100:0}),(m=l.image)==null||m.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=_e(this.config,n);let r=S1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var w,s,m,l;this.state="config";let A;this.config=_e(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,o=v();await this.checkBackend(),await this.load(),this.config.scoped&&R.engine().startScope(),this.analyze("Start Scope:"),A=v();let i=S1(e,this.config);if(!i||!i.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(v()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(i.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=v(),x=this.config.face.enabled?await this.detectFace(i.tensor):[],this.perf.face=Math.trunc(v()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(w=this.models.posenet)==null?void 0:w.estimatePoses(i.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=v(),_=this.config.body.enabled?await((s=this.models.posenet)==null?void 0:s.estimatePoses(i.tensor,this.config)):[],this.perf.body=Math.trunc(v()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(m=this.models.handpose)==null?void 0:m.estimateHands(i.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=v(),h=this.config.hand.enabled?await((l=this.models.handpose)==null?void 0:l.estimateHands(i.tensor,this.config)):[],this.perf.hand=Math.trunc(v()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),i.tensor.dispose(),this.config.scoped&&R.engine().endScope(),this.analyze("End Scope:");let d=[];this.config.gesture.enabled&&(A=v(),d=[...E0(x),...R0(_),...M0(h),...z0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(v()-A)),this.perf.total=Math.trunc(v()-o),this.state="idle",r({face:x,body:_,hand:h,gesture:d,performance:this.perf,canvas:i.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(Me);break;case"full":n=await e(Se);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+Me;break;case"full":r=1200,n="data:image/jpeg;base64,"+Se;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(Me):e(Se),r=R.node.decodeJpeg(n),A=r.expandDims(0);R.dispose(r);let c=await this.detect(A,this.config);return R.dispose(A),c}async warmup(e){let n=v();e&&(this.config=_e(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=v();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}};export{Q0 as default}; //# sourceMappingURL=human.esm-nobundle.js.map diff --git a/dist/human.esm.js b/dist/human.esm.js index c00883f0..787dca87 100644 --- a/dist/human.esm.js +++ b/dist/human.esm.js @@ -4771,7 +4771,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var G2={};kr(G2,{author:()=>$6,browser:()=>O6,bugs:()=>D6,default:()=>Pae,dependencies:()=>B6,description:()=>C6,devDependencies:()=>U6,engines:()=>L6,homepage:()=>z6,keywords:()=>G6,license:()=>P6,main:()=>F6,module:()=>M6,name:()=>E6,peerDependencies:()=>V6,repository:()=>W6,scripts:()=>j6,sideEffects:()=>R6,version:()=>H2});var E6="@vladmandic/human",H2="0.20.2",C6="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",R6=!1,F6="dist/human.node.js",M6="dist/human.esm.js",O6="dist/human.esm.js",$6="Vladimir Mandic ",D6={url:"https://github.com/vladmandic/human/issues"},z6="https://github.com/vladmandic/human#readme",P6="MIT",L6={node:">=12.0.0"},W6={type:"git",url:"git+https://github.com/vladmandic/human.git"},B6={},V6={},U6={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},j6={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},G6=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],Pae={name:E6,version:H2,description:C6,sideEffects:R6,main:F6,module:M6,browser:O6,author:$6,bugs:D6,homepage:z6,license:P6,engines:L6,repository:W6,dependencies:B6,peerDependencies:V6,devDependencies:U6,scripts:j6,keywords:G6};var dt=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Dl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=Dl(s,i):n[a]=i}),n),{})}var q6=class{constructor(t={}){this.tf=lh,this.package=G2,this.version=H2,this.config=Dl(T6,t),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=H6,this.age=i2,this.gender=u2,this.emotion=m2,this.body=M2,this.hand=W2}profile(){return this.config.profile?r2:{}}analyze(...t){if(!this.analyzeMemoryLeaks)return;let n=dn().state.numTensors,r=this.numTensors;this.numTensors=n;let a=n-r;a!==0&&Te(...t,a)}sanity(t){if(!this.checkSanity)return null;if(!t)return"input is not defined";if(nn.flags.IS_NODE&&!(t instanceof Xe))return"input must be a tensor";try{nd()}catch(n){return"backend not loaded"}return null}simmilarity(t,n){return this.config.face.embedding.enabled?Zv(t,n):0}async load(t=null){this.state="load";let n=dt();t&&(this.config=Dl(this.config,t)),this.firstRun&&(Te(`version: ${this.version} TensorFlow/JS version: ${u5}`),await this.checkBackend(!0),nn.flags.IS_BROWSER&&(Te("configuration:",this.config),Te("tf flags:",nn.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?a2:H6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?o2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?p2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?g2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?w2(this.config):null),this.models.posenet||(this.config.body.enabled?$2(this.config):null),this.models.handpose||(this.config.hand.enabled?U2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await o2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await p2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await g2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await w2(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await $2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await U2(this.config))),this.firstRun&&(Te("tf engine state:",dn().state.numBytes,"bytes",dn().state.numTensors,"tensors"),this.firstRun=!1);let a=Math.trunc(dt()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async checkBackend(t=!1){if(this.config.backend&&this.config.backend!==""&&t||nd()!==this.config.backend){let n=dt();this.state="backend",Te("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Te("settings wasm path:",this.config.wasmPath),Hb(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Te("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&Dv();try{await h5(this.config.backend)}catch(r){Te("error: cannot set backend:",this.config.backend,r)}if(c5(),nd()==="webgl"){this.config.deallocate&&(Te("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),nn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),nn.set("WEBGL_FORCE_F16_TEXTURES",!0),nn.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await hf().getGPGPUContext().gl;Te(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await d5(),this.perf.backend=Math.trunc(dt()-n)}}async detectFace(t){var c,u,h,p,d,f;let n,r,a,s,i,o=[];this.state="run:face",n=dt();let l=await((c=this.models.face)==null?void 0:c.estimateFaces(t,this.config));this.perf.face=Math.trunc(dt()-n);for(let m of l){if(this.analyze("Get Face"),!m.image||m.image.isDisposedInternal){Te("Face object is disposed:",m.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?l2(m.image,this.config):{}:(this.state="run:age",n=dt(),r=this.config.face.age.enabled?await l2(m.image,this.config):{},this.perf.age=Math.trunc(dt()-n)),this.analyze("Start Gender:"),this.config.async?a=this.config.face.gender.enabled?f2(m.image,this.config):{}:(this.state="run:gender",n=dt(),a=this.config.face.gender.enabled?await f2(m.image,this.config):{},this.perf.gender=Math.trunc(dt()-n)),this.analyze("Start Emotion:"),this.config.async?s=this.config.face.emotion.enabled?x2(m.image,this.config):{}:(this.state="run:emotion",n=dt(),s=this.config.face.emotion.enabled?await x2(m.image,this.config):{},this.perf.emotion=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?i=this.config.face.embedding.enabled?_2(m.image,this.config):{}:(this.state="run:embedding",n=dt(),i=this.config.face.embedding.enabled?await _2(m.image,this.config):{},this.perf.embedding=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.config.async&&([r,a,s,i]=await Promise.all([r,a,s,i])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((u=m==null?void 0:m.annotations)==null?void 0:u.leftEyeIris)&&((h=m==null?void 0:m.annotations)==null?void 0:h.rightEyeIris)&&(delete m.annotations.leftEyeIris,delete m.annotations.rightEyeIris);let A=((p=m.annotations)==null?void 0:p.leftEyeIris)&&((d=m.annotations)==null?void 0:d.rightEyeIris)?11.7*Math.max(Math.abs(m.annotations.leftEyeIris[3][0]-m.annotations.leftEyeIris[1][0]),Math.abs(m.annotations.rightEyeIris[4][1]-m.annotations.rightEyeIris[2][1])):0;o.push({confidence:m.confidence,box:m.box,mesh:m.mesh,boxRaw:m.boxRaw,meshRaw:m.meshRaw,annotations:m.annotations,age:r.age,gender:a.gender,genderConfidence:a.confidence,emotion:s,embedding:i,iris:A!==0?Math.trunc(A)/100:0}),(f=m.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),o}async image(t,n={}){var a;this.state="image",this.config=Dl(this.config,n);let r=j2(t,this.config);return(a=r==null?void 0:r.tensor)==null||a.dispose(),r==null?void 0:r.canvas}async detect(t,n={}){return new Promise(async r=>{var p,d,f,m;this.state="config";let a;this.config=Dl(this.config,n),this.state="check";let s=this.sanity(t);s&&(Te(s,t),r({error:s}));let i,o,l,c=dt();await this.checkBackend(),await this.load(),this.config.scoped&&dn().startScope(),this.analyze("Start Scope:"),a=dt();let u=j2(t,this.config);if(!u||!u.tensor){Te("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(dt()-a),this.analyze("Get Image:"),this.config.async?(l=this.config.face.enabled?this.detectFace(u.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=dt(),l=this.config.face.enabled?await this.detectFace(u.tensor):[],this.perf.face=Math.trunc(dt()-a)),this.analyze("Start Body:"),this.config.async?(i=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(u.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",a=dt(),i=this.config.body.enabled?await((d=this.models.posenet)==null?void 0:d.estimatePoses(u.tensor,this.config)):[],this.perf.body=Math.trunc(dt()-a)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(o=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(u.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=dt(),o=this.config.hand.enabled?await((m=this.models.handpose)==null?void 0:m.estimateHands(u.tensor,this.config)):[],this.perf.hand=Math.trunc(dt()-a)),this.analyze("End Hand:"),this.config.async&&([l,i,o]=await Promise.all([l,i,o])),u.tensor.dispose(),this.config.scoped&&dn().endScope(),this.analyze("End Scope:");let h=[];this.config.gesture.enabled&&(a=dt(),h=[...b6(l),..._6(i),...k6(o),...v6(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(dt()-a)),this.perf.total=Math.trunc(dt()-c),this.state="idle",r({face:l,body:i,hand:o,gesture:h,performance:this.perf,canvas:u.canvas})})}async warmupBitmap(){let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(f0);break;case"full":n=await t(m0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r}async warmupCanvas(){return new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+f0;break;case"full":r=1200,n="data:image/jpeg;base64,"+m0;break;default:n=null}let a=new Image(r,r);a.onload=()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=r,s.height=r;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=i==null?void 0:i.getImageData(0,0,r,r);this.detect(o,this.config).then(l=>t(l))},n?a.src=n:t(null)})}async warmupNode(){let t=i=>Buffer.from(i,"base64"),n=this.config.warmup==="face"?t(f0):t(m0),r=(void 0).decodeJpeg(n),a=r.expandDims(0);Ne(r);let s=await this.detect(a,this.config);return Ne(a),s}async warmup(t){let n=dt();t&&(this.config=Dl(this.config,t));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await this.warmupBitmap():typeof Image!="undefined"?a=await this.warmupCanvas():a=await this.warmupNode(),this.config.videoOptimized=r;let s=dt();return Te("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};export{q6 as default}; +2Q==`;var G2={};kr(G2,{author:()=>$6,browser:()=>O6,bugs:()=>D6,default:()=>Pae,dependencies:()=>B6,description:()=>C6,devDependencies:()=>U6,engines:()=>L6,homepage:()=>z6,keywords:()=>G6,license:()=>P6,main:()=>F6,module:()=>M6,name:()=>E6,peerDependencies:()=>V6,repository:()=>W6,scripts:()=>j6,sideEffects:()=>R6,version:()=>H2});var E6="@vladmandic/human",H2="0.20.3",C6="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",R6=!1,F6="dist/human.node.js",M6="dist/human.esm.js",O6="dist/human.esm.js",$6="Vladimir Mandic ",D6={url:"https://github.com/vladmandic/human/issues"},z6="https://github.com/vladmandic/human#readme",P6="MIT",L6={node:">=12.0.0"},W6={type:"git",url:"git+https://github.com/vladmandic/human.git"},B6={},V6={},U6={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},j6={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},G6=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],Pae={name:E6,version:H2,description:C6,sideEffects:R6,main:F6,module:M6,browser:O6,author:$6,bugs:D6,homepage:z6,license:P6,engines:L6,repository:W6,dependencies:B6,peerDependencies:V6,devDependencies:U6,scripts:j6,keywords:G6};var dt=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Dl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=Dl(s,i):n[a]=i}),n),{})}var q6=class{constructor(t={}){this.tf=lh,this.package=G2,this.version=H2,this.config=Dl(T6,t),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=H6,this.age=i2,this.gender=u2,this.emotion=m2,this.body=M2,this.hand=W2}profile(){return this.config.profile?r2:{}}analyze(...t){if(!this.analyzeMemoryLeaks)return;let n=dn().state.numTensors,r=this.numTensors;this.numTensors=n;let a=n-r;a!==0&&Te(...t,a)}sanity(t){if(!this.checkSanity)return null;if(!t)return"input is not defined";if(nn.flags.IS_NODE&&!(t instanceof Xe))return"input must be a tensor";try{nd()}catch(n){return"backend not loaded"}return null}simmilarity(t,n){return this.config.face.embedding.enabled?Zv(t,n):0}async load(t=null){this.state="load";let n=dt();t&&(this.config=Dl(this.config,t)),this.firstRun&&(Te(`version: ${this.version} TensorFlow/JS version: ${u5}`),await this.checkBackend(!0),nn.flags.IS_BROWSER&&(Te("configuration:",this.config),Te("tf flags:",nn.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?a2:H6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?o2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?p2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?g2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?w2(this.config):null),this.models.posenet||(this.config.body.enabled?$2(this.config):null),this.models.handpose||(this.config.hand.enabled?U2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await o2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await p2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await g2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await w2(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await $2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await U2(this.config))),this.firstRun&&(Te("tf engine state:",dn().state.numBytes,"bytes",dn().state.numTensors,"tensors"),this.firstRun=!1);let a=Math.trunc(dt()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async checkBackend(t=!1){if(this.config.backend&&this.config.backend!==""&&t||nd()!==this.config.backend){let n=dt();this.state="backend",Te("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Te("settings wasm path:",this.config.wasmPath),Hb(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Te("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&Dv();try{await h5(this.config.backend)}catch(r){Te("error: cannot set backend:",this.config.backend,r)}if(c5(),nd()==="webgl"){this.config.deallocate&&(Te("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),nn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),nn.set("WEBGL_FORCE_F16_TEXTURES",!0),nn.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await hf().getGPGPUContext().gl;Te(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await d5(),this.perf.backend=Math.trunc(dt()-n)}}async detectFace(t){var c,u,h,p,d,f;let n,r,a,s,i,o=[];this.state="run:face",n=dt();let l=await((c=this.models.face)==null?void 0:c.estimateFaces(t,this.config));this.perf.face=Math.trunc(dt()-n);for(let m of l){if(this.analyze("Get Face"),!m.image||m.image.isDisposedInternal){Te("Face object is disposed:",m.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?l2(m.image,this.config):{}:(this.state="run:age",n=dt(),r=this.config.face.age.enabled?await l2(m.image,this.config):{},this.perf.age=Math.trunc(dt()-n)),this.analyze("Start Gender:"),this.config.async?a=this.config.face.gender.enabled?f2(m.image,this.config):{}:(this.state="run:gender",n=dt(),a=this.config.face.gender.enabled?await f2(m.image,this.config):{},this.perf.gender=Math.trunc(dt()-n)),this.analyze("Start Emotion:"),this.config.async?s=this.config.face.emotion.enabled?x2(m.image,this.config):{}:(this.state="run:emotion",n=dt(),s=this.config.face.emotion.enabled?await x2(m.image,this.config):{},this.perf.emotion=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?i=this.config.face.embedding.enabled?_2(m.image,this.config):{}:(this.state="run:embedding",n=dt(),i=this.config.face.embedding.enabled?await _2(m.image,this.config):{},this.perf.embedding=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.config.async&&([r,a,s,i]=await Promise.all([r,a,s,i])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((u=m==null?void 0:m.annotations)==null?void 0:u.leftEyeIris)&&((h=m==null?void 0:m.annotations)==null?void 0:h.rightEyeIris)&&(delete m.annotations.leftEyeIris,delete m.annotations.rightEyeIris);let A=((p=m.annotations)==null?void 0:p.leftEyeIris)&&((d=m.annotations)==null?void 0:d.rightEyeIris)?11.7*Math.max(Math.abs(m.annotations.leftEyeIris[3][0]-m.annotations.leftEyeIris[1][0]),Math.abs(m.annotations.rightEyeIris[4][1]-m.annotations.rightEyeIris[2][1])):0;o.push({confidence:m.confidence,box:m.box,mesh:m.mesh,boxRaw:m.boxRaw,meshRaw:m.meshRaw,annotations:m.annotations,age:r.age,gender:a.gender,genderConfidence:a.confidence,emotion:s,embedding:i,iris:A!==0?Math.trunc(A)/100:0}),(f=m.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),o}async image(t,n={}){var a;this.state="image",this.config=Dl(this.config,n);let r=j2(t,this.config);return(a=r==null?void 0:r.tensor)==null||a.dispose(),r==null?void 0:r.canvas}async detect(t,n={}){return new Promise(async r=>{var p,d,f,m;this.state="config";let a;this.config=Dl(this.config,n),this.state="check";let s=this.sanity(t);s&&(Te(s,t),r({error:s}));let i,o,l,c=dt();await this.checkBackend(),await this.load(),this.config.scoped&&dn().startScope(),this.analyze("Start Scope:"),a=dt();let u=j2(t,this.config);if(!u||!u.tensor){Te("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(dt()-a),this.analyze("Get Image:"),this.config.async?(l=this.config.face.enabled?this.detectFace(u.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=dt(),l=this.config.face.enabled?await this.detectFace(u.tensor):[],this.perf.face=Math.trunc(dt()-a)),this.analyze("Start Body:"),this.config.async?(i=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(u.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",a=dt(),i=this.config.body.enabled?await((d=this.models.posenet)==null?void 0:d.estimatePoses(u.tensor,this.config)):[],this.perf.body=Math.trunc(dt()-a)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(o=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(u.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=dt(),o=this.config.hand.enabled?await((m=this.models.handpose)==null?void 0:m.estimateHands(u.tensor,this.config)):[],this.perf.hand=Math.trunc(dt()-a)),this.analyze("End Hand:"),this.config.async&&([l,i,o]=await Promise.all([l,i,o])),u.tensor.dispose(),this.config.scoped&&dn().endScope(),this.analyze("End Scope:");let h=[];this.config.gesture.enabled&&(a=dt(),h=[...b6(l),..._6(i),...k6(o),...v6(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(dt()-a)),this.perf.total=Math.trunc(dt()-c),this.state="idle",r({face:l,body:i,hand:o,gesture:h,performance:this.perf,canvas:u.canvas})})}async warmupBitmap(){let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(f0);break;case"full":n=await t(m0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r}async warmupCanvas(){return new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+f0;break;case"full":r=1200,n="data:image/jpeg;base64,"+m0;break;default:n=null}let a=new Image(r,r);a.onload=()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=r,s.height=r;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=i==null?void 0:i.getImageData(0,0,r,r);this.detect(o,this.config).then(l=>t(l))},n?a.src=n:t(null)})}async warmupNode(){let t=i=>Buffer.from(i,"base64"),n=this.config.warmup==="face"?t(f0):t(m0),r=(void 0).decodeJpeg(n),a=r.expandDims(0);Ne(r);let s=await this.detect(a,this.config);return Ne(a),s}async warmup(t){let n=dt();t&&(this.config=Dl(this.config,t));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await this.warmupBitmap():typeof Image!="undefined"?a=await this.warmupCanvas():a=await this.warmupNode(),this.config.videoOptimized=r;let s=dt();return Te("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};export{q6 as default}; /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/dist/human.node-gpu.js b/dist/human.node-gpu.js index e451b3b6..589f155b 100644 --- a/dist/human.node-gpu.js +++ b/dist/human.node-gpu.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var N1={};B(N1,{author:()=>q0,browser:()=>F0,bugs:()=>Y0,default:()=>i5,dependencies:()=>D0,description:()=>X0,devDependencies:()=>G0,engines:()=>U0,homepage:()=>B0,keywords:()=>$0,license:()=>J0,main:()=>k0,module:()=>H0,name:()=>V0,peerDependencies:()=>C0,repository:()=>K0,scripts:()=>Q0,sideEffects:()=>L0,version:()=>j1});var V0="@vladmandic/human",j1="0.20.2",X0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",L0=!1,k0="dist/human.node.js",H0="dist/human.esm.js",F0="dist/human.esm.js",q0="Vladimir Mandic ",Y0={url:"https://github.com/vladmandic/human/issues"},B0="https://github.com/vladmandic/human#readme",J0="MIT",U0={node:">=12.0.0"},K0={type:"git",url:"git+https://github.com/vladmandic/human.git"},D0={},C0={},G0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},Q0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},$0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],i5={name:V0,version:j1,description:X0,sideEffects:L0,main:k0,module:H0,browser:F0,author:q0,bugs:Y0,homepage:B0,license:J0,engines:U0,repository:K0,dependencies:D0,peerDependencies:C0,devDependencies:G0,scripts:Q0,keywords:$0};var T=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function ce(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=ce(c,_):n[A]=_}),n),{})}var tt=class{constructor(e={}){this.tf=P,this.package=N1,this.version=j1,this.config=ce(Z0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=et,this.age=Je,this.gender=De,this.emotion=t1,this.body=u1,this.hand=R1}profile(){return this.config.profile?qe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=P.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(P.ENV.flags.IS_NODE&&!(e instanceof P.Tensor))return"input must be a tensor";try{P.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?t0(e,n):0}async load(e=null){this.state="load";let n=T();e&&(this.config=ce(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${P.version_core}`),await this.checkBackend(!0),P.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",P.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?Ye:et;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Ue(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?$e(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?A1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?_1(this.config):null),this.models.posenet||(this.config.body.enabled?b1(this.config):null),this.models.handpose||(this.config.hand.enabled?S1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Ue(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await $e(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await A1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await _1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await b1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S1(this.config))),this.firstRun&&(u("tf engine state:",P.engine().state.numBytes,"bytes",P.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(T()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||P.getBackend()!==this.config.backend){let n=T();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),P.setWasmPaths(this.config.wasmPath),await P.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&k1();try{await P.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(P.enableProdMode(),P.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),P.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),P.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),P.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await P.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await P.ready(),this.perf.backend=Math.trunc(T()-n)}}async detectFace(e){var s,o,w,a,y,f;let n,r,A,c,_,h=[];this.state="run:face",n=T();let x=await((s=this.models.face)==null?void 0:s.estimateFaces(e,this.config));this.perf.face=Math.trunc(T()-n);for(let d of x){if(this.analyze("Get Face"),!d.image||d.image.isDisposedInternal){u("Face object is disposed:",d.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ke(d.image,this.config):{}:(this.state="run:age",n=T(),r=this.config.face.age.enabled?await Ke(d.image,this.config):{},this.perf.age=Math.trunc(T()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?e1(d.image,this.config):{}:(this.state="run:gender",n=T(),A=this.config.face.gender.enabled?await e1(d.image,this.config):{},this.perf.gender=Math.trunc(T()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?c1(d.image,this.config):{}:(this.state="run:emotion",n=T(),c=this.config.face.emotion.enabled?await c1(d.image,this.config):{},this.perf.emotion=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?h1(d.image,this.config):{}:(this.state="run:embedding",n=T(),_=this.config.face.embedding.enabled?await h1(d.image,this.config):{},this.perf.embedding=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((o=d==null?void 0:d.annotations)==null?void 0:o.leftEyeIris)&&((w=d==null?void 0:d.annotations)==null?void 0:w.rightEyeIris)&&(delete d.annotations.leftEyeIris,delete d.annotations.rightEyeIris);let Z=((a=d.annotations)==null?void 0:a.leftEyeIris)&&((y=d.annotations)==null?void 0:y.rightEyeIris)?11.7*Math.max(Math.abs(d.annotations.leftEyeIris[3][0]-d.annotations.leftEyeIris[1][0]),Math.abs(d.annotations.rightEyeIris[4][1]-d.annotations.rightEyeIris[2][1])):0;h.push({confidence:d.confidence,box:d.box,mesh:d.mesh,boxRaw:d.boxRaw,meshRaw:d.meshRaw,annotations:d.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:Z!==0?Math.trunc(Z)/100:0}),(f=d.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=ce(this.config,n);let r=W1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var a,y,f,d;this.state="config";let A;this.config=ce(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,s=T();await this.checkBackend(),await this.load(),this.config.scoped&&P.engine().startScope(),this.analyze("Start Scope:"),A=T();let o=W1(e,this.config);if(!o||!o.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(T()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=T(),x=this.config.face.enabled?await this.detectFace(o.tensor):[],this.perf.face=Math.trunc(T()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(a=this.models.posenet)==null?void 0:a.estimatePoses(o.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=T(),_=this.config.body.enabled?await((y=this.models.posenet)==null?void 0:y.estimatePoses(o.tensor,this.config)):[],this.perf.body=Math.trunc(T()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=T(),h=this.config.hand.enabled?await((d=this.models.handpose)==null?void 0:d.estimateHands(o.tensor,this.config)):[],this.perf.hand=Math.trunc(T()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),o.tensor.dispose(),this.config.scoped&&P.engine().endScope(),this.analyze("End Scope:");let w=[];this.config.gesture.enabled&&(A=T(),w=[...S0(x),...M0(_),...N0(h),...W0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(T()-A)),this.perf.total=Math.trunc(T()-s),this.state="idle",r({face:x,body:_,hand:h,gesture:w,performance:this.perf,canvas:o.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(ze);break;case"full":n=await e(Me);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+ze;break;case"full":r=1200,n="data:image/jpeg;base64,"+Me;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(ze):e(Me),r=P.node.decodeJpeg(n),A=r.expandDims(0);P.dispose(r);let c=await this.detect(A,this.config);return P.dispose(A),c}async warmup(e){let n=T();e&&(this.config=ce(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=T();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}}; +2Q==`;var N1={};B(N1,{author:()=>q0,browser:()=>F0,bugs:()=>Y0,default:()=>i5,dependencies:()=>D0,description:()=>X0,devDependencies:()=>G0,engines:()=>U0,homepage:()=>B0,keywords:()=>$0,license:()=>J0,main:()=>k0,module:()=>H0,name:()=>V0,peerDependencies:()=>C0,repository:()=>K0,scripts:()=>Q0,sideEffects:()=>L0,version:()=>j1});var V0="@vladmandic/human",j1="0.20.3",X0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",L0=!1,k0="dist/human.node.js",H0="dist/human.esm.js",F0="dist/human.esm.js",q0="Vladimir Mandic ",Y0={url:"https://github.com/vladmandic/human/issues"},B0="https://github.com/vladmandic/human#readme",J0="MIT",U0={node:">=12.0.0"},K0={type:"git",url:"git+https://github.com/vladmandic/human.git"},D0={},C0={},G0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},Q0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},$0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],i5={name:V0,version:j1,description:X0,sideEffects:L0,main:k0,module:H0,browser:F0,author:q0,bugs:Y0,homepage:B0,license:J0,engines:U0,repository:K0,dependencies:D0,peerDependencies:C0,devDependencies:G0,scripts:Q0,keywords:$0};var T=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function ce(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=ce(c,_):n[A]=_}),n),{})}var tt=class{constructor(e={}){this.tf=P,this.package=N1,this.version=j1,this.config=ce(Z0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=et,this.age=Je,this.gender=De,this.emotion=t1,this.body=u1,this.hand=R1}profile(){return this.config.profile?qe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=P.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(P.ENV.flags.IS_NODE&&!(e instanceof P.Tensor))return"input must be a tensor";try{P.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?t0(e,n):0}async load(e=null){this.state="load";let n=T();e&&(this.config=ce(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${P.version_core}`),await this.checkBackend(!0),P.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",P.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?Ye:et;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Ue(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?$e(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?A1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?_1(this.config):null),this.models.posenet||(this.config.body.enabled?b1(this.config):null),this.models.handpose||(this.config.hand.enabled?S1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Ue(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await $e(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await A1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await _1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await b1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S1(this.config))),this.firstRun&&(u("tf engine state:",P.engine().state.numBytes,"bytes",P.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(T()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||P.getBackend()!==this.config.backend){let n=T();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),P.setWasmPaths(this.config.wasmPath),await P.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&k1();try{await P.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(P.enableProdMode(),P.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),P.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),P.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),P.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await P.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await P.ready(),this.perf.backend=Math.trunc(T()-n)}}async detectFace(e){var s,o,w,a,y,f;let n,r,A,c,_,h=[];this.state="run:face",n=T();let x=await((s=this.models.face)==null?void 0:s.estimateFaces(e,this.config));this.perf.face=Math.trunc(T()-n);for(let d of x){if(this.analyze("Get Face"),!d.image||d.image.isDisposedInternal){u("Face object is disposed:",d.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ke(d.image,this.config):{}:(this.state="run:age",n=T(),r=this.config.face.age.enabled?await Ke(d.image,this.config):{},this.perf.age=Math.trunc(T()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?e1(d.image,this.config):{}:(this.state="run:gender",n=T(),A=this.config.face.gender.enabled?await e1(d.image,this.config):{},this.perf.gender=Math.trunc(T()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?c1(d.image,this.config):{}:(this.state="run:emotion",n=T(),c=this.config.face.emotion.enabled?await c1(d.image,this.config):{},this.perf.emotion=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?h1(d.image,this.config):{}:(this.state="run:embedding",n=T(),_=this.config.face.embedding.enabled?await h1(d.image,this.config):{},this.perf.embedding=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((o=d==null?void 0:d.annotations)==null?void 0:o.leftEyeIris)&&((w=d==null?void 0:d.annotations)==null?void 0:w.rightEyeIris)&&(delete d.annotations.leftEyeIris,delete d.annotations.rightEyeIris);let Z=((a=d.annotations)==null?void 0:a.leftEyeIris)&&((y=d.annotations)==null?void 0:y.rightEyeIris)?11.7*Math.max(Math.abs(d.annotations.leftEyeIris[3][0]-d.annotations.leftEyeIris[1][0]),Math.abs(d.annotations.rightEyeIris[4][1]-d.annotations.rightEyeIris[2][1])):0;h.push({confidence:d.confidence,box:d.box,mesh:d.mesh,boxRaw:d.boxRaw,meshRaw:d.meshRaw,annotations:d.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:Z!==0?Math.trunc(Z)/100:0}),(f=d.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=ce(this.config,n);let r=W1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var a,y,f,d;this.state="config";let A;this.config=ce(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,s=T();await this.checkBackend(),await this.load(),this.config.scoped&&P.engine().startScope(),this.analyze("Start Scope:"),A=T();let o=W1(e,this.config);if(!o||!o.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(T()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=T(),x=this.config.face.enabled?await this.detectFace(o.tensor):[],this.perf.face=Math.trunc(T()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(a=this.models.posenet)==null?void 0:a.estimatePoses(o.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=T(),_=this.config.body.enabled?await((y=this.models.posenet)==null?void 0:y.estimatePoses(o.tensor,this.config)):[],this.perf.body=Math.trunc(T()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=T(),h=this.config.hand.enabled?await((d=this.models.handpose)==null?void 0:d.estimateHands(o.tensor,this.config)):[],this.perf.hand=Math.trunc(T()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),o.tensor.dispose(),this.config.scoped&&P.engine().endScope(),this.analyze("End Scope:");let w=[];this.config.gesture.enabled&&(A=T(),w=[...S0(x),...M0(_),...N0(h),...W0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(T()-A)),this.perf.total=Math.trunc(T()-s),this.state="idle",r({face:x,body:_,hand:h,gesture:w,performance:this.perf,canvas:o.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(ze);break;case"full":n=await e(Me);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+ze;break;case"full":r=1200,n="data:image/jpeg;base64,"+Me;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(ze):e(Me),r=P.node.decodeJpeg(n),A=r.expandDims(0);P.dispose(r);let c=await this.detect(A,this.config);return P.dispose(A),c}async warmup(e){let n=T();e&&(this.config=ce(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=T();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}}; //# sourceMappingURL=human.node-gpu.js.map diff --git a/dist/human.node.js b/dist/human.node.js index 3b2bea5d..55b56a7a 100644 --- a/dist/human.node.js +++ b/dist/human.node.js @@ -731,5 +731,5 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var N1={};B(N1,{author:()=>q0,browser:()=>F0,bugs:()=>Y0,default:()=>i5,dependencies:()=>D0,description:()=>X0,devDependencies:()=>G0,engines:()=>U0,homepage:()=>B0,keywords:()=>$0,license:()=>J0,main:()=>k0,module:()=>H0,name:()=>V0,peerDependencies:()=>C0,repository:()=>K0,scripts:()=>Q0,sideEffects:()=>L0,version:()=>j1});var V0="@vladmandic/human",j1="0.20.2",X0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",L0=!1,k0="dist/human.node.js",H0="dist/human.esm.js",F0="dist/human.esm.js",q0="Vladimir Mandic ",Y0={url:"https://github.com/vladmandic/human/issues"},B0="https://github.com/vladmandic/human#readme",J0="MIT",U0={node:">=12.0.0"},K0={type:"git",url:"git+https://github.com/vladmandic/human.git"},D0={},C0={},G0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},Q0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},$0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],i5={name:V0,version:j1,description:X0,sideEffects:L0,main:k0,module:H0,browser:F0,author:q0,bugs:Y0,homepage:B0,license:J0,engines:U0,repository:K0,dependencies:D0,peerDependencies:C0,devDependencies:G0,scripts:Q0,keywords:$0};var T=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function ce(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=ce(c,_):n[A]=_}),n),{})}var tt=class{constructor(e={}){this.tf=P,this.package=N1,this.version=j1,this.config=ce(Z0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=et,this.age=Je,this.gender=De,this.emotion=t1,this.body=u1,this.hand=R1}profile(){return this.config.profile?qe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=P.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(P.ENV.flags.IS_NODE&&!(e instanceof P.Tensor))return"input must be a tensor";try{P.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?t0(e,n):0}async load(e=null){this.state="load";let n=T();e&&(this.config=ce(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${P.version_core}`),await this.checkBackend(!0),P.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",P.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?Ye:et;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Ue(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?$e(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?A1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?_1(this.config):null),this.models.posenet||(this.config.body.enabled?b1(this.config):null),this.models.handpose||(this.config.hand.enabled?S1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Ue(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await $e(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await A1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await _1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await b1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S1(this.config))),this.firstRun&&(u("tf engine state:",P.engine().state.numBytes,"bytes",P.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(T()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||P.getBackend()!==this.config.backend){let n=T();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),P.setWasmPaths(this.config.wasmPath),await P.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&k1();try{await P.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(P.enableProdMode(),P.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),P.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),P.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),P.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await P.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await P.ready(),this.perf.backend=Math.trunc(T()-n)}}async detectFace(e){var s,o,w,a,y,f;let n,r,A,c,_,h=[];this.state="run:face",n=T();let x=await((s=this.models.face)==null?void 0:s.estimateFaces(e,this.config));this.perf.face=Math.trunc(T()-n);for(let d of x){if(this.analyze("Get Face"),!d.image||d.image.isDisposedInternal){u("Face object is disposed:",d.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ke(d.image,this.config):{}:(this.state="run:age",n=T(),r=this.config.face.age.enabled?await Ke(d.image,this.config):{},this.perf.age=Math.trunc(T()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?e1(d.image,this.config):{}:(this.state="run:gender",n=T(),A=this.config.face.gender.enabled?await e1(d.image,this.config):{},this.perf.gender=Math.trunc(T()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?c1(d.image,this.config):{}:(this.state="run:emotion",n=T(),c=this.config.face.emotion.enabled?await c1(d.image,this.config):{},this.perf.emotion=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?h1(d.image,this.config):{}:(this.state="run:embedding",n=T(),_=this.config.face.embedding.enabled?await h1(d.image,this.config):{},this.perf.embedding=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((o=d==null?void 0:d.annotations)==null?void 0:o.leftEyeIris)&&((w=d==null?void 0:d.annotations)==null?void 0:w.rightEyeIris)&&(delete d.annotations.leftEyeIris,delete d.annotations.rightEyeIris);let Z=((a=d.annotations)==null?void 0:a.leftEyeIris)&&((y=d.annotations)==null?void 0:y.rightEyeIris)?11.7*Math.max(Math.abs(d.annotations.leftEyeIris[3][0]-d.annotations.leftEyeIris[1][0]),Math.abs(d.annotations.rightEyeIris[4][1]-d.annotations.rightEyeIris[2][1])):0;h.push({confidence:d.confidence,box:d.box,mesh:d.mesh,boxRaw:d.boxRaw,meshRaw:d.meshRaw,annotations:d.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:Z!==0?Math.trunc(Z)/100:0}),(f=d.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=ce(this.config,n);let r=W1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var a,y,f,d;this.state="config";let A;this.config=ce(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,s=T();await this.checkBackend(),await this.load(),this.config.scoped&&P.engine().startScope(),this.analyze("Start Scope:"),A=T();let o=W1(e,this.config);if(!o||!o.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(T()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=T(),x=this.config.face.enabled?await this.detectFace(o.tensor):[],this.perf.face=Math.trunc(T()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(a=this.models.posenet)==null?void 0:a.estimatePoses(o.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=T(),_=this.config.body.enabled?await((y=this.models.posenet)==null?void 0:y.estimatePoses(o.tensor,this.config)):[],this.perf.body=Math.trunc(T()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=T(),h=this.config.hand.enabled?await((d=this.models.handpose)==null?void 0:d.estimateHands(o.tensor,this.config)):[],this.perf.hand=Math.trunc(T()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),o.tensor.dispose(),this.config.scoped&&P.engine().endScope(),this.analyze("End Scope:");let w=[];this.config.gesture.enabled&&(A=T(),w=[...S0(x),...M0(_),...N0(h),...W0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(T()-A)),this.perf.total=Math.trunc(T()-s),this.state="idle",r({face:x,body:_,hand:h,gesture:w,performance:this.perf,canvas:o.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(ze);break;case"full":n=await e(Me);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+ze;break;case"full":r=1200,n="data:image/jpeg;base64,"+Me;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(ze):e(Me),r=P.node.decodeJpeg(n),A=r.expandDims(0);P.dispose(r);let c=await this.detect(A,this.config);return P.dispose(A),c}async warmup(e){let n=T();e&&(this.config=ce(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=T();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}}; +2Q==`;var N1={};B(N1,{author:()=>q0,browser:()=>F0,bugs:()=>Y0,default:()=>i5,dependencies:()=>D0,description:()=>X0,devDependencies:()=>G0,engines:()=>U0,homepage:()=>B0,keywords:()=>$0,license:()=>J0,main:()=>k0,module:()=>H0,name:()=>V0,peerDependencies:()=>C0,repository:()=>K0,scripts:()=>Q0,sideEffects:()=>L0,version:()=>j1});var V0="@vladmandic/human",j1="0.20.3",X0="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",L0=!1,k0="dist/human.node.js",H0="dist/human.esm.js",F0="dist/human.esm.js",q0="Vladimir Mandic ",Y0={url:"https://github.com/vladmandic/human/issues"},B0="https://github.com/vladmandic/human#readme",J0="MIT",U0={node:">=12.0.0"},K0={type:"git",url:"git+https://github.com/vladmandic/human.git"},D0={},C0={},G0={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},Q0={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},$0=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],i5={name:V0,version:j1,description:X0,sideEffects:L0,main:k0,module:H0,browser:F0,author:q0,bugs:Y0,homepage:B0,license:J0,engines:U0,repository:K0,dependencies:D0,peerDependencies:C0,devDependencies:G0,scripts:Q0,keywords:$0};var T=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function ce(...t){let e=n=>n&&typeof n=="object";return t.reduce((n,r)=>(Object.keys(r||{}).forEach(A=>{let c=n[A],_=r[A];Array.isArray(c)&&Array.isArray(_)?n[A]=c.concat(..._):e(c)&&e(_)?n[A]=ce(c,_):n[A]=_}),n),{})}var tt=class{constructor(e={}){this.tf=P,this.package=N1,this.version=j1,this.config=ce(Z0,e),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=et,this.age=Je,this.gender=De,this.emotion=t1,this.body=u1,this.hand=R1}profile(){return this.config.profile?qe:{}}analyze(...e){if(!this.analyzeMemoryLeaks)return;let n=P.engine().state.numTensors,r=this.numTensors;this.numTensors=n;let A=n-r;A!==0&&u(...e,A)}sanity(e){if(!this.checkSanity)return null;if(!e)return"input is not defined";if(P.ENV.flags.IS_NODE&&!(e instanceof P.Tensor))return"input must be a tensor";try{P.getBackend()}catch(n){return"backend not loaded"}return null}simmilarity(e,n){return this.config.face.embedding.enabled?t0(e,n):0}async load(e=null){this.state="load";let n=T();e&&(this.config=ce(this.config,e)),this.firstRun&&(u(`version: ${this.version} TensorFlow/JS version: ${P.version_core}`),await this.checkBackend(!0),P.ENV.flags.IS_BROWSER&&(u("configuration:",this.config),u("tf flags:",P.ENV.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?Ye:et;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?Ue(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?$e(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?A1(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?_1(this.config):null),this.models.posenet||(this.config.body.enabled?b1(this.config):null),this.models.handpose||(this.config.hand.enabled?S1(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await Ue(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await $e(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await A1(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await _1(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await b1(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await S1(this.config))),this.firstRun&&(u("tf engine state:",P.engine().state.numBytes,"bytes",P.engine().state.numTensors,"tensors"),this.firstRun=!1);let A=Math.trunc(T()-n);A>(this.perf.load||0)&&(this.perf.load=A)}async checkBackend(e=!1){if(this.config.backend&&this.config.backend!==""&&e||P.getBackend()!==this.config.backend){let n=T();this.state="backend",u("setting backend:",this.config.backend),this.config.backend==="wasm"&&(u("settings wasm path:",this.config.wasmPath),P.setWasmPaths(this.config.wasmPath),await P.env().getAsync("WASM_HAS_SIMD_SUPPORT")||u("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&k1();try{await P.setBackend(this.config.backend)}catch(r){u("error: cannot set backend:",this.config.backend,r)}if(P.enableProdMode(),P.getBackend()==="webgl"){this.config.deallocate&&(u("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),P.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),P.ENV.set("WEBGL_FORCE_F16_TEXTURES",!0),P.ENV.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await P.backend().getGPGPUContext().gl;u(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await P.ready(),this.perf.backend=Math.trunc(T()-n)}}async detectFace(e){var s,o,w,a,y,f;let n,r,A,c,_,h=[];this.state="run:face",n=T();let x=await((s=this.models.face)==null?void 0:s.estimateFaces(e,this.config));this.perf.face=Math.trunc(T()-n);for(let d of x){if(this.analyze("Get Face"),!d.image||d.image.isDisposedInternal){u("Face object is disposed:",d.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?Ke(d.image,this.config):{}:(this.state="run:age",n=T(),r=this.config.face.age.enabled?await Ke(d.image,this.config):{},this.perf.age=Math.trunc(T()-n)),this.analyze("Start Gender:"),this.config.async?A=this.config.face.gender.enabled?e1(d.image,this.config):{}:(this.state="run:gender",n=T(),A=this.config.face.gender.enabled?await e1(d.image,this.config):{},this.perf.gender=Math.trunc(T()-n)),this.analyze("Start Emotion:"),this.config.async?c=this.config.face.emotion.enabled?c1(d.image,this.config):{}:(this.state="run:emotion",n=T(),c=this.config.face.emotion.enabled?await c1(d.image,this.config):{},this.perf.emotion=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?_=this.config.face.embedding.enabled?h1(d.image,this.config):{}:(this.state="run:embedding",n=T(),_=this.config.face.embedding.enabled?await h1(d.image,this.config):{},this.perf.embedding=Math.trunc(T()-n)),this.analyze("End Emotion:"),this.config.async&&([r,A,c,_]=await Promise.all([r,A,c,_])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((o=d==null?void 0:d.annotations)==null?void 0:o.leftEyeIris)&&((w=d==null?void 0:d.annotations)==null?void 0:w.rightEyeIris)&&(delete d.annotations.leftEyeIris,delete d.annotations.rightEyeIris);let Z=((a=d.annotations)==null?void 0:a.leftEyeIris)&&((y=d.annotations)==null?void 0:y.rightEyeIris)?11.7*Math.max(Math.abs(d.annotations.leftEyeIris[3][0]-d.annotations.leftEyeIris[1][0]),Math.abs(d.annotations.rightEyeIris[4][1]-d.annotations.rightEyeIris[2][1])):0;h.push({confidence:d.confidence,box:d.box,mesh:d.mesh,boxRaw:d.boxRaw,meshRaw:d.meshRaw,annotations:d.annotations,age:r.age,gender:A.gender,genderConfidence:A.confidence,emotion:c,embedding:_,iris:Z!==0?Math.trunc(Z)/100:0}),(f=d.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),h}async image(e,n={}){var A;this.state="image",this.config=ce(this.config,n);let r=W1(e,this.config);return(A=r==null?void 0:r.tensor)==null||A.dispose(),r==null?void 0:r.canvas}async detect(e,n={}){return new Promise(async r=>{var a,y,f,d;this.state="config";let A;this.config=ce(this.config,n),this.state="check";let c=this.sanity(e);c&&(u(c,e),r({error:c}));let _,h,x,s=T();await this.checkBackend(),await this.load(),this.config.scoped&&P.engine().startScope(),this.analyze("Start Scope:"),A=T();let o=W1(e,this.config);if(!o||!o.tensor){u("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(T()-A),this.analyze("Get Image:"),this.config.async?(x=this.config.face.enabled?this.detectFace(o.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",A=T(),x=this.config.face.enabled?await this.detectFace(o.tensor):[],this.perf.face=Math.trunc(T()-A)),this.analyze("Start Body:"),this.config.async?(_=this.config.body.enabled?(a=this.models.posenet)==null?void 0:a.estimatePoses(o.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",A=T(),_=this.config.body.enabled?await((y=this.models.posenet)==null?void 0:y.estimatePoses(o.tensor,this.config)):[],this.perf.body=Math.trunc(T()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(h=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(o.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",A=T(),h=this.config.hand.enabled?await((d=this.models.handpose)==null?void 0:d.estimateHands(o.tensor,this.config)):[],this.perf.hand=Math.trunc(T()-A)),this.analyze("End Hand:"),this.config.async&&([x,_,h]=await Promise.all([x,_,h])),o.tensor.dispose(),this.config.scoped&&P.engine().endScope(),this.analyze("End Scope:");let w=[];this.config.gesture.enabled&&(A=T(),w=[...S0(x),...M0(_),...N0(h),...W0(x)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(T()-A)),this.perf.total=Math.trunc(T()-s),this.state="idle",r({face:x,body:_,hand:h,gesture:w,performance:this.perf,canvas:o.canvas})})}async warmupBitmap(){let e=(A,c="application/octet-stream")=>fetch(`data:${c};base64,${A}`).then(_=>_.blob()),n,r;switch(this.config.warmup){case"face":n=await e(ze);break;case"full":n=await e(Me);break;default:n=null}if(n){let A=await createImageBitmap(n);r=await this.detect(A,this.config),A.close()}return r}async warmupCanvas(){return new Promise(e=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+ze;break;case"full":r=1200,n="data:image/jpeg;base64,"+Me;break;default:n=null}let A=new Image(r,r);A.onload=()=>{let c=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");c.width=r,c.height=r;let _=c.getContext("2d");_==null||_.drawImage(A,0,0);let h=_==null?void 0:_.getImageData(0,0,r,r);this.detect(h,this.config).then(x=>e(x))},n?A.src=n:e(null)})}async warmupNode(){let e=_=>Buffer.from(_,"base64"),n=this.config.warmup==="face"?e(ze):e(Me),r=P.node.decodeJpeg(n),A=r.expandDims(0);P.dispose(r);let c=await this.detect(A,this.config);return P.dispose(A),c}async warmup(e){let n=T();e&&(this.config=ce(this.config,e));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let A;typeof createImageBitmap=="function"?A=await this.warmupBitmap():typeof Image!="undefined"?A=await this.warmupCanvas():A=await this.warmupNode(),this.config.videoOptimized=r;let c=T();return u("Warmup",this.config.warmup,Math.round(c-n),"ms",A),A}}; //# sourceMappingURL=human.node.js.map diff --git a/dist/human.ts b/dist/human.ts index 09dcd015..f1f6082b 100644 --- a/dist/human.ts +++ b/dist/human.ts @@ -4771,7 +4771,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2 SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/ -2Q==`;var G2={};cr(G2,{author:()=>D6,browser:()=>$6,bugs:()=>z6,default:()=>Pae,dependencies:()=>V6,description:()=>R6,devDependencies:()=>j6,engines:()=>W6,homepage:()=>P6,keywords:()=>H6,license:()=>L6,main:()=>M6,module:()=>O6,name:()=>C6,peerDependencies:()=>U6,repository:()=>B6,scripts:()=>G6,sideEffects:()=>F6,version:()=>H2});var C6="@vladmandic/human",H2="0.20.2",R6="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",F6=!1,M6="dist/human.node.js",O6="dist/human.esm.js",$6="dist/human.esm.js",D6="Vladimir Mandic ",z6={url:"https://github.com/vladmandic/human/issues"},P6="https://github.com/vladmandic/human#readme",L6="MIT",W6={node:">=12.0.0"},B6={type:"git",url:"git+https://github.com/vladmandic/human.git"},V6={},U6={},j6={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},G6={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},H6=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],Pae={name:C6,version:H2,description:R6,sideEffects:F6,main:M6,module:O6,browser:$6,author:D6,bugs:z6,homepage:P6,license:L6,engines:W6,repository:B6,dependencies:V6,peerDependencies:U6,devDependencies:j6,scripts:G6,keywords:H6};var dt=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Dl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=Dl(s,i):n[a]=i}),n),{})}var q2=class{constructor(t={}){this.tf=lh,this.package=G2,this.version=H2,this.config=Dl(E6,t),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=q6,this.age=i2,this.gender=u2,this.emotion=m2,this.body=M2,this.hand=W2}profile(){return this.config.profile?r2:{}}analyze(...t){if(!this.analyzeMemoryLeaks)return;let n=dn().state.numTensors,r=this.numTensors;this.numTensors=n;let a=n-r;a!==0&&Te(...t,a)}sanity(t){if(!this.checkSanity)return null;if(!t)return"input is not defined";if(nn.flags.IS_NODE&&!(t instanceof Xe))return"input must be a tensor";try{nd()}catch(n){return"backend not loaded"}return null}simmilarity(t,n){return this.config.face.embedding.enabled?Yv(t,n):0}async load(t=null){this.state="load";let n=dt();t&&(this.config=Dl(this.config,t)),this.firstRun&&(Te(`version: ${this.version} TensorFlow/JS version: ${c5}`),await this.checkBackend(!0),nn.flags.IS_BROWSER&&(Te("configuration:",this.config),Te("tf flags:",nn.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?a2:q6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?o2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?p2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?g2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?w2(this.config):null),this.models.posenet||(this.config.body.enabled?$2(this.config):null),this.models.handpose||(this.config.hand.enabled?U2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await o2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await p2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await g2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await w2(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await $2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await U2(this.config))),this.firstRun&&(Te("tf engine state:",dn().state.numBytes,"bytes",dn().state.numTensors,"tensors"),this.firstRun=!1);let a=Math.trunc(dt()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async checkBackend(t=!1){if(this.config.backend&&this.config.backend!==""&&t||nd()!==this.config.backend){let n=dt();this.state="backend",Te("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Te("settings wasm path:",this.config.wasmPath),qb(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Te("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&zv();try{await d5(this.config.backend)}catch(r){Te("error: cannot set backend:",this.config.backend,r)}if(h5(),nd()==="webgl"){this.config.deallocate&&(Te("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),nn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),nn.set("WEBGL_FORCE_F16_TEXTURES",!0),nn.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await hf().getGPGPUContext().gl;Te(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await p5(),this.perf.backend=Math.trunc(dt()-n)}}async detectFace(t){var c,u,h,p,d,f;let n,r,a,s,i,o=[];this.state="run:face",n=dt();let l=await((c=this.models.face)==null?void 0:c.estimateFaces(t,this.config));this.perf.face=Math.trunc(dt()-n);for(let m of l){if(this.analyze("Get Face"),!m.image||m.image.isDisposedInternal){Te("Face object is disposed:",m.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?l2(m.image,this.config):{}:(this.state="run:age",n=dt(),r=this.config.face.age.enabled?await l2(m.image,this.config):{},this.perf.age=Math.trunc(dt()-n)),this.analyze("Start Gender:"),this.config.async?a=this.config.face.gender.enabled?f2(m.image,this.config):{}:(this.state="run:gender",n=dt(),a=this.config.face.gender.enabled?await f2(m.image,this.config):{},this.perf.gender=Math.trunc(dt()-n)),this.analyze("Start Emotion:"),this.config.async?s=this.config.face.emotion.enabled?x2(m.image,this.config):{}:(this.state="run:emotion",n=dt(),s=this.config.face.emotion.enabled?await x2(m.image,this.config):{},this.perf.emotion=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?i=this.config.face.embedding.enabled?_2(m.image,this.config):{}:(this.state="run:embedding",n=dt(),i=this.config.face.embedding.enabled?await _2(m.image,this.config):{},this.perf.embedding=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.config.async&&([r,a,s,i]=await Promise.all([r,a,s,i])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((u=m==null?void 0:m.annotations)==null?void 0:u.leftEyeIris)&&((h=m==null?void 0:m.annotations)==null?void 0:h.rightEyeIris)&&(delete m.annotations.leftEyeIris,delete m.annotations.rightEyeIris);let A=((p=m.annotations)==null?void 0:p.leftEyeIris)&&((d=m.annotations)==null?void 0:d.rightEyeIris)?11.7*Math.max(Math.abs(m.annotations.leftEyeIris[3][0]-m.annotations.leftEyeIris[1][0]),Math.abs(m.annotations.rightEyeIris[4][1]-m.annotations.rightEyeIris[2][1])):0;o.push({confidence:m.confidence,box:m.box,mesh:m.mesh,boxRaw:m.boxRaw,meshRaw:m.meshRaw,annotations:m.annotations,age:r.age,gender:a.gender,genderConfidence:a.confidence,emotion:s,embedding:i,iris:A!==0?Math.trunc(A)/100:0}),(f=m.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),o}async image(t,n={}){var a;this.state="image",this.config=Dl(this.config,n);let r=j2(t,this.config);return(a=r==null?void 0:r.tensor)==null||a.dispose(),r==null?void 0:r.canvas}async detect(t,n={}){return new Promise(async r=>{var p,d,f,m;this.state="config";let a;this.config=Dl(this.config,n),this.state="check";let s=this.sanity(t);s&&(Te(s,t),r({error:s}));let i,o,l,c=dt();await this.checkBackend(),await this.load(),this.config.scoped&&dn().startScope(),this.analyze("Start Scope:"),a=dt();let u=j2(t,this.config);if(!u||!u.tensor){Te("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(dt()-a),this.analyze("Get Image:"),this.config.async?(l=this.config.face.enabled?this.detectFace(u.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=dt(),l=this.config.face.enabled?await this.detectFace(u.tensor):[],this.perf.face=Math.trunc(dt()-a)),this.analyze("Start Body:"),this.config.async?(i=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(u.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",a=dt(),i=this.config.body.enabled?await((d=this.models.posenet)==null?void 0:d.estimatePoses(u.tensor,this.config)):[],this.perf.body=Math.trunc(dt()-a)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(o=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(u.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=dt(),o=this.config.hand.enabled?await((m=this.models.handpose)==null?void 0:m.estimateHands(u.tensor,this.config)):[],this.perf.hand=Math.trunc(dt()-a)),this.analyze("End Hand:"),this.config.async&&([l,i,o]=await Promise.all([l,i,o])),u.tensor.dispose(),this.config.scoped&&dn().endScope(),this.analyze("End Scope:");let h=[];this.config.gesture.enabled&&(a=dt(),h=[...v6(l),...b6(i),...I6(o),...k6(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(dt()-a)),this.perf.total=Math.trunc(dt()-c),this.state="idle",r({face:l,body:i,hand:o,gesture:h,performance:this.perf,canvas:u.canvas})})}async warmupBitmap(){let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(f0);break;case"full":n=await t(m0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r}async warmupCanvas(){return new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+f0;break;case"full":r=1200,n="data:image/jpeg;base64,"+m0;break;default:n=null}let a=new Image(r,r);a.onload=()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=r,s.height=r;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=i==null?void 0:i.getImageData(0,0,r,r);this.detect(o,this.config).then(l=>t(l))},n?a.src=n:t(null)})}async warmupNode(){let t=i=>Buffer.from(i,"base64"),n=this.config.warmup==="face"?t(f0):t(m0),r=(void 0).decodeJpeg(n),a=r.expandDims(0);Ne(r);let s=await this.detect(a,this.config);return Ne(a),s}async warmup(t){let n=dt();t&&(this.config=Dl(this.config,t));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await this.warmupBitmap():typeof Image!="undefined"?a=await this.warmupCanvas():a=await this.warmupNode(),this.config.videoOptimized=r;let s=dt();return Te("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};return Lae;})(); +2Q==`;var G2={};cr(G2,{author:()=>D6,browser:()=>$6,bugs:()=>z6,default:()=>Pae,dependencies:()=>V6,description:()=>R6,devDependencies:()=>j6,engines:()=>W6,homepage:()=>P6,keywords:()=>H6,license:()=>L6,main:()=>M6,module:()=>O6,name:()=>C6,peerDependencies:()=>U6,repository:()=>B6,scripts:()=>G6,sideEffects:()=>F6,version:()=>H2});var C6="@vladmandic/human",H2="0.20.3",R6="Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition",F6=!1,M6="dist/human.node.js",O6="dist/human.esm.js",$6="dist/human.esm.js",D6="Vladimir Mandic ",z6={url:"https://github.com/vladmandic/human/issues"},P6="https://github.com/vladmandic/human#readme",L6="MIT",W6={node:">=12.0.0"},B6={type:"git",url:"git+https://github.com/vladmandic/human.git"},V6={},U6={},j6={"@tensorflow/tfjs":"^3.1.0","@tensorflow/tfjs-backend-cpu":"^3.1.0","@tensorflow/tfjs-backend-wasm":"^3.1.0","@tensorflow/tfjs-backend-webgl":"^3.1.0","@tensorflow/tfjs-converter":"^3.1.0","@tensorflow/tfjs-core":"^3.1.0","@tensorflow/tfjs-data":"^3.1.0","@tensorflow/tfjs-layers":"^3.1.0","@tensorflow/tfjs-node":"^3.1.0","@tensorflow/tfjs-node-gpu":"^3.1.0","@types/node":"^14.14.28","@typescript-eslint/eslint-plugin":"^4.15.1","@typescript-eslint/parser":"^4.15.1","@vladmandic/pilogger":"^0.2.14",chokidar:"^3.5.1",dayjs:"^1.10.4",esbuild:"^0.8.46",eslint:"^7.20.0","eslint-config-airbnb-base":"^14.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-json":"^2.1.2","eslint-plugin-node":"^11.1.0","eslint-plugin-promise":"^4.3.1",rimraf:"^3.0.2",seedrandom:"^3.0.5","simple-git":"^2.35.0",tslib:"^2.1.0",typescript:"^4.3.0-dev.20210217"},G6={start:"node --trace-warnings --unhandled-rejections=strict --trace-uncaught --no-deprecation src/node.js",lint:"eslint src demo server",dev:"npm install && node server/serve.js",build:"rimraf dist/* && rimraf types/* && node server/build.js && node server/changelog.js",update:"npm update --depth 20 --force && npm dedupe && npm prune && npm audit"},H6=["tensorflowjs","face-detection","face-geometry","face-embedding","face-recognition","body-tracking","hand-tracking","iris-tracking","age-estimation","emotion-detection","gender-prediction","gesture-recognition"],Pae={name:C6,version:H2,description:R6,sideEffects:F6,main:M6,module:O6,browser:$6,author:D6,bugs:z6,homepage:P6,license:L6,engines:W6,repository:B6,dependencies:V6,peerDependencies:U6,devDependencies:j6,scripts:G6,keywords:H6};var dt=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Dl(...e){let t=n=>n&&typeof n=="object";return e.reduce((n,r)=>(Object.keys(r||{}).forEach(a=>{let s=n[a],i=r[a];Array.isArray(s)&&Array.isArray(i)?n[a]=s.concat(...i):t(s)&&t(i)?n[a]=Dl(s,i):n[a]=i}),n),{})}var q2=class{constructor(t={}){this.tf=lh,this.package=G2,this.version=H2,this.config=Dl(E6,t),this.fx=null,this.state="idle",this.numTensors=0,this.analyzeMemoryLeaks=!1,this.checkSanity=!1,this.firstRun=!0,this.perf={},this.models={facemesh:null,posenet:null,handpose:null,iris:null,age:null,gender:null,emotion:null},this.facemesh=q6,this.age=i2,this.gender=u2,this.emotion=m2,this.body=M2,this.hand=W2}profile(){return this.config.profile?r2:{}}analyze(...t){if(!this.analyzeMemoryLeaks)return;let n=dn().state.numTensors,r=this.numTensors;this.numTensors=n;let a=n-r;a!==0&&Te(...t,a)}sanity(t){if(!this.checkSanity)return null;if(!t)return"input is not defined";if(nn.flags.IS_NODE&&!(t instanceof Xe))return"input must be a tensor";try{nd()}catch(n){return"backend not loaded"}return null}simmilarity(t,n){return this.config.face.embedding.enabled?Yv(t,n):0}async load(t=null){this.state="load";let n=dt();t&&(this.config=Dl(this.config,t)),this.firstRun&&(Te(`version: ${this.version} TensorFlow/JS version: ${c5}`),await this.checkBackend(!0),nn.flags.IS_BROWSER&&(Te("configuration:",this.config),Te("tf flags:",nn.flags)));let r=this.config.face.detector.modelPath.includes("faceboxes")?a2:q6;this.config.async?[this.models.face,this.models.age,this.models.gender,this.models.emotion,this.models.embedding,this.models.posenet,this.models.handpose]=await Promise.all([this.models.face||(this.config.face.enabled?r.load(this.config):null),this.models.age||(this.config.face.enabled&&this.config.face.age.enabled?o2(this.config):null),this.models.gender||(this.config.face.enabled&&this.config.face.gender.enabled?p2(this.config):null),this.models.emotion||(this.config.face.enabled&&this.config.face.emotion.enabled?g2(this.config):null),this.models.embedding||(this.config.face.enabled&&this.config.face.embedding.enabled?w2(this.config):null),this.models.posenet||(this.config.body.enabled?$2(this.config):null),this.models.handpose||(this.config.hand.enabled?U2(this.config):null)]):(this.config.face.enabled&&!this.models.face&&(this.models.face=await r.load(this.config)),this.config.face.enabled&&this.config.face.age.enabled&&!this.models.age&&(this.models.age=await o2(this.config)),this.config.face.enabled&&this.config.face.gender.enabled&&!this.models.gender&&(this.models.gender=await p2(this.config)),this.config.face.enabled&&this.config.face.emotion.enabled&&!this.models.emotion&&(this.models.emotion=await g2(this.config)),this.config.face.enabled&&this.config.face.embedding.enabled&&!this.models.embedding&&(this.models.embedding=await w2(this.config)),this.config.body.enabled&&!this.models.posenet&&(this.models.posenet=await $2(this.config)),this.config.hand.enabled&&!this.models.handpose&&(this.models.handpose=await U2(this.config))),this.firstRun&&(Te("tf engine state:",dn().state.numBytes,"bytes",dn().state.numTensors,"tensors"),this.firstRun=!1);let a=Math.trunc(dt()-n);a>(this.perf.load||0)&&(this.perf.load=a)}async checkBackend(t=!1){if(this.config.backend&&this.config.backend!==""&&t||nd()!==this.config.backend){let n=dt();this.state="backend",Te("setting backend:",this.config.backend),this.config.backend==="wasm"&&(Te("settings wasm path:",this.config.wasmPath),qb(this.config.wasmPath),await Q().getAsync("WASM_HAS_SIMD_SUPPORT")||Te("warning: wasm simd support is not enabled")),this.config.backend==="humangl"&&zv();try{await d5(this.config.backend)}catch(r){Te("error: cannot set backend:",this.config.backend,r)}if(h5(),nd()==="webgl"){this.config.deallocate&&(Te("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",this.config.deallocate),nn.set("WEBGL_DELETE_TEXTURE_THRESHOLD",this.config.deallocate?0:-1)),nn.set("WEBGL_FORCE_F16_TEXTURES",!0),nn.set("WEBGL_PACK_DEPTHWISECONV",!0);let r=await hf().getGPGPUContext().gl;Te(`gl version:${r.getParameter(r.VERSION)} renderer:${r.getParameter(r.RENDERER)}`)}await p5(),this.perf.backend=Math.trunc(dt()-n)}}async detectFace(t){var c,u,h,p,d,f;let n,r,a,s,i,o=[];this.state="run:face",n=dt();let l=await((c=this.models.face)==null?void 0:c.estimateFaces(t,this.config));this.perf.face=Math.trunc(dt()-n);for(let m of l){if(this.analyze("Get Face"),!m.image||m.image.isDisposedInternal){Te("Face object is disposed:",m.image);continue}this.analyze("Start Age:"),this.config.async?r=this.config.face.age.enabled?l2(m.image,this.config):{}:(this.state="run:age",n=dt(),r=this.config.face.age.enabled?await l2(m.image,this.config):{},this.perf.age=Math.trunc(dt()-n)),this.analyze("Start Gender:"),this.config.async?a=this.config.face.gender.enabled?f2(m.image,this.config):{}:(this.state="run:gender",n=dt(),a=this.config.face.gender.enabled?await f2(m.image,this.config):{},this.perf.gender=Math.trunc(dt()-n)),this.analyze("Start Emotion:"),this.config.async?s=this.config.face.emotion.enabled?x2(m.image,this.config):{}:(this.state="run:emotion",n=dt(),s=this.config.face.emotion.enabled?await x2(m.image,this.config):{},this.perf.emotion=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.analyze("Start Embedding:"),this.config.async?i=this.config.face.embedding.enabled?_2(m.image,this.config):{}:(this.state="run:embedding",n=dt(),i=this.config.face.embedding.enabled?await _2(m.image,this.config):{},this.perf.embedding=Math.trunc(dt()-n)),this.analyze("End Emotion:"),this.config.async&&([r,a,s,i]=await Promise.all([r,a,s,i])),this.analyze("Finish Face:"),!this.config.face.iris.enabled&&((u=m==null?void 0:m.annotations)==null?void 0:u.leftEyeIris)&&((h=m==null?void 0:m.annotations)==null?void 0:h.rightEyeIris)&&(delete m.annotations.leftEyeIris,delete m.annotations.rightEyeIris);let A=((p=m.annotations)==null?void 0:p.leftEyeIris)&&((d=m.annotations)==null?void 0:d.rightEyeIris)?11.7*Math.max(Math.abs(m.annotations.leftEyeIris[3][0]-m.annotations.leftEyeIris[1][0]),Math.abs(m.annotations.rightEyeIris[4][1]-m.annotations.rightEyeIris[2][1])):0;o.push({confidence:m.confidence,box:m.box,mesh:m.mesh,boxRaw:m.boxRaw,meshRaw:m.meshRaw,annotations:m.annotations,age:r.age,gender:a.gender,genderConfidence:a.confidence,emotion:s,embedding:i,iris:A!==0?Math.trunc(A)/100:0}),(f=m.image)==null||f.dispose(),this.analyze("End Face")}return this.analyze("End FaceMesh:"),this.config.async&&(this.perf.face&&delete this.perf.face,this.perf.age&&delete this.perf.age,this.perf.gender&&delete this.perf.gender,this.perf.emotion&&delete this.perf.emotion),o}async image(t,n={}){var a;this.state="image",this.config=Dl(this.config,n);let r=j2(t,this.config);return(a=r==null?void 0:r.tensor)==null||a.dispose(),r==null?void 0:r.canvas}async detect(t,n={}){return new Promise(async r=>{var p,d,f,m;this.state="config";let a;this.config=Dl(this.config,n),this.state="check";let s=this.sanity(t);s&&(Te(s,t),r({error:s}));let i,o,l,c=dt();await this.checkBackend(),await this.load(),this.config.scoped&&dn().startScope(),this.analyze("Start Scope:"),a=dt();let u=j2(t,this.config);if(!u||!u.tensor){Te("could not convert input to tensor"),r({error:"could not convert input to tensor"});return}this.perf.image=Math.trunc(dt()-a),this.analyze("Get Image:"),this.config.async?(l=this.config.face.enabled?this.detectFace(u.tensor):[],this.perf.face&&delete this.perf.face):(this.state="run:face",a=dt(),l=this.config.face.enabled?await this.detectFace(u.tensor):[],this.perf.face=Math.trunc(dt()-a)),this.analyze("Start Body:"),this.config.async?(i=this.config.body.enabled?(p=this.models.posenet)==null?void 0:p.estimatePoses(u.tensor,this.config):[],this.perf.body&&delete this.perf.body):(this.state="run:body",a=dt(),i=this.config.body.enabled?await((d=this.models.posenet)==null?void 0:d.estimatePoses(u.tensor,this.config)):[],this.perf.body=Math.trunc(dt()-a)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.config.async?(o=this.config.hand.enabled?(f=this.models.handpose)==null?void 0:f.estimateHands(u.tensor,this.config):[],this.perf.hand&&delete this.perf.hand):(this.state="run:hand",a=dt(),o=this.config.hand.enabled?await((m=this.models.handpose)==null?void 0:m.estimateHands(u.tensor,this.config)):[],this.perf.hand=Math.trunc(dt()-a)),this.analyze("End Hand:"),this.config.async&&([l,i,o]=await Promise.all([l,i,o])),u.tensor.dispose(),this.config.scoped&&dn().endScope(),this.analyze("End Scope:");let h=[];this.config.gesture.enabled&&(a=dt(),h=[...v6(l),...b6(i),...I6(o),...k6(l)],this.config.async?this.perf.gesture&&delete this.perf.gesture:this.perf.gesture=Math.trunc(dt()-a)),this.perf.total=Math.trunc(dt()-c),this.state="idle",r({face:l,body:i,hand:o,gesture:h,performance:this.perf,canvas:u.canvas})})}async warmupBitmap(){let t=(a,s="application/octet-stream")=>fetch(`data:${s};base64,${a}`).then(i=>i.blob()),n,r;switch(this.config.warmup){case"face":n=await t(f0);break;case"full":n=await t(m0);break;default:n=null}if(n){let a=await createImageBitmap(n);r=await this.detect(a,this.config),a.close()}return r}async warmupCanvas(){return new Promise(t=>{let n,r=0;switch(this.config.warmup){case"face":r=256,n="data:image/jpeg;base64,"+f0;break;case"full":r=1200,n="data:image/jpeg;base64,"+m0;break;default:n=null}let a=new Image(r,r);a.onload=()=>{let s=typeof OffscreenCanvas!="undefined"?new OffscreenCanvas(r,r):document.createElement("canvas");s.width=r,s.height=r;let i=s.getContext("2d");i==null||i.drawImage(a,0,0);let o=i==null?void 0:i.getImageData(0,0,r,r);this.detect(o,this.config).then(l=>t(l))},n?a.src=n:t(null)})}async warmupNode(){let t=i=>Buffer.from(i,"base64"),n=this.config.warmup==="face"?t(f0):t(m0),r=(void 0).decodeJpeg(n),a=r.expandDims(0);Ne(r);let s=await this.detect(a,this.config);return Ne(a),s}async warmup(t){let n=dt();t&&(this.config=Dl(this.config,t));let r=this.config.videoOptimized;this.config.videoOptimized=!1;let a;typeof createImageBitmap=="function"?a=await this.warmupBitmap():typeof Image!="undefined"?a=await this.warmupCanvas():a=await this.warmupNode(),this.config.videoOptimized=r;let s=dt();return Te("Warmup",this.config.warmup,Math.round(s-n),"ms",a),a}};return Lae;})(); /** * @license * Copyright 2017 Google LLC. All Rights Reserved. diff --git a/wiki b/wiki index b7cfba49..245c26d9 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b7cfba497d975a86b558a7eeb612ad453b21b5d3 +Subproject commit 245c26d973519aa5653a9869c52aa42ccaf5f6ed