update embedding and strong typings

pull/91/head
Vladimir Mandic 2021-03-13 11:26:53 -05:00
parent c5ef0c1bd5
commit ff2d53f893
27 changed files with 2655 additions and 2211 deletions

View File

@ -1,6 +1,6 @@
# @vladmandic/human
Version: **1.1.1**
Version: **1.1.2**
Description: **Human: AI-powered 3D Face Detection, Face Embedding & Recognition, Body Pose Tracking, Hand & Finger Tracking, Iris Analysis, Age & Gender & Emotion Prediction & Gesture Recognition**
Author: **Vladimir Mandic <mandic00@live.com>**
@ -9,8 +9,10 @@ Repository: **<git+https://github.com/vladmandic/human.git>**
## Changelog
### **HEAD -> main** 2021/03/12 mandic00@live.com
### **1.1.2** 2021/03/12 mandic00@live.com
- distance based on minkowski space and limited euclidean space
- guard against invalid input images
### **1.1.1** 2021/03/12 mandic00@live.com

17
TODO.md
View File

@ -4,21 +4,26 @@
- Strong(er) typing
- Automated testing framework
- API Documentation
- API Extractor: generate dts rollup and docs
<https://api-extractor.com/>
- TypeDoc: generate docs
<http://typedoc.org/>
## Explore Models
- EfficientPose
<https://github.com/daniegr/EfficientPose>
<https://github.com/PINTO0309/PINTO_model_zoo/tree/main/084_EfficientPose>
- ArcFace
- RetinaFace
- CenterFace
- InsightFace
RetinaFace detetor and ArcFace recognition
<https://github.com/deepinsight/insightface>
- NanoDet
<https://github.com/RangiLyu/nanodet>
## WiP Items
- Embedding:
- Try average of flipped image
- Try with variable aspect ratio
- face.tensor should return image in correct aspect ratio
## Issues

View File

