Browse Source

Add precision

pull/4/head
coomdev 2 years ago
commit
9823da0ad6
  1. 38
      README.md
  2. 7223
      main.user.js
  3. 28
      package-lock.json
  4. 28
      package.json
  5. 352
      src/main.ts
  6. 64
      tsconfig.json
  7. 230
      yarn.lock

38
README.md

@ -0,0 +1,38 @@
PNG Extra Embedder (PEE)
========================
Can embed any file in a PNG and upload it through 4chanX.
Requires 4chanX and tampermonkey.
Notes: 4chan seems to limit the amount of embedded data to around 140kb files.
How to Build
============
npm i and npm run build
then add something like
```
// ==UserScript==
// @name PNGFileEmbed
// @namespace http://tampermonkey.net/
// @version 0.1
// @description uhh
// @author You
// @match https://boards.4channel.org/g/thread/*
// @icon https://www.google.com/s2/favicons?domain=4channel.org
// @grant GM_xmlhttpRequest
// @run-at document-start
// @connect 4chan.org
// @connect 4channel.org
// @connect i.4cdn.org
// ==/UserScript==
```
at the very top of the file `dist/main.js` and import it in tampermonkey.
Don't know how to make this automatically yet.
How to Install
==============
Or use the prebuilt main.user.js at the root of this repo.

7223
main.user.js

File diff suppressed because it is too large

28
package-lock.json

@ -0,0 +1,28 @@
{
"name": "coomext",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "coomext",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@types/tampermonkey": "^4.0.5"
}
},
"node_modules/@types/tampermonkey": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tampermonkey/-/tampermonkey-4.0.5.tgz",
"integrity": "sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw=="
}
},
"dependencies": {
"@types/tampermonkey": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tampermonkey/-/tampermonkey-4.0.5.tgz",
"integrity": "sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw=="
}
}
}

28
package.json

@ -0,0 +1,28 @@
{
"name": "coomext",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "esbuild src/main.ts --bundle --outfile=dist/main.js --define:global=window",
"watch": "esbuild src/main.ts --bundle --outfile=dist/main.js --define:global=window --watch"
},
"author": "",
"license": "ISC",
"dependencies": {
"@types/tampermonkey": "^4.0.5",
"buffer": "^6.0.3",
"crc-32": "^1.2.0",
"events": "^3.3.0",
"file-type": "^17.0.2",
"readable-stream": "^3.6.0"
},
"devDependencies": {
"esbuild": "^0.14.7"
},
"browser": {
"node:buffer": "buffer",
"node:stream": "readable-stream"
}
}

352
src/main.ts

