From 4db2639a4ab9b03e7115dbdbb9d5a23d170b66fa Mon Sep 17 00:00:00 2001 From: Eric Enns Date: Fri, 4 Nov 2022 08:39:53 -0500 Subject: [PATCH] feat(build): gradle buildWebapp now only runs when packages change, inputs change, or output directory is modified. --- build.gradle.kts | 14 ++- settings.gradle.kts | 2 +- src/main/webapp/package.json | 13 +- src/main/webapp/pnpm-lock.yaml | 219 +++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+), 12 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9e81cfbe510..32bfc15525f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -304,15 +304,19 @@ tasks.register("cleanWebapp") { } tasks.register("buildWebapp") { - dependsOn(":cleanWebapp") - pnpmCommand.set(listOf("build")) - inputs.dir("${project.projectDir}/src/main/webapp/resources") + inputs.files(fileTree("${project.projectDir}/src/main/webapp/resources")) + inputs.file("${project.projectDir}/src/main/webapp/package.json") + inputs.file("${project.projectDir}/src/main/webapp/pnpm-lock.yaml") + outputs.dir("${project.projectDir}/src/main/webapp/dist") + + dependsOn(":pnpmInstall") + pnpmCommand.set(listOf("clean", "build")) } tasks.register("startWebapp") { - dependsOn(":cleanWebapp") - pnpmCommand.set(listOf("start")) + dependsOn(":pnpmInstall") + pnpmCommand.set(listOf("clean", "start")) inputs.dir("${project.projectDir}/src/main/webapp/resources") outputs.dir("${project.projectDir}/src/main/webapp/dist") } diff --git a/settings.gradle.kts b/settings.gradle.kts index de2c326a16c..5010e60c23d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,7 +4,7 @@ pluginManagement { gradlePluginPortal() } plugins { - id("com.github.node-gradle.node") version "3.4.0" + id("com.github.node-gradle.node") version "3.5.0" id("io.spring.dependency-management") version "1.0.11.RELEASE" id("org.gradle.test-retry") version "1.4.0" id("org.springframework.boot") version "2.7.4" diff --git a/src/main/webapp/package.json b/src/main/webapp/package.json index a7ff2001b73..c2d761131cd 100644 --- a/src/main/webapp/package.json +++ b/src/main/webapp/package.json @@ -3,12 +3,12 @@ "version": "1.0.0", "license": "Apache-2.0", "scripts": { - "build": "webpack --mode production", - "start": "webpack --mode development --watch", - "clean": "rm -rf dist/ pages/templates/i18n/", - "test": "jest resources/js/**/*.test.js", - "test_watch": "jest --watch resources/js/**/*.test.js", - "lint": "eslint --ext resources/js/**/*.{js,jsx,ts,tsx}" + "build": "run-z --then webpack --mode production", + "start": "run-z --then webpack --mode development --watch", + "clean": "run-z --then rm -rf dist/ pages/templates/i18n/", + "test": "run-z --then jest resources/js/**/*.test.js", + "test_watch": "run-z --then jest --watch resources/js/**/*.test.js", + "lint": "run-z --then eslint --ext resources/js/**/*.{js,jsx,ts,tsx}" }, "browserslist": [ "last 2 Chrome versions", @@ -128,6 +128,7 @@ "prettier": "^2.7.0", "properties-reader": "^2.2.0", "react-is": "^17.0.2", + "run-z": "^1.10.1", "speed-measure-webpack-plugin": "^1.5.0", "terser-webpack-plugin": "^5.3.1", "typescript": "^4.7.2", diff --git a/src/main/webapp/pnpm-lock.yaml b/src/main/webapp/pnpm-lock.yaml index 0e7d54ac308..c8651e76944 100644 --- a/src/main/webapp/pnpm-lock.yaml +++ b/src/main/webapp/pnpm-lock.yaml @@ -114,6 +114,7 @@ specifiers: reactour: ^1.18.7 redux: 4.1.2 redux-saga: ^1.1.3 + run-z: ^1.10.1 speed-measure-webpack-plugin: ^1.5.0 styled-components: ^5.3.5 terser-webpack-plugin: ^5.3.1 @@ -237,6 +238,7 @@ devDependencies: prettier: 2.7.1 properties-reader: 2.2.0 react-is: 17.0.2 + run-z: 1.10.1 speed-measure-webpack-plugin: 1.5.0_webpack@5.72.0 terser-webpack-plugin: 5.3.1_webpack@5.72.0 typescript: 4.7.2 @@ -2611,6 +2613,47 @@ packages: '@babel/runtime': 7.17.9 dev: false + /@proc7ts/context-values/7.0.1: + resolution: {integrity: sha512-I50cq8eTUQenWgeZ7thHxmsiW2uqez/SsOWofvvzzLklAWypA/2xpmVUUc29e0z6IwmCZrqHVUsbZVPkbzhyCw==} + peerDependencies: + '@proc7ts/fun-events': ^10.5.1 + peerDependenciesMeta: + '@proc7ts/fun-events': + optional: true + dependencies: + '@proc7ts/primitives': 3.0.2 + '@proc7ts/push-iterator': 3.1.0 + '@proc7ts/supply': 1.2.3 + transitivePeerDependencies: + - '@proc7ts/call-thru' + dev: true + + /@proc7ts/logger/1.3.2: + resolution: {integrity: sha512-hzPVA4GcdUYxdYd9RSG1pZ+VLa56HDIhhyqlofcGdyVJbIfazbpwwMR4ZC1zlFGHefvQ+RbjskBCOCeRTiGgqA==} + dependencies: + '@proc7ts/context-values': 7.0.1 + transitivePeerDependencies: + - '@proc7ts/call-thru' + - '@proc7ts/fun-events' + dev: true + + /@proc7ts/primitives/3.0.2: + resolution: {integrity: sha512-sPGz+vVXydw0wUP2eixVNvWzwrXsrW+j1NmCH3/LQo4tE1/jODQGkXB2MWTCQqNy3grpoAf6piOOpxAynm4tZw==} + dev: true + + /@proc7ts/push-iterator/3.1.0: + resolution: {integrity: sha512-5pgO8yaMMn1LnIMPMxtchSsqHHQsAEiMQ9EszOSijn4dwYADnPmGXh1hSG34EBHEIhhohZzxu/tN0oAAsSki+Q==} + peerDependencies: + '@proc7ts/call-thru': ^4.4.0 + peerDependenciesMeta: + '@proc7ts/call-thru': + optional: true + dev: true + + /@proc7ts/supply/1.2.3: + resolution: {integrity: sha512-NxIArWgpwyMKFaoklfEXkq3/0mLDl64ZrWxFFE9t/uBUgkzKnq3mSmw9gmeQQlnjkFS9mXInH873qBOOzzK5bw==} + dev: true + /@react-dnd/asap/4.0.1: resolution: {integrity: sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==} dev: false @@ -2696,6 +2739,38 @@ packages: react: 17.0.2 dev: false + /@run-z/exec-z/1.4.1: + resolution: {integrity: sha512-d05A1gfSPbHeqqg0IJxb4Bw2lZ6JA7J9GFL+7sXNkP4hbkcPQCGr+gmJFM4V5RcAmJgWh9kkgQT2CVVyJ13QZQ==} + dependencies: + '@proc7ts/primitives': 3.0.2 + dev: true + + /@run-z/log-z/2.1.0: + resolution: {integrity: sha512-+1oM4HtYi8xH+h3dxfAo9RenyPDtUfKAuSqrELK8AbtVwZ36652AXCqEmR3jJE4Jr9/LweTtlMpf50stUj8oEA==} + dependencies: + '@proc7ts/context-values': 7.0.1 + '@proc7ts/logger': 1.3.2 + '@proc7ts/primitives': 3.0.2 + '@proc7ts/push-iterator': 3.1.0 + transitivePeerDependencies: + - '@proc7ts/call-thru' + - '@proc7ts/fun-events' + dev: true + + /@run-z/optionz/2.4.0_chalk@5.1.2: + resolution: {integrity: sha512-GU8zFgmo5D1PbGJ1YI1hpNCQDTseo1iSjQd2R8ilINndoocvKtrLbYf1xvfv/vT6Q689UTMXjQC9aURE50uYkA==} + peerDependencies: + chalk: ^5.0.0 + peerDependenciesMeta: + chalk: + optional: true + dependencies: + '@proc7ts/primitives': 3.0.2 + chalk: 5.1.2 + string-width: 5.1.2 + wrap-ansi: 8.0.1 + dev: true + /@sinonjs/commons/1.8.2: resolution: {integrity: sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==} dependencies: @@ -3334,11 +3409,23 @@ packages: type-fest: 0.21.3 dev: true + /ansi-escapes/5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: true + /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: true + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -3357,6 +3444,11 @@ packages: engines: {node: '>=10'} dev: true + /ansi-styles/6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /antd/4.19.5_sfoxds7t5ydpegc3knd667wn6m: resolution: {integrity: sha512-C4H/VJqlVO5iMvHZyiV27R8SbPs4jsOKCGPhDXIHUry/RnUCbMmVeQaPRfUIxSI1NbqDflsuQfevPtz1svyIlg==} peerDependencies: @@ -3822,6 +3914,11 @@ packages: supports-color: 7.2.0 dev: true + /chalk/5.1.2: + resolution: {integrity: sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /char-regex/1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -3850,6 +3947,19 @@ packages: resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} dev: false + /cli-spinners/2.7.0: + resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} + engines: {node: '>=6'} + dev: true + + /cli-truncate/3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + /clipboard/1.7.1: resolution: {integrity: sha512-smkaRaIQsrnKN1F3wd1/vY9Q+DeR4L8ZCXKeHCFC2j8RZuSBbuImcLdnIO4GTxmzJxQuDGNKkyfpGoPW7Ua5bQ==} dependencies: @@ -4592,6 +4702,10 @@ packages: resolution: {integrity: sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==} dev: false + /eastasianwidth/0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + /electron-to-chromium/1.4.107: resolution: {integrity: sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg==} @@ -5480,6 +5594,11 @@ packages: engines: {node: '>=8'} dev: true + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + /is-generator-fn/2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -5558,6 +5677,11 @@ packages: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true + /is-unicode-supported/1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + /is-weakref/1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: @@ -6377,6 +6501,14 @@ packages: /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + /log-symbols/5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.1.2 + is-unicode-supported: 1.3.0 + dev: true + /long/3.2.0: resolution: {integrity: sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg==} engines: {node: '>=0.6'} @@ -6813,6 +6945,13 @@ packages: path-key: 3.1.1 dev: true + /npm-run-path/5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /nth-check/2.0.1: resolution: {integrity: sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==} dependencies: @@ -6983,6 +7122,11 @@ packages: engines: {node: '>=8'} dev: true + /path-key/4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true @@ -8766,6 +8910,34 @@ packages: queue-microtask: 1.2.3 dev: true + /run-z/1.10.1: + resolution: {integrity: sha512-URsE2xx6RK3iumCrQS7gbNcCj7ffNRWcytOmSh9ctIeDZjeZ22fbH47TTVR5BiEIcM6PuLe+sjRn5XCc1G2Dvg==} + engines: {node: '>=12'} + hasBin: true + dependencies: + '@proc7ts/logger': 1.3.2 + '@proc7ts/primitives': 3.0.2 + '@run-z/exec-z': 1.4.1 + '@run-z/log-z': 2.1.0 + '@run-z/optionz': 2.4.0_chalk@5.1.2 + ansi-escapes: 5.0.0 + chalk: 5.1.2 + cli-spinners: 2.7.0 + cli-truncate: 3.1.0 + cross-spawn: 7.0.3 + log-symbols: 5.1.0 + npm-run-path: 5.1.0 + path-key: 4.0.0 + semver: 7.3.7 + shell-quote: 1.7.4 + string-width: 5.1.2 + strip-ansi: 7.0.1 + tree-kill: 1.2.2 + transitivePeerDependencies: + - '@proc7ts/call-thru' + - '@proc7ts/fun-events' + dev: true + /rw/1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} dev: false @@ -8904,6 +9076,10 @@ packages: engines: {node: '>=8'} dev: true + /shell-quote/1.7.4: + resolution: {integrity: sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==} + dev: true + /side-channel/1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -8928,6 +9104,14 @@ packages: engines: {node: '>=8'} dev: true + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -9010,6 +9194,15 @@ packages: strip-ansi: 6.0.1 dev: true + /string-width/5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.0.1 + dev: true + /string.prototype.matchall/4.0.6: resolution: {integrity: sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==} dependencies: @@ -9044,6 +9237,13 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + /strip-bom/4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -9280,6 +9480,11 @@ packages: punycode: 2.1.1 dev: true + /tree-kill/1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + /trough/2.1.0: resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} dev: false @@ -9329,6 +9534,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest/1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: true + /typedarray-to-buffer/3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: @@ -9770,6 +9980,15 @@ packages: strip-ansi: 6.0.1 dev: true + /wrap-ansi/8.0.1: + resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.0.1 + dev: true + /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true