@ -82,7 +82,7 @@ let original;
async function calcSimmilariry(result) {
document.getElementById('compare-container').style.display = human.config.face.embedding.enabled ? 'block' : 'none';
if (!human.config.face.embedding.enabled) return;
if (!(result?.face?.length > 0) || (result?.face[0]?.embedding?.length !== 256)) return;
if (!(result?.face?.length > 0) || (result?.face[0]?.embedding?.length >= 64)) return;
if (!original) {
original = result;
if (result.face[0].tensor) {

View File

@ -20,7 +20,7 @@
body { margin: 0; background: black; color: white; overflow-x: hidden; scrollbar-width: none; }
body::-webkit-scrollbar { display: none; }
img { object-fit: contain; }
.face { width: 150px; height: 150px; }
.face { width: 128px; height: 128px; }
</style>
</head>
<body>

View File

@ -5,7 +5,6 @@ const userConfig = {
async: false,
warmup: 'none',
debug: true,
filter: false,
videoOptimized: false,
face: {
enabled: true,
@ -20,15 +19,13 @@ const userConfig = {
hand: { enabled: false },
gesture: { enabled: false },
body: { enabled: false },
filter: {
enabled: false,
},
};
const human = new Human(userConfig); // new instance of human
// const samples = ['../assets/sample-me.jpg', '../assets/sample6.jpg', '../assets/sample1.jpg', '../assets/sample4.jpg', '../assets/sample5.jpg', '../assets/sample3.jpg', '../assets/sample2.jpg'];
// const samples = ['../assets/sample-me.jpg', '../assets/sample6.jpg', '../assets/sample1.jpg', '../assets/sample4.jpg', '../assets/sample5.jpg', '../assets/sample3.jpg', '../assets/sample2.jpg',
// '../private/me (1).jpg', '../private/me (2).jpg', '../private/me (3).jpg', '../private/me (4).jpg', '../private/me (5).jpg', '../private/me (6).jpg', '../private/me (7).jpg', '../private/me (8).jpg',
// '../private/me (9).jpg', '../private/me (10).jpg', '../private/me (11).jpg', '../private/me (12).jpg', '../private/me (13).jpg'];
const all = []; // array that will hold all detected faces
function log(...msg) {
@ -39,8 +36,6 @@ function log(...msg) {
}
async function analyze(face) {
log('Face:', face);
// if we have face image tensor, enhance it and display it
if (face.tensor) {
const enhanced = human.enhance(face);
@ -87,7 +82,7 @@ async function faces(index, res) {
canvas.className = 'face';
// mouse click on any face canvas triggers analysis
canvas.addEventListener('click', (evt) => {
log('Select:', 'Image:', evt.target.tag.sample, 'Face:', evt.target.tag.face);
log('Select:', 'Image:', evt.target.tag.sample, 'Face:', evt.target.tag.face, all[evt.target.tag.sample][evt.target.tag.face]);
analyze(all[evt.target.tag.sample][evt.target.tag.face]);
});
// if we actually got face image tensor, draw canvas with that face
@ -98,14 +93,16 @@ async function faces(index, res) {
}
}
async function add(index, image) {
log('Add image:', index + 1, image);
async function process(index, image) {
return new Promise((resolve) => {
const img = new Image(100, 100);
const img = new Image(128, 128);
img.onload = () => { // must wait until image is loaded
human.detect(img).then((res) => faces(index, res)); // then wait until image is analyzed
human.detect(img).then((res) => {
faces(index, res); // then wait until image is analyzed
log('Add image:', index + 1, image, 'faces:', res.face.length);
document.getElementById('images').appendChild(img); // and finally we can add it
resolve(true);
});
};
img.title = image;
img.src = encodeURI(image);
@ -126,8 +123,11 @@ async function main() {
// download and analyze all images
log('Enumerated:', images.length, 'images');
for (const i in images) await add(i, images[i]);
for (let i = 0; i < images.length; i++) await process(i, images[i]);
const num = all.reduce((prev, cur) => prev += cur.length, 0);
log('Extracted faces:', num, 'from images:', all.length);
log(human.tf.engine().memory());
log('Ready');
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

910
dist/human.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

910
dist/human.js vendored

File diff suppressed because one or more lines are too long

6
dist/human.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

18
dist/human.node.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1176
dist/tfjs.esm.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

614
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "1.1.2",
"license": "MIT",
"devDependencies": {
"@microsoft/api-extractor": "^7.13.2",
"@tensorflow/tfjs": "^3.3.0",
"@tensorflow/tfjs-backend-cpu": "^3.3.0",
"@tensorflow/tfjs-backend-wasm": "^3.3.0",
@ -26,7 +27,7 @@
"chokidar": "^3.5.1",
"dayjs": "^1.10.4",
"esbuild": "^0.9.2",
"eslint": "^7.21.0",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-json": "^2.1.2",
@ -149,6 +150,30 @@
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"dependencies": {
"type-fest": "^0.8.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@eslint/eslintrc/node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@kwsites/file-exists": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
@ -164,6 +189,57 @@
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
"dev": true
},
"node_modules/@microsoft/api-extractor": {
"version": "7.13.2",
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.13.2.tgz",
"integrity": "sha512-2fD0c8OxZW+e6NTaxbtrdNxXVuX7aqil3+cqig3pKsHymvUuRJVCEAcAJmZrJ/ENqYXNiB265EyqOT6VxbMysw==",
"dev": true,
"dependencies": {
"@microsoft/api-extractor-model": "7.12.2",
"@microsoft/tsdoc": "0.12.24",
"@rushstack/node-core-library": "3.36.0",
"@rushstack/rig-package": "0.2.10",
"@rushstack/ts-command-line": "4.7.8",
"colors": "~1.2.1",
"lodash": "~4.17.15",
"resolve": "~1.17.0",
"semver": "~7.3.0",
"source-map": "~0.6.1",
"typescript": "~4.1.3"
},
"bin": {
"api-extractor": "bin/api-extractor"
}
},
"node_modules/@microsoft/api-extractor-model": {
"version": "7.12.2",
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.12.2.tgz",
"integrity": "sha512-EU+U09Mj65zUH0qwPF4PFJiL6Y+PQQE/RRGEHEDGJJzab/mRQDpKOyrzSdb00xvcd/URehIHJqC55cY2Y4jGOA==",
"dev": true,
"dependencies": {
"@microsoft/tsdoc": "0.12.24",
"@rushstack/node-core-library": "3.36.0"
}
},
"node_modules/@microsoft/api-extractor/node_modules/typescript": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz",
"integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/@microsoft/tsdoc": {
"version": "0.12.24",
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz",
"integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==",
"dev": true
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@ -199,6 +275,51 @@
"node": ">= 8"
}
},
"node_modules/@rushstack/node-core-library": {
"version": "3.36.0",
"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz",
"integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==",
"dev": true,
"dependencies": {
"@types/node": "10.17.13",
"colors": "~1.2.1",
"fs-extra": "~7.0.1",
"import-lazy": "~4.0.0",
"jju": "~1.4.0",
"resolve": "~1.17.0",
"semver": "~7.3.0",
"timsort": "~0.3.0",
"z-schema": "~3.18.3"
}
},
"node_modules/@rushstack/node-core-library/node_modules/@types/node": {
"version": "10.17.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz",
"integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==",
"dev": true
},
"node_modules/@rushstack/rig-package": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.10.tgz",
"integrity": "sha512-WXYerEJEPf8bS3ruqfM57NnwXtA7ehn8VJjLjrjls6eSduE5CRydcob/oBTzlHKsQ7N196XKlqQl9P6qIyYG2A==",
"dev": true,
"dependencies": {
"resolve": "~1.17.0",
"strip-json-comments": "~3.1.1"
}
},
"node_modules/@rushstack/ts-command-line": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.8.tgz",
"integrity": "sha512-8ghIWhkph7NnLCMDJtthpsb7TMOsVGXVDvmxjE/CeklTqjbbUFBjGXizJfpbEkRQTELuZQ2+vGn7sGwIWKN2uA==",
"dev": true,
"dependencies": {
"@types/argparse": "1.0.38",
"argparse": "~1.0.9",
"colors": "~1.2.1",
"string-argv": "~0.3.1"
}
},
"node_modules/@tensorflow/tfjs": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.3.0.tgz",
@ -237,12 +358,6 @@
"@tensorflow/tfjs-core": "3.3.0"
}
},
"node_modules/@tensorflow/tfjs-backend-cpu/node_modules/seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
},
"node_modules/@tensorflow/tfjs-backend-wasm": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-3.3.0.tgz",
@ -276,12 +391,6 @@
"@tensorflow/tfjs-core": "3.3.0"
}
},
"node_modules/@tensorflow/tfjs-backend-webgl/node_modules/seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
},
"node_modules/@tensorflow/tfjs-converter": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.3.0.tgz",
@ -307,12 +416,6 @@
"yarn": ">= 1.3.2"
}
},
"node_modules/@tensorflow/tfjs-core/node_modules/seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
},
"node_modules/@tensorflow/tfjs-data": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-3.3.0.tgz",
@ -400,6 +503,12 @@
"rimraf": "bin.js"
}
},
"node_modules/@types/argparse": {
"version": "1.0.38",
"resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
"integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
"dev": true
},
"node_modules/@types/emscripten": {
"version": "0.0.34",
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-0.0.34.tgz",
@ -982,6 +1091,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/colors": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz",
"integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==",
"dev": true,
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -994,6 +1112,13 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"optional": true
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -1271,9 +1396,9 @@
}
},
"node_modules/eslint": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
"integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==",
"version": "7.22.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.22.0.tgz",
"integrity": "sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==",
"dev": true,
"dependencies": {
"@babel/code-frame": "7.12.11",
@ -1293,7 +1418,7 @@
"file-entry-cache": "^6.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"globals": "^13.6.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@ -1301,7 +1426,7 @@
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.20",
"lodash": "^4.17.21",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
@ -1784,6 +1909,20 @@
"node": ">= 6"
}
},
"node_modules/fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@ -1918,12 +2057,12 @@
}
},
"node_modules/globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"version": "13.6.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz",
"integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==",
"dev": true,
"dependencies": {
"type-fest": "^0.8.1"
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
@ -2095,6 +2234,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/import-lazy": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
"integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@ -2180,18 +2328,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-core-module": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
@ -2325,6 +2461,12 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"node_modules/jju": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
"dev": true
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -2374,6 +2516,15 @@
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
"dev": true
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -2421,6 +2572,18 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"dev": true
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -3155,12 +3318,11 @@
}
},
"node_modules/resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"dev": true,
"dependencies": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
},
"funding": {
@ -3243,11 +3405,10 @@
"dev": true
},
"node_modules/seedrandom": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz",
"integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA==",
"dev": true,
"peer": true
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
},
"node_modules/semver": {
"version": "7.3.4",
@ -3343,6 +3504,15 @@
"node": ">=8"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
@ -3390,6 +3560,15 @@
"safe-buffer": "~5.1.0"
}
},
"node_modules/string-argv": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
"integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
"dev": true,
"engines": {
"node": ">=0.6.19"
}
},
"node_modules/string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@ -3586,6 +3765,12 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"node_modules/timsort": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -3650,12 +3835,15 @@
}
},
"node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
"engines": {
"node": ">=8"
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript": {
@ -3683,6 +3871,15 @@
"which-boxed-primitive": "^1.0.1"
}
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true,
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -3714,6 +3911,15 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/validator": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
"integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==",
"dev": true,
"engines": {
"node": ">= 0.10"
}
},
"node_modules/vscode-json-languageservice": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.11.0.tgz",
@ -3910,6 +4116,23 @@
"engines": {
"node": ">=8"
}
},
"node_modules/z-schema": {
"version": "3.18.4",
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
"integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
"dev": true,
"dependencies": {
"lodash.get": "^4.0.0",
"lodash.isequal": "^4.0.0",
"validator": "^8.0.0"
},
"bin": {
"z-schema": "bin/z-schema"
},
"optionalDependencies": {
"commander": "^2.7.1"
}
}
},
"dependencies": {
@ -4006,6 +4229,23 @@
"js-yaml": "^3.13.1",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
}
}
},
"@kwsites/file-exists": {
@ -4023,6 +4263,49 @@
"integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
"dev": true
},
"@microsoft/api-extractor": {
"version": "7.13.2",
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.13.2.tgz",
"integrity": "sha512-2fD0c8OxZW+e6NTaxbtrdNxXVuX7aqil3+cqig3pKsHymvUuRJVCEAcAJmZrJ/ENqYXNiB265EyqOT6VxbMysw==",
"dev": true,
"requires": {
"@microsoft/api-extractor-model": "7.12.2",
"@microsoft/tsdoc": "0.12.24",
"@rushstack/node-core-library": "3.36.0",
"@rushstack/rig-package": "0.2.10",
"@rushstack/ts-command-line": "4.7.8",
"colors": "~1.2.1",
"lodash": "~4.17.15",
"resolve": "~1.17.0",
"semver": "~7.3.0",
"source-map": "~0.6.1",
"typescript": "~4.1.3"
},
"dependencies": {
"typescript": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.5.tgz",
"integrity": "sha512-6OSu9PTIzmn9TCDiovULTnET6BgXtDYL4Gg4szY+cGsc3JP1dQL8qvE8kShTRx1NIw4Q9IBHlwODjkjWEtMUyA==",
"dev": true
}
}
},
"@microsoft/api-extractor-model": {
"version": "7.12.2",
"resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.12.2.tgz",
"integrity": "sha512-EU+U09Mj65zUH0qwPF4PFJiL6Y+PQQE/RRGEHEDGJJzab/mRQDpKOyrzSdb00xvcd/URehIHJqC55cY2Y4jGOA==",
"dev": true,
"requires": {
"@microsoft/tsdoc": "0.12.24",
"@rushstack/node-core-library": "3.36.0"
}
},
"@microsoft/tsdoc": {
"version": "0.12.24",
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz",
"integrity": "sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg==",
"dev": true
},
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@ -4049,6 +4332,53 @@
"fastq": "^1.6.0"
}
},
"@rushstack/node-core-library": {
"version": "3.36.0",
"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.36.0.tgz",
"integrity": "sha512-bID2vzXpg8zweXdXgQkKToEdZwVrVCN9vE9viTRk58gqzYaTlz4fMId6V3ZfpXN6H0d319uGi2KDlm+lUEeqCg==",
"dev": true,
"requires": {
"@types/node": "10.17.13",
"colors": "~1.2.1",
"fs-extra": "~7.0.1",
"import-lazy": "~4.0.0",
"jju": "~1.4.0",
"resolve": "~1.17.0",
"semver": "~7.3.0",
"timsort": "~0.3.0",
"z-schema": "~3.18.3"
},
"dependencies": {
"@types/node": {
"version": "10.17.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz",
"integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==",
"dev": true
}
}
},
"@rushstack/rig-package": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.10.tgz",
"integrity": "sha512-WXYerEJEPf8bS3ruqfM57NnwXtA7ehn8VJjLjrjls6eSduE5CRydcob/oBTzlHKsQ7N196XKlqQl9P6qIyYG2A==",
"dev": true,
"requires": {
"resolve": "~1.17.0",
"strip-json-comments": "~3.1.1"
}
},
"@rushstack/ts-command-line": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.8.tgz",
"integrity": "sha512-8ghIWhkph7NnLCMDJtthpsb7TMOsVGXVDvmxjE/CeklTqjbbUFBjGXizJfpbEkRQTELuZQ2+vGn7sGwIWKN2uA==",
"dev": true,
"requires": {
"@types/argparse": "1.0.38",
"argparse": "~1.0.9",
"colors": "~1.2.1",
"string-argv": "~0.3.1"
}
},
"@tensorflow/tfjs": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-3.3.0.tgz",
@ -4076,14 +4406,6 @@
"requires": {
"@types/seedrandom": "2.4.27",
"seedrandom": "2.4.3"
},
"dependencies": {
"seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
}
}
},
"@tensorflow/tfjs-backend-wasm": {
@ -4108,14 +4430,6 @@
"@types/webgl-ext": "0.0.30",
"@types/webgl2": "0.0.5",
"seedrandom": "2.4.3"
},
"dependencies": {
"seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
}
}
},
"@tensorflow/tfjs-converter": {
@ -4136,14 +4450,6 @@
"@types/webgl-ext": "0.0.30",
"node-fetch": "~2.6.1",
"seedrandom": "2.4.3"
},
"dependencies": {
"seedrandom": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
}
}
},
"@tensorflow/tfjs-data": {
@ -4217,6 +4523,12 @@
}
}
},
"@types/argparse": {
"version": "1.0.38",
"resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
"integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
"dev": true
},
"@types/emscripten": {
"version": "0.0.34",
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-0.0.34.tgz",
@ -4638,6 +4950,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"colors": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz",
"integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@ -4647,6 +4965,13 @@
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -4859,9 +5184,9 @@
"dev": true
},
"eslint": {
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.21.0.tgz",
"integrity": "sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==",
"version": "7.22.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.22.0.tgz",
"integrity": "sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
@ -4881,7 +5206,7 @@
"file-entry-cache": "^6.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"globals": "^13.6.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@ -4889,7 +5214,7 @@
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.20",
"lodash": "^4.17.21",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
@ -5269,6 +5594,17 @@
"mime-types": "^2.1.12"
}
},
"fs-extra": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@ -5377,12 +5713,12 @@
}
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"version": "13.6.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz",
"integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
"type-fest": "^0.20.2"
}
},
"globby": {
@ -5513,6 +5849,12 @@
"resolve-from": "^4.0.0"
}
},
"import-lazy": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
"integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
"dev": true
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@ -5577,15 +5919,6 @@
"integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
"dev": true
},
"is-core-module": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"is-date-object": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
@ -5671,6 +6004,12 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"jju": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
"dev": true
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@ -5714,6 +6053,15 @@
"integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -5752,6 +6100,18 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
"dev": true
},
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"dev": true
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -6321,12 +6681,11 @@
"dev": true
},
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"dev": true,
"requires": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
}
},
@ -6379,11 +6738,10 @@
"dev": true
},
"seedrandom": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz",
"integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA==",
"dev": true,
"peer": true
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz",
"integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=",
"dev": true
},
"semver": {
"version": "7.3.4",
@ -6457,6 +6815,12 @@
}
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"spdx-correct": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
@ -6504,6 +6868,12 @@
"safe-buffer": "~5.1.0"
}
},
"string-argv": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
"integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
"dev": true
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@ -6660,6 +7030,12 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"timsort": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
"dev": true
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -6714,9 +7090,9 @@
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true
},
"typescript": {
@ -6737,6 +7113,12 @@
"which-boxed-primitive": "^1.0.1"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@ -6768,6 +7150,12 @@
"spdx-expression-parse": "^3.0.0"
}
},
"validator": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz",
"integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==",
"dev": true
},
"vscode-json-languageservice": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-3.11.0.tgz",
@ -6929,6 +7317,18 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
"integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
"dev": true
},
"z-schema": {
"version": "3.18.4",
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz",
"integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==",
"dev": true,
"requires": {
"commander": "^2.7.1",
"lodash.get": "^4.0.0",
"lodash.isequal": "^4.0.0",
"validator": "^8.0.0"
}
}
}
}

