From 653864be994734783be2dd76d37237d49cfb09db Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Mon, 11 Oct 2021 02:41:45 +0100 Subject: [PATCH 01/24] Start working on //copy, but it's not finished yet. We need to merge @VorTechnix's branch in first to gain access to advanced axis parsing functions before we can complete it. For this reason, the command registration for //copy is currently commented out. --- worldeditadditions/init.lua | 2 + worldeditadditions/lib/copy.lua | 47 ++++++++++++++++ worldeditadditions/utils/parse/axes.lua | 55 +++++++++++++++++++ worldeditadditions/utils/parse/init.lua | 4 +- worldeditadditions_commands/commands/copy.lua | 50 +++++++++++++++++ 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 worldeditadditions/lib/copy.lua create mode 100644 worldeditadditions/utils/parse/axes.lua create mode 100644 worldeditadditions_commands/commands/copy.lua diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 2b50a0e..8dfe215 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -53,6 +53,8 @@ dofile(wea.modpath.."/lib/conv/conv.lua") dofile(wea.modpath.."/lib/erode/erode.lua") dofile(wea.modpath.."/lib/noise/init.lua") +dofile(wea.modpath.."/lib/copy.lua") + dofile(wea.modpath.."/lib/count.lua") dofile(wea.modpath.."/lib/bonemeal.lua") diff --git a/worldeditadditions/lib/copy.lua b/worldeditadditions/lib/copy.lua new file mode 100644 index 0000000..5bac439 --- /dev/null +++ b/worldeditadditions/lib/copy.lua @@ -0,0 +1,47 @@ +--- Copies a region to another location, potentially overwriting the exiting region. +-- @module worldeditadditions.copy + +local wea = worldeditadditions +local Vector3 = wea.Vector3 + +-- ██████ ██████ ██████ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██████ ████ +-- ██ ██ ██ ██ ██ +-- ██████ ██████ ██ ██ + +function worldeditadditions.count(source_pos1, source_pos2, target_pos1, target_pos2) + source_pos1, source_pos2 = Vector3.sort(source_pos1, source_pos2) + target_pos1, target_pos2 = Vector3.sort(target_pos1, target_pos2) + + local offset = source_pos1:subtract(target_pos1) + -- {source,target}_pos2 will always have the highest co-ordinates now + + -- Fetch the nodes in the source area + local manip_source, area_source = worldedit.manip_helpers.init(source_pos1, source_pos2) + local data_source = manip_source:get_data() + + -- Fetch a manip for the target area + local manip_target, area_target = worldedit.manip_helpers.init(target_pos1, target_pos2) + local data_target = manip_target:get_data() + + -- z y x is the preferred loop order (because CPU cache I'd guess, since then we're iterating linearly through the data array) + + for z = source_pos2.z, source_pos1.z, -1 do + for y = source_pos2.y, source_pos1.y, -1 do + for x = source_pos2.x, source_pos1.x, -1 do + local source = Vector3.new(x, y, z) + local source_i = area_source:index(x, y, z) + local target = source:subtract(offset) + local target_i = area_target:index(target.x, target.y, target.z) + + data_target[target_i] = data_source[source_i] + end + end + end + + -- Save the modified nodes back to disk & return + worldedit.manip_helpers.finish(manip_target, data_target) + + return true, worldedit.volume(target_pos1, target_pos2) +end diff --git a/worldeditadditions/utils/parse/axes.lua b/worldeditadditions/utils/parse/axes.lua new file mode 100644 index 0000000..9cb29ed --- /dev/null +++ b/worldeditadditions/utils/parse/axes.lua @@ -0,0 +1,55 @@ +local wea = worldeditadditions +local Vector3 = dofile(wea.modpath.."/utils/vector3.lua") +-- BUG: This does not exist yet - need to merge @VorTechnix's branch first to get it +-- TODO: Uncomment then once it's implemented +-- local parse_axis = dofile(wea.modpath.."/utils/axis.lua") + +--- Parses a token list of axes and counts into a Vector3. +-- For example, "x 4" would become { x = 4, y = 0, z = 0 }, and "? 4 -z 10" +-- might become { x = 4, y = 0, z = -10 }. +-- Note that the input here needs to be *pre split*. wea.split_shell is +-- recommended for this purpose. +-- Uses wea.parse.axis for parsing axis names. +-- @param token_list string[] A list of tokens to parse +-- @returns Vector3 A Vector3 generated from parsing out the input token list. +local function parse_axes(token_list) + local vector_result = wea.Vector3.new() + + if #token_list < 2 then + return false, "Error: Not enough arguments (at least 2 are required)" + end + + local state = "AXIS" + local current_axis = nil + local success + + for i,token in ipairs(token_list) do + if state == "AXIS" then + success, current_axis = parse_axis(token) + if not success then return success, current_axis end + state = "VALUE" + elseif state == "VALUE" then + + local offset_this = tonumber(token) + if not offset_this then + return false, "Error: Invalid count value for axis '"..current_axis.."'. Values may only be positive or negative integers." + end + + -- Handle negative axes + if current_axis:sub(1, 1) == "-" then + offset_this = -offset_this + current_axis = current_axis:sub(2, 2) + end + + vector_result[current_axis] = vector_result[current_axis] + offset_this + + state = "AXIS" + else + return false, "Error: Failed to parse input due to unknown state '"..tostring(state).."' (this is probably a bug - please report it!)" + end + end + + return vector_result +end + +return parse_axes diff --git a/worldeditadditions/utils/parse/init.lua b/worldeditadditions/utils/parse/init.lua index ae8d8b4..dc01104 100644 --- a/worldeditadditions/utils/parse/init.lua +++ b/worldeditadditions/utils/parse/init.lua @@ -4,7 +4,9 @@ -- ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ██ ██ ██ ███████ ███████ -worldeditadditions.parse = {} +worldeditadditions.parse = { + axes = dofile(worldeditadditions.modpath.."/utils/parse/axes.lua") +} dofile(worldeditadditions.modpath.."/utils/parse/chance.lua") dofile(worldeditadditions.modpath.."/utils/parse/map.lua") diff --git a/worldeditadditions_commands/commands/copy.lua b/worldeditadditions_commands/commands/copy.lua new file mode 100644 index 0000000..4a0e1e3 --- /dev/null +++ b/worldeditadditions_commands/commands/copy.lua @@ -0,0 +1,50 @@ +local wea = worldeditadditions +-- ██████ ██████ ██████ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██████ ████ +-- ██ ██ ██ ██ ██ +-- ██████ ██████ ██ ██ +worldedit.register_command("copy", { -- TODO: Make this an override + params = " [ [...]]", + description = "Copies the defined region to another location - potentially on multiple axes at once.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + if not params_text then params_text = "" end + + local parts = wea.split_shell(params_text) + + local copy_offset = wea.parse.axes(parts) + + if copy_offset == wea.Vector3.new() then + return false, "Refusing to copy region a distance of 0 nodes" + end + + return true, copy_offset:floor() + end, + nodes_needed = function(name) + -- We don't actually modify anything, but without returning a + -- number here safe_region doesn't work + return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) + end, + func = function(name, copy_offset) + local start_time = wea.get_ms_time() + + local source_pos1 = wea.Vector3.clone(worldedit.pos1[name]) + local source_pos2 = wea.Vector3.clone(worldedit.pos2[name]) + + local target_pos1 = source_pos1:add(copy_offset) + local target_pos2 = source_pos2:add(copy_offset) + + local success, nodes_modified = wea.copy( + source_pos1, source_pos2, + target_pos1, target_pos2 + ) + + local time_taken = wea.get_ms_time() - start_time + + + minetest.log("action", name.." used //copy from "..source_pos1.." - "..source_pos2.." to "..target_pos1.." - "..target_pos2..", modifying "..nodes_modified.." nodes in "..wea.format.human_time(time_taken)) + return true, nodes_modified.." nodes copied using offset "..copy_offset.." in "..wea.format.human_time(time_taken) + end +}) From 4955aa7579a21cef12627c11f74b7b7289d3934c Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Mon, 11 Oct 2021 02:45:21 +0100 Subject: [PATCH 02/24] docs: update dependencies --- .docs/package-lock.json | 118 +++++++++++++++------------------------- 1 file changed, 45 insertions(+), 73 deletions(-) diff --git a/.docs/package-lock.json b/.docs/package-lock.json index b06e3b4..72f0a12 100644 --- a/.docs/package-lock.json +++ b/.docs/package-lock.json @@ -113,23 +113,6 @@ "url": "https://opencollective.com/11ty" } }, - "node_modules/@11ty/eleventy-img/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", @@ -243,9 +226,9 @@ "dev": true }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -374,12 +357,12 @@ } }, "node_modules/axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, "dependencies": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "node_modules/babel-walk": { @@ -976,9 +959,9 @@ } }, "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2334,15 +2317,15 @@ } }, "node_modules/localtunnel": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz", - "integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.2.tgz", + "integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==", "dev": true, "dependencies": { - "axios": "0.21.1", - "debug": "4.3.1", + "axios": "0.21.4", + "debug": "4.3.2", "openurl": "1.1.1", - "yargs": "16.2.0" + "yargs": "17.1.1" }, "bin": { "lt": "bin/lt.js" @@ -2389,9 +2372,9 @@ } }, "node_modules/localtunnel/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", + "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", "dev": true, "dependencies": { "cliui": "^7.0.2", @@ -2403,13 +2386,13 @@ "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/localtunnel/node_modules/yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { "node": ">=10" @@ -4780,17 +4763,6 @@ "p-queue": "^6.6.2", "sharp": "^0.29.0", "short-hash": "^1.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } } }, "@babel/helper-validator-identifier": { @@ -4882,9 +4854,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -4986,12 +4958,12 @@ "dev": true }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" } }, "babel-walk": { @@ -5484,9 +5456,9 @@ "dev": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -6549,15 +6521,15 @@ "dev": true }, "localtunnel": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz", - "integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.2.tgz", + "integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==", "dev": true, "requires": { - "axios": "0.21.1", - "debug": "4.3.1", + "axios": "0.21.4", + "debug": "4.3.2", "openurl": "1.1.1", - "yargs": "16.2.0" + "yargs": "17.1.1" }, "dependencies": { "cliui": { @@ -6589,9 +6561,9 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", + "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -6604,9 +6576,9 @@ } }, "yargs-parser": { - "version": "20.2.7", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", - "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } From 32fb8be8fe78b467f9f6b53c6640daf7f0f9e64b Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Tue, 12 Oct 2021 02:23:33 +0100 Subject: [PATCH 03/24] docs: remember searchall setting with localStorage; better categorical command list filtering --- .docs/Reference.html | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/.docs/Reference.html b/.docs/Reference.html index bf10399..2cfefcc 100644 --- a/.docs/Reference.html +++ b/.docs/Reference.html @@ -14,11 +14,11 @@
- - + +
- +
@@ -128,6 +128,7 @@ function do_filter() { let el_search = document.querySelector("#input-filter"); let el_searchall = document.querySelector("#input-searchall"); + localStorage.setItem("commandlist-searchall", el_searchall.checked); /* Filterable items - Sections - Commands in the command list @@ -165,6 +166,22 @@ el_next.classList.remove("visible", "hidden"); el_next.classList.add(show ? "visible" : "hidden"); } + + let commandlist_is_categorical = document.querySelector("button.active[data-mode=categorical]") !== null; + if(commandlist_is_categorical) { + let container = document.querySelector(".command-container"); + for(let i = 0; i < container.children.length; i++) { + if(container.children[i].nodeName.toLowerCase() === "ul") { + let class_name = "visible"; + if(container.children[i].querySelector("li.visible") === null) + class_name = "hidden"; + if(i > 0) { + container.children[i-1].classList.remove("visible", "hidden"); + container.children[i-1].classList.add(class_name); + } + } + } + } } window.addEventListener("load", (_event) => { @@ -181,6 +198,9 @@ els_cats[i].addEventListener("touchend", handle_display_mode); } + if(localStorage.getItem("commandlist-searchall") !== null) + el_searchall.checked = localStorage.getItem("commandlist-searchall") === "true"; + if(localStorage.getItem("commandlist-displaymode") !== null) set_display_mode(localStorage.getItem("commandlist-displaymode")) }); From 5bdd8ddb5e312e46275d0213ccc5ec28fd7bbe3e Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Wed, 13 Oct 2021 22:46:14 +0100 Subject: [PATCH 04/24] ellipsoid: remove redundant minetest.get_content_id("air") call wea.is_airlike() is the new function that should be used instead, but in this case the call wasn't even necessary --- worldeditadditions/lib/ellipsoid.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/worldeditadditions/lib/ellipsoid.lua b/worldeditadditions/lib/ellipsoid.lua index d63fdb8..72a9ac1 100644 --- a/worldeditadditions/lib/ellipsoid.lua +++ b/worldeditadditions/lib/ellipsoid.lua @@ -18,7 +18,6 @@ function worldeditadditions.ellipsoid(position, radius, target_node, hollow) local data = manip:get_data() local node_id = minetest.get_content_id(target_node) - local node_id_air = minetest.get_content_id("air") local stride_z, stride_y = area.zstride, area.ystride From 91d5b9abc2d2c75df686d7f3bd85478c5d46f92a Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Wed, 13 Oct 2021 22:50:37 +0100 Subject: [PATCH 05/24] ellipsoid: add comment --- worldeditadditions/lib/ellipsoid.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/worldeditadditions/lib/ellipsoid.lua b/worldeditadditions/lib/ellipsoid.lua index 72a9ac1..235c4e2 100644 --- a/worldeditadditions/lib/ellipsoid.lua +++ b/worldeditadditions/lib/ellipsoid.lua @@ -4,6 +4,14 @@ -- ██ ██ ██ ██ ██ ██ ██ -- ███████ ███████ ███████ ██ ██ ███████ ███████ +--- Fills an ellipsoidal area around the given position with the target node. +-- The resulting ellipsoid may optionally be hollow (in which case +-- nodes inside the ellipsoid are left untouched). +-- @param position Vector3 The centre position of the ellipsoid. +-- @param radius Vector3 The radius of the ellipsoid in all 3 dimensions. +-- @param target_node string The name of the node to use to fill the ellipsoid. +-- @param hollow bool Whether the ellipsoid should be hollow or not. +-- @returns number The number of nodes filled to create the (optionally hollow) ellipsoid. This number will be lower with hollow ellipsoids, since the internals of an ellipsoid aren't altered. function worldeditadditions.ellipsoid(position, radius, target_node, hollow) -- position = { x, y, z } local hollow_inner_radius = { From 2ae241aee527e714f76b08c664a4f97af08852c7 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Thu, 14 Oct 2021 01:50:27 +0100 Subject: [PATCH 06/24] Add //ellipsoid2 --- CHANGELOG.md | 3 +- Chat-Command-Reference.md | 12 +++ README.md | 1 + worldeditadditions/init.lua | 1 + worldeditadditions/lib/ellipsoid2.lua | 76 +++++++++++++++++++ .../commands/ellipsoid2.lua | 51 +++++++++++++ worldeditadditions_commands/init.lua | 1 + 7 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 worldeditadditions/lib/ellipsoid2.lua create mode 100644 worldeditadditions_commands/commands/ellipsoid2.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index a0305cf..e6c3891 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ Note to self: See the bottom of this file for the release template text. - Add `//airapply` for applying commands only to air nodes in the defined region - Add `//noise2d` for perturbing terrain with multiple different noise functions - Add `//noiseapply2d` for running commands on columns where a noise value is over a threshold - - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues + - Add `//ellipsoid2` which creates an ellipsoid that fills the defined region + - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting - `//layers`: Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) - `//bonemeal`: Add optional node list constraint diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 86bc4ca..de93b5a 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -42,6 +42,18 @@ Creates a hollow ellipsoid at position 1 with the radius `(rx, ry, rz)`. Works t //hollowellipsoid 21 11 41 stone ``` +### `//ellipsoid2 [ [h[ollow]]]` +Creates an (optionally hollow) solid ellipsoid that fills the defined region. + +```weacmd +//ellipsoid2 +//ellipsoid2 ice +//ellipsoid2 air +//ellipsoid2 steelblock h +//ellipsoid2 papyrus hollow +``` + + ### `//torus [ [h[ollow]]]` Creates a solid torus at position 1 with the specified major and minor radii. The major radius is the distance from the centre of the torus to the centre of the circle bit, and the minor radius is the radius of the circle bit. diff --git a/README.md b/README.md index 670ef3a..4ebc5f7 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ The detailed explanations have moved! Check them out [here](https://github.com/s ### Geometry - [`//ellipsoid [h[ollow]]`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid) + - [`//ellipsoid2 [h[ollow]]`](https://worldeditadditions.mooncarrot.space/Reference/#ellipsoid2) - [`//hollowellipsoid `](https://worldeditadditions.mooncarrot.space/Reference/#hollowellipsoid) - [`//torus [ [h[ollow]]]`](https://worldeditadditions.mooncarrot.space/Reference/#torus) - [`//hollowtorus []`](https://worldeditadditions.mooncarrot.space/Reference/#hollowtorus) diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 8dfe215..2e83be2 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -39,6 +39,7 @@ dofile(wea.modpath.."/lib/overlay.lua") dofile(wea.modpath.."/lib/layers.lua") dofile(wea.modpath.."/lib/fillcaves.lua") dofile(wea.modpath.."/lib/ellipsoid.lua") +dofile(wea.modpath.."/lib/ellipsoid2.lua") dofile(wea.modpath.."/lib/torus.lua") dofile(wea.modpath.."/lib/line.lua") dofile(wea.modpath.."/lib/walls.lua") diff --git a/worldeditadditions/lib/ellipsoid2.lua b/worldeditadditions/lib/ellipsoid2.lua new file mode 100644 index 0000000..6a677dd --- /dev/null +++ b/worldeditadditions/lib/ellipsoid2.lua @@ -0,0 +1,76 @@ +local wea = worldeditadditions + +-- ███████ ██ ██ ██ ██████ ███████ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ +-- █████ ██ ██ ██ ██████ ███████ █████ +-- ██ ██ ██ ██ ██ ██ ██ +-- ███████ ███████ ███████ ██ ██ ███████ ███████ + + +function worldeditadditions.ellipsoid2(pos1, pos2, target_node, hollow) + pos1, pos2 = wea.Vector3.sort(pos1, pos2) + local volume = pos2:subtract(pos1) + local volume_half = volume:divide(2) + + local radius = pos2:subtract(pos1):divide(2) + + print("DEBUG:ellipsoid2 | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node) + print("DEBUG:ellipsoid2 radius", radius) + + -- position = { x, y, z } + local hollow_inner_radius = { + x = radius.x - 1, + y = radius.y - 1, + z = radius.z - 1 + } + + -- Fetch the nodes in the specified area + -- OPTIMIZE: We should be able to calculate a more efficient box-area here + local manip, area = worldedit.manip_helpers.init(pos1, pos2) + local data = manip:get_data() + + local node_id = minetest.get_content_id(target_node) + + local count = 0 -- The number of nodes replaced + + for z = pos2.z, pos1.z, -1 do + for y = pos2.y, pos1.y, -1 do + for x = pos2.x, pos1.x, -1 do + + local pos_relative = wea.Vector3.new(x, y, z):subtract(pos1) + :subtract(volume_half) + + print("DEBUG pos1", pos1, "pos2", pos2, "volume_half", volume_half, "pos_relative", pos_relative) + + -- If we're inside the ellipse, then fill it in + local comp = pos_relative:divide(radius) + local ellipsoid_dist = comp:length_squared() + if ellipsoid_dist <= 1 then + local place_ok = not hollow; + + if not place_ok then + -- It must be hollow! Do some additional calculations. + local hx_comp = x/hollow_inner_radius.x + local hy_comp = y/hollow_inner_radius.y + local hz_comp = z/hollow_inner_radius.z + + -- It's only ok to place it if it's outside our inner ellipse + place_ok = hx_comp*hx_comp + hy_comp*hy_comp + hz_comp*hz_comp >= 1 + end + + if place_ok then + data[area:index(x, y, z)] = node_id + count = count + 1 + end + end + + end + end + end + + + -- Save the modified nodes back to disk & return + worldedit.manip_helpers.finish(manip, data) + + return count +end diff --git a/worldeditadditions_commands/commands/ellipsoid2.lua b/worldeditadditions_commands/commands/ellipsoid2.lua new file mode 100644 index 0000000..541532a --- /dev/null +++ b/worldeditadditions_commands/commands/ellipsoid2.lua @@ -0,0 +1,51 @@ +-- ███████ ██ ██ ██ ██████ ███████ ██████ ██ ██████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- █████ ██ ██ ██ ██████ ███████ ██ ██ ██ ██ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ███████ ███████ ██ ██ ███████ ██████ ██ ██████ +local wea = worldeditadditions + +worldedit.register_command("ellipsoid2", { + params = "[ [h[ollow]]]", + description = "Creates am optionally hollow 3D ellipsoid that fills the defined region, filled with .", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + if not params_text or params_text == "" then + params_text = "dirt" + end + + local parts = wea.split_shell(params_text) + + + local replace_node = worldedit.normalize_nodename(parts[1]) + if not replace_node then + return false, "Error: Invalid replace_node specified." + end + + local hollow = false + if parts[2] == "hollow" or parts[2] == "h" then + hollow = true + end + + return true, replace_node, hollow + end, + nodes_needed = function(name, target_node) + local pos1, pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name]) + return math.ceil(4/3 * math.pi * (pos2.x - pos1.x)/2 * (pos2.y - pos1.y)/2 * (pos2.z - pos1.z)/2) + end, + func = function(name, target_node, radius, hollow) + local start_time = wea.get_ms_time() + local pos1, pos2 = wea.Vector3.sort(worldedit.pos1[name], worldedit.pos2[name]) + + local replaced = wea.ellipsoid2( + pos1, pos2, + target_node, + hollow + ) + local time_taken = wea.get_ms_time() - start_time + + minetest.log("action", name .. " used //ellipsoid2 at "..pos1.." - "..pos2..", replacing " .. replaced .. " nodes in " .. time_taken .. "s") + return true, replaced .. " nodes replaced in " .. wea.format.human_time(time_taken) + end +}) diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index cc3cdf5..491669d 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -21,6 +21,7 @@ dofile(we_c.modpath.."/player_notify_suppress.lua") dofile(we_c.modpath.."/commands/convolve.lua") dofile(we_c.modpath.."/commands/ellipsoid.lua") +dofile(we_c.modpath.."/commands/ellipsoid2.lua") dofile(we_c.modpath.."/commands/erode.lua") dofile(we_c.modpath.."/commands/fillcaves.lua") dofile(we_c.modpath.."/commands/floodfill.lua") From 6eaa3799d3a5aa9e165eb1595b64ed85d5c21808 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 17 Oct 2021 03:00:24 +0100 Subject: [PATCH 07/24] docs: massively improve image conversion system more formats, memoizing, custom element generation, async image conversion to optimise CPU usage, and more! Too bad that the imagemagick apt package doesn't natively support JPEG XL just yet (Imagemagick 7 does though), but that's an easy fix on our end once they add support :D It looks like we need to implement our own alternative to the serve command though :-/ --- .docs/.eleventy.js | 56 +- .docs/Reference.11tydata.js | 22 +- .docs/lib/Ansi.js | 88 ++ .docs/lib/HTMLPicture.js | 154 ++++ .docs/lib/parse_sections.js | 3 +- .docs/package-lock.json | 1658 ++++++----------------------------- .docs/package.json | 9 +- 7 files changed, 541 insertions(+), 1449 deletions(-) create mode 100644 .docs/lib/Ansi.js create mode 100644 .docs/lib/HTMLPicture.js diff --git a/.docs/.eleventy.js b/.docs/.eleventy.js index 3142200..cddd9b5 100644 --- a/.docs/.eleventy.js +++ b/.docs/.eleventy.js @@ -1,12 +1,14 @@ +"use strict"; + const os = require("os"); const fs = require("fs"); const path = require("path"); +const debug = require("debug"); const htmlentities = require("html-entities"); const phin = require("phin"); -const Image = require("@11ty/eleventy-img"); - +const HTMLPicture = require("./lib/HTMLPicture.js"); var nextid = 0; @@ -16,46 +18,22 @@ const image_filename_format = (_id, src, width, format, _options) => { return `${name}-${width}w.${format}`; }; -function image_metadata_log(metadata, source) { - for(let format in metadata) { - for(let img of metadata[format]) { - console.log(`${source.padEnd(10)} ${format.padEnd(5)} ${`${img.width}x${img.height}`.padEnd(10)} ${img.outputPath}`); - } - } -} - -async function shortcode_image(src, alt, classes = "") { - let metadata = await Image(src, { - widths: [300, null], - formats: ["avif", "jpeg"], - outputDir: `./_site/img/`, - filenameFormat: image_filename_format - }); - image_metadata_log(metadata, `IMAGE`); +async function shortcode_image(src, alt) { - let imageAttributes = { - class: classes, - alt: htmlentities.encode(alt), - sizes: Object.values(metadata)[0].map((el) => `${el.width}w`).join(" "), - loading: "lazy", - decoding: "async", - }; - - // You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay) - return Image.generateHTML(metadata, imageAttributes); + return HTMLPicture( + src, alt, + `./_site/img`, `/img` + ); } async function shortcode_image_url(src) { - let metadata = await Image(src, { - widths: [ null ], - formats: [ "jpeg" ], - outputDir: `./_site/img/`, - filenameFormat: image_filename_format - }); - image_metadata_log(metadata, `IMAGE_URL`); + const src_parsed = path.parse(src); + const target = path.join(`./_site/img`, src_parsed.base); + if(!fs.existsSync(path.dirname(target))) + await fs.promises.mkdir(target_dir, { recursive: true }); + await fs.promises.copyFile(src, target); - let data = metadata.jpeg[metadata.jpeg.length - 1]; - return data.url; + return path.join(`/img`, src_parsed.base); } async function shortcode_image_urlpass(src) { @@ -82,14 +60,14 @@ async function shortcode_gallerybox(content, src, idthis, idprev, idnext) { } async function fetch(url) { - let package = JSON.parse(await fs.promises.readFile( + const pkg_obj = JSON.parse(await fs.promises.readFile( path.join(__dirname, "package.json"), "utf8" )); return (await phin({ url, headers: { - "user-agent": `WorldEditAdditionsStaticBuilder/${package.version} (Node.js/${process.version}; ${os.platform()} ${os.arch()}) eleventy/${package.devDependencies["@11ty/eleventy"].replace(/\^/, "")}` + "user-agent": `WorldEditAdditionsStaticBuilder/${pkg_obj.version} (Node.js/${process.version}; ${os.platform()} ${os.arch()}) eleventy/${pkg_obj.devDependencies["@11ty/eleventy"].replace(/\^/, "")}` }, followRedirects: true, parse: "string" diff --git a/.docs/Reference.11tydata.js b/.docs/Reference.11tydata.js index 1bcba38..6b68fc8 100644 --- a/.docs/Reference.11tydata.js +++ b/.docs/Reference.11tydata.js @@ -1,5 +1,12 @@ +"use strict"; + const fs = require("fs"); const path = require("path"); + +const columnify = require("columnify"); +const htmlentities = require("html-entities"); + +const a = require("./lib/Ansi.js"); const parse_sections = require("./lib/parse_sections.js"); let { sections, categories } = parse_sections(fs.readFileSync( @@ -15,11 +22,20 @@ sections = sections.slice(1).sort((a, b) => a.title.replace(/^\/+/g, "").localeC console.log(`REFERENCE SECTION TITLES`) -console.log(sections - .map(s => [s.category, s.title].join(`\t`)).join(`\n`)); +console.log(columnify(sections.map(s => { return { + category: `${a.hicol}${a.fyellow}${s.category}${a.reset}`, + command: `${a.hicol}${a.fmagenta}${htmlentities.decode(s.title)}${a.reset}` +} }))); +// console.log(sections +// .map(s => `${a.fyellow}${a.hicol}${s.category}${a.reset}\t${a.fmagenta}${a.hicol}${s.title}${a.reset}`).join(`\n`)); console.log(`************************`); -console.log(`REFERENCE SECTION COLOURS`, categories); +console.log(`REFERENCE SECTION COLOURS`); +console.log(columnify(Array.from(categories).map(el => { return { + category: el[0], + colour: el[1] +} }))); + module.exports = { layout: "theme.njk", title: "Reference", diff --git a/.docs/lib/Ansi.js b/.docs/lib/Ansi.js new file mode 100644 index 0000000..4bb7493 --- /dev/null +++ b/.docs/lib/Ansi.js @@ -0,0 +1,88 @@ +"use strict"; + +/** + * Generates various VT100 ANSI escape sequences. + * Ported from C#. + * @licence MPL-2.0 + * @source https://gist.github.com/a4edd3204a03f4eedb79785751efb0f3#file-ansi-cs + * @author Starbeamrainbowlabs + * GitHub: @sbrl | Twitter: @SBRLabs | Reddit: u/Starbeamrainbowlabs + ***** Changelog ***** + * 27th March 2019: + * - Initial public release + * 9th March 2020: + * - Add Italics (\u001b[3m]) + * - Export a new instance of it by default (makes it so that there's 1 global instance) + * 5th September 2020: + * - Add support for NO_COLOR environment variable + */ +class Ansi { + constructor() { + /** + * Whether we should *actually* emit ANSI escape codes or not. + * Useful when we want to output to a log file, for example + * @type {Boolean} + */ + this.enabled = true; + + this.escape_codes(); + } + + escape_codes() { + if(typeof process !== "undefined" && typeof process.env.NO_COLOR == "string") { + this.enabled = false; + return; + } + // Solution on how to output ANSI escape codes in C# from here: + // https://www.jerriepelser.com/blog/using-ansi-color-codes-in-net-console-apps + this.reset = this.enabled ? "\u001b[0m" : ""; + this.hicol = this.enabled ? "\u001b[1m" : ""; + this.locol = this.enabled ? "\u001b[2m" : ""; + this.italics = this.enabled ? "\u001b[3m" : ""; + this.underline = this.enabled ? "\u001b[4m" : ""; + this.inverse = this.enabled ? "\u001b[7m" : ""; + this.fblack = this.enabled ? "\u001b[30m" : ""; + this.fred = this.enabled ? "\u001b[31m" : ""; + this.fgreen = this.enabled ? "\u001b[32m" : ""; + this.fyellow = this.enabled ? "\u001b[33m" : ""; + this.fblue = this.enabled ? "\u001b[34m" : ""; + this.fmagenta = this.enabled ? "\u001b[35m" : ""; + this.fcyan = this.enabled ? "\u001b[36m" : ""; + this.fwhite = this.enabled ? "\u001b[37m" : ""; + this.bblack = this.enabled ? "\u001b[40m" : ""; + this.bred = this.enabled ? "\u001b[41m" : ""; + this.bgreen = this.enabled ? "\u001b[42m" : ""; + this.byellow = this.enabled ? "\u001b[43m" : ""; + this.bblue = this.enabled ? "\u001b[44m" : ""; + this.bmagenta = this.enabled ? "\u001b[45m" : ""; + this.bcyan = this.enabled ? "\u001b[46m" : ""; + this.bwhite = this.enabled ? "\u001b[47m" : ""; + } + + // Thanks to http://ascii-table.com/ansi-escape-sequences.php for the following ANSI escape sequences + up(lines = 1) { + return this.enabled ? `\u001b[${lines}A` : ""; + } + down(lines = 1) { + return this.enabled ? `\u001b[${lines}B` : ""; + } + right(lines = 1) { + return this.enabled ? `\u001b[${lines}C` : ""; + } + left(lines = 1) { + return this.enabled ? `\u001b[${lines}D` : ""; + } + + jump_to(x, y) { + return this.enabled ? `\u001b[${y};${x}H` : ""; + } + + cursor_pos_save() { + return this.enabled ? `\u001b[s` : ""; + } + cursor_pos_restore() { + return this.enabled ? `\u001b[u` : ""; + } +} + +module.exports = new Ansi(); diff --git a/.docs/lib/HTMLPicture.js b/.docs/lib/HTMLPicture.js new file mode 100644 index 0000000..3cf053a --- /dev/null +++ b/.docs/lib/HTMLPicture.js @@ -0,0 +1,154 @@ +"use strict"; + +const os = require(`os`); +const fs = require("fs"); +const path = require("path"); + +const pretty_ms = require("pretty-ms"); +const debug = require("debug")("image"); +const imagickal = require("imagickal"); +const htmlentities = require("html-entities"); + +const a = require("./Ansi.js"); + +function calculate_size(width, height, size_spec) { + if(size_spec.indexOf("%") > -1) { + // It's a percentage + const multiplier = parseInt(size_spec.replace(/%/, ""), 10) / 100; + return { + width: Math.ceil(width * multiplier), + height: Math.ceil(height * multiplier) + }; + } + else { + // It's an absolute image width + const new_width = parseInt(size_spec, 10); + return { + width: new_width, + height: Math.ceil(new_width/width * height) + }; + } +} + +// Main task list - we make sure it completes before exiting. +var queue = null; +var pMemoize = null; + +async function make_queue() { + // 1: Setup task queue + const PQueue = (await import("p-queue")).default; + let concurrency = os.cpus().length; + if(process.env["MAX_CONCURRENT"]) + concurrency = parseInt(process.env["MAX_CONCURRENT"], 10); + debug(`Image conversion queue concurrency: `, concurrency); + queue = new PQueue({ concurrency }); + queue.on("idle", () => console.log(`IMAGE ${a.fcyan}all conversions complete${a.reset}`)); + process.on("exit", async () => { + debug(`Waiting for image conversions to finish...`); + await queue.onEmpty(); + debug(`All image conversions complete.`); + }); +} + +async function srcset(source_image, target_dir, urlpath, format = "__AUTO__", sizes = [ "25%", "50%", "100%" ], quality = 95, strip = true) { + if(queue === null) await make_queue(); + + const source_parsed = path.parse(source_image); + // ext contains the dot . already + const target_format = format == "__AUTO__" ? source_parsed.ext.replace(/\./g, "") : format; + + const source_size = await imagickal.dimensions(source_image); + + debug(`SOURCE_SIZE`, source_size, `TARGET_FORMAT`, target_format); + + let setitems = await Promise.all(sizes.map(async (size) => { + let target_filename = `${source_parsed.name}_${size}.${target_format}`; + let target_current = path.join( + target_dir, + target_filename + ); + queue.add(async () => { + const start = new Date(); + await imagickal.transform(source_image, target_current, { + resize: { width: size }, + quality, + strip + }); + console.log(`IMAGE\t${a.fcyan}${queue.size}/${queue.pending} tasks${a.reset}\t${a.fyellow}${pretty_ms(new Date() - start)}${a.reset}\t${a.fgreen}${target_current}${a.reset}`); + }); + // const size_target = await imagickal.dimensions(target_current); + + const predict = calculate_size(source_size.width, source_size.height, size); + // debug(`size spec:`, size, `size predicted: ${predict.width}x${predict.height} actual: ${size_target.width}x${size_target.height}`); + return `${path.resolve(urlpath, target_filename)} ${predict.width}w`; + })); + + return setitems.join(", "); +} + +/** + * Generates a string of HTML for a element, converting images to the specified formats in the process. + * @param {string} source_image The filepath to the source image. + * @param {string} alt The alt (alternative) text. Automatically run though htmlentities. + * @param {string} target_dir The target directory to save converted images to. + * @param {string} urlpath The path to the aforementionoed target directory as a URL. Image paths in the HTML will be prefixed with this value. + * @param {string} [formats="__AUTO__"] A list of formats to convert the source image to. Defaults to automatically determining the most optimal formats based on the input format. [must be lowercase] + * @param {Array} [sizes=["25%","50%", "100%" ]] The sizes, as imagemagick size specs, to convert the source image to. + * @param {Number} [quality=95] The quality value to use when converting images. + * @param {Boolean} [strip=true] Whether to strip all metadata from images when converting them [saves some space] + * @return {Promise} A Promise that returns a generated string of HTML. + */ +async function picture(source_image, alt, target_dir, urlpath, formats = "__AUTO__", sizes = [ "25%", "50%", "100%" ], quality = 95, strip = true) { + const source_parsed = path.parse(source_image); + const source_format = source_parsed.ext.toLowerCase().replace(".", ""); + + if(formats == "__AUTO__") { + switch(source_format) { + case "png": + case "gif": // * shudder * + case "bmp": + formats = [ "png" ]; + break; + default: + // jxl = JPEG XL - not currently supported by the old version of imagemagick shipped via apt :-/ + // Imagemagick v7+ does support it, but isn't shipped yet :-( + formats = [ "jpeg", "webp", "avif", /*"jxl"*/ ]; + break; + } + } + + const target_original = path.join(target_dir, source_parsed.base); + await fs.promises.copyFile(source_image, target_original); + + const sources = await Promise.all(formats.map(async (format) => { + debug(`${format} ${source_image}`); + + return { + mime: `image/${format}`, + srcset: await srcset( + source_image, + target_dir, urlpath, + format, sizes, + quality, strip + ) + }; + })); + + let result = `\n\t`; + result += sources.map(source => ``).join(`\n\t`); + result += `\n\t${htmlentities.encode(alt)}\n`; + result += `\n` + return result; +} + +var picture_memoize = null; + +async function setup_memoize() { + const pMemoize = (await import("p-memoize")).default; + picture_memoize = pMemoize(picture); +} + +module.exports = async function(...args) { + if(picture_memoize === null) await setup_memoize(); + return await picture_memoize(...args); +}; diff --git a/.docs/lib/parse_sections.js b/.docs/lib/parse_sections.js index 1c82213..a96204b 100644 --- a/.docs/lib/parse_sections.js +++ b/.docs/lib/parse_sections.js @@ -1,3 +1,5 @@ +"use strict"; + const crypto = require("crypto"); const htmlentities = require("html-entities"); @@ -6,7 +8,6 @@ const markdown = require("markdown-it")({ }); const chroma = require("chroma-js"); - const markdown_prism = require("markdown-it-prism"); markdown.use(markdown_prism, { init: (Prism) => { diff --git a/.docs/package-lock.json b/.docs/package-lock.json index 72f0a12..ef134dc 100644 --- a/.docs/package-lock.json +++ b/.docs/package-lock.json @@ -13,10 +13,15 @@ }, "devDependencies": { "@11ty/eleventy": "^0.12.1", - "@11ty/eleventy-img": "^0.10.0", "chroma-js": "^2.1.2", + "columnify": "^1.5.4", + "debug": "^4.3.2", + "imagickal": "^5.0.1", "markdown-it-prism": "^2.2.1", - "phin": "^3.6.0" + "p-memoize": "^6.0.1", + "p-queue": "^7.1.0", + "phin": "^3.6.0", + "pretty-ms": "^7.0.1" } }, "node_modules/@11ty/dependency-tree": { @@ -75,44 +80,6 @@ "url": "https://opencollective.com/11ty" } }, - "node_modules/@11ty/eleventy-cache-assets": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@11ty/eleventy-cache-assets/-/eleventy-cache-assets-2.3.0.tgz", - "integrity": "sha512-W8tvO00GlWaKt3ccpEStaUBoj9BE3EgzuD8uYChCfYbN2Q4HkEItkiapvIJT0zJwAwoMfnSq6VHPLScYlX2XCg==", - "dev": true, - "dependencies": { - "debug": "^4.3.1", - "flat-cache": "^3.0.4", - "node-fetch": "^2.6.1", - "p-queue": "^6.6.2", - "short-hash": "^1.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/11ty" - } - }, - "node_modules/@11ty/eleventy-img": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@11ty/eleventy-img/-/eleventy-img-0.10.0.tgz", - "integrity": "sha512-9Mi1Wg8qc1gD7TixQtbwa8t0Z4D2hZF0eweYeMHEFr4WGklnSVckUnTJBr0qG+9f+UX7MzUDXbDPPSRCIRdyYw==", - "dev": true, - "dependencies": { - "@11ty/eleventy-cache-assets": "^2.3.0", - "debug": "^4.3.2", - "image-size": "^1.0.0", - "p-queue": "^6.6.2", - "sharp": "^0.29.0", - "short-hash": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/11ty" - } - }, "node_modules/@babel/helper-validator-identifier": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", @@ -262,22 +229,6 @@ "node": ">= 8" } }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -398,26 +349,6 @@ "node": ">= 0.6.0" } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -442,37 +373,18 @@ "node": ">=8" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -600,30 +512,6 @@ "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", "dev": true }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -707,12 +595,6 @@ "fsevents": "~2.3.1" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "node_modules/chroma-js": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.1.2.tgz", @@ -733,23 +615,13 @@ "wrap-ansi": "^6.2.0" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" + "node": ">=0.8" } }, "node_modules/color-convert": { @@ -770,14 +642,35 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", + "node_modules/columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", "dev": true, "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "node_modules/columnify/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/columnify/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/commander": { @@ -888,12 +781,6 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, "node_modules/constantinople": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", @@ -913,12 +800,6 @@ "node": ">= 0.6" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, "node_modules/cross-env": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", @@ -984,25 +865,13 @@ "node": ">=0.10.0" } }, - "node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" + "clone": "^1.0.2" } }, "node_modules/del": { @@ -1023,12 +892,6 @@ "node": ">=0.10.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, "node_modules/depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1053,18 +916,6 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/dev-ip": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", @@ -1180,15 +1031,6 @@ "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/engine.io": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", @@ -1333,15 +1175,6 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -1438,40 +1271,6 @@ "node": ">=8" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, "node_modules/follow-redirects": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", @@ -1501,12 +1300,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -1547,69 +1340,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1633,12 +1363,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "dev": true - }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -1835,18 +1559,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "node_modules/hash-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hash-string/-/hash-string-1.0.0.tgz", - "integrity": "sha1-w/oV8Hjd0WvBULQXb95wkWIPLH8=", - "dev": true - }, "node_modules/html-entities": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", @@ -1903,39 +1615,26 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/image-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", - "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", + "node_modules/imagickal": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/imagickal/-/imagickal-5.0.1.tgz", + "integrity": "sha512-aoo+7q14odsdMzvHkbbvV4J7yxRHncUBbgsRjIpzKfWZPgx/aENuN35nAxZ1JQ8uhea7l2DOzm6brSz6qubs2g==", "dev": true, "dependencies": { - "queue": "6.0.2" - }, - "bin": { - "image-size": "bin/image-size.js" + "bluebird": "^3.3.4", + "debug": "^3.1.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.x.x" + } + }, + "node_modules/imagickal/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" } }, "node_modules/immutable": { @@ -1988,12 +1687,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2581,13 +2274,13 @@ "node": ">= 0.6" } }, - "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2629,12 +2322,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/moo": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", @@ -2675,12 +2362,6 @@ "npm": ">=1.4.0" } }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, "node_modules/negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -2696,39 +2377,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node_modules/node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "dev": true, - "dependencies": { - "semver": "^5.4.1" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/node-addon-api": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.1.0.tgz", - "integrity": "sha512-Zz1o1BDX2VtduiAt6kgiUl8jX1Vm3NMboljFYKQJ6ee8AGfiTvM2mlZFI3xPbqjs80rCQgiVJI/DjQ/1QJ0HwA==", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==", - "dev": true, - "engines": { - "node": "4.x || >=6.0.0" - } - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -2753,27 +2401,6 @@ "node": ">=0.10.0" } }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nunjucks": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", @@ -2847,15 +2474,6 @@ "node": ">=4" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2883,32 +2501,47 @@ "node": ">=8" } }, - "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "node_modules/p-memoize": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/p-memoize/-/p-memoize-6.0.1.tgz", + "integrity": "sha512-DG0wxA5fIYor0ypRltebDEZs45ZFRvgztFGv/+glYMdUCIaI9eZKIsNJ2IVihw6LYVUgfhIHtPG5XUgvN+pLtQ==", "dev": true, "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sindresorhus/p-memoize?sponsor=1" + } + }, + "node_modules/p-queue": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.1.0.tgz", + "integrity": "sha512-V+0vPJbhYkBqknPp0qnaz+dWcj8cNepfXZcsVIVEHPbFQXMPwrzCNIiM4FoxGtwHXtPzVCPHDvqCr1YrOJX2Gw==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.7", + "p-timeout": "^5.0.0" + }, + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.0.1.tgz", + "integrity": "sha512-iIxgiUu9dGmC9y234OT0scvFEoH/RZdslZrNJP/50wIg4ufqQlFv5DddQQ62kZ9ZAxS0cfwMu3Ewf98Oe6QlGg==", "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -2935,12 +2568,12 @@ } }, "node_modules/parse-ms": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", - "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, "node_modules/parseqs": { @@ -3101,33 +2734,6 @@ "npm": ">=1.0.0" } }, - "node_modules/prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", - "dev": true, - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/pretty": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz", @@ -3143,18 +2749,18 @@ } }, "node_modules/pretty-ms": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", - "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", "dev": true, "dependencies": { - "parse-ms": "^0.1.0" - }, - "bin": { - "pretty-ms": "cli.js" + "parse-ms": "^2.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/prismjs": { @@ -3163,12 +2769,6 @@ "integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==", "dev": true }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -3320,16 +2920,6 @@ "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", "dev": true }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/qs": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", @@ -3339,15 +2929,6 @@ "node": ">=0.6" } }, - "node_modules/queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.3" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3392,42 +2973,6 @@ "node": ">= 0.8" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "node_modules/readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -3595,12 +3140,6 @@ "npm": ">=2.0.0" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3836,29 +3375,6 @@ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, - "node_modules/sharp": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.29.1.tgz", - "integrity": "sha512-DpgdAny9TuS+oWCQ7MRS8XyY9x6q1+yW3a5wNx0J3HrGuB/Jot/8WcT+lElHY9iJu2pwtegSGxqMaqFiMhs4rQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "color": "^4.0.1", - "detect-libc": "^1.0.3", - "node-addon-api": "^4.1.0", - "prebuild-install": "^6.1.4", - "semver": "^7.3.5", - "simple-get": "^3.1.0", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=12.13.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3880,67 +3396,12 @@ "node": ">=8" } }, - "node_modules/short-hash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/short-hash/-/short-hash-1.0.0.tgz", - "integrity": "sha1-P0kdco/Md37GBbuvf4PyNxL0IFA=", - "dev": true, - "dependencies": { - "hash-string": "^1.0.0" - } - }, "node_modules/sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dev": true, - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, "node_modules/slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -4107,15 +3568,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -4151,15 +3603,6 @@ "node": ">=0.10.0" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4181,48 +3624,6 @@ "node": ">=0.10.0" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4332,6 +3733,30 @@ "node": ">=0.8.0" } }, + "node_modules/time-require/node_modules/parse-ms": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", + "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/time-require/node_modules/pretty-ms": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", + "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "dev": true, + "dependencies": { + "parse-ms": "^0.1.0" + }, + "bin": { + "pretty-ms": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/time-require/node_modules/strip-ansi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", @@ -4386,18 +3811,6 @@ "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=", "dev": true }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/ua-parser-js": { "version": "0.7.28", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", @@ -4463,12 +3876,6 @@ "node": ">= 0.8" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -4493,6 +3900,15 @@ "node": ">=0.10.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4514,58 +3930,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/with": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", @@ -4738,33 +4102,6 @@ "valid-url": "^1.0.9" } }, - "@11ty/eleventy-cache-assets": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@11ty/eleventy-cache-assets/-/eleventy-cache-assets-2.3.0.tgz", - "integrity": "sha512-W8tvO00GlWaKt3ccpEStaUBoj9BE3EgzuD8uYChCfYbN2Q4HkEItkiapvIJT0zJwAwoMfnSq6VHPLScYlX2XCg==", - "dev": true, - "requires": { - "debug": "^4.3.1", - "flat-cache": "^3.0.4", - "node-fetch": "^2.6.1", - "p-queue": "^6.6.2", - "short-hash": "^1.0.0" - } - }, - "@11ty/eleventy-img": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@11ty/eleventy-img/-/eleventy-img-0.10.0.tgz", - "integrity": "sha512-9Mi1Wg8qc1gD7TixQtbwa8t0Z4D2hZF0eweYeMHEFr4WGklnSVckUnTJBr0qG+9f+UX7MzUDXbDPPSRCIRdyYw==", - "dev": true, - "requires": { - "@11ty/eleventy-cache-assets": "^2.3.0", - "debug": "^4.3.2", - "image-size": "^1.0.0", - "p-queue": "^6.6.2", - "sharp": "^0.29.0", - "short-hash": "^1.0.0" - } - }, "@babel/helper-validator-identifier": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", @@ -4878,22 +4215,6 @@ "picomatch": "^2.0.4" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4993,12 +4314,6 @@ "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, "base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -5017,36 +4332,18 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5164,16 +4461,6 @@ "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", "dev": true }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -5237,12 +4524,6 @@ "readdirp": "~3.5.0" } }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "chroma-js": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.1.2.tgz", @@ -5263,22 +4544,12 @@ "wrap-ansi": "^6.2.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, - "color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "dev": true, - "requires": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5294,14 +4565,31 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", "dev": true, "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "commander": { @@ -5401,12 +4689,6 @@ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, "constantinople": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", @@ -5423,12 +4705,6 @@ "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", "dev": true }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, "cross-env": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", @@ -5470,21 +4746,15 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "mimic-response": "^2.0.0" + "clone": "^1.0.2" } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, "del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", @@ -5500,12 +4770,6 @@ "rimraf": "^2.2.8" } }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -5524,12 +4788,6 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, "dev-ip": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", @@ -5622,15 +4880,6 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "dev": true }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "engine.io": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.5.0.tgz", @@ -5756,12 +5005,6 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true - }, "extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", @@ -5845,33 +5088,6 @@ "path-exists": "^4.0.0" } }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, "follow-redirects": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", @@ -5884,12 +5100,6 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -5920,59 +5130,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -5990,12 +5147,6 @@ "has-symbols": "^1.0.1" } }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "dev": true - }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -6146,18 +5297,6 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "hash-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hash-string/-/hash-string-1.0.0.tgz", - "integrity": "sha1-w/oV8Hjd0WvBULQXb95wkWIPLH8=", - "dev": true - }, "html-entities": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.2.tgz", @@ -6204,19 +5343,25 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "image-size": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.0.tgz", - "integrity": "sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw==", + "imagickal": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/imagickal/-/imagickal-5.0.1.tgz", + "integrity": "sha512-aoo+7q14odsdMzvHkbbvV4J7yxRHncUBbgsRjIpzKfWZPgx/aENuN35nAxZ1JQ8uhea7l2DOzm6brSz6qubs2g==", "dev": true, "requires": { - "queue": "6.0.2" + "bluebird": "^3.3.4", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "immutable": { @@ -6263,12 +5408,6 @@ "is-windows": "^1.0.1" } }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -6726,10 +5865,10 @@ "mime-db": "1.47.0" } }, - "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, "minimatch": { @@ -6759,12 +5898,6 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "moo": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", @@ -6796,12 +5929,6 @@ "integrity": "sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==", "dev": true }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "dev": true - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -6814,35 +5941,6 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, - "node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "dev": true, - "requires": { - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-addon-api": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.1.0.tgz", - "integrity": "sha512-Zz1o1BDX2VtduiAt6kgiUl8jX1Vm3NMboljFYKQJ6ee8AGfiTvM2mlZFI3xPbqjs80rCQgiVJI/DjQ/1QJ0HwA==", - "dev": true - }, - "node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==", - "dev": true - }, "nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", @@ -6858,24 +5956,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nunjucks": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.3.tgz", @@ -6926,12 +6006,6 @@ "is-wsl": "^1.1.0" } }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -6950,24 +6024,30 @@ "p-limit": "^2.2.0" } }, - "p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "p-memoize": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/p-memoize/-/p-memoize-6.0.1.tgz", + "integrity": "sha512-DG0wxA5fIYor0ypRltebDEZs45ZFRvgztFGv/+glYMdUCIaI9eZKIsNJ2IVihw6LYVUgfhIHtPG5XUgvN+pLtQ==", "dev": true, "requires": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" + "mimic-fn": "^4.0.0" + } + }, + "p-queue": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.1.0.tgz", + "integrity": "sha512-V+0vPJbhYkBqknPp0qnaz+dWcj8cNepfXZcsVIVEHPbFQXMPwrzCNIiM4FoxGtwHXtPzVCPHDvqCr1YrOJX2Gw==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.7", + "p-timeout": "^5.0.0" } }, "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.0.1.tgz", + "integrity": "sha512-iIxgiUu9dGmC9y234OT0scvFEoH/RZdslZrNJP/50wIg4ufqQlFv5DddQQ62kZ9ZAxS0cfwMu3Ewf98Oe6QlGg==", + "dev": true }, "p-try": { "version": "2.2.0", @@ -6987,9 +6067,9 @@ } }, "parse-ms": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", - "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", "dev": true }, "parseqs": { @@ -7110,27 +6190,6 @@ "is-number-like": "^1.0.3" } }, - "prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", - "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, "pretty": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz", @@ -7143,12 +6202,12 @@ } }, "pretty-ms": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", - "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", "dev": true, "requires": { - "parse-ms": "^0.1.0" + "parse-ms": "^2.1.0" } }, "prismjs": { @@ -7157,12 +6216,6 @@ "integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -7314,31 +6367,12 @@ "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "qs": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", "dev": true }, - "queue": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", - "dev": true, - "requires": { - "inherits": "~2.0.3" - } - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7363,41 +6397,6 @@ "unpipe": "1.0.0" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, "readdirp": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", @@ -7530,12 +6529,6 @@ "symbol-observable": "1.0.1" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7744,22 +6737,6 @@ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, - "sharp": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.29.1.tgz", - "integrity": "sha512-DpgdAny9TuS+oWCQ7MRS8XyY9x6q1+yW3a5wNx0J3HrGuB/Jot/8WcT+lElHY9iJu2pwtegSGxqMaqFiMhs4rQ==", - "dev": true, - "requires": { - "color": "^4.0.1", - "detect-libc": "^1.0.3", - "node-addon-api": "^4.1.0", - "prebuild-install": "^6.1.4", - "semver": "^7.3.5", - "simple-get": "^3.1.0", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -7775,53 +6752,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "short-hash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/short-hash/-/short-hash-1.0.0.tgz", - "integrity": "sha1-P0kdco/Md37GBbuvf4PyNxL0IFA=", - "dev": true, - "requires": { - "hash-string": "^1.0.0" - } - }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", "dev": true }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true - }, - "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", - "dev": true, - "requires": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "requires": { - "is-arrayish": "^0.3.1" - } - }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -7976,15 +6912,6 @@ } } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -8011,12 +6938,6 @@ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8032,44 +6953,6 @@ "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", "dev": true }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8157,6 +7040,21 @@ "strip-ansi": "~0.1.0" } }, + "parse-ms": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", + "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", + "dev": true + }, + "pretty-ms": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", + "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", + "dev": true, + "requires": { + "parse-ms": "^0.1.0" + } + }, "strip-ansi": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", @@ -8198,15 +7096,6 @@ "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=", "dev": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, "ua-parser-js": { "version": "0.7.28", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", @@ -8244,12 +7133,6 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -8268,6 +7151,15 @@ "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", "dev": true }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8283,48 +7175,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, "with": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", diff --git a/.docs/package.json b/.docs/package.json index fff70e1..b3cdc9d 100644 --- a/.docs/package.json +++ b/.docs/package.json @@ -21,10 +21,15 @@ "homepage": "https://github.com/sbrl/Minetest-WorldEditAdditions#readme", "devDependencies": { "@11ty/eleventy": "^0.12.1", - "@11ty/eleventy-img": "^0.10.0", "chroma-js": "^2.1.2", + "columnify": "^1.5.4", + "debug": "^4.3.2", + "imagickal": "^5.0.1", "markdown-it-prism": "^2.2.1", - "phin": "^3.6.0" + "p-memoize": "^6.0.1", + "p-queue": "^7.1.0", + "phin": "^3.6.0", + "pretty-ms": "^7.0.1" }, "dependencies": { "html-entities": "^2.3.2" From 2aa15116e2750dc960dd8482151e6b648de559c8 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 17 Oct 2021 03:04:50 +0100 Subject: [PATCH 08/24] docs: Apparently some web servers don't like % characters in filepaths. Wierd! --- .docs/lib/HTMLPicture.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.docs/lib/HTMLPicture.js b/.docs/lib/HTMLPicture.js index 3cf053a..654ced8 100644 --- a/.docs/lib/HTMLPicture.js +++ b/.docs/lib/HTMLPicture.js @@ -62,7 +62,8 @@ async function srcset(source_image, target_dir, urlpath, format = "__AUTO__", si debug(`SOURCE_SIZE`, source_size, `TARGET_FORMAT`, target_format); let setitems = await Promise.all(sizes.map(async (size) => { - let target_filename = `${source_parsed.name}_${size}.${target_format}`; + let target_filename = `${source_parsed.name}_${size}.${target_format}` + .replace(/%/, "pcent"); let target_current = path.join( target_dir, target_filename From 84741f5cb96f46ba88e1f8336f143aec47072712 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 23 Oct 2021 14:32:44 +0100 Subject: [PATCH 09/24] ellipsoid2: remove todo --- worldeditadditions/lib/ellipsoid2.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/worldeditadditions/lib/ellipsoid2.lua b/worldeditadditions/lib/ellipsoid2.lua index 6a677dd..bf5c90d 100644 --- a/worldeditadditions/lib/ellipsoid2.lua +++ b/worldeditadditions/lib/ellipsoid2.lua @@ -25,7 +25,6 @@ function worldeditadditions.ellipsoid2(pos1, pos2, target_node, hollow) } -- Fetch the nodes in the specified area - -- OPTIMIZE: We should be able to calculate a more efficient box-area here local manip, area = worldedit.manip_helpers.init(pos1, pos2) local data = manip:get_data() From 5fca3e4322f8829c9ef49e862b8b12ade759fc49 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Mon, 25 Oct 2021 15:18:03 +0100 Subject: [PATCH 10/24] Fix bonemeal mod detection to look for the global bonemeal, not whether the bonemeal mod name has been loaded --- CHANGELOG.md | 1 + worldeditadditions_commands/init.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6c3891..b8a5bac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ Note to self: See the bottom of this file for the release template text. - Add `holly` ⇒ `hollytree:sapling` - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) - Cloud wand: Improve chat message text + - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded ## v1.12: The selection tools update (26th June 2021) diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index 491669d..62f59f8 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -55,7 +55,7 @@ dofile(we_c.modpath.."/commands/extra/saplingaliases.lua") dofile(we_c.modpath.."/commands/extra/basename.lua") -- Don't registry the //bonemeal command if the bonemeal mod isn't present -if minetest.get_modpath("bonemeal") then +if minetest.global_exists("bonemeal") then dofile(we_c.modpath.."/commands/bonemeal.lua") dofile(we_c.modpath.."/commands/forest.lua") else From ad789d500a9518ad03f8870496d00738144af026 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 30 Oct 2021 02:46:25 +0100 Subject: [PATCH 11/24] Implement spiral square, but it's untested. It would also be awesome to customise the directional plane upon which the spiral is generated. It might actually be possible without melting my brain I think.... Looking at http://www.mathematische-basteleien.de/spiral.htm it should be possible to go this for circles too. But there's 1 particular function in Vector2.js that we need to port to Vector3.lua that we haven't yet which we'd need for that..... --- worldeditadditions/lib/spiral_square.lua | 83 ++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 worldeditadditions/lib/spiral_square.lua diff --git a/worldeditadditions/lib/spiral_square.lua b/worldeditadditions/lib/spiral_square.lua new file mode 100644 index 0000000..aa0b2fa --- /dev/null +++ b/worldeditadditions/lib/spiral_square.lua @@ -0,0 +1,83 @@ +local wea = worldeditadditions +local Vector3 = wea.Vector3 + +-- ███████ ██████ ██ ██████ █████ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██████ ██ ██████ ███████ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ██ ██ ██ ██ ██ ███████ +-- +-- ███████ ██████ ██ ██ █████ ██████ ███████ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ██ ██ ██ ███████ ██████ █████ +-- ██ ██ ▄▄ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██████ ██████ ██ ██ ██ ██ ███████ +-- ▀▀ + +--- Creates a square spiral that fills the defined region. +-- @param pos1 Vector3 The 1st position of the defined region. +-- @param pos2 Vector3 The 2nd position of the defined region. +-- @param target_node Vector3 The *normalised* name of the node to use to build the square spiral with. +-- @param interval number The distance between the walls of the spiral. +-- @param acceleration=0 number Increate the interval by this number every time we hit a corner of the square spiral. +-- @returns bool,number|string A success boolean value, followed by either the number of the nodes set or an error message string. +function worldeditadditions.spiral_square(pos1, pos2, target_node, interval, acceleration) + if not acceleration then acceleration = 0 end + + pos1, pos2 = Vector3.sort(pos1, pos2) + local volume = pos2:subtract(pos1) + local volume_half = volume:divide(2) + + print("DEBUG:spiral_square | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node) + + + -- Fetch the nodes in the specified area + local manip, area = worldedit.manip_helpers.init(pos1, pos2) + local data = manip:get_data() + + local node_id = minetest.get_content_id(target_node) + + local count = 0 -- The number of nodes replaced + + local centre = pos2:subtract(pos1):floor() + + local pos_current = centre:clone() + local pos_corner_last = pos_current:clone() + local side_length = 0 + local direction = Vector3.new(1, 0, 0) + local side_length_max = interval + + while pos_current:is_contained(pos1, pos2) do + + for y = pos2.y, pos1.y, -1 do + data[area:index(pos_current.x, y, pos_current.z)] = node_id + count = count + 1 + end + + pos_current = pos_current:add(direction) + side_length = side_length + 1 + + if side_length > side_length_max then + side_length_max = side_length_max + interval + acceleration + + if direction.x == 0 and direction.z == 1 then + direction.x = 1 + direction.z = 0 + elseif direction.x == 1 and direction.z == 0 then + direction.x = 0 + direction.z = -1 + elseif direction.x == 0 and direction.z == -1 then + direction.x = -1 + direction.z = 0 + else + direction.x = 0 + direction.z = 1 + end + end + end + + -- Save the modified nodes back to disk & return + worldedit.manip_helpers.finish(manip, data) + + return true, count +end From a3f26200a0fab08483427966e3f8ece9ba4e3976 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sat, 30 Oct 2021 02:47:19 +0100 Subject: [PATCH 12/24] init: call spiral_square --- worldeditadditions/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 2e83be2..8233a7f 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -50,6 +50,7 @@ dofile(wea.modpath.."/lib/hollow.lua") dofile(wea.modpath.."/lib/scale_up.lua") dofile(wea.modpath.."/lib/scale_down.lua") dofile(wea.modpath.."/lib/scale.lua") +dofile(wea.modpath.."/lib/spiral_square.lua") dofile(wea.modpath.."/lib/conv/conv.lua") dofile(wea.modpath.."/lib/erode/erode.lua") dofile(wea.modpath.."/lib/noise/init.lua") From d3a8efb9b8560a25f2002a12b6d5ba0691e738d6 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 31 Oct 2021 15:11:01 +0000 Subject: [PATCH 13/24] Add //spiral2, write glue for square spirals Next up: circular spirals! --- worldeditadditions/lib/spiral_square.lua | 23 +++-- .../commands/spiral2.lua | 83 +++++++++++++++++++ worldeditadditions_commands/init.lua | 1 + 3 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 worldeditadditions_commands/commands/spiral2.lua diff --git a/worldeditadditions/lib/spiral_square.lua b/worldeditadditions/lib/spiral_square.lua index aa0b2fa..4eb2441 100644 --- a/worldeditadditions/lib/spiral_square.lua +++ b/worldeditadditions/lib/spiral_square.lua @@ -28,7 +28,7 @@ function worldeditadditions.spiral_square(pos1, pos2, target_node, interval, acc local volume = pos2:subtract(pos1) local volume_half = volume:divide(2) - print("DEBUG:spiral_square | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node) + print("DEBUG:spiral_square | pos1: "..pos1..", pos2: "..pos2..", target_node: "..target_node, "interval:"..interval..", acceleration: "..acceleration) -- Fetch the nodes in the specified area @@ -39,13 +39,14 @@ function worldeditadditions.spiral_square(pos1, pos2, target_node, interval, acc local count = 0 -- The number of nodes replaced - local centre = pos2:subtract(pos1):floor() + local centre = pos2:subtract(pos1):floor():divide(2):add(pos1) - local pos_current = centre:clone() - local pos_corner_last = pos_current:clone() + local pos_current = centre:clone():floor() local side_length = 0 local direction = Vector3.new(1, 0, 0) - local side_length_max = interval + local side_length_max = interval + 1 + local sides_complete = 0 + -- local sides_acc = 0 while pos_current:is_contained(pos1, pos2) do @@ -57,8 +58,16 @@ function worldeditadditions.spiral_square(pos1, pos2, target_node, interval, acc pos_current = pos_current:add(direction) side_length = side_length + 1 - if side_length > side_length_max then - side_length_max = side_length_max + interval + acceleration + print("DEBUG cpos", pos_current, "side_length", side_length, "side_length_max", side_length_max, "direction", direction) + + if side_length >= side_length_max then + sides_complete = sides_complete + 1 + -- sides_acc = sides_acc + 1 + if sides_complete % 2 == 0 then + -- sides_acc = 0 + side_length_max = side_length_max + interval + acceleration + 1 + end + side_length = 0 if direction.x == 0 and direction.z == 1 then direction.x = 1 diff --git a/worldeditadditions_commands/commands/spiral2.lua b/worldeditadditions_commands/commands/spiral2.lua new file mode 100644 index 0000000..eb94f56 --- /dev/null +++ b/worldeditadditions_commands/commands/spiral2.lua @@ -0,0 +1,83 @@ + +local wea = worldeditadditions +local Vector3 = wea.Vector3 + +worldedit.register_command("spiral2", { + params = "[] [ [ [] ] ]", + description = "Generates a spiral that fills the defined region using the specified replace node. The spiral is either circular (default) or square in shape. The interval specifies the distance between the walls of the spiral, and the acceleration specifies how quickly this value should increase.", + privs = { worldedit = true }, + require_pos = 2, + parse = function(params_text) + if not params_text then return true, "circle", "dirt" end + params_text = wea.trim(params_text) + if params_text == "" then return true, "circle", "dirt" end + + local parts = wea.split_shell(params_text) + + local mode = "circle" + local target_node = "dirt" + local target_node_found = false + local interval = 3 + local acceleration = 0 + + if parts[1] ~= "circle" and parts[1] ~= "square" then + target_node = parts[1] + target_node_found = true + else + mode = parts[1] + table.remove(parts, 1) + end + + if #parts >= 1 and not target_node_found then + target_node = parts[1] + table.remove(parts, 1) + end + if #parts >= 1 then + interval = tonumber(parts[1]) + table.remove(parts, 1) + end + if #parts >= 1 then + acceleration = tonumber(parts[3]) + table.remove(parts, 1) + end + + local target_node_norm = worldedit.normalize_nodename(target_node) + if not target_node_norm then + return false, "Error: Unknown node '"..target_node_norm.."'." + end + + if not interval then + return false, "Error: Invalid interval value. Interval values must be integers." + end + if not acceleration then + return false, "Error: Invalid acceleration value. Acceleration values must be integers." + end + + return true, mode, target_node_norm, interval, acceleration + end, + nodes_needed = function(name) + return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) + end, + func = function(name, mode, target_node, interval, acceleration) + local start_time = wea.get_ms_time() + + local pos1, pos2 = Vector3.sort(worldedit.pos1[name], worldedit.pos2[name]) + + local success, count + + if mode == "circle" then + return false, "Error: Not implemented yet. Coming soon!" + else + success, count = wea.spiral_square( + pos1, pos2, + target_node, + interval, acceleration + ) + if not success then return success, count end + end + local time_taken = wea.get_ms_time() - start_time + + minetest.log("action", name .. " used //spiral at "..pos1.." - "..pos2..", adding " .. count .. " nodes in " .. time_taken .. "s") + return true, count .. " nodes replaced in " .. wea.format.human_time(time_taken) + end +}) diff --git a/worldeditadditions_commands/init.lua b/worldeditadditions_commands/init.lua index 62f59f8..7a41d7f 100644 --- a/worldeditadditions_commands/init.lua +++ b/worldeditadditions_commands/init.lua @@ -35,6 +35,7 @@ dofile(we_c.modpath.."/commands/replacemix.lua") dofile(we_c.modpath.."/commands/scale.lua") dofile(we_c.modpath.."/commands/torus.lua") dofile(we_c.modpath.."/commands/walls.lua") +dofile(we_c.modpath.."/commands/spiral2.lua") dofile(we_c.modpath.."/commands/count.lua") From dae59b63db282ad9d63ec2e563fc508ef1024cb4 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 31 Oct 2021 16:41:52 +0000 Subject: [PATCH 14/24] //walls: Prevent crash if not parameters are specified by defaulting to dirt as the replace_node --- CHANGELOG.md | 1 + Chat-Command-Reference.md | 5 +++-- worldeditadditions_commands/commands/walls.lua | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8a5bac..de32dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Note to self: See the bottom of this file for the release template text. - `//replacemix`: Improve error handling to avoid crashes (thanks, Jonathon for reporting via Discord!) - Cloud wand: Improve chat message text - Fix `bonemeal` mod detection to look for the global `bonemeal`, not whether the `bonemeal` mod name has been loaded + - `//walls`: Prevent crash if not parameters are specified by defaulting to `dirt` as the replace_node ## v1.12: The selection tools update (26th June 2021) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index de93b5a..1000ac2 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -146,10 +146,11 @@ Additional examples: ``` -### `//walls []` -Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. +### `//walls [ []]` +Creates vertical walls of `` around the inside edges of the defined region, optionally specifying the thickness thereof. Defaults to a replace node of `dirt` and a wall thickness of 1. ```weacmd +//walls //walls dirt //walls stone //walls goldblock diff --git a/worldeditadditions_commands/commands/walls.lua b/worldeditadditions_commands/commands/walls.lua index f017763..12d6d72 100644 --- a/worldeditadditions_commands/commands/walls.lua +++ b/worldeditadditions_commands/commands/walls.lua @@ -4,11 +4,12 @@ -- ██ ███ ██ ██ ██ ██ ██ ██ -- ███ ███ ██ ██ ███████ ███████ ███████ worldedit.register_command("walls", { - params = " []", + params = "[ []]", description = "Creates vertical walls of around the inside edges of the defined region. Optionally specifies a thickness for the walls to be created (defaults to 1)", privs = { worldedit = true }, require_pos = 2, parse = function(params_text) + if not params_text or params_text == "" then params_text = "dirt" end local parts = worldeditadditions.split_shell(params_text) local target_node From e610eb7a92cce77bdb62d51b4ac04c5f3cde1106 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 31 Oct 2021 16:42:12 +0000 Subject: [PATCH 15/24] //spiral2: fix bugs --- .../commands/spiral2.lua | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/worldeditadditions_commands/commands/spiral2.lua b/worldeditadditions_commands/commands/spiral2.lua index eb94f56..e8efc06 100644 --- a/worldeditadditions_commands/commands/spiral2.lua +++ b/worldeditadditions_commands/commands/spiral2.lua @@ -8,9 +8,9 @@ worldedit.register_command("spiral2", { privs = { worldedit = true }, require_pos = 2, parse = function(params_text) - if not params_text then return true, "circle", "dirt" end + if not params_text then params_text = "" end params_text = wea.trim(params_text) - if params_text == "" then return true, "circle", "dirt" end + if params_text == "" then return true, "circle", "dirt", 3, 0 end local parts = wea.split_shell(params_text) @@ -23,6 +23,7 @@ worldedit.register_command("spiral2", { if parts[1] ~= "circle" and parts[1] ~= "square" then target_node = parts[1] target_node_found = true + table.remove(parts, 1) else mode = parts[1] table.remove(parts, 1) @@ -34,10 +35,16 @@ worldedit.register_command("spiral2", { end if #parts >= 1 then interval = tonumber(parts[1]) + if not interval then + return false, "Error: Invalid interval value '"..parts[1].."'. Interval values must be integers." + end table.remove(parts, 1) end if #parts >= 1 then - acceleration = tonumber(parts[3]) + acceleration = tonumber(parts[1]) + if not acceleration then + return false, "Error: Invalid acceleration value '"..parts[1].."'. Acceleration values must be integers." + end table.remove(parts, 1) end @@ -46,13 +53,6 @@ worldedit.register_command("spiral2", { return false, "Error: Unknown node '"..target_node_norm.."'." end - if not interval then - return false, "Error: Invalid interval value. Interval values must be integers." - end - if not acceleration then - return false, "Error: Invalid acceleration value. Acceleration values must be integers." - end - return true, mode, target_node_norm, interval, acceleration end, nodes_needed = function(name) @@ -66,7 +66,12 @@ worldedit.register_command("spiral2", { local success, count if mode == "circle" then - return false, "Error: Not implemented yet. Coming soon!" + success, count = wea.spiral_circle( + pos1, pos2, + target_node, + interval, acceleration + ) + if not success then return success, count end else success, count = wea.spiral_square( pos1, pos2, From 9d7000baed6124bb33ed523505115c62331d2a84 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 31 Oct 2021 16:59:52 +0000 Subject: [PATCH 16/24] Add circular spirals :D --- worldeditadditions/init.lua | 1 + worldeditadditions/lib/spiral_circle.lua | 86 ++++++++++++++++++++++++ worldeditadditions/utils/vector3.lua | 16 +++++ 3 files changed, 103 insertions(+) create mode 100644 worldeditadditions/lib/spiral_circle.lua diff --git a/worldeditadditions/init.lua b/worldeditadditions/init.lua index 8233a7f..8138a04 100644 --- a/worldeditadditions/init.lua +++ b/worldeditadditions/init.lua @@ -51,6 +51,7 @@ dofile(wea.modpath.."/lib/scale_up.lua") dofile(wea.modpath.."/lib/scale_down.lua") dofile(wea.modpath.."/lib/scale.lua") dofile(wea.modpath.."/lib/spiral_square.lua") +dofile(wea.modpath.."/lib/spiral_circle.lua") dofile(wea.modpath.."/lib/conv/conv.lua") dofile(wea.modpath.."/lib/erode/erode.lua") dofile(wea.modpath.."/lib/noise/init.lua") diff --git a/worldeditadditions/lib/spiral_circle.lua b/worldeditadditions/lib/spiral_circle.lua new file mode 100644 index 0000000..c1da6d8 --- /dev/null +++ b/worldeditadditions/lib/spiral_circle.lua @@ -0,0 +1,86 @@ +local wea = worldeditadditions +local Vector3 = wea.Vector3 + +-- ███████ ██████ ██ ██████ █████ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██████ ██ ██████ ███████ ██ +-- ██ ██ ██ ██ ██ ██ ██ ██ +-- ███████ ██ ██ ██ ██ ██ ██ ███████ +-- +-- ██████ ██ ██████ ██████ ██ ███████ +-- ██ ██ ██ ██ ██ ██ ██ +-- ██ ██ ██████ ██ ██ █████ +-- ██ ██ ██ ██ ██ ██ ██ +-- ██████ ██ ██ ██ ██████ ███████ ███████ + + +--- Creates a circular spiral that fills the defined region. +-- @param pos1 Vector3 The 1st position of the defined region. +-- @param pos2 Vector3 The 2nd position of the defined region. +-- @param target_node Vector3 The *normalised* name of the node to use to build the square spiral with. +-- @param interval_initial number The distance between the walls of the spiral. +-- @param acceleration=0 number Increate the interval by this number every time we hit a corner of the square spiral. +-- @returns bool,number|string A success boolean value, followed by either the number of the nodes set or an error message string. +function worldeditadditions.spiral_circle(pos1, pos2, target_node, interval_initial, acceleration) + if not acceleration then acceleration = 0 end + + pos1, pos2 = Vector3.sort(pos1, pos2) + local volume = pos2:subtract(pos1) + local volume_half = volume:divide(2) + + print("DEBUG:spiral_square | pos1", pos1, "pos2", pos2, "target_node", target_node, "interval_initial:", interval_initial, "acceleration", acceleration) + + interval_initial = interval_initial + 1 + + -- Fetch the nodes in the specified area + local manip, area = worldedit.manip_helpers.init(pos1, pos2) + local data = manip:get_data() + + local node_id = minetest.get_content_id(target_node) + + local count = 0 -- The number of nodes replaced + + local centre = pos2:subtract(pos1):floor():divide(2):add(pos1) + + local pos_current = centre:clone():floor() + local interval = interval_initial + local radius = 1 + local angle = 0 + -- local sides_acc = 0 + + while pos_current:is_contained(pos1, pos2) do + + for y = pos2.y, pos1.y, -1 do + data[area:index( + math.floor(pos_current.x), + y, + math.floor(pos_current.z) + )] = node_id + count = count + 1 + end + + -- print("DEBUG:spiral_circle centre", centre, "bearing", Vector3.fromBearing(angle, 0, radius)) + pos_current = centre:add(Vector3.fromBearing(angle, 0, radius)) + + local circumference_now = 2 * math.pi * radius + local step = (math.pi*2)/(circumference_now*2) + if angle < math.pi then step = step / 10 end + angle = angle + (step) + + local acceleration_constant = 0 + if angle > math.pi / 2 then + acceleration_constant = (interval/angle * acceleration) * step + end + radius = 1 + interval*(angle / (math.pi*2)) + interval = interval_initial + acceleration_constant + + + print("DEBUG cpos", pos_current:multiply(1000):floor():divide(1000), "angle", math.deg(angle), "step", wea.round(math.deg(step), 3), "radius", wea.round(radius, 3), "interval", wea.round(interval, 3), "accel_const", acceleration_constant) + + end + + -- Save the modified nodes back to disk & return + worldedit.manip_helpers.finish(manip, data) + + return true, count +end diff --git a/worldeditadditions/utils/vector3.lua b/worldeditadditions/utils/vector3.lua index 5733279..b860079 100644 --- a/worldeditadditions/utils/vector3.lua +++ b/worldeditadditions/utils/vector3.lua @@ -361,6 +361,22 @@ function Vector3.max(pos1, pos2) ) end +--- Given 2 angles and a length, return a Vector3 pointing in that direction. +-- Consider a sphere, with the 2 angles defining a point on the sphere's surface. +-- This function returns that point as a Vector3. +-- @source https://math.stackexchange.com/a/1881767/221181 +-- @param angle_x number The X angle. +-- @param angle_y number The Y angle. +-- @param length number The radius of the sphere in question. +-- @returns Vector3 The point on the sphere defined by the aforementioned parameters. +function Vector3.fromBearing(angle_x, angle_y, length) + return Vector3.new( -- X and Y swapped + length * math.cos(angle_x), + length * math.sin(angle_x) * math.sin(angle_y), + length * math.sin(angle_x) * math.cos(angle_y) + ) +end + -- ██████ ██████ ███████ ██████ █████ ████████ ██████ ██████ From 21902b851294a13cc86f4c9040aeaed492db942b Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Sun, 31 Oct 2021 17:10:22 +0000 Subject: [PATCH 17/24] //spiral2: update docs --- CHANGELOG.md | 1 + Chat-Command-Reference.md | 15 ++++++++++++++- README.md | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de32dec..04554d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Note to self: See the bottom of this file for the release template text. - Add `//noise2d` for perturbing terrain with multiple different noise functions - Add `//noiseapply2d` for running commands on columns where a noise value is over a threshold - Add `//ellipsoid2` which creates an ellipsoid that fills the defined region + - Add `//spiral2` for creating both square and circular spirals - Use [luacheck](https://github.com/mpeterv/luacheck) to find and fix a large number of bugs and other issues [code quality from now on will be significantly improved] - Multiple commands: Allow using quotes (`"thing"`, `'thing'`) to quote values when splitting - `//layers`: Add optional slope constraint (inspired by [WorldPainter](https://worldpainter.net/)) diff --git a/Chat-Command-Reference.md b/Chat-Command-Reference.md index 1000ac2..1244b8a 100644 --- a/Chat-Command-Reference.md +++ b/Chat-Command-Reference.md @@ -159,6 +159,19 @@ Creates vertical walls of `` around the inside edges of the define ``` +### `//spiral2 [] [ [ [] ] ]` +Generates both square and circular spiral shapes with the given ``. The interval defines the gap between the spiral in nodes, and the acceleration defines by how much the interval should be increased (a value of 1 means 1 node per revolution). + +``` +//spiral2 +//spiral2 circle stone +//spiral2 square +//spiral2 circle +//spiral2 glass 5 +//spiral2 square desert_sand 3 1 +``` + + ## Misc