feat: self-hosting existing google fonts (#8540)
This commit is contained in:
@@ -130,15 +130,6 @@
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
<!-- For Nunito only preload the latin range, which should be good enough for now -->
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
|
||||
<!-- Register Assistant as the UI font, before the scene inits -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
|
||||
@@ -48,6 +48,8 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
sourcemap: true,
|
||||
// don't auto-inline small assets (i.e. fonts hosted on CDN)
|
||||
assetsInlineLimit: 0,
|
||||
},
|
||||
plugins: [
|
||||
woff2BrowserPlugin(),
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -24,14 +24,14 @@ import Cascadia from "./assets/CascadiaCode-Regular.woff2";
|
||||
import ComicShanns from "./assets/ComicShanns-Regular.woff2";
|
||||
import LiberationSans from "./assets/LiberationSans-Regular.woff2";
|
||||
|
||||
import LilitaLatin from "https://fonts.gstatic.com/s/lilitaone/v15/i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2";
|
||||
import LilitaLatinExt from "https://fonts.gstatic.com/s/lilitaone/v15/i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2";
|
||||
import LilitaLatin from "./assets/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2";
|
||||
import LilitaLatinExt from "./assets/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2";
|
||||
|
||||
import NunitoLatin from "https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2";
|
||||
import NunitoLatinExt from "https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2";
|
||||
import NunitoCyrilic from "https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2";
|
||||
import NunitoCyrilicExt from "https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2";
|
||||
import NunitoVietnamese from "https://fonts.gstatic.com/s/nunito/v26/XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2";
|
||||
import NunitoLatin from "./assets/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2";
|
||||
import NunitoLatinExt from "./assets/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2";
|
||||
import NunitoCyrilic from "./assets/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2";
|
||||
import NunitoCyrilicExt from "./assets/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2";
|
||||
import NunitoVietnamese from "./assets/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2";
|
||||
|
||||
export class Fonts {
|
||||
// it's ok to track fonts across multiple instances only once, so let's use
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -68,7 +68,6 @@
|
||||
"css-loader": "6.7.1",
|
||||
"file-loader": "6.2.0",
|
||||
"fonteditor-core": "2.4.0",
|
||||
"node-fetch": "3.3.2",
|
||||
"sass-loader": "13.0.2",
|
||||
"ts-loader": "9.3.1",
|
||||
"typescript": "4.9.4",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const { build } = require("esbuild");
|
||||
const { sassPlugin } = require("esbuild-sass-plugin");
|
||||
const { externalGlobalPlugin } = require("esbuild-plugin-external-global");
|
||||
const { woff2BrowserPlugin } = require("./woff2/woff2-esbuild-plugins");
|
||||
|
||||
// Will be used later for treeshaking
|
||||
//const fs = require("fs");
|
||||
@@ -45,13 +44,15 @@ const browserConfig = {
|
||||
format: "esm",
|
||||
plugins: [
|
||||
sassPlugin(),
|
||||
woff2BrowserPlugin(),
|
||||
externalGlobalPlugin({
|
||||
react: "React",
|
||||
"react-dom": "ReactDOM",
|
||||
}),
|
||||
],
|
||||
splitting: true,
|
||||
loader: {
|
||||
".woff2": "file",
|
||||
},
|
||||
};
|
||||
const createESMBrowserBuild = async () => {
|
||||
// Development unminified build with source maps
|
||||
@@ -100,9 +101,10 @@ const rawConfig = {
|
||||
entryPoints: ["index.tsx"],
|
||||
bundle: true,
|
||||
format: "esm",
|
||||
plugins: [sassPlugin(), woff2BrowserPlugin()],
|
||||
plugins: [sassPlugin()],
|
||||
loader: {
|
||||
".json": "copy",
|
||||
".woff2": "file",
|
||||
},
|
||||
packages: "external",
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
const fs = require("fs");
|
||||
const { build } = require("esbuild");
|
||||
const { sassPlugin } = require("esbuild-sass-plugin");
|
||||
const {
|
||||
woff2BrowserPlugin,
|
||||
woff2ServerPlugin,
|
||||
} = require("./woff2/woff2-esbuild-plugins");
|
||||
const { woff2ServerPlugin } = require("./woff2/woff2-esbuild-plugins");
|
||||
|
||||
const browserConfig = {
|
||||
entryPoints: ["index.ts"],
|
||||
bundle: true,
|
||||
format: "esm",
|
||||
plugins: [sassPlugin(), woff2BrowserPlugin()],
|
||||
plugins: [sassPlugin()],
|
||||
assetNames: "assets/[name]",
|
||||
loader: {
|
||||
".woff2": "file",
|
||||
},
|
||||
};
|
||||
|
||||
// Will be used later for treeshaking
|
||||
|
||||
@@ -2,45 +2,9 @@ const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { execSync } = require("child_process");
|
||||
const which = require("which");
|
||||
const fetch = require("node-fetch");
|
||||
const wawoff = require("wawoff2");
|
||||
const { Font } = require("fonteditor-core");
|
||||
|
||||
/**
|
||||
* Custom esbuild plugin to convert url woff2 imports into a text.
|
||||
* Other woff2 imports are handled by a "file" loader.
|
||||
*
|
||||
* @returns {import("esbuild").Plugin}
|
||||
*/
|
||||
module.exports.woff2BrowserPlugin = () => {
|
||||
return {
|
||||
name: "woff2BrowserPlugin",
|
||||
setup(build) {
|
||||
build.initialOptions.loader = {
|
||||
".woff2": "file",
|
||||
...build.initialOptions.loader,
|
||||
};
|
||||
|
||||
build.onResolve({ filter: /^https:\/\/.+?\.woff2$/ }, (args) => {
|
||||
return {
|
||||
path: args.path,
|
||||
namespace: "woff2BrowserPlugin",
|
||||
};
|
||||
});
|
||||
|
||||
build.onLoad(
|
||||
{ filter: /.*/, namespace: "woff2BrowserPlugin" },
|
||||
async (args) => {
|
||||
return {
|
||||
contents: args.path,
|
||||
loader: "text",
|
||||
};
|
||||
},
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom esbuild plugin to:
|
||||
* 1. inline all woff2 (url and relative imports) as base64 for server-side use cases (no need for additional font fetch; works in both esm and commonjs)
|
||||
@@ -53,27 +17,6 @@ module.exports.woff2BrowserPlugin = () => {
|
||||
* @returns {import("esbuild").Plugin}
|
||||
*/
|
||||
module.exports.woff2ServerPlugin = (options = {}) => {
|
||||
// google CDN fails time to time, so let's retry
|
||||
async function fetchRetry(url, options = {}, retries = 0, delay = 1000) {
|
||||
try {
|
||||
const response = await fetch(url, options);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Status: ${response.status}, ${await response.json()}`);
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (e) {
|
||||
if (retries > 0) {
|
||||
await new Promise((resolve) => setTimeout(resolve, delay));
|
||||
return fetchRetry(url, options, retries - 1, delay * 2);
|
||||
}
|
||||
|
||||
console.error(`Couldn't fetch: ${url}, error: ${e.message}`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: "woff2ServerPlugin",
|
||||
setup(build) {
|
||||
@@ -82,9 +25,7 @@ module.exports.woff2ServerPlugin = (options = {}) => {
|
||||
const fonts = new Map();
|
||||
|
||||
build.onResolve({ filter: /\.woff2$/ }, (args) => {
|
||||
const resolvedPath = args.path.startsWith("http")
|
||||
? args.path // url
|
||||
: path.resolve(args.resolveDir, args.path); // absolute path
|
||||
const resolvedPath = path.resolve(args.resolveDir, args.path);
|
||||
|
||||
return {
|
||||
path: resolvedPath,
|
||||
@@ -101,9 +42,7 @@ module.exports.woff2ServerPlugin = (options = {}) => {
|
||||
// read local woff2 as a buffer (WARN: `readFileSync` does not work!)
|
||||
woff2Buffer = await fs.promises.readFile(args.path);
|
||||
} else {
|
||||
// fetch remote woff2 as a buffer (i.e. from a cdn)
|
||||
const response = await fetchRetry(args.path, {}, 3);
|
||||
woff2Buffer = await response.buffer();
|
||||
throw new Error(`Font path has to be absolute! "${args.path}"`);
|
||||
}
|
||||
|
||||
// google's brotli decompression into snft
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
// `EXCALIDRAW_ASSET_PATH` as a SSOT
|
||||
const OSS_FONTS_CDN =
|
||||
"https://excalidraw.nyc3.cdn.digitaloceanspaces.com/fonts/oss/";
|
||||
|
||||
/**
|
||||
* Custom vite plugin to convert url woff2 imports into a text.
|
||||
* Other woff2 imports are automatically served and resolved as a file uri.
|
||||
* Custom vite plugin for auto-prefixing `EXCALIDRAW_ASSET_PATH` woff2 fonts in `excalidraw-app`.
|
||||
*
|
||||
* @returns {import("vite").PluginOption}
|
||||
*/
|
||||
module.exports.woff2BrowserPlugin = () => {
|
||||
// for now limited to woff2 only, might be extended to any assets in the future
|
||||
const regex = /^https:\/\/.+?\.woff2$/;
|
||||
let isDev;
|
||||
|
||||
return {
|
||||
@@ -18,34 +16,9 @@ module.exports.woff2BrowserPlugin = () => {
|
||||
config(_, { command }) {
|
||||
isDev = command === "serve";
|
||||
},
|
||||
resolveId(source) {
|
||||
if (!regex.test(source)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// getting the url to the dependency tree
|
||||
return source;
|
||||
},
|
||||
load(id) {
|
||||
if (!regex.test(id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// loading the url as string
|
||||
return `export default "${id}"`;
|
||||
},
|
||||
// necessary for dev as vite / rollup does skips https imports in serve (~dev) mode
|
||||
// aka dev mode equivalent of "export default x" above (resolveId + load)
|
||||
transform(code, id) {
|
||||
// treat https woff2 imports as a text
|
||||
if (isDev && id.endsWith("/excalidraw/fonts/index.ts")) {
|
||||
return code.replaceAll(
|
||||
/import\s+(\w+)\s+from\s+(["']https:\/\/.+?\.woff2["'])/g,
|
||||
`const $1 = $2`,
|
||||
);
|
||||
}
|
||||
|
||||
// use CDN for Assistant
|
||||
// using copy / replace as fonts defined in the `.css` don't have to be manually copied over (vite/rollup does this automatically),
|
||||
// but at the same time can't be easily prefixed with the `EXCALIDRAW_ASSET_PATH` only for the `excalidraw-app`
|
||||
if (!isDev && id.endsWith("/excalidraw/fonts/assets/fonts.css")) {
|
||||
return `/* WARN: The following content is generated during excalidraw-app build */
|
||||
|
||||
@@ -90,7 +63,6 @@ module.exports.woff2BrowserPlugin = () => {
|
||||
}`;
|
||||
}
|
||||
|
||||
// using EXCALIDRAW_ASSET_PATH as a SSOT
|
||||
if (!isDev && id.endsWith("excalidraw-app/index.html")) {
|
||||
return code.replace(
|
||||
"<!-- PLACEHOLDER:EXCALIDRAW_APP_FONTS -->",
|
||||
@@ -110,9 +82,10 @@ module.exports.woff2BrowserPlugin = () => {
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<!-- For Nunito only preload the latin range, which should be good enough for now -->
|
||||
<link
|
||||
rel="preload"
|
||||
href="${OSS_FONTS_CDN}Virgil-Regular-hO16qHwV.woff2"
|
||||
href="${OSS_FONTS_CDN}Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg-DqUjjPte.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
@@ -124,6 +97,13 @@ module.exports.woff2BrowserPlugin = () => {
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="${OSS_FONTS_CDN}Virgil-Regular-hO16qHwV.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { woff2BrowserPlugin } from "./scripts/woff2/woff2-vite-plugins";
|
||||
|
||||
export default defineConfig({
|
||||
//@ts-ignore
|
||||
plugins: [woff2BrowserPlugin()],
|
||||
test: {
|
||||
// Since hooks are running in stack in v2, which means all hooks run serially whereas
|
||||
// we need to run them in parallel
|
||||
|
||||
@@ -5194,11 +5194,6 @@ damerau-levenshtein@^1.0.8:
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
|
||||
|
||||
data-uri-to-buffer@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
|
||||
integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
|
||||
|
||||
data-urls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-4.0.0.tgz#333a454eca6f9a5b7b0f1013ff89074c3f522dd4"
|
||||
@@ -6262,14 +6257,6 @@ fd-slicer@~1.1.0:
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
fetch-blob@^3.1.2, fetch-blob@^3.1.4:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9"
|
||||
integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
|
||||
dependencies:
|
||||
node-domexception "^1.0.0"
|
||||
web-streams-polyfill "^3.0.3"
|
||||
|
||||
fflate@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea"
|
||||
@@ -6408,13 +6395,6 @@ form-data@^4.0.0:
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
formdata-polyfill@^4.0.10:
|
||||
version "4.0.10"
|
||||
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423"
|
||||
integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
|
||||
dependencies:
|
||||
fetch-blob "^3.1.2"
|
||||
|
||||
fraction.js@^4.2.0:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
|
||||
@@ -8256,11 +8236,6 @@ no-case@^3.0.4:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-domexception@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
|
||||
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
|
||||
|
||||
node-fetch@2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
@@ -8273,15 +8248,6 @@ node-fetch@2.6.7:
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-fetch@3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b"
|
||||
integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
|
||||
dependencies:
|
||||
data-uri-to-buffer "^4.0.0"
|
||||
fetch-blob "^3.1.4"
|
||||
formdata-polyfill "^4.0.10"
|
||||
|
||||
node-html-parser@^5.3.3:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-5.4.2.tgz#93e004038c17af80226c942336990a0eaed8136a"
|
||||
@@ -9667,7 +9633,7 @@ string-natural-compare@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
||||
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@@ -9685,15 +9651,6 @@ string-width@^4.1.0, string-width@^4.2.0:
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
|
||||
@@ -9765,14 +9722,7 @@ stringify-object@^3.3.0:
|
||||
is-obj "^1.0.1"
|
||||
is-regexp "^1.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@6.0.1, strip-ansi@^3.0.0, strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@^7.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^3.0.0, strip-ansi@^6.0.0, strip-ansi@^6.0.1, strip-ansi@^7.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@@ -10562,11 +10512,6 @@ wawoff2@2.0.1:
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
web-streams-polyfill@^3.0.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b"
|
||||
integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==
|
||||
|
||||
web-worker@^1.2.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.3.0.tgz#e5f2df5c7fe356755a5fb8f8410d4312627e6776"
|
||||
@@ -11009,7 +10954,7 @@ workbox-window@7.1.0, workbox-window@^7.0.0:
|
||||
"@types/trusted-types" "^2.0.2"
|
||||
workbox-core "7.1.0"
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
@@ -11027,15 +10972,6 @@ wrap-ansi@^6.2.0:
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
|
||||
|
||||
Reference in New Issue
Block a user