feat: 完善淘宝小程序拍照、报告与登录流程

接入本地实时识别和自动三连拍,调整报告裁切、商品跳转、分享标题及居中页眉;完善游客会话、后台渠道隔离、部署脚本与回归测试。
This commit is contained in:
xsl
2026-11-04 15:07:51 +08:00
parent 381da60ae4
commit 774376fa16
147 changed files with 17420 additions and 597 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Vincent Mühler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Portions Copyright (c) Microsoft Corporation.
Portions Copyright 2017 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+242
View File
@@ -0,0 +1,242 @@
# Local tensor face engine
Runtime adapter: `taobao/utils/native-face.js`.
The vendor bundle, tiny detector and full 68-point model come from the existing,
unchanged `h5/vendor/faceapi/` files. The added tiny 68-point model is downloaded
only from the same official upstream's `weights/` directory; its manifest,
77224-byte shard and source URLs/hashes are in `reference/native-face-models/`.
Upstream is
https://github.com/justadudewhohacks/face-api.js. MIT and TensorFlow Apache 2.0
licenses are included; original inline Google/Microsoft notices are retained.
Build or verify from the repository root:
```
node taobao/scripts/build-native-face.cjs
node taobao/scripts/build-native-face.cjs --check
node --test taobao/test/native-face.test.cjs
node taobao/scripts/benchmark-native-face.cjs --repeats=2
node taobao/scripts/benchmark-native-face.cjs --guided --input-sizes=256,160,128 --repeats=2
```
`provenance.json` records every source file's SHA-256 and byte length. The
quantized model bytes total 627385 bytes including the optional full model;
the default tiny detector plus tiny landmark weights total 270545 bytes.
Base64 and manifests are packaged in
one CJS module. Runtime decoding uses typed arrays, with no filesystem or Buffer.
The generated face-api copy has a private TFJS global registry and shadows Node
`process`/`Buffer`. Optional Node-only imports (`crypto`, `node-fetch`, `util`,
`fs`) are replaced with functions that explicitly throw if reached. The
tfjs-node help-string reference is also replaced. The build fails if an
unreviewed static `require()` remains, because the IDE resolves unreachable
imports too. No Node polyfill or native AI plugin is bundled.
Create an engine with `create({defaultPixelFormat:'RGBA', maxSide:320,
inputSize:160, landmarkModel:'tiny', scoreThreshold:0.35})`; these are the
defaults. `landmarkModel:'full'` remains available for controlled comparisons.
The runtime default backend remains `cpu` for compatibility. Select WebGL
explicitly with `create({backend:'webgl', platform:my, ...})`; no unsupported
WebGL request silently falls back to the CPU profile that was too slow on phone.
`init()` returns a Promise with backend, inputSize, maxSide, landmarkModel and
cpuOptimization. `detect(frame)` returns a Promise with original width,
height, total faceCount and at most two complete detections. Each detection has
`detection.{box:{x,y,width,height},score}` and `landmarks.positions` containing
68 `{x,y}` points. All coordinates refer to original raw frame pixels; no
mirroring, rotation or preview crop is applied. Two complete detections suffice
for the existing multiple-person rejection gate.
Input must have integer width/height in 1..4096 and tightly packed four-channel
data in an ArrayBuffer or typed-array view. RGBA, BGRA, ARGB, ABGR and their
8888 aliases are supported. An explicit format is authoritative: the configured
default only fills missing metadata. Unknown formats (including NV/YUV), a
stride/bytesPerRow other than width*4, and a nonzero rotation marker are rejected.
`detect()` synchronously snapshots only the downsampled RGB before returning,
so native buffer reuse cannot change a queued inference. All model operations
use the CPU backend. The lower-level tensor crop/landmark path avoids the
high-level `withFaceLandmarks()` canvas dependency. Concurrent inference rejects
with `NATIVE_FACE_BUSY`. `dispose()` is idempotent; pending work rejects with
`NATIVE_FACE_DISPOSED`, and tensors are released after that work settles. The
last engine instance releases the shared model tensors. `stats()` returns only
backend, selected configuration, memory counters and lifecycle booleans.
The CPU `pad-copy` specialization copies contiguous source blocks into the
already zero-filled output tensor. It preserves the original pad values exactly;
unhandled scalar/complex inputs fall back to the bundled implementation. Disable
it with `cpuOptimization:false` (`cpuOptimization:'none'` in returned diagnostics).
It does not change model arithmetic or relax quality/freshness gates. The trial
1x1 convolution specialization showed no stable benefit and was removed.
`detect()` additionally returns inputSize, maxSide, landmarkModel,
cpuOptimization and `timings.{snapshotMs,modelMs,tensorMs,detectorMs,landmarkMs,
totalMs}` in milliseconds. `elapsedMs` remains total elapsed wall time; source
frame age must still be calculated from the camera's frame arrival time.
Tests run the real models without document, Image, canvas, fetch, process,
Buffer or host Node imports. The local face fixture derives from the already
present reference SDK example `C3_180.jpg`; it is never transmitted. Tests check
actual positive face detection and 68 points, all supported byte layouts,
original-coordinate scaling, concurrent/disposed calls, native buffer reuse,
and zero tensors after final disposal. The pad kernel is tested bit-for-bit
against original CPU pad across ranks 1–4, dtypes and padding/constants; the
real full-model detection and all 68 points are identical with it enabled or
disabled. An aspect-preserving two-face composition must reach the actual
native-face-quality single-person rejection gate. Tests print timings/counts,
never the image or point coordinates.
Desktop no-DOM VM stage measurements on the same 540×960 portrait reference
(two samples per profile): old full/256/no specialization took about 934 ms
(detector 730, landmarks 189, snapshot 16). Tiny/160/pad-copy took about 302 ms
(detector 188, landmarks 99, snapshot 15), about 3.1× faster. Default model
tensors occupy 1082180 bytes (47 tensors), versus full's 2200644 bytes (68).
The original small face ratio was 0.208, below the H5 near gate of 0.30. With
an aspect-preserving crop targeting a valid larger face, tiny/128 can detect
one face and 68 points in about 254 ms; however, 128 misses one person in the
two-face regression while 160 detects both. Therefore 160 remains the default.
Reducing maxSide from 320 to 192 saved only about 24 ms on the eligible portrait;
320 is retained for landmark detail. These are desktop CPU observations, not
phone performance guarantees. Benchmark flags `--baseline-cpu`, `--max-side=192`
and `--input-sizes=160,128` support reproducing the separate comparisons. A zero
face result is explicitly flagged by `allSamplesDetected:false`, not a speed win.
## Explicit WebGL candidate
`utils/native-face-webgl.js` obtains an owned logical-layer Canvas using the
official synchronous `my.createOffscreenCanvas(32,32)` and
`getContext('webgl',{enable_flip_y_after_read_pixels:false})`.
The host app must enable its documented Skia capability. The adapter injects the
actual GL1 context into the bundled TFJS backend; it never forges HAS_WEBGL or
float-extension ENV flags. Initialization runs a 16×16 matrix product, a
four-channel convolution, numerical readback checks and observed real shader
draw/readPixels counters. A missing or readonly instrumentable native API fails
explicitly; the adapter does not report GPU success from API names alone.
The current device candidate is `LOCAL-FACE-20261102-07`. The preceding `03`
candidate executed four matrix shader draws on the iPhone, then failed the
strict numerical check with `MATMUL_FAILED`; it did not process camera frames.
Candidate `04` tried `default`, `packed_byte` (disables float downloads),
then `unpacked_byte` (also disables packed shaders). Each attempt runs the same
matrix/convolution/readback checks with the original numerical tolerance. A
failed attempt releases its backend and tracked GL objects before the next
attempt. Only numerical/readback failures permit another profile; missing APIs,
context loss and resource errors stop explicitly. There is no CPU fallback.
All three profiles failed on the device in `04`. The final unpacked byte
attempt observed five draws, one byte read, checksum 0 versus expected 2786,
244 mismatches and maximum absolute error 22. These aggregate values have an
all-zero signature; they do not by themselves prove every output value is zero
or identify the cause. Real camera frames were never processed.
Candidate `05` disables the host's extra readPixels flip using the documented
[Taobao context option](https://developer.alibaba.com/docs/doc.htm?articleId=121761&docType=1&treeId=829).
A canvas-height-based read-coordinate conversion with a smaller framebuffer can
produce zero output in an isolated experiment; that is a testable hypothesis,
not a confirmed description of the device implementation. Before TFJS setup,
the adapter checks a 2×2 RGBA8 framebuffer with clear/readback, an asymmetric
shader pattern, byte-texture sampling and float-texture sampling. Fixed nonzero
synthetic inputs and a prefilled destination sentinel distinguish an unchanged
typed array from incorrect GPU output. Any failed preflight stops initialization
and releases its graphics objects. Passing this preflight does not replace the
original matrix/convolution numerical checks, compatibility selection or model
warmup.
On the device, `05` passed clear/readback but failed the asymmetric shader with
three mismatches: expected checksum 2244, actual 2040. The actual checksum equals
the preceding clear color's checksum. This is consistent with no draw coverage,
but does not uniquely distinguish coverage, coordinates, typed-buffer uploads
or GL state. Real camera inference still did not start.
Candidate `06` explicitly initializes drawing state and clears to black before
each draw. It first checks a constant-color `drawArrays` pass and then an indexed
pass, followed by the original asymmetric shader and byte/float texture tests.
It verifies native strategies in order: `standard`, `buffer_copy` (tightly copy
a view's bytes into an ArrayBuffer for standard bufferData upload),
`framebuffer_y` (compensate viewport/scissor Y only for a bound framebuffer),
then `combined`. These are candidates selected by actual numerical checks, not
assumptions based on phone model. Only `VALUE_MISMATCH` permits another native
strategy; all other failures stop. All four native strategies share one context
and release each probe's objects before the next. The TF profiles still create
at most three contexts. A selected native strategy must pass every native test,
then the unchanged strict matrix/convolution tests and real-model warmup.
The source frame freshness limit remains 1500 ms. Device strategy selection,
compatibility, speed and automatic capture still need phone acceptance.
Candidate `06` failed on the device after its standard constant-array draw
passed: `nativeInitialStage=constant_indexed`. The later coordinate candidate's
black output is not the original failure. Candidate `07` first rebinds the
element buffer immediately before indexed draws. If the indexed result still
fails while the array draw passed, it verifies a four-vertex triangle strip as
an alternative. Strip probes report `constantQuad:passed` and leave
`constantIndexed:not_run`; `drawStrategy:quad_strip` identifies the physical
method without claiming the native indexed API passed.
Only the owned quad with uploaded indices `[0,1,2,2,1,3]` and exact
`TRIANGLES/6/UNSIGNED_SHORT/offset0` arguments can be converted. Upload bytes
are checked within typed-view bounds. Unknown buffers, different signatures,
numeric allocations and buffers modified with bufferSubData are refused;
deletion invalidates the record. This matches the pinned upstream
[quad data](https://raw.githubusercontent.com/tensorflow/tfjs/tfjs-core-v1.7.0/tfjs-core/src/backends/webgl/gpgpu_util.ts)
and retains the original tensor checks and model warmup. Native strategies can
each add a verified strip attempt, up to eight probes on the same context.
This is an experimental device compatibility path, not an assertion that the
Taobao indexed API is generally unsupported. Phone success and speed remain
unverified.
After the numerical checks, initialization loads the selected real models and
warms both the detector on synthetic portrait black pixels and the landmark
network on a synthetic tensor crop. Warmup results are discarded and never
count as user face/pose data. Only after the warmup does initialization return
`backend:'webgl'`, `gpu.selftest:'passed'` and `gpu.stage:'ready'`. The source
frame age and 1500 ms capture gate remain the camera's responsibility.
The returned `gpu` record contains fixed stage/code/profile enums, booleans,
counts and metrics computed only from the fixed synthetic selftest arrays:
requested, selftest, stage, code, contextLost, profile, attemptCount,
matmulDraws, convDraws, pixelReads, floatReads, byteReads, selftestMs and
warmupMs. Each synthetic matrix/convolution record reports actual length,
nonfinite/mismatch counts, maximum absolute error, first expected/actual values
and expected/actual checksums. The camera caches those synthetic metrics,
profile, attempts and read counts only during initialization; later detection
results cannot replace them in copied diagnostics. Errors use
`NATIVE_FACE_WEBGL_*` codes and the same safe record. Native error strings,
renderer strings, image pixels and coordinates do not enter that record. Each
detect checks actual context-loss state before and after model work; a lost
backend must be retired and rebuilt.
The startup record also includes the fixed-input `nativeProbe` stage/result,
sentinel-change and mismatch counts, expected/actual checksums, read return-kind
enum, GL error and framebuffer status. The record also preserves
`nativeInitialStage`/`nativeInitialCode`, selected `nativeStrategy`,
`constantArrays`/`constantIndexed`, optional vertex/index buffer byte counts and
`pixel0` through `pixel3` as big-endian RGBA uint32 values from fixed synthetic
input only. TFJS readback state is collected before
throwing for a numerical mismatch, so a failing value no longer hides a native
GL error. These fields are cached only during initialization and cannot be
replaced by real-camera inference results.
A shared live engine group admits one backend kind at a time. Initialization,
model loading, warmup and inference are queued; decoded weights are not reused
across a CPU/WebGL switch. Disposal waits for pending work, then releases model
tensors, backend programs/textures, the externally supplied GPGPUContext and all
remaining tracked GL objects including TFJS 1.7's vertex buffer/shader leftovers.
Native cleanup exceptions are isolated so they cannot preserve a busy lock or
replace the original inference error.
```
node --test taobao/test/native-face.test.cjs taobao/test/native-face-webgl.test.cjs
```
The WebGL tests run packaged modules with DOM/Node environment names hidden,
explicitly supply real headless WebGL1 and abort all network routes. They cover
numerical shader/readback, corrupted FLOAT readback followed by packed byte
readback, two failed contexts followed by unpacked byte readback, and all three
profiles failing closed. Both compatible paths run the real 68-point model and
are compared with CPU face boxes, confidence and landmark geometry. They also
cover context loss, initialization failure, shared engines, deferred disposal
and rebuilding, with zero final
tensors and tracked GL objects. Desktop SwiftShader proves the computation and
lifecycle paths; it does not establish native Taobao iPhone compatibility or
phone inference speed. Those still require the device's actual diagnostics.
File diff suppressed because one or more lines are too long
+70
View File
@@ -0,0 +1,70 @@
{
"source": "Existing h5/vendor/faceapi (unchanged) plus official upstream tiny 68 model in reference/native-face-models",
"upstream": "https://github.com/justadudewhohacks/face-api.js",
"build": "node taobao/scripts/build-native-face.cjs",
"verify": "node taobao/scripts/build-native-face.cjs --check",
"modifications": [
"Module-local TFJS registry",
"Shadow process and Buffer to keep Node branches inactive",
"Node-only require calls replaced with explicit unsupported stubs"
],
"nodeOnlyStubs": {
"crypto": 1,
"@tensorflow/tfjs-node": 1,
"node-fetch": 1,
"util": 1,
"fs": 1
},
"quantizedBytes": 627385,
"sourceFiles": [
{
"path": "h5/vendor/faceapi/models/tiny_face_detector_model-weights_manifest.json",
"bytes": 2953,
"sha256": "14c60659a31b6b7b1320077171b8f8adcb24ef0e62dde62ce603bcb49a1b49b5"
},
{
"path": "h5/vendor/faceapi/models/tiny_face_detector_model-shard1",
"bytes": 193321,
"sha256": "b7503ce7df31039b1c43316a9b865cab6a70dd748cc602d3fa28b551503c3871"
},
{
"path": "h5/vendor/faceapi/models/face_landmark_68_model-weights_manifest.json",
"bytes": 7889,
"sha256": "d30f6cc341009ea4f8223876959289b96576fc54a2615f92da9741ab9c5f0bbc"
},
{
"path": "h5/vendor/faceapi/models/face_landmark_68_model-shard1",
"bytes": 356840,
"sha256": "4611ef65c87d836d03d684b30eec4d195d8b219fa1dd58fc58945831c6b9299b"
},
{
"path": "reference/native-face-models/face_landmark_68_tiny_model-weights_manifest.json",
"bytes": 4441,
"sha256": "3c63b8984302c187b218d9ef5aa149ed8c2c7fa3fe54db078614692bc48d153c"
},
{
"path": "reference/native-face-models/face_landmark_68_tiny_model-shard1",
"bytes": 77224,
"sha256": "b98e9f2f7da76f8a6dda9741a36ed485b224b889d552de2b2c1bb16217f67bfc"
},
{
"path": "h5/vendor/faceapi/face-api.js",
"bytes": 859250,
"sha256": "24e27b366566d9c871619d4a3dc0187766f054aecd6858fd40a329ec30a57b0b"
}
],
"downloadedSources": [
{
"file": "face_landmark_68_tiny_model-weights_manifest.json",
"source": "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_landmark_68_tiny_model-weights_manifest.json",
"bytes": 4441,
"sha256": "3c63b8984302c187b218d9ef5aa149ed8c2c7fa3fe54db078614692bc48d153c"
},
{
"file": "face_landmark_68_tiny_model-shard1",
"source": "https://raw.githubusercontent.com/justadudewhohacks/face-api.js/master/weights/face_landmark_68_tiny_model-shard1",
"bytes": 77224,
"sha256": "b98e9f2f7da76f8a6dda9741a36ed485b224b889d552de2b2c1bb16217f67bfc"
}
]
}
File diff suppressed because one or more lines are too long