changed how building works

This commit is contained in:
AloeSapling 2025-08-15 20:54:40 +02:00
parent c57c61041a
commit 61ecabfad3
20 changed files with 864 additions and 580 deletions

View file

@ -0,0 +1 @@
*

142
PRE-OVERHAUL/build/build.js Normal file
View file

@ -0,0 +1,142 @@
/** Builds the userscript using esbuild.
* This will:
* 1. Update the package version across the entire project
* 2. Bundle the JS files into one file (esbuild)
* 3. Bundle the CSS files into one file (esbuild)
* 4. Compress & obfuscate the bundled JS file (terner)
* 5. Runs the CSS selector mangler (cssMandler.js)
* @since 0.0.6
*/
// ES Module imports
import esbuild from 'esbuild';
import fs from 'fs';
import { execSync } from 'child_process';
import { consoleStyle } from './utils.js';
import mangleSelectors from './cssMangler.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
// CommonJS imports (require)
const terser = require('terser');
const isGitHub = !!process.env?.GITHUB_ACTIONS; // Is this running in a GitHub Action Workflow?'
console.log(`${consoleStyle.BLUE}Starting build...${consoleStyle.RESET}`);
// Tries to build the wiki if build.js is run in a GitHub Workflow
// if (isGitHub) {
// try {
// console.log(`Generating JSDoc...`);
// execSync(`npx jsdoc src/ -r -d docs -t node_modules/minami`, { stdio: "inherit" });
// console.log(`JSDoc built ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
// } catch (error) {
// console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to generate JSDoc${consoleStyle.RESET}:`, error);
// process.exit(1);
// }
// }
// Tries to bump the version
try {
const update = execSync('node build/update-version.js', { stdio: 'inherit' });
console.log(`Version updated in meta file ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
} catch (error) {
console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
process.exit(1);
}
// Fetches the userscript metadata banner
const metaContent = fs.readFileSync('src/BlueMarble.meta.js', 'utf8');
// Compiles a string array of all CSS files
const cssFiles = fs.readdirSync('src/')
.filter(file => file.endsWith('.css'))
.map(file => `src/${file}`);
// Compiles the CSS files
esbuild.build({
entryPoints: cssFiles,
bundle: true,
outfile: 'dist/BlueMarble.user.css',
minify: true
});
// Compiles the JS files
const resultEsbuild = await esbuild.build({
entryPoints: ['src/main.ts'], // "Infect" the files from this point (it spreads from this "patient 0")
bundle: true, // Should the code be bundled?
outfile: 'dist/BlueMarble.user.js', // The file the bundled code is exported to
format: 'iife', // What format the bundler bundles the code into
target: 'es2020', // What is the minimum version/year that should be supported? When omited, it attempts to support backwards compatability with legacy browsers
platform: 'browser', // The platform the bundled code will be operating on
legalComments: 'inline', // What level of legal comments are preserved? (Hard: none, Soft: inline)
minify: false, // Should the code be minified?
write: false, // Should we write the outfile to the disk?
}).catch(() => process.exit(1));
// Retrieves the JS file
const resultEsbuildJS = resultEsbuild.outputFiles.find(file => file.path.endsWith('.js'));
// Obfuscates the JS file
let resultTerser = await terser.minify(resultEsbuildJS.text, {
mangle: {
//toplevel: true, // Obfuscate top-level class/function names
keep_classnames: false, // Should class names be preserved?
keep_fnames: false, // Should function names be preserved?
reserved: [], // List of keywords to preserve
properties: {
// regex: /.*/, // Yes, I am aware I should be using a RegEx. Yes, like you, I am also suprised the userscript still functions
keep_quoted: true, // Should names in quotes be preserved?
reserved: [] // What properties should be preserved?
},
},
format: {
comments: 'some' // Save legal comments
},
compress: {
dead_code: isGitHub, // Should unreachable code be removed?
drop_console: isGitHub, // Should console code be removed?
drop_debugger: isGitHub, // SHould debugger code be removed?
passes: 2 // How many times terser will compress the code
}
});
// Writes the obfuscated/mangled JS code to a file
fs.writeFileSync('dist/BlueMarble.user.js', resultTerser.code, 'utf8');
let importedMapCSS = {}; // The imported CSS map
// Only import a CSS map if we are NOT in production (GitHub Workflow)
// Theoretically, if the previous map is always imported, the names would not scramble. However, the names would never decrease in number...
if (!isGitHub) {
try {
importedMapCSS = JSON.parse(fs.readFileSync('dist/BlueMarble.user.css.map.json', 'utf8'));
} catch {
console.log(`${consoleStyle.YELLOW}Warning! Could not find a CSS map to import. A 100% new CSS map will be generated...${consoleStyle.RESET}`);
}
}
// Mangles the CSS selectors
// If we are in production (GitHub Workflow), then generate the CSS mapping
// const mapCSS = mangleSelectors({
// inputPrefix: 'bm-',
// outputPrefix: 'bm-',
// pathJS: 'dist/BlueMarble.user.js',
// pathCSS: 'dist/BlueMarble.user.css',
// importMap: importedMapCSS,
// returnMap: isGitHub
// });
// If a map was returned, write it to the file
// if (mapCSS) {
// fs.writeFileSync('dist/BlueMarble.user.css.map.json', JSON.stringify(mapCSS, null, 2));
// }
// Adds the banner
fs.writeFileSync(
'dist/BlueMarble.user.js',
metaContent + fs.readFileSync('dist/BlueMarble.user.js', 'utf8'),
'utf8'
);
console.log(`${consoleStyle.GREEN + consoleStyle.BOLD + consoleStyle.UNDERLINE}Building complete!${consoleStyle.RESET}`);

View file

@ -0,0 +1,3 @@
paths-ignore:
- dist/
- wiki/

View file

@ -0,0 +1,203 @@
/** Mangles all matching CSS selectors provided:
* - The CSS selector starts with the correct prefix
* - The prefix case matches (case-sensitive)
* - There is 1 (bundled) CSS file
* - There is 1 (bundled) JS file
* The default mangling is base64, as small as possible
* @since 0.56.1
* @example
* // (Assume 'bm-' is the input prefix, and 'b-' is the output prefix)
* // Input:
* // JS
* const element = docuement.createElement('p');
* element.id = 'bm-paragraph-id';
* element.className = 'bm-paragraph-class';
* // CSS
* #bm-paragraph-id {color:red;}
* .bm-paragraph-class {background-color:blue;}
*
* // Output:
* // JS
* const element = docuement.createElement('p');
* element.id = 'b-1'; // The longer the selector, the smaller it gets...
* element.className = 'b-0'; // ...therefore, the class selector is "0"
* // CSS
* #b-1 {color:red;}
* .b-0 {background-color:blue;}
* // Optional returned map Object:
* console.log(JSON.stringify(mangleSelectors('bm-', 'b-', 'bundled.js', 'bundled.css', true), null, 2));
* {
* "bm-paragraph-class": "b-0",
* "bm-paragraph-id": "b-1",
* }
*/
import fs from 'fs';
/** Mangles the CSS selectors in a JS and CSS file.
* Both the JS and CSS file are needed to ensure the names are synced.
* A prefix is needed on all selectors to ensure the proper matching.
* The input prefix is case-sensitive, and can match inside words.
* Assume the input prefix matching is as greedy as possible. Make sure your input prefix is unique!
*
* For example:
* - `bm` is a bad prefix because it will match `Submit Form` (Not unique enough)
* - `b-` is a bad prefix because it will match `This is my b-day!` (Not long enough)
* - `bm-` is a good prefix because no words end with or contain `bm-`
*
* The default mangling is all valid single byte characters for CSS selectors (which is, ironically, 64 characters).
* You can optionally return the key-value mapping of all selector names.
* You can optionally pass in a map to be used. If you do, any selectors not in the map will be added.
* @param {Object} params - The parameters object.
* @param {string} params.inputPrefix - The prefix to search for.
* @param {string} params.outputPrefix - The prefix to replace with.
* @param {string} params.pathJS - The path to the JS file.
* @param {string} params.pathCSS - The path to the CSS file.
* @param {Object<string, string>} [params.importMap={}] - Imported map to use.
* @param {boolean} [params.returnMap=false] - Should this function return the key-value map Object?
* @param {string} [params.encoding=''] - The characters you want the mangled selectors to consist of.
* @returns {Object<string, string>|undefined} A mapping of the mangled CSS selectors as an Object, or `undefined` if `returnMap` is not `true`.
* @since 0.56.1
* @example
* // (Assume 'bm-' is the input prefix, and 'b-' is the output prefix)
* // Input:
* // JS
* const element = docuement.createElement('p');
* element.id = 'bm-paragraph-id';
* element.className = 'bm-paragraph-class';
* // CSS
* #bm-paragraph-id {color:red;}
* .bm-paragraph-class {background-color:blue;}
*
* // Output:
* // JS
* const element = docuement.createElement('p');
* element.id = 'b-1'; // The longer the selector, the smaller it gets...
* element.className = 'b-0'; // ...therefore, the class selector is "0"
* // CSS
* #b-1 {color:red;}
* .b-0 {background-color:blue;}
* // Optional returned map Object:
* console.log(
* JSON.stringify(
* mangleSelectors({
* inputPrefix: 'bm-',
* outputPrefix: 'b-',
* pathJS: 'bundled.js',
* pathCSS: 'bundled.css',
* returnMap: true
* }),
* null, 2
* )
* );
* // Return Map:
* {
* "bm-paragraph-class": "b-0",
* "bm-paragraph-id": "b-1",
* }
*/
export default function mangleSelectors({
inputPrefix = '',
outputPrefix = '',
pathJS = '',
pathCSS = '',
importMap = {},
returnMap = false,
encoding = ''
} = {}) {
if (!inputPrefix || !outputPrefix || !pathJS || !pathCSS) {
throw new Error(`mangleSelectors() was called without the required variables: ${!inputPrefix ? 'inputPrefix ' : ''}${!outputPrefix ? 'outputPrefix ' : ''}${!pathJS ? 'pathJS ' : ''}${!pathCSS ? 'pathCSS' : ''}`);
}
encoding = encoding || '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'; // Default encoding
const fileInputJS = fs.readFileSync(pathJS, 'utf8'); // The JS file
const fileInputCSS = fs.readFileSync(pathCSS, 'utf8'); // The CSS file
/** How many keys-value pairs there are in the in the imported map, along with an "index shift" if a map was imported.
* @example
* // Assume the imported map has 10 keys.
* // The first key of the new map has an index of 0.
* // If we add 10 + 0, we get an index collision.
* // Therefore, we add 10 + 2 + 0.
* // However, if no map is imported, the map will start it's index at 2. We don't want that.
* // Therefore, if we abuse the fact that `true` is `1`, and `false` is `0`, we can add `2 * !!importMap.length` which will only shift the index by 2 if a map was imported.
* @example
* const importMap = {};
* console.log(importMapLength); // 0
* @example
* const importMap = {'foo': 'bar'};
* console.log(importMapLength); // 3
* @example
* const importMap = {'foo': 'bar', 'bar': 'foo'};
* console.log(importMapLength); // 4
*/
const importMapLength = Object.keys(importMap).length + (2 * !!Object.keys(importMap).length);
// One of each of all matching selectors
// File -> RegEx -> Array (Duplicates) -> Set (Unique) -> Array (Unique)
let matchedSelectors = [...new Set([...fileInputJS.matchAll(new RegExp(`\\b${escapeRegex(inputPrefix)}[a-zA-Z0-9_-]+`, 'g'))].map(match => match[0]))];
// Sort keys in selector from longest to shortest
// This will avoid partial matches, which could cause bugs
// E.g. `foo-foobar` will match before `foo-foo` matches
matchedSelectors.sort((a, b) => b.length - a.length);
// Converts the string[] to an Object (key-value)
matchedSelectors = {
...importMap,
...Object.fromEntries(
matchedSelectors
.filter(key => !(key in importMap))
.map(key => [key, outputPrefix + numberToEncoded(importMapLength + matchedSelectors.indexOf(key), encoding)]
)
)
};
// Compile the RegEx from the selector map
const regex = new RegExp(Object.keys(matchedSelectors).map(selector => escapeRegex(selector)).join('|'), 'g');
// Replaces the CSS selectors in both files with encoded versions
fs.writeFileSync(pathJS, fileInputJS.replace(regex, match => matchedSelectors[match]), 'utf8');
fs.writeFileSync(pathCSS, fileInputCSS.replace(regex, match => matchedSelectors[match]), 'utf8');
if (!!returnMap) {return matchedSelectors;} // Return the map Object optionally
}
/** Escapes characters in a string that are about to be inserted into a Regular Expression
* @param {string} string - The string to pass in
* @returns {string} String that has been escaped for RegEx
* @since 0.56.2
*/
function escapeRegex(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
/** Encodes a number into a custom encoded string.
* @param {number} number - The number to encode
* @param {string} encoding - The characters to use when encoding
* @since 0.56.12
* @returns {string} Encoded string
* @example
* const encode = '012abcABC'; // Base 9
* console.log(numberToEncoded(0, encode)); // 0
* console.log(numberToEncoded(5, encode)); // c
* console.log(numberToEncoded(15, encode)); // 1A
* console.log(numberToEncoded(12345, encode)); // 1BCaA
*/
function numberToEncoded(number, encoding) {
if (number === 0) return encoding[0]; // End quickly if number equals 0. No special calculation needed
let result = ''; // The encoded string
const base = encoding.length; // The number of characters used, which determines the base
// Base conversion algorithm
while (number > 0) {
result = encoding[number % base] + result; // Find's the character's encoded value determined by the modulo of the base
number = Math.floor(number / base); // Divides the number by the base so the next iteration can find the next modulo character
}
return result; // The final encoded string
}

View file

@ -0,0 +1,28 @@
/** For development compiling of patches
* @since 0.12.0
*/
import fs from 'fs';
import { execSync } from 'child_process';
import { consoleStyle } from './utils.js';
console.log(`${consoleStyle.BLUE}Starting patch...${consoleStyle.RESET}`);
try {
const update = execSync('npm version patch --no-git-tag-version', { stdio: 'inherit' });
console.log(`Version patch updated ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
} catch (error) {
console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
process.exit(1);
}
const readmePath = 'docs/README.md';
let readmeContent = fs.readFileSync(readmePath, 'utf-8');
readmeContent = readmeContent.replace(/(Total_Patches-)(\d+)(-black)/, (match, prefix, number, suffix) => {
const incremented = Number(number) + 1;
return `${prefix}${incremented}${suffix}`;
});
fs.writeFileSync(readmePath, readmeContent, 'utf-8');

View file

@ -0,0 +1,18 @@
/** Updates the version number in the metadata.
* This updates the version number in the metadata to the version specified in package.json.
* @since 0.0.6
*/
import fs from 'fs';
import { consoleStyle } from './utils.js';
console.log(`${consoleStyle.BLUE}Starting update-version...${consoleStyle.RESET}`);
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
const version = pkg.version;
let meta = fs.readFileSync('src/BlueMarble.meta.js', 'utf-8');
meta = meta.replace(/@version\s+[\d.]+/, `@version ${version}`);
fs.writeFileSync('src/BlueMarble.meta.js', meta);
console.log(`${consoleStyle.GREEN}Updated${consoleStyle.RESET} userscript version to ${consoleStyle.MAGENTA}${version}${consoleStyle.RESET}`);

View file

@ -0,0 +1,32 @@
/** Styling for the console log.
* This only affects the console in the dev's IDE and GitHub Workflow.
* @since 0.58.24
*/
export const consoleStyle = {
/** Resets all styling */
RESET: '\x1b[0m',
/** Makes the text **bold** */
BOLD: '\x1b[1m',
/** Makes the text underlined */
UNDERLINE: '\x1b[4m',
/** Inverses the color of the text and the background */
INVERSE: '\x1b[7m',
/** Turns the text white */
WHITE: '\x1b[37m',
/** Turns the text black */
BLACK: '\x1b[30m',
/** Turns the text red */
RED: '\x1b[31m',
/** Turns the text green */
GREEN: '\x1b[32m',
/** Turns the text yellow */
YELLOW: '\x1b[33m',
/** Turns the text blue */
BLUE: '\x1b[34m',
/** Turns the text magenta */
MAGENTA: '\x1b[35m',
/** Turns the text cyan */
CYAN: '\x1b[36m'
}

View file

@ -6,22 +6,20 @@
* 4. Compress & obfuscate the bundled JS file (terner)
* 5. Runs the CSS selector mangler (cssMandler.js)
* @since 0.0.6
*/
*/
// ES Module imports
import esbuild from 'esbuild';
import fs from 'fs';
import { execSync } from 'child_process';
import { consoleStyle } from './utils.js';
import mangleSelectors from './cssMangler.js';
import { createRequire } from 'module';
import esbuild from "esbuild";
import fs from "fs";
import { execSync } from "child_process";
import { consoleStyle } from "./utils.js";
import { createRequire } from "module";
import { minify } from "html-minifier-terser";
const require = createRequire(import.meta.url);
// CommonJS imports (require)
const terser = require('terser');
const terser = require("terser");
const isGitHub = !!process.env?.GITHUB_ACTIONS; // Is this running in a GitHub Action Workflow?'
console.log(`${consoleStyle.BLUE}Starting build...${consoleStyle.RESET}`);
// Tries to build the wiki if build.js is run in a GitHub Workflow
@ -37,18 +35,14 @@ console.log(`${consoleStyle.BLUE}Starting build...${consoleStyle.RESET}`);
// }
// Tries to bump the version
try {
const update = execSync('node build/update-version.js', { stdio: 'inherit' });
console.log(`Version updated in meta file ${consoleStyle.GREEN}successfully${consoleStyle.RESET}`);
} catch (error) {
console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
process.exit(1);
}
// try {
// execSync('node build/update-version.js', { stdio: 'inherit' });
// } catch (error) {
// console.error(`${consoleStyle.RED + consoleStyle.BOLD}Failed to update version number${consoleStyle.RESET}:`, error);
// process.exit(1);
// }
// Fetches the userscript metadata banner
const metaContent = fs.readFileSync('src/BlueMarble.meta.js', 'utf8');
// Compiles a string array of all CSS files
// Gets a string array of all CSS files
const cssFiles = fs.readdirSync('src/')
.filter(file => file.endsWith('.css'))
.map(file => `src/${file}`);
@ -61,6 +55,39 @@ esbuild.build({
minify: true
});
const miniCSS = fs.readFileSync('dist/BlueMarble.user.css', 'utf-8')
// A piece of code injected into the outputted JS file that injects the CSS into the page
const cssAttachCode = `
const miniCSSStyleElem = document.createElement("style");
miniCSSStyleElem.textContent=\`${miniCSS}\`;
document.body.appendChild(miniCSSStyleElem);
`
const attachCodes = [cssAttachCode]
// Gets a string array of all HTML files in src
fs.readdirSync('src/')
.filter(file => file.endsWith('.html'))
.map(file => `src/${file}`)
.forEach(filePath => {
const html = fs.readFileSync(filePath, 'utf-8')
if(!html.startsWith('<!--')){
console.log(`${consoleStyle.RED}HTML file '${filePath}' doesn't start with a comment about its inject location${consoleStyle.RESET}`)
}else{
// Extract only the css query of where to attach this html
const cssQuery = html.slice(4, html.indexOf('-->')).trim()
// Pushes a piece of code that injects the html into the page
attachCodes.push(`document.querySelector("${cssQuery}").innerHTML += \`${html}\`;`);
}
})
// Gets the current
let code = fs.readFileSync('src/main.ts', 'utf-8')
const originalCode = code;
// Inject the codes that inject CSS / HTML into the page
code = attachCodes.join('\n') + code;
// Write the altered file data back into a file
fs.writeFileSync('src/main.ts', code, { flag: 'w+' })
// Compiles the JS files
const resultEsbuild = await esbuild.build({
entryPoints: ['src/main.ts'], // "Infect" the files from this point (it spreads from this "patient 0")
@ -134,9 +161,9 @@ if (!isGitHub) {
// Adds the banner
fs.writeFileSync(
'dist/BlueMarble.user.js',
metaContent + fs.readFileSync('dist/BlueMarble.user.js', 'utf8'),
'dist/index.js',
"(function (){ return ({ patches: [], load: () => {" + resultTerser.code + "},});})();",
'utf8'
);
fs.writeFileSync('src/main.ts', originalCode)
console.log(`${consoleStyle.GREEN + consoleStyle.BOLD + consoleStyle.UNDERLINE}Building complete!${consoleStyle.RESET}`);

93
build/codes.js Normal file
View file

@ -0,0 +1,93 @@
const miniCSSStyleElem = document.createElement("style");
miniCSSStyleElem.textContent=`#bm-overlay{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000;transition:all .3s ease,transform 0s;max-width:300px;width:auto;will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}#bm-contain-userinfo,#bm-overlay hr,#bm-contain-automation,#bm-contain-buttons-action{transition:opacity .2s ease,height .2s ease}div#bm-overlay{font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}#bm-bar-drag{margin-bottom:.5em;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;cursor:grab;width:100%;height:1em}#bm-bar-drag.dragging{cursor:grabbing}#bm-overlay:has(#bm-bar-drag.dragging){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}#bm-bar-drag.dragging{pointer-events:auto}#bm-contain-header{margin-bottom:.5em}#bm-contain-header[style*="text-align: center"]{display:flex;flex-direction:column;align-items:center;justify-content:center}#bm-overlay[style*="padding: 5px"]{width:auto!important;max-width:300px;min-width:200px}#bm-overlay img{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle;transition:opacity .2s ease}#bm-contain-header[style*="text-align: center"] img{display:block;margin:0 auto}#bm-bar-drag{transition:margin-bottom .2s ease}#bm-overlay h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}#bm-contain-automation input[type=checkbox]{vertical-align:middle;margin-right:.5ch}#bm-contain-automation label{margin-right:.5ch}.bm-help{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}#bm-button-coords{vertical-align:middle}#bm-button-coords svg{width:50%;margin:0 auto;fill:#111}div:has(>#bm-button-teleport){display:flex;gap:.5ch}#bm-button-favorite svg,#bm-button-template svg{height:1em;margin:2px auto 0;text-align:center;line-height:1em;vertical-align:bottom}#bm-contain-coords input[type=number]{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}#bm-contain-coords input[type=number]::-webkit-outer-spin-button,#bm-contain-coords input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}#bm-contain-buttons-template{display:flex;flex-direction:row;flex-wrap:wrap;align-content:center;justify-content:center;align-items:center;gap:1ch}div:has(>#bm-input-file-template)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#bm-input-file-template,input[type=file][id*=template]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}#bm-output-status{font-size:small;background-color:#0003;padding:0 .5ch;height:3.75em;width:100%}#bm-contain-buttons-action{display:flex;justify-content:space-between}#bm-overlay small{font-size:x-small;color:#d3d3d3}#bm-contain-userinfo,#bm-contain-automation,#bm-contain-coords,#bm-contain-buttons-template,div:has(>#bm-input-file-template),#bm-output-status{margin-top:.5em}#bm-overlay button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}#bm-overlay button:hover,#bm-overlay button:focus-visible{background-color:#1061e5}#bm-overlay button:active,#bm-overlay button:disabled{background-color:#2e97ff}#bm-overlay button:disabled{text-decoration:line-through}
`;
document.body.appendChild(miniCSSStyleElem);
document.querySelector("body").innerHTML += `<!-- body -->
<div id="bm-overlay" style="top: 10px; right: 75px">
<header id="bm-contain-header">
<div id="bm-bar-drag">
<img
src="https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png"
alt="Blue Marble Icon - Click to minimize/maximize"
style="cursor: pointer"
onclick="VAR_clickfunc"
/>
<h1>VAR_name</h1>
</div>
<hr />
<div id="bm-contain-userinfo">
<p id="bm-user-name">Name:</p>
<p id="bm-user-droplets">Droplets:</p>
<p id="bm-user-nextlevel">Next level in...</p>
</div>
<hr />
<section id="bm-contain-automation">
<div id="bm-contain-coords">
<button id="bm-button-coords" class="bm-help" style="margin-top: 0">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6">
<circle cx="2" cy="2" r="2"></circle>
<path d="M2 6 L3.7 3 L0.3 3 Z"></path>
<circle cx="2" cy="2" r="0.7" fill="white"></circle>
</svg>
</button>
<input
type="number"
id="bm-input-tx"
placeholder="Tl X"
min="0"
max="2047"
step="1"
required="true"
/>
<input
type="number"
id="bm-input-ty"
placeholder="Tl Y"
min="0"
max="2047"
step="1"
required="true"
/>
<input
type="number"
id="bm-input-px"
placeholder="Px X"
min="0"
max="2047"
step="1"
required="true"
/>
<input
type="number"
id="bm-input-py"
placeholder="Px Y"
min="0"
max="2047"
step="1"
required="true"
/>
</div>
<label>
Upload Template
<input
id="bm-input-file-template"
type="file"
accept="image/png, image/jpeg, image/webp, image/bmp, image/gif"
/>
</label>
<div id="bm-contain-buttons-template">
<button id="bm-button-enable">Enable</button>
<button id="bm-button-create">Create</button>
<button id="bm-button-disable">Disable</button>
</div>
<textarea id="overlayMain.outputStatusId" placeholder="Status: Sleeping...\nVersion: {version}" readonly></textarea>
<div id="bm-contain-buttons-action">
<button id="bm-button-convert" class="bm-help" title="Template Color Converter">🎨</button>
<p style="margin-top: auto">Made by SwingTheVine</p>
</section>
</div>
</header>
</div>
`;

View file

@ -8,11 +8,16 @@ import { consoleStyle } from './utils.js';
console.log(`${consoleStyle.BLUE}Starting update-version...${consoleStyle.RESET}`);
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
const version = pkg.version;
// Get the current version number
const manifest = JSON.parse(fs.readFileSync('dist/manifest.json', 'utf-8'))
const currVersion = manifest.version
let meta = fs.readFileSync('src/BlueMarble.meta.js', 'utf-8');
meta = meta.replace(/@version\s+[\d.]+/, `@version ${version}`);
console.log(`${consoleStyle.GREEN}Read version from manifest.json.${consoleStyle.RESET} Version: ${consoleStyle.MAGENTA}${currVersion}${consoleStyle.RESET}`)
fs.writeFileSync('src/BlueMarble.meta.js', meta);
console.log(`${consoleStyle.GREEN}Updated${consoleStyle.RESET} userscript version to ${consoleStyle.MAGENTA}${version}${consoleStyle.RESET}`);
// Update the version number
const versionNums = manifest.version.split('.'); // Split the version numbers into individual strings
versionNums[versionNums.length-1] = Number(versionNums[versionNums.length-1])+1; // Add one to the last version number position
manifest.version = versionNums.join('.'); // Combine the version numbers back int a whoel string
fs.writeFileSync('dist/manifest.json', JSON.stringify(manifest));
console.log(`${consoleStyle.GREEN}Updated userscript version.${consoleStyle.RESET} Version: ${consoleStyle.MAGENTA}${manifest.version}${consoleStyle.RESET}`);

File diff suppressed because one or more lines are too long

13
dist/index.js vendored Normal file

File diff suppressed because one or more lines are too long

371
package-lock.json generated
View file

@ -12,9 +12,10 @@
},
"devDependencies": {
"@eslint/js": "^9.33.0",
"esbuild": "^0.25.0",
"esbuild": "^0.25.9",
"eslint": "^9.33.0",
"globals": "^16.3.0",
"html-minifier-terser": "^7.2.0",
"jsdoc": "^4.0.4",
"minami": "^1.2.3",
"prettier": "^3.6.2",
@ -146,13 +147,14 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz",
"integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
"integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
@ -162,13 +164,14 @@
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz",
"integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
"integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -178,13 +181,14 @@
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz",
"integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
"integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -194,13 +198,14 @@
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz",
"integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
"integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
@ -210,13 +215,14 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz",
"integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
"integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -226,13 +232,14 @@
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz",
"integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
"integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -242,13 +249,14 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz",
"integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
"integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
@ -258,13 +266,14 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz",
"integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
"integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
@ -274,13 +283,14 @@
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz",
"integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
"integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -290,13 +300,14 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz",
"integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
"integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -306,13 +317,14 @@
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz",
"integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
"integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -322,13 +334,14 @@
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz",
"integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
"integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -338,13 +351,14 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz",
"integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
"integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -354,13 +368,14 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz",
"integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
"integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -370,13 +385,14 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz",
"integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
"integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -386,13 +402,14 @@
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz",
"integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
"integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -402,13 +419,14 @@
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz",
"integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
"integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -418,13 +436,14 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz",
"integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
"integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
@ -434,13 +453,14 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz",
"integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
"integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
@ -450,13 +470,14 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz",
"integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
"integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
@ -466,13 +487,14 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz",
"integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
"integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
@ -482,13 +504,14 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz",
"integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
"integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
@ -498,13 +521,14 @@
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz",
"integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
"integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
@ -514,13 +538,14 @@
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz",
"integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
"integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -530,13 +555,14 @@
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz",
"integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
"integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -546,13 +572,14 @@
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz",
"integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
"integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -1290,6 +1317,17 @@
"node": ">=6"
}
},
"node_modules/camel-case": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"pascal-case": "^3.1.2",
"tslib": "^2.0.3"
}
},
"node_modules/catharsis": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
@ -1319,6 +1357,19 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/clean-css": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
"integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
"dev": true,
"license": "MIT",
"dependencies": {
"source-map": "~0.6.0"
},
"engines": {
"node": ">= 10.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@ -1392,6 +1443,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/dot-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@ -1405,11 +1467,12 @@
}
},
"node_modules/esbuild": {
"version": "0.25.8",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz",
"integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==",
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
"integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@ -1417,32 +1480,32 @@
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.8",
"@esbuild/android-arm": "0.25.8",
"@esbuild/android-arm64": "0.25.8",
"@esbuild/android-x64": "0.25.8",
"@esbuild/darwin-arm64": "0.25.8",
"@esbuild/darwin-x64": "0.25.8",
"@esbuild/freebsd-arm64": "0.25.8",
"@esbuild/freebsd-x64": "0.25.8",
"@esbuild/linux-arm": "0.25.8",
"@esbuild/linux-arm64": "0.25.8",
"@esbuild/linux-ia32": "0.25.8",
"@esbuild/linux-loong64": "0.25.8",
"@esbuild/linux-mips64el": "0.25.8",
"@esbuild/linux-ppc64": "0.25.8",
"@esbuild/linux-riscv64": "0.25.8",
"@esbuild/linux-s390x": "0.25.8",
"@esbuild/linux-x64": "0.25.8",
"@esbuild/netbsd-arm64": "0.25.8",
"@esbuild/netbsd-x64": "0.25.8",
"@esbuild/openbsd-arm64": "0.25.8",
"@esbuild/openbsd-x64": "0.25.8",
"@esbuild/openharmony-arm64": "0.25.8",
"@esbuild/sunos-x64": "0.25.8",
"@esbuild/win32-arm64": "0.25.8",
"@esbuild/win32-ia32": "0.25.8",
"@esbuild/win32-x64": "0.25.8"
"@esbuild/aix-ppc64": "0.25.9",
"@esbuild/android-arm": "0.25.9",
"@esbuild/android-arm64": "0.25.9",
"@esbuild/android-x64": "0.25.9",
"@esbuild/darwin-arm64": "0.25.9",
"@esbuild/darwin-x64": "0.25.9",
"@esbuild/freebsd-arm64": "0.25.9",
"@esbuild/freebsd-x64": "0.25.9",
"@esbuild/linux-arm": "0.25.9",
"@esbuild/linux-arm64": "0.25.9",
"@esbuild/linux-ia32": "0.25.9",
"@esbuild/linux-loong64": "0.25.9",
"@esbuild/linux-mips64el": "0.25.9",
"@esbuild/linux-ppc64": "0.25.9",
"@esbuild/linux-riscv64": "0.25.9",
"@esbuild/linux-s390x": "0.25.9",
"@esbuild/linux-x64": "0.25.9",
"@esbuild/netbsd-arm64": "0.25.9",
"@esbuild/netbsd-x64": "0.25.9",
"@esbuild/openbsd-arm64": "0.25.9",
"@esbuild/openbsd-x64": "0.25.9",
"@esbuild/openharmony-arm64": "0.25.9",
"@esbuild/sunos-x64": "0.25.9",
"@esbuild/win32-arm64": "0.25.9",
"@esbuild/win32-ia32": "0.25.9",
"@esbuild/win32-x64": "0.25.9"
}
},
"node_modules/escape-string-regexp": {
@ -1796,6 +1859,38 @@
"node": ">=8"
}
},
"node_modules/html-minifier-terser": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz",
"integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"camel-case": "^4.1.2",
"clean-css": "~5.3.2",
"commander": "^10.0.0",
"entities": "^4.4.0",
"param-case": "^3.0.4",
"relateurl": "^0.2.7",
"terser": "^5.15.1"
},
"bin": {
"html-minifier-terser": "cli.js"
},
"engines": {
"node": "^14.13.1 || >=16.0.0"
}
},
"node_modules/html-minifier-terser/node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
}
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@ -2036,6 +2131,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
@ -2150,6 +2255,17 @@
"dev": true,
"license": "MIT"
},
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"dev": true,
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@ -2200,6 +2316,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/param-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
"dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -2213,6 +2340,17 @@
"node": ">=6"
}
},
"node_modules/pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -2337,6 +2475,16 @@
],
"license": "MIT"
},
"node_modules/relateurl": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
"integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/requizzle": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz",
@ -2515,6 +2663,13 @@
"typescript": ">=4.8.4"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",