View File

@ -44,6 +44,7 @@
"blazepose"
],
"devDependencies": {
"@microsoft/api-extractor": "^7.13.2",
"@tensorflow/tfjs": "^3.3.0",
"@tensorflow/tfjs-backend-cpu": "^3.3.0",
"@tensorflow/tfjs-backend-wasm": "^3.3.0",
@ -61,7 +62,7 @@
"chokidar": "^3.5.1",
"dayjs": "^1.10.4",
"esbuild": "^0.9.2",
"eslint": "^7.21.0",
"eslint": "^7.22.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-json": "^2.1.2",

View File

@ -172,9 +172,9 @@ async function getStats(json) {
}
// rebuild typings
function compile(fileNames, options) {
log.info('Compile typings:', fileNames);
const program = ts.createProgram(fileNames, options);
function compile(entryPoint, options) {
log.info('Compile typings:', entryPoint);
const program = ts.createProgram(entryPoint, options);
const emit = program.emit();
const diag = ts
.getPreEmitDiagnostics(program)
@ -183,7 +183,6 @@ function compile(fileNames, options) {
// @ts-ignore
const msg = info.messageText.messageText || info.messageText;
if (msg.includes('package.json')) continue;
if (msg.includes('Expected 0 arguments, but got 1')) continue;
if (info.file) {
const pos = info.file.getLineAndCharacterOfPosition(info.start || 0);
log.error(`TSC: ${info.file.fileName} [${pos.line + 1},${pos.character + 1}]:`, msg);

View File

@ -50,7 +50,7 @@ export class MediaPipeFaceMesh {
boxRaw,
meshRaw,
annotations,
image: prediction.image ? tf.clone(prediction.image) : null,
image: prediction.image ? prediction.image.clone() : null,
});
if (prediction.coords) prediction.coords.dispose();
if (prediction.image) prediction.image.dispose();

View File

@ -47,6 +47,15 @@ export function enhance(input) {
const grayscale = tf.addN([redNorm, greenNorm, blueNorm]);
const merge = tf.stack([grayscale, grayscale, grayscale], 3).squeeze(4);
/*
// optional increase image contrast
// or do it per-channel so mean is done on each channel
// or do it based on histogram
const mean = merge.mean();
const factor = 5;
const contrast = merge.sub(mean).mul(factor).add(mean);
*/
// normalize brightness from 0..1
const darken = merge.sub(merge.min());
const lighten = darken.div(darken.max());
@ -59,31 +68,52 @@ export function enhance(input) {
export async function predict(input, config) {
if (!model) return null;
return new Promise(async (resolve) => {
const image = enhance(input);
// let data: Array<[]> = [];
let data: Array<number> = [];
if (config.face.embedding.enabled) {
const image = enhance(input);
if (!config.profile) {
const res = await model.predict(image);
// optional normalize outputs with l2 normalization
data = tf.tidy(() => {
/*
// if needed convert from NHWC to NCHW
const nchw = image.transpose([3, 0, 1, 2]);
*/
const res = model.predict(image);
/*
// optionally do it twice with flipped image and average results
const res1 = model.predict(image);
const flipped = tf.image.flipLeftRight(image);
const res2 = model.predict(flipped);
const merge = tf.stack([res1, res2], 2).squeeze();
const res = reshape.logSumExp(1);
*/
/*
// optional normalize outputs with l2 normalization
const scaled = tf.tidy(() => {
const l2 = res.norm('euclidean');
const scale = res.div(l2);
return scale;
});
tf.dispose(scaled);
*/
data = res.dataSync();
tf.dispose(res);
// optional reduce feature vector complexity
const reshape = res.reshape([128, 2]); // split 256 vectors into 128 x 2
const reduce = reshape.logSumExp(1); // reduce 2nd dimension by calculating logSumExp on it
const output: Array<number> = reduce.dataSync();
return output;
});
} else {
const profileData = await tf.profile(() => model.predict({ img_inputs: image }));
data = [...profileData.result.dataSync()];
profileData.result.dispose();
profile.run('emotion', profileData);
}
}
image.dispose();
}
resolve(data);
});
}

View File

@ -43,7 +43,7 @@ class Human {
version: string;
config: typeof config.default;
state: string;
image: { tensor, canvas };
image: { tensor: any, canvas: OffscreenCanvas | HTMLCanvasElement };
// classes
tf: typeof tf;
draw: typeof draw;
@ -67,7 +67,7 @@ class Human {
body: typeof posenet | typeof blazepose;
hand: typeof handpose;
};
sysinfo: { platform, agent };
sysinfo: { platform: string, agent: string };
#package: any;
#perf: any;
#numTensors: number;
@ -146,7 +146,7 @@ class Human {
return null;
}
simmilarity(embedding1, embedding2): number {
simmilarity(embedding1: Array<number>, embedding2: Array<number>): number {
if (this.config.face.embedding.enabled) return embedding.simmilarity(embedding1, embedding2);
return 0;
}
@ -309,7 +309,6 @@ class Human {
embedding: any,
iris: number,
angle: any,
tensor: any,
}> = [];
this.state = 'run:face';
@ -401,11 +400,11 @@ class Human {
embedding: embeddingRes,
iris: (irisSize !== 0) ? Math.trunc(irisSize) / 100 : 0,
angle,
tensor: this.config.face.detector.return ? face.image.squeeze() : null,
tensor: this.config.face.detector.return ? face.image?.squeeze() : null,
});
// dont need face anymore
// dispose original face tensor
face.image?.dispose();
this.#analyze('End Face');
}
this.#analyze('End FaceMesh:');
@ -419,7 +418,7 @@ class Human {
}
// main detect function
async detect(input, userConfig = {}): Promise<{ face, body, hand, gesture, performance, canvas } | { error }> {
async detect(input, userConfig = {}): Promise<{ face: Array<{ any }>, body: Array<{ any }>, hand: Array<{ any }>, gesture: Array<{ any }>, performance: object, canvas: OffscreenCanvas | HTMLCanvasElement } | { error: string }> {
// detection happens inside a promise
return new Promise(async (resolve) => {
this.state = 'config';

30
types/human.d.ts vendored
View File

@ -15,7 +15,7 @@ declare class Human {
state: string;
image: {
tensor: any;
canvas: any;
canvas: OffscreenCanvas | HTMLCanvasElement;
};
tf: typeof tf;
draw: typeof draw;
@ -39,8 +39,8 @@ declare class Human {
hand: typeof handpose;
};
sysinfo: {
platform: any;
agent: any;
platform: string;
agent: string;
};
constructor(userConfig?: {});
profileData(): {
@ -52,18 +52,26 @@ declare class Human {
slowestKernelOps: any;
largestKernelOps: any;
} | {};
simmilarity(embedding1: any, embedding2: any): number;
simmilarity(embedding1: Array<number>, embedding2: Array<number>): number;
enhance(input: any): any;
load(userConfig?: null): Promise<void>;
detect(input: any, userConfig?: {}): Promise<{
face: any;
body: any;
hand: any;
gesture: any;
performance: any;
canvas: any;
face: Array<{
any: any;
}>;
body: Array<{
any: any;
}>;
hand: Array<{
any: any;
}>;
gesture: Array<{
any: any;
}>;
performance: object;
canvas: OffscreenCanvas | HTMLCanvasElement;
} | {
error: any;
error: string;
}>;
warmup(userConfig: any): Promise<{
face: any;

2
wiki

@ -1 +1 @@
Subproject commit ac5d01255f2f02de6b308b82976c5866c458f149
Subproject commit cdd53841d5adf0542379c87b52919ea12a02335d