pull/356/head
Vladimir Mandic 2022-04-01 09:13:32 -04:00
parent 898866f94a
commit ccd2f8e244
7 changed files with 718 additions and 1191 deletions

View File

@ -1,6 +1,6 @@
# @vladmandic/human
Version: **2.6.4**
Version: **2.6.5**
Description: **Human: AI-powered 3D Face Detection & Rotation Tracking, Face Description & Recognition, Body Pose Tracking, 3D Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction, Gesture Recognition**
Author: **Vladimir Mandic <mandic00@live.com>**
@ -9,8 +9,10 @@
## Changelog
### **HEAD -> main** 2022/03/19 mandic00@live.com
### **2.6.5** 2022/04/01 mandic00@live.com
- bundle offscreencanvas types
- prototype precompile pass
### **origin/main** 2022/03/16 mandic00@live.com

View File

@ -4,329 +4,8 @@
author: <https://github.com/vladmandic>'
*/
// demo/faceid/index.ts
import { Human } from "../../dist/human.esm.js";
// demo/faceid/indexdb.ts
var db;
var database = "human";
var table = "person";
var log = (...msg) => console.log("indexdb", ...msg);
async function open() {
if (db)
return true;
return new Promise((resolve) => {
const request = indexedDB.open(database, 1);
request.onerror = (evt) => log("error:", evt);
request.onupgradeneeded = (evt) => {
log("create:", evt.target);
db = evt.target.result;
db.createObjectStore(table, { keyPath: "id", autoIncrement: true });
};
request.onsuccess = (evt) => {
db = evt.target.result;
log("open:", db);
resolve(true);
};
});
}
async function load() {
const faceDB = [];
if (!db)
await open();
return new Promise((resolve) => {
const cursor = db.transaction([table], "readwrite").objectStore(table).openCursor(null, "next");
cursor.onerror = (evt) => log("load error:", evt);
cursor.onsuccess = (evt) => {
if (evt.target.result) {
faceDB.push(evt.target.result.value);
evt.target.result.continue();
} else {
resolve(faceDB);
}
};
});
}
async function count() {
if (!db)
await open();
return new Promise((resolve) => {
const store = db.transaction([table], "readwrite").objectStore(table).count();
store.onerror = (evt) => log("count error:", evt);
store.onsuccess = () => resolve(store.result);
});
}
async function save(faceRecord) {
if (!db)
await open();
const newRecord = { name: faceRecord.name, descriptor: faceRecord.descriptor, image: faceRecord.image };
db.transaction([table], "readwrite").objectStore(table).put(newRecord);
log("save:", newRecord);
}
async function remove(faceRecord) {
if (!db)
await open();
db.transaction([table], "readwrite").objectStore(table).delete(faceRecord.id);
log("delete:", faceRecord);
}
// demo/faceid/index.ts
var humanConfig = {
modelBasePath: "../../models",
filter: { equalization: true },
face: {
enabled: true,
detector: { rotation: true, return: true, cropFactor: 1.6, mask: false },
description: { enabled: true },
mobilefacenet: { enabled: false, modelPath: "https://vladmandic.github.io/human-models/models/mobilefacenet.json" },
iris: { enabled: true },
emotion: { enabled: false },
antispoof: { enabled: true },
liveness: { enabled: true }
},
body: { enabled: false },
hand: { enabled: false },
object: { enabled: false },
gesture: { enabled: true }
};
var matchOptions = { order: 2, multiplier: 25, min: 0.2, max: 0.8 };
var options = {
minConfidence: 0.6,
minSize: 224,
maxTime: 1e4,
blinkMin: 10,
blinkMax: 800,
threshold: 0.5,
mask: humanConfig.face.detector.mask,
rotation: humanConfig.face.detector.rotation,
cropFactor: humanConfig.face.detector.cropFactor,
...matchOptions
};
var ok = {
faceCount: false,
faceConfidence: false,
facingCenter: false,
lookingCenter: false,
blinkDetected: false,
faceSize: false,
antispoofCheck: false,
livenessCheck: false,
elapsedMs: 0
};
var allOk = () => ok.faceCount && ok.faceSize && ok.blinkDetected && ok.facingCenter && ok.lookingCenter && ok.faceConfidence && ok.antispoofCheck && ok.livenessCheck;
var current = { face: null, record: null };
var blink = {
start: 0,
end: 0,
time: 0
};
var human = new Human(humanConfig);
human.env["perfadd"] = false;
human.draw.options.font = 'small-caps 18px "Lato"';
human.draw.options.lineHeight = 20;
var dom = {
video: document.getElementById("video"),
canvas: document.getElementById("canvas"),
log: document.getElementById("log"),
fps: document.getElementById("fps"),
match: document.getElementById("match"),
name: document.getElementById("name"),
save: document.getElementById("save"),
delete: document.getElementById("delete"),
retry: document.getElementById("retry"),
source: document.getElementById("source"),
ok: document.getElementById("ok")
};
var timestamp = { detect: 0, draw: 0 };
var fps = { detect: 0, draw: 0 };
var startTime = 0;
var log2 = (...msg) => {
dom.log.innerText += msg.join(" ") + "\n";
console.log(...msg);
};
var printFPS = (msg) => dom.fps.innerText = msg;
async function webCam() {
printFPS("starting webcam...");
const cameraOptions = { audio: false, video: { facingMode: "user", resizeMode: "none", width: { ideal: document.body.clientWidth } } };
const stream = await navigator.mediaDevices.getUserMedia(cameraOptions);
const ready = new Promise((resolve) => {
dom.video.onloadeddata = () => resolve(true);
});
dom.video.srcObject = stream;
dom.video.play();
await ready;
dom.canvas.width = dom.video.videoWidth;
dom.canvas.height = dom.video.videoHeight;
if (human.env.initial)
log2("video:", dom.video.videoWidth, dom.video.videoHeight, "|", stream.getVideoTracks()[0].label);
dom.canvas.onclick = () => {
if (dom.video.paused)
dom.video.play();
else
dom.video.pause();
};
}
async function detectionLoop() {
if (!dom.video.paused) {
if (current.face && current.face.tensor)
human.tf.dispose(current.face.tensor);
await human.detect(dom.video);
const now = human.now();
fps.detect = 1e3 / (now - timestamp.detect);
timestamp.detect = now;
requestAnimationFrame(detectionLoop);
}
}
async function validationLoop() {
const interpolated = await human.next(human.result);
await human.draw.canvas(dom.video, dom.canvas);
await human.draw.all(dom.canvas, interpolated);
const now = human.now();
fps.draw = 1e3 / (now - timestamp.draw);
timestamp.draw = now;
printFPS(`fps: ${fps.detect.toFixed(1).padStart(5, " ")} detect | ${fps.draw.toFixed(1).padStart(5, " ")} draw`);
ok.faceCount = human.result.face.length === 1;
if (ok.faceCount) {
const gestures = Object.values(human.result.gesture).map((gesture) => gesture.gesture);
if (gestures.includes("blink left eye") || gestures.includes("blink right eye"))
blink.start = human.now();
if (blink.start > 0 && !gestures.includes("blink left eye") && !gestures.includes("blink right eye"))
blink.end = human.now();
ok.blinkDetected = ok.blinkDetected || Math.abs(blink.end - blink.start) > options.blinkMin && Math.abs(blink.end - blink.start) < options.blinkMax;
if (ok.blinkDetected && blink.time === 0)
blink.time = Math.trunc(blink.end - blink.start);
ok.facingCenter = gestures.includes("facing center");
ok.lookingCenter = gestures.includes("looking center");
ok.faceConfidence = (human.result.face[0].boxScore || 0) > options.minConfidence && (human.result.face[0].faceScore || 0) > options.minConfidence && (human.result.face[0].genderScore || 0) > options.minConfidence;
ok.antispoofCheck = (human.result.face[0].real || 0) > options.minConfidence;
ok.livenessCheck = (human.result.face[0].live || 0) > options.minConfidence;
ok.faceSize = human.result.face[0].box[2] >= options.minSize && human.result.face[0].box[3] >= options.minSize;
}
let y = 32;
for (const [key, val] of Object.entries(ok)) {
let el = document.getElementById(`ok-${key}`);
if (!el) {
el = document.createElement("div");
el.innerText = key;
el.className = "ok";
el.style.top = `${y}px`;
dom.ok.appendChild(el);
}
if (typeof val === "boolean")
el.style.backgroundColor = val ? "lightgreen" : "lightcoral";
else
el.innerText = `${key}:${val}`;
y += 28;
}
if (allOk()) {
dom.video.pause();
return human.result.face[0];
}
if (ok.elapsedMs > options.maxTime) {
dom.video.pause();
return human.result.face[0];
} else {
ok.elapsedMs = Math.trunc(human.now() - startTime);
return new Promise((resolve) => {
setTimeout(async () => {
const res = await validationLoop();
if (res)
resolve(human.result.face[0]);
}, 30);
});
}
}
async function saveRecords() {
var _a, _b;
if (dom.name.value.length > 0) {
const image = (_a = dom.canvas.getContext("2d")) == null ? void 0 : _a.getImageData(0, 0, dom.canvas.width, dom.canvas.height);
const rec = { id: 0, name: dom.name.value, descriptor: (_b = current.face) == null ? void 0 : _b.embedding, image };
await save(rec);
log2("saved face record:", rec.name);
} else {
log2("invalid name");
}
}
async function deleteRecord() {
if (current.record && current.record.id > 0) {
await remove(current.record);
}
}
async function detectFace() {
var _a, _b;
(_a = dom.canvas.getContext("2d")) == null ? void 0 : _a.clearRect(0, 0, options.minSize, options.minSize);
if (!current.face || !current.face.tensor || !current.face.embedding)
return false;
console.log("face record:", current.face);
human.tf.browser.toPixels(current.face.tensor, dom.canvas);
if (await count() === 0) {
log2("face database is empty");
document.body.style.background = "black";
dom.delete.style.display = "none";
return false;
}
const db2 = await load();
const descriptors = db2.map((rec) => rec.descriptor);
const res = await human.match(current.face.embedding, descriptors, matchOptions);
current.record = db2[res.index] || null;
if (current.record) {
log2(`best match: ${current.record.name} | id: ${current.record.id} | similarity: ${Math.round(1e3 * res.similarity) / 10}%`);
dom.name.value = current.record.name;
dom.source.style.display = "";
(_b = dom.source.getContext("2d")) == null ? void 0 : _b.putImageData(current.record.image, 0, 0);
}
document.body.style.background = res.similarity > options.threshold ? "darkgreen" : "maroon";
return res.similarity > options.threshold;
}
async function main() {
var _a, _b, _c, _d;
ok.faceCount = false;
ok.faceConfidence = false;
ok.facingCenter = false;
ok.blinkDetected = false;
ok.faceSize = false;
ok.antispoofCheck = false;
ok.livenessCheck = false;
ok.elapsedMs = 0;
dom.match.style.display = "none";
dom.retry.style.display = "none";
dom.source.style.display = "none";
document.body.style.background = "black";
await webCam();
await detectionLoop();
startTime = human.now();
current.face = await validationLoop();
dom.canvas.width = ((_b = (_a = current.face) == null ? void 0 : _a.tensor) == null ? void 0 : _b.shape[1]) || options.minSize;
dom.canvas.height = ((_d = (_c = current.face) == null ? void 0 : _c.tensor) == null ? void 0 : _d.shape[0]) || options.minSize;
dom.source.width = dom.canvas.width;
dom.source.height = dom.canvas.height;
dom.canvas.style.width = "";
dom.match.style.display = "flex";
dom.save.style.display = "flex";
dom.delete.style.display = "flex";
dom.retry.style.display = "block";
if (!allOk()) {
log2("did not find valid face");
return false;
} else {
return detectFace();
}
}
async function init() {
log2("human version:", human.version, "| tfjs version:", human.tf.version["tfjs-core"]);
log2("options:", JSON.stringify(options).replace(/{|}|"|\[|\]/g, "").replace(/,/g, " "));
printFPS("loading...");
log2("known face records:", await count());
await webCam();
await human.load();
printFPS("initializing...");
dom.retry.addEventListener("click", main);
dom.save.addEventListener("click", saveRecords);
dom.delete.addEventListener("click", deleteRecord);
await human.warmup();
await main();
}
window.onload = init;
import{Human as H}from"../../dist/human.esm.js";var d,R="human",m="person",g=(...t)=>console.log("indexdb",...t);async function b(){return d?!0:new Promise(t=>{let i=indexedDB.open(R,1);i.onerror=s=>g("error:",s),i.onupgradeneeded=s=>{g("create:",s.target),d=s.target.result,d.createObjectStore(m,{keyPath:"id",autoIncrement:!0})},i.onsuccess=s=>{d=s.target.result,g("open:",d),t(!0)}})}async function C(){let t=[];return d||await b(),new Promise(i=>{let s=d.transaction([m],"readwrite").objectStore(m).openCursor(null,"next");s.onerror=o=>g("load error:",o),s.onsuccess=o=>{o.target.result?(t.push(o.target.result.value),o.target.result.continue()):i(t)}})}async function k(){return d||await b(),new Promise(t=>{let i=d.transaction([m],"readwrite").objectStore(m).count();i.onerror=s=>g("count error:",s),i.onsuccess=()=>t(i.result)})}async function x(t){d||await b();let i={name:t.name,descriptor:t.descriptor,image:t.image};d.transaction([m],"readwrite").objectStore(m).put(i),g("save:",i)}async function D(t){d||await b(),d.transaction([m],"readwrite").objectStore(m).delete(t.id),g("delete:",t)}var v={modelBasePath:"../../models",filter:{equalization:!0},face:{enabled:!0,detector:{rotation:!0,return:!0,cropFactor:1.6,mask:!1},description:{enabled:!0},mobilefacenet:{enabled:!1,modelPath:"https://vladmandic.github.io/human-models/models/mobilefacenet.json"},iris:{enabled:!0},emotion:{enabled:!1},antispoof:{enabled:!0},liveness:{enabled:!0}},body:{enabled:!1},hand:{enabled:!1},object:{enabled:!1},gesture:{enabled:!0}},I={order:2,multiplier:25,min:.2,max:.8},c={minConfidence:.6,minSize:224,maxTime:1e4,blinkMin:10,blinkMax:800,threshold:.5,mask:v.face.detector.mask,rotation:v.face.detector.rotation,cropFactor:v.face.detector.cropFactor,...I},n={faceCount:!1,faceConfidence:!1,facingCenter:!1,lookingCenter:!1,blinkDetected:!1,faceSize:!1,antispoofCheck:!1,livenessCheck:!1,elapsedMs:0},M=()=>n.faceCount&&n.faceSize&&n.blinkDetected&&n.facingCenter&&n.lookingCenter&&n.faceConfidence&&n.antispoofCheck&&n.livenessCheck,r={face:null,record:null},l={start:0,end:0,time:0},a=new H(v);a.env.perfadd=!1;a.draw.options.font='small-caps 18px "Lato"';a.draw.options.lineHeight=20;var e={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("fps"),match:document.getElementById("match"),name:document.getElementById("name"),save:document.getElementById("save"),delete:document.getElementById("delete"),retry:document.getElementById("retry"),source:document.getElementById("source"),ok:document.getElementById("ok")},h={detect:0,draw:0},y={detect:0,draw:0},E=0,p=(...t)=>{e.log.innerText+=t.join(" ")+`
`,console.log(...t)},w=t=>e.fps.innerText=t;async function S(){w("starting webcam...");let t={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth}}},i=await navigator.mediaDevices.getUserMedia(t),s=new Promise(o=>{e.video.onloadeddata=()=>o(!0)});e.video.srcObject=i,e.video.play(),await s,e.canvas.width=e.video.videoWidth,e.canvas.height=e.video.videoHeight,a.env.initial&&p("video:",e.video.videoWidth,e.video.videoHeight,"|",i.getVideoTracks()[0].label),e.canvas.onclick=()=>{e.video.paused?e.video.play():e.video.pause()}}async function T(){if(!e.video.paused){r.face&&r.face.tensor&&a.tf.dispose(r.face.tensor),await a.detect(e.video);let t=a.now();y.detect=1e3/(t-h.detect),h.detect=t,requestAnimationFrame(T)}}async function L(){let t=await a.next(a.result);await a.draw.canvas(e.video,e.canvas),await a.draw.all(e.canvas,t);let i=a.now();if(y.draw=1e3/(i-h.draw),h.draw=i,w(`fps: ${y.detect.toFixed(1).padStart(5," ")} detect | ${y.draw.toFixed(1).padStart(5," ")} draw`),n.faceCount=a.result.face.length===1,n.faceCount){let o=Object.values(a.result.gesture).map(f=>f.gesture);(o.includes("blink left eye")||o.includes("blink right eye"))&&(l.start=a.now()),l.start>0&&!o.includes("blink left eye")&&!o.includes("blink right eye")&&(l.end=a.now()),n.blinkDetected=n.blinkDetected||Math.abs(l.end-l.start)>c.blinkMin&&Math.abs(l.end-l.start)<c.blinkMax,n.blinkDetected&&l.time===0&&(l.time=Math.trunc(l.end-l.start)),n.facingCenter=o.includes("facing center"),n.lookingCenter=o.includes("looking center"),n.faceConfidence=(a.result.face[0].boxScore||0)>c.minConfidence&&(a.result.face[0].faceScore||0)>c.minConfidence&&(a.result.face[0].genderScore||0)>c.minConfidence,n.antispoofCheck=(a.result.face[0].real||0)>c.minConfidence,n.livenessCheck=(a.result.face[0].live||0)>c.minConfidence,n.faceSize=a.result.face[0].box[2]>=c.minSize&&a.result.face[0].box[3]>=c.minSize}let s=32;for(let[o,f]of Object.entries(n)){let u=document.getElementById(`ok-${o}`);u||(u=document.createElement("div"),u.innerText=o,u.className="ok",u.style.top=`${s}px`,e.ok.appendChild(u)),typeof f=="boolean"?u.style.backgroundColor=f?"lightgreen":"lightcoral":u.innerText=`${o}:${f}`,s+=28}return M()||n.elapsedMs>c.maxTime?(e.video.pause(),a.result.face[0]):(n.elapsedMs=Math.trunc(a.now()-E),new Promise(o=>{setTimeout(async()=>{await L()&&o(a.result.face[0])},30)}))}async function P(){var t,i;if(e.name.value.length>0){let s=(t=e.canvas.getContext("2d"))==null?void 0:t.getImageData(0,0,e.canvas.width,e.canvas.height),o={id:0,name:e.name.value,descriptor:(i=r.face)==null?void 0:i.embedding,image:s};await x(o),p("saved face record:",o.name)}else p("invalid name")}async function z(){r.record&&r.record.id>0&&await D(r.record)}async function j(){var o,f;if((o=e.canvas.getContext("2d"))==null||o.clearRect(0,0,c.minSize,c.minSize),!r.face||!r.face.tensor||!r.face.embedding)return!1;if(console.log("face record:",r.face),a.tf.browser.toPixels(r.face.tensor,e.canvas),await k()===0)return p("face database is empty"),document.body.style.background="black",e.delete.style.display="none",!1;let t=await C(),i=t.map(u=>u.descriptor),s=await a.match(r.face.embedding,i,I);return r.record=t[s.index]||null,r.record&&(p(`best match: ${r.record.name} | id: ${r.record.id} | similarity: ${Math.round(1e3*s.similarity)/10}%`),e.name.value=r.record.name,e.source.style.display="",(f=e.source.getContext("2d"))==null||f.putImageData(r.record.image,0,0)),document.body.style.background=s.similarity>c.threshold?"darkgreen":"maroon",s.similarity>c.threshold}async function B(){var t,i,s,o;return n.faceCount=!1,n.faceConfidence=!1,n.facingCenter=!1,n.blinkDetected=!1,n.faceSize=!1,n.antispoofCheck=!1,n.livenessCheck=!1,n.elapsedMs=0,e.match.style.display="none",e.retry.style.display="none",e.source.style.display="none",document.body.style.background="black",await S(),await T(),E=a.now(),r.face=await L(),e.canvas.width=((i=(t=r.face)==null?void 0:t.tensor)==null?void 0:i.shape[1])||c.minSize,e.canvas.height=((o=(s=r.face)==null?void 0:s.tensor)==null?void 0:o.shape[0])||c.minSize,e.source.width=e.canvas.width,e.source.height=e.canvas.height,e.canvas.style.width="",e.match.style.display="flex",e.save.style.display="flex",e.delete.style.display="flex",e.retry.style.display="block",M()?j():(p("did not find valid face"),!1)}async function q(){p("human version:",a.version,"| tfjs version:",a.tf.version["tfjs-core"]),p("options:",JSON.stringify(c).replace(/{|}|"|\[|\]/g,"").replace(/,/g," ")),w("loading..."),p("known face records:",await k()),await S(),await a.load(),w("initializing..."),e.retry.addEventListener("click",B),e.save.addEventListener("click",P),e.delete.addEventListener("click",z),await a.warmup(),await B()}window.onload=q;
/**
* Human demo for browsers
* @default Human Library

File diff suppressed because one or more lines are too long

View File

@ -4,100 +4,8 @@
author: <https://github.com/vladmandic>'
*/
// demo/typescript/index.ts
import { Human } from "../../dist/human.esm.js";
var humanConfig = {
modelBasePath: "../../models",
filter: { enabled: true, equalization: false },
face: { enabled: true, detector: { rotation: false }, mesh: { enabled: true }, iris: { enabled: true }, description: { enabled: true }, emotion: { enabled: true } },
body: { enabled: true },
hand: { enabled: true },
object: { enabled: true },
gesture: { enabled: true }
};
var human = new Human(humanConfig);
human.env["perfadd"] = false;
human.draw.options.font = 'small-caps 18px "Lato"';
human.draw.options.lineHeight = 20;
var dom = {
video: document.getElementById("video"),
canvas: document.getElementById("canvas"),
log: document.getElementById("log"),
fps: document.getElementById("status"),
perf: document.getElementById("performance")
};
var timestamp = { detect: 0, draw: 0, tensors: 0 };
var fps = { detect: 0, draw: 0 };
var log = (...msg) => {
dom.log.innerText += msg.join(" ") + "\n";
console.log(...msg);
};
var status = (msg) => dom.fps.innerText = msg;
var perf = (msg) => dom.perf.innerText = "tensors:" + human.tf.memory().numTensors + " | performance: " + JSON.stringify(msg).replace(/"|{|}/g, "").replace(/,/g, " | ");
async function webCam() {
status("starting webcam...");
const options = { audio: false, video: { facingMode: "user", resizeMode: "none", width: { ideal: document.body.clientWidth } } };
const stream = await navigator.mediaDevices.getUserMedia(options);
const ready = new Promise((resolve) => {
dom.video.onloadeddata = () => resolve(true);
});
dom.video.srcObject = stream;
dom.video.play();
await ready;
dom.canvas.width = dom.video.videoWidth;
dom.canvas.height = dom.video.videoHeight;
const track = stream.getVideoTracks()[0];
const capabilities = track.getCapabilities ? track.getCapabilities() : "";
const settings = track.getSettings ? track.getSettings() : "";
const constraints = track.getConstraints ? track.getConstraints() : "";
log("video:", dom.video.videoWidth, dom.video.videoHeight, track.label, { stream, track, settings, constraints, capabilities });
dom.canvas.onclick = () => {
if (dom.video.paused)
dom.video.play();
else
dom.video.pause();
};
}
async function detectionLoop() {
if (!dom.video.paused) {
await human.detect(dom.video);
const tensors = human.tf.memory().numTensors;
if (tensors - timestamp.tensors !== 0)
log("allocated tensors:", tensors - timestamp.tensors);
timestamp.tensors = tensors;
}
const now = human.now();
fps.detect = 1e3 / (now - timestamp.detect);
timestamp.detect = now;
requestAnimationFrame(detectionLoop);
}
async function drawLoop() {
if (!dom.video.paused) {
const interpolated = await human.next(human.result);
await human.draw.canvas(dom.video, dom.canvas);
await human.draw.all(dom.canvas, interpolated);
perf(interpolated.performance);
}
const now = human.now();
fps.draw = 1e3 / (now - timestamp.draw);
timestamp.draw = now;
status(dom.video.paused ? "paused" : `fps: ${fps.detect.toFixed(1).padStart(5, " ")} detect | ${fps.draw.toFixed(1).padStart(5, " ")} draw`);
setTimeout(drawLoop, 30);
}
async function main() {
log("human version:", human.version, "| tfjs version:", human.tf.version["tfjs-core"]);
log("platform:", human.env.platform, "| agent:", human.env.agent);
status("loading...");
await human.load();
log("backend:", human.tf.getBackend(), "| available:", human.env.backends);
log("loaded models:", Object.values(human.models).filter((model) => model !== null).length);
status("initializing...");
await human.warmup();
await webCam();
await detectionLoop();
await drawLoop();
}
window.onload = main;
import{Human as p}from"../../dist/human.esm.js";var w={modelBasePath:"../../models",filter:{enabled:!0,equalization:!1},face:{enabled:!0,detector:{rotation:!1},mesh:{enabled:!0},iris:{enabled:!0},description:{enabled:!0},emotion:{enabled:!0}},body:{enabled:!0},hand:{enabled:!0},object:{enabled:!0},gesture:{enabled:!0}},t=new p(w);t.env.perfadd=!1;t.draw.options.font='small-caps 18px "Lato"';t.draw.options.lineHeight=20;var e={video:document.getElementById("video"),canvas:document.getElementById("canvas"),log:document.getElementById("log"),fps:document.getElementById("status"),perf:document.getElementById("performance")},i={detect:0,draw:0,tensors:0},d={detect:0,draw:0},s=(...a)=>{e.log.innerText+=a.join(" ")+`
`,console.log(...a)},r=a=>e.fps.innerText=a,b=a=>e.perf.innerText="tensors:"+t.tf.memory().numTensors+" | performance: "+JSON.stringify(a).replace(/"|{|}/g,"").replace(/,/g," | ");async function h(){r("starting webcam...");let a={audio:!1,video:{facingMode:"user",resizeMode:"none",width:{ideal:document.body.clientWidth}}},n=await navigator.mediaDevices.getUserMedia(a),m=new Promise(f=>{e.video.onloadeddata=()=>f(!0)});e.video.srcObject=n,e.video.play(),await m,e.canvas.width=e.video.videoWidth,e.canvas.height=e.video.videoHeight;let o=n.getVideoTracks()[0],u=o.getCapabilities?o.getCapabilities():"",v=o.getSettings?o.getSettings():"",g=o.getConstraints?o.getConstraints():"";s("video:",e.video.videoWidth,e.video.videoHeight,o.label,{stream:n,track:o,settings:v,constraints:g,capabilities:u}),e.canvas.onclick=()=>{e.video.paused?e.video.play():e.video.pause()}}async function c(){if(!e.video.paused){await t.detect(e.video);let n=t.tf.memory().numTensors;n-i.tensors!==0&&s("allocated tensors:",n-i.tensors),i.tensors=n}let a=t.now();d.detect=1e3/(a-i.detect),i.detect=a,requestAnimationFrame(c)}async function l(){if(!e.video.paused){let n=await t.next(t.result);await t.draw.canvas(e.video,e.canvas),await t.draw.all(e.canvas,n),b(n.performance)}let a=t.now();d.draw=1e3/(a-i.draw),i.draw=a,r(e.video.paused?"paused":`fps: ${d.detect.toFixed(1).padStart(5," ")} detect | ${d.draw.toFixed(1).padStart(5," ")} draw`),setTimeout(l,30)}async function y(){s("human version:",t.version,"| tfjs version:",t.tf.version["tfjs-core"]),s("platform:",t.env.platform,"| agent:",t.env.agent),r("loading..."),await t.load(),s("backend:",t.tf.getBackend(),"| available:",t.env.backends),s("loaded models:",Object.values(t.models).filter(a=>a!==null).length),r("initializing..."),await t.warmup(),await h(),await c(),await l()}window.onload=y;
/**
* Human demo for browsers
* @default Human Library

File diff suppressed because one or more lines are too long

View File

@ -1,86 +1,24 @@
2022-04-01 09:08:29 INFO:  Application: {"name":"@vladmandic/human","version":"2.6.4"}
2022-04-01 09:08:29 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-04-01 09:08:29 INFO:  Toolchain: {"build":"0.7.2","esbuild":"0.14.29","typescript":"4.6.3","typedoc":"0.22.13","eslint":"8.12.0"}
2022-04-01 09:08:29 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2022-04-01 09:08:29 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
2022-04-01 09:08:29 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":595}
2022-04-01 09:08:29 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":64,"inputBytes":564766,"outputBytes":293301}
2022-04-01 09:08:29 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":599}
2022-04-01 09:08:29 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":64,"inputBytes":564770,"outputBytes":293305}
2022-04-01 09:08:29 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":651}
2022-04-01 09:08:29 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":64,"inputBytes":564822,"outputBytes":293355}
2022-04-01 09:08:29 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":394}
2022-04-01 09:08:29 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1068,"outputBytes":615}
2022-04-01 09:08:29 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":64,"inputBytes":564786,"outputBytes":292260}
2022-04-01 09:08:30 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1344131}
2022-04-01 09:08:30 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":64,"inputBytes":1908302,"outputBytes":1635407}
2022-04-01 09:08:30 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":64,"inputBytes":1908302,"outputBytes":2113578}
2022-04-01 09:08:35 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":114}
2022-04-01 09:08:37 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":75,"generated":true}
2022-04-01 09:08:37 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5862,"outputBytes":2915}
2022-04-01 09:08:37 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
2022-04-01 09:08:45 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":96,"errors":0,"warnings":0}
2022-04-01 09:08:45 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2022-04-01 09:08:45 INFO:  Done...
2022-04-01 09:09:34 INFO:  @vladmandic/human version 2.6.4
2022-04-01 09:09:34 INFO:  User: vlado Platform: linux Arch: x64 Node: v17.4.0
2022-04-01 09:09:34 INFO:  Application: {"name":"@vladmandic/human","version":"2.6.4"}
2022-04-01 09:09:34 INFO:  Environment: {"profile":"development","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-04-01 09:09:34 INFO:  Toolchain: {"build":"0.7.2","esbuild":"0.14.29","typescript":"4.6.3","typedoc":"0.22.13","eslint":"8.12.0"}
2022-04-01 09:09:34 INFO:  Build: {"profile":"development","steps":["serve","watch","compile"]}
2022-04-01 09:09:34 STATE: WebServer: {"ssl":false,"port":10030,"root":"."}
2022-04-01 09:09:34 STATE: WebServer: {"ssl":true,"port":10031,"root":".","sslKey":"node_modules/@vladmandic/build/cert/https.key","sslCrt":"node_modules/@vladmandic/build/cert/https.crt"}
2022-04-01 09:09:34 STATE: Watch: {"locations":["src/**/*","tfjs/**/*","demo/**/*.ts"]}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":1084}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":64,"inputBytes":565255,"outputBytes":461910}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1104}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":64,"inputBytes":565275,"outputBytes":461926}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":1191}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":64,"inputBytes":565362,"outputBytes":462017}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":1652}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":2326,"outputBytes":912}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":64,"inputBytes":565083,"outputBytes":463792}
2022-04-01 09:09:34 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":2521981}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":64,"inputBytes":3086152,"outputBytes":1635604}
2022-04-01 09:09:34 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":64,"inputBytes":3086152,"outputBytes":2990599}
2022-04-01 09:09:34 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5862,"outputBytes":4125}
2022-04-01 09:09:34 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":11794}
2022-04-01 09:09:34 INFO:  Listening...
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/html","size":7842,"url":"/","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/css","size":107884,"url":"/icons.css","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":48528,"url":"/index.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"font/woff2","size":181500,"url":"/assets/lato-light.woff2","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":2990599,"url":"/dist/human.esm.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":14514,"url":"/helpers/menu.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":10901,"url":"/helpers/gl-bench.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":3406,"url":"/helpers/webrtc.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":5785,"url":"/helpers/jsonview.js","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"image/x-icon","size":261950,"url":"/favicon.ico","remote":"::1"}
2022-04-01 09:09:47 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":4115,"url":"/index-pwa.js","remote":"::1"}
2022-04-01 09:09:48 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/manifest+json","size":304,"url":"/manifest.webmanifest","remote":"::1"}
2022-04-01 09:09:48 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"image/png","size":142790,"url":"/assets/icon.png","remote":"::1"}
2022-04-01 09:09:50 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":1778,"url":"/index-worker.js","remote":"::1"}
2022-04-01 09:09:50 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":1635604,"url":"/dist/human.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/html","size":1953,"url":"/typescript","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":48528,"url":"/index.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"font/woff2","size":181500,"url":"/assets/lato-light.woff2","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":2990599,"url":"/dist/human.esm.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":14514,"url":"/helpers/menu.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":10901,"url":"/helpers/gl-bench.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":3406,"url":"/helpers/webrtc.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":5785,"url":"/helpers/jsonview.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/manifest+json","size":304,"url":"/manifest.webmanifest","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":4115,"url":"/index-pwa.js","remote":"::1"}
2022-04-01 09:10:49 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"image/png","size":142790,"url":"/assets/icon.png","remote":"::1"}
2022-04-01 09:10:55 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/manifest+json","size":304,"url":"/manifest.webmanifest","remote":"::1"}
2022-04-01 09:10:55 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/octet-stream","size":5089284,"url":"/dist/human.esm.js.map","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/html","size":1953,"url":"/typescript/index.html","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":4125,"url":"/typescript/index.js","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"font/woff2","size":181500,"url":"/assets/lato-light.woff2","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"text/javascript","size":2990599,"url":"/dist/human.esm.js","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/octet-stream","size":8956,"url":"/typescript/index.js.map","remote":"::1"}
2022-04-01 09:11:02 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/octet-stream","size":5089284,"url":"/dist/human.esm.js.map","remote":"::1"}
2022-04-01 09:11:03 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/manifest+json","size":304,"url":"/manifest.webmanifest","remote":"::1"}
2022-04-01 09:11:03 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"image/png","size":142790,"url":"/assets/icon.png","remote":"::1"}
2022-04-01 09:11:03 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/json","size":201677,"url":"/models/mb3-centernet.json","remote":"::1"}
2022-04-01 09:11:03 DATA:  HTTPS: {"method":"GET","ver":"2.0","status":200,"mime":"application/octet-stream","size":4030290,"url":"/models/mb3-centernet.bin","remote":"::1"}
2022-04-01 09:12:16 INFO:  Application: {"name":"@vladmandic/human","version":"2.6.5"}
2022-04-01 09:12:16 INFO:  Environment: {"profile":"production","config":".build.json","package":"package.json","tsconfig":true,"eslintrc":true,"git":true}
2022-04-01 09:12:16 INFO:  Toolchain: {"build":"0.7.2","esbuild":"0.14.29","typescript":"4.6.3","typedoc":"0.22.13","eslint":"8.12.0"}
2022-04-01 09:12:16 INFO:  Build: {"profile":"production","steps":["clean","compile","typings","typedoc","lint","changelog"]}
2022-04-01 09:12:16 STATE: Clean: {"locations":["dist/*","types/lib/*","typedoc/*"]}
2022-04-01 09:12:16 STATE: Compile: {"name":"tfjs/nodejs/cpu","format":"cjs","platform":"node","input":"tfjs/tf-node.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":102,"outputBytes":595}
2022-04-01 09:12:16 STATE: Compile: {"name":"human/nodejs/cpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node.js","files":64,"inputBytes":564766,"outputBytes":293301}
2022-04-01 09:12:16 STATE: Compile: {"name":"tfjs/nodejs/gpu","format":"cjs","platform":"node","input":"tfjs/tf-node-gpu.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":599}
2022-04-01 09:12:16 STATE: Compile: {"name":"human/nodejs/gpu","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-gpu.js","files":64,"inputBytes":564770,"outputBytes":293305}
2022-04-01 09:12:16 STATE: Compile: {"name":"tfjs/nodejs/wasm","format":"cjs","platform":"node","input":"tfjs/tf-node-wasm.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":149,"outputBytes":651}
2022-04-01 09:12:16 STATE: Compile: {"name":"human/nodejs/wasm","format":"cjs","platform":"node","input":"src/human.ts","output":"dist/human.node-wasm.js","files":64,"inputBytes":564822,"outputBytes":293355}
2022-04-01 09:12:16 STATE: Compile: {"name":"tfjs/browser/version","format":"esm","platform":"browser","input":"tfjs/tf-version.ts","output":"dist/tfjs.version.js","files":1,"inputBytes":1063,"outputBytes":394}
2022-04-01 09:12:16 STATE: Compile: {"name":"tfjs/browser/esm/nobundle","format":"esm","platform":"browser","input":"tfjs/tf-browser.ts","output":"dist/tfjs.esm.js","files":2,"inputBytes":1068,"outputBytes":615}
2022-04-01 09:12:16 STATE: Compile: {"name":"human/browser/esm/nobundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm-nobundle.js","files":64,"inputBytes":564786,"outputBytes":292260}
2022-04-01 09:12:17 STATE: Compile: {"name":"tfjs/browser/esm/custom","format":"esm","platform":"browser","input":"tfjs/tf-custom.ts","output":"dist/tfjs.esm.js","files":1,"inputBytes":110,"outputBytes":1344131}
2022-04-01 09:12:17 STATE: Compile: {"name":"human/browser/iife/bundle","format":"iife","platform":"browser","input":"src/human.ts","output":"dist/human.js","files":64,"inputBytes":1908302,"outputBytes":1635407}
2022-04-01 09:12:17 STATE: Compile: {"name":"human/browser/esm/bundle","format":"esm","platform":"browser","input":"src/human.ts","output":"dist/human.esm.js","files":64,"inputBytes":1908302,"outputBytes":2113578}
2022-04-01 09:12:23 STATE: Typings: {"input":"src/human.ts","output":"types/lib","files":114}
2022-04-01 09:12:25 STATE: TypeDoc: {"input":"src/human.ts","output":"typedoc","objects":75,"generated":true}
2022-04-01 09:12:25 STATE: Compile: {"name":"demo/typescript","format":"esm","platform":"browser","input":"demo/typescript/index.ts","output":"demo/typescript/index.js","files":1,"inputBytes":5862,"outputBytes":2915}
2022-04-01 09:12:25 STATE: Compile: {"name":"demo/faceid","format":"esm","platform":"browser","input":"demo/faceid/index.ts","output":"demo/faceid/index.js","files":2,"inputBytes":15174,"outputBytes":7820}
2022-04-01 09:12:33 STATE: Lint: {"locations":["*.json","src/**/*.ts","test/**/*.js","demo/**/*.js"],"files":96,"errors":0,"warnings":0}
2022-04-01 09:12:33 STATE: ChangeLog: {"repository":"https://github.com/vladmandic/human","branch":"main","output":"CHANGELOG.md"}
2022-04-01 09:12:33 INFO:  Done...

File diff suppressed because it is too large Load Diff