@ -0,0 +1,352 @@
/* eslint-disable */
import { Buffer } from "buffer";
import { buf } from "crc-32";
import { fileTypeFromBuffer } from 'file-type';
const IDAT = Buffer.from("IDAT");
const IEND = Buffer.from("IEND");
const tEXt = Buffer.from("tEXt");
const CUM0 = Buffer.from("CUM0");
let concatAB = (...bufs: Buffer[]) => {
let sz = bufs.map(e => e.byteLength).reduce((a, b) => a + b);
const ret = Buffer.alloc(sz);
let ptr = 0;
for (const b of bufs) {
b.copy(ret, ptr);
ptr += b.byteLength;
}
return ret;
}
let extractTextData = async (reader: ReadableStreamDefaultReader<Uint8Array>) => {
let total = Buffer.from('');
let ptr = 8;
let req = 8; // required bytes: require the png signature
try {
let chunk: ReadableStreamDefaultReadResult<Uint8Array>;
const catchup = async () => {
while (total.byteLength < req) {
chunk = await reader.read();
if (chunk.done)
throw new Error("Unexpected EOF");
total = concatAB(total, Buffer.from(chunk.value));
}
}
do {
req += 8; // require the bytes that store the length of the next chunk and its name
await catchup();
// at this point, ptr pointing to length of current chunk
let length = total.readInt32BE(ptr);
// ptr pointing to type of current chunk
ptr += 4;
const name = total.slice(ptr, ptr + 4);
if (Buffer.compare(IDAT, name) == 0 ||
Buffer.compare(IEND, name) == 0) {
// reached idat or iend before finding a tEXt, bail out
throw new Error("Couldn't find tEXt chunk");
}
req += length + 4; // require the rest of the chunk + CRC
//let crc = total.readInt32BE(ptr + 4 + length); // dont really care
ptr += 4; // ptr now points to the chunk data
if (Buffer.compare(tEXt, name) == 0) {
// our specific format stores a single file, CUM0 stores it as Base64. Could be enhanced to use more characters (the whole printable ascii characters, ie base85, but we lack good encoders...)
// catchup because we need to know the type;
await catchup();
if (Buffer.compare(total.slice(ptr, ptr + 4), CUM0) == 0) {
let data = Buffer.from(total.slice(ptr + 4, ptr + length - 4).toString(), 'base64');
let fns = data.readUInt32LE(0);
let filename = data.slice(4, 4 + fns).toString();
return { data: data.slice(4 + fns), filename };
}
// Unknown tEXt format
}
ptr += length + 4; // skips over data section and crc
} while (!chunk!.done);
} catch (e) {
console.error(e);
await reader.cancel();
reader.releaseLock();
}
}
let TMFetch = GM_xmlhttpRequest || GM.xmlHttpRequest;
let getUrl = (u: string) => {
let xml: Tampermonkey.AbortHandle<void>;
let pos = 0;
let total = 0;
return new ReadableStream<Uint8Array>({
cancel() {
xml?.abort();
},
start(cont) {
/*
get a small 128k chunk first then get the rest if required
*/
return new Promise<void>(reso => {
const size = (cont.desiredSize! > 2 ** 17 ? cont.desiredSize! : 2 ** 17);
const range = !total ? `bytes=${pos}-${pos + size - 1}` : `bytes=${pos}-${total - 1}`;
console.log(range, cont.desiredSize);
xml = TMFetch({
url: u,
fetch: true,
method: "GET",
binary: true,
responseType: "arraybuffer",
headers: {
range
},
// a bit spagetthi
onload(res) {
let hr = res.responseHeaders.split('\n').map(e => e.split(':'));
let r = hr.find(e => e[0] == "content-range")!;
let er = hr.find(e => e[0] == "content-length")!;
cont.enqueue(Buffer.from(res.response))
pos += +er[1];
if (r) {
let m = r[1].match(/bytes 0-\d+\/(\d+)/)
if (m)
total = +m[1];
}
if (pos >= total) {
cont.close()
reso();
return;
}
reso();
}
});
})
},
pull(cont) {
console.log("pulling") // shouldn't ever happen
return this.start!(cont);
}
}, {
highWaterMark: 40,
size(c) {
return 1;
}
})
}
let processImage = async (src: string) => {
if (!src.match(/\.png$/))
return;
let resp = getUrl(src);
let reader = resp?.getReader();
if (!reader)
return;
return await extractTextData(reader);
};
/* Used for debugging */
let processImage2 = async (src: string) => {
if (!src.match(/\.png$/))
return;
let resp = getUrl(src);
let reader = resp.getReader();
let data = Buffer.alloc(0);
let chunk;
while ((chunk = await reader.read()) && !chunk.done) {
data = concatAB(data, Buffer.from(chunk.value));
}
return {
filename: 'aaaa',
data
};
};
let processPost = async (post: HTMLDivElement) => {
let thumb = post.querySelector(".fileThumb") as HTMLAnchorElement;
if (!thumb)
return;
console.log("Processing post", post)
let res = await processImage(thumb.href);
if (!res)
return;
// add buttons
let fi = post.querySelector(".file-info")!;
let a = document.createElement('a');
a.className = "fa fa-eye";
let type = await fileTypeFromBuffer(res.data);
let cont: HTMLImageElement | HTMLVideoElement;
let w: number, h: number;
if (type?.mime.startsWith("image")) {
cont = document.createElement("img");
} else if (type?.mime.startsWith("video")) {
cont = document.createElement("video");
} else
return; // TODO: handle new file types??? Or direct "download"?
cont.src = URL.createObjectURL(new Blob([res.data]));
await new Promise(res => {
cont.onload = res;
});
if (cont instanceof HTMLImageElement) {
w = cont.naturalWidth;
h = cont.naturalHeight;
}
if (cont instanceof HTMLVideoElement) {
w = cont.width;
h = cont.height;
}
let contract = () => {
cont.style.width = "auto";
cont.style.height = "auto";
cont.style.maxWidth = "125px";
cont.style.maxHeight = "125px";
}
let expand = () => {
cont.style.width = `${w}px`;
cont.style.height = `${h}px`;
cont.style.maxWidth = "unset";
cont.style.maxHeight = "unset";
}
let imgcont = document.createElement('div');
let p = thumb.parentElement!;
p.removeChild(thumb);
imgcont.appendChild(thumb);
p.appendChild(imgcont);
thumb.style.display = "flex";
thumb.style.gap = "5px";
thumb.style.flexDirection = "column";
a.classList.toggle("disabled");
let contracted = true;
contract();
cont.onclick = (e) => {
contracted = !contracted;
(contracted) ? contract() : expand();
e.stopPropagation();
}
let visible = false;
a.onclick = () => {
visible = !visible;
if (visible) {
imgcont.appendChild(cont)
} else {
imgcont.removeChild(cont);
}
a.classList.toggle("disabled");
}
fi.children[1].insertAdjacentElement('afterend', a);
}
let buildTextChunk = async (f: File) => {
let ab = await f.arrayBuffer();
let fns = Buffer.alloc(4);
fns.writeInt32LE(f.name.length, 0)
let fb = Buffer.from(await new Blob([fns, f.name, ab]).arrayBuffer()).toString('base64');
let buff = Buffer.alloc(4 /*Length storage*/ + 4 /*Chunk Type*/ + 4 /*Magic*/ + 1 /*Null separator*/ + fb.length + 4 /* CRC */);
let ptr = 0;
buff.writeInt32BE(buff.byteLength - 12, ptr); // doesn't count chunk type, lenght storage and crc
ptr += 4;
buff.write("tEXtCUM0\0", ptr); // Writes Chunktype+ Magic+null byte
ptr += 9;
buff.write(fb, ptr);
ptr += fb.length;
// CRC over the chunk name to the last piece of data
let checksum = buf(buff.slice(4, -4))
buff.writeInt32BE(checksum, ptr);
return buff;
}
let buildInjection = async (container: File, inj: File) => {
let tEXtChunk = await buildTextChunk(inj);
let ogFile = Buffer.from(await container.arrayBuffer());
let ret = Buffer.alloc(tEXtChunk.byteLength + ogFile.byteLength);
let ptr = 8;
let wptr = 8;
let wrote = false;
ogFile.copy(ret, 0, 0, ptr);// copy PNG signature
// copy every chunk as is except inject the text chunk before the first IDAT or END
while (ptr < ogFile.byteLength) {
let len = ogFile.readInt32BE(ptr);
let name = ogFile.slice(ptr + 4, ptr + 8);
if (name.equals(IDAT) || name.equals(IEND)) {
if (!wrote) {
wrote = true;
tEXtChunk.copy(ret, wptr);
wptr += tEXtChunk.byteLength;
}
}
ret.writeInt32BE(len, wptr);
wptr += 4;
name.copy(ret, wptr);
wptr += 4;
ogFile.slice(ptr + 8, ptr + 8 + len + 4).copy(ret, wptr);
ptr += len + 8 + 4;
wptr += len + 4;
}
return { file: new Blob([ret]), name: container.name };
}
let embedded;
const startup = async () => {
//await Promise.all(
let glow = [...document.querySelectorAll('.postContainer')].find(e => e.textContent?.includes("191 KB"));
await processPost(glow as any)
document.addEventListener('PostsInserted', <any>(async (e: CustomEvent<string>) => {
processPost(e.target as any);
}));
let getSelectedFile = () => {
return new Promise<File>(res => {
document.addEventListener('QRFile', e => res((e as any).detail), { once: true });
document.dispatchEvent(new CustomEvent('QRGetFile'));
})
}
let injected = false;
document.addEventListener('QRDialogCreation', <any>((e: CustomEvent<string>) => {
if (injected)
return;
injected = true;
let target = e.target as HTMLDivElement;
let bts = target.querySelector('#qr-filename-container')
let i = document.createElement('i');
i.className = "fa fa-magnet";
let a = document.createElement('a')
a.appendChild(i);
a.title = "Embed File (Select a file before...)";
bts?.appendChild(a);
a.onclick = async (e) => {
let file = await getSelectedFile();
if (!file)
return;
let input = document.createElement('input') as HTMLInputElement;
input.setAttribute("type", "file");
input.onchange = (async ev => {
if (input.files)
document.dispatchEvent(new CustomEvent('QRSetFile', { detail: await buildInjection(file, input.files[0]) }))
})
input.click();
}
}));
};
document.addEventListener('4chanXInitFinished', startup);

