mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-12 15:26:16 -08:00
build(site): [SITE-07] verify modified forks and preserve upstream author notices
This commit is contained in:
1 parent
d2a83f8a69
commit
3136eb2402
31 files changed
+2567
-23
No files matched your search
@@ -28,3 +28,4 @@ refactor/baselines/site-vendor/console-commonjs/** -text whitespace=-trailing-sp
|
||||
refactor/baselines/site-vendor/console-esm/** -text whitespace=-trailing-space,cr-at-eol
|
||||
refactor/baselines/site-vendor/console-embedded/** -text whitespace=-trailing-space,cr-at-eol
|
||||
docs/licenses/console/** -text whitespace=-trailing-space,cr-at-eol
|
||||
refactor/baselines/site-vendor/console-attribution/** -text whitespace=-trailing-space,cr-at-eol
|
||||
@@ -80,7 +80,7 @@ Source: https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.26.tgz
|
||||
|
||||
Source: https://github.com/zhw2590582/ArtPlayer/blob/5d6b2f22bc75213ac97cff0bcffa4a1ce2bc786c/docs/assets/js/console.js
|
||||
|
||||
The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance.
|
||||
The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance. Modified replicator and Emotion/Stylis copies retain upstream author licenses; the original Emotion online Closure stage is not claimed to be reproducible. MurmurHash credits include Gary Court and Austin Appleby.
|
||||
|
||||
Included component: console-feed 3.2.2
|
||||
|
||||
@@ -234,6 +234,22 @@ Included component: simple-html-tokenizer git-04799f4638ec5ed903a4e5aa6e832269fa
|
||||
|
||||
Source: https://api.github.com/repos/nfrasser/simple-html-tokenizer/tarball/04799f4638ec5ed903a4e5aa6e832269fa59be6b
|
||||
|
||||
Included component: replicator (console-feed fork) modified; upstream 1.0.x license
|
||||
|
||||
Source: https://registry.npmjs.org/replicator/-/replicator-1.0.1.tgz
|
||||
|
||||
Included component: stylis (Emotion fork) 3.5.4-derived
|
||||
|
||||
Source: https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz
|
||||
|
||||
Included component: murmurhash-js (Gary Court) license commit 23dc2e7
|
||||
|
||||
Source: https://github.com/garycourt/murmurhash-js/blob/23dc2e7008582ca3ef69d8623f02bba4c8dd05e5/README.md
|
||||
|
||||
Included component: murmurhash2 (Austin Appleby) 61a0530
|
||||
|
||||
Source: https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp
|
||||
|
||||
- licenses/console/console-feed/console-feed-3.2.2-LICENSE
|
||||
- licenses/console/react/react-17.0.2-LICENSE
|
||||
- licenses/console/react-dom/react-dom-17.0.2-LICENSE
|
||||
@@ -272,3 +288,7 @@ Source: https://api.github.com/repos/nfrasser/simple-html-tokenizer/tarball/0479
|
||||
- licenses/console/react-inspector-babel/LICENSE
|
||||
- licenses/console/regenerator-runtime/LICENSE
|
||||
- licenses/console/simple-html-tokenizer/LICENSE
|
||||
- licenses/console/replicator/LICENSE
|
||||
- licenses/console/stylis/LICENSE
|
||||
- licenses/console/murmurhash-js/README.md
|
||||
- licenses/console/murmurhash2/PUBLIC-DOMAIN.txt
|
||||
@@ -0,0 +1,20 @@
|
||||
# MurmurHash.js
|
||||
|
||||
An optimized JavaScript implementation of the MurmurHash algorithms.
|
||||
|
||||
These algorithms take a JavaScript string (and a seed), and quickly create a non-cryptographic 32-bit hash from it. And by quick I mean sub-millisecond performance.
|
||||
|
||||
More information about these algorithms can be found at:
|
||||
|
||||
* [MurmurHash Homepage](http://sites.google.com/site/murmurhash/)
|
||||
* [Wikipedia Entry on MurmurHash](http://en.wikipedia.org/wiki/MurmurHash)
|
||||
|
||||
## License (MIT)
|
||||
|
||||
Copyright (c) 2011 Gary Court
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,2 @@
|
||||
// MurmurHash2 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Ivan Nikulin (ifaaan@gmail.com, https://github.com/inikulin)
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Sultan Tarimo
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,163 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"task": "SITE-07",
|
||||
"archives": [
|
||||
{
|
||||
"id": "replicator-1.0.1",
|
||||
"name": "replicator",
|
||||
"version": "1.0.1",
|
||||
"tarball": "https://registry.npmjs.org/replicator/-/replicator-1.0.1.tgz",
|
||||
"integrity": "sha512-BwkUVdSQ08mGLa1OoP8thQ0zTUcxplGNZ1p0rsaSEL7xc4N3v5kkR/WFLjikkdjQPjp+67p24QOerWwIj2oN4g==",
|
||||
"sha256": "2baede665f8f4899b7196251e39c775ee0111872f04afef08ab5e2e6ada70925",
|
||||
"notices": [
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/replicator-1.0.1-LICENSE.txt",
|
||||
"member": "package/LICENSE",
|
||||
"sha256": "52f634086a97b3861a35afff7acf703ddbd5add8e617f6a1f540ae2f2c621284"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "stylis-3.5.4",
|
||||
"name": "stylis",
|
||||
"version": "3.5.4",
|
||||
"tarball": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
|
||||
"integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==",
|
||||
"sha256": "8e378e277ef50bd5282045dfac95019e66986d7d3819205a9e99c93220e3e950",
|
||||
"notices": [
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/stylis-3.5.4-LICENSE.txt",
|
||||
"member": "package/LICENSE.md",
|
||||
"sha256": "045109dfd0547aa898408d08593e1adc41e9705519ba8a20baff89e7c6c52e91"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"compiler": {
|
||||
"archive": {
|
||||
"id": "typescript-4.1.2",
|
||||
"name": "typescript",
|
||||
"version": "4.1.2",
|
||||
"tarball": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz",
|
||||
"integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==",
|
||||
"sha256": "383b18630fc00016cb7bde65f111e79d43fccb8c025faf33d7a3a07a5abdf026"
|
||||
},
|
||||
"member": "package/lib/typescript.js",
|
||||
"sha256": "7fb17b02f99364980c5f8540175309b09932f8fad41dcc7e9429d335535604e0",
|
||||
"version": "4.1.2",
|
||||
"options": {
|
||||
"target": 0,
|
||||
"module": 1,
|
||||
"newLine": 1
|
||||
}
|
||||
},
|
||||
"remotes": [
|
||||
{
|
||||
"id": "replicator-source",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/replicator-source.txt",
|
||||
"sha256": "2bf53776cfd80aaf6365d4419ab910ca282db649fc942ac285765748db6f875e",
|
||||
"gitBlobSha": "7399074f5c003120d17d9bb48e6b0832434d64dc",
|
||||
"apiUrl": "https://api.github.com/repos/samdenty/console-feed/contents/src/Transform/replicator/index.ts?ref=de41ef2662019c645a652199d9bdbbfc71419f5e",
|
||||
"url": "https://github.com/samdenty/console-feed/blob/de41ef2662019c645a652199d9bdbbfc71419f5e/src/Transform/replicator/index.ts"
|
||||
},
|
||||
{
|
||||
"id": "emotion-build",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/emotion-build.txt",
|
||||
"sha256": "7d9a3d176b6da384d729d45f7e36dec6cd6effb85cd19d486f4f50af5cf2925f",
|
||||
"gitBlobSha": "fdd877e14000329ff556ca2f1aa7fc44c724060d",
|
||||
"apiUrl": "https://api.github.com/repos/emotion-js/emotion/git/blobs/fdd877e14000329ff556ca2f1aa7fc44c724060d",
|
||||
"url": "https://github.com/emotion-js/emotion/blob/6dd425bd1b8db7ab5144cca81b592639a68af2cb/packages/stylis/build.js"
|
||||
},
|
||||
{
|
||||
"id": "emotion-stylis-source",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/emotion-stylis-source.txt",
|
||||
"sha256": "2d49f50cb973b395bb30ca1d03955599e6220dd347d57ae38324afe8c734506a",
|
||||
"gitBlobSha": "c6b56ec79517a0dce4b84eceb15acb4730e04101",
|
||||
"apiUrl": "https://api.github.com/repos/emotion-js/emotion/git/blobs/c6b56ec79517a0dce4b84eceb15acb4730e04101",
|
||||
"url": "https://github.com/emotion-js/emotion/blob/6dd425bd1b8db7ab5144cca81b592639a68af2cb/packages/stylis/src/stylis.min.js"
|
||||
},
|
||||
{
|
||||
"id": "gary-readme",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/gary-readme.txt",
|
||||
"sha256": "73b67c593a2a0d6395bfe90d3bad32556ed5e7ce71883062efebc643d4e4b7b4",
|
||||
"gitBlobSha": "567ae1bca393a150e129cec8d60230a7b88e77c7",
|
||||
"apiUrl": "https://api.github.com/repos/garycourt/murmurhash-js/contents/README.md?ref=23dc2e7008582ca3ef69d8623f02bba4c8dd05e5",
|
||||
"url": "https://github.com/garycourt/murmurhash-js/blob/23dc2e7008582ca3ef69d8623f02bba4c8dd05e5/README.md"
|
||||
},
|
||||
{
|
||||
"id": "smhasher",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/smhasher.txt",
|
||||
"sha256": "8cdec1fed73de41e4ee91ab78fe5ba76110582263064dcdcc0b770a25c0573f3",
|
||||
"gitBlobSha": "cd1e53a9b92620d2656eae423017f81be1fb3ad1",
|
||||
"apiUrl": "https://api.github.com/repos/aappleby/smhasher/contents/src/MurmurHash2.cpp?ref=61a0530f28277f2e850bfc39600ce61d02b518de",
|
||||
"url": "https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp"
|
||||
}
|
||||
],
|
||||
"replicator": {
|
||||
"source": "replicator-source",
|
||||
"target": {
|
||||
"archive": "console-feed-3.2.2",
|
||||
"member": "package/lib/Transform/replicator/index.js",
|
||||
"sha256": "33ea546afdd46833594d7cdccbfc45dc654b8e9fa737d9ee5d940b6f164dba6b"
|
||||
},
|
||||
"upstream": {
|
||||
"archive": "replicator-1.0.1",
|
||||
"member": "package/index.js",
|
||||
"sha256": "7b0f488ae3581c23d252ac5c73fd6ae35884d876bfd8e186d23bbfa5847430d7"
|
||||
},
|
||||
"scope": "Modified fork of the replicator 1.0.x source family; the MIT notice is taken from 1.0.1, not a claim that npm 1.0.1 is installed or identical. The fixed console-feed TS revision compiles to the exact runtime before the original inline source map."
|
||||
},
|
||||
"stylis": {
|
||||
"source": "emotion-stylis-source",
|
||||
"target": {
|
||||
"archive": "%40emotion%2Fstylis-0.8.5",
|
||||
"member": "package/src/stylis.min.js",
|
||||
"sha256": "2d49f50cb973b395bb30ca1d03955599e6220dd347d57ae38324afe8c734506a"
|
||||
},
|
||||
"dependency": {
|
||||
"archive": "%40emotion%2Fstylis-0.8.5",
|
||||
"member": "package/package.json",
|
||||
"sha256": "1da8e474cb88a0070baa42cec78a3704dea0889c4decdb38d4e7b7489c83c8b0"
|
||||
},
|
||||
"dependencyVersion": "3.5.4",
|
||||
"recipe": "emotion-build",
|
||||
"scope": "Fixed tag commit source matches npm source exactly. Its original recipe modifies Stylis and calls an unversioned online Closure compiler; this earlier compiler stage was not rerun."
|
||||
},
|
||||
"hash": {
|
||||
"source": "smhasher",
|
||||
"notice": {
|
||||
"archive": "aappleby/smhasher@61a0530f28277f2e850bfc39600ce61d02b518de",
|
||||
"member": "src/MurmurHash2.cpp",
|
||||
"memberSha256": "8cdec1fed73de41e4ee91ab78fe5ba76110582263064dcdcc0b770a25c0573f3",
|
||||
"sourceSha256": "8cdec1fed73de41e4ee91ab78fe5ba76110582263064dcdcc0b770a25c0573f3",
|
||||
"start": "// MurmurHash2 was written by Austin Appleby, and is placed in the public",
|
||||
"end": "// domain. The author hereby disclaims copyright to this source code.\n",
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/murmurhash2-public-domain.txt",
|
||||
"sha256": "50e13b0a1963f0b382255d2425df245dbdfd209201621e8c157687caedbbb949"
|
||||
},
|
||||
"reference": {
|
||||
"archive": "%40emotion%2Fhash-0.8.0",
|
||||
"member": "package/dist/hash.browser.esm.js",
|
||||
"sha256": "3f6d63bdf3241054ccac29fa5bad7ca228bb889a51214e22224a8fe8c6d3573d"
|
||||
},
|
||||
"references": [
|
||||
"https://github.com/garycourt/murmurhash-js",
|
||||
"61a0530f28277f2e850bfc39600ce61d02b518de"
|
||||
]
|
||||
},
|
||||
"cache": {
|
||||
"reference": {
|
||||
"archive": "%40emotion%2Fcache-10.0.29",
|
||||
"member": "package/dist/cache.browser.esm.js",
|
||||
"sha256": "7df64362f28f43e9af8dda5dc5edc2b3c4ecb094101f7c723bc9ef03f40767f0"
|
||||
},
|
||||
"upstreamUrl": "https://github.com/thysultan/stylis.js/tree/master/plugins/rule-sheet",
|
||||
"notice": "docs/licenses/console/stylis-rule-sheet/LICENSE"
|
||||
},
|
||||
"limitations": [
|
||||
"No replacement or execution of archived runtime libraries.",
|
||||
"Replicator is a modified fork; neither a unique npm fork base nor the entire original install lock is claimed.",
|
||||
"Emotion historical online Closure service was not re-executed; its published source is pinned to the matching upstream tag commit.",
|
||||
"Stack Overflow attribution and final remaining embedded-source review stay open."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"task": "SITE-07",
|
||||
"status": "checkpoint-incomplete",
|
||||
"recordedAt": "2026-09-14T23:49:08.277Z",
|
||||
"baseCommit": "d2a83f8a69c7a5d9a8bf30c9b370e573034f2000",
|
||||
"node": "v24.21.0",
|
||||
"sourceFingerprint": {
|
||||
"manifestSha256": "c0238bf1acb77ddf931c4b8702a1dc4d3ea341b525c23c78e000fff0d8109fec",
|
||||
"sourceRecordSha256": "d8d5237cf261177b571b07eec17acb11f7b3905a98a2aa0675b366b8d21d7b12",
|
||||
"consoleSha256": "5644af7bb35bb6d0bcfa7eeae9a21b406ac4fc1b499a6c797a6534c7d33f0678"
|
||||
},
|
||||
"unit": {
|
||||
"passed": 24,
|
||||
"failed": 0,
|
||||
"log": "refactor/.cache/console-derived-tests.log"
|
||||
},
|
||||
"reproduction": {
|
||||
"archives": 42,
|
||||
"exactModules": 100,
|
||||
"embeddedNotices": 2,
|
||||
"mappedMembers": 17,
|
||||
"transformedMembers": 7,
|
||||
"derivedGitSources": 5,
|
||||
"replicatorFork": true,
|
||||
"emotionStylisSource": true,
|
||||
"offlineLog": "refactor/.cache/console-derived-reproduce.log",
|
||||
"fetchLog": "refactor/.cache/console-derived-fetch.log",
|
||||
"licenseClosure": false
|
||||
},
|
||||
"browser": {
|
||||
"report": "refactor/.cache/browser/report.json",
|
||||
"sha256": "b902b3ac4e6f83a825112dda5f6ef815326c268893264c08d17bf2b44bb08cf0",
|
||||
"tests": [
|
||||
{
|
||||
"project": "chromium",
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"browser": "153.0.8010.12",
|
||||
"platform": "win32",
|
||||
"errors": [],
|
||||
"consoleErrors": [],
|
||||
"failedRequests": [
|
||||
{
|
||||
"url": "http://127.0.0.1:8084/test/pattern.mp4",
|
||||
"resourceType": "media",
|
||||
"failure": {
|
||||
"errorText": "net::ERR_ABORTED"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"project": "firefox",
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"browser": "155.0",
|
||||
"platform": "win32",
|
||||
"errors": [],
|
||||
"consoleErrors": [],
|
||||
"failedRequests": []
|
||||
},
|
||||
{
|
||||
"project": "webkit",
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"browser": "26.6",
|
||||
"platform": "win32",
|
||||
"errors": [],
|
||||
"consoleErrors": [],
|
||||
"failedRequests": []
|
||||
}
|
||||
],
|
||||
"noticeFilesPerEngine": 60
|
||||
},
|
||||
"checks": [
|
||||
"Strict docs-tools TypeScript",
|
||||
"Scoped source/test/maintenance ESLint",
|
||||
"Read-only console and site-notice generation checks"
|
||||
],
|
||||
"remaining": [
|
||||
"Component Stack Overflow attribution and final embedded-source review",
|
||||
"Other site asset provenance tasks"
|
||||
],
|
||||
"limits": [
|
||||
"Replicator is a modified source-family fork, not an unmodified npm 1.0.1 installation.",
|
||||
"Original Emotion online Closure compiler stage was not rerun; its generated source matches the immutable tag commit.",
|
||||
"No claim of the unique original full dependency lockfile.",
|
||||
"HTTPS integrations isolated; Windows local-page evidence does not replace physical-device or remote-publish validation.",
|
||||
"No runtime or lockfile changes, pushes, deployments or publications."
|
||||
]
|
||||
}
|
||||
@@ -30,11 +30,11 @@
|
||||
"Chromium copyright and full BSD conditions in console-feed source",
|
||||
"Sultan Tarimo MIT header in styled-components embedded rule-sheet source",
|
||||
"All seven linkifyjs simple-html-tokenizer files exactly reproduce from its fixed Git dependency with Babel 6.26.0; Yehuda Katz license preserved.",
|
||||
"All 17 react-inspector external source-map members exactly match Babel runtime 7.13.10 and regenerator-runtime 0.13.7; both licenses preserved."
|
||||
"All 17 react-inspector external source-map members exactly match Babel runtime 7.13.10 and regenerator-runtime 0.13.7; both licenses preserved.",
|
||||
"Modified replicator fork has fixed console-feed TS source matching the archived runtime, with Ivan Nikulin MIT attribution.",
|
||||
"Emotion Stylis pinned source and 3.5.4 dependency, rule-sheet source references, and MurmurHash references retain Sultan Tarimo, Gary Court and Austin Appleby notices; historical Closure stage not rerun."
|
||||
],
|
||||
"pending": [
|
||||
"console-feed replicator upstream attribution",
|
||||
"Emotion stylis/hash and cache rule-sheet attribution",
|
||||
"console-feed Component Stack Overflow attribution and any additional embedded sources"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
// this whole thing is a really fragile hack
|
||||
// but it works so ¯\_(ツ)_/¯
|
||||
|
||||
const stylisPath = require.resolve('stylis')
|
||||
const { promisify } = require('util')
|
||||
const j = require('jscodeshift')
|
||||
const request = require('request-promise-native')
|
||||
const fs = require('fs')
|
||||
const prettier = require('prettier')
|
||||
const recast = require('recast')
|
||||
|
||||
const readFile = promisify(fs.readFile)
|
||||
const writeFile = promisify(fs.writeFile)
|
||||
|
||||
const simplifySet = src =>
|
||||
j(src)
|
||||
.find(j.FunctionDeclaration, { id: { name: 'set' } })
|
||||
.forEach(path => {
|
||||
j(path).replaceWith(
|
||||
recast.parse(`function set(options) {
|
||||
var prefixOpt = options.prefix
|
||||
if (prefixOpt!==undefined) {
|
||||
should = null
|
||||
|
||||
if (!prefixOpt) {
|
||||
prefix = 0
|
||||
} else if (typeof prefixOpt !== 'function') {
|
||||
prefix = 1
|
||||
} else {
|
||||
prefix = 2
|
||||
should = prefixOpt
|
||||
}
|
||||
}
|
||||
return set
|
||||
}`).program.body[0]
|
||||
)
|
||||
})
|
||||
.toSource()
|
||||
|
||||
const removeOptions = src =>
|
||||
j(src)
|
||||
.find(j.SwitchStatement)
|
||||
.forEach(thing => {
|
||||
thing.value.cases = thing.value.cases.filter(node => {
|
||||
if (!node.test) return true
|
||||
switch (node.test.value) {
|
||||
case 'keyframe':
|
||||
case 'cascade':
|
||||
case 'preserve':
|
||||
case 'semicolon':
|
||||
case 'compress':
|
||||
case 'global': {
|
||||
return false
|
||||
}
|
||||
default: {
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.toSource()
|
||||
|
||||
const setOptions = src =>
|
||||
j(src)
|
||||
.find(j.VariableDeclarator)
|
||||
.forEach(path => {
|
||||
switch (path.value.id.name) {
|
||||
case 'escape':
|
||||
case 'keyed': {
|
||||
path.value.init.value = 0
|
||||
return
|
||||
}
|
||||
case 'semicolon': {
|
||||
path.value.init.value = 1
|
||||
}
|
||||
}
|
||||
})
|
||||
.toSource()
|
||||
|
||||
const removeUMDWrapper = src => {
|
||||
let code
|
||||
j(src)
|
||||
.find(j.FunctionExpression, { id: { name: 'factory' } })
|
||||
.forEach(path => {
|
||||
code = j(path).toSource()
|
||||
})
|
||||
.toSource()
|
||||
return "'use strict';\nwindow['stylis'] = " + code
|
||||
}
|
||||
|
||||
async function doThing() {
|
||||
const stylisSrc = (await readFile(stylisPath))
|
||||
.toString()
|
||||
.replace(
|
||||
'cascade + quote + bracket + atrule === 0 && id !== KEYFRAME && code !== SEMICOLON',
|
||||
'true === false'
|
||||
)
|
||||
.replace(
|
||||
'comment + quote + parentheses + bracket + semicolon === 0',
|
||||
'true === false'
|
||||
)
|
||||
.replace('switch (selector.charCodeAt(1))', 'switch (100)')
|
||||
.replace('(insert === 1)', '(true === false)')
|
||||
.replace('input.charCodeAt(9)*keyed', '0')
|
||||
.replace('switch (cascade + level) {', 'switch (2) {')
|
||||
.replace('compress*code === 0', 'true')
|
||||
.replace(`typeof(output = result) !== 'string'`, '(output = result)')
|
||||
// .replace("stylis['set'] = set", '')
|
||||
// .replace('set(options)', '')
|
||||
.replace('this !== void 0 && this.constructor === stylis', 'false')
|
||||
.replace('return factory(selector)', '')
|
||||
const result = removeUMDWrapper(
|
||||
simplifySet(setOptions(removeOptions(stylisSrc)))
|
||||
)
|
||||
// await writeFile('./src/stylis.js', result)
|
||||
console.log('start request')
|
||||
const data = (await request('https://closure-compiler.appspot.com/compile', {
|
||||
method: 'POST',
|
||||
form: {
|
||||
js_code: result,
|
||||
compilation_level: 'ADVANCED_OPTIMIZATIONS',
|
||||
output_format: 'text',
|
||||
output_info: 'compiled_code'
|
||||
}
|
||||
})).toString()
|
||||
|
||||
let finalSrc = data.replace('window.stylis=', 'export default ')
|
||||
|
||||
await writeFile(
|
||||
'./src/stylis.min.js',
|
||||
prettier.format(finalSrc, {
|
||||
semi: false,
|
||||
singleQuote: true
|
||||
})
|
||||
)
|
||||
|
||||
console.log('done')
|
||||
}
|
||||
|
||||
doThing()
|
||||
@@ -0,0 +1,625 @@
|
||||
export default function(W) {
|
||||
function M(d, c, e, h, a) {
|
||||
for (
|
||||
var m = 0,
|
||||
b = 0,
|
||||
v = 0,
|
||||
n = 0,
|
||||
q,
|
||||
g,
|
||||
x = 0,
|
||||
K = 0,
|
||||
k,
|
||||
u = (k = q = 0),
|
||||
l = 0,
|
||||
r = 0,
|
||||
I = 0,
|
||||
t = 0,
|
||||
B = e.length,
|
||||
J = B - 1,
|
||||
y,
|
||||
f = '',
|
||||
p = '',
|
||||
F = '',
|
||||
G = '',
|
||||
C;
|
||||
l < B;
|
||||
|
||||
) {
|
||||
g = e.charCodeAt(l)
|
||||
l === J &&
|
||||
0 !== b + n + v + m &&
|
||||
(0 !== b && (g = 47 === b ? 10 : 47), (n = v = m = 0), B++, J++)
|
||||
if (0 === b + n + v + m) {
|
||||
if (l === J && (0 < r && (f = f.replace(N, '')), 0 < f.trim().length)) {
|
||||
switch (g) {
|
||||
case 32:
|
||||
case 9:
|
||||
case 59:
|
||||
case 13:
|
||||
case 10:
|
||||
break
|
||||
default:
|
||||
f += e.charAt(l)
|
||||
}
|
||||
g = 59
|
||||
}
|
||||
switch (g) {
|
||||
case 123:
|
||||
f = f.trim()
|
||||
q = f.charCodeAt(0)
|
||||
k = 1
|
||||
for (t = ++l; l < B; ) {
|
||||
switch ((g = e.charCodeAt(l))) {
|
||||
case 123:
|
||||
k++
|
||||
break
|
||||
case 125:
|
||||
k--
|
||||
break
|
||||
case 47:
|
||||
switch ((g = e.charCodeAt(l + 1))) {
|
||||
case 42:
|
||||
case 47:
|
||||
a: {
|
||||
for (u = l + 1; u < J; ++u)
|
||||
switch (e.charCodeAt(u)) {
|
||||
case 47:
|
||||
if (
|
||||
42 === g &&
|
||||
42 === e.charCodeAt(u - 1) &&
|
||||
l + 2 !== u
|
||||
) {
|
||||
l = u + 1
|
||||
break a
|
||||
}
|
||||
break
|
||||
case 10:
|
||||
if (47 === g) {
|
||||
l = u + 1
|
||||
break a
|
||||
}
|
||||
}
|
||||
l = u
|
||||
}
|
||||
}
|
||||
break
|
||||
case 91:
|
||||
g++
|
||||
case 40:
|
||||
g++
|
||||
case 34:
|
||||
case 39:
|
||||
for (; l++ < J && e.charCodeAt(l) !== g; );
|
||||
}
|
||||
if (0 === k) break
|
||||
l++
|
||||
}
|
||||
k = e.substring(t, l)
|
||||
0 === q && (q = (f = f.replace(ca, '').trim()).charCodeAt(0))
|
||||
switch (q) {
|
||||
case 64:
|
||||
0 < r && (f = f.replace(N, ''))
|
||||
g = f.charCodeAt(1)
|
||||
switch (g) {
|
||||
case 100:
|
||||
case 109:
|
||||
case 115:
|
||||
case 45:
|
||||
r = c
|
||||
break
|
||||
default:
|
||||
r = O
|
||||
}
|
||||
k = M(c, r, k, g, a + 1)
|
||||
t = k.length
|
||||
0 < A &&
|
||||
((r = X(O, f, I)),
|
||||
(C = H(3, k, r, c, D, z, t, g, a, h)),
|
||||
(f = r.join('')),
|
||||
void 0 !== C &&
|
||||
0 === (t = (k = C.trim()).length) &&
|
||||
((g = 0), (k = '')))
|
||||
if (0 < t)
|
||||
switch (g) {
|
||||
case 115:
|
||||
f = f.replace(da, ea)
|
||||
case 100:
|
||||
case 109:
|
||||
case 45:
|
||||
k = f + '{' + k + '}'
|
||||
break
|
||||
case 107:
|
||||
f = f.replace(fa, '$1 $2')
|
||||
k = f + '{' + k + '}'
|
||||
k =
|
||||
1 === w || (2 === w && L('@' + k, 3))
|
||||
? '@-webkit-' + k + '@' + k
|
||||
: '@' + k
|
||||
break
|
||||
default:
|
||||
;(k = f + k), 112 === h && (k = ((p += k), ''))
|
||||
}
|
||||
else k = ''
|
||||
break
|
||||
default:
|
||||
k = M(c, X(c, f, I), k, h, a + 1)
|
||||
}
|
||||
F += k
|
||||
k = I = r = u = q = 0
|
||||
f = ''
|
||||
g = e.charCodeAt(++l)
|
||||
break
|
||||
case 125:
|
||||
case 59:
|
||||
f = (0 < r ? f.replace(N, '') : f).trim()
|
||||
if (1 < (t = f.length))
|
||||
switch (
|
||||
(0 === u &&
|
||||
((q = f.charCodeAt(0)), 45 === q || (96 < q && 123 > q)) &&
|
||||
(t = (f = f.replace(' ', ':')).length),
|
||||
0 < A &&
|
||||
void 0 !== (C = H(1, f, c, d, D, z, p.length, h, a, h)) &&
|
||||
0 === (t = (f = C.trim()).length) &&
|
||||
(f = '\x00\x00'),
|
||||
(q = f.charCodeAt(0)),
|
||||
(g = f.charCodeAt(1)),
|
||||
q)
|
||||
) {
|
||||
case 0:
|
||||
break
|
||||
case 64:
|
||||
if (105 === g || 99 === g) {
|
||||
G += f + e.charAt(l)
|
||||
break
|
||||
}
|
||||
default:
|
||||
58 !== f.charCodeAt(t - 1) &&
|
||||
(p += P(f, q, g, f.charCodeAt(2)))
|
||||
}
|
||||
I = r = u = q = 0
|
||||
f = ''
|
||||
g = e.charCodeAt(++l)
|
||||
}
|
||||
}
|
||||
switch (g) {
|
||||
case 13:
|
||||
case 10:
|
||||
47 === b
|
||||
? (b = 0)
|
||||
: 0 === 1 + q &&
|
||||
107 !== h &&
|
||||
0 < f.length &&
|
||||
((r = 1), (f += '\x00'))
|
||||
0 < A * Y && H(0, f, c, d, D, z, p.length, h, a, h)
|
||||
z = 1
|
||||
D++
|
||||
break
|
||||
case 59:
|
||||
case 125:
|
||||
if (0 === b + n + v + m) {
|
||||
z++
|
||||
break
|
||||
}
|
||||
default:
|
||||
z++
|
||||
y = e.charAt(l)
|
||||
switch (g) {
|
||||
case 9:
|
||||
case 32:
|
||||
if (0 === n + m + b)
|
||||
switch (x) {
|
||||
case 44:
|
||||
case 58:
|
||||
case 9:
|
||||
case 32:
|
||||
y = ''
|
||||
break
|
||||
default:
|
||||
32 !== g && (y = ' ')
|
||||
}
|
||||
break
|
||||
case 0:
|
||||
y = '\\0'
|
||||
break
|
||||
case 12:
|
||||
y = '\\f'
|
||||
break
|
||||
case 11:
|
||||
y = '\\v'
|
||||
break
|
||||
case 38:
|
||||
0 === n + b + m && ((r = I = 1), (y = '\f' + y))
|
||||
break
|
||||
case 108:
|
||||
if (0 === n + b + m + E && 0 < u)
|
||||
switch (l - u) {
|
||||
case 2:
|
||||
112 === x && 58 === e.charCodeAt(l - 3) && (E = x)
|
||||
case 8:
|
||||
111 === K && (E = K)
|
||||
}
|
||||
break
|
||||
case 58:
|
||||
0 === n + b + m && (u = l)
|
||||
break
|
||||
case 44:
|
||||
0 === b + v + n + m && ((r = 1), (y += '\r'))
|
||||
break
|
||||
case 34:
|
||||
case 39:
|
||||
0 === b && (n = n === g ? 0 : 0 === n ? g : n)
|
||||
break
|
||||
case 91:
|
||||
0 === n + b + v && m++
|
||||
break
|
||||
case 93:
|
||||
0 === n + b + v && m--
|
||||
break
|
||||
case 41:
|
||||
0 === n + b + m && v--
|
||||
break
|
||||
case 40:
|
||||
if (0 === n + b + m) {
|
||||
if (0 === q)
|
||||
switch (2 * x + 3 * K) {
|
||||
case 533:
|
||||
break
|
||||
default:
|
||||
q = 1
|
||||
}
|
||||
v++
|
||||
}
|
||||
break
|
||||
case 64:
|
||||
0 === b + v + n + m + u + k && (k = 1)
|
||||
break
|
||||
case 42:
|
||||
case 47:
|
||||
if (!(0 < n + m + v))
|
||||
switch (b) {
|
||||
case 0:
|
||||
switch (2 * g + 3 * e.charCodeAt(l + 1)) {
|
||||
case 235:
|
||||
b = 47
|
||||
break
|
||||
case 220:
|
||||
;(t = l), (b = 42)
|
||||
}
|
||||
break
|
||||
case 42:
|
||||
47 === g &&
|
||||
42 === x &&
|
||||
t + 2 !== l &&
|
||||
(33 === e.charCodeAt(t + 2) &&
|
||||
(p += e.substring(t, l + 1)),
|
||||
(y = ''),
|
||||
(b = 0))
|
||||
}
|
||||
}
|
||||
0 === b && (f += y)
|
||||
}
|
||||
K = x
|
||||
x = g
|
||||
l++
|
||||
}
|
||||
t = p.length
|
||||
if (0 < t) {
|
||||
r = c
|
||||
if (
|
||||
0 < A &&
|
||||
((C = H(2, p, r, d, D, z, t, h, a, h)),
|
||||
void 0 !== C && 0 === (p = C).length)
|
||||
)
|
||||
return G + p + F
|
||||
p = r.join(',') + '{' + p + '}'
|
||||
if (0 !== w * E) {
|
||||
2 !== w || L(p, 2) || (E = 0)
|
||||
switch (E) {
|
||||
case 111:
|
||||
p = p.replace(ha, ':-moz-$1') + p
|
||||
break
|
||||
case 112:
|
||||
p =
|
||||
p.replace(Q, '::-webkit-input-$1') +
|
||||
p.replace(Q, '::-moz-$1') +
|
||||
p.replace(Q, ':-ms-input-$1') +
|
||||
p
|
||||
}
|
||||
E = 0
|
||||
}
|
||||
}
|
||||
return G + p + F
|
||||
}
|
||||
function X(d, c, e) {
|
||||
var h = c.trim().split(ia)
|
||||
c = h
|
||||
var a = h.length,
|
||||
m = d.length
|
||||
switch (m) {
|
||||
case 0:
|
||||
case 1:
|
||||
var b = 0
|
||||
for (d = 0 === m ? '' : d[0] + ' '; b < a; ++b)
|
||||
c[b] = Z(d, c[b], e, m).trim()
|
||||
break
|
||||
default:
|
||||
var v = (b = 0)
|
||||
for (c = []; b < a; ++b)
|
||||
for (var n = 0; n < m; ++n) c[v++] = Z(d[n] + ' ', h[b], e, m).trim()
|
||||
}
|
||||
return c
|
||||
}
|
||||
function Z(d, c, e) {
|
||||
var h = c.charCodeAt(0)
|
||||
33 > h && (h = (c = c.trim()).charCodeAt(0))
|
||||
switch (h) {
|
||||
case 38:
|
||||
return c.replace(F, '$1' + d.trim())
|
||||
case 58:
|
||||
return d.trim() + c.replace(F, '$1' + d.trim())
|
||||
default:
|
||||
if (0 < 1 * e && 0 < c.indexOf('\f'))
|
||||
return c.replace(F, (58 === d.charCodeAt(0) ? '' : '$1') + d.trim())
|
||||
}
|
||||
return d + c
|
||||
}
|
||||
function P(d, c, e, h) {
|
||||
var a = d + ';',
|
||||
m = 2 * c + 3 * e + 4 * h
|
||||
if (944 === m) {
|
||||
d = a.indexOf(':', 9) + 1
|
||||
var b = a.substring(d, a.length - 1).trim()
|
||||
b = a.substring(0, d).trim() + b + ';'
|
||||
return 1 === w || (2 === w && L(b, 1)) ? '-webkit-' + b + b : b
|
||||
}
|
||||
if (0 === w || (2 === w && !L(a, 1))) return a
|
||||
switch (m) {
|
||||
case 1015:
|
||||
return 97 === a.charCodeAt(10) ? '-webkit-' + a + a : a
|
||||
case 951:
|
||||
return 116 === a.charCodeAt(3) ? '-webkit-' + a + a : a
|
||||
case 963:
|
||||
return 110 === a.charCodeAt(5) ? '-webkit-' + a + a : a
|
||||
case 1009:
|
||||
if (100 !== a.charCodeAt(4)) break
|
||||
case 969:
|
||||
case 942:
|
||||
return '-webkit-' + a + a
|
||||
case 978:
|
||||
return '-webkit-' + a + '-moz-' + a + a
|
||||
case 1019:
|
||||
case 983:
|
||||
return '-webkit-' + a + '-moz-' + a + '-ms-' + a + a
|
||||
case 883:
|
||||
if (45 === a.charCodeAt(8)) return '-webkit-' + a + a
|
||||
if (0 < a.indexOf('image-set(', 11))
|
||||
return a.replace(ja, '$1-webkit-$2') + a
|
||||
break
|
||||
case 932:
|
||||
if (45 === a.charCodeAt(4))
|
||||
switch (a.charCodeAt(5)) {
|
||||
case 103:
|
||||
return (
|
||||
'-webkit-box-' +
|
||||
a.replace('-grow', '') +
|
||||
'-webkit-' +
|
||||
a +
|
||||
'-ms-' +
|
||||
a.replace('grow', 'positive') +
|
||||
a
|
||||
)
|
||||
case 115:
|
||||
return (
|
||||
'-webkit-' + a + '-ms-' + a.replace('shrink', 'negative') + a
|
||||
)
|
||||
case 98:
|
||||
return (
|
||||
'-webkit-' +
|
||||
a +
|
||||
'-ms-' +
|
||||
a.replace('basis', 'preferred-size') +
|
||||
a
|
||||
)
|
||||
}
|
||||
return '-webkit-' + a + '-ms-' + a + a
|
||||
case 964:
|
||||
return '-webkit-' + a + '-ms-flex-' + a + a
|
||||
case 1023:
|
||||
if (99 !== a.charCodeAt(8)) break
|
||||
b = a
|
||||
.substring(a.indexOf(':', 15))
|
||||
.replace('flex-', '')
|
||||
.replace('space-between', 'justify')
|
||||
return '-webkit-box-pack' + b + '-webkit-' + a + '-ms-flex-pack' + b + a
|
||||
case 1005:
|
||||
return ka.test(a)
|
||||
? a.replace(aa, ':-webkit-') + a.replace(aa, ':-moz-') + a
|
||||
: a
|
||||
case 1e3:
|
||||
b = a.substring(13).trim()
|
||||
c = b.indexOf('-') + 1
|
||||
switch (b.charCodeAt(0) + b.charCodeAt(c)) {
|
||||
case 226:
|
||||
b = a.replace(G, 'tb')
|
||||
break
|
||||
case 232:
|
||||
b = a.replace(G, 'tb-rl')
|
||||
break
|
||||
case 220:
|
||||
b = a.replace(G, 'lr')
|
||||
break
|
||||
default:
|
||||
return a
|
||||
}
|
||||
return '-webkit-' + a + '-ms-' + b + a
|
||||
case 1017:
|
||||
if (-1 === a.indexOf('sticky', 9)) break
|
||||
case 975:
|
||||
c = (a = d).length - 10
|
||||
b = (33 === a.charCodeAt(c) ? a.substring(0, c) : a)
|
||||
.substring(d.indexOf(':', 7) + 1)
|
||||
.trim()
|
||||
switch ((m = b.charCodeAt(0) + (b.charCodeAt(7) | 0))) {
|
||||
case 203:
|
||||
if (111 > b.charCodeAt(8)) break
|
||||
case 115:
|
||||
a = a.replace(b, '-webkit-' + b) + ';' + a
|
||||
break
|
||||
case 207:
|
||||
case 102:
|
||||
a =
|
||||
a.replace(b, '-webkit-' + (102 < m ? 'inline-' : '') + 'box') +
|
||||
';' +
|
||||
a.replace(b, '-webkit-' + b) +
|
||||
';' +
|
||||
a.replace(b, '-ms-' + b + 'box') +
|
||||
';' +
|
||||
a
|
||||
}
|
||||
return a + ';'
|
||||
case 938:
|
||||
if (45 === a.charCodeAt(5))
|
||||
switch (a.charCodeAt(6)) {
|
||||
case 105:
|
||||
return (
|
||||
(b = a.replace('-items', '')),
|
||||
'-webkit-' + a + '-webkit-box-' + b + '-ms-flex-' + b + a
|
||||
)
|
||||
case 115:
|
||||
return '-webkit-' + a + '-ms-flex-item-' + a.replace(ba, '') + a
|
||||
default:
|
||||
return (
|
||||
'-webkit-' +
|
||||
a +
|
||||
'-ms-flex-line-pack' +
|
||||
a.replace('align-content', '').replace(ba, '') +
|
||||
a
|
||||
)
|
||||
}
|
||||
break
|
||||
case 973:
|
||||
case 989:
|
||||
if (45 !== a.charCodeAt(3) || 122 === a.charCodeAt(4)) break
|
||||
case 931:
|
||||
case 953:
|
||||
if (!0 === la.test(d))
|
||||
return 115 === (b = d.substring(d.indexOf(':') + 1)).charCodeAt(0)
|
||||
? P(d.replace('stretch', 'fill-available'), c, e, h).replace(
|
||||
':fill-available',
|
||||
':stretch'
|
||||
)
|
||||
: a.replace(b, '-webkit-' + b) +
|
||||
a.replace(b, '-moz-' + b.replace('fill-', '')) +
|
||||
a
|
||||
break
|
||||
case 962:
|
||||
if (
|
||||
((a =
|
||||
'-webkit-' + a + (102 === a.charCodeAt(5) ? '-ms-' + a : '') + a),
|
||||
211 === e + h &&
|
||||
105 === a.charCodeAt(13) &&
|
||||
0 < a.indexOf('transform', 10))
|
||||
)
|
||||
return (
|
||||
a.substring(0, a.indexOf(';', 27) + 1).replace(ma, '$1-webkit-$2') +
|
||||
a
|
||||
)
|
||||
}
|
||||
return a
|
||||
}
|
||||
function L(d, c) {
|
||||
var e = d.indexOf(1 === c ? ':' : '{'),
|
||||
h = d.substring(0, 3 !== c ? e : 10)
|
||||
e = d.substring(e + 1, d.length - 1)
|
||||
return R(2 !== c ? h : h.replace(na, '$1'), e, c)
|
||||
}
|
||||
function ea(d, c) {
|
||||
var e = P(c, c.charCodeAt(0), c.charCodeAt(1), c.charCodeAt(2))
|
||||
return e !== c + ';'
|
||||
? e.replace(oa, ' or ($1)').substring(4)
|
||||
: '(' + c + ')'
|
||||
}
|
||||
function H(d, c, e, h, a, m, b, v, n, q) {
|
||||
for (var g = 0, x = c, w; g < A; ++g)
|
||||
switch ((w = S[g].call(B, d, x, e, h, a, m, b, v, n, q))) {
|
||||
case void 0:
|
||||
case !1:
|
||||
case !0:
|
||||
case null:
|
||||
break
|
||||
default:
|
||||
x = w
|
||||
}
|
||||
if (x !== c) return x
|
||||
}
|
||||
function T(d) {
|
||||
switch (d) {
|
||||
case void 0:
|
||||
case null:
|
||||
A = S.length = 0
|
||||
break
|
||||
default:
|
||||
if ('function' === typeof d) S[A++] = d
|
||||
else if ('object' === typeof d)
|
||||
for (var c = 0, e = d.length; c < e; ++c) T(d[c])
|
||||
else Y = !!d | 0
|
||||
}
|
||||
return T
|
||||
}
|
||||
function U(d) {
|
||||
d = d.prefix
|
||||
void 0 !== d &&
|
||||
((R = null),
|
||||
d ? ('function' !== typeof d ? (w = 1) : ((w = 2), (R = d))) : (w = 0))
|
||||
return U
|
||||
}
|
||||
function B(d, c) {
|
||||
var e = d
|
||||
33 > e.charCodeAt(0) && (e = e.trim())
|
||||
V = e
|
||||
e = [V]
|
||||
if (0 < A) {
|
||||
var h = H(-1, c, e, e, D, z, 0, 0, 0, 0)
|
||||
void 0 !== h && 'string' === typeof h && (c = h)
|
||||
}
|
||||
var a = M(O, e, c, 0, 0)
|
||||
0 < A &&
|
||||
((h = H(-2, a, e, e, D, z, a.length, 0, 0, 0)), void 0 !== h && (a = h))
|
||||
V = ''
|
||||
E = 0
|
||||
z = D = 1
|
||||
return a
|
||||
}
|
||||
var ca = /^\0+/g,
|
||||
N = /[\0\r\f]/g,
|
||||
aa = /: */g,
|
||||
ka = /zoo|gra/,
|
||||
ma = /([,: ])(transform)/g,
|
||||
ia = /,\r+?/g,
|
||||
F = /([\t\r\n ])*\f?&/g,
|
||||
fa = /@(k\w+)\s*(\S*)\s*/,
|
||||
Q = /::(place)/g,
|
||||
ha = /:(read-only)/g,
|
||||
G = /[svh]\w+-[tblr]{2}/,
|
||||
da = /\(\s*(.*)\s*\)/g,
|
||||
oa = /([\s\S]*?);/g,
|
||||
ba = /-self|flex-/g,
|
||||
na = /[^]*?(:[rp][el]a[\w-]+)[^]*/,
|
||||
la = /stretch|:\s*\w+\-(?:conte|avail)/,
|
||||
ja = /([^-])(image-set\()/,
|
||||
z = 1,
|
||||
D = 1,
|
||||
E = 0,
|
||||
w = 1,
|
||||
O = [],
|
||||
S = [],
|
||||
A = 0,
|
||||
R = null,
|
||||
Y = 0,
|
||||
V = ''
|
||||
B.use = T
|
||||
B.set = U
|
||||
void 0 !== W && U(W)
|
||||
return B
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
# MurmurHash.js
|
||||
|
||||
An optimized JavaScript implementation of the MurmurHash algorithms.
|
||||
|
||||
These algorithms take a JavaScript string (and a seed), and quickly create a non-cryptographic 32-bit hash from it. And by quick I mean sub-millisecond performance.
|
||||
|
||||
More information about these algorithms can be found at:
|
||||
|
||||
* [MurmurHash Homepage](http://sites.google.com/site/murmurhash/)
|
||||
* [Wikipedia Entry on MurmurHash](http://en.wikipedia.org/wiki/MurmurHash)
|
||||
|
||||
## License (MIT)
|
||||
|
||||
Copyright (c) 2011 Gary Court
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,2 @@
|
||||
// MurmurHash2 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Ivan Nikulin (ifaaan@gmail.com, https://github.com/inikulin)
|
||||
|
||||
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.
|
||||
|
||||
@@ -0,0 +1,588 @@
|
||||
// Const
|
||||
const TRANSFORMED_TYPE_KEY = '@t'
|
||||
const CIRCULAR_REF_KEY = '@r'
|
||||
const KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/
|
||||
|
||||
const GLOBAL = (function getGlobal() {
|
||||
// NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10
|
||||
const savedEval = eval
|
||||
|
||||
return savedEval('this')
|
||||
})()
|
||||
|
||||
const ARRAY_BUFFER_SUPPORTED = typeof ArrayBuffer === 'function'
|
||||
const MAP_SUPPORTED = typeof Map === 'function'
|
||||
const SET_SUPPORTED = typeof Set === 'function'
|
||||
|
||||
const TYPED_ARRAY_CTORS = [
|
||||
'Int8Array',
|
||||
'Uint8Array',
|
||||
'Uint8ClampedArray',
|
||||
'Int16Array',
|
||||
'Uint16Array',
|
||||
'Int32Array',
|
||||
'Uint32Array',
|
||||
'Float32Array',
|
||||
'Float64Array',
|
||||
]
|
||||
|
||||
// Saved proto functions
|
||||
const arrSlice = Array.prototype.slice
|
||||
|
||||
// Default serializer
|
||||
const JSONSerializer = {
|
||||
serialize(val: any) {
|
||||
return JSON.stringify(val)
|
||||
},
|
||||
|
||||
deserialize(val: any) {
|
||||
return JSON.parse(val)
|
||||
},
|
||||
}
|
||||
|
||||
// EncodingTransformer
|
||||
class EncodingTransformer {
|
||||
references: any
|
||||
transforms: any
|
||||
circularCandidates: any
|
||||
circularCandidatesDescrs: any
|
||||
circularRefCount: any
|
||||
|
||||
constructor(val: any, transforms: any) {
|
||||
this.references = val
|
||||
this.transforms = transforms
|
||||
this.circularCandidates = []
|
||||
this.circularCandidatesDescrs = []
|
||||
this.circularRefCount = 0
|
||||
}
|
||||
|
||||
static _createRefMark(idx: any) {
|
||||
const obj = Object.create(null)
|
||||
|
||||
obj[CIRCULAR_REF_KEY] = idx
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
_createCircularCandidate(val: any, parent: any, key: any) {
|
||||
this.circularCandidates.push(val)
|
||||
this.circularCandidatesDescrs.push({ parent, key, refIdx: -1 })
|
||||
}
|
||||
|
||||
_applyTransform(val: any, parent: any, key: any, transform: any) {
|
||||
const result = Object.create(null)
|
||||
const serializableVal = transform.toSerializable(val)
|
||||
|
||||
if (typeof serializableVal === 'object')
|
||||
this._createCircularCandidate(val, parent, key)
|
||||
|
||||
result[TRANSFORMED_TYPE_KEY] = transform.type
|
||||
result.data = this._handleValue(() => serializableVal, parent, key)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
_handleArray(arr: any): any {
|
||||
const result = [] as any
|
||||
|
||||
for (let i = 0; i < arr.length; i++)
|
||||
result[i] = this._handleValue(() => arr[i], result, i)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
_handlePlainObject(obj: any) {
|
||||
const result = Object.create(null)
|
||||
|
||||
for (const key in obj) {
|
||||
if (Reflect.has(obj, key)) {
|
||||
const resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? `#${key}` : key
|
||||
|
||||
result[resultKey] = this._handleValue(() => obj[key], result, resultKey)
|
||||
}
|
||||
}
|
||||
|
||||
const name = obj?.__proto__?.constructor?.name
|
||||
if (name && name !== 'Object') {
|
||||
result.constructor = { name }
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
_handleObject(obj: any, parent: any, key: any) {
|
||||
this._createCircularCandidate(obj, parent, key)
|
||||
|
||||
return Array.isArray(obj)
|
||||
? this._handleArray(obj)
|
||||
: this._handlePlainObject(obj)
|
||||
}
|
||||
|
||||
_ensureCircularReference(obj: any) {
|
||||
const circularCandidateIdx = this.circularCandidates.indexOf(obj)
|
||||
|
||||
if (circularCandidateIdx > -1) {
|
||||
const descr = this.circularCandidatesDescrs[circularCandidateIdx]
|
||||
|
||||
if (descr.refIdx === -1)
|
||||
descr.refIdx = descr.parent ? ++this.circularRefCount : 0
|
||||
|
||||
return EncodingTransformer._createRefMark(descr.refIdx)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
_handleValue(getVal: () => any, parent: any, key: any) {
|
||||
try {
|
||||
const val = getVal()
|
||||
const type = typeof val
|
||||
const isObject = type === 'object' && val !== null
|
||||
|
||||
if (isObject) {
|
||||
const refMark = this._ensureCircularReference(val)
|
||||
|
||||
if (refMark) return refMark
|
||||
}
|
||||
|
||||
for (const transform of this.transforms) {
|
||||
if (transform.shouldTransform(type, val))
|
||||
return this._applyTransform(val, parent, key, transform)
|
||||
}
|
||||
|
||||
if (isObject) return this._handleObject(val, parent, key)
|
||||
|
||||
return val
|
||||
} catch (e) {
|
||||
try {
|
||||
return this._handleValue(
|
||||
() => (e instanceof Error ? e : new Error(e)),
|
||||
parent,
|
||||
key
|
||||
)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform() {
|
||||
const references = [this._handleValue(() => this.references, null, null)]
|
||||
|
||||
for (const descr of this.circularCandidatesDescrs) {
|
||||
if (descr.refIdx > 0) {
|
||||
references[descr.refIdx] = descr.parent[descr.key]
|
||||
descr.parent[descr.key] = EncodingTransformer._createRefMark(
|
||||
descr.refIdx
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return references
|
||||
}
|
||||
}
|
||||
|
||||
// DecodingTransform
|
||||
class DecodingTransformer {
|
||||
references: any
|
||||
transformMap: any
|
||||
activeTransformsStack = [] as any
|
||||
visitedRefs = Object.create(null)
|
||||
|
||||
constructor(references: any, transformsMap: any) {
|
||||
this.references = references
|
||||
this.transformMap = transformsMap
|
||||
}
|
||||
|
||||
_handlePlainObject(obj: any) {
|
||||
const unescaped = Object.create(null)
|
||||
|
||||
if ('constructor' in obj) {
|
||||
if (!obj.constructor || typeof obj.constructor.name !== 'string') {
|
||||
obj.constructor = {
|
||||
name: 'Object',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
this._handleValue(obj[key], obj, key)
|
||||
|
||||
if (KEY_REQUIRE_ESCAPING_RE.test(key)) {
|
||||
// NOTE: use intermediate object to avoid unescaped and escaped keys interference
|
||||
// E.g. unescaped "##@t" will be "#@t" which can overwrite escaped "#@t".
|
||||
unescaped[key.substring(1)] = obj[key]
|
||||
delete obj[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const unsecapedKey in unescaped)
|
||||
obj[unsecapedKey] = unescaped[unsecapedKey]
|
||||
}
|
||||
|
||||
_handleTransformedObject(obj: any, parent: any, key: any) {
|
||||
const transformType = obj[TRANSFORMED_TYPE_KEY]
|
||||
const transform = this.transformMap[transformType]
|
||||
|
||||
if (!transform)
|
||||
throw new Error(`Can't find transform for "${transformType}" type.`)
|
||||
|
||||
this.activeTransformsStack.push(obj)
|
||||
this._handleValue(obj.data, obj, 'data')
|
||||
this.activeTransformsStack.pop()
|
||||
|
||||
parent[key] = transform.fromSerializable(obj.data)
|
||||
}
|
||||
|
||||
_handleCircularSelfRefDuringTransform(refIdx: any, parent: any, key: any) {
|
||||
// NOTE: we've hit a hard case: object reference itself during transformation.
|
||||
// We can't dereference it since we don't have resulting object yet. And we'll
|
||||
// not be able to restore reference lately because we will need to traverse
|
||||
// transformed object again and reference might be unreachable or new object contain
|
||||
// new circular references. As a workaround we create getter, so once transformation
|
||||
// complete, dereferenced property will point to correct transformed object.
|
||||
const references = this.references
|
||||
|
||||
Object.defineProperty(parent, key, {
|
||||
// @ts-ignore
|
||||
val: void 0,
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
|
||||
get() {
|
||||
if (this.val === void 0) this.val = references[refIdx]
|
||||
|
||||
return (<any>this).val
|
||||
},
|
||||
|
||||
set(value) {
|
||||
this.val = value
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
_handleCircularRef(refIdx: any, parent: any, key: any) {
|
||||
if (this.activeTransformsStack.includes(this.references[refIdx]))
|
||||
this._handleCircularSelfRefDuringTransform(refIdx, parent, key)
|
||||
else {
|
||||
if (!this.visitedRefs[refIdx]) {
|
||||
this.visitedRefs[refIdx] = true
|
||||
this._handleValue(this.references[refIdx], this.references, refIdx)
|
||||
}
|
||||
|
||||
parent[key] = this.references[refIdx]
|
||||
}
|
||||
}
|
||||
|
||||
_handleValue(val: any, parent: any, key: any) {
|
||||
if (typeof val !== 'object' || val === null) return
|
||||
|
||||
const refIdx = val[CIRCULAR_REF_KEY]
|
||||
|
||||
if (refIdx !== void 0) this._handleCircularRef(refIdx, parent, key)
|
||||
else if (val[TRANSFORMED_TYPE_KEY])
|
||||
this._handleTransformedObject(val, parent, key)
|
||||
else if (Array.isArray(val)) {
|
||||
for (let i = 0; i < val.length; i++) this._handleValue(val[i], val, i)
|
||||
} else this._handlePlainObject(val)
|
||||
}
|
||||
|
||||
transform() {
|
||||
this.visitedRefs[0] = true
|
||||
this._handleValue(this.references[0], this.references, 0)
|
||||
|
||||
return this.references[0]
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms
|
||||
const builtInTransforms = [
|
||||
{
|
||||
type: '[[NaN]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return type === 'number' && isNaN(val)
|
||||
},
|
||||
|
||||
toSerializable() {
|
||||
return ''
|
||||
},
|
||||
|
||||
fromSerializable() {
|
||||
return NaN
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[undefined]]',
|
||||
|
||||
shouldTransform(type: any) {
|
||||
return type === 'undefined'
|
||||
},
|
||||
|
||||
toSerializable() {
|
||||
return ''
|
||||
},
|
||||
|
||||
fromSerializable() {
|
||||
return void 0
|
||||
},
|
||||
},
|
||||
{
|
||||
type: '[[Date]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return val instanceof Date
|
||||
},
|
||||
|
||||
toSerializable(date: any) {
|
||||
return date.getTime()
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
const date = new Date()
|
||||
|
||||
date.setTime(val)
|
||||
return date
|
||||
},
|
||||
},
|
||||
{
|
||||
type: '[[RegExp]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return val instanceof RegExp
|
||||
},
|
||||
|
||||
toSerializable(re: any) {
|
||||
const result = {
|
||||
src: re.source,
|
||||
flags: '',
|
||||
}
|
||||
|
||||
if (re.global) result.flags += 'g'
|
||||
|
||||
if (re.ignoreCase) result.flags += 'i'
|
||||
|
||||
if (re.multiline) result.flags += 'm'
|
||||
|
||||
return result
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
return new RegExp(val.src, val.flags)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[Error]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return val instanceof Error
|
||||
},
|
||||
|
||||
toSerializable(err: any) {
|
||||
if (!err.stack) {
|
||||
;(Error as any).captureStackTrace?.(err)
|
||||
}
|
||||
|
||||
return {
|
||||
name: err.name,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
}
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
const Ctor = GLOBAL[val.name] || Error
|
||||
const err = new Ctor(val.message)
|
||||
|
||||
err.stack = val.stack
|
||||
return err
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[ArrayBuffer]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return ARRAY_BUFFER_SUPPORTED && val instanceof ArrayBuffer
|
||||
},
|
||||
|
||||
toSerializable(buffer: any) {
|
||||
const view = new Int8Array(buffer)
|
||||
|
||||
return arrSlice.call(view)
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
if (ARRAY_BUFFER_SUPPORTED) {
|
||||
const buffer = new ArrayBuffer(val.length)
|
||||
const view = new Int8Array(buffer)
|
||||
|
||||
view.set(val)
|
||||
|
||||
return buffer
|
||||
}
|
||||
|
||||
return val
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[TypedArray]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
for (const ctorName of TYPED_ARRAY_CTORS) {
|
||||
if (
|
||||
typeof GLOBAL[ctorName] === 'function' &&
|
||||
val instanceof GLOBAL[ctorName]
|
||||
)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
|
||||
toSerializable(arr: any) {
|
||||
return {
|
||||
ctorName: arr.constructor.name,
|
||||
arr: arrSlice.call(arr),
|
||||
}
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
return typeof GLOBAL[val.ctorName] === 'function'
|
||||
? new GLOBAL[val.ctorName](val.arr)
|
||||
: val.arr
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[Map]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return MAP_SUPPORTED && val instanceof Map
|
||||
},
|
||||
|
||||
toSerializable(map: any) {
|
||||
const flattenedKVArr: any = []
|
||||
|
||||
map.forEach((val: any, key: any) => {
|
||||
flattenedKVArr.push(key)
|
||||
flattenedKVArr.push(val)
|
||||
})
|
||||
|
||||
return flattenedKVArr
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
if (MAP_SUPPORTED) {
|
||||
// NOTE: new Map(iterable) is not supported by all browsers
|
||||
const map = new Map()
|
||||
|
||||
for (var i = 0; i < val.length; i += 2) map.set(val[i], val[i + 1])
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
const kvArr = []
|
||||
|
||||
// @ts-ignore
|
||||
for (let j = 0; j < val.length; j += 2) kvArr.push([val[i], val[i + 1]])
|
||||
|
||||
return kvArr
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
type: '[[Set]]',
|
||||
|
||||
shouldTransform(type: any, val: any) {
|
||||
return SET_SUPPORTED && val instanceof Set
|
||||
},
|
||||
|
||||
toSerializable(set: any) {
|
||||
const arr: any = []
|
||||
|
||||
set.forEach((val: any) => {
|
||||
arr.push(val)
|
||||
})
|
||||
|
||||
return arr
|
||||
},
|
||||
|
||||
fromSerializable(val: any) {
|
||||
if (SET_SUPPORTED) {
|
||||
// NOTE: new Set(iterable) is not supported by all browsers
|
||||
const set = new Set()
|
||||
|
||||
for (let i = 0; i < val.length; i++) set.add(val[i])
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
return val
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
// Replicator
|
||||
class Replicator {
|
||||
transforms = [] as any
|
||||
transformsMap = Object.create(null)
|
||||
serializer: any
|
||||
|
||||
constructor(serializer?: any) {
|
||||
this.serializer = serializer || JSONSerializer
|
||||
|
||||
this.addTransforms(builtInTransforms)
|
||||
}
|
||||
|
||||
addTransforms(transforms: any) {
|
||||
transforms = Array.isArray(transforms) ? transforms : [transforms]
|
||||
|
||||
for (const transform of transforms) {
|
||||
if (this.transformsMap[transform.type])
|
||||
throw new Error(
|
||||
`Transform with type "${transform.type}" was already added.`
|
||||
)
|
||||
|
||||
this.transforms.push(transform)
|
||||
this.transformsMap[transform.type] = transform
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
removeTransforms(transforms: any) {
|
||||
transforms = Array.isArray(transforms) ? transforms : [transforms]
|
||||
|
||||
for (const transform of transforms) {
|
||||
const idx = this.transforms.indexOf(transform)
|
||||
|
||||
if (idx > -1) this.transforms.splice(idx, 1)
|
||||
|
||||
delete this.transformsMap[transform.type]
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
encode(val: any) {
|
||||
const transformer = new EncodingTransformer(val, this.transforms)
|
||||
const references = transformer.transform()
|
||||
|
||||
return this.serializer.serialize(references)
|
||||
}
|
||||
|
||||
decode(val: any) {
|
||||
const references = this.serializer.deserialize(val)
|
||||
const transformer = new DecodingTransformer(references, this.transformsMap)
|
||||
|
||||
return transformer.transform()
|
||||
}
|
||||
}
|
||||
|
||||
export default Replicator
|
||||
@@ -0,0 +1,523 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash2 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
// Note - This code makes a few assumptions about how your machine behaves -
|
||||
|
||||
// 1. We can read a 4-byte value from any address without crashing
|
||||
// 2. sizeof(int) == 4
|
||||
|
||||
// And it has a few limitations -
|
||||
|
||||
// 1. It will not work incrementally.
|
||||
// 2. It will not produce the same results on little-endian and big-endian
|
||||
// machines.
|
||||
|
||||
#include "MurmurHash2.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Platform-specific functions and macros
|
||||
|
||||
// Microsoft Visual Studio
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#define BIG_CONSTANT(x) (x)
|
||||
|
||||
// Other compilers
|
||||
|
||||
#else // defined(_MSC_VER)
|
||||
|
||||
#define BIG_CONSTANT(x) (x##LLU)
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )
|
||||
{
|
||||
// 'm' and 'r' are mixing constants generated offline.
|
||||
// They're not really 'magic', they just happen to work well.
|
||||
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
// Initialize the hash to a 'random' value
|
||||
|
||||
uint32_t h = seed ^ len;
|
||||
|
||||
// Mix 4 bytes at a time into the hash
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k = *(uint32_t*)data;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
// Handle the last few bytes of the input array
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h ^= data[2] << 16;
|
||||
case 2: h ^= data[1] << 8;
|
||||
case 1: h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
|
||||
// Do a few final mixes of the hash to ensure the last few
|
||||
// bytes are well-incorporated.
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash2, 64-bit versions, by Austin Appleby
|
||||
|
||||
// The same caveats as 32-bit MurmurHash2 apply here - beware of alignment
|
||||
// and endian-ness issues if used across multiple platforms.
|
||||
|
||||
// 64-bit hash for 64-bit platforms
|
||||
|
||||
uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed )
|
||||
{
|
||||
const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);
|
||||
const int r = 47;
|
||||
|
||||
uint64_t h = seed ^ (len * m);
|
||||
|
||||
const uint64_t * data = (const uint64_t *)key;
|
||||
const uint64_t * end = data + (len/8);
|
||||
|
||||
while(data != end)
|
||||
{
|
||||
uint64_t k = *data++;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h ^= k;
|
||||
h *= m;
|
||||
}
|
||||
|
||||
const unsigned char * data2 = (const unsigned char*)data;
|
||||
|
||||
switch(len & 7)
|
||||
{
|
||||
case 7: h ^= uint64_t(data2[6]) << 48;
|
||||
case 6: h ^= uint64_t(data2[5]) << 40;
|
||||
case 5: h ^= uint64_t(data2[4]) << 32;
|
||||
case 4: h ^= uint64_t(data2[3]) << 24;
|
||||
case 3: h ^= uint64_t(data2[2]) << 16;
|
||||
case 2: h ^= uint64_t(data2[1]) << 8;
|
||||
case 1: h ^= uint64_t(data2[0]);
|
||||
h *= m;
|
||||
};
|
||||
|
||||
h ^= h >> r;
|
||||
h *= m;
|
||||
h ^= h >> r;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
// 64-bit hash for 32-bit platforms
|
||||
|
||||
uint64_t MurmurHash64B ( const void * key, int len, uint64_t seed )
|
||||
{
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
uint32_t h1 = uint32_t(seed) ^ len;
|
||||
uint32_t h2 = uint32_t(seed >> 32);
|
||||
|
||||
const uint32_t * data = (const uint32_t *)key;
|
||||
|
||||
while(len >= 8)
|
||||
{
|
||||
uint32_t k1 = *data++;
|
||||
k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
||||
h1 *= m; h1 ^= k1;
|
||||
len -= 4;
|
||||
|
||||
uint32_t k2 = *data++;
|
||||
k2 *= m; k2 ^= k2 >> r; k2 *= m;
|
||||
h2 *= m; h2 ^= k2;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
if(len >= 4)
|
||||
{
|
||||
uint32_t k1 = *data++;
|
||||
k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
||||
h1 *= m; h1 ^= k1;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h2 ^= ((unsigned char*)data)[2] << 16;
|
||||
case 2: h2 ^= ((unsigned char*)data)[1] << 8;
|
||||
case 1: h2 ^= ((unsigned char*)data)[0];
|
||||
h2 *= m;
|
||||
};
|
||||
|
||||
h1 ^= h2 >> 18; h1 *= m;
|
||||
h2 ^= h1 >> 22; h2 *= m;
|
||||
h1 ^= h2 >> 17; h1 *= m;
|
||||
h2 ^= h1 >> 19; h2 *= m;
|
||||
|
||||
uint64_t h = h1;
|
||||
|
||||
h = (h << 32) | h2;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash2A, by Austin Appleby
|
||||
|
||||
// This is a variant of MurmurHash2 modified to use the Merkle-Damgard
|
||||
// construction. Bulk speed should be identical to Murmur2, small-key speed
|
||||
// will be 10%-20% slower due to the added overhead at the end of the hash.
|
||||
|
||||
// This variant fixes a minor issue where null keys were more likely to
|
||||
// collide with each other than expected, and also makes the function
|
||||
// more amenable to incremental implementations.
|
||||
|
||||
#define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
|
||||
|
||||
uint32_t MurmurHash2A ( const void * key, int len, uint32_t seed )
|
||||
{
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
uint32_t l = len;
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
uint32_t h = seed;
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k = *(uint32_t*)data;
|
||||
|
||||
mmix(h,k);
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
uint32_t t = 0;
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: t ^= data[2] << 16;
|
||||
case 2: t ^= data[1] << 8;
|
||||
case 1: t ^= data[0];
|
||||
};
|
||||
|
||||
mmix(h,t);
|
||||
mmix(h,l);
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CMurmurHash2A, by Austin Appleby
|
||||
|
||||
// This is a sample implementation of MurmurHash2A designed to work
|
||||
// incrementally.
|
||||
|
||||
// Usage -
|
||||
|
||||
// CMurmurHash2A hasher
|
||||
// hasher.Begin(seed);
|
||||
// hasher.Add(data1,size1);
|
||||
// hasher.Add(data2,size2);
|
||||
// ...
|
||||
// hasher.Add(dataN,sizeN);
|
||||
// uint32_t hash = hasher.End()
|
||||
|
||||
class CMurmurHash2A
|
||||
{
|
||||
public:
|
||||
|
||||
void Begin ( uint32_t seed = 0 )
|
||||
{
|
||||
m_hash = seed;
|
||||
m_tail = 0;
|
||||
m_count = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void Add ( const unsigned char * data, int len )
|
||||
{
|
||||
m_size += len;
|
||||
|
||||
MixTail(data,len);
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k = *(uint32_t*)data;
|
||||
|
||||
mmix(m_hash,k);
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
MixTail(data,len);
|
||||
}
|
||||
|
||||
uint32_t End ( void )
|
||||
{
|
||||
mmix(m_hash,m_tail);
|
||||
mmix(m_hash,m_size);
|
||||
|
||||
m_hash ^= m_hash >> 13;
|
||||
m_hash *= m;
|
||||
m_hash ^= m_hash >> 15;
|
||||
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const uint32_t m = 0x5bd1e995;
|
||||
static const int r = 24;
|
||||
|
||||
void MixTail ( const unsigned char * & data, int & len )
|
||||
{
|
||||
while( len && ((len<4) || m_count) )
|
||||
{
|
||||
m_tail |= (*data++) << (m_count * 8);
|
||||
|
||||
m_count++;
|
||||
len--;
|
||||
|
||||
if(m_count == 4)
|
||||
{
|
||||
mmix(m_hash,m_tail);
|
||||
m_tail = 0;
|
||||
m_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t m_hash;
|
||||
uint32_t m_tail;
|
||||
uint32_t m_count;
|
||||
uint32_t m_size;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHashNeutral2, by Austin Appleby
|
||||
|
||||
// Same as MurmurHash2, but endian- and alignment-neutral.
|
||||
// Half the speed though, alas.
|
||||
|
||||
uint32_t MurmurHashNeutral2 ( const void * key, int len, uint32_t seed )
|
||||
{
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
uint32_t h = seed ^ len;
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k;
|
||||
|
||||
k = data[0];
|
||||
k |= data[1] << 8;
|
||||
k |= data[2] << 16;
|
||||
k |= data[3] << 24;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h ^= data[2] << 16;
|
||||
case 2: h ^= data[1] << 8;
|
||||
case 1: h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHashAligned2, by Austin Appleby
|
||||
|
||||
// Same algorithm as MurmurHash2, but only does aligned reads - should be safer
|
||||
// on certain platforms.
|
||||
|
||||
// Performance will be lower than MurmurHash2
|
||||
|
||||
#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
|
||||
|
||||
|
||||
uint32_t MurmurHashAligned2 ( const void * key, int len, uint32_t seed )
|
||||
{
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
uint32_t h = seed ^ len;
|
||||
|
||||
int align = (uint64_t)data & 3;
|
||||
|
||||
if(align && (len >= 4))
|
||||
{
|
||||
// Pre-load the temp registers
|
||||
|
||||
uint32_t t = 0, d = 0;
|
||||
|
||||
switch(align)
|
||||
{
|
||||
case 1: t |= data[2] << 16;
|
||||
case 2: t |= data[1] << 8;
|
||||
case 3: t |= data[0];
|
||||
}
|
||||
|
||||
t <<= (8 * align);
|
||||
|
||||
data += 4-align;
|
||||
len -= 4-align;
|
||||
|
||||
int sl = 8 * (4-align);
|
||||
int sr = 8 * align;
|
||||
|
||||
// Mix
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
d = *(uint32_t *)data;
|
||||
t = (t >> sr) | (d << sl);
|
||||
|
||||
uint32_t k = t;
|
||||
|
||||
MIX(h,k,m);
|
||||
|
||||
t = d;
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
// Handle leftover data in temp registers
|
||||
|
||||
d = 0;
|
||||
|
||||
if(len >= align)
|
||||
{
|
||||
switch(align)
|
||||
{
|
||||
case 3: d |= data[2] << 16;
|
||||
case 2: d |= data[1] << 8;
|
||||
case 1: d |= data[0];
|
||||
}
|
||||
|
||||
uint32_t k = (t >> sr) | (d << sl);
|
||||
MIX(h,k,m);
|
||||
|
||||
data += align;
|
||||
len -= align;
|
||||
|
||||
//----------
|
||||
// Handle tail bytes
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h ^= data[2] << 16;
|
||||
case 2: h ^= data[1] << 8;
|
||||
case 1: h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(len)
|
||||
{
|
||||
case 3: d |= data[2] << 16;
|
||||
case 2: d |= data[1] << 8;
|
||||
case 1: d |= data[0];
|
||||
case 0: h ^= (t >> sr) | (d << sl);
|
||||
h *= m;
|
||||
}
|
||||
}
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(len >= 4)
|
||||
{
|
||||
uint32_t k = *(uint32_t *)data;
|
||||
|
||||
MIX(h,k,m);
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
//----------
|
||||
// Handle tail bytes
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h ^= data[2] << 16;
|
||||
case 2: h ^= data[1] << 8;
|
||||
case 1: h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Sultan Tarimo
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,50 @@
|
||||
# SITE-07 修改版源码与原作者署名
|
||||
|
||||
修改前 HEAD:d2a83f8a69c7a5d9a8bf30c9b370e573034f2000。继续控制台内嵌来源
|
||||
核查;本批不改任何站点运行时、公开API、包版本或锁文件。
|
||||
|
||||
## 来源与实现
|
||||
|
||||
replicator 属于修改过的1.0.x源码家族,不能称为原样安装某个npm版本。其固定
|
||||
console-feed提交de41ef2662019c645a652199d9bdbbfc71419f5e中的TS源码,使用
|
||||
TypeScript4.1.2、ES3/CommonJS/LF生成,与npm3.2.2的运行代码逐字节一致;唯一
|
||||
排除的是末尾原有inline source map。当前TS5.9.3会改变模板字符串的编译方式,
|
||||
不能拿它的输出当作历史源码不匹配。原作者Ivan Nikulin的MIT许可从1.0.1保存,
|
||||
明确这是修改版来源署名,不声称恢复唯一上游基点或原安装锁。
|
||||
|
||||
Emotion Stylis0.8.5对应Git tag提交6dd425bd1b8db7ab5144cca81b592639a68af2cb,
|
||||
src/stylis.min.js与npm归档逐字节一致,package.json明确固定Stylis3.5.4。
|
||||
上游build.js修改原始Stylis后请求在线Closure服务;保存这一历史配方与源码,
|
||||
不执行过时服务,也不声称该更早阶段已重新构建。补齐Sultan Tarimo的MIT全文。
|
||||
cache源码显式链接rule-sheet来源,已有Sultan完整注释继续保留并验证。
|
||||
|
||||
Emotion hash的两个显式来源分别为Gary Court的murmurhash-js与Austin Appleby
|
||||
的MurmurHash2。Gary于2011年提交的README含完整MIT文本;Austin固定提交的CPP
|
||||
顶部含作者署名及public-domain声明。保存源文件及原样截取声明,不用外层Emotion
|
||||
许可替代这些作者信息。
|
||||
|
||||
attribution.ts负责Git内容/对象身份校验和修改版输出边界,reproduce.ts负责调度。
|
||||
所有固定Git内容同时校验SHA-256和实际Git blob SHA-1,联网读取的base64响应也
|
||||
走相同校验。历史TS编译器9,002,076字节,成员读取上限由8提升为16MiB;只在
|
||||
忽略的复现缓存加载,不安装为项目依赖。新增4份公开notice,console共42份、
|
||||
全站60份,加总索引61输出;生成器防遗漏保护同步更新。
|
||||
|
||||
## 验证与剩余范围
|
||||
|
||||
- Node24.21.0,Yarn1.22.22策略不变;24/24单元通过,增加Git对象错误、修改
|
||||
内容、错误API编码、缺正文,以及只允许末尾source map差异的反例。
|
||||
- docs-tools严格TS和相关lint通过;console及notices只读生成校验保持。
|
||||
- 离线完整复现通过:原100模块/Parcel/包边、17map源/7tokenizer、5个固定Git
|
||||
来源、replicator运行代码和Emotion发布源码匹配。联网及三浏览器交付细节见
|
||||
[验证记录](../baselines/console-derived-validation.json)。
|
||||
- 浏览器使用本地真实页面与媒体,逐字节比较60份许可,并验证移动日志、播放及
|
||||
销毁。外部HTTPS由夹具隔离,不代表手机、远端CI或发布验收。
|
||||
Chromium诊断包含一次pattern.mp4的ERR_ABORTED,媒体播放断言通过;没有
|
||||
未处理页面错误或console error。记录未包含请求失败时间,不推断具体取消时刻。
|
||||
|
||||
来源台账为[derived attribution](../baselines/console-derived-attribution.json)。
|
||||
控制台仍需处理Component的Stack Overflow引用与最终内嵌清查,VENDOR-08保留
|
||||
open;SITE-07及其他Monaco/字体/媒体范围仍未完成,状态为doing,199/265不变。
|
||||
|
||||
回退移除本批4个notice及额外来源/复现步骤,恢复38份console清单,不影响此前
|
||||
控制台修复。独立本地检查点提交,没有推送、部署或发布。
|
||||
+1
-1
@@ -653,7 +653,7 @@
|
||||
- SITE-AI-DOCS-01: [记录](changes/2026-09-14-SITE-AI-DOCS-01-documentation-pipeline.md) [记录](baselines/documentation-pipeline-validation.json)
|
||||
- SITE-BUILD-01: [记录](changes/2026-09-14-SITE-BUILD-01-staged-builds.md) [记录](baselines/site-build-validation.json)
|
||||
- SITE-03: [记录](changes/2026-09-14-SITE-03-desktop-editor.md) [记录](baselines/site-editor-validation.json)
|
||||
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md)
|
||||
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.md) [记录](baselines/console-derived-attribution.json) [记录](baselines/console-derived-validation.json) [记录](changes/2026-09-15-SITE-07-console-derived-attribution.md)
|
||||
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
|
||||
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
|
||||
- MOD-01: [记录](changes/2026-09-15-MOD-01-bun-evaluation.md) [记录](baselines/bun-install-validation.json) [记录](bun-evaluation.md)
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# 进度与证据
|
||||
|
||||
## SITE-07 修改版 replicator 与 Emotion 署名
|
||||
|
||||
固定TS源码重现replicator运行代码,Emotion Stylis发布源码匹配Git tag;补齐
|
||||
Ivan Nikulin、Sultan Tarimo、Gary Court和Austin Appleby的许可/声明。单元24/24,
|
||||
联网/离线复现及三引擎实际交付3/3通过。
|
||||
见[记录](changes/2026-09-15-SITE-07-console-derived-attribution.md)。不声称重跑旧
|
||||
Closure服务或恢复完整原锁。控制台剩Stack Overflow引用及最终清查,其他站点
|
||||
资产继续待审;VENDOR-08 open、SITE-07 doing,仍199/265,运行时和锁未改。
|
||||
|
||||
## SITE-07 三项内嵌依赖来源与许可
|
||||
|
||||
react-inspector中的Babel16文件、regenerator1文件及tokenizer7文件已逐字节
|
||||
|
||||
+6
-2
@@ -699,11 +699,15 @@
|
||||
"refactor/baselines/console-embedded-sources.json",
|
||||
"refactor/baselines/console-embedded-validation.json",
|
||||
"refactor/changes/2026-09-15-SITE-07-console-embedded-sources.md",
|
||||
"scripts/site-vendor/console/embedded-sources.ts"
|
||||
"scripts/site-vendor/console/embedded-sources.ts",
|
||||
"refactor/baselines/console-derived-attribution.json",
|
||||
"refactor/baselines/console-derived-validation.json",
|
||||
"refactor/changes/2026-09-15-SITE-07-console-derived-attribution.md",
|
||||
"scripts/site-vendor/console/attribution.ts"
|
||||
],
|
||||
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
|
||||
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。",
|
||||
"workspaceState": "All 100 vendor module bodies and Parcel loader exactly reproduce from fixed archives. Additionally all 17 react-inspector external source-map members and seven tokenizer files match pinned upstream sources. Public console notices cover 38 entries; all 56 site notice files passed byte-for-byte HTTP checks in three engines. Remaining embedded attribution is tracked in console-embedded-notices.json. Original full lockfile is not recovered; runtime unchanged."
|
||||
"workspaceState": "All 100 vendor modules and Parcel loader reproduce. Embedded inspector/tokenizer sources match; fixed replicator TS fork reproduces its archived runtime and Emotion Stylis source matches the immutable tag. Additional upstream author notices bring console notices to 42; all 60 site notice files passed HTTP byte checks in three engines. Stack Overflow attribution and final embedded review remain open. Original Closure service and full historical lockfile are not claimed; runtime unchanged."
|
||||
},
|
||||
{
|
||||
"id": "SDK-01",
|
||||
|
||||
+4
-1
@@ -4500,7 +4500,10 @@
|
||||
"changes/2026-09-15-SITE-07-console-notices.md",
|
||||
"baselines/console-embedded-sources.json",
|
||||
"baselines/console-embedded-validation.json",
|
||||
"changes/2026-09-15-SITE-07-console-embedded-sources.md"
|
||||
"changes/2026-09-15-SITE-07-console-embedded-sources.md",
|
||||
"baselines/console-derived-attribution.json",
|
||||
"baselines/console-derived-validation.json",
|
||||
"changes/2026-09-15-SITE-07-console-derived-attribution.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -45,6 +45,8 @@ assert.deepEqual(consoleGroup?.components?.map(component => component.name).sort
|
||||
'is-object',
|
||||
'is-window',
|
||||
'linkifyjs',
|
||||
'murmurhash-js (Gary Court)',
|
||||
'murmurhash2 (Austin Appleby)',
|
||||
'object-assign',
|
||||
'parcel-bundler',
|
||||
'process',
|
||||
@@ -54,13 +56,15 @@ assert.deepEqual(consoleGroup?.components?.map(component => component.name).sort
|
||||
'react-inspector',
|
||||
'react-is',
|
||||
'regenerator-runtime',
|
||||
'replicator (console-feed fork)',
|
||||
'scheduler',
|
||||
'shallowequal',
|
||||
'simple-html-tokenizer',
|
||||
'styled-components',
|
||||
'stylis (Emotion fork)',
|
||||
'stylis-rule-sheet',
|
||||
], 'Do not silently drop verified console component attribution')
|
||||
assert.equal(consoleGroup?.notices.length, 38, 'Missing reviewed console notice')
|
||||
assert.equal(consoleGroup?.notices.length, 42, 'Missing reviewed console notice')
|
||||
const vconsoleNotices = manifest.groups.find(group => group.name === 'vconsole')?.notices.map(notice => notice.target)
|
||||
for (const name of ['LICENSE', 'MIT-LICENSE', 'ATTRIBUTION.md'])
|
||||
assert(vconsoleNotices?.includes(`docs/licenses/vconsole/${name}`), `Missing vConsole notice: ${name}`)
|
||||
|
||||
@@ -23,7 +23,7 @@ files retain their exact upstream bytes, including final blank lines.
|
||||
`yarn check:site-notices`. The write command cannot bless altered vendor assets;
|
||||
review the new archive and license evidence before changing the manifest. The
|
||||
CLI prevents accidentally dropping any of the three groups, the ten reviewed
|
||||
Monaco/vConsole components, the 38 identified console components or their notice
|
||||
Monaco/vConsole components, the 42 identified console components or their notice
|
||||
count, and vConsole's original license, supplemental MIT body and attribution.
|
||||
Component references require their runtime assets and every notice before writing.
|
||||
Source notices
|
||||
@@ -60,7 +60,7 @@ The desktop console's owned TS entry/view and lifecycle now build through
|
||||
`build:console` / `check:console`; see [console maintenance](console/README.md).
|
||||
Its other 100 Parcel modules remain frozen and now reproduce exactly from fixed
|
||||
archives, including the Parcel loader. Its package/loader licenses, two embedded
|
||||
headers and three additional embedded dependency licenses now ship as 38 files
|
||||
headers, embedded dependency licenses and upstream author notices now ship as 42 files
|
||||
under `docs/licenses/console/`. Full embedded
|
||||
attribution remains open; the generated index explicitly preserves that boundary.
|
||||
|
||||
|
||||
@@ -163,11 +163,28 @@ tokenizer members exactly reproduce with the self-contained Babel 6.26.0 compile
|
||||
and es2015 loose preset. Archive, compiler, source and output bytes are checked.
|
||||
The Git archive's SHA-512 is a measured fingerprint, not an npm registry SRI;
|
||||
the recorded immutable URL and dependency string retain its actual provenance.
|
||||
These three licenses are included in the 38 console notice outputs. The normal
|
||||
These three licenses are included in the console notice outputs. The normal
|
||||
site build still executes only the owned TS build; historical reproduction now
|
||||
fetches 39 archives only when explicitly run with `--fetch`.
|
||||
fetches 42 archives and fixed Git sources only when explicitly run with `--fetch`.
|
||||
|
||||
This is partial embedded review. Remaining follow-ups are replicator, Emotion
|
||||
stylis/hash/cache and the Component Stack Overflow reference. Source-map names and
|
||||
comment links alone are leads, not proof of complete notice coverage. Do not close
|
||||
VENDOR-08 solely because all Parcel modules reproduce.
|
||||
`attribution.ts` verifies immutable Git content against SHA-256 and Git blob SHA-1,
|
||||
and compares compiled forks with the archived runtime before its single terminal
|
||||
inline source map. `console-derived-attribution.json` pins the console-feed
|
||||
replicator TS revision and TypeScript 4.1.2 ES3/CommonJS/LF compiler options. The
|
||||
fork's runtime matches exactly; it is not a verbatim npm replicator release.
|
||||
Ivan Nikulin's original MIT notice is retained from the 1.0.x source family.
|
||||
Historical compiler extraction permits 16 MiB because this fixed compiler member
|
||||
is 9,002,076 bytes; it is not an installed workspace dependency.
|
||||
|
||||
Emotion's Stylis source matches its fixed tag commit and declares Stylis 3.5.4.
|
||||
The original build recipe modifies Stylis and uses an unversioned online Closure
|
||||
service. We preserve that recipe and the matching generated source without claiming
|
||||
to rerun the earlier service. Sultan Tarimo's MIT notice covers the upstream
|
||||
attribution, including the separately identified rule-sheet reference in cache.
|
||||
Gary Court's original README/MIT text and Austin Appleby's public-domain header
|
||||
are preserved for the two explicit MurmurHash source references. Original sources
|
||||
and excerpts are hashed; attribution is never inferred from the outer Emotion MIT.
|
||||
|
||||
There are now 42 console notice outputs. Remaining follow-ups are the Component
|
||||
Stack Overflow reference and final embedded-source review. Do not close VENDOR-08
|
||||
solely because all Parcel modules reproduce.
|
||||
@@ -0,0 +1,29 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { Buffer } from 'node:buffer'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { hash } from './provenance.ts'
|
||||
|
||||
export interface GitSource { source: string, sha256: string, gitBlobSha: string, apiUrl: string }
|
||||
|
||||
export function verifyGitSource(bytes: Uint8Array, source: GitSource): void {
|
||||
assert.equal(hash(bytes), source.sha256, 'Fixed Git source content changed')
|
||||
const blob = createHash('sha1').update(`blob ${bytes.byteLength}\0`).update(bytes).digest('hex')
|
||||
assert.equal(blob, source.gitBlobSha, 'Fixed Git blob identity differs')
|
||||
}
|
||||
|
||||
export function decodeGitSource(response: Uint8Array, source: GitSource): Uint8Array {
|
||||
const data: { encoding: string, content: string } = JSON.parse(Buffer.from(response).toString('utf8'))
|
||||
assert.equal(data.encoding, 'base64', 'Unexpected Git source encoding')
|
||||
assert.equal(typeof data.content, 'string', 'Missing Git source content')
|
||||
const bytes = Buffer.from(data.content, 'base64')
|
||||
verifyGitSource(bytes, source)
|
||||
return bytes
|
||||
}
|
||||
|
||||
export function verifyForkOutput(compiled: string, target: string): void {
|
||||
const marker = '//# sourceMappingURL=data:application/json;base64,'
|
||||
const start = target.indexOf(marker)
|
||||
assert(start >= 0 && !target.includes(marker, start + 1), 'Expected one terminal inline source map')
|
||||
assert(/^[A-Z0-9+/=]+$/i.test(target.slice(start + marker.length)), 'Unexpected inline source map trailer')
|
||||
assert.equal(compiled, target.slice(0, start), 'Fork compiled runtime differs')
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { GitSource } from './attribution.ts'
|
||||
import type { EmbeddedNotice } from './embedded-notices.ts'
|
||||
import type { Member, SourceMapRecord, TransformedSource } from './embedded-sources.ts'
|
||||
import type { Archive, External, Source } from './provenance.ts'
|
||||
@@ -10,6 +11,7 @@ import { createRequire } from 'node:module'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { decodeGitSource, verifyForkOutput, verifyGitSource } from './attribution.ts'
|
||||
import { extractNotice } from './embedded-notices.ts'
|
||||
import { verifyMappedSources, verifyTransformedSources } from './embedded-sources.ts'
|
||||
import { hash, parcelModules, verifyArchive, verifyModules, verifyPackageEdges } from './provenance.ts'
|
||||
@@ -46,12 +48,23 @@ interface EmbeddedProvenance {
|
||||
tokenizer: { dependency: Member, value: string, sources: TransformedSource[] }
|
||||
}
|
||||
interface HistoricalBabel { version: string, transform: (source: string, options: EmbeddedProvenance['compiler']['options']) => { code: string } }
|
||||
interface DerivedProvenance {
|
||||
archives: (Archive & { id: string, notices: Notice[] })[]
|
||||
compiler: { archive: Archive, member: string, sha256: string, version: string, options: { target: number, module: number, newLine: number } }
|
||||
remotes: (GitSource & { id: string })[]
|
||||
replicator: { source: string, target: Member, upstream: Member }
|
||||
stylis: { source: string, target: Member, dependency: Member, dependencyVersion: string, recipe: string }
|
||||
hash: { source: string, notice: EmbeddedNotice, reference: Member, references: string[] }
|
||||
cache: { reference: Member, upstreamUrl: string, notice: string }
|
||||
}
|
||||
interface HistoricalTypeScript { version: string, transpileModule: (source: string, options: { compilerOptions: DerivedProvenance['compiler']['options'] }) => { outputText: string } }
|
||||
|
||||
const root = fileURLToPath(new URL('../../../', import.meta.url))
|
||||
const record: Provenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-feed-provenance.json'), 'utf8'))
|
||||
const common: SourceGroup<CommonSource> = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-commonjs-provenance.json'), 'utf8'))
|
||||
const esm: EsmProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-esm-provenance.json'), 'utf8'))
|
||||
const embeddedSources: EmbeddedProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-embedded-sources.json'), 'utf8'))
|
||||
const derived: DerivedProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-derived-attribution.json'), 'utf8'))
|
||||
assert(process.argv.slice(2).every(arg => arg === '--fetch'), 'Use reproduce.ts [--fetch]')
|
||||
assert.equal(process.version, `v${fs.readFileSync(path.join(root, '.node-version'), 'utf8').trim()}`, 'Use canonical Node')
|
||||
const cacheRoot = fs.realpathSync(path.join(root, 'refactor/.cache'))
|
||||
@@ -70,7 +83,7 @@ async function download(url: string) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
const allArchives = [record.archive, record.compiler.archive, ...common.archives, ...esm.archives, esm.babel.archive, esm.parcel.archive, ...embeddedSources.archives, embeddedSources.compiler.archive]
|
||||
const allArchives = [record.archive, record.compiler.archive, ...common.archives, ...esm.archives, esm.babel.archive, esm.parcel.archive, ...embeddedSources.archives, embeddedSources.compiler.archive, ...derived.archives, derived.compiler.archive]
|
||||
const allArchiveIds = new Set(allArchives.map(archive => `${encodeURIComponent(archive.name)}-${archive.version}`))
|
||||
assert.equal(allArchiveIds.size, allArchives.length, 'Duplicate reproduction archive')
|
||||
for (const archive of allArchives) {
|
||||
@@ -82,7 +95,7 @@ for (const archive of allArchives) {
|
||||
}
|
||||
verifyArchive(fs.readFileSync(target), archive)
|
||||
}
|
||||
const readMember = (name: string, member: string) => execFileSync('tar', ['-xOzf', path.join(cache, name), member], { maxBuffer: 8 * 1024 * 1024 })
|
||||
const readMember = (name: string, member: string) => execFileSync('tar', ['-xOzf', path.join(cache, name), member], { maxBuffer: 16 * 1024 * 1024 })
|
||||
const compilerBytes = readMember('terser-3.17.0.tgz', record.compiler.member)
|
||||
assert.equal(hash(compilerBytes), record.compiler.sha256, 'Compiler member changed')
|
||||
const compilerPath = path.join(cache, 'terser.cjs')
|
||||
@@ -195,7 +208,7 @@ function readEmbedded(source: Member) {
|
||||
assert(allArchiveIds.has(source.archive), 'Unknown embedded source archive')
|
||||
return readMember(`${source.archive}.tgz`, source.member)
|
||||
}
|
||||
for (const archive of embeddedSources.archives) {
|
||||
for (const archive of [...embeddedSources.archives, ...derived.archives]) {
|
||||
assert.equal(archive.id, `${encodeURIComponent(archive.name)}-${archive.version}`, 'Embedded archive ID differs')
|
||||
for (const notice of archive.notices) {
|
||||
assert.equal(hash(readMember(`${archive.id}.tgz`, notice.member)), notice.sha256, 'Embedded upstream license changed')
|
||||
@@ -220,4 +233,46 @@ assert.equal(legacyBabel.version, compiler.version, 'Embedded compiler version c
|
||||
assert.deepEqual(compiler.options, { presets: [['es2015', { loose: true }]] }, 'Embedded compiler options changed')
|
||||
const transformedCount = verifyTransformedSources(tokenizer.sources, readEmbedded, source => legacyBabel.transform(source, compiler.options).code)
|
||||
assert.equal(transformedCount, 7, 'Incomplete tokenizer scope')
|
||||
console.log(JSON.stringify({ exactModules: identified.size, consoleFeed: count, commonjs: commonCount, esm: esmCount, parcelPrelude: true, packageEdges: true, embeddedNotices: embedded.notices.length, embeddedMappedSources: mappedCount, embeddedTransformedSources: transformedCount, unresolved: 0, licenseClosure: false }))
|
||||
const gitSources = new Map<string, Buffer>()
|
||||
assert.equal(derived.remotes.length, 5, 'Incomplete derived Git source scope')
|
||||
for (const source of derived.remotes) {
|
||||
assert(!gitSources.has(source.id), 'Duplicate derived Git source')
|
||||
const bytes = fs.readFileSync(path.join(root, source.source))
|
||||
verifyGitSource(bytes, source)
|
||||
if (process.argv.includes('--fetch'))
|
||||
decodeGitSource(await download(source.apiUrl), source)
|
||||
gitSources.set(source.id, bytes)
|
||||
}
|
||||
function gitSource(id: string): Buffer {
|
||||
const bytes = gitSources.get(id)
|
||||
assert(bytes, `Missing derived Git source: ${id}`)
|
||||
return bytes
|
||||
}
|
||||
function derivedMember(member: Member): Buffer {
|
||||
const bytes = readEmbedded(member)
|
||||
assert.equal(hash(bytes), member.sha256, 'Derived source member changed')
|
||||
return bytes
|
||||
}
|
||||
const tsCompiler = derived.compiler
|
||||
const tsBytes = readMember(`${tsCompiler.archive.name}-${tsCompiler.archive.version}.tgz`, tsCompiler.member)
|
||||
assert.equal(hash(tsBytes), tsCompiler.sha256, 'Historical TypeScript compiler changed')
|
||||
const tsPath = path.join(cache, 'typescript4.cjs')
|
||||
fs.writeFileSync(tsPath, tsBytes)
|
||||
const historicalTs = require(tsPath) as HistoricalTypeScript
|
||||
assert.equal(historicalTs.version, tsCompiler.version, 'Historical TypeScript version changed')
|
||||
assert.deepEqual(tsCompiler.options, { target: 0, module: 1, newLine: 1 }, 'Historical TypeScript options changed')
|
||||
const fork = historicalTs.transpileModule(gitSource(derived.replicator.source).toString('utf8'), { compilerOptions: tsCompiler.options }).outputText
|
||||
verifyForkOutput(fork, derivedMember(derived.replicator.target).toString('utf8'))
|
||||
derivedMember(derived.replicator.upstream)
|
||||
assert(gitSource(derived.stylis.source).equals(derivedMember(derived.stylis.target)), 'Emotion Git/npm source differs')
|
||||
const stylisPackage: { devDependencies: { stylis: string } } = JSON.parse(derivedMember(derived.stylis.dependency).toString('utf8'))
|
||||
assert.equal(stylisPackage.devDependencies.stylis, derived.stylis.dependencyVersion, 'Emotion Stylis dependency changed')
|
||||
assert(gitSource(derived.stylis.recipe).toString('utf8').includes('https://closure-compiler.appspot.com/compile'), 'Historical Closure recipe changed')
|
||||
const murmurSource = derivedMember(derived.hash.reference).toString('utf8')
|
||||
for (const reference of derived.hash.references)
|
||||
assert(murmurSource.includes(reference), 'MurmurHash source attribution changed')
|
||||
const publicDomain = extractNotice(gitSource(derived.hash.source), derived.hash.notice)
|
||||
assert.equal(fs.readFileSync(path.join(root, derived.hash.notice.source), 'utf8'), publicDomain, 'Public domain notice changed')
|
||||
assert(derivedMember(derived.cache.reference).toString('utf8').includes(derived.cache.upstreamUrl), 'Rule-sheet source attribution changed')
|
||||
assert(fs.readFileSync(path.join(root, derived.cache.notice), 'utf8').includes('Copyright (c) 2016 Sultan Tarimo'), 'Rule-sheet attribution missing')
|
||||
console.log(JSON.stringify({ exactModules: identified.size, consoleFeed: count, commonjs: commonCount, esm: esmCount, parcelPrelude: true, packageEdges: true, embeddedNotices: embedded.notices.length, embeddedMappedSources: mappedCount, embeddedTransformedSources: transformedCount, derivedGitSources: gitSources.size, replicatorFork: true, emotionStylisSource: true, unresolved: 0, licenseClosure: false }))
|
||||
@@ -944,7 +944,7 @@
|
||||
"name": "console",
|
||||
"version": "legacy-vendor-with-TS-adapter",
|
||||
"tarball": "https://github.com/zhw2590582/ArtPlayer/blob/5d6b2f22bc75213ac97cff0bcffa4a1ce2bc786c/docs/assets/js/console.js",
|
||||
"review": "The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance.",
|
||||
"review": "The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance. Modified replicator and Emotion/Stylis copies retain upstream author licenses; the original Emotion online Closure stage is not claimed to be reproducible. MurmurHash credits include Gary Court and Austin Appleby.",
|
||||
"roots": [
|
||||
"docs/assets/js/console.js"
|
||||
],
|
||||
@@ -1145,6 +1145,26 @@
|
||||
"source": "refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt",
|
||||
"target": "docs/licenses/console/simple-html-tokenizer/LICENSE",
|
||||
"sha256": "c41881de2a9f2200936648343500524be154eb79f649582f9582dd251b051b11"
|
||||
},
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/replicator-1.0.1-LICENSE.txt",
|
||||
"target": "docs/licenses/console/replicator/LICENSE",
|
||||
"sha256": "52f634086a97b3861a35afff7acf703ddbd5add8e617f6a1f540ae2f2c621284"
|
||||
},
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/stylis-3.5.4-LICENSE.txt",
|
||||
"target": "docs/licenses/console/stylis/LICENSE",
|
||||
"sha256": "045109dfd0547aa898408d08593e1adc41e9705519ba8a20baff89e7c6c52e91"
|
||||
},
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/gary-readme.txt",
|
||||
"target": "docs/licenses/console/murmurhash-js/README.md",
|
||||
"sha256": "73b67c593a2a0d6395bfe90d3bad32556ed5e7ce71883062efebc643d4e4b7b4"
|
||||
},
|
||||
{
|
||||
"source": "refactor/baselines/site-vendor/console-attribution/murmurhash2-public-domain.txt",
|
||||
"target": "docs/licenses/console/murmurhash2/PUBLIC-DOMAIN.txt",
|
||||
"sha256": "50e13b0a1963f0b382255d2425df245dbdfd209201621e8c157687caedbbb949"
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
@@ -1565,6 +1585,50 @@
|
||||
"notices": [
|
||||
"docs/licenses/console/simple-html-tokenizer/LICENSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "replicator (console-feed fork)",
|
||||
"version": "modified; upstream 1.0.x license",
|
||||
"tarball": "https://registry.npmjs.org/replicator/-/replicator-1.0.1.tgz",
|
||||
"assets": [
|
||||
"docs/assets/js/console.js"
|
||||
],
|
||||
"notices": [
|
||||
"docs/licenses/console/replicator/LICENSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stylis (Emotion fork)",
|
||||
"version": "3.5.4-derived",
|
||||
"tarball": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
|
||||
"assets": [
|
||||
"docs/assets/js/console.js"
|
||||
],
|
||||
"notices": [
|
||||
"docs/licenses/console/stylis/LICENSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "murmurhash-js (Gary Court)",
|
||||
"version": "license commit 23dc2e7",
|
||||
"tarball": "https://github.com/garycourt/murmurhash-js/blob/23dc2e7008582ca3ef69d8623f02bba4c8dd05e5/README.md",
|
||||
"assets": [
|
||||
"docs/assets/js/console.js"
|
||||
],
|
||||
"notices": [
|
||||
"docs/licenses/console/murmurhash-js/README.md"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "murmurhash2 (Austin Appleby)",
|
||||
"version": "61a0530",
|
||||
"tarball": "https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash2.cpp",
|
||||
"assets": [
|
||||
"docs/assets/js/console.js"
|
||||
],
|
||||
"notices": [
|
||||
"docs/licenses/console/murmurhash2/PUBLIC-DOMAIN.txt"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ test('mobile vConsole shows logs and upstream site notice texts are served uncha
|
||||
expect(await index.text()).toContain('Included component: @babel/runtime (react-inspector embedded) 7.13.10')
|
||||
expect(await index.text()).toContain('Included component: regenerator-runtime 0.13.7')
|
||||
expect(await index.text()).toContain('Included component: simple-html-tokenizer git-04799f4638ec5ed903a4e5aa6e832269fa59be6b')
|
||||
expect(await index.text()).toContain('Included component: replicator (console-feed fork)')
|
||||
expect(await index.text()).toContain('Included component: stylis (Emotion fork)')
|
||||
expect(await index.text()).toContain('Included component: murmurhash-js (Gary Court)')
|
||||
expect(await index.text()).toContain('Included component: murmurhash2 (Austin Appleby)')
|
||||
expect(await index.text()).toContain('Embedded attribution review is still incomplete')
|
||||
await page.evaluate(() => {
|
||||
window.vConsole.destroy()
|
||||
|
||||
@@ -6,6 +6,7 @@ import process from 'node:process'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Native console subscription and frozen build boundaries.
|
||||
import test from 'node:test'
|
||||
import ts from 'typescript'
|
||||
import { decodeGitSource, verifyForkOutput, verifyGitSource } from '../scripts/site-vendor/console/attribution.ts'
|
||||
import { generateConsole, moduleRanges, obsoleteMap, upstreamSha256 } from '../scripts/site-vendor/console/build.ts'
|
||||
import { extractNotice } from '../scripts/site-vendor/console/embedded-notices.ts'
|
||||
import { verifyMappedSources, verifyTransformedSources } from '../scripts/site-vendor/console/embedded-sources.ts'
|
||||
@@ -15,6 +16,28 @@ import { errorArgument } from '../scripts/site-vendor/console/runtime/errors.ts'
|
||||
import { css } from '../scripts/site-vendor/console/runtime/style.ts'
|
||||
import { createSubscriptions } from '../scripts/site-vendor/console/runtime/subscriptions.ts'
|
||||
|
||||
test('Immutable Git attribution verifies original blob identity and rejects altered API content', () => {
|
||||
const record = JSON.parse(fs.readFileSync('refactor/baselines/console-derived-attribution.json', 'utf8'))
|
||||
const source = record.remotes.find(source => source.id === 'gary-readme')
|
||||
const bytes = fs.readFileSync(source.source)
|
||||
const response = Buffer.from(JSON.stringify({ encoding: 'base64', content: bytes.toString('base64') }))
|
||||
assert.deepEqual(decodeGitSource(response, source), bytes)
|
||||
assert.throws(() => verifyGitSource(bytes, { ...source, gitBlobSha: '0'.repeat(40) }), /blob identity/)
|
||||
assert.throws(() => verifyGitSource(Buffer.from('shortened license'), source), /content changed/)
|
||||
assert.throws(() => decodeGitSource(Buffer.from(JSON.stringify({ encoding: 'utf8', content: bytes.toString() })), source), /encoding/)
|
||||
assert.throws(() => decodeGitSource(Buffer.from('{"encoding":"base64"}'), source), /Missing Git/)
|
||||
})
|
||||
|
||||
test('Fork reproduction permits only the pinned terminal source map and exact runtime bytes', () => {
|
||||
const code = 'var value = 1;\n'
|
||||
const trailer = '//# sourceMappingURL=data:application/json;base64,e30='
|
||||
verifyForkOutput(code, code + trailer)
|
||||
assert.throws(() => verifyForkOutput(code, code), /one terminal/)
|
||||
assert.throws(() => verifyForkOutput(code, code + trailer + trailer), /one terminal/)
|
||||
assert.throws(() => verifyForkOutput(code, `${code + trailer}\nrun()`), /trailer/)
|
||||
assert.throws(() => verifyForkOutput('var value = 2;\n', code + trailer), /runtime differs/)
|
||||
})
|
||||
|
||||
test('Embedded source maps reject omitted dependencies and content from a different release', () => {
|
||||
const upstream = Buffer.from('export const value = 1;\n')
|
||||
const map = { sources: ['../../src/owned.js', '../../node_modules/library/index.js'], sourcesContent: ['owned', upstream.toString()] }
|
||||
|
||||
@@ -111,7 +111,7 @@ test('Console notice CLI rejects omitted package or embedded attribution before
|
||||
const manifestPath = path.join(root, 'scripts/site-vendor/manifest.json')
|
||||
fs.mkdirSync(path.dirname(manifestPath), { recursive: true })
|
||||
const original = JSON.parse(fs.readFileSync('scripts/site-vendor/manifest.json', 'utf8'))
|
||||
for (const name of ['console-feed', 'parcel-bundler', 'styled-components', 'chromium-string-utils', 'stylis-rule-sheet', '@babel/runtime (react-inspector embedded)', 'regenerator-runtime', 'simple-html-tokenizer']) {
|
||||
for (const name of ['console-feed', 'parcel-bundler', 'styled-components', 'chromium-string-utils', 'stylis-rule-sheet', '@babel/runtime (react-inspector embedded)', 'regenerator-runtime', 'simple-html-tokenizer', 'replicator (console-feed fork)', 'stylis (Emotion fork)', 'murmurhash-js (Gary Court)', 'murmurhash2 (Austin Appleby)']) {
|
||||
for (const field of ['components', 'notices']) {
|
||||
const manifest = structuredClone(original)
|
||||
const group = manifest.groups.find(group => group.name === 'console')
|
||||
|
||||
Reference in new issue
Block a user