View file

@ -8,9 +8,10 @@
},
"devDependencies": {
"@eslint/js": "^9.33.0",
"esbuild": "^0.25.0",
"esbuild": "^0.25.9",
"eslint": "^9.33.0",
"globals": "^16.3.0",
"html-minifier-terser": "^7.2.0",
"jsdoc": "^4.0.4",
"minami": "^1.2.3",
"prettier": "^3.6.2",

View file

@ -1,184 +0,0 @@
/** This is a summary of the file's purpose as a top-of-file JSDoc comment.
* This is an optional, detailed explanation.
* The first line of the comment should be 1 sentence.
* If more sentences are needed, they are put after the first line.
* @since 1.2.3
* @author SwingTheVine
*/
/*! Import lines go here, usually in 1 logic block */
import fs from 'fs';
import { foo, bar } from './foobar.js';
import { foo } from './foobar.js'; /*! There is ALWAYS a whitespace around the braces for imports. */
/*! Import lines can optionally be grouped into logic blocks, based on type.
* For example, all default imports could be grouped together, or all "require" imports could be in a different logic block from the "import"s.
* If multiple logic blocks are used. There must ALWAYS be a comment before the logic block that explains the common logic of why all of the imports are in this specific logic block.
* If there are multiple import logic blocks, there must ALWAYS be 1 blank line between them.
*/
// CommonJS "imports" which require "require" in order to be imported
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const terser = require('terser');
const foo = require('foo');
/*! There should ALWAYS be 1 blank line between the last import logic block, and the class definition logic block. */
/** A 1 sentence description of what the class does.
* An optional multi-line detailed description of what the class does.
* @class Foo
* @since 1.2.3
* @example
* // An example of how to use the Foo class
*/
export default class Foo {
/* An optional multi-line comment to further explain things about the Foo class.
* This is rarely used, but comes in handy when you want to explain how the inside of the class works, but you don't want to flood the class JSDoc comment with details, since the JSDoc should only contain information about how to *use* the class and what the class *does*, not how the class *works*.
* This multi-line comment should ALWAYS be right under the class definition.
*/
/*! There should ALWAYS be 1 blank line after the logic block that defines the class. */
/** This line should declare if this is the main constructor, or an overload.
* An optional description of why this constructor should be used.
* @param {*} foo - What foo is.
* @param {*} bar - What bar is.
* @since 1.2.3
* @see {@link Foo}
*/
constructor(foo, bar) { /*! Opening braces are ALWAYS on the same line as declaration */
/*! There should NEVER be a whitespace before the first variable, and after the last variable. */
/*! The blank line after the declaration is optional for constructors */
this.foo = foo; // The description of foo should go here only if there is no JSDoc...
this.bar = bar + 5; // ...but if the passed in variable is modified, a comment should be added to explain why.
this.hatMan = 'a'; /*! Constants are ALWAYS camelCase */
this.color = foo.RED_APPLE; /*! Enum variables are ALWAYS SCREAMING_SNAKE_CASE */
/*! There is NEVER a blank line after the end of the last logic block in a statement */
}
/*! Closing braces are ALWAYS on their own line if the statement contains more than 1 line of code.
* The closing brace is aligned with start of the statement.
* However, if there are multiple closing braces, they can optionally be stacked onto the same line.
*/
/** A 1 sentence description of what the function does.
* An optional multi-line detailed description of what the function does.
* @param {*} foo - What foo is.
* @param {*} [bar=''] - What bar is.
*/
function bar(foo, bar='') { /*! There should NEVER be a whitespace between the function name and the passed in variables.
* There should NEVER be a whitespace before the first variable passed in when the variables are all on the same line as the function declaration.
* There should NEVER be a whitespace after the last variable passed in when the variables are all on the same line as the function declaration.
*/
/* An optional multi-line comment to further explain things about the bar function.
* This is rarely used, but comes in handy when you want to explain how the inside of the function works, but you don't want to flood the function JSDoc comment with details, since the JSDoc should only contain information about how to *use* the function and what the function *does*, not how the function *works*.
* This multi-line comment should ALWAYS be right under the function definition.
*/
/*! There should ALWAYS be 1 blank line after the logic block that defines the function. */
// Logic blocks with short comments use single-line comments.
// Even if multiple single-line comments are needed.
foo = `${foo} ${bar} + 5 foos`; /*! Template literals are prefered over strings when concatenating. */
const barfoo = foo + 'apple'; /*! There should ALWAYS be a whitespace before and after math operators that do not use parentheses. */
const flap = String.toLowerCase(foo + '.'); /*! There should NEVER be whitespaces after the opening parentheses, and before the closing parentheses (assuming the parentheses are on the same line). */
/*! There should ALWAYS be 1 blank line between logic blocks. */
// IF bar exists, AND the length of bar is greater than 0...
if (!!bar && bar.length > 0) {
// ...then prepend bar to foo
const goo = `${bar}${foo}`;
foo = goo;
}
// IF foo exists, then set bar to foo
if (!!foo) {
bar = foo; /*! When the entire conditional statement is 1 logic block, which includes all code within the conditional statement, and the conditional statement itself, there is NEVER a blank line after the statement declaration. */
}
/*! The comment line immediately above conditional statments SHOULD be spoken form of the conditional statement.
* In addition, the comment ALWAYS uses all captital letters for logical operators and conditional statements.
* E.g., "IF", "ELSE IF", "AND", "WHILE", "XOR", "NOT", "NOR", "greater than", "integer", "one", "bitwise OR", "then", "try", "exists"
* In addition, the comment ALWAYS ends with an eclipse.
* The eclipse is continued on the start of the next comment inside the conditional statment, and finishes the "thought" about what the conditional statement does.
* If multiple comments are needed, then they MAY all start and end with eclipses to show a"continual thought process" that requires you to read multiple lines of comments, which arescattered apart.
* However, if the conditional statement is 1 logic block, which includes all code within the conditional statement, and the conditional statement itself, then no eclipse is added, and the purpose of the logic statement is combined with the comment line that contains the spoken form of the conditional statement.
* If nested logic is used within the conditional statement, it is written as follows...
*/
// IF foobar exists...
// ...AND foo exists...
// ...OR bar exists, AND goo exists...
if (!!foobar && (!!foo || (!!bar && !!goo))) {
// ...then set foobar to bar
let goo = foo * bar; // Describe why foo * bar is used
goo += 5; // Describe why 5 is being added here
foobar = goo;
}
// Sum 1 + 1, then try to set a & b to the result
const sum = ((a, b) => (a + b)); /*! Parentheses MIGHT be used around arrow functions and IIFEs. */
try {
const a, b = sum(1, 1);
} catch (exception) { /*! It is perfered that the caught error variable be named "exception" */
throw new Exception('lol get pwned');
}
} /*! There is ALWAYS no blank line after the last logic block, and the ending brace. */
/** A 1 sentence description of what the function does.
* An optional multi-line detailed description of what the function does.
* @param {Object} [object] - NEVER describe the optional object here unless there are multiple objects being passed in.
* @param {Array<string>} [object.never] - What never is.
* @param {string} [object.gonna] - What gonna is.
* @param {Boolean} [object.give] - What give is.
* @param {Number} [object.number] - What you is.
* @param {Number} [object.up] - What's up.
* @since 1.2.3
* @author SwingTheVine
* @example
* // One example
* @example
* // One example
* @example
* // One example
*/
function #foo({
never: [''], // A comment should describe each default value of these, ONLY if not described in @param
gonna: '', // Going to hold "foobar" in gonna, or default to empty string if nothing is passed in.
give: true,
you: 1,
up: 0.5, /*! Trailing comment is ALWAYS used on the last variable in objects UNLESS it causes lint warnings or errors. */
} = {}) {
never = ['foo', 'bar']; /*! Trailing comment is NEVER used on the last index of an array UNLESS it causes lint warnings or errors. */
/*! Variables are named in the order of their most common denominator of what property they share. */
const fooApple = undefined;
const fooBar = undefined;
const fooBarCarrot = undefined;
const fooBarCarrotColor = 'orange';
const fooHit = 'hurts others';
const fooHitByBarFight = 'hurts me';
const fooHitByTruck = 'hurts me more';
/*! And the variable declarations can be in logic blocks */
const bars = undefined;
const barsLocations = undefined;
const barsApple = undefined
const barDrink = undefined;
return true;
}
// Assume there is a JSDoc comment here
function call() {
#foo({
you: false,
});
}
}