64
tsconfig.json

@ -0,0 +1,64 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
//"sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
"inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
"inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

230
yarn.lock

@ -0,0 +1,230 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@tokenizer/token@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276"
integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==
"@types/tampermonkey@^4.0.5":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@types/tampermonkey/-/tampermonkey-4.0.5.tgz#03a0c2366a7c1fe5e1c77c88adf568f40b3c18e5"
integrity sha512-FGPo7d+qZkDF7vyrwY1WNhcUnfDyVpt2uyL7krAu3WKCUMCfIUzOuvt8aSk8N2axHT8XPr9stAEDGVHLvag6Pw==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
buffer@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.2.1"
crc-32@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
dependencies:
exit-on-epipe "~1.0.1"
printj "~1.1.0"
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.7.tgz#8c78cbb617f9f216abfb5a84cca453b51421a1b6"
integrity sha512-9/Q1NC4JErvsXzJKti0NHt+vzKjZOgPIjX/e6kkuCzgfT/GcO3FVBcGIv4HeJG7oMznE6KyKhvLrFgt7CdU2/w==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.7.tgz#7424bdb64c104556d36b7429af79ab51415ab8f4"
integrity sha512-Z9X+3TT/Xj+JiZTVlwHj2P+8GoiSmUnGVz0YZTSt8WTbW3UKw5Pw2ucuJ8VzbD2FPy0jbIKJkko/6CMTQchShQ==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.7.tgz#6a243dc0132aeb11c1991f968a6a9e393f43c6bc"
integrity sha512-68e7COhmwIiLXBEyxUxZSSU0akgv8t3e50e2QOtKdBUE0F6KIRISzFntLe2rYlNqSsjGWsIO6CCc9tQxijjSkw==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.7.tgz#e7281e50522e724c4da502504dcd75be0db46c94"
integrity sha512-76zy5jAjPiXX/S3UvRgG85Bb0wy0zv/J2lel3KtHi4V7GUTBfhNUPt0E5bpSXJ6yMT7iThhnA5rOn+IJiUcslQ==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.7.tgz#31e513098efd181d76a3ba3ea285836d37f018a3"
integrity sha512-lSlYNLiqyzd7qCN5CEOmLxn7MhnGHPcu5KuUYOG1i+t5A6q7LgBmfYC9ZHJBoYyow3u4CNu79AWHbvVLpE/VQQ==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.7.tgz#82cf96accbf55d3007c3338dc3b3144efa9ae108"
integrity sha512-Vk28u409wVOXqTaT6ek0TnfQG4Ty1aWWfiysIaIRERkNLhzLhUf4i+qJBN8mMuGTYOkE40F0Wkbp6m+IidOp2A==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.7.tgz#67bdfe23a6ca918a0bb8e9558a3ee0fdf98c0bc0"
integrity sha512-+Lvz6x+8OkRk3K2RtZwO+0a92jy9si9cUea5Zoru4yJ/6EQm9ENX5seZE0X9DTwk1dxJbjmLsJsd3IoowyzgVg==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.7.tgz#f79c69ff0c176559c418de8e59aa3cf388fff992"
integrity sha512-kJd5beWSqteSAW086qzCEsH6uwpi7QRIpzYWHzEYwKKu9DiG1TwIBegQJmLpPsLp4v5RAFjea0JAmAtpGtRpqg==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.7.tgz#3d665b35e1c27dbe1c9deb8bf956d7d1f191a21b"
integrity sha512-OzpXEBogbYdcBqE4uKynuSn5YSetCvK03Qv1HcOY1VN6HmReuatjJ21dCH+YPHSpMEF0afVCnNfffvsGEkxGJQ==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.7.tgz#226114a0cc6649ba0ffd3428118a8f622872f16d"
integrity sha512-mFWpnDhZJmj/h7pxqn1GGDsKwRfqtV7fx6kTF5pr4PfXe8pIaTERpwcKkoCwZUkWAOmUEjMIUAvFM72A6hMZnA==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.7.tgz#5c67ae56517f2644d567b2ca5ecb97f9520cfc49"
integrity sha512-wM7f4M0bsQXfDL4JbbYD0wsr8cC8KaQ3RPWc/fV27KdErPW7YsqshZZSjDV0kbhzwpNNdhLItfbaRT8OE8OaKA==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.7.tgz#69dc0469ea089013956d8c6aa71c9e7fc25fc567"
integrity sha512-J/afS7woKyzGgAL5FlgvMyqgt5wQ597lgsT+xc2yJ9/7BIyezeXutXqfh05vszy2k3kSvhLesugsxIA71WsqBw==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.7.tgz#3a9d04ecf820708e2e5b7d26fa7332e3f19f6b6c"
integrity sha512-7CcxgdlCD+zAPyveKoznbgr3i0Wnh0L8BDGRCjE/5UGkm5P/NQko51tuIDaYof8zbmXjjl0OIt9lSo4W7I8mrw==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.7.tgz#7c33a682f0fd9565cae7df165d0e8736b7b62623"
integrity sha512-GKCafP2j/KUljVC3nesw1wLFSZktb2FGCmoT1+730zIF5O6hNroo0bSEofm6ZK5mNPnLiSaiLyRB9YFgtkd5Xg==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.7.tgz#24ec706a5f25b4499048f56146bcff0ed3839dce"
integrity sha512-5I1GeL/gZoUUdTPA0ws54bpYdtyeA2t6MNISalsHpY269zK8Jia/AXB3ta/KcDHv2SvNwabpImeIPXC/k0YW6A==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.7.tgz#dd6d5b5bace93cd7a9174d31fbd727ba21885abf"
integrity sha512-CIGKCFpQOSlYsLMbxt8JjxxvVw9MlF1Rz2ABLVfFyHUF5OeqHD5fPhGrCVNaVrhO8Xrm+yFmtjcZudUGr5/WYQ==
[email protected]:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.7.tgz#ecfd9ac289606f26760c4f737caaeeadfff3cfe3"
integrity sha512-eOs1eSivOqN7cFiRIukEruWhaCf75V0N8P0zP7dh44LIhLl8y6/z++vv9qQVbkBm5/D7M7LfCfCTmt1f1wHOCw==
esbuild@^0.14.7:
version "0.14.7"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.7.tgz#e85cead55b0e1001abf1b2ce4a11c1d4d709d13c"
integrity sha512-+u/msd6iu+HvfysUPkZ9VHm83LImmSNnecYPfFI01pQ7TTcsFR+V0BkybZX7mPtIaI7LCrse6YRj+v3eraJSgw==
optionalDependencies:
esbuild-android-arm64 "0.14.7"
esbuild-darwin-64 "0.14.7"
esbuild-darwin-arm64 "0.14.7"
esbuild-freebsd-64 "0.14.7"
esbuild-freebsd-arm64 "0.14.7"
esbuild-linux-32 "0.14.7"
esbuild-linux-64 "0.14.7"
esbuild-linux-arm "0.14.7"
esbuild-linux-arm64 "0.14.7"
esbuild-linux-mips64le "0.14.7"
esbuild-linux-ppc64le "0.14.7"
esbuild-netbsd-64 "0.14.7"
esbuild-openbsd-64 "0.14.7"
esbuild-sunos-64 "0.14.7"
esbuild-windows-32 "0.14.7"
esbuild-windows-64 "0.14.7"
esbuild-windows-arm64 "0.14.7"
events@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
exit-on-epipe@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
file-type@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-17.0.2.tgz#7e7564058a18aeb232b75832e5f38c6881fc7822"
integrity sha512-lrBLqujGI8O1aOsXuCuwvAu0kmU+pUNsusQNlp2Xs+8JNJm8VNGGPDwLfmtQPmnOxoIKvwk5rOEijrF0RbYHvQ==
dependencies:
readable-web-to-node-stream "^3.0.2"
strtok3 "^7.0.0-alpha.7"
token-types "^5.0.0-alpha.1"
ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
inherits@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
peek-readable@^5.0.0-alpha.5:
version "5.0.0-alpha.5"
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0-alpha.5.tgz#ace5dfedf7bc33f17c9b5170b9d54f69a4fba79b"
integrity sha512-pJohF/tDwV3ntnT5+EkUo4E700q/j/OCDuPxtM+5/kFGjyOai/sK4/We4Cy1MB2OiTQliWU5DxPvYIKQAdPqAA==
printj@~1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readable-web-to-node-stream@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb"
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==
dependencies:
readable-stream "^3.6.0"
safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
strtok3@^7.0.0-alpha.7:
version "7.0.0-alpha.7"
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0-alpha.7.tgz#631b7684ba7fc432a04846ceddd1d564b44b448e"
integrity sha512-lISXV4xwiHu4Oi0KzSod9CT3LPnJNIQueXrgVr+xCZ5avUakHxgOwEztm0buiw2pLbWBatZ48GxsoSMyuObLdQ==
dependencies:
"@tokenizer/token" "^0.3.0"
peek-readable "^5.0.0-alpha.5"
token-types@^5.0.0-alpha.1:
version "5.0.0-alpha.2"
resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.0-alpha.2.tgz#e43d63b2a8223a593d1c782a5149bec18f1abf97"
integrity sha512-EsG9UxAW4M6VATrEEjhPFTKEUi1OiJqTUMIZOGBN49fGxYjZB36k0p7to3HZSmWRoHm1QfZgrg3e02fpqAt5fQ==
dependencies:
"@tokenizer/token" "^0.3.0"
ieee754 "^1.2.1"
util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
Loading…
Cancel
Save