diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..4083d9d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,29 @@
+# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: build
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [18.x, 20.x, 22.x]
+ # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm ci
+ - run: npm run build --if-present
+ # - run: npm test
diff --git a/.gitignore b/.gitignore
index 032b978..6e66c17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
-.ignoreme
-.build
\ No newline at end of file
+.old
+.build
+node_modules/
+dist/
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..1a793f5
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,10 @@
+{
+ "json.schemas": [
+ {
+ "fileMatch": [
+ "/manifest.json"
+ ],
+ "url": "http://json.schemastore.org/chrome-manifest"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/icons/icon.128.png b/icons/icon.128.png
deleted file mode 100644
index 24a47d8..0000000
Binary files a/icons/icon.128.png and /dev/null differ
diff --git a/icons/icon.16.png b/icons/icon.16.png
deleted file mode 100644
index 6926e21..0000000
Binary files a/icons/icon.16.png and /dev/null differ
diff --git a/icons/icon.32.png b/icons/icon.32.png
deleted file mode 100644
index f7d9c97..0000000
Binary files a/icons/icon.32.png and /dev/null differ
diff --git a/icons/icon.48.png b/icons/icon.48.png
deleted file mode 100644
index 43f1e24..0000000
Binary files a/icons/icon.48.png and /dev/null differ
diff --git a/icons/icon.64.png b/icons/icon.64.png
deleted file mode 100644
index 6c208bd..0000000
Binary files a/icons/icon.64.png and /dev/null differ
diff --git a/js/main.js b/js/main.js
deleted file mode 100644
index c476897..0000000
--- a/js/main.js
+++ /dev/null
@@ -1,298 +0,0 @@
-"use strict";
-
-window._forksdiffconstants = {
- icons: {
- loading:
- '',
-
- star: '',
- fork: '',
- },
- regex: {
- diff: /
[\S\s]*?This branch is[\S\s]*?((?
[0-9]*) commits? ahead[\S\s]*?(?[0-9]*) commits? behind|(?[0-9]*) commits? behind|(?[0-9]*) commits? ahead)/,
- stars: /([0-9]+) users? starred this repository/,
- },
-};
-
-const LegacyLoadDiffButton = (() => {
- const queue = [];
- const parallelNum = 3;
-
- const _addSpan = (parent, text, className) => {
- const span = document.createElement("span");
- span.className = className;
- span.appendChild(document.createTextNode(text));
- parent.appendChild(span);
- };
-
- const _processRepo = () => {
- const currentRepo = queue.shift();
-
- // Add spinner
- const spinner = document.createElement("span");
- spinner.innerHTML = window._forksdiffconstants.icons.loading;
- currentRepo.appendChild(spinner);
-
- const request = new XMLHttpRequest();
- request.addEventListener("load", function () {
- if (this.status == 429) {
- // Rate limited :(
- console.log(this.getResponseHeader("Retry-After"));
- return;
- }
-
- const body = this.responseText;
- currentRepo.removeChild(spinner);
-
- // Read diff
- const diffRegexResult = window._forksdiffconstants.regex.diff.exec(body);
- if (!diffRegexResult) {
- _addSpan(currentRepo, "is even", "text-gray");
- } else {
- const {
- groups: { a1, a2, b, c },
- } = diffRegexResult;
-
- if (a1 && a2) {
- _addSpan(currentRepo, "+" + a1, "cadd");
- _addSpan(currentRepo, " ");
- _addSpan(currentRepo, "-" + a2, "cdel");
- } else if (b) {
- _addSpan(currentRepo, "-" + b, "cdel");
- } else if (c) {
- _addSpan(currentRepo, "+" + c, "cadd");
- }
- }
-
- // Read stars
- _addSpan(currentRepo, " ");
- const stars = body.match(window._forksdiffconstants.regex.stars);
- const starIndicator = document.createElement("span");
- starIndicator.innerHTML =
- window._forksdiffconstants.icons.star + " " + stars[1];
- currentRepo.appendChild(starIndicator);
-
- // Process next repo
- if (queue.length > 0) {
- _processRepo();
- }
- });
-
- // Send request
- request.open("GET", currentRepo.getElementsByTagName("a")[2].href);
- request.send();
- };
-
- const _buttonAction = (e) => {
- // Disable button
- e.target.classList.add("disabled");
- e.target.removeEventListener("click", _buttonAction);
-
- // Iterate through repos
- const repos = document
- .getElementById("network")
- .querySelector("div").children;
- for (let i = 0; i < repos.length; i++) {
- // Skip root fork
- if (repos[i].getElementsByClassName("network-tree").length === 0) {
- continue;
- }
-
- queue.push(repos[i]);
- }
-
- // Start
- for (let i = parallelNum - 1; i >= 0; i--) {
- if (queue.length > 0) {
- _processRepo();
- }
- }
- };
-
- const addButton = () => {
- const network = document.getElementById("network");
-
- // Check if we have at least one div.repo, if not we are on Network page and not Forks page
- if (network === null || network.querySelector("div.repo") === null) return;
-
- const mainButton = document.createElement("button");
- mainButton.className = "btn float-right";
- mainButton.innerHTML = window._forksdiffconstants.icons.fork + " Load diff";
- mainButton.addEventListener("click", _buttonAction);
- network.insertBefore(mainButton, network.childNodes[0]);
-
- // Add space if Refined Github is enabled
- if (
- mainButton.nextElementSibling.tagName === "A" &&
- mainButton.nextElementSibling.href &&
- mainButton.nextElementSibling.href.includes("useful-forks.github.io")
- ) {
- mainButton.classList.add("ml-2");
- } else {
- mainButton.classList.add("mr-2");
- }
- };
-
- return {
- addButton: addButton,
- };
-})();
-
-const LoadDiffButton = (() => {
- const queue = [];
- const parallelNum = 3;
-
- const addSpan = (parent, text, className) => {
- const span = document.createElement("span");
- span.className = className;
- span.appendChild(document.createTextNode(text));
- parent.appendChild(span);
- };
-
- const createInfoBox = () => {
- const box = document.createElement("div");
- box.className = "mr-4 f6";
- return box;
- };
-
- const processRepo = () => {
- const currentRepo = queue.shift();
-
- // Get info box
- const infoBoxContainer = currentRepo
- .querySelector("div")
- .querySelector("div");
-
- // Create info box
- const infoBox = createInfoBox();
- infoBoxContainer.insertBefore(infoBox, infoBoxContainer.children[4]);
-
- // Add spinner
- const spinner = document.createElement("span");
- spinner.innerHTML = window._forksdiffconstants.icons.loading;
- infoBox.appendChild(spinner);
-
- // TODO: Maybe switch to fetch
- const request = new XMLHttpRequest();
- request.addEventListener("load", function () {
- // Remove spinner
- infoBox.removeChild(spinner);
-
- if (this.status == 429) {
- // Rate limited :(
- console.log(this.getResponseHeader("Retry-After"));
- return;
- }
-
- const body = this.responseText;
-
- // Read diff
- const diffRegexResult = window._forksdiffconstants.regex.diff.exec(body);
- if (!diffRegexResult) {
- addSpan(infoBox, "is even", "text-gray");
- } else {
- const {
- groups: { a1, a2, b, c },
- } = diffRegexResult;
-
- if (a1 && a2) {
- addSpan(infoBox, "+" + a1, "cadd");
- addSpan(infoBox, " ");
- addSpan(infoBox, "-" + a2, "cdel");
- } else if (b) {
- addSpan(infoBox, "-" + b, "cdel");
- } else if (c) {
- addSpan(infoBox, "+" + c, "cadd");
- }
- }
-
- // Process next repo
- if (queue.length > 0) {
- processRepo();
- }
- });
-
- // Send request
- request.open("GET", currentRepo.querySelectorAll("a")[1].href);
- request.send();
- };
-
- const buttonAction = (e) => {
- console.log(e);
-
- // Disable button
- e.target.setAttribute("disabled", "disabled");
- e.target.removeEventListener("click", buttonAction);
-
- // Extract forks links
- const forks = document
- .querySelector(".Layout-main")
- .querySelector("ul")
- .querySelectorAll("li");
- console.log(forks);
- queue.push.apply(queue, forks);
- console.log(queue);
-
- // Start
- for (let i = 0; i < parallelNum; i++) {
- if (queue.length > 0) {
- processRepo();
- }
- }
- };
-
- const addButton = () => {
- const buttons = document
- .querySelector("search-control-menu")
- .querySelector("div");
-
- const mainButton = document.createElement("button");
- mainButton.className =
- "Button--secondary Button--small Button text-normal mt-2 ml-lg-2 mt-lg-0";
- mainButton.addEventListener("click", buttonAction);
-
- // Add text
- // const span1 = document.createElement("span");
- // span1.className = "Button-content";
- // const span2 = document.createElement("span");
- // span2.className = "Button-label";
- // span2.appendChild(document.createTextNode("Load diff"));
- // span1.appendChild(span2);
- // mainButton.appendChild(span1);
- mainButton.appendChild(document.createTextNode("Load diff"));
-
- buttons.appendChild(mainButton);
- };
-
- return {
- addButton: addButton,
- };
-})();
-
-const ForksDiff = (() => {
- // Regex
- const legacyNetworkRegex =
- /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/network\/members/;
- const forksUrlRegex = /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/forks/;
-
- const init = () => {
- // Check page
- if (forksUrlRegex.test(location.href)) {
- LoadDiffButton.addButton();
- } else if (legacyNetworkRegex.test(location.href)) {
- LegacyLoadDiffButton.addButton();
- }
- };
-
- return {
- init: init,
- };
-})();
-
-// On load
-ForksDiff.init();
-
-// Add Turbo listener
-document.addEventListener("turbo:render", () => {
- ForksDiff.init();
-});
diff --git a/pack.sh b/pack.sh
index b7e076f..abe24f5 100755
--- a/pack.sh
+++ b/pack.sh
@@ -1,17 +1,18 @@
#!/usr/bin/env bash
-VERSION="1.2.4-chrome"
+VERSION="1.3.0-chrome"
ICONS_SIZES="16 32 48 64 128"
OUTPUT_FOLDER=".build"
# Prepare icons
for size in ${ICONS_SIZES}; do
(
- cd icons || exit 1
+ cd public/icons || exit 1
inkscape -w "${size}" -h "${size}" source.svg --export-filename "icon.${size}.png"
)
done
# Pack to zip
-mkdir "${OUTPUT_FOLDER}"
-7z a "${OUTPUT_FOLDER}/${VERSION}.zip" -x!pack.sh -x!icons/source.svg -x!.git -x!.gitignore -x!.ignoreme -x!.github -x!"${OUTPUT_FOLDER}"
+mkdir -p "${OUTPUT_FOLDER}"
+(cd dist && zip -r "${VERSION}.zip" ./*)
+mv dist/"${VERSION}.zip" "${OUTPUT_FOLDER}"
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..33f8801
--- /dev/null
+++ b/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "forks-diff",
+ "version": "1.3.0",
+ "author": "Giacomo Ferretti",
+ "description": "A Chrome/Firefox extension that shows commits behind and ahead for every fork.",
+ "keywords": [
+ "chrome",
+ "firefox",
+ "extension",
+ "github",
+ "forks",
+ "diff"
+ ],
+ "license": "Apache-2.0",
+ "main": "index.js",
+ "scripts": {
+ "watch": "webpack --config webpack/webpack.dev.js --watch",
+ "build": "webpack --config webpack/webpack.prod.js",
+ "clean": "rimraf dist"
+ },
+ "devDependencies": {
+ "@types/chrome": "^0.0.279",
+ "copy-webpack-plugin": "^12.0.2",
+ "rimraf": "^6.0.1",
+ "ts-loader": "^9.5.1",
+ "typescript": "^5.6.3",
+ "webpack": "^5.95.0",
+ "webpack-cli": "^5.1.4",
+ "webpack-merge": "^6.0.1"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..86e3aa4
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,1541 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ devDependencies:
+ '@types/chrome':
+ specifier: ^0.0.279
+ version: 0.0.279
+ copy-webpack-plugin:
+ specifier: ^12.0.2
+ version: 12.0.2(webpack@5.95.0)
+ rimraf:
+ specifier: ^6.0.1
+ version: 6.0.1
+ ts-loader:
+ specifier: ^9.5.1
+ version: 9.5.1(typescript@5.6.3)(webpack@5.95.0)
+ typescript:
+ specifier: ^5.6.3
+ version: 5.6.3
+ webpack:
+ specifier: ^5.95.0
+ version: 5.95.0(webpack-cli@5.1.4)
+ webpack-cli:
+ specifier: ^5.1.4
+ version: 5.1.4(webpack@5.95.0)
+ webpack-merge:
+ specifier: ^6.0.1
+ version: 6.0.1
+
+packages:
+
+ '@discoveryjs/json-ext@0.5.7':
+ resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==}
+ engines: {node: '>=10.0.0'}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/source-map@0.3.6':
+ resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@sindresorhus/merge-streams@2.3.0':
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+
+ '@types/chrome@0.0.279':
+ resolution: {integrity: sha512-wl0IxQ2OQiMazPZM5LimHQ7Jwd72/O8UvvzyptplXT2S4eUqXH5C0n8S+v8PtKhyX89p0igCPpNy3Bwksyk57g==}
+
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+ '@types/filesystem@0.0.36':
+ resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==}
+
+ '@types/filewriter@0.0.33':
+ resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==}
+
+ '@types/har-format@1.2.16':
+ resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/node@22.7.9':
+ resolution: {integrity: sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==}
+
+ '@webassemblyjs/ast@1.12.1':
+ resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6':
+ resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==}
+
+ '@webassemblyjs/helper-api-error@1.11.6':
+ resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==}
+
+ '@webassemblyjs/helper-buffer@1.12.1':
+ resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==}
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6':
+ resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==}
+
+ '@webassemblyjs/ieee754@1.11.6':
+ resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==}
+
+ '@webassemblyjs/leb128@1.11.6':
+ resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==}
+
+ '@webassemblyjs/utf8@1.11.6':
+ resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==}
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==}
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==}
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==}
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==}
+
+ '@webpack-cli/configtest@2.1.1':
+ resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==}
+ engines: {node: '>=14.15.0'}
+ peerDependencies:
+ webpack: 5.x.x
+ webpack-cli: 5.x.x
+
+ '@webpack-cli/info@2.0.2':
+ resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==}
+ engines: {node: '>=14.15.0'}
+ peerDependencies:
+ webpack: 5.x.x
+ webpack-cli: 5.x.x
+
+ '@webpack-cli/serve@2.0.5':
+ resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==}
+ engines: {node: '>=14.15.0'}
+ peerDependencies:
+ webpack: 5.x.x
+ webpack-cli: 5.x.x
+ webpack-dev-server: '*'
+ peerDependenciesMeta:
+ webpack-dev-server:
+ optional: true
+
+ '@xtuc/ieee754@1.2.0':
+ resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
+
+ '@xtuc/long@4.2.2':
+ resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
+
+ acorn-import-attributes@1.9.5:
+ resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==}
+ peerDependencies:
+ acorn: ^8
+
+ acorn@8.13.0:
+ resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv-formats@2.1.1:
+ resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv-keywords@3.5.2:
+ resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
+ peerDependencies:
+ ajv: ^6.9.1
+
+ ajv-keywords@5.1.0:
+ resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
+ peerDependencies:
+ ajv: ^8.8.2
+
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
+ ajv@8.17.1:
+ resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.24.2:
+ resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ caniuse-lite@1.0.30001669:
+ resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ chrome-trace-event@1.0.4:
+ resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
+ engines: {node: '>=6.0'}
+
+ clone-deep@4.0.1:
+ resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==}
+ engines: {node: '>=6'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ colorette@2.0.20:
+ resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+
+ commander@10.0.1:
+ resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
+ engines: {node: '>=14'}
+
+ commander@2.20.3:
+ resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+
+ copy-webpack-plugin@12.0.2:
+ resolution: {integrity: sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==}
+ engines: {node: '>= 18.12.0'}
+ peerDependencies:
+ webpack: ^5.1.0
+
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.5.43:
+ resolution: {integrity: sha512-NxnmFBHDl5Sachd2P46O7UJiMaMHMLSofoIWVJq3mj8NJgG0umiSeljAVP9lGzjI0UDLJJ5jjoGjcrB8RSbjLQ==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ enhanced-resolve@5.17.1:
+ resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==}
+ engines: {node: '>=10.13.0'}
+
+ envinfo@7.14.0:
+ resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ eslint-scope@5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ events@3.3.0:
+ resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
+ engines: {node: '>=0.8.x'}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-uri@3.0.3:
+ resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==}
+
+ fastest-levenshtein@1.0.16:
+ resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
+ engines: {node: '>= 4.9.1'}
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@4.1.0:
+ resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ engines: {node: '>=8'}
+
+ flat@5.0.2:
+ resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+ hasBin: true
+
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob-to-regexp@0.4.1:
+ resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
+
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ globby@14.0.2:
+ resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==}
+ engines: {node: '>=18'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ import-local@3.2.0:
+ resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ interpret@3.1.1:
+ resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==}
+ engines: {node: '>=10.13.0'}
+
+ is-core-module@2.15.1:
+ resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-plain-object@2.0.4:
+ resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
+ engines: {node: '>=0.10.0'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ isobject@3.0.1:
+ resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
+ engines: {node: '>=0.10.0'}
+
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
+ jest-worker@27.5.1:
+ resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
+ engines: {node: '>= 10.13.0'}
+
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
+ loader-runner@4.3.0:
+ resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
+ engines: {node: '>=6.11.5'}
+
+ locate-path@5.0.0:
+ resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
+ engines: {node: '>=8'}
+
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ neo-async@2.6.2:
+ resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+
+ node-releases@2.0.18:
+ resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ p-limit@2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+
+ p-locate@4.1.0:
+ resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
+ engines: {node: '>=8'}
+
+ p-try@2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
+ path-type@5.0.0:
+ resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
+ engines: {node: '>=12'}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ pkg-dir@4.2.0:
+ resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
+ engines: {node: '>=8'}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ randombytes@2.1.0:
+ resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
+
+ rechoir@0.8.0:
+ resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
+ engines: {node: '>= 10.13.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-cwd@3.0.0:
+ resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
+ engines: {node: '>=8'}
+
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rimraf@6.0.1:
+ resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ schema-utils@3.3.0:
+ resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
+ engines: {node: '>= 10.13.0'}
+
+ schema-utils@4.2.0:
+ resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==}
+ engines: {node: '>= 12.13.0'}
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ serialize-javascript@6.0.2:
+ resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
+
+ shallow-clone@3.0.1:
+ resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==}
+ engines: {node: '>=8'}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
+
+ source-map-support@0.5.21:
+ resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.4:
+ resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+ engines: {node: '>= 8'}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ supports-color@8.1.1:
+ resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
+ engines: {node: '>=10'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tapable@2.2.1:
+ resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
+ engines: {node: '>=6'}
+
+ terser-webpack-plugin@5.3.10:
+ resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
+ engines: {node: '>= 10.13.0'}
+ peerDependencies:
+ '@swc/core': '*'
+ esbuild: '*'
+ uglify-js: '*'
+ webpack: ^5.1.0
+ peerDependenciesMeta:
+ '@swc/core':
+ optional: true
+ esbuild:
+ optional: true
+ uglify-js:
+ optional: true
+
+ terser@5.36.0:
+ resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-loader@9.5.1:
+ resolution: {integrity: sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ typescript: '*'
+ webpack: ^5.0.0
+
+ typescript@5.6.3:
+ resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ unicorn-magic@0.1.0:
+ resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
+ engines: {node: '>=18'}
+
+ update-browserslist-db@1.1.1:
+ resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ watchpack@2.4.2:
+ resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==}
+ engines: {node: '>=10.13.0'}
+
+ webpack-cli@5.1.4:
+ resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==}
+ engines: {node: '>=14.15.0'}
+ hasBin: true
+ peerDependencies:
+ '@webpack-cli/generators': '*'
+ webpack: 5.x.x
+ webpack-bundle-analyzer: '*'
+ webpack-dev-server: '*'
+ peerDependenciesMeta:
+ '@webpack-cli/generators':
+ optional: true
+ webpack-bundle-analyzer:
+ optional: true
+ webpack-dev-server:
+ optional: true
+
+ webpack-merge@5.10.0:
+ resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==}
+ engines: {node: '>=10.0.0'}
+
+ webpack-merge@6.0.1:
+ resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==}
+ engines: {node: '>=18.0.0'}
+
+ webpack-sources@3.2.3:
+ resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+ engines: {node: '>=10.13.0'}
+
+ webpack@5.95.0:
+ resolution: {integrity: sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ peerDependencies:
+ webpack-cli: '*'
+ peerDependenciesMeta:
+ webpack-cli:
+ optional: true
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ wildcard@2.0.1:
+ resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+snapshots:
+
+ '@discoveryjs/json-ext@0.5.7': {}
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jridgewell/gen-mapping@0.3.5':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/source-map@0.3.6':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ '@sindresorhus/merge-streams@2.3.0': {}
+
+ '@types/chrome@0.0.279':
+ dependencies:
+ '@types/filesystem': 0.0.36
+ '@types/har-format': 1.2.16
+
+ '@types/estree@1.0.6': {}
+
+ '@types/filesystem@0.0.36':
+ dependencies:
+ '@types/filewriter': 0.0.33
+
+ '@types/filewriter@0.0.33': {}
+
+ '@types/har-format@1.2.16': {}
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/node@22.7.9':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@webassemblyjs/ast@1.12.1':
+ dependencies:
+ '@webassemblyjs/helper-numbers': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+
+ '@webassemblyjs/floating-point-hex-parser@1.11.6': {}
+
+ '@webassemblyjs/helper-api-error@1.11.6': {}
+
+ '@webassemblyjs/helper-buffer@1.12.1': {}
+
+ '@webassemblyjs/helper-numbers@1.11.6':
+ dependencies:
+ '@webassemblyjs/floating-point-hex-parser': 1.11.6
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/helper-wasm-bytecode@1.11.6': {}
+
+ '@webassemblyjs/helper-wasm-section@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/wasm-gen': 1.12.1
+
+ '@webassemblyjs/ieee754@1.11.6':
+ dependencies:
+ '@xtuc/ieee754': 1.2.0
+
+ '@webassemblyjs/leb128@1.11.6':
+ dependencies:
+ '@xtuc/long': 4.2.2
+
+ '@webassemblyjs/utf8@1.11.6': {}
+
+ '@webassemblyjs/wasm-edit@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/helper-wasm-section': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-opt': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ '@webassemblyjs/wast-printer': 1.12.1
+
+ '@webassemblyjs/wasm-gen@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wasm-opt@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-buffer': 1.12.1
+ '@webassemblyjs/wasm-gen': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+
+ '@webassemblyjs/wasm-parser@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/helper-api-error': 1.11.6
+ '@webassemblyjs/helper-wasm-bytecode': 1.11.6
+ '@webassemblyjs/ieee754': 1.11.6
+ '@webassemblyjs/leb128': 1.11.6
+ '@webassemblyjs/utf8': 1.11.6
+
+ '@webassemblyjs/wast-printer@1.12.1':
+ dependencies:
+ '@webassemblyjs/ast': 1.12.1
+ '@xtuc/long': 4.2.2
+
+ '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.95.0)':
+ dependencies:
+ webpack: 5.95.0(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack@5.95.0)
+
+ '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.95.0)':
+ dependencies:
+ webpack: 5.95.0(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack@5.95.0)
+
+ '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.95.0)':
+ dependencies:
+ webpack: 5.95.0(webpack-cli@5.1.4)
+ webpack-cli: 5.1.4(webpack@5.95.0)
+
+ '@xtuc/ieee754@1.2.0': {}
+
+ '@xtuc/long@4.2.2': {}
+
+ acorn-import-attributes@1.9.5(acorn@8.13.0):
+ dependencies:
+ acorn: 8.13.0
+
+ acorn@8.13.0: {}
+
+ ajv-formats@2.1.1(ajv@8.17.1):
+ optionalDependencies:
+ ajv: 8.17.1
+
+ ajv-keywords@3.5.2(ajv@6.12.6):
+ dependencies:
+ ajv: 6.12.6
+
+ ajv-keywords@5.1.0(ajv@8.17.1):
+ dependencies:
+ ajv: 8.17.1
+ fast-deep-equal: 3.1.3
+
+ ajv@6.12.6:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ajv@8.17.1:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.0.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.1.0: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@6.2.1: {}
+
+ balanced-match@1.0.2: {}
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.24.2:
+ dependencies:
+ caniuse-lite: 1.0.30001669
+ electron-to-chromium: 1.5.43
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.1(browserslist@4.24.2)
+
+ buffer-from@1.1.2: {}
+
+ caniuse-lite@1.0.30001669: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ chrome-trace-event@1.0.4: {}
+
+ clone-deep@4.0.1:
+ dependencies:
+ is-plain-object: 2.0.4
+ kind-of: 6.0.3
+ shallow-clone: 3.0.1
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ colorette@2.0.20: {}
+
+ commander@10.0.1: {}
+
+ commander@2.20.3: {}
+
+ copy-webpack-plugin@12.0.2(webpack@5.95.0):
+ dependencies:
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ globby: 14.0.2
+ normalize-path: 3.0.0
+ schema-utils: 4.2.0
+ serialize-javascript: 6.0.2
+ webpack: 5.95.0(webpack-cli@5.1.4)
+
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ eastasianwidth@0.2.0: {}
+
+ electron-to-chromium@1.5.43: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ enhanced-resolve@5.17.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.2.1
+
+ envinfo@7.14.0: {}
+
+ es-module-lexer@1.5.4: {}
+
+ escalade@3.2.0: {}
+
+ eslint-scope@5.1.1:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@4.3.0: {}
+
+ estraverse@5.3.0: {}
+
+ events@3.3.0: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.2:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-uri@3.0.3: {}
+
+ fastest-levenshtein@1.0.16: {}
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up@4.1.0:
+ dependencies:
+ locate-path: 5.0.0
+ path-exists: 4.0.0
+
+ flat@5.0.2: {}
+
+ foreground-child@3.3.0:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ function-bind@1.1.2: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-to-regexp@0.4.1: {}
+
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
+ globby@14.0.2:
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.2
+ ignore: 5.3.2
+ path-type: 5.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.1.0
+
+ graceful-fs@4.2.11: {}
+
+ has-flag@4.0.0: {}
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ ignore@5.3.2: {}
+
+ import-local@3.2.0:
+ dependencies:
+ pkg-dir: 4.2.0
+ resolve-cwd: 3.0.0
+
+ interpret@3.1.1: {}
+
+ is-core-module@2.15.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ is-plain-object@2.0.4:
+ dependencies:
+ isobject: 3.0.1
+
+ isexe@2.0.0: {}
+
+ isobject@3.0.1: {}
+
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
+ jest-worker@27.5.1:
+ dependencies:
+ '@types/node': 22.7.9
+ merge-stream: 2.0.0
+ supports-color: 8.1.1
+
+ json-parse-even-better-errors@2.3.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ kind-of@6.0.3: {}
+
+ loader-runner@4.3.0: {}
+
+ locate-path@5.0.0:
+ dependencies:
+ p-locate: 4.1.0
+
+ lru-cache@11.0.1: {}
+
+ merge-stream@2.0.0: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minipass@7.1.2: {}
+
+ neo-async@2.6.2: {}
+
+ node-releases@2.0.18: {}
+
+ normalize-path@3.0.0: {}
+
+ p-limit@2.3.0:
+ dependencies:
+ p-try: 2.2.0
+
+ p-locate@4.1.0:
+ dependencies:
+ p-limit: 2.3.0
+
+ p-try@2.2.0: {}
+
+ package-json-from-dist@1.0.1: {}
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ path-parse@1.0.7: {}
+
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
+ path-type@5.0.0: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1: {}
+
+ pkg-dir@4.2.0:
+ dependencies:
+ find-up: 4.1.0
+
+ punycode@2.3.1: {}
+
+ queue-microtask@1.2.3: {}
+
+ randombytes@2.1.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ rechoir@0.8.0:
+ dependencies:
+ resolve: 1.22.8
+
+ require-from-string@2.0.2: {}
+
+ resolve-cwd@3.0.0:
+ dependencies:
+ resolve-from: 5.0.0
+
+ resolve-from@5.0.0: {}
+
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.0.4: {}
+
+ rimraf@6.0.1:
+ dependencies:
+ glob: 11.0.0
+ package-json-from-dist: 1.0.1
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safe-buffer@5.2.1: {}
+
+ schema-utils@3.3.0:
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ajv: 6.12.6
+ ajv-keywords: 3.5.2(ajv@6.12.6)
+
+ schema-utils@4.2.0:
+ dependencies:
+ '@types/json-schema': 7.0.15
+ ajv: 8.17.1
+ ajv-formats: 2.1.1(ajv@8.17.1)
+ ajv-keywords: 5.1.0(ajv@8.17.1)
+
+ semver@7.6.3: {}
+
+ serialize-javascript@6.0.2:
+ dependencies:
+ randombytes: 2.1.0
+
+ shallow-clone@3.0.1:
+ dependencies:
+ kind-of: 6.0.3
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ signal-exit@4.1.0: {}
+
+ slash@5.1.0: {}
+
+ source-map-support@0.5.21:
+ dependencies:
+ buffer-from: 1.1.2
+ source-map: 0.6.1
+
+ source-map@0.6.1: {}
+
+ source-map@0.7.4: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-color@8.1.1:
+ dependencies:
+ has-flag: 4.0.0
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tapable@2.2.1: {}
+
+ terser-webpack-plugin@5.3.10(webpack@5.95.0):
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.25
+ jest-worker: 27.5.1
+ schema-utils: 3.3.0
+ serialize-javascript: 6.0.2
+ terser: 5.36.0
+ webpack: 5.95.0(webpack-cli@5.1.4)
+
+ terser@5.36.0:
+ dependencies:
+ '@jridgewell/source-map': 0.3.6
+ acorn: 8.13.0
+ commander: 2.20.3
+ source-map-support: 0.5.21
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-loader@9.5.1(typescript@5.6.3)(webpack@5.95.0):
+ dependencies:
+ chalk: 4.1.2
+ enhanced-resolve: 5.17.1
+ micromatch: 4.0.8
+ semver: 7.6.3
+ source-map: 0.7.4
+ typescript: 5.6.3
+ webpack: 5.95.0(webpack-cli@5.1.4)
+
+ typescript@5.6.3: {}
+
+ undici-types@6.19.8: {}
+
+ unicorn-magic@0.1.0: {}
+
+ update-browserslist-db@1.1.1(browserslist@4.24.2):
+ dependencies:
+ browserslist: 4.24.2
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ watchpack@2.4.2:
+ dependencies:
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+
+ webpack-cli@5.1.4(webpack@5.95.0):
+ dependencies:
+ '@discoveryjs/json-ext': 0.5.7
+ '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.95.0)
+ '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.95.0)
+ '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.95.0)
+ colorette: 2.0.20
+ commander: 10.0.1
+ cross-spawn: 7.0.3
+ envinfo: 7.14.0
+ fastest-levenshtein: 1.0.16
+ import-local: 3.2.0
+ interpret: 3.1.1
+ rechoir: 0.8.0
+ webpack: 5.95.0(webpack-cli@5.1.4)
+ webpack-merge: 5.10.0
+
+ webpack-merge@5.10.0:
+ dependencies:
+ clone-deep: 4.0.1
+ flat: 5.0.2
+ wildcard: 2.0.1
+
+ webpack-merge@6.0.1:
+ dependencies:
+ clone-deep: 4.0.1
+ flat: 5.0.2
+ wildcard: 2.0.1
+
+ webpack-sources@3.2.3: {}
+
+ webpack@5.95.0(webpack-cli@5.1.4):
+ dependencies:
+ '@types/estree': 1.0.6
+ '@webassemblyjs/ast': 1.12.1
+ '@webassemblyjs/wasm-edit': 1.12.1
+ '@webassemblyjs/wasm-parser': 1.12.1
+ acorn: 8.13.0
+ acorn-import-attributes: 1.9.5(acorn@8.13.0)
+ browserslist: 4.24.2
+ chrome-trace-event: 1.0.4
+ enhanced-resolve: 5.17.1
+ es-module-lexer: 1.5.4
+ eslint-scope: 5.1.1
+ events: 3.3.0
+ glob-to-regexp: 0.4.1
+ graceful-fs: 4.2.11
+ json-parse-even-better-errors: 2.3.1
+ loader-runner: 4.3.0
+ mime-types: 2.1.35
+ neo-async: 2.6.2
+ schema-utils: 3.3.0
+ tapable: 2.2.1
+ terser-webpack-plugin: 5.3.10(webpack@5.95.0)
+ watchpack: 2.4.2
+ webpack-sources: 3.2.3
+ optionalDependencies:
+ webpack-cli: 5.1.4(webpack@5.95.0)
+ transitivePeerDependencies:
+ - '@swc/core'
+ - esbuild
+ - uglify-js
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ wildcard@2.0.1: {}
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
diff --git a/_locales/en/messages.json b/public/_locales/en/messages.json
similarity index 100%
rename from _locales/en/messages.json
rename to public/_locales/en/messages.json
diff --git a/public/icons/icon.128.png b/public/icons/icon.128.png
new file mode 100644
index 0000000..32e4a30
Binary files /dev/null and b/public/icons/icon.128.png differ
diff --git a/public/icons/icon.16.png b/public/icons/icon.16.png
new file mode 100644
index 0000000..e0dc30e
Binary files /dev/null and b/public/icons/icon.16.png differ
diff --git a/public/icons/icon.32.png b/public/icons/icon.32.png
new file mode 100644
index 0000000..bbd40db
Binary files /dev/null and b/public/icons/icon.32.png differ
diff --git a/public/icons/icon.48.png b/public/icons/icon.48.png
new file mode 100644
index 0000000..72e4100
Binary files /dev/null and b/public/icons/icon.48.png differ
diff --git a/public/icons/icon.64.png b/public/icons/icon.64.png
new file mode 100644
index 0000000..08df272
Binary files /dev/null and b/public/icons/icon.64.png differ
diff --git a/icons/source.svg b/public/icons/source.svg
similarity index 100%
rename from icons/source.svg
rename to public/icons/source.svg
diff --git a/manifest.json b/public/manifest.json
similarity index 86%
rename from manifest.json
rename to public/manifest.json
index 2b6d0a9..755121a 100644
--- a/manifest.json
+++ b/public/manifest.json
@@ -1,8 +1,7 @@
{
"manifest_version": 3,
"name": "__MSG_appName__",
- "version": "1.2.4",
-
+ "version": "1.3.0",
"description": "__MSG_appDescription__",
"default_locale": "en",
"icons": {
@@ -12,11 +11,10 @@
"64": "icons/icon.64.png",
"128": "icons/icon.128.png"
},
-
"content_scripts": [
{
"matches": ["*://github.com/*"],
- "js": ["js/main.js"]
+ "js": ["js/content_script.js"]
}
]
}
diff --git a/src/constants.ts b/src/constants.ts
new file mode 100644
index 0000000..18d4f19
--- /dev/null
+++ b/src/constants.ts
@@ -0,0 +1,11 @@
+export const FORKS_URL_REGEX =
+ /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/forks/;
+
+export const LEGACY_FORKS_URL_REGEX =
+ /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/network\/members/;
+
+export const ICON_LOADING =
+ '';
+
+export const ICON_DIFF =
+ '';
diff --git a/src/content_script.ts b/src/content_script.ts
new file mode 100644
index 0000000..606128c
--- /dev/null
+++ b/src/content_script.ts
@@ -0,0 +1,41 @@
+import { FORKS_URL_REGEX, LEGACY_FORKS_URL_REGEX } from "./constants";
+import { ForkProcessor } from "./lib";
+import { ForksPageParser, ForksDiffButton } from "./lib/forks";
+import {
+ LegacyForksPageParser,
+ LegacyForksDiffButton,
+} from "./lib/legacy-forks";
+
+const addButton = () => {
+ // Early exit if wrong page
+ if (
+ !FORKS_URL_REGEX.test(location.href) &&
+ !LEGACY_FORKS_URL_REGEX.test(location.href)
+ ) {
+ return;
+ }
+
+ // Forks page (/forks)
+ if (FORKS_URL_REGEX.test(location.href)) {
+ const forks = ForksPageParser.parse();
+ const processor = new ForkProcessor(forks);
+ const button = new ForksDiffButton(processor);
+ button.insertButton();
+ }
+
+ // Legacy forks page (/network/members)
+ if (LEGACY_FORKS_URL_REGEX.test(location.href)) {
+ const forks = LegacyForksPageParser.parse();
+ const processor = new ForkProcessor(forks);
+ const button = new LegacyForksDiffButton(processor);
+ button.insertButton();
+ }
+};
+
+// On load
+addButton();
+
+// Add Turbo listener
+document.addEventListener("turbo:render", () => {
+ addButton();
+});
diff --git a/src/lib/forks.ts b/src/lib/forks.ts
new file mode 100644
index 0000000..09acdb9
--- /dev/null
+++ b/src/lib/forks.ts
@@ -0,0 +1,80 @@
+import type { Fork, ForkProcessor } from ".";
+
+export class ForksPageParser {
+ static parse() {
+ const forks = document.querySelectorAll(".Layout-main ul > li");
+ if (!forks) {
+ return [];
+ }
+
+ const result: Array = [];
+
+ forks.forEach((fork) => {
+ // Extract fork URL
+ const forkUrl = fork.querySelectorAll("a")[1].href;
+ if (!forkUrl) {
+ return;
+ }
+
+ // Create result container
+ const container = document.createElement("div");
+ container.classList.add("mr-4", "f6");
+ container.style.display = "none"; // Hide by default
+
+ // Append container to fork
+ const infoBoxContainer = fork.querySelector("div")?.querySelector("div");
+ if (!infoBoxContainer || !infoBoxContainer.children[4]) {
+ return;
+ }
+ infoBoxContainer.insertBefore(container, infoBoxContainer.children[4]);
+
+ result.push({
+ url: forkUrl,
+ container: container,
+ });
+ });
+
+ return result;
+ }
+}
+
+export class ForksDiffButton {
+ private button: HTMLButtonElement;
+
+ constructor(processor: ForkProcessor) {
+ this.button = document.createElement("button");
+ this.button.textContent = "Load diff";
+ this.button.classList.add(
+ "Button",
+ "Button--secondary",
+ "Button--small",
+ "text-normal",
+ "mt-2",
+ "ml-lg-2",
+ "mt-lg-0"
+ );
+ this.button.addEventListener("click", () => {
+ if (this.button.getAttribute("disabled")) {
+ return;
+ }
+
+ this.button.setAttribute("disabled", "disabled");
+
+ processor.process();
+ });
+ }
+
+ insertButton() {
+ const searchControlMenu = document.querySelector("search-control-menu");
+ if (!searchControlMenu) {
+ return;
+ }
+
+ const buttons = searchControlMenu.querySelector("div");
+ if (!buttons) {
+ return;
+ }
+
+ buttons.appendChild(this.button);
+ }
+}
diff --git a/src/lib/index.ts b/src/lib/index.ts
new file mode 100644
index 0000000..ddef7b9
--- /dev/null
+++ b/src/lib/index.ts
@@ -0,0 +1,125 @@
+import { ICON_DIFF, ICON_LOADING } from "../constants";
+
+export const MAX_CONCURRENT_REQUESTS = 5; // N threads
+
+export type Fork = {
+ url: string;
+ container: HTMLElement;
+};
+
+export class ForkProcessor {
+ constructor(private forks: Array) {}
+
+ process() {
+ // Function to process a single repo from the queue
+ const processRepo = async (fork: Fork) => {
+ console.log(`Processing: ${fork}`);
+
+ fork.container.removeAttribute("style");
+ fork.container.classList.add("color-fg-muted");
+
+ const spinner = document.createElement("span");
+ spinner.innerHTML = ICON_LOADING;
+ fork.container.appendChild(spinner);
+
+ // Perform network request using fetch or XMLHttpRequest
+ try {
+ const data = await (await fetch(fork.url)).text();
+ const match = data.match(/"defaultBranch":"(.+?)"/);
+ if (!match) {
+ throw new Error("No defaultBranch found");
+ }
+
+ const defaultBranch = match[1];
+ const url = fork.url + "/branch-infobar/" + defaultBranch;
+
+ const branchInfobar = await (
+ await fetch(url, {
+ headers: {
+ Accept: "application/json",
+ },
+ })
+ ).json();
+
+ const ahead = branchInfobar.refComparison.ahead;
+ const behind = branchInfobar.refComparison.behind;
+
+ const diffIcon = document.createElement("span");
+ diffIcon.innerHTML = ICON_DIFF;
+ fork.container.appendChild(diffIcon);
+
+ if (ahead === 0 && behind === 0) {
+ const noDiff = document.createElement("span");
+ noDiff.textContent = " is even ";
+ fork.container.appendChild(noDiff);
+ }
+
+ if (ahead > 0) {
+ const aheadSpan = document.createElement("span");
+ aheadSpan.textContent = ` +${ahead} `;
+ aheadSpan.classList.add("cadd");
+ fork.container.appendChild(aheadSpan);
+ }
+
+ if (ahead > 0 && behind > 0) {
+ const separator = document.createElement("span");
+ separator.textContent = "/";
+ separator.classList.add("color-fg-muted");
+ fork.container.appendChild(separator);
+ }
+
+ if (behind > 0) {
+ const behindSpan = document.createElement("span");
+ behindSpan.textContent = ` -${behind} `;
+ behindSpan.classList.add("cdel");
+ fork.container.appendChild(behindSpan);
+ }
+
+ spinner.remove();
+ } catch (error: unknown) {
+ fork.container.innerHTML = "";
+
+ const errorSpan = document.createElement("span");
+ if (error instanceof Error) {
+ errorSpan.textContent = error.message;
+ } else {
+ errorSpan.textContent = "Unknown error";
+ }
+ fork.container.appendChild(errorSpan);
+ }
+ };
+
+ // Function to run parallel requests with a max concurrency limit
+ const runQueue = async () => {
+ const queueCopy = [...this.forks]; // Copy the queue to avoid mutation
+
+ // Helper function to process items with a concurrency limit
+ const processNext = async () => {
+ if (queueCopy.length === 0) return;
+ // Get the next URL from the queue
+ const nextUrl = queueCopy.shift();
+ if (!nextUrl) {
+ return;
+ }
+
+ // Process the current repo
+ await processRepo(nextUrl);
+
+ // Start processing the next URL once this one finishes
+ await processNext();
+ };
+
+ // Spawn initial threads (N)
+ const threads = [];
+ for (let i = 0; i < MAX_CONCURRENT_REQUESTS; i++) {
+ threads.push(processNext());
+ }
+
+ // Wait for all "threads" to finish
+ await Promise.all(threads);
+ };
+
+ // Start processing the queue
+ runQueue();
+ }
+}
diff --git a/src/lib/legacy-forks.ts b/src/lib/legacy-forks.ts
new file mode 100644
index 0000000..2f41fff
--- /dev/null
+++ b/src/lib/legacy-forks.ts
@@ -0,0 +1,57 @@
+import type { Fork, ForkProcessor } from ".";
+
+export class LegacyForksPageParser {
+ static parse() {
+ const networkTree = document.querySelector("#network > div");
+ if (!networkTree) {
+ return [];
+ }
+
+ const result: Array = [];
+
+ // Iterate through repository forks (skip the first one)
+ for (let i = 1; i < networkTree.children.length; i++) {
+ const fork = networkTree.children[i];
+
+ // Create result container
+ const container = document.createElement("span");
+ container.style.display = "none"; // Hide by default
+ fork.appendChild(container);
+
+ result.push({
+ url: fork.querySelectorAll("a")[2].href,
+ container: container,
+ });
+ }
+
+ return result;
+ }
+}
+
+export class LegacyForksDiffButton {
+ private button: HTMLButtonElement;
+
+ constructor(processor: ForkProcessor) {
+ this.button = document.createElement("button");
+ this.button.textContent = "Load diff";
+ this.button.classList.add("btn", "float-right");
+ this.button.addEventListener("click", () => {
+ if (this.button.classList.contains("disabled")) {
+ return;
+ }
+
+ this.button.classList.add("disabled");
+
+ processor.process();
+ });
+ }
+
+ insertButton() {
+ const network = document.getElementById("network");
+ if (!network) {
+ return;
+ }
+
+ network.insertBefore(this.button, network.childNodes[0]);
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..28ad8ed
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "target": "es6",
+ "moduleResolution": "bundler",
+ "module": "ES6",
+ "esModuleInterop": true,
+ "sourceMap": false,
+ "rootDir": "src",
+ "outDir": "dist/js",
+ "noEmitOnError": true,
+ "jsx": "react",
+ "typeRoots": [ "node_modules/@types" ]
+ }
+}
diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js
new file mode 100644
index 0000000..0df382b
--- /dev/null
+++ b/webpack/webpack.common.js
@@ -0,0 +1,43 @@
+const webpack = require("webpack");
+const path = require("path");
+const CopyPlugin = require("copy-webpack-plugin");
+const srcDir = path.join(__dirname, "..", "src");
+
+module.exports = {
+ entry: {
+ // popup: path.join(srcDir, 'popup.tsx'),
+ // options: path.join(srcDir, 'options.tsx'),
+ // background: path.join(srcDir, 'background.ts'),
+ content_script: path.join(srcDir, "content_script.ts"),
+ },
+ output: {
+ path: path.join(__dirname, "../dist/js"),
+ filename: "[name].js",
+ },
+ optimization: {
+ splitChunks: {
+ name: "vendor",
+ chunks(chunk) {
+ return chunk.name !== "background";
+ },
+ },
+ },
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ use: "ts-loader",
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ resolve: {
+ extensions: [".ts", ".tsx", ".js"],
+ },
+ plugins: [
+ new CopyPlugin({
+ patterns: [{ from: ".", to: "../", context: "public" }],
+ options: {},
+ }),
+ ],
+};
diff --git a/webpack/webpack.dev.js b/webpack/webpack.dev.js
new file mode 100644
index 0000000..117d2d1
--- /dev/null
+++ b/webpack/webpack.dev.js
@@ -0,0 +1,7 @@
+const { merge } = require("webpack-merge");
+const common = require("./webpack.common.js");
+
+module.exports = merge(common, {
+ devtool: "inline-source-map",
+ mode: "development",
+});
diff --git a/webpack/webpack.prod.js b/webpack/webpack.prod.js
new file mode 100644
index 0000000..80ceacd
--- /dev/null
+++ b/webpack/webpack.prod.js
@@ -0,0 +1,6 @@
+const { merge } = require("webpack-merge");
+const common = require("./webpack.common.js");
+
+module.exports = merge(common, {
+ mode: "production",
+});