diff --git a/.gitignore b/.gitignore index 64de864..32b6bec 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ bin dist +build node_modules assets/react diff --git a/assets/svg/atom-2-mac.ico b/assets/svg/atom-2-mac.ico new file mode 100644 index 0000000..be0691a Binary files /dev/null and b/assets/svg/atom-2-mac.ico differ diff --git a/electron-builder.json b/electron-builder.json new file mode 100644 index 0000000..03a5ca0 --- /dev/null +++ b/electron-builder.json @@ -0,0 +1,6 @@ +{ + "npmRebuild": false, + "mac": { + "minimumSystemVersion": "10.11" + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3b8ff19..930695b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "probelab-reimager-app", - "version": "1.4.0-beta", + "version": "1.6.1-dev", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -38,9 +38,9 @@ }, "dependencies": { "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -141,6 +141,37 @@ "prop-types": "^15.7.2" } }, + "@malept/cross-spawn-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.0.tgz", + "integrity": "sha512-GeIK5rfU1Yd7BZJQPTGZMMmcZy5nhRToPXZcjaDwQDRSewdhp648GT2E4dh+L7+Io7AOW6WQ+GR44QSzja4qxg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -165,11 +196,17 @@ "@babel/runtime": "^7.10.5" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true + "@types/cacheable-request": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", + "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } }, "@types/debug": { "version": "4.1.5", @@ -178,9 +215,9 @@ "dev": true }, "@types/fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-B42Sxuaz09MhC3DDeW5kubRcQ5by4iuVQ0cRRWM2lggLzAa/KVom0Aft/208NgMvNQQZ86s5rVcqDdn/SH0/mg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.2.tgz", + "integrity": "sha512-jp0RI6xfZpi5JL8v7WQwpBEQTq63RqW2kxwTZt+m27LcJqQdPVU1yGnT1ZI4EtCDynQQJtIGyQahkiCGCS7e+A==", "dev": true, "requires": { "@types/node": "*" @@ -197,6 +234,21 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", + "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", + "dev": true + }, + "@types/keyv": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", + "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -210,10 +262,19 @@ "integrity": "sha512-m3Nmo/YaDUfYzdCQlxjF5pIy7TNyDTAJhIa//xtHcF0dlgYIBKULKnmloCPtByDxtZXrWV8Pge1AKT6/lRvVWg==", "dev": true }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", - "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "version": "15.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz", + "integrity": "sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -366,21 +427,21 @@ "dev": true }, "app-builder-lib": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.8.1.tgz", - "integrity": "sha512-D/ac1+vuGIAAwEeTtXl8b+qWl7Gz/IQatFyzYl2ocag/7N8LqUjKzZFJJISQPWt6PFDPDH0oCj8/GMh63aV0yw==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.9.1.tgz", + "integrity": "sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A==", "dev": true, "requires": { "7zip-bin": "~5.0.3", "@develar/schema-utils": "~2.6.5", "async-exit-hook": "^2.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "22.8.1", + "builder-util": "22.9.1", "builder-util-runtime": "8.7.2", "chromium-pickle-js": "^0.2.0", - "debug": "^4.2.0", - "ejs": "^3.1.3", - "electron-publish": "22.8.1", + "debug": "^4.3.0", + "ejs": "^3.1.5", + "electron-publish": "22.9.1", "fs-extra": "^9.0.1", "hosted-git-info": "^3.0.5", "is-ci": "^2.0.0", @@ -396,9 +457,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", "dev": true, "requires": { "ms": "2.1.2" @@ -423,22 +484,30 @@ "dev": true }, "hosted-git-info": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.5.tgz", - "integrity": "sha512-i4dpK6xj9BIpVOTboXIlKG9+8HMKggcrMX7WA24xZtKwX0TPelq/rbaS5rCKeNX8sJXZJGdSxpnEGtta+wismQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz", + "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "lru-cache": { @@ -1513,10 +1582,21 @@ "tweetnacl": "^0.14.3" } }, + "bent": { + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/bent/-/bent-7.3.12.tgz", + "integrity": "sha512-T3yrKnVGB63zRuoco/7Ybl7BwwGZR0lceoVG5XmQyMIH9s19SV5m+a8qam4if0zQuAmOQTyPTPmsQBdAorGK3w==", + "dev": true, + "requires": { + "bytesish": "^0.4.1", + "caseless": "~0.12.0", + "is-stream": "^2.0.0" + } + }, "bl": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", - "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -1609,12 +1689,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -1655,12 +1734,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -1688,9 +1761,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -2018,9 +2091,9 @@ "dev": true }, "builder-util": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.8.1.tgz", - "integrity": "sha512-LZG+E1xszMdut5hL5h7RkJQ7yOsQqdhJYgn1wvOP7MmF3MoUPRNDiRodLpYiWlaqZmgYhcfaipR/Mb8F/RqK8w==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.9.1.tgz", + "integrity": "sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw==", "dev": true, "requires": { "7zip-bin": "~5.0.3", @@ -2030,7 +2103,7 @@ "bluebird-lst": "^1.0.9", "builder-util-runtime": "8.7.2", "chalk": "^4.1.0", - "debug": "^4.2.0", + "debug": "^4.3.0", "fs-extra": "^9.0.1", "is-ci": "^2.0.0", "js-yaml": "^3.14.0", @@ -2040,12 +2113,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -2075,9 +2147,9 @@ "dev": true }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.0.tgz", + "integrity": "sha512-jjO6JD2rKfiZQnBoRzhRTbXjHLGLfH+UtGkWLc/UXAh/rzZMyjbgn0NcfFpqT8nd1kTtFnDiJcrIFkq4UKeJVg==", "dev": true, "requires": { "ms": "2.1.2" @@ -2101,20 +2173,22 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "ms": { @@ -2140,9 +2214,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -2167,12 +2241,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -2189,6 +2263,12 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "bytesish": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/bytesish/-/bytesish-0.4.4.tgz", + "integrity": "sha512-i4uu6M4zuMUiyfZN4RU2+i9+peJh//pXhd9x1oSe1LBkZ3LEbCoygu8W0bXTukU1Jme2txKuotpCZRaC3FLxcQ==", + "dev": true + }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -2206,6 +2286,12 @@ "unset-value": "^1.0.0" } }, + "cacheable-lookup": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz", + "integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==", + "dev": true + }, "cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -2363,24 +2449,24 @@ } }, "cli-boxes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", - "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "dev": true }, "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "restore-cursor": "^3.1.0" } }, "cli-spinners": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.3.0.tgz", - "integrity": "sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz", + "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==", "dev": true }, "cliui": { @@ -2459,12 +2545,12 @@ } }, "color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", - "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", "requires": { "color-convert": "^1.9.1", - "color-string": "^1.5.2" + "color-string": "^1.5.4" } }, "color-convert": { @@ -2481,9 +2567,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", - "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz", + "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -2965,13 +3051,13 @@ } }, "dmg-builder": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.8.1.tgz", - "integrity": "sha512-WeGom1moM00gBII6swljl4DQGrlJuEivoUhOmh8U9p1ALgeJL+EiTHbZFERlj8Ejy62xUUjURV+liOxUKmJFWg==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.9.1.tgz", + "integrity": "sha512-jc+DAirqmQrNT6KbDHdfEp8D1kD0DBTnsLhwUR3MX+hMBun5bT134LQzpdK0GKvd22GqF8L1Cz/NOgaVjscAXQ==", "dev": true, "requires": { - "app-builder-lib": "22.8.1", - "builder-util": "22.8.1", + "app-builder-lib": "22.9.1", + "builder-util": "22.9.1", "fs-extra": "^9.0.1", "iconv-lite": "^0.6.2", "js-yaml": "^3.14.0", @@ -3006,13 +3092,21 @@ } }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "universalify": { @@ -3030,9 +3124,9 @@ "dev": true }, "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { "is-obj": "^2.0.0" @@ -3076,18 +3170,18 @@ } }, "ejs": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz", - "integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz", + "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==", "dev": true, "requires": { "jake": "^10.6.1" } }, "electron": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/electron/-/electron-9.1.2.tgz", - "integrity": "sha512-xEYadr3XqIqJ4ktBPo0lhzPdovv4jLCpiUUGc2M1frUhFhwqXokwhPaTUcE+zfu5+uf/ONDnQApwjzznBsRrgQ==", + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-10.1.5.tgz", + "integrity": "sha512-fys/KnEfJq05TtMij+lFvLuKkuVH030CHYx03iZrW5DNNLwjE6cW3pysJ420lB0FRSfPjTHBMu2eVCf5TG71zQ==", "dev": true, "requires": { "@electron/get": "^1.0.1", @@ -3096,25 +3190,25 @@ } }, "electron-builder": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.8.1.tgz", - "integrity": "sha512-Hs7KTMq1rGSvT0fwGKXrjbLiJkK6sAKDQooUSwklOkktUgWi4ATjlP0fVE3l8SmS7zcLoww2yDZonSDqxEFhaQ==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.9.1.tgz", + "integrity": "sha512-GXPt8l5Mxwm1QKYopUM6/Tdh9W3695G6Ax+IFyj5pQ51G4SD5L1uq4/RkPSsOgs3rP7jNSV6g6OfDzdtVufPdA==", "dev": true, "requires": { "@types/yargs": "^15.0.5", - "app-builder-lib": "22.8.1", + "app-builder-lib": "22.9.1", "bluebird-lst": "^1.0.9", - "builder-util": "22.8.1", + "builder-util": "22.9.1", "builder-util-runtime": "8.7.2", "chalk": "^4.1.0", - "dmg-builder": "22.8.1", + "dmg-builder": "22.9.1", "fs-extra": "^9.0.1", "is-ci": "^2.0.0", "lazy-val": "^1.0.4", "read-config-file": "6.0.0", "sanitize-filename": "^1.6.3", - "update-notifier": "^4.1.0", - "yargs": "^15.4.1" + "update-notifier": "^4.1.1", + "yargs": "^16.0.3" }, "dependencies": { "ansi-regex": { @@ -3124,21 +3218,14 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -3150,14 +3237,14 @@ } }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.3.tgz", + "integrity": "sha512-Gj3QHTkVMPKqwP3f7B4KPkBZRMR9r4rfi5bXFpg1a+Svvj8l7q5CnkBkVQzfxT5DFSsGk2+PascOgL0JYkL2kw==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "color-convert": { @@ -3181,16 +3268,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "fs-extra": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", @@ -3209,12 +3286,6 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3222,21 +3293,23 @@ "dev": true }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -3258,9 +3331,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3273,9 +3346,9 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -3283,34 +3356,32 @@ "strip-ansi": "^6.0.0" } }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", + "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.2", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", + "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "dev": true } } }, @@ -3325,12 +3396,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "fs-extra": { @@ -3352,13 +3423,21 @@ "dev": true }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "ms": { @@ -3401,9 +3480,9 @@ } }, "electron-packager": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.0.0.tgz", - "integrity": "sha512-J0yQP7/fKPkjxo9Yz5+vsQVig0dBbSXW8LQYA1pvNMvi+bL00hfI2SAyORP6EU7XaeiXGUIBSG2Px01EkKfGCw==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.1.0.tgz", + "integrity": "sha512-THNm4bz1DfvR9f0g51+NjuAYELflM8+1vhQ/iv/G8vyZNKzSMuFd5doobngQKq3rRsLdPNZVnGqDdgS884d7Og==", "dev": true, "requires": { "@electron/get": "^1.6.0", @@ -3422,22 +3501,16 @@ "rcedit": "^2.0.0", "resolve": "^1.1.6", "semver": "^7.1.3", - "yargs-parser": "^18.0.0" + "yargs-parser": "^19.0.1" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "extract-zip": { @@ -3465,9 +3538,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -3480,13 +3553,21 @@ "dev": true }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "ms": { @@ -3508,26 +3589,22 @@ "dev": true }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-19.0.4.tgz", + "integrity": "sha512-eXeQm7yXRjPFFyf1voPkZgXQZJjYfjgQUmGPbD2TLtZeIYzvacgWX7sQ5a1HsRgVP+pfKAkRZDNtTGev4h9vhw==", + "dev": true } } }, "electron-publish": { - "version": "22.8.1", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.8.1.tgz", - "integrity": "sha512-zqI66vl7j1CJZJ60J+1ez1tQNQeuqVspW44JvYDa5kZbM5wSFDAJFMK9RWHOqRF1Ezd4LDeiBa4aeTOwOt9syA==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz", + "integrity": "sha512-ducLjRJLEeU87FaTCWaUyDjCoLXHkawkltP2zqS/n2PyGke54ZIql0tBuUheht4EpR8AhFbVJ11spSn1gy8r6w==", "dev": true, "requires": { "@types/fs-extra": "^9.0.1", "bluebird-lst": "^1.0.9", - "builder-util": "22.8.1", + "builder-util": "22.9.1", "builder-util-runtime": "8.7.2", "chalk": "^4.1.0", "fs-extra": "^9.0.1", @@ -3536,12 +3613,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -3588,20 +3664,22 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } } }, "mime": { @@ -3611,9 +3689,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3628,295 +3706,307 @@ } }, "electron-rebuild": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-1.11.0.tgz", - "integrity": "sha512-cn6AqZBQBVtaEyj5jZW1/LOezZZ22PA1HvhEP7asvYPJ8PDF4i4UFt9be4i9T7xJKiSiomXvY5Fd+dSq3FXZxA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-2.3.2.tgz", + "integrity": "sha512-VLd3iIn65PmYWmvL+nx0oKspbohkDUhCAz8I2EWbMJcOFzWKW1UXJZ+ZG53iEDJFldm9PahE4q2Bx3ns4bdzeQ==", "dev": true, "requires": { + "@malept/cross-spawn-promise": "^1.1.0", "colors": "^1.3.3", "debug": "^4.1.1", "detect-libc": "^1.0.3", - "fs-extra": "^8.1.0", - "node-abi": "^2.11.0", - "node-gyp": "^6.0.1", - "ora": "^3.4.0", - "spawn-rx": "^3.0.0", - "yargs": "^14.2.0" + "fs-extra": "^9.0.1", + "got": "^11.7.0", + "lzma-native": "^6.0.1", + "node-abi": "^2.19.1", + "node-gyp": "^7.1.0", + "ora": "^5.1.0", + "tar": "^6.0.5", + "yargs": "^16.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "@sindresorhus/is": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", + "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==", "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "@szmarczak/http-timer": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", + "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "defer-to-connect": "^2.0.0" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "color-convert": "^2.0.1" } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "cacheable-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", + "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", "dev": true, "requires": { - "ms": "^2.1.1" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^2.0.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "cliui": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.3.tgz", + "integrity": "sha512-Gj3QHTkVMPKqwP3f7B4KPkBZRMR9r4rfi5bXFpg1a+Svvj8l7q5CnkBkVQzfxT5DFSsGk2+PascOgL0JYkL2kw==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "color-name": "~1.1.4" } }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "dev": true, + "requires": { + "ms": "2.1.2" + } }, - "is-fullwidth-code-point": { + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { "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=", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", + "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==", "dev": true }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" } }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "pump": "^3.0.0" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node-abi": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", - "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", + "got": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.0.tgz", + "integrity": "sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ==", "dev": true, "requires": { - "semver": "^5.4.1" + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.1", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" } }, - "node-gyp": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz", - "integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==", - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", - "npmlog": "^4.1.2", - "request": "^2.88.0", - "rimraf": "^2.6.3", - "semver": "^5.7.1", - "tar": "^4.4.12", - "which": "^1.3.1" + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" }, "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true } } }, - "nopt": { + "keyv": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", "dev": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "json-buffer": "3.0.1" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "require-main-filename": { + "p-cancelable": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", + "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", "dev": true }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "lowercase-keys": "^2.0.0" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "ansi-regex": "^5.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true }, "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", + "integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", "dev": true, "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" + "string-width": "^4.2.0", + "y18n": "^5.0.2", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", - "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.3.tgz", + "integrity": "sha512-emOFRT9WVHw03QSvN5qor9QQT9+sw5vwxfYweivSMHTcAXPefwVae2FjO7JJjj8hCE4CzPOPeFM83VwT29HCww==", + "dev": true } } }, @@ -4002,6 +4092,12 @@ "dev": true, "optional": true }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", @@ -4244,9 +4340,9 @@ "dev": true }, "filenamify": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.1.0.tgz", - "integrity": "sha512-KQV/uJDI9VQgN7sHH1Zbk6+42cD6mnQ2HONzkXUfPJ+K2FC8GZ1dpewbbHw0Sz8Tf5k3EVdHVayM4DoAwWlmtg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.2.0.tgz", + "integrity": "sha512-pkgE+4p7N1n7QieOopmn3TqJaefjdWXwEkj2XLZJLKfOgcQKkn11ahvGNgTD8mLggexLiDFQxeTs14xVU22XPA==", "dev": true, "requires": { "filename-reserved-regex": "^2.0.0", @@ -4331,12 +4427,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "fs-extra": { @@ -4549,44 +4645,10 @@ "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", @@ -4838,9 +4900,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-unicode": { @@ -4991,6 +5053,16 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "1.0.0-beta.5.2", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", + "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -5228,6 +5300,12 @@ "is-path-inside": "^3.0.1" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", @@ -5281,6 +5359,12 @@ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -5366,6 +5450,12 @@ "supports-color": "^5.3.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -5543,12 +5633,13 @@ } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { @@ -5557,12 +5648,6 @@ "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -5576,41 +5661,55 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^4.0.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" } }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -5650,6 +5749,35 @@ "yallist": "^2.1.2" } }, + "lzma-native": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-6.0.1.tgz", + "integrity": "sha512-O6oWF0xe1AFvOCjU8uOZBZ/lhjaMNwHfVNaqVMqmoQXlRwBcFWpCAToiZOdXcKVMdo/5s/D0a2QgA5laMErxHQ==", + "dev": true, + "requires": { + "node-addon-api": "^1.6.0", + "node-pre-gyp": "^0.11.0", + "readable-stream": "^2.3.5", + "rimraf": "^2.7.1" + }, + "dependencies": { + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -5811,9 +5939,9 @@ } }, "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "mimic-response": { @@ -5933,6 +6061,12 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", @@ -5988,17 +6122,17 @@ } }, "node-abi": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.18.0.tgz", - "integrity": "sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw==", + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.1.tgz", + "integrity": "sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==", "requires": { "semver": "^5.4.1" } }, "node-addon-api": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.1.tgz", - "integrity": "sha512-YUpjl57P55u2yUaKX5Bgy4t5s6SCNYMg+62XNg+k41aYbBL1NgWrZfcgljR5MxDxHDjzl0qHDNtH6SkW4DXNCA==" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.2.tgz", + "integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg==" }, "node-adodb": { "version": "5.0.3", @@ -6027,6 +6161,100 @@ } } }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "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" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "node-pre-gyp": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", @@ -6161,6 +6389,15 @@ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -6314,70 +6551,86 @@ } }, "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "mimic-fn": "^2.1.0" } }, "ora": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", - "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz", + "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==", "dev": true, "requires": { - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-spinners": "^2.0.0", - "log-symbols": "^2.2.0", - "strip-ansi": "^5.2.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.4.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" } }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } @@ -6414,27 +6667,27 @@ "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "package-json": { @@ -6533,6 +6786,12 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -6653,6 +6912,25 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, + "probelab-reimager": { + "version": "github:bob620/probelab-reimager#1185368b64bf607fa26c2c1009f6df8b6c210456", + "from": "github:bob620/probelab-reimager#dev", + "requires": { + "database-js-adodb": "^1.1.3", + "iconv-lite": "^0.6.2", + "sharp": "^0.25.4" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", + "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -6738,9 +7016,9 @@ "dev": true }, "pupa": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.0.1.tgz", - "integrity": "sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dev": true, "requires": { "escape-goat": "^2.0.0" @@ -6764,6 +7042,12 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -7090,6 +7374,12 @@ "path-parse": "^1.0.6" } }, + "resolve-alpn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", + "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", + "dev": true + }, "resolve-dir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", @@ -7116,12 +7406,12 @@ } }, "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "onetime": "^2.0.0", + "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, @@ -7164,15 +7454,6 @@ "sprintf-js": "^1.1.2" } }, - "rxjs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", - "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -7401,6 +7682,21 @@ "fast-safe-stringify": "^2.0.7" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "shell-quote": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", @@ -7589,17 +7885,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "spawn-rx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spawn-rx/-/spawn-rx-3.0.0.tgz", - "integrity": "sha512-dw4Ryg/KMNfkKa5ezAR5aZe9wNwPdKlnHEXtHOjVnyEDSPQyOpIPPRtcIiu7127SmtHhaCjw21yC43HliW0iIg==", - "dev": true, - "requires": { - "debug": "^2.5.1", - "lodash.assign": "^4.2.0", - "rxjs": "^6.3.1" - } - }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", @@ -7894,14 +8179,14 @@ } }, "tar": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", - "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", + "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", - "minizlib": "^2.1.0", + "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, @@ -7928,9 +8213,9 @@ } }, "minizlib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", - "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -7960,11 +8245,11 @@ } }, "tar-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz", - "integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", + "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", "requires": { - "bl": "^4.0.1", + "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", @@ -7994,9 +8279,9 @@ } }, "term-size": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.0.tgz", - "integrity": "sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true }, "terser": { @@ -8028,14 +8313,6 @@ } } }, - "thermo-reimager": { - "version": "github:bob620/thermo-reimager#6765ea0b225db62eeb34e2e395f87d889cb25a18", - "from": "github:bob620/thermo-reimager#beta", - "requires": { - "database-js-adodb": "^1.1.3", - "sharp": "^0.25.4" - } - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -8164,12 +8441,6 @@ "utf8-byte-length": "^1.0.1" } }, - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", - "dev": true - }, "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -8333,9 +8604,9 @@ } }, "update-notifier": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.0.tgz", - "integrity": "sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "dev": true, "requires": { "boxen": "^4.2.0", @@ -8354,12 +8625,11 @@ }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -8388,16 +8658,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" diff --git a/package.json b/package.json index 8ec6dcf..1148496 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,18 @@ { "name": "probelab-reimager-app", "productName": "Probelab ReImager", - "version": "1.4.0-stable", + "version": "1.6.1-dev", "description": "Visual UI for Probelab ReImager using Electron", "main": "./src/backend/main.js", "scripts": { "start": "electron .", - "build": "node build.js", - "build-prod": "node build.js production", - "rebuild": "electron-rebuild -f", - "test": "echo \"Error: no test specified\" && exit 1", - "compile": "npm run build-prod && node package.js && cd ./bin/unpackaged && npm install --production && npm run rebuild", - "package": "npm run compile && electron-packager ./bin/unpackaged --out ./bin --overwrite", - "win-package": "npm run compile && electron-packager ./bin/unpackaged --out ./bin --overwrite --platform=win32 --arch=x64", - "postpack": "electron-builder --pd \"./bin/Probelab ReImager-win32-x64\"" + "build": "node util/build.js", + "build-prod": "node util/build.js production", + "build-el-capitan": "node util/elcapitain/download.js", + "compile": "node util/compile.js", + "clean": "node util/clean.js", + "distclean": "node util/clean.js distclean", + "test": "echo \"Error: no test specified\" && exit 1" }, "browserify": { "transform": [ @@ -32,7 +31,7 @@ ] }, "build": { - "icon": "./assets/svg/atom-2.ico", + "icon": "./assets/svg/atom-2-mac.ico", "appId": "net.probelab.reimager", "win": { "target": [ @@ -75,7 +74,6 @@ "mac": { "target": [ { - "sign": false, "target": "dmg", "arch": [ "x64" @@ -98,13 +96,15 @@ "babel-preset-react": "^6.24.1", "babelify": "^8.0.0", "bakadux": "^1.1.0", + "bent": "^7.3.12", "browserify": "^16.5.1", "browserify-css": "^0.15.0", - "electron": "^9.1.2", - "electron-builder": "^22.8.0", - "electron-packager": "^15.0.0", - "electron-rebuild": "^1.11.0", + "electron": "10.1.5", + "electron-builder": "^22.9.1", + "electron-packager": "^15.1.0", + "electron-rebuild": "^2.3.2", "envify": "^4.1.0", + "node-gyp": "^7.1.2", "react": "^16.13.1", "react-dom": "^16.13.1", "react-svg": "^11.0.32", @@ -114,7 +114,7 @@ }, "dependencies": { "canvas": "^2.5.0", - "sharp": "^0.25.4", - "thermo-reimager": "github:bob620/thermo-reimager" + "probelab-reimager": "github:bob620/probelab-reimager", + "sharp": "^0.25.4" } } diff --git a/src/backend/children/reimager/child.js b/src/backend/children/reimager/child.js index a9ed58a..364d352 100644 --- a/src/backend/children/reimager/child.js +++ b/src/backend/children/reimager/child.js @@ -1,11 +1,11 @@ -const { CanvasRoot, NodeCanvas } = require('thermo-reimager'); +const {CanvasRoot, NodeCanvas} = require('probelab-reimager'); const ThermoWatcher = require('../thermowatcher.js'); const Communications = require('../../communications.js'); const Functions = require('./functions.js'); class Child { - constructor(canvas, comms=process) { + constructor(canvas, comms = process) { this.data = { watchedDirs: new Map(), comms: new Communications(comms), @@ -20,8 +20,9 @@ class Child { this.data.comms.on('watchDir', this.watchDir.bind(this)); this.data.comms.on('writeImage', this.writeImage.bind(this)); - canvas.init().then(() => { - this.data.comms.send('ready'); + canvas.init().then(async () => { + await this.data.comms.send('ready'); + this.data.log = this.data.comms.log; }); } @@ -30,10 +31,15 @@ class Child { } async getDir({uri}) { - return (await Functions.getDir(uri, this.data.canvas)).map(thermo => thermo.serialize()); + this.data.log.info('Getting directory...'); + const thermos = (await Functions.getDir(uri, this.data.canvas)).map(thermo => thermo.serialize()); + + this.data.log.info('Returning thermos from directory'); + return thermos; } - async getImages({uri, uuids={}}) { + async getImages({uri, uuids = {}}) { + this.data.log.info('Getting images...'); return (await Functions.getImages(uri, this.data.canvas)).map(thermo => { const uuid = uuids[thermo.data.files.entry]; thermo.data.uuid = uuid ? uuid : thermo.data.uuid; @@ -41,7 +47,10 @@ class Child { }); } - async processImage({uri, uuid, operations, settings}, returnThermo=false) { + async processImage({uri, uuid, operations, settings}, returnThermo = false) { + this.data.log.info(`Processing image (${uuid}) ${uri}`); + this.data.log.info(`operations: ${operations.map(e => e.command).join(', ')}`); + settings = Functions.sanitizeSettings(settings); for (let i = 0; i < operations.length; i++) { @@ -51,18 +60,31 @@ class Child { } const tempThermos = await Functions.getImages(uri.split('/').slice(0, -1).join('/') + '/', this.data.canvas); - if (tempThermos === undefined) throw {code: 0, message: 'No Thermo found'}; + if (tempThermos === undefined) { + this.data.log.info(`Unable to find Thermo`); + throw {code: 0, message: 'No Thermo found'}; + } + this.data.log.info(`${tempThermos.length} Thermos found`); for (const thermo of tempThermos) { if (thermo.data.files.entry === uri) { thermo.data.uuid = uuid ? uuid : thermo.data.uuid; - for (const {command, args} of operations) - await thermo[command](...args, settings); + for (const {command, args} of operations) { + this.data.log.info(`Running ${command}(${args.join(', ')})`); + try { + await thermo[command](...args, settings); + } catch(err) { + this.data.log.error(err); + console.log(err); + throw {code: 0, message: 'RIP'}; + } + } if (returnThermo) return thermo; + this.data.log.info(`Serializing thermo for transport...`); return { data: thermo.serialize(), image: await thermo.toUrl(settings) @@ -70,10 +92,12 @@ class Child { } } + this.data.log.info(`Unable to find Thermo matching`); throw {code: 0, message: 'No Thermo found'}; } async unwatchDir({uri}) { + this.data.log.info('Unwatching directory'); const watcher = this.data.watchedDirs.get(uri); if (watcher) { watcher.unwatch(); @@ -83,6 +107,7 @@ class Child { async watchDir({uri}) { if (!this.data.watchedDirs.has(uri)) { + this.data.log.info('Watching directory'); const watcher = new ThermoWatcher(uri); watcher.on('close', uri => { @@ -96,6 +121,7 @@ class Child { } async writeImage({uri, uuid, operations, settings}) { + this.data.log.info('Processing image...'); const thermo = await this.processImage( { uri, @@ -104,7 +130,10 @@ class Child { }, true ); + + this.data.log.info('Writing image...'); await thermo.write(Functions.sanitizeSettings(settings)); + this.data.log.info('Image written'); } } diff --git a/src/backend/children/reimager/functions.js b/src/backend/children/reimager/functions.js index 73d3593..172844f 100644 --- a/src/backend/children/reimager/functions.js +++ b/src/backend/children/reimager/functions.js @@ -1,6 +1,6 @@ const fs = require('fs'); const fsPromise = fs.promises; -const {PointShoot, ExtractedMap, constants, JeolImage, PFEImage, getPFEExpectedImages} = require('thermo-reimager'); +const {PointShoot, ExtractedMap, constants, JeolImage, PFEImage, getPFEExpectedImages} = require('probelab-reimager'); const appConstants = require('../../../../constants.json'); @@ -86,40 +86,32 @@ const Functions = { return settings; }, getDir: async (dirUri, canvas) => { - try { - const directory = await fsPromise.readdir(dirUri, {withFileTypes: true}); - const files = (await Functions.getImages(dirUri + '/', canvas)).filter(i => i); - return files.concat((await Promise.all(directory.map(dir => dir.isDirectory() ? Functions.getImages(dirUri + dir.name + '/', canvas) : []))).flat().filter(i => i)); - } catch(err) { - return []; - } + const directory = await fsPromise.readdir(dirUri, {withFileTypes: true}); + const files = (await Functions.getImages(dirUri + '/', canvas)).filter(i => i); + return files.concat((await Promise.all(directory.map(dir => dir.isDirectory() ? Functions.getImages(dirUri + dir.name + '/', canvas) : []))).flat().filter(i => i)); }, getImages: async (dirUri, canvas) => { - try { - const files = fs.readdirSync(dirUri, {withFileTypes: true}).filter(file => file.isFile()); - let thermos = []; - let extraLayers = []; + const files = fs.readdirSync(dirUri, {withFileTypes: true}).filter(file => file.isFile()); + let thermos = []; + let extraLayers = []; - return (await Promise.all(files.map(file => { - file.uri = dirUri + file.name; - if (file.name.endsWith(constants.extractedMap.fileFormats.LAYER)) { - extraLayers.push(file); - return Promise.all(thermos.map(thermo => thermo.addLayerFile(file.uri))).then(() => undefined); - } else { - const thermo = Functions.createThermo(file, canvas); - if (thermo) { - thermos.push(thermo[0]); - return new Promise(async resolve => { - for (const layer of extraLayers) - await thermo[0].addLayerFile(layer.uri); - resolve(thermo[1]); - }); - } + return (await Promise.all(files.map(file => { + file.uri = dirUri + file.name; + if (file.name.endsWith(constants.extractedMap.fileFormats.LAYER)) { + extraLayers.push(file); + return Promise.all(thermos.map(thermo => thermo.addLayerFile(file.uri))).then(() => undefined); + } else { + const thermo = Functions.createThermo(file, canvas); + if (thermo) { + thermos.push(thermo[0]); + return new Promise(async resolve => { + for (const layer of extraLayers) + await thermo[0].addLayerFile(layer.uri); + resolve(thermo[1]); + }); } - }).flat())).filter(i => i); - } catch(err) { - return []; - } + } + }).flat())).filter(i => i); }, createThermo: (file, canvas, uuid = undefined) => { if (file.isFile()) { diff --git a/src/backend/childspawn.js b/src/backend/childspawn.js index ce57781..1006e4a 100644 --- a/src/backend/childspawn.js +++ b/src/backend/childspawn.js @@ -1,17 +1,59 @@ const fork = require('child_process').fork; +const CreateFakeLog = require('./log.js').CreateFakeLog; const Communications = require('./communications.js'); +const FakeComm = require('./fakecomm.js'); + +class FakeChild { + constructor(childFile, comms) { + this.data = { + child: undefined, + comms, + fakeComm: new FakeComm() + }; + + this.data.comms.setMessageChannel(this.data.fakeComm.endTwo); + this.data.child = new (require(childFile))(this.data.fakeComm.endOne); + } + + on(event, func) { + + } + + kill() { + this.data.child = undefined; + } +} module.exports = class { - constructor(childName='') { + constructor(childName = '', { + commsLog = CreateFakeLog(), + internalLog = CreateFakeLog(), + childDomain = '', + childComm = '' + } = { + commsLog: CreateFakeLog(), + internalLog: CreateFakeLog(), + childDomain: '', + childComm: '' + }) { if (childName === '') throw {code: 2, message: 'No child name specified'}; + internalLog.info(`Creating child '${childName}'...`); + this.data = { childName, process: undefined, - comms: new Communications(), + comms: new Communications(undefined, commsLog), toRun: [], - ready: false + ready: false, + fails: 0, + log: internalLog, + commsLog, + childLog: { + domain: childDomain, + comm: childComm + } }; this.respawn(); @@ -28,42 +70,79 @@ module.exports = class { this.data.process.kill(); } - respawn() { - this.kill(); - this.data.toRun = []; - this.data.process = fork(`${__dirname}/children/${this.data.childName}/child.js`); - this.data.comms.setMessageChannel(this.data.process); + respawn(fakeChild = false) { + if (this.data.process === undefined) { + this.data.process = ''; + + const childFile = `${__dirname}/children/${this.data.childName}/child.js`; - this.data.comms.on('ready', () => { - this.data.ready = true; + this.data.log.info(`Attempting to spawn '${childFile}'${fakeChild ? ' as a fake child' : ''}`); - const toRun = this.data.toRun; + this.kill(); this.data.toRun = []; - for (const {resolve, reject, type, data} of toRun) { - try { - resolve(this.send(type, data)); - } catch(err) { - reject(err); - } + if (fakeChild) { + this.data.process = new FakeChild(childFile, this.data.comms); + } else { + this.data.process = fork(childFile); + this.data.comms.setMessageChannel(this.data.process); } - }); + this.on('ready', async () => { + await this.data.comms.send('logger', { + uuid: this.data.log.uuid, + domain: this.data.childLog.domain, + comm: this.data.childLog.comm + }); - this.data.comms.on('error', () => { - this.data.ready = false; - this.respawn(); - }); + this.data.log.listenOn(this.data.comms); - this.data.comms.on('exit', () => { - this.data.ready = false; - this.respawn(); - }); + this.data.log.info('Spawned and ready'); + this.data.ready = true; + + const toRun = this.data.toRun; + this.data.toRun = []; + + for (const {resolve, reject, type, data} of toRun) { + try { + resolve(this.send(type, data)); + } catch(err) { + reject(err); + } + } + }); + + this.data.process.on('error', err => { + this.data.log.error(err); + this.data.ready = false; + + this.data.process.kill(); + this.data.comms = new Communications(undefined, this.data.commsLog); + + this.data.process = undefined; + this.respawn(); + }); + + this.data.process.on('exit', (code, signal) => { + this.data.log.info(`Exited with code ${code !== null ? code : signal}, respawning...`); + this.data.ready = false; + this.data.fails++; + + this.data.process.kill(); + this.data.comms = new Communications(undefined, this.data.commsLog); + + this.data.process = undefined; + if (this.data.fails > 2) + this.respawn(true); + else + this.respawn(); + }); + } } on(type, callback) { if (typeof callback === 'function') - this.data.comms.on(type, callback) + this.data.comms.on(type, callback); } send(type, data) { diff --git a/src/backend/communications.js b/src/backend/communications.js index ddc07ca..5a8c10d 100644 --- a/src/backend/communications.js +++ b/src/backend/communications.js @@ -1,25 +1,45 @@ const generateUUID = require('./generateuuid.js'); +const {CreateFakeLog, CreateCommLog} = require('./log.js'); module.exports = class { - constructor(messageChannel={on: () => {}, send: () => {}}) { + constructor(messageChannel = { + on: () => { + }, + send: () => { + } + }, log = CreateFakeLog()) { this.data = { messageChannel, messageCallbacks: new Map(), - uuidCallbacks: new Map() + uuidCallbacks: new Map(), + log, + childLog: CreateFakeLog() }; this.setMessageChannel(); + + this.on('logger', async ({uuid, domain, comm}) => { + if (uuid && (domain !== '' || comm !== '')) { + this.data.childLog = await CreateCommLog(domain, this, uuid); + this.data.log = await CreateCommLog(comm, this, uuid); + } + }); + } + + get log() { + return this.data.childLog; } - setMessageChannel(messageChannel=this.data.messageChannel) { + setMessageChannel(messageChannel = this.data.messageChannel) { this.data.messageChannel = messageChannel; for (const {reject} of this.data.uuidCallbacks.values()) - reject({code: 1, message: 'Message channel changed'}); + if (reject !== undefined) + reject({code: 1, message: 'Message channel changed'}); this.data.uuidCallbacks = new Map(); - this.data.messageChannel.on('message', async ({type, data, uuid}, sender=undefined) => { + this.data.messageChannel.on('message', async ({type, data, uuid}, sender = undefined) => { if (type === 'reject') { const callbacks = this.data.uuidCallbacks.get(uuid); this.data.uuidCallbacks.delete(uuid); @@ -34,6 +54,8 @@ module.exports = class { callback.resolve(data); } else try { + this.data.log.info(`Received '${type}' (${uuid})`); + const callbacks = this.data.messageCallbacks.get(type); if (callbacks) if (sender) @@ -41,6 +63,8 @@ module.exports = class { else this.send('resolve', (await Promise.all(callbacks.map(callback => callback(data)))).flat().filter(i => i), uuid); } catch(err) { + this.data.log.error(err); + if (sender) sender.send('reject', err.stack, uuid); else @@ -52,20 +76,37 @@ module.exports = class { on(type, callback) { if (typeof callback === 'function') { const callbacks = this.data.messageCallbacks.get(type); + if (callbacks) callbacks.push(callback); else this.data.messageCallbacks.set(type, [callback]); + + this.data.log.info(`Added '${type}' callback`); } } - send(type, data={}, uuid=generateUUID.v4()) { + send(type, data = {}, uuid = generateUUID.v4()) { + if (!type.startsWith(`log-${this.data.childLog.uuid}-`)) + this.data.log.info(`Sending '${type}' (${uuid})`); + return new Promise((resolve, reject) => { - const callbacks = this.data.uuidCallbacks.get(uuid); - if (callbacks) - callbacks.push({resolve, reject}); - else - this.data.uuidCallbacks.set(uuid, [{resolve, reject}]); + if (type !== 'resolve' || type !== 'reject') { + const callbacks = this.data.uuidCallbacks.get(uuid); + if (callbacks) + callbacks.push({ + resolve: data => { + this.data.log.info(`Received '${type}' (${uuid})`); + resolve(data); + }, reject: err => { + this.data.log.error(err); + reject(err); + } + }); + else + this.data.uuidCallbacks.set(uuid, [{resolve, reject}]); + } + this.data.messageChannel.send({type, data, uuid}); }); } diff --git a/src/backend/createwindow.js b/src/backend/createwindow.js index f2d419c..878fea6 100644 --- a/src/backend/createwindow.js +++ b/src/backend/createwindow.js @@ -1,90 +1,54 @@ -const { BrowserWindow, app, Menu, shell } = require('electron'); +const {BrowserWindow, app, Menu, shell} = require('electron'); const isMac = process.platform === 'darwin'; +const isDev = require('../../package.json').version.includes('dev'); const template = [ - // { role: 'appMenu' } - ...(isMac ? [{ + (isMac ? { label: app.getName(), submenu: [ - { role: 'about' }, - { type: 'separator' }, - { role: 'services' }, - { type: 'separator' }, - { role: 'hide' }, - { role: 'hideothers' }, - { role: 'unhide' }, - { type: 'separator' }, - { role: 'quit' } + {role: 'about'}, + {type: 'separator'}, + {role: 'services'}, + {type: 'separator'}, + {role: 'hide'}, + {role: 'hideothers'}, + {role: 'unhide'}, + {type: 'separator'}, + {role: 'quit'} ] - }] : []), - // { role: 'fileMenu' } + } : {}), { label: 'File', submenu: [ - isMac ? { role: 'close' } : { role: 'quit' } + isMac ? {role: 'close'} : {role: 'quit'} ] }, - // { role: 'editMenu' } -/* { - label: 'Edit', - submenu: [ - { role: 'undo' }, - { role: 'redo' }, - { type: 'separator' }, - { role: 'cut' }, - { role: 'copy' }, - { role: 'paste' }, - ...(isMac ? [ - { role: 'pasteAndMatchStyle' }, - { role: 'delete' }, - { role: 'selectAll' }, - { type: 'separator' }, - { - label: 'Speech', - submenu: [ - { role: 'startspeaking' }, - { role: 'stopspeaking' } - ] - } - ] : [ - { role: 'delete' }, - { type: 'separator' }, - { role: 'selectAll' } - ]) - ] - }, -*/ - - // { role: 'viewMenu' } - { + (isDev ? { label: 'View', submenu: [ - { role: 'reload' }, - { role: 'forcereload' }, - { role: 'toggledevtools' }, - { type: 'separator' }, - { role: 'resetzoom' }, - { role: 'zoomin' }, - { role: 'zoomout' }, - { type: 'separator' }, - { role: 'togglefullscreen' } + {role: 'reload'}, + {role: 'forcereload'}, + {role: 'toggledevtools'}, + {type: 'separator'}, + {role: 'resetzoom'}, + {role: 'zoomin'}, + {role: 'zoomout'}, + {type: 'separator'}, + {role: 'togglefullscreen'} ] - }, - - // { role: 'windowMenu' } + } : {}), { label: 'Window', submenu: [ - { role: 'minimize' }, - { role: 'zoom' }, + {role: 'minimize'}, ...(isMac ? [ - { type: 'separator' }, - { role: 'front' }, - { type: 'separator' }, - { role: 'window' } + {type: 'separator'}, + {role: 'front'}, + {type: 'separator'}, + {role: 'window'} ] : [ - { role: 'close' } + {role: 'close'} ]) ] }, @@ -119,37 +83,34 @@ const template = [ } ]; -const menu = Menu.buildFromTemplate(template); -Menu.setApplicationMenu(menu); +Menu.setApplicationMenu(Menu.buildFromTemplate(template.filter(e => e.label || e.role))); + +module.exports = log => { + log.info('Creating window...'); + if (isDev) + log.info('Window running in Dev mode'); -module.exports = () => { let window = new BrowserWindow({ - minWidth: 1100, - minHeight: 800, + minWidth: 1060, // 1060, down from 1100 + minHeight: 680, // 680, down from 800 backgroundColor: '#4b6584', width: 1100, height: 800, - title: 'Probelab ReImager', + title: `Probelab ReImager${isDev ? ' Dev' : ''}`, webPreferences: { nodeIntegration: true, enableRemoteModule: false }, - show: false, + show: false }); window.loadFile('./assets/index.html'); window.once('ready-to-show', () => { + log.info(`Window ready to show`); window.show(); }); - // Emitted when the window is closed. - window.on('closed', function () { - // Dereference the window object, usually you would store windows - // in an array if your app supports multi windows, this is the time - // when you should delete the corresponding element. - window = null - }); - + log.info(`Window created`); return window; }; \ No newline at end of file diff --git a/src/backend/fakecomm.js b/src/backend/fakecomm.js new file mode 100644 index 0000000..95c2d04 --- /dev/null +++ b/src/backend/fakecomm.js @@ -0,0 +1,43 @@ +module.exports = class FakeComm { + constructor() { + this.data = { + one: { + listeners: new Map() + }, + two: { + listeners: new Map() + } + } + } + + get endOne() { + return { + send: this.send.bind(this, 'two'), + on: this.on.bind(this, 'one') + } + } + + get endTwo() { + return { + send: this.send.bind(this, 'one'), + on: this.on.bind(this, 'two') + } + } + + send(end, message) { + const listeners = this.data[end].listeners.get('message'); + if (listeners) + for (const listener of listeners) + listener(message); + } + + on(end, event, listener) { + if (typeof listener === 'function') { + const listeners = this.data[end].listeners.get(event); + if (listeners) + listeners.push(listener); + else + this.data[end].listeners.set(event, [listener]); + } + } +} \ No newline at end of file diff --git a/src/backend/log.js b/src/backend/log.js new file mode 100644 index 0000000..1c30d87 --- /dev/null +++ b/src/backend/log.js @@ -0,0 +1,125 @@ +const fs = require('fs'); + +const generateUuid = require('./generateuuid.js').v4; + +class Log { + constructor() { + this.data = { + history: [], + uuid: generateUuid() + }; + } + + get uuid() { + return this.data.uuid + } + + listenOn(comm) { + comm.on(`log-${this.data.uuid}-info`, ({domain, message}) => this.info.call(this, domain, message)); + comm.on(`log-${this.data.uuid}-warn`, ({domain, err}) => this.warn.call(this, domain, err)); + comm.on(`log-${this.data.uuid}-error`, ({domain, err}) => this.error.call(this, domain, err)); + comm.on(`log-${this.data.uuid}-serialize`, () => this.serialize.call(this)); + comm.on(`log-${this.data.uuid}-export`, ({uri}) => this.warn.call(this, uri)); + } + + createDomain(domain) { + return { + uuid: this.uuid, + listenOn: this.listenOn.bind(this), + createDomain: this.createDomain.bind(this), + info: this.info.bind(this, domain), + warn: this.warn.bind(this, domain), + error: this.error.bind(this, domain), + serialize: this.serialize.bind(this), + export: this.export.bind(this) + }; + } + + info(domain, message) { + this.data.history.push(`${domain} | ${message}`); + console.info(`${domain} | ${message}`); + } + + warn(domain, err) { + this.data.history.push(`${domain} | ${Object.prototype.toString.call(err) === '[object String]' ? err : `${err.code} - ${err.message}`}`); + console.warn(`${domain} | ${Object.prototype.toString.call(err) === '[object String]' ? err : `${err.code} - ${err.message}`}`); + + if (err.stack) { + this.data.history.push(err.stack); + console.log(err.stack); + } + } + + error(domain, err = new Error()) { + this.data.history.push(`${domain} | ${Object.prototype.toString.call(err) === '[object String]' ? err : `${err.code} - ${err.message}`}`); + console.error(`${domain} | ${Object.prototype.toString.call(err) === '[object String]' ? err : `${err.code} - ${err.message}`}`); + + if (err.stack) { + this.data.history.push(err.stack); + console.log(err.stack); + } + } + + serialize() { + return this.data.history.join('\n'); + } + + export(uri) { + fs.writeFileSync(uri, this.serialize()); + } +} + +function CreateFakeLog() { + return { + uuid: generateUuid(), + listenOn: () => {}, + createDomain: CreateFakeLog, + info: () => { + }, + warn: () => { + }, + error: () => { + }, + serialize: () => { + }, + export: () => { + } + }; +} + +async function CreateCommLog(domain, comm, uuid) { + return { + uuid, + listenOn: (newComm) => { + if (comm !== newComm) { + newComm.on(`log-${this.data.uuid}-info`, this.info.bind(this)); + newComm.on(`log-${this.data.uuid}-warn`, this.warn.bind(this)); + newComm.on(`log-${this.data.uuid}-error`, this.error.bind(this)); + newComm.on(`log-${this.data.uuid}-serialize`, this.serialize.bind(this)); + newComm.on(`log-${this.data.uuid}-export`, this.export.bind(this)); + } + }, + createDomain: CreateCommLog, + info: async message => { + await comm.send(`log-${uuid}-info`, {domain, message}); + }, + warn: async err => { + await comm.send(`log-${uuid}-warn`, {domain, err}); + }, + error: async err => { + await comm.send(`log-${uuid}-error`, {domain, err}); + }, + serialize: async () => { + return await comm.send(`log-${uuid}-serialize`); + }, + export: async uri => { + await comm.send(`log-${uuid}-export`, {uri}); + } + }; +} + +module.exports = { + Log, + CreateFakeLog, + CreateCommLog +}; \ No newline at end of file diff --git a/src/backend/main.js b/src/backend/main.js index bafc0d7..900f59e 100644 --- a/src/backend/main.js +++ b/src/backend/main.js @@ -1,5 +1,24 @@ +const Log = require('./log.js').Log; +const log = new Log(); +const logs = { + main: log.createDomain(' main '), + update: log.createDomain(' update '), + window: log.createDomain(' window '), + updateDir: log.createDomain(' updateDir '), + dirUpdate: log.createDomain(' dirUpdate '), + saveImage: log.createDomain(' saveImage '), + writeImage: log.createDomain(' writeImage'), + loadImage: log.createDomain(' loadImage '), + processDir: log.createDomain(' processDir'), + comms: log.createDomain(' wComms '), + reimagerComms: log.createDomain(' cComms '), + riChild: log.createDomain(' riChild ') +}; + +logs.main.info('Loading Node modules...'); const fs = require('fs'); +logs.main.info('Loading internal modules...'); const createWindow = require('./createwindow.js'); const ChildSpawn = require('./childspawn.js'); const IPC = require('./ipc.js'); @@ -15,13 +34,22 @@ const { const [version] = require('../../package.json').version.split('-'); const constants = require('../../constants.json'); -const { app, dialog, shell } = require('electron'); +const {app, dialog, shell} = require('electron'); -let window = null; -const reimager = new ChildSpawn('reimager'); +logs.main.info('All modules loaded'); +logs.main.info(`Running version ${version} on ${process.getSystemVersion()} ${process.arch}`); + +logs.main.info('Spawning children...'); +const reimager = new ChildSpawn('reimager', { + commsLog: logs.reimagerComms, + internalLog: logs.riChild, + childDomain: ' reimager ', + childComm: ' ccComms ' +}); const relayerer = new ChildSpawn('relayerer'); +logs.main.info('Children spawned'); -const comms = new Communications(); +const comms = new Communications(undefined, logs.comms); let activeDir = ''; let imageMap = new Map(); @@ -30,20 +58,29 @@ let uuidMap = new Map(); let entryMap = new Map(); let savedMap = new Map(); +let window = null; //app.setAppUserModelId(process.execPath); app.on('ready', async () => { + logs.main.info('App ready'); if (window === null) - window = createWindow(); - - comms.setMessageChannel(new IPC(window)); - let recentlyUpdated = new Map(); + window = createWindow(logs.window); + + // Emitted when the window is closed. + window.on('closed', function () { + logs.window.info(`Window closed`); + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + window = null + }); - setTimeout(async () => { + window.on('ready-to-show', async () => { try { const latest = await lookForUpdate(); - if (latest.version > version) + if (latest.version > version) { + logs.update.info('Update found'); await comms.send('notification', { type: 'update', title: `Update Available (${latest.version})`, @@ -51,15 +88,26 @@ app.on('ready', async () => { link: latest.link, linkAlt: 'Download Page' }); + } else + logs.update.info('No updates found'); } catch (err) { + logs.update.error(err); } - }, 100); + }); + + logs.main.info('Setting up IPC connection to window...'); + comms.setMessageChannel(new IPC(window)); + logs.main.info('IPC connection to window initialized'); + + let recentlyUpdated = new Map(); setInterval(async () => { + logs.update.info('Checking for updates...'); try { const latest = await lookForUpdate(); - if (latest.version > version) + if (latest.version > version) { + logs.update.info('Update found'); await comms.send('notification', { type: 'update', title: `Update Available (${latest.version})`, @@ -67,13 +115,18 @@ app.on('ready', async () => { link: latest.link, linkAlt: 'Download Page' }); - } catch (err) {} + } else + logs.update.info('No updates found'); + } catch (err) { + logs.update.error(err); + } }, 86400000); setInterval(() => { - try { - if (recentlyUpdated.size > 0) - Array.from(recentlyUpdated.keys()).map(async uri => { + if (recentlyUpdated.size > 0) { + logs.updateDir.info('Updated files found, updating index...'); + Array.from(recentlyUpdated.keys()).map(async uri => { + try { recentlyUpdated.delete(uri); const thermo = (await reimager.send('getImages', {uri: uri + '/'}))[0]; let uuids = []; @@ -91,13 +144,16 @@ app.on('ready', async () => { return temp; }) }); - }); - } catch (err) { - + } catch (err) { + logs.updateDir.error(err); + } + }); + logs.updateDir.info('Updated files'); } }, 1000); reimager.on('dirUpdate', async ({filename, uri}) => { + logs.dirUpdate.info('Processing dir for new layers...'); try { if (filename.endsWith('.tif')) { const [dirName, type, element, line] = filename.split('_'); @@ -109,7 +165,21 @@ app.on('ready', async () => { }); } else if (!recentlyUpdated.has(uri + filename)) recentlyUpdated.set(uri + filename, true); - } catch(err) {} + } catch (err) { + logs.dirUpdate.error(err); + } + logs.dirUpdate.info('New layers added'); + }); + + comms.on('exportLog', async () => { + const path = await dialog.showSaveDialog({ + defaultPath: 'output.log' + }); + + if (!path.canceled) { + log.info('Hi', 'o/'); + log.export(path.filePath); + } }); comms.on('canvas', data => { @@ -117,6 +187,7 @@ app.on('ready', async () => { }); comms.on('saveImage', async data => { + logs.saveImage.info('Saving image to uuid map'); const uuid = GenerateUuid.v4(); let oldThermo = uuidMap.get(data.uuid); @@ -127,88 +198,103 @@ app.on('ready', async () => { uuidMap.set(uuid, oldThermo); + logs.saveImage.info('Image saved'); return {uuid}; }); comms.on('removeImage', async data => { savedMap.delete(data.imageUuid); + logs.saveImage.info('Image deleted from uuid map'); }); comms.on('writeImages', ({images, settings}) => { - return new Promise((resolve, reject) => { + logs.writeImage.info('Writing images'); + return new Promise(async (resolve, reject) => { window.setProgressBar(2); try { - dialog.showSaveDialog({ + const path = await dialog.showSaveDialog({ defaultPath: '{name}.png', filters: constants.export.FILTERS - }, - async path => { - if (path) { - const exports = exportImage(images, settings, path, reimager, {uuidMap, savedMap}); - - exports.on('update', ({finished, total}) => { - window.setProgressBar(finished / total); - comms.send('exportUpdate', {exported: finished, total, type: 'all'}); - }); - - exports.on('finish', total => { - window.setProgressBar(-1); - resolve(); - }); - } else { + }); + + if (!path.canceled) { + logs.writeImage.info('Exporting images...'); + const exports = exportImage(images, settings, path.filePath, reimager, {uuidMap, savedMap}); + + exports.on('update', ({finished, total}) => { + window.setProgressBar(finished / total); + comms.send('exportUpdate', {exported: finished, total, type: 'all'}); + }); + + exports.on('finish', total => { window.setProgressBar(-1); + logs.writeImage.info('Image written'); resolve(); - } - }); - } catch(err) { + }); + } else { + window.setProgressBar(-1); + logs.writeImage.info('Writing canceled by user'); + resolve(); + } + } catch (err) { window.setProgressBar(-1); + logs.writeImage.error(err); reject(err); } }); }); - comms.on('writeImage', ({imageUuid, settings}) => { - return new Promise((resolve, reject) => { + comms.on('writeImage', async ({imageUuid, settings}) => { + logs.writeImage.info('Writing image'); + return new Promise(async (resolve, reject) => { window.setProgressBar(2); let image = uuidMap.get(imageUuid); image = image ? image : savedMap.get(imageUuid); + try { - dialog.showSaveDialog({ + const path = await dialog.showSaveDialog({ defaultPath: image.name + '.png', filters: constants.export.FILTERS - }, - async path => { - if (path) { - const exports = exportImage([image], settings, path, reimager, {uuidMap, savedMap}); - - exports.on('update', ({finished, total}) => { - window.setProgressBar(finished / total); - comms.send('exportUpdate', {exported: finished, total, type: 'all'}); - }); - - exports.on('finish', total => { - window.setProgressBar(-1); - resolve(); - }); - } else { + }); + + if (!path.canceled) { + logs.writeImage.info('Exporting image...'); + const exports = exportImage([image], settings, path.filePath, reimager, {uuidMap, savedMap}); + + exports.on('update', ({finished, total}) => { + window.setProgressBar(finished / total); + comms.send('exportUpdate', {exported: finished, total, type: 'all'}); + }); + + exports.on('finish', total => { window.setProgressBar(-1); + logs.writeImage.info('Image written'); resolve(); - } - }); - } catch(err) { + }); + } else { + window.setProgressBar(-1); + logs.writeImage.info('Writing canceled by user'); + resolve(); + } + } catch (err) { window.setProgressBar(-1); + logs.writeImage.error(err); reject(err); } }); }); comms.on('loadImage', async data => { + logs.loadImage.info('Loading image...'); window.setProgressBar(2); + + logs.loadImage.info('Looking for cached image...'); const imageKey = createSettingKey(data); const testThermo = imageMap.get(imageKey); if (!testThermo) { + logs.loadImage.info('Cached not found, generating image...'); let image = uuidMap.get(data.imageUuid); image = image ? image : savedMap.get(data.imageUuid); @@ -229,44 +315,69 @@ app.on('ready', async () => { imageMap.set(imageKey, thermo); window.setProgressBar(-1); + logs.loadImage.info('Image cached and loaded'); return thermo; } testThermo.imageUuid = testThermo.uuid; testThermo.uuid = data.uuid; + window.setProgressBar(-1); + logs.loadImage.info('Image loaded from cache'); return testThermo; }); comms.on('processDirectory', async data => { + logs.processDir.info('Processing directory...'); window.setProgressBar(2); + + logs.processDir.info('Sanitizing directory uri...'); let dirUri = data.dir.replace(/\\/gmi, '/'); if (!dirUri.endsWith('/')) dirUri = dirUri + '/'; - const files = fs.readdirSync(dirUri, {withFileTypes: true}); - const dirNames = files.filter(file => file.isDirectory()).reduce((dirs, file) => { - dirs[file.name] = fs.readdirSync(`${dirUri}${file.name}`, {withFileTypes: true}).map(file => file.name); - return dirs; - }, {}); + logs.processDir.info(`'${data.dir}' -> '${dirUri}'`); - for (const file of files) - if (file.isFile() && file.name.endsWith('.tif')) { - const [dirName, type, element, line] = file.name.split('_'); - - if (element && element !== 'Grey' && element !== 'RefGrey' && !element.startsWith('Spec') && line && line.length === 1) - if (dirNames[`${dirName}.MAP.EDS`] && !dirNames[`${dirName}.MAP.EDS`].includes(`${dirName} ${type} ${element}_${line}.layer`)) - await relayerer.send('relayer', { - output: `${dirUri}${dirName}.MAP.EDS/${dirName} ${type} ${element}_${line}.layer`, - input: dirUri + file.name - }); - } + logs.processDir.info('Reading directory...'); + try { + const files = fs.readdirSync(dirUri, {withFileTypes: true}); + const dirNames = files.filter(file => file.isDirectory()).reduce((dirs, file) => { + dirs[file.name] = fs.readdirSync(`${dirUri}${file.name}`, {withFileTypes: true}).map(file => file.name); + return dirs; + }, {}); + + logs.processDir.info('Looking for thermo layers...'); + for (const file of files) + if (file.isFile() && file.name.endsWith('.tif')) { + const [dirName, type, element, line] = file.name.split('_'); + + if (element && element !== 'Grey' && element !== 'RefGrey' && !element.startsWith('Spec') && line && line.length === 1) + if (dirNames[`${dirName}.MAP.EDS`] && !dirNames[`${dirName}.MAP.EDS`].includes(`${dirName} ${type} ${element}_${line}.layer`)) + await relayerer.send('relayer', { + output: `${dirUri}${dirName}.MAP.EDS/${dirName} ${type} ${element}_${line}.layer`, + input: dirUri + file.name + }); + } + logs.processDir.info('Thermo layers classified'); + } catch (err) { + logs.processDir.error(err); + return { + error: err.code + }; + } - reimager.send('unwatch', {uri: activeDir}); + try { + logs.processDir.info('Unwatching previous directory'); + reimager.send('unwatch', {uri: activeDir}); + } catch(err) { + logs.processDir.error(err); + } activeDir = dirUri; + logs.processDir.info('Getting new directory...'); const thermos = await reimager.send('getDir', {uri: dirUri}); + logs.processDir.info('Sanitizing thermos...'); for (const thermo of thermos) { let uuid = entryMap.get(thermo.entryFile); uuid = uuid ? uuid : thermo.uuid; @@ -276,9 +387,15 @@ app.on('ready', async () => { uuidMap.set(uuid, thermo); } - reimager.send('watchDir', {uri: dirUri}); + try { + logs.processDir.info('Watching directory for future updates'); + reimager.send('watchDir', {uri: dirUri}); + } catch(err) { + logs.processDir.error(err); + } window.setProgressBar(-1); + logs.processDir.info('Directory processed'); return { thermos }; @@ -287,6 +404,7 @@ app.on('ready', async () => { // Quit when all windows are closed. app.on('window-all-closed', () => { + logs.window.info('Closing window'); // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== 'darwin') @@ -294,19 +412,32 @@ app.on('window-all-closed', () => { }); app.on('activate', () => { + logs.window.info('Reactivating window'); // On macOS it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (window === null) - window = createWindow(); + window = createWindow(logs.window); + + // Emitted when the window is closed. + window.on('closed', function () { + logs.window.info(`Window closed`); + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + window = null + }); }); app.on('web-contents-created', (event, contents) => { contents.on('new-window', async (event, navigationUrl) => { + logs.window.info('Opening link in default browser'); + event.preventDefault(); shell.openExternal(navigationUrl) }); contents.on('will-navigate', (event, navigationUrl) => { + logs.window.info('Negating window navigation'); event.preventDefault(); }); }); diff --git a/src/components/general/actions.js b/src/components/general/actions.js index 79bd3d8..f7fa678 100644 --- a/src/components/general/actions.js +++ b/src/components/general/actions.js @@ -1,6 +1,7 @@ -import { CreateActions } from 'bakadux'; +import {CreateActions} from 'bakadux'; import Communications from './communications'; -const { ipcRenderer } = window.require('electron'); + +const {ipcRenderer} = window.require('electron'); import IPC from './ipc'; import GenerateUuid from './generateuuid.js'; import constants from '../../../constants'; @@ -35,7 +36,7 @@ comms.on('notification', notification => { }); comms.on('navigate', ({page}) => { - switch(page) { + switch (page) { default: case 'home': actions.navigateHome(); @@ -50,7 +51,7 @@ comms.on('navigate', ({page}) => { }); comms.on('exportUpdate', ({type, total, exported}) => { - switch(type) { + switch (type) { default: case 'store': actions.updateStoreExport({exported, total, done: exported === total}); @@ -62,6 +63,12 @@ comms.on('exportUpdate', ({type, total, exported}) => { }); const actions = CreateActions([ + { + actionType: 'exportLog', + func: () => { + comms.send('exportLog'); + } + }, { actionType: 'addNotification', func: ({stores}, data) => { @@ -84,7 +91,7 @@ const actions = CreateActions([ }, { actionType: 'saveImage', - func: ({stores}, uuid, data, callback=undefined) => { + func: ({stores}, uuid, data, callback = undefined) => { if (uuid) comms.send('saveImage', { uuid @@ -141,7 +148,7 @@ const actions = CreateActions([ generalStore.set('workingDir', dir); generalStore.set('loadingDir', true); - comms.send('processDirectory', { dir }).then(([{thermos}]) => { + comms.send('processDirectory', {dir}).then(([{thermos}]) => { generalStore.set('loadingDir', false); actions.updateDirImages(thermos); @@ -157,7 +164,7 @@ const actions = CreateActions([ }, { actionType: 'updateDirImages', - func: ({stores}, thermos, update=false) => { + func: ({stores}, thermos, update = false) => { stores.general.set('images', thermos.reduce((thermos, thermo) => { thermo.points = Object.values(thermo.points).reduce((points, point) => { const uuid = GenerateUuid.v4(); @@ -209,7 +216,7 @@ const actions = CreateActions([ }, { actionType: 'loadImage', - func: ({stores}, uuid=false, activeOverride=false, shift=false, ctrl=false) => { + func: ({stores}, uuid = false, activeOverride = false, shift = false, ctrl = false) => { const settingStore = stores.settings; const generalStore = stores.general; const images = generalStore.get('images'); @@ -318,7 +325,8 @@ const actions = CreateActions([ }, { actionType: 'writeSelectedImage', - func: ({stores}, override=undefined, callback=() => {}) => { + func: ({stores}, override = undefined, callback = () => { + }) => { const generalStore = stores.general; const selectedUuid = override ? override : generalStore.get('selectedUuid'); @@ -357,7 +365,8 @@ const actions = CreateActions([ comms.send('writeImage', data).then(() => { if (typeof callback === 'function') callback(); - }).catch(() => {}); + }).catch(() => { + }); } } }, @@ -369,19 +378,18 @@ const actions = CreateActions([ }, { actionType: 'writeSelectedImages', - func: ({actions, stores}, uuidList=undefined, easy=stores.general.get('easyExport')) => { + func: ({actions, stores}, uuidList = undefined, easy = stores.general.get('easyExport')) => { let uuids = uuidList !== undefined ? uuidList : Array.from(stores.general.get('selectedUuids').keys()); if (easy) actions.writeAllImages(uuids); - else - if (uuids.length > 0) - actions.writeSelectedImage(uuids.pop(), actions.writeSelectedImages.bind(undefined, uuids, easy)); + else if (uuids.length > 0) + actions.writeSelectedImage(uuids.pop(), actions.writeSelectedImages.bind(undefined, uuids, easy)); } }, { actionType: 'writeSavedImages', - func: ({actions, stores}, uuidList=undefined) => { + func: ({actions, stores}, uuidList = undefined) => { let uuids = uuidList !== undefined ? uuidList : Array.from(stores.general.get('safebox').keys()); if (uuids.length > 0) { @@ -394,7 +402,7 @@ const actions = CreateActions([ }, { actionType: 'writeAllImages', - func: ({actions, stores}, uuidList=undefined) => { + func: ({actions, stores}, uuidList = undefined) => { const generalStore = stores.general; const settingStore = stores.settings; @@ -431,9 +439,9 @@ const actions = CreateActions([ }); comms.send('writeImages', {images, settings}) - .then(() => { + .then(() => { - }).catch(() => { + }).catch(() => { }); } @@ -480,11 +488,11 @@ const actions = CreateActions([ func: ({stores}, event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; - const xpos = event.screenX; + const xpos = event.clientX; const optionsWidth = stores.general.get('optionsWidth'); if (xpos > 290) // Smaller breaks Export button text - if (xpos < 500) + if (xpos < 500) // Arbitrary max if (xpos + optionsWidth <= window.innerWidth * .8) { if (document.styleSheets[0].cssRules[0].selectorText === '.app') document.styleSheets[0].deleteRule(0); @@ -499,11 +507,11 @@ const actions = CreateActions([ func: ({stores}, event) => { event.preventDefault(); event.dataTransfer.dropEffect = 'move'; - const xpos = event.screenX - window.innerWidth; + const xpos = event.clientX - window.innerWidth; const sidebarWidth = stores.general.get('sidebarWidth'); if (xpos < -272) // Smaller wraps button text - if (xpos > -500) + if (xpos > -500) // Arbitrary max if (Math.abs(xpos) + sidebarWidth <= window.innerWidth * .75) { if (document.styleSheets[0].cssRules[0].selectorText === '.app') document.styleSheets[0].deleteRule(0); @@ -517,7 +525,7 @@ const actions = CreateActions([ function sortLayers(layers, order) { let outputLayers = []; - for (let i = 0; i < order.length; i ++) + for (let i = 0; i < order.length; i++) outputLayers.push(undefined); let offset = 0; diff --git a/src/components/navbar/navbar.scss b/src/components/navbar/navbar.scss index 1a02330..72116af 100644 --- a/src/components/navbar/navbar.scss +++ b/src/components/navbar/navbar.scss @@ -4,6 +4,8 @@ display: flex; flex-direction: row; align-items: center; + min-width: 465px; + width: 100%; height: 100%; > .notifications { diff --git a/src/components/options/options.jsx b/src/components/options/options.jsx index f3877f1..57b307b 100644 --- a/src/components/options/options.jsx +++ b/src/components/options/options.jsx @@ -74,11 +74,6 @@ class Options extends Component { >

Below Right

-
{}} - > -