View file

@ -1,191 +0,0 @@
/** This is a summary of the file's purpose as a top-of-file JSDoc comment.
* This is an optional, detailed explanation.
* The first line of the comment should be 1 sentence.
* If more sentences are needed, they are put after the first line.
* @since 1.2.3
* @author SwingTheVine
*/
/*! Import lines go here, usually in 1 logic block */
import fs from "fs";
import { foo, bar } from "./foobar.js";
import { foo } from "./foobar.js"; /*! There is ALWAYS a whitespace around the braces for imports. */
/*! Import lines can optionally be grouped into logic blocks, based on type.
* For example, all default imports could be grouped together, or all "require" imports could be in a different logic block from the "import"s.
* If multiple logic blocks are used. There must ALWAYS be a comment before the logic block that explains the common logic of why all of the imports are in this specific logic block.
* If there are multiple import logic blocks, there must ALWAYS be 1 blank line between them.
*/
// CommonJS "imports" which require "require" in order to be imported
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const terser = require("terser");
const foo = require("foo");
/*! There should ALWAYS be 1 blank line between the last import logic block, and the class definition logic block. */
/** A 1 sentence description of what the class does.
* An optional multi-line detailed description of what the class does.
* @class Foo
* @since 1.2.3
* @example
* // An example of how to use the Foo class
*/
export default class Foo {
/* An optional multi-line comment to further explain things about the Foo class.
* This is rarely used, but comes in handy when you want to explain how the inside of the class works, but you don't want to flood the class JSDoc comment with details, since the JSDoc should only contain information about how to *use* the class and what the class *does*, not how the class *works*.
* This multi-line comment should ALWAYS be right under the class definition.
*/
/*! There should ALWAYS be 1 blank line after the logic block that defines the class. */
/** This line should declare if this is the main constructor, or an overload.
* An optional description of why this constructor should be used.
* @param {*} foo - What foo is.
* @param {*} bar - What bar is.
* @since 1.2.3
* @see {@link Foo}
*/
constructor(foo, bar) {
/*! Opening braces are ALWAYS on the same line as declaration */
/*! There should NEVER be a whitespace before the first variable, and after the last variable. */
/*! The blank line after the declaration is optional for constructors */
this.foo = foo; // The description of foo should go here only if there is no JSDoc...
this.bar = bar + 5; // ...but if the passed in variable is modified, a comment should be added to explain why.
this.hatMan = "a"; /*! Constants are ALWAYS camelCase */
this.color = foo.RED_APPLE; /*! Enum variables are ALWAYS SCREAMING_SNAKE_CASE */
/*! There is NEVER a blank line after the end of the last logic block in a statement */
}
/*! Closing braces are ALWAYS on their own line if the statement contains more than 1 line of code.
* The closing brace is aligned with start of the statement.
* However, if there are multiple closing braces, they can optionally be stacked onto the same line.
*/
/** A 1 sentence description of what the function does.
* An optional multi-line detailed description of what the function does.
* @param {*} foo - What foo is.
* @param {*} [bar=''] - What bar is.
*/
#bar(foo, bar = "") {
/*! There should NEVER be a whitespace between the function name and the passed in variables.
* There should NEVER be a whitespace before the first variable passed in when the variables are all on the same line as the function declaration.
* There should NEVER be a whitespace after the last variable passed in when the variables are all on the same line as the function declaration.
*/
/* An optional multi-line comment to further explain things about the bar function.
* This is rarely used, but comes in handy when you want to explain how the inside of the function works, but you don't want to flood the function JSDoc comment with details, since the JSDoc should only contain information about how to *use* the function and what the function *does*, not how the function *works*.
* This multi-line comment should ALWAYS be right under the function definition.
*/
/*! There should ALWAYS be 1 blank line after the logic block that defines the function. */
// Logic blocks with short comments use single-line comments.
// Even if multiple single-line comments are needed.
foo = `${foo} ${bar} + 5 foos`; /*! Template literals are prefered over strings when concatenating. */
const barfoo =
foo +
"apple"; /*! There should ALWAYS be a whitespace before and after math operators that do not use parentheses. */
const flap = String.toLowerCase(
foo + "."
); /*! There should NEVER be whitespaces after the opening parentheses, and before the closing parentheses (assuming the parentheses are on the same line). */
/*! There should ALWAYS be 1 blank line between logic blocks. */
// IF bar exists, AND the length of bar is greater than 0...
if (!!bar && bar.length > 0) {
// ...then prepend bar to foo
const goo = `${bar}${foo}`;
foo = goo;
}
// IF foo exists, then set bar to foo
if (!!foo) {
bar =
foo; /*! When the entire conditional statement is 1 logic block, which includes all code within the conditional statement, and the conditional statement itself, there is NEVER a blank line after the statement declaration. */
}
/*! The comment line immediately above conditional statments SHOULD be spoken form of the conditional statement.
* In addition, the comment ALWAYS uses all captital letters for logical operators and conditional statements.
* E.g., "IF", "ELSE IF", "AND", "WHILE", "XOR", "NOT", "NOR", "greater than", "integer", "one", "bitwise OR", "then", "try", "exists"
* In addition, the comment ALWAYS ends with an eclipse.
* The eclipse is continued on the start of the next comment inside the conditional statment, and finishes the "thought" about what the conditional statement does.
* If multiple comments are needed, then they MAY all start and end with eclipses to show a"continual thought process" that requires you to read multiple lines of comments, which arescattered apart.
* However, if the conditional statement is 1 logic block, which includes all code within the conditional statement, and the conditional statement itself, then no eclipse is added, and the purpose of the logic statement is combined with the comment line that contains the spoken form of the conditional statement.
* If nested logic is used within the conditional statement, it is written as follows...
*/
// IF foobar exists...
// ...AND foo exists...
// ...OR bar exists, AND goo exists...
if (!!foobar && (!!foo || (!!bar && !!goo))) {
// ...then set foobar to bar
let goo = foo * bar; // Describe why foo * bar is used
goo += 5; // Describe why 5 is being added here
foobar = goo;
}
// Sum 1 + 1, then try to set a & b to the result
const sum = (a, b) => a + b; /*! Parentheses MIGHT be used around arrow functions and IIFEs. */
try {
const { a, b } = sum(1, 1);
} catch (exception) {
/*! It is perfered that the caught error variable be named "exception" */
throw new Exception("lol get pwned");
}
} /*! There is ALWAYS no blank line after the last logic block, and the ending brace. */
/** A 1 sentence description of what the function does.
* An optional multi-line detailed description of what the function does.
* @param {Object} [object] - NEVER describe the optional object here unless there are multiple objects being passed in.
* @param {Array<string>} [object.never] - What never is.
* @param {string} [object.gonna] - What gonna is.
* @param {Boolean} [object.give] - What give is.
* @param {Number} [object.number] - What you is.
* @param {Number} [object.up] - What's up.
* @since 1.2.3
* @author SwingTheVine
* @example
* // One example
* @example
* // One example
* @example
* // One example
*/
#foo({
never = [""], // A comment should describe each default value of these, ONLY if not described in @param
gonna = "", // Going to hold "foobar" in gonna, or default to empty string if nothing is passed in.
give = true,
you = 1,
up = 0.5 /*! Trailing comment is ALWAYS used on the last variable in objects UNLESS it causes lint warnings or errors. */,
} = {}) {
never = [
"foo",
"bar",
]; /*! Trailing comment is NEVER used on the last index of an array UNLESS it causes lint warnings or errors. */
/*! Variables are named in the order of their most common denominator of what property they share. */
const fooApple = undefined;
const fooBar = undefined;
const fooBarCarrot = undefined;
const fooBarCarrotColor = "orange";
const fooHit = "hurts others";
const fooHitByBarFight = "hurts me";
const fooHitByTruck = "hurts me more";
/*! And the variable declarations can be in logic blocks */
const bars = undefined;
const barsLocations = undefined;
const barsApple = undefined;
const barDrink = undefined;
return true;
}
// Assume there is a JSDoc comment here
call() {
foo({
you: false,
});
}
}