Jeol-like

-
diff --git a/src/components/options/options.scss b/src/components/options/options.scss index 2ab48cf..db4451f 100644 --- a/src/components/options/options.scss +++ b/src/components/options/options.scss @@ -16,7 +16,8 @@ > .content { width: 100%; - overflow-x: hidden; + height: 100%; + overflow: hidden; display: flex; flex-direction: column; @@ -32,7 +33,9 @@ grid-template-columns: 1fr 10px 1fr 10px 1fr; grid-template-rows: 1fr 10px 1fr 10px 1fr; grid-template-areas: "ul . . . ur" ". . . . ." "ll . lc . lr" "f f f f f" "bl fl bc fr br""jeol jeol jeol jeol jeol"; - height: 200px; + min-height: 140px; + max-height: 200px; + height: 30%; width: calc(90% - 4px); margin-left: 5%; border-radius: 4px; @@ -223,7 +226,7 @@ > ul { overflow-y: hidden !important; - height: 100%; + height: max-content; } } diff --git a/src/components/options/optionslist.jsx b/src/components/options/optionslist.jsx index 247c3bc..d243940 100644 --- a/src/components/options/optionslist.jsx +++ b/src/components/options/optionslist.jsx @@ -23,7 +23,7 @@ module.exports = class OptionsList extends Component { } } - componentWillUpdate(nextProps, nextState, nextContext) { + UNSAFE_componentWillUpdate(nextProps, nextState, nextContext) { const selectedUuid = generalStore.get('selectedUuid'); let image = generalStore.get('images').get(selectedUuid); image = image ? image : generalStore.get('safebox').get(selectedUuid); diff --git a/src/components/settings/settings.jsx b/src/components/settings/settings.jsx index 573fcd4..07413d1 100644 --- a/src/components/settings/settings.jsx +++ b/src/components/settings/settings.jsx @@ -26,6 +26,9 @@ class Settings extends Component { }
+
+

Export Log

+
); diff --git a/src/components/sidebar/sidebar.scss b/src/components/sidebar/sidebar.scss index 9250c20..b305102 100644 --- a/src/components/sidebar/sidebar.scss +++ b/src/components/sidebar/sidebar.scss @@ -49,7 +49,7 @@ p { > .content { width: 100%; - overflow-x: hidden; + overflow: hidden; display: flex; flex-direction: column; diff --git a/tests/reimagertest.js b/tests/reimagertest.js index 8bbb1e7..8538def 100644 --- a/tests/reimagertest.js +++ b/tests/reimagertest.js @@ -2,50 +2,7 @@ const fs = require('fs'); const generateUuid = require('../src/backend/generateuuid'); const Reimager = require('../src/backend/children/reimager/child.js'); - -class FakeComm { - constructor() { - this.data = { - one: { - listeners: new Map() - }, - two: { - listeners: new Map() - } - } - } - - get endOne() { - return { - send: this.send.bind(this, 'two'), - on: this.on.bind(this, 'one') - } - } - - get endTwo() { - return { - send: this.send.bind(this, 'one'), - on: this.on.bind(this, 'two') - } - } - - send(end, message) { - const listeners = this.data[end].listeners.get('message'); - if (listeners) - for (const listener of listeners) - listener(message); - } - - on(end, event, listener) { - if (typeof listener === 'function') { - const listeners = this.data[end].listeners.get(event); - if (listeners) - listeners.push(listener); - else - this.data[end].listeners.set(event, [listener]); - } - } -} +const FakeComm = require('../src/backend/fakecomm.js'); const fakeComm = new FakeComm(); diff --git a/build.js b/util/build.js similarity index 100% rename from build.js rename to util/build.js diff --git a/util/clean.js b/util/clean.js new file mode 100644 index 0000000..e7fd419 --- /dev/null +++ b/util/clean.js @@ -0,0 +1,78 @@ +const fs = require('fs/promises'); + +const data = { + distClean: { + build: { + all: true + }, + dist: { + all: true + }, + bin: { + all: true + } + }, + clean: { + build: { + dirs: ['lib', 'include', 'share', 'bin', 'etc'] + }, + bin: { + files: [] + }, + dist: { + all: true + } + } +}; + +async function clean(type = 'clean') { + const dirs = (await fs.readdir('../')).map(e => { + if (data.clean[e] !== undefined) { + let dir = JSON.parse(JSON.stringify(data[type][e])); + dir.name = e; + return dir; + } + return undefined; + }).filter(e => e !== undefined); + + let filePrefix = __dirname + '../'; + for (const dir of dirs) + if (dir.all) { + try { + console.log(`Deleting ${filePrefix}${dir.name}/*`); + await fs.rmdir(`${filePrefix}${dir.name}`, {recursive: true}); + await fs.mkdir(`${filePrefix}${dir.name}`); + } catch(e) { + } + } else { + if (dir.files) + for (const fileName of dir.files) + try { + console.log(`Deleting ${filePrefix}${dir.name}/${fileName}`); + await fs.unlink(`${filePrefix}${dir.name}/${fileName}`); + } catch(e) { + } + + if (dir.dirs) + for (const dirName of dir.dirs) + try { + console.log(`Deleting ${filePrefix}${dir.name}/${dirName}`); + await fs.rmdir(`${filePrefix}${dir.name}/${dirName}`, {recursive: true}); + } catch(e) { + } + } +} + +async function init(amount = 'clean') { + switch(amount.toLowerCase()) { + case 'clean': + case 'pre-compile': + default: + return await clean('clean'); + case 'distclean': + return await clean('distClean'); + } +} + +// Run the script +init(process.argv[2]); \ No newline at end of file diff --git a/util/compile.js b/util/compile.js new file mode 100644 index 0000000..dcb3fd0 --- /dev/null +++ b/util/compile.js @@ -0,0 +1,98 @@ +const crypto = require('crypto'); +const fs = require('fs'); +const execSync = require('child_process').execSync; + +const {buildPrefix, macTargetVersion, packageVersion} = require('./elcapitain/config.js'); + +function hashFile(uri) { + const hash = crypto.createHash('sha256'); + hash.update(fs.readFileSync(uri)); + return hash.digest('hex'); +} + +function exec(command, cwd = './', returnResult = false, newEnv = {}) { + let env = JSON.parse(JSON.stringify(process.env)); + for (const key of Array.from(Object.keys(newEnv))) + env[key] = newEnv[key]; + + const out = execSync(command, { + cwd, + stdio: returnResult ? 'pipe' : 'inherit', + env + }); + + if (returnResult) + return out.toString(); +} + +function copyDirSync(src, dest) { + src = src.endsWith('/') ? src : src + '/'; + dest = dest.endsWith('/') ? dest : dest + '/'; + const files = fs.readdirSync(src, {withFileTypes: true}); + try { + fs.mkdirSync(dest); + } catch(e) {} + + for (const file of files) { + const srcUri = `${src}${file.name}`; + const destUri = `${dest}${file.name}`; + + if (file.isFile()) + fs.copyFileSync(srcUri, destUri); + else if (file.isDirectory()) + copyDirSync(srcUri, destUri); + } +} + +function installPackage(packName) { + exec(`rm -fr ./bin/unpackaged/node_modules/${packName}`); + copyDirSync(`${buildPrefix}/electron/${packName}`, `./bin/unpackaged/node_modules/${packName}`); +} + +console.log('Building and packaging existing code...'); +exec('npm run build-prod'); +exec('node package.js'); + +console.log('Installing production npm packages...'); +exec('npm install --production', './bin/unpackaged'); + +if (process.platform === 'darwin') { + console.log(`Preparing packages for MacOSX (${macTargetVersion}) build...`); + exec('npm run build-el-capitan'); + + console.log(`Injecting packages into MacOSX (${macTargetVersion}) build...`); + installPackage('sharp'); + installPackage('canvas'); + + console.log('Packaging...'); + exec('"./node_modules/.bin/electron-packager" ./bin/unpackaged --out ./bin --overwrite'); + + console.log(`Injecting dylibs into MacOSX (${macTargetVersion}) build...`); + copyDirSync(`./bin/libs`, `./bin/Probelab ReImager-darwin-x64/Probelab ReImager.app/contents/Frameworks/Electron Framework.framework/Libraries/libs`); + + console.log('Building installer package for MacOS x64'); + exec('"./node_modules/.bin/electron-builder" --pd "./bin/Probelab ReImager-darwin-x64"'); + + fs.renameSync(`./dist/Probelab ReImager-${packageVersion}.dmg`, `./dist/reimager-${packageVersion}.dmg`); + const hash = hashFile(`./dist/reimager-${packageVersion}.dmg`); + console.log(`sha256: ${hash}`); +} else { + console.log('Rebuilding packages...'); + exec('"../../node_modules/.bin/electron-rebuild" -f', './bin/unpackaged'); + + console.log('Packaging...'); + exec('"./node_modules/.bin/electron-packager" ./bin/unpackaged --out ./bin --overwrite'); + + try { + fs.accessSync('./bin/Probelab ReImager-win32-x64', fs.constants.F_OK); + console.log('Building installer package for Windows x64'); + exec('"./node_modules/.bin/electron-builder" --pd "./bin/Probelab ReImager-win32-x64"'); + } catch(e) {} + + try { + fs.accessSync('./bin/Probelab ReImager-linux-x64', fs.constants.F_OK); + console.log('Building installer package for Linux x64'); + exec('"./node_modules/.bin/electron-builder" --pd "./bin/Probelab ReImager-linux-x64"'); + } catch(e) {} +} + diff --git a/util/elcapitain/compile.js b/util/elcapitain/compile.js new file mode 100644 index 0000000..2b4ba5f --- /dev/null +++ b/util/elcapitain/compile.js @@ -0,0 +1,152 @@ +const fs = require('fs/promises'); + +const {buildPrefix, configureConfig, cmakeConfig, mesonConfig, exec, packages, nodeGyp, electronConfig, macTargetVersion} = require('./config.js'); + +async function compile(pack, recompile = false) { + if (!pack.compiled || recompile) { + switch(pack.method) { + case 'configure': + console.log(`Cleaning ${pack.name} (${pack.link})`); + try { + await exec('make distclean > /dev/null', pack.name); + } catch(e) { + try { + await exec('make clean > /dev/null', pack.name); + } catch(e) { + } + } + + if (pack.postClean) + await pack.postClean(); + + console.log(`Configuring ${pack.name} (${pack.link})`); + await exec(`./configure ${configureConfig} ${pack.args.join(' ')} > /dev/null`, pack.name); + + if (pack.postConfigure) + await pack.postConfigure(); + + console.log(`Building ${pack.name} (${pack.link})`); + await exec('make install > /dev/null', pack.name); + + break; + case 'cmake': + console.log(`Cleaning ${pack.name} (${pack.link})`); + try { + await exec('make distclean > /dev/null', pack.name); + } catch(e) { + try { + await exec('make clean > /dev/null', pack.name); + } catch(e) { + } + } + + if (pack.postClean) + await pack.postClean(); + + console.log(`Configuring ${pack.name} (${pack.link})`); + await exec(`cmake make ${cmakeConfig} ${pack.args.join(' ')} . > /dev/null`, pack.name); + + if (pack.postConfigure) + await pack.postConfigure(); + + console.log(`Building ${pack.name} (${pack.link})`); + await exec('cmake --build . --target install > /dev/null', pack.name); + break; + case 'meson': + console.log(`Cleaning ${pack.name} (${pack.link})`); + try { + await fs.rmdir(`${buildPrefix}/${pack.name}/_build`, {recursive: true}); + } catch(e) { + } + + if (pack.postClean) + await pack.postClean(); + + console.log(`Configuring ${pack.name} (${pack.link})`); + try { + await exec(`meson _build ${mesonConfig} ${pack.args.join(' ')}`, pack.name); + } catch(err) { + throw err.stdout.toString(); + } + + await fs.writeFile(`${buildPrefix}/${pack.name}/_build/build.ninja`, (await fs.readFile(`${buildPrefix}/${pack.name}/_build/build.ninja`, {encoding: 'utf8'})) + .replace('-liconv', `${buildPrefix}/lib/libiconv.dylib`) + .replace(/command = cc/gm, `command = cc -mmacosx-version-min=${macTargetVersion}`) + .replace(/command = c\+\+/gm, `command = c++ -mmacosx-version-min=${macTargetVersion}`)); + + if (pack.postConfigure) + await pack.postConfigure(); + + console.log(`Building ${pack.name} (${pack.link})`); + try { + await exec(`ninja -C _build install`, pack.name); + } catch(err) { + throw err.stdout.toString(); + } + + break; + case 'make': + console.log(`Cleaning ${pack.name} (${pack.link})`); + try { + await exec('make distclean > /dev/null', pack.name); + } catch(e) { + try { + await exec('make clean > /dev/null', pack.name); + } catch(e) { + } + } + + if (pack.postClean) + await pack.postClean(); + + if (pack.postConfigure) + await pack.postConfigure(); + + console.log(`Building ${pack.name} (${pack.link})`); + await exec('make install > /dev/null', pack.name); + + break; + case 'electron': + if (pack.postClean) + await pack.postClean(); + + if (pack.postConfigure) + await pack.postConfigure(); + + console.log(`Building ${pack.name} (${pack.link})`); + await exec(`${nodeGyp} rebuild ${electronConfig} > /dev/null`, pack.name); + + console.log(`Packaging ${pack.name} (${pack.link})`); + await exec('npm pack > /dev/null', pack.name); + + const tarballName = `${pack.name}-${require(`${buildPrefix}/${pack.name}/package.json`).version}.tgz`; + try { + await fs.rmdir(`${buildPrefix}/electron/package`, {recursive: true}); + } catch(e) {} + + await exec(`tar -C ${buildPrefix}/electron -xzf ${buildPrefix}/${pack.name}/${tarballName}`); + try { + await fs.unlink(`${buildPrefix}/${pack.name}/${tarballName}`); + } catch(e) {} + + await fs.mkdir(`${buildPrefix}/electron/package/build/Release`, {recursive: true}); + await fs.copyFile(`${buildPrefix}/${pack.name}/build/Release/${pack.name}.node`, `${buildPrefix}/electron/package/build/Release/${pack.name}.node`); + await fs.rename(`${buildPrefix}/electron/package`, `${buildPrefix}/electron/${pack.name}`); + await exec(`"${buildPrefix}/bin/dylibbundler" -s "${buildPrefix}/lib" -of -cd -b -d "./bin/libs" -x "${buildPrefix}/electron/${pack.name}/build/Release/${pack.name}.node" -p "@rpath/libs/"`); + break; + default: + break; + } + + if (pack.postCompile) + await pack.postCompile(); + + if (pack.recompiles && pack.recompiles.length > 0) + for (const packName of pack.recompiles) + await compile(packages.get(packName), true); + } +} + +module.exports = { + compile +}; \ No newline at end of file diff --git a/util/elcapitain/config.js b/util/elcapitain/config.js new file mode 100644 index 0000000..c53ab49 --- /dev/null +++ b/util/elcapitain/config.js @@ -0,0 +1,632 @@ +const fs = require('fs/promises'); +const fsConstants = require('fs').constants; +const execSync = require('child_process').execSync; + +const packageJson = require('../../package.json'); + +const electronVersion = packageJson.devDependencies.electron; +const packageVersion = packageJson.version; + +const dirPrefix = __dirname.split('/').slice(0, -2).join('/'); +const buildPrefix = dirPrefix + '/build'; + +const macTargetVersion = '10.11'; + +const env = { + LDFLAGS: `-mmacosx-version-min=${macTargetVersion}`, + CXXFLAGS: `-stdlib=libc++ -mmacosx-version-min=${macTargetVersion}`, + CPPFLAGS: `-stdlib=libc++ -mmacosx-version-min=${macTargetVersion}`, + CFLAGS: `-stdlib=libc++ -mmacosx-version-min=${macTargetVersion}`, + PATH: `${buildPrefix}:${buildPrefix}/bin:/usr/local/bin:/usr/bin:/bin`, + PKG_CONFIG_PATH: `${buildPrefix}/lib/pkgconfig`, + CMAKE_INSTALL_PREFIX: `${buildPrefix}/`, + HOME: process.env.HOME +}; + +const mesonConfig = `--prefix="${buildPrefix}/"`; +const configureConfig = `--prefix="${buildPrefix}/"`; +const cmakeConfig = `-f makefile.unix -DCMAKE_INSTALL_PREFIX="${buildPrefix}" -DCMAKE_SYSTEM_PREFIX_PATH="${buildPrefix}"`; +const electronConfig = `--target=${electronVersion} --arch=x64 --dist-url=https://electronjs.org/headers`; + +const nodeGyp = `HOME=~/.electron-gyp "${buildPrefix}/../node_modules/.bin/node-gyp"`; + +const packages = new Map([ + ['package', { + 'details': '', + 'link': '', + 'name': 'package', + 'method': '', + 'args': [], + 'requires': [ + 'canvas', + 'sharp' + ], + 'recompiles': [], + 'makes': [], + 'postCompile': async () => { + } + }], + ['canvas', { + 'details': 'https://www.npmjs.com/package/canvas', + 'link': 'https://github.com/Automattic/node-canvas/archive/v2.7.0.tar.gz', + 'name': 'canvas', + 'method': 'electron', + 'args': [], + 'requires': [ + 'pango', + 'glib', + 'cairo', + 'dylibbundler' + ], + 'recompiles': [], + 'makes': ['canvas'] + }], + ['sharp', { + 'details': 'https://sharp.pixelplumbing.com', + 'link': 'https://github.com/lovell/sharp/archive/v0.26.2.zip', + 'name': 'sharp', + 'method': 'electron', + 'args': [], + 'requires': [ + 'vips', + 'dylibbundler' + ], + 'recompiles': [], + 'makes': ['sharp'] + }], + ['dylibbundler', { + 'details': 'https://pango.gnome.org/', + 'link': 'https://github.com/auriamg/macdylibbundler.git', + 'name': 'dylibbundler', + 'method': 'make', + 'args': [], + 'requires': [], + 'recompiles': [], + 'makes': ['dylibbundler'], + 'postCompile': async () => { + try { + await fs.unlink(`${buildPrefix}/bin/dylibbundler`); + } catch(e) { + } + await fs.symlink(`${buildPrefix}/dylibbundler/dylibbundler`, `${buildPrefix}/bin/dylibbundler`); + } + }], + ['rsvg', { + 'details': 'https://gitlab.gnome.org/GNOME/librsvg', + 'link': 'https://gitlab.gnome.org/GNOME/librsvg/-/archive/2.50.1/librsvg-2.50.1.tar.gz', + 'name': 'rsvg', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig', + 'pango', + 'cairo', + 'xml2', + 'pixbuf', + 'freetype', + 'gobject', + 'glib' + ], + 'recompiles': [], + 'makes': [] + }], + ['xml2', { + 'details': 'http://www.xmlsoft.org/', + 'link': 'http://xmlsoft.org/libxml2/libxml2-2.9.10.tar.gz', + 'name': 'xml2', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig', + 'zlib', + 'iconv' + ], + 'recompiles': [], + 'makes': [] + }], + ['pixbuf', { + 'details': 'https://gitlab.gnome.org/GNOME/gdk-pixbuf', + 'link': 'https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/archive/2.40.0/gdk-pixbuf-2.40.0.tar.gz', + 'name': 'pixbuf', + 'method': 'meson', + 'args': [], + 'requires': [ + 'pkgconfig', + 'pango', + 'cairo' + ], + 'recompiles': [], + 'makes': [] + }], + ['pango', { + 'details': 'https://pango.gnome.org/', + 'link': 'https://download.gnome.org/sources/pango/1.47/pango-1.47.0.tar.xz', + 'name': 'pango', + 'method': 'meson', + 'args': [], + 'requires': [ + 'pkgconfig', + 'harfbuzz', + 'cairo' + ], + 'recompiles': [], + 'makes': ['libpango-1.0.dylib'] + }], + ['gobject', { + 'details': 'https://gitlab.gnome.org/GNOME/gobject-introspection/', + 'link': 'https://gitlab.gnome.org/GNOME/gobject-introspection/-/archive/1.66.1/gobject-introspection-1.66.1.zip', + 'name': 'gobject', + 'method': 'meson', + 'args': [], + 'requires': [ + 'pkgconfig', + 'cairo', + 'ffi', + 'glib' + ], + 'recompiles': [], + 'makes': ['libgirepository-1.0.dylib'] + }], + ['harfbuzz', { + 'details': 'https://harfbuzz.github.io/', + 'link': 'https://github.com/harfbuzz/harfbuzz/releases/download/2.7.2/harfbuzz-2.7.2.tar.xz', + 'name': 'harfbuzz', + 'method': 'configure', + 'args': ['--with-glib', '--with-gobject', '--with-freetype', '--with-fontconfig', '--with-coretext', '--with-cairo'], + 'requires': [ + 'pkgconfig', + 'cairo', + 'freetype', + 'glib', + 'gobject' + ], + 'recompiles': [], + 'makes': ['hb-coretext.h', 'libharfbuzz.dylib'], + 'postCompile': async () => { + const files = await fs.readdir(`${buildPrefix}/include/harfbuzz/`); + for (const file of files) + try { + await fs.symlink(`${buildPrefix}/include/harfbuzz/${file}`, `${buildPrefix}/include/${file}`); + } catch(e) { + } + } + }], + ['lzo2', { + 'details': 'http://www.oberhumer.com/opensource/lzo', + 'link': 'http://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz', + 'name': 'lzo2', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['liblzo2.a'] + }], + ['freetype', { + 'details': 'https://www.freetype.org/download.html', + 'link': 'https://download.savannah.gnu.org/releases/freetype/freetype-2.9.1.tar.gz', + 'name': 'freetype', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['ft2build.h', 'libfreetype.dylib'], + 'postCompile': async () => { + await fs.symlink(`${buildPrefix}/include/freetype2/ft2build.h`, `${buildPrefix}/include/ft2build.h`); + await fs.symlink(`${buildPrefix}/include/freetype2/freetype`, `${buildPrefix}/include/freetype`); + } + }], + ['fontconfig', { + 'details': 'https://www.freedesktop.org/wiki/Software/fontconfig/', + 'link': 'https://www.freedesktop.org/software/fontconfig/release/fontconfig-2.13.92.tar.gz', + 'name': 'fontconfig', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libfontconfig.dylib'] + }], + ['zlib', { + 'details': 'http://zlib.net/', + 'link': 'http://zlib.net/zlib-1.2.11.tar.gz', + 'name': 'zlib', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libz.dylib'] + }], + ['pixman', { + 'details': 'https://www.cairographics.org', + 'link': 'https://www.cairographics.org/releases/pixman-0.40.0.tar.gz', + 'name': 'pixman', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libpixman-1.dylib'] + }], + ['cairo', { + 'details': 'https://www.cairographics.org', + 'link': 'https://www.cairographics.org/releases/cairo-1.16.0.tar.xz', + 'name': 'cairo', + 'method': 'configure', + 'args': ['--enable-gtk-doc-html=no', '--disable-xlib'], + 'requires': [ + 'pkgconfig', + 'pixman', + 'libpng', + 'zlib', + 'lzo2', + 'freetype', + 'fontconfig' + ], + 'recompiles': [], + 'makes': ['cairo-trace', 'libcairo.dylib'] + }], + ['lcms2', { + 'details': 'https://github.com/mm2/Little-CMS', + 'link': 'https://managedway.dl.sourceforge.net/project/lcms/lcms/2.11/lcms2-2.11.tar.gz', + 'name': 'lcms2', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['liblcms2.dylib'] + }], + ['exif', { + 'details': 'https://github.com/libexif/libexif', + 'link': 'https://github.com/libexif/libexif/releases/download/libexif-0_6_22-release/libexif-0.6.22.tar.gz', + 'name': 'exif', + 'method': 'configure', + 'args': ['--disable-dependency-tracking'], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': [] + }], + ['orc', { + 'details': 'https://github.com/GStreamer/orc', + 'link': 'https://gstreamer.freedesktop.org/data/src/orc/orc-0.4.32.tar.xz', + 'name': 'orc', + 'method': 'meson', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['liborc-0.4.0.dylib'] + }], + ['fftw', { + 'details': 'http://fftw.org/index.html', + 'link': 'http://fftw.org/fftw-3.3.8.tar.gz', + 'name': 'fftw', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libfftw3.a'] + }], + ['heif', { + 'details': 'http://www.libheif.org/', + 'link': 'https://github.com/strukturag/libheif/releases/download/v1.9.1/libheif-1.9.1.tar.gz', + 'name': 'heif', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libheif.dylib'] + }], + ['libjpeg', { + 'details': 'https://www.libjpeg-turbo.org/', + 'link': 'https://newcontinuum.dl.sourceforge.net/project/libjpeg-turbo/2.0.5/libjpeg-turbo-2.0.5.tar.gz', + 'name': 'libjpeg', + 'method': 'cmake', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libturbojpeg.dylib'] + }], + ['libpng', { + 'details': 'http://www.libpng.org/pub/png/libpng.html', + 'link': 'https://phoenixnap.dl.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz', + 'name': 'libpng', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['png.h', 'libpng.dylib'] + }], + ['libspng', { + 'details': 'https://libspng.org', + 'link': 'https://github.com/randy408/libspng/archive/v0.6.1.tar.gz', + 'name': 'libspng', + 'method': 'meson', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libspng.dylib'] + }], + ['libwebp', { + 'details': 'https://github.com/webmproject/libwebp', + 'link': 'https://github.com/webmproject/libwebp/archive/v1.1.0.zip', + 'name': 'libwebp', + 'method': 'cmake', + 'args': ['--enable-libwebpmux', '--enable-libwebpdemux', '--enable-libwebpdecoder', '--enable-libwebpextras'], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libwebp.a', 'libwebpdemux.a', 'libwebpdecoder.a', 'libwebpmux.a'] + }], + ['libtiff', { + 'details': 'http://libtiff.org/', + 'link': 'http://download.osgeo.org/libtiff/tiff-4.1.0.zip', + 'name': 'libtiff', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['libtiff.dylib'] + }], + ['expat', { + 'details': 'https://libexpat.github.io/', + 'link': 'https://github.com/libexpat/libexpat/releases/download/R_2_2_10/expat-2.2.10.tar.gz', + 'name': 'expat', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['expat.h', 'libexpat.dylib'] + }], + ['vips', { + 'details': 'https://libvips.github.io/libvips/', + 'link': 'https://github.com/libvips/libvips/releases/download/v8.10.2/vips-8.10.2.tar.gz', + 'name': 'vips', + 'method': 'configure', + 'args': ['--without-rsvg', '--without-gsf', '--without-magick', '--without-OpenEXR', '--without-pdfium', '--without-poppler', '--without-openslide', '--without-matio', '--without-cfitsio', '--without-giflib', '--without-imagequant', '--without-libexif'], + 'requires': [ + 'pkgconfig', + 'glib', + 'expat', + 'libjpeg', + 'libspng', + 'libpng', + 'libwebp', + 'libtiff', + 'orc', + 'fftw', +// 'exif', + 'heif', + 'lcms2' + ], + 'recompiles': [], + 'makes': ['vips'] + }], + ['glib', { + 'details': 'https://gitlab.gnome.org/GNOME/glib', + 'link': 'https://download.gnome.org/sources/glib/2.67/glib-2.67.0.tar.xz', + 'name': 'glib', + 'method': 'meson', + 'args': [ + '--default-library=shared', + '-Dxattr=false', + '-Dselinux=disabled', + '-Ddtrace=false', + '-Dc_args=""', + '-Dsystemtap=false', + `-Dcpp_args="-mmacosx-version-min=${macTargetVersion}"`, + `-Dc_link_args="-mmacosx-version-min=${macTargetVersion}"`, + `-Dcpp_link_args="-mmacosx-version-min=${macTargetVersion}"`, + `--pkg-config-path="${env.PKG_CONFIG_PATH}"` + ], + 'requires': [ + 'pkgconfig', + 'iconv', + 'gettext', + 'ffi', + 'pcre' + ], + 'recompiles': [], + 'makes': ['gio', 'libgobject-2.0.dylib', 'libgio-2.0.0.dylib', 'libglib-2.0.0.dylib'], + 'postConfigure': async () => { + + } + }], + ['pkgconfig', { + 'details': 'https://pkg-config.freedesktop.org', + 'link': 'https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz', + 'name': 'pkgconfig', + 'method': 'configure', + 'args': ['--with-internal-glib'], + 'requires': [ + 'iconv' + ], + 'recompiles': [], + 'makes': ['pkg-config'] + }], + ['iconv', { + 'details': 'http://www.gnu.org/software/libiconv', + 'link': 'https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz', + 'name': 'iconv', + 'method': 'configure', + 'args': [], + 'requires': [], + 'recompiles': [], + 'makes': ['iconv.h', 'libcharset.h', 'localcharset.h', 'libiconv.dylib', 'libcharset.dylib', 'iconv'] + }], + ['gettext', { + 'details': 'https://www.gnu.org/software/gettext/', + 'link': 'https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz', + 'name': 'gettext', + 'method': 'configure', + 'args': [], + 'requires': [ + 'iconv', + 'pkgconfig' + ], + 'recompiles': [ + 'iconv' + ], + 'makes': ['gettext-po.h', 'libgettextlib.dylib', 'libgettextpo.dylib', 'libintl.dylib', 'gettext', 'gettextize'] + }], + ['ffi', { + 'details': 'http://www.sourceware.org/libffi/', + 'link': 'https://github.com/libffi/libffi/releases/download/v3.3/libffi-3.3.tar.gz', + 'name': 'ffi', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['ffi.h', 'ffitarget.h', 'libffi.a', 'libffi.dylib', 'libffi.la'] + }], + ['pcre', { + 'details': 'http://www.pcre.org/', + 'link': 'https://ftp.pcre.org/pub/pcre/pcre-8.44.zip', + 'name': 'pcre', + 'method': 'configure', + 'args': [], + 'requires': [ + 'pkgconfig' + ], + 'recompiles': [], + 'makes': ['pcre.h', 'libpcre.dylib', 'libpcrecpp.dylib', 'libpcreposix.dylib'] + }] +]); + +let compileOrder = new Set(); + +async function testForFile(fileName) { + let exists = false; + + try { + await fs.access(`${buildPrefix}/bin/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + try { + await fs.access(`${buildPrefix}/include/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + try { + await fs.access(`${buildPrefix}/lib/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + try { + await fs.access(`${buildPrefix}/etc/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + try { + await fs.access(`${buildPrefix}/share/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + try { + await fs.access(`${buildPrefix}/electron/${fileName}`, fsConstants.F_OK); + exists = true; + } catch(e) { + } + + return exists; +} + +async function prepare(packName) { + const pack = packages.get(packName); + try { + await fs.access(`${buildPrefix}/${packName}`, fsConstants.F_OK); + pack.downloaded = true; + } catch(e) { + pack.downloaded = false; + } + + pack.compiled = false; + if (pack.makes && pack.makes.length > 0 && pack.downloaded) + try { + for (const file of pack.makes) + if (!await testForFile(file)) + throw ''; + + pack.compiled = true; + } catch(e) { + } + + for (const prePack of pack.requires) + await prepare(prePack); + compileOrder.add(pack.name); +} + +async function exec(command, cwd = '', override = false) { + return execSync(command, { + env, + cwd: override ? cwd : `${buildPrefix}/${cwd}`, + maxBuffer: 1024 * 1024 + }); +} + +module.exports = { + packages, + dirPrefix, + buildPrefix, + mesonConfig, + cmakeConfig, + configureConfig, + electronConfig, + macTargetVersion, + packageVersion, + nodeGyp, + electronVersion, + exec, + requirements: async () => { + try { + await fs.access(buildPrefix, fsConstants.F_OK); + } catch(e) { + await fs.mkdir(buildPrefix); + } + + try { + await fs.access(`${buildPrefix}/electron`, fsConstants.F_OK); + } catch(e) { + await fs.mkdir(`${buildPrefix}/electron`); + } + + await prepare('package'); + + return compileOrder; + } +}; \ No newline at end of file diff --git a/util/elcapitain/download.js b/util/elcapitain/download.js new file mode 100644 index 0000000..951d919 --- /dev/null +++ b/util/elcapitain/download.js @@ -0,0 +1,93 @@ +const fs = require('fs/promises'); + +const bent = require('bent')('buffer'); + +const {requirements, buildPrefix, packages, exec} = require('./config.js'); +const {compile} = require('./compile.js'); + +async function doomload(type, link, pack, name, downloadLocation, extractLocation) { + try { + await fs.writeFile(downloadLocation, await bent(link)); + await fs.mkdir(extractLocation); + if (type === 'zip') { + let rawName = name.split('.'); + rawName.pop(); + rawName = rawName.join('.'); + + await exec(`unzip -d ${extractLocation} ${downloadLocation}`); + try { + await exec(`mv ${extractLocation}/${rawName}/* ${extractLocation}`); + } catch(e) { + try { + await exec(`mv ${extractLocation}/${pack.name}-${rawName}/* ${extractLocation}`); + } catch(e) { + await exec(`mv ${extractLocation}/${pack.name}-${rawName.replace('v', '')}/* ${extractLocation}`); + } + } + } else + await exec(`tar --strip-components=1 -C ${extractLocation} -${type} ${downloadLocation}`); + } catch(err) { + if (err.statusCode === 302) + return doomload(type, err.headers.location, pack, name, downloadLocation, extractLocation); + throw err; + } +} + +async function download(pack) { + let type; + const name = pack.link.split('/').slice(-1)[0]; + const downloadLocation = `${buildPrefix}/${name}`; + const extractLocation = `${buildPrefix}/${pack.name}`; + + if (!pack.downloaded) + switch(pack.link.split('.').pop()) { + case 'zip': + if (!type) type = 'zip'; + case 'gz': + if (!type) type = 'xzf'; + case 'xz': + if (!type) type = 'xJf'; + case 'bz2': + if (!type) type = 'xjf'; + case 'lz': + if (!type) type = '-lzma -xf'; + case 'tar': + if (!type) type = 'xf'; + console.log(`Downloading ${pack.name} (${pack.link})`); + + await doomload(type, pack.link, pack, name, downloadLocation, extractLocation); + await fs.unlink(downloadLocation); + pack.downloaded = true; + break; + case 'git': + console.log(`Cloning ${pack.name} (${pack.link})`); + + await exec(`git clone ${pack.link}`); + await fs.rename(downloadLocation.split('.').slice(0, -1).join('.'), extractLocation); + pack.downloaded = true; + break; + default: + console.log(`Unable to download ${pack.name} (${pack.link})`); + break; + } +} + +requirements().then(async compileOrder => { + let toCompile = new Set(); + + for (const packName of compileOrder) { + const pack = packages.get(packName); + if (pack.link !== '') + await download(pack); + + if (pack.requires.filter(e => !packages.get(e).compiled).length !== 0) { + toCompile.add(packName); + } else + try { + await compile(pack); + pack.compiled = true; + } catch(err) { + console.log(err); + } + } +});