View file

@ -1,39 +1 @@
import { Context } from './types';
import { getGMResourceText } from './utils';
/** Injects code into the client
* This code will execute outside of TamperMonkey's sandbox
* @param {*} callback - The code to execute
* @since 0.11.15
*/
function inject(callback: (x: Context) => void, context: Context) {
const script: HTMLScriptElement = document.createElement('script');
script.textContent = `(${callback})(${JSON.stringify(context)});`;
document.documentElement?.appendChild(script);
script.remove();
}
const cond = true;
if (cond) {console.log('test');console.log('test');}
const context: Context = {};
// Needs to be wrapped in async functionality to keep synchronous flow with the async GM functions
(async () => {
context.HTMLData = await getGMResourceText('HTML-BM-File');
context.CSSUrl = await GM.getResourceUrl('CSS-BM-File');
/** What code to execute instantly in the client (webpage) to spy on fetch calls.
* This code will execute outside of TamperMonkey's sandbox.
* @since 0.11.15
*/
inject((ctx: Context) => {
console.log('Test', ctx);
const link: HTMLLinkElement = document.createElement('link'); // Create element in order to link css
link.rel = 'stylesheet';
link.href = ctx.CSSUrl || '';
document.head.appendChild(link); // Links the css to the document
document.body.innerHTML += ctx.HTMLData; // Inserts the raw html into body
}, context);
})();
console.log("I'm blue marble!")

View file

@ -1,3 +1,4 @@
<!-- body -->
<div id="bm-overlay" style="top: 10px; right: 75px">
<header id="bm-contain-header">
<div id="bm-bar-drag">
@ -75,7 +76,7 @@
<button id="bm-button-create">Create</button>
<button id="bm-button-disable">Disable</button>
</div>
<textarea id="overlayMain.outputStatusId" placeholder="Status: Sleeping...\nVersion: ${version}" readonly></textarea>
<textarea id="overlayMain.outputStatusId" placeholder="Status: Sleeping...\nVersion: {version}" readonly></textarea>
<div id="bm-contain-buttons-action">
<button id="bm-button-convert" class="bm-help" title="Template Color Converter">🎨</button>
<p style="margin-top: auto">Made by SwingTheVine</p>