├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── layers ├── background │ └── black.png ├── ball │ ├── red eye ball_sr.png │ └── white eye ball.png ├── bottom lid │ ├── high bottom.png │ ├── low bottom.png │ └── tilted bottom_r.png ├── eye color │ ├── cyan big.png │ ├── cyan small.png │ ├── green big.png │ ├── green small.png │ ├── pink big.png │ ├── pink small.png │ ├── purple big_r.png │ ├── purple small.png │ ├── red big_sr.png │ ├── red small.png │ ├── yellow big.png │ └── yellow small.png ├── iris │ ├── large.png │ ├── medium.png │ └── small.png ├── shine │ └── shapes.png └── top lid │ ├── high top.png │ ├── low top.png │ └── tilted top_r.png ├── package-lock.json ├── package.json └── src ├── config.js ├── main.js └── preview.png /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .eslintcache 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | /.idea 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 HashLips 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Welcome to HashLips 👄 2 | 3 | Important: There is a new repo for this code. 4 | [https://github.com/HashLips/hashlips_art_engine](https://github.com/HashLips/hashlips_art_engine) 5 | 6 | All the code in these repos was created and explained by HashLips on the main YouTube channel. 7 | 8 | To find out more please visit: 9 | 10 | [📺 YouTube](https://www.youtube.com/channel/UC1LV4_VQGBJHTJjEWUmy8nA) 11 | 12 | [👄 Discord](https://discord.com/invite/qh6MWhMJDN) 13 | 14 | [💬 Telegram](https://t.me/hashlipsnft) 15 | 16 | [🐦 Twitter](https://twitter.com/hashlipsnft) 17 | 18 | [ℹ️ Website](https://hashlips.online/HashLips) 19 | 20 | # generative-art-node 21 | 22 | Create generative art by using the canvas api and node js 23 | 24 | ![](https://github.com/HashLips/generative-art-node/blob/main/src/preview.png) 25 | 26 | ## Installation 27 | 28 | ```sh 29 | git clone https://github.com/HashLips/generative-art-node 30 | 31 | yarn install 32 | ``` 33 | 34 | ## Usage 35 | 36 | Create your different layers as folders in the 'layers' directory, and add all the layer assets in these directories. Optionally, append '_r' and '_sr' to the layer file names to make those layer files rare or super rare respectively. 37 | 38 | *Example:* If you had an ball layer you would create a ball directory, and then a file might be called: 39 | 40 | - `red_eye_ball_sr.png` 41 | - `red_eye_ball_r.png` 42 | - `red_eye_ball.png` 43 | 44 | > Rarity is customizable in `src/config.js`. 45 | 46 | Once you have all your layers, go into `src/config.js` and update the `layersOrder` array to be your layer folders name in order of the back layer to the front layer. 47 | 48 | *Example:* If you were creating a portrait design, you might have a background, then a head, a mouth, eyes, eyewear, and then headwear, so your `layersOrder` would look something like this: 49 | 50 | ```js 51 | const layersOrder = [ 52 | { name: 'background', number: 1 }, 53 | { name: 'ball', number: 2 }, 54 | { name: 'eye color', number: 12 }, 55 | { name: 'iris', number: 3 }, 56 | { name: 'shine', number: 1 }, 57 | { name: 'bottom lid', number: 3 }, 58 | { name: 'top lid', number: 3 }, 59 | ]; 60 | ``` 61 | 62 | The `name` of each layer object represents the name of the folder (in `/layers/`) that the images reside in. The `number` of each layer object represents the total number of image files you want to select from (possibly including blanks.) For instance, if you have three images in a layer folder and want to pick one of those each time, the `number` should be `3`. If you have a single image in a layer that you want to increase the rarity of to 1 in 100, the `number` for that layer should be `100`. In this case, 99 times out of 100, you will get a completely transparent layer. 63 | 64 | Then optionally, update your `format` size, ie the outputted image size, and the defaultEdition, which is the amount of variation outputted. 65 | 66 | When you are all ready, run the following command and your outputted art will be in the `build` directory: 67 | 68 | ```sh 69 | npm run build 70 | ``` 71 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const myArgs = process.argv.slice(2); 2 | const { buildSetup, createFiles, createMetaData } = require("./src/main.js"); 3 | const { defaultEdition } = require("./src/config.js"); 4 | const edition = myArgs.length > 0 ? Number(myArgs[0]) : defaultEdition; 5 | 6 | (() => { 7 | buildSetup(); 8 | createFiles(edition); 9 | createMetaData(); 10 | })(); 11 | 12 | -------------------------------------------------------------------------------- /layers/background/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/background/black.png -------------------------------------------------------------------------------- /layers/ball/red eye ball_sr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/ball/red eye ball_sr.png -------------------------------------------------------------------------------- /layers/ball/white eye ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/ball/white eye ball.png -------------------------------------------------------------------------------- /layers/bottom lid/high bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/bottom lid/high bottom.png -------------------------------------------------------------------------------- /layers/bottom lid/low bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/bottom lid/low bottom.png -------------------------------------------------------------------------------- /layers/bottom lid/tilted bottom_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/bottom lid/tilted bottom_r.png -------------------------------------------------------------------------------- /layers/eye color/cyan big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/cyan big.png -------------------------------------------------------------------------------- /layers/eye color/cyan small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/cyan small.png -------------------------------------------------------------------------------- /layers/eye color/green big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/green big.png -------------------------------------------------------------------------------- /layers/eye color/green small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/green small.png -------------------------------------------------------------------------------- /layers/eye color/pink big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/pink big.png -------------------------------------------------------------------------------- /layers/eye color/pink small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/pink small.png -------------------------------------------------------------------------------- /layers/eye color/purple big_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/purple big_r.png -------------------------------------------------------------------------------- /layers/eye color/purple small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/purple small.png -------------------------------------------------------------------------------- /layers/eye color/red big_sr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/red big_sr.png -------------------------------------------------------------------------------- /layers/eye color/red small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/red small.png -------------------------------------------------------------------------------- /layers/eye color/yellow big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/yellow big.png -------------------------------------------------------------------------------- /layers/eye color/yellow small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/eye color/yellow small.png -------------------------------------------------------------------------------- /layers/iris/large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/iris/large.png -------------------------------------------------------------------------------- /layers/iris/medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/iris/medium.png -------------------------------------------------------------------------------- /layers/iris/small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/iris/small.png -------------------------------------------------------------------------------- /layers/shine/shapes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/shine/shapes.png -------------------------------------------------------------------------------- /layers/top lid/high top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/top lid/high top.png -------------------------------------------------------------------------------- /layers/top lid/low top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/top lid/low top.png -------------------------------------------------------------------------------- /layers/top lid/tilted top_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/layers/top lid/tilted top_r.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "art_generator", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "art_generator", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "canvas": "^2.8.0" 13 | } 14 | }, 15 | "node_modules/@mapbox/node-pre-gyp": { 16 | "version": "1.0.5", 17 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", 18 | "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", 19 | "dependencies": { 20 | "detect-libc": "^1.0.3", 21 | "https-proxy-agent": "^5.0.0", 22 | "make-dir": "^3.1.0", 23 | "node-fetch": "^2.6.1", 24 | "nopt": "^5.0.0", 25 | "npmlog": "^4.1.2", 26 | "rimraf": "^3.0.2", 27 | "semver": "^7.3.4", 28 | "tar": "^6.1.0" 29 | }, 30 | "bin": { 31 | "node-pre-gyp": "bin/node-pre-gyp" 32 | } 33 | }, 34 | "node_modules/abbrev": { 35 | "version": "1.1.1", 36 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 37 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 38 | }, 39 | "node_modules/agent-base": { 40 | "version": "6.0.2", 41 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 42 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 43 | "dependencies": { 44 | "debug": "4" 45 | }, 46 | "engines": { 47 | "node": ">= 6.0.0" 48 | } 49 | }, 50 | "node_modules/ansi-regex": { 51 | "version": "2.1.1", 52 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 53 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 54 | "engines": { 55 | "node": ">=0.10.0" 56 | } 57 | }, 58 | "node_modules/aproba": { 59 | "version": "1.2.0", 60 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 61 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 62 | }, 63 | "node_modules/are-we-there-yet": { 64 | "version": "1.1.5", 65 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 66 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 67 | "dependencies": { 68 | "delegates": "^1.0.0", 69 | "readable-stream": "^2.0.6" 70 | } 71 | }, 72 | "node_modules/balanced-match": { 73 | "version": "1.0.2", 74 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 75 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 76 | }, 77 | "node_modules/brace-expansion": { 78 | "version": "1.1.11", 79 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 80 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 81 | "dependencies": { 82 | "balanced-match": "^1.0.0", 83 | "concat-map": "0.0.1" 84 | } 85 | }, 86 | "node_modules/canvas": { 87 | "version": "2.8.0", 88 | "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", 89 | "integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==", 90 | "hasInstallScript": true, 91 | "dependencies": { 92 | "@mapbox/node-pre-gyp": "^1.0.0", 93 | "nan": "^2.14.0", 94 | "simple-get": "^3.0.3" 95 | }, 96 | "engines": { 97 | "node": ">=6" 98 | } 99 | }, 100 | "node_modules/chownr": { 101 | "version": "2.0.0", 102 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 103 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", 104 | "engines": { 105 | "node": ">=10" 106 | } 107 | }, 108 | "node_modules/code-point-at": { 109 | "version": "1.1.0", 110 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 111 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 112 | "engines": { 113 | "node": ">=0.10.0" 114 | } 115 | }, 116 | "node_modules/concat-map": { 117 | "version": "0.0.1", 118 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 119 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 120 | }, 121 | "node_modules/console-control-strings": { 122 | "version": "1.1.0", 123 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 124 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 125 | }, 126 | "node_modules/core-util-is": { 127 | "version": "1.0.2", 128 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 129 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 130 | }, 131 | "node_modules/debug": { 132 | "version": "4.3.2", 133 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 134 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 135 | "dependencies": { 136 | "ms": "2.1.2" 137 | }, 138 | "engines": { 139 | "node": ">=6.0" 140 | }, 141 | "peerDependenciesMeta": { 142 | "supports-color": { 143 | "optional": true 144 | } 145 | } 146 | }, 147 | "node_modules/decompress-response": { 148 | "version": "4.2.1", 149 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", 150 | "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", 151 | "dependencies": { 152 | "mimic-response": "^2.0.0" 153 | }, 154 | "engines": { 155 | "node": ">=8" 156 | } 157 | }, 158 | "node_modules/delegates": { 159 | "version": "1.0.0", 160 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 161 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 162 | }, 163 | "node_modules/detect-libc": { 164 | "version": "1.0.3", 165 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 166 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", 167 | "bin": { 168 | "detect-libc": "bin/detect-libc.js" 169 | }, 170 | "engines": { 171 | "node": ">=0.10" 172 | } 173 | }, 174 | "node_modules/fs-minipass": { 175 | "version": "2.1.0", 176 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 177 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 178 | "dependencies": { 179 | "minipass": "^3.0.0" 180 | }, 181 | "engines": { 182 | "node": ">= 8" 183 | } 184 | }, 185 | "node_modules/fs.realpath": { 186 | "version": "1.0.0", 187 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 188 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 189 | }, 190 | "node_modules/gauge": { 191 | "version": "2.7.4", 192 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 193 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 194 | "dependencies": { 195 | "aproba": "^1.0.3", 196 | "console-control-strings": "^1.0.0", 197 | "has-unicode": "^2.0.0", 198 | "object-assign": "^4.1.0", 199 | "signal-exit": "^3.0.0", 200 | "string-width": "^1.0.1", 201 | "strip-ansi": "^3.0.1", 202 | "wide-align": "^1.1.0" 203 | } 204 | }, 205 | "node_modules/glob": { 206 | "version": "7.1.7", 207 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", 208 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", 209 | "dependencies": { 210 | "fs.realpath": "^1.0.0", 211 | "inflight": "^1.0.4", 212 | "inherits": "2", 213 | "minimatch": "^3.0.4", 214 | "once": "^1.3.0", 215 | "path-is-absolute": "^1.0.0" 216 | }, 217 | "engines": { 218 | "node": "*" 219 | }, 220 | "funding": { 221 | "url": "https://github.com/sponsors/isaacs" 222 | } 223 | }, 224 | "node_modules/has-unicode": { 225 | "version": "2.0.1", 226 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 227 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 228 | }, 229 | "node_modules/https-proxy-agent": { 230 | "version": "5.0.0", 231 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 232 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 233 | "dependencies": { 234 | "agent-base": "6", 235 | "debug": "4" 236 | }, 237 | "engines": { 238 | "node": ">= 6" 239 | } 240 | }, 241 | "node_modules/inflight": { 242 | "version": "1.0.6", 243 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 244 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 245 | "dependencies": { 246 | "once": "^1.3.0", 247 | "wrappy": "1" 248 | } 249 | }, 250 | "node_modules/inherits": { 251 | "version": "2.0.4", 252 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 253 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 254 | }, 255 | "node_modules/is-fullwidth-code-point": { 256 | "version": "1.0.0", 257 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 258 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 259 | "dependencies": { 260 | "number-is-nan": "^1.0.0" 261 | }, 262 | "engines": { 263 | "node": ">=0.10.0" 264 | } 265 | }, 266 | "node_modules/isarray": { 267 | "version": "1.0.0", 268 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 269 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 270 | }, 271 | "node_modules/lru-cache": { 272 | "version": "6.0.0", 273 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 274 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 275 | "dependencies": { 276 | "yallist": "^4.0.0" 277 | }, 278 | "engines": { 279 | "node": ">=10" 280 | } 281 | }, 282 | "node_modules/make-dir": { 283 | "version": "3.1.0", 284 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 285 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 286 | "dependencies": { 287 | "semver": "^6.0.0" 288 | }, 289 | "engines": { 290 | "node": ">=8" 291 | }, 292 | "funding": { 293 | "url": "https://github.com/sponsors/sindresorhus" 294 | } 295 | }, 296 | "node_modules/make-dir/node_modules/semver": { 297 | "version": "6.3.0", 298 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 299 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 300 | "bin": { 301 | "semver": "bin/semver.js" 302 | } 303 | }, 304 | "node_modules/mimic-response": { 305 | "version": "2.1.0", 306 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", 307 | "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", 308 | "engines": { 309 | "node": ">=8" 310 | }, 311 | "funding": { 312 | "url": "https://github.com/sponsors/sindresorhus" 313 | } 314 | }, 315 | "node_modules/minimatch": { 316 | "version": "3.0.4", 317 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 318 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 319 | "dependencies": { 320 | "brace-expansion": "^1.1.7" 321 | }, 322 | "engines": { 323 | "node": "*" 324 | } 325 | }, 326 | "node_modules/minipass": { 327 | "version": "3.1.3", 328 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", 329 | "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", 330 | "dependencies": { 331 | "yallist": "^4.0.0" 332 | }, 333 | "engines": { 334 | "node": ">=8" 335 | } 336 | }, 337 | "node_modules/minizlib": { 338 | "version": "2.1.2", 339 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 340 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 341 | "dependencies": { 342 | "minipass": "^3.0.0", 343 | "yallist": "^4.0.0" 344 | }, 345 | "engines": { 346 | "node": ">= 8" 347 | } 348 | }, 349 | "node_modules/mkdirp": { 350 | "version": "1.0.4", 351 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 352 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 353 | "bin": { 354 | "mkdirp": "bin/cmd.js" 355 | }, 356 | "engines": { 357 | "node": ">=10" 358 | } 359 | }, 360 | "node_modules/ms": { 361 | "version": "2.1.2", 362 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 363 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 364 | }, 365 | "node_modules/nan": { 366 | "version": "2.15.0", 367 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", 368 | "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" 369 | }, 370 | "node_modules/node-fetch": { 371 | "version": "2.6.1", 372 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 373 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", 374 | "engines": { 375 | "node": "4.x || >=6.0.0" 376 | } 377 | }, 378 | "node_modules/nopt": { 379 | "version": "5.0.0", 380 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", 381 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", 382 | "dependencies": { 383 | "abbrev": "1" 384 | }, 385 | "bin": { 386 | "nopt": "bin/nopt.js" 387 | }, 388 | "engines": { 389 | "node": ">=6" 390 | } 391 | }, 392 | "node_modules/npmlog": { 393 | "version": "4.1.2", 394 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 395 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 396 | "dependencies": { 397 | "are-we-there-yet": "~1.1.2", 398 | "console-control-strings": "~1.1.0", 399 | "gauge": "~2.7.3", 400 | "set-blocking": "~2.0.0" 401 | } 402 | }, 403 | "node_modules/number-is-nan": { 404 | "version": "1.0.1", 405 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 406 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 407 | "engines": { 408 | "node": ">=0.10.0" 409 | } 410 | }, 411 | "node_modules/object-assign": { 412 | "version": "4.1.1", 413 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 414 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 415 | "engines": { 416 | "node": ">=0.10.0" 417 | } 418 | }, 419 | "node_modules/once": { 420 | "version": "1.4.0", 421 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 422 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 423 | "dependencies": { 424 | "wrappy": "1" 425 | } 426 | }, 427 | "node_modules/path-is-absolute": { 428 | "version": "1.0.1", 429 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 430 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 431 | "engines": { 432 | "node": ">=0.10.0" 433 | } 434 | }, 435 | "node_modules/process-nextick-args": { 436 | "version": "2.0.1", 437 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 438 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 439 | }, 440 | "node_modules/readable-stream": { 441 | "version": "2.3.7", 442 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 443 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 444 | "dependencies": { 445 | "core-util-is": "~1.0.0", 446 | "inherits": "~2.0.3", 447 | "isarray": "~1.0.0", 448 | "process-nextick-args": "~2.0.0", 449 | "safe-buffer": "~5.1.1", 450 | "string_decoder": "~1.1.1", 451 | "util-deprecate": "~1.0.1" 452 | } 453 | }, 454 | "node_modules/rimraf": { 455 | "version": "3.0.2", 456 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 457 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 458 | "dependencies": { 459 | "glob": "^7.1.3" 460 | }, 461 | "bin": { 462 | "rimraf": "bin.js" 463 | }, 464 | "funding": { 465 | "url": "https://github.com/sponsors/isaacs" 466 | } 467 | }, 468 | "node_modules/safe-buffer": { 469 | "version": "5.1.2", 470 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 471 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 472 | }, 473 | "node_modules/semver": { 474 | "version": "7.3.5", 475 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 476 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 477 | "dependencies": { 478 | "lru-cache": "^6.0.0" 479 | }, 480 | "bin": { 481 | "semver": "bin/semver.js" 482 | }, 483 | "engines": { 484 | "node": ">=10" 485 | } 486 | }, 487 | "node_modules/set-blocking": { 488 | "version": "2.0.0", 489 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 490 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 491 | }, 492 | "node_modules/signal-exit": { 493 | "version": "3.0.3", 494 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 495 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 496 | }, 497 | "node_modules/simple-concat": { 498 | "version": "1.0.1", 499 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 500 | "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", 501 | "funding": [ 502 | { 503 | "type": "github", 504 | "url": "https://github.com/sponsors/feross" 505 | }, 506 | { 507 | "type": "patreon", 508 | "url": "https://www.patreon.com/feross" 509 | }, 510 | { 511 | "type": "consulting", 512 | "url": "https://feross.org/support" 513 | } 514 | ] 515 | }, 516 | "node_modules/simple-get": { 517 | "version": "3.1.0", 518 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", 519 | "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", 520 | "dependencies": { 521 | "decompress-response": "^4.2.0", 522 | "once": "^1.3.1", 523 | "simple-concat": "^1.0.0" 524 | } 525 | }, 526 | "node_modules/string_decoder": { 527 | "version": "1.1.1", 528 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 529 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 530 | "dependencies": { 531 | "safe-buffer": "~5.1.0" 532 | } 533 | }, 534 | "node_modules/string-width": { 535 | "version": "1.0.2", 536 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 537 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 538 | "dependencies": { 539 | "code-point-at": "^1.0.0", 540 | "is-fullwidth-code-point": "^1.0.0", 541 | "strip-ansi": "^3.0.0" 542 | }, 543 | "engines": { 544 | "node": ">=0.10.0" 545 | } 546 | }, 547 | "node_modules/strip-ansi": { 548 | "version": "3.0.1", 549 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 550 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 551 | "dependencies": { 552 | "ansi-regex": "^2.0.0" 553 | }, 554 | "engines": { 555 | "node": ">=0.10.0" 556 | } 557 | }, 558 | "node_modules/tar": { 559 | "version": "6.1.11", 560 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", 561 | "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", 562 | "dependencies": { 563 | "chownr": "^2.0.0", 564 | "fs-minipass": "^2.0.0", 565 | "minipass": "^3.0.0", 566 | "minizlib": "^2.1.1", 567 | "mkdirp": "^1.0.3", 568 | "yallist": "^4.0.0" 569 | }, 570 | "engines": { 571 | "node": ">= 10" 572 | } 573 | }, 574 | "node_modules/util-deprecate": { 575 | "version": "1.0.2", 576 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 577 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 578 | }, 579 | "node_modules/wide-align": { 580 | "version": "1.1.3", 581 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 582 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 583 | "dependencies": { 584 | "string-width": "^1.0.2 || 2" 585 | } 586 | }, 587 | "node_modules/wrappy": { 588 | "version": "1.0.2", 589 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 590 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 591 | }, 592 | "node_modules/yallist": { 593 | "version": "4.0.0", 594 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 595 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 596 | } 597 | }, 598 | "dependencies": { 599 | "@mapbox/node-pre-gyp": { 600 | "version": "1.0.5", 601 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", 602 | "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", 603 | "requires": { 604 | "detect-libc": "^1.0.3", 605 | "https-proxy-agent": "^5.0.0", 606 | "make-dir": "^3.1.0", 607 | "node-fetch": "^2.6.1", 608 | "nopt": "^5.0.0", 609 | "npmlog": "^4.1.2", 610 | "rimraf": "^3.0.2", 611 | "semver": "^7.3.4", 612 | "tar": "^6.1.0" 613 | } 614 | }, 615 | "abbrev": { 616 | "version": "1.1.1", 617 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 618 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 619 | }, 620 | "agent-base": { 621 | "version": "6.0.2", 622 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 623 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 624 | "requires": { 625 | "debug": "4" 626 | } 627 | }, 628 | "ansi-regex": { 629 | "version": "2.1.1", 630 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 631 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 632 | }, 633 | "aproba": { 634 | "version": "1.2.0", 635 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 636 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 637 | }, 638 | "are-we-there-yet": { 639 | "version": "1.1.5", 640 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 641 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 642 | "requires": { 643 | "delegates": "^1.0.0", 644 | "readable-stream": "^2.0.6" 645 | } 646 | }, 647 | "balanced-match": { 648 | "version": "1.0.2", 649 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 650 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 651 | }, 652 | "brace-expansion": { 653 | "version": "1.1.11", 654 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 655 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 656 | "requires": { 657 | "balanced-match": "^1.0.0", 658 | "concat-map": "0.0.1" 659 | } 660 | }, 661 | "canvas": { 662 | "version": "2.8.0", 663 | "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.8.0.tgz", 664 | "integrity": "sha512-gLTi17X8WY9Cf5GZ2Yns8T5lfBOcGgFehDFb+JQwDqdOoBOcECS9ZWMEAqMSVcMYwXD659J8NyzjRY/2aE+C2Q==", 665 | "requires": { 666 | "@mapbox/node-pre-gyp": "^1.0.0", 667 | "nan": "^2.14.0", 668 | "simple-get": "^3.0.3" 669 | } 670 | }, 671 | "chownr": { 672 | "version": "2.0.0", 673 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 674 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" 675 | }, 676 | "code-point-at": { 677 | "version": "1.1.0", 678 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 679 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 680 | }, 681 | "concat-map": { 682 | "version": "0.0.1", 683 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 684 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 685 | }, 686 | "console-control-strings": { 687 | "version": "1.1.0", 688 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 689 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 690 | }, 691 | "core-util-is": { 692 | "version": "1.0.2", 693 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 694 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 695 | }, 696 | "debug": { 697 | "version": "4.3.2", 698 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 699 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 700 | "requires": { 701 | "ms": "2.1.2" 702 | } 703 | }, 704 | "decompress-response": { 705 | "version": "4.2.1", 706 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", 707 | "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", 708 | "requires": { 709 | "mimic-response": "^2.0.0" 710 | } 711 | }, 712 | "delegates": { 713 | "version": "1.0.0", 714 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 715 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 716 | }, 717 | "detect-libc": { 718 | "version": "1.0.3", 719 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 720 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 721 | }, 722 | "fs-minipass": { 723 | "version": "2.1.0", 724 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 725 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 726 | "requires": { 727 | "minipass": "^3.0.0" 728 | } 729 | }, 730 | "fs.realpath": { 731 | "version": "1.0.0", 732 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 733 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 734 | }, 735 | "gauge": { 736 | "version": "2.7.4", 737 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 738 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 739 | "requires": { 740 | "aproba": "^1.0.3", 741 | "console-control-strings": "^1.0.0", 742 | "has-unicode": "^2.0.0", 743 | "object-assign": "^4.1.0", 744 | "signal-exit": "^3.0.0", 745 | "string-width": "^1.0.1", 746 | "strip-ansi": "^3.0.1", 747 | "wide-align": "^1.1.0" 748 | } 749 | }, 750 | "glob": { 751 | "version": "7.1.7", 752 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", 753 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", 754 | "requires": { 755 | "fs.realpath": "^1.0.0", 756 | "inflight": "^1.0.4", 757 | "inherits": "2", 758 | "minimatch": "^3.0.4", 759 | "once": "^1.3.0", 760 | "path-is-absolute": "^1.0.0" 761 | } 762 | }, 763 | "has-unicode": { 764 | "version": "2.0.1", 765 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 766 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 767 | }, 768 | "https-proxy-agent": { 769 | "version": "5.0.0", 770 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 771 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 772 | "requires": { 773 | "agent-base": "6", 774 | "debug": "4" 775 | } 776 | }, 777 | "inflight": { 778 | "version": "1.0.6", 779 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 780 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 781 | "requires": { 782 | "once": "^1.3.0", 783 | "wrappy": "1" 784 | } 785 | }, 786 | "inherits": { 787 | "version": "2.0.4", 788 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 789 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 790 | }, 791 | "is-fullwidth-code-point": { 792 | "version": "1.0.0", 793 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 794 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 795 | "requires": { 796 | "number-is-nan": "^1.0.0" 797 | } 798 | }, 799 | "isarray": { 800 | "version": "1.0.0", 801 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 802 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 803 | }, 804 | "lru-cache": { 805 | "version": "6.0.0", 806 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 807 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 808 | "requires": { 809 | "yallist": "^4.0.0" 810 | } 811 | }, 812 | "make-dir": { 813 | "version": "3.1.0", 814 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 815 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 816 | "requires": { 817 | "semver": "^6.0.0" 818 | }, 819 | "dependencies": { 820 | "semver": { 821 | "version": "6.3.0", 822 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 823 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 824 | } 825 | } 826 | }, 827 | "mimic-response": { 828 | "version": "2.1.0", 829 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", 830 | "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" 831 | }, 832 | "minimatch": { 833 | "version": "3.0.4", 834 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 835 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 836 | "requires": { 837 | "brace-expansion": "^1.1.7" 838 | } 839 | }, 840 | "minipass": { 841 | "version": "3.1.3", 842 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", 843 | "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", 844 | "requires": { 845 | "yallist": "^4.0.0" 846 | } 847 | }, 848 | "minizlib": { 849 | "version": "2.1.2", 850 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 851 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 852 | "requires": { 853 | "minipass": "^3.0.0", 854 | "yallist": "^4.0.0" 855 | } 856 | }, 857 | "mkdirp": { 858 | "version": "1.0.4", 859 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 860 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" 861 | }, 862 | "ms": { 863 | "version": "2.1.2", 864 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 865 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 866 | }, 867 | "nan": { 868 | "version": "2.15.0", 869 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", 870 | "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" 871 | }, 872 | "node-fetch": { 873 | "version": "2.6.1", 874 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", 875 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" 876 | }, 877 | "nopt": { 878 | "version": "5.0.0", 879 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", 880 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", 881 | "requires": { 882 | "abbrev": "1" 883 | } 884 | }, 885 | "npmlog": { 886 | "version": "4.1.2", 887 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 888 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 889 | "requires": { 890 | "are-we-there-yet": "~1.1.2", 891 | "console-control-strings": "~1.1.0", 892 | "gauge": "~2.7.3", 893 | "set-blocking": "~2.0.0" 894 | } 895 | }, 896 | "number-is-nan": { 897 | "version": "1.0.1", 898 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 899 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 900 | }, 901 | "object-assign": { 902 | "version": "4.1.1", 903 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 904 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 905 | }, 906 | "once": { 907 | "version": "1.4.0", 908 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 909 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 910 | "requires": { 911 | "wrappy": "1" 912 | } 913 | }, 914 | "path-is-absolute": { 915 | "version": "1.0.1", 916 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 917 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 918 | }, 919 | "process-nextick-args": { 920 | "version": "2.0.1", 921 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 922 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 923 | }, 924 | "readable-stream": { 925 | "version": "2.3.7", 926 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 927 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 928 | "requires": { 929 | "core-util-is": "~1.0.0", 930 | "inherits": "~2.0.3", 931 | "isarray": "~1.0.0", 932 | "process-nextick-args": "~2.0.0", 933 | "safe-buffer": "~5.1.1", 934 | "string_decoder": "~1.1.1", 935 | "util-deprecate": "~1.0.1" 936 | } 937 | }, 938 | "rimraf": { 939 | "version": "3.0.2", 940 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 941 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 942 | "requires": { 943 | "glob": "^7.1.3" 944 | } 945 | }, 946 | "safe-buffer": { 947 | "version": "5.1.2", 948 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 949 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 950 | }, 951 | "semver": { 952 | "version": "7.3.5", 953 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 954 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 955 | "requires": { 956 | "lru-cache": "^6.0.0" 957 | } 958 | }, 959 | "set-blocking": { 960 | "version": "2.0.0", 961 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 962 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 963 | }, 964 | "signal-exit": { 965 | "version": "3.0.3", 966 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", 967 | "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" 968 | }, 969 | "simple-concat": { 970 | "version": "1.0.1", 971 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", 972 | "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" 973 | }, 974 | "simple-get": { 975 | "version": "3.1.0", 976 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", 977 | "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", 978 | "requires": { 979 | "decompress-response": "^4.2.0", 980 | "once": "^1.3.1", 981 | "simple-concat": "^1.0.0" 982 | } 983 | }, 984 | "string_decoder": { 985 | "version": "1.1.1", 986 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 987 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 988 | "requires": { 989 | "safe-buffer": "~5.1.0" 990 | } 991 | }, 992 | "string-width": { 993 | "version": "1.0.2", 994 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 995 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 996 | "requires": { 997 | "code-point-at": "^1.0.0", 998 | "is-fullwidth-code-point": "^1.0.0", 999 | "strip-ansi": "^3.0.0" 1000 | } 1001 | }, 1002 | "strip-ansi": { 1003 | "version": "3.0.1", 1004 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1005 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1006 | "requires": { 1007 | "ansi-regex": "^2.0.0" 1008 | } 1009 | }, 1010 | "tar": { 1011 | "version": "6.1.11", 1012 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", 1013 | "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", 1014 | "requires": { 1015 | "chownr": "^2.0.0", 1016 | "fs-minipass": "^2.0.0", 1017 | "minipass": "^3.0.0", 1018 | "minizlib": "^2.1.1", 1019 | "mkdirp": "^1.0.3", 1020 | "yallist": "^4.0.0" 1021 | } 1022 | }, 1023 | "util-deprecate": { 1024 | "version": "1.0.2", 1025 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1026 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1027 | }, 1028 | "wide-align": { 1029 | "version": "1.1.3", 1030 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1031 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1032 | "requires": { 1033 | "string-width": "^1.0.2 || 2" 1034 | } 1035 | }, 1036 | "wrappy": { 1037 | "version": "1.0.2", 1038 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1039 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1040 | }, 1041 | "yallist": { 1042 | "version": "4.0.0", 1043 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1044 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 1045 | } 1046 | } 1047 | } 1048 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "art_generator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "node index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Daniel Eugene Botha", 11 | "license": "ISC", 12 | "dependencies": { 13 | "canvas": "^2.8.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/config.js: -------------------------------------------------------------------------------- 1 | const layersOrder = [ 2 | { name: 'background', number: 1 }, 3 | { name: 'ball', number: 2 }, 4 | { name: 'eye color', number: 12 }, 5 | { name: 'iris', number: 3 }, 6 | { name: 'shine', number: 1 }, 7 | { name: 'shine', number: 1 }, 8 | { name: 'bottom lid', number: 3 }, 9 | { name: 'top lid', number: 3 }, 10 | ]; 11 | 12 | const format = { 13 | width: 230, 14 | height: 230 15 | }; 16 | 17 | const rarity = [ 18 | { key: "", val: "original" }, 19 | { key: "_r", val: "rare" }, 20 | { key: "_sr", val: "super rare" }, 21 | ]; 22 | 23 | const defaultEdition = 5; 24 | 25 | module.exports = { layersOrder, format, rarity, defaultEdition }; -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const { createCanvas, loadImage } = require("canvas"); 3 | const console = require("console"); 4 | const { layersOrder, format, rarity } = require("./config.js"); 5 | 6 | const canvas = createCanvas(format.width, format.height); 7 | const ctx = canvas.getContext("2d"); 8 | 9 | if (!process.env.PWD) { 10 | process.env.PWD = process.cwd(); 11 | } 12 | 13 | const buildDir = `${process.env.PWD}/build`; 14 | const metDataFile = '_metadata.json'; 15 | const layersDir = `${process.env.PWD}/layers`; 16 | 17 | let metadata = []; 18 | let attributes = []; 19 | let hash = []; 20 | let decodedHash = []; 21 | const Exists = new Map(); 22 | 23 | 24 | const addRarity = _str => { 25 | let itemRarity; 26 | 27 | rarity.forEach((r) => { 28 | if (_str.includes(r.key)) { 29 | itemRarity = r.val; 30 | } 31 | }); 32 | 33 | return itemRarity; 34 | }; 35 | 36 | const cleanName = _str => { 37 | let name = _str.slice(0, -4); 38 | rarity.forEach((r) => { 39 | name = name.replace(r.key, ""); 40 | }); 41 | return name; 42 | }; 43 | 44 | const getElements = path => { 45 | return fs 46 | .readdirSync(path) 47 | .filter((item) => !/(^|\/)\.[^\/\.]/g.test(item)) 48 | .map((i, index) => { 49 | return { 50 | id: index + 1, 51 | name: cleanName(i), 52 | fileName: i, 53 | rarity: addRarity(i), 54 | }; 55 | }); 56 | }; 57 | 58 | const layersSetup = layersOrder => { 59 | const layers = layersOrder.map((layerObj, index) => ({ 60 | id: index, 61 | name: layerObj.name, 62 | location: `${layersDir}/${layerObj.name}/`, 63 | elements: getElements(`${layersDir}/${layerObj.name}/`), 64 | position: { x: 0, y: 0 }, 65 | size: { width: format.width, height: format.height }, 66 | number: layerObj.number 67 | })); 68 | 69 | return layers; 70 | }; 71 | 72 | const buildSetup = () => { 73 | if (fs.existsSync(buildDir)) { 74 | fs.rmdirSync(buildDir, { recursive: true }); 75 | } 76 | fs.mkdirSync(buildDir); 77 | }; 78 | 79 | const saveLayer = (_canvas, _edition) => { 80 | fs.writeFileSync(`${buildDir}/${_edition}.png`, _canvas.toBuffer("image/png")); 81 | }; 82 | 83 | const addMetadata = _edition => { 84 | let dateTime = Date.now(); 85 | let tempMetadata = { 86 | hash: hash.join(""), 87 | decodedHash: decodedHash, 88 | edition: _edition, 89 | date: dateTime, 90 | attributes: attributes, 91 | }; 92 | metadata.push(tempMetadata); 93 | attributes = []; 94 | hash = []; 95 | decodedHash = []; 96 | }; 97 | 98 | const addAttributes = (_element, _layer) => { 99 | let tempAttr = { 100 | id: _element.id, 101 | layer: _layer.name, 102 | name: _element.name, 103 | rarity: _element.rarity, 104 | }; 105 | attributes.push(tempAttr); 106 | hash.push(_layer.id); 107 | hash.push(_element.id); 108 | decodedHash.push({ [_layer.id]: _element.id }); 109 | }; 110 | 111 | const drawLayer = async (_layer, _edition) => { 112 | const rand = Math.random(); 113 | let element = 114 | _layer.elements[Math.floor(rand * _layer.number)] ? _layer.elements[Math.floor(rand * _layer.number)] : null; 115 | if (element) { 116 | addAttributes(element, _layer); 117 | const image = await loadImage(`${_layer.location}${element.fileName}`); 118 | 119 | ctx.drawImage( 120 | image, 121 | _layer.position.x, 122 | _layer.position.y, 123 | _layer.size.width, 124 | _layer.size.height 125 | ); 126 | saveLayer(canvas, _edition); 127 | } 128 | }; 129 | 130 | const createFiles = async edition => { 131 | const layers = layersSetup(layersOrder); 132 | 133 | let numDupes = 0; 134 | for (let i = 1; i <= edition; i++) { 135 | await layers.forEach(async (layer) => { 136 | await drawLayer(layer, i); 137 | }); 138 | 139 | let key = hash.toString(); 140 | if (Exists.has(key)) { 141 | console.log( 142 | `Duplicate creation for edition ${i}. Same as edition ${Exists.get( 143 | key 144 | )}` 145 | ); 146 | numDupes++; 147 | if (numDupes > edition) break; //prevents infinite loop if no more unique items can be created 148 | i--; 149 | } else { 150 | Exists.set(key, i); 151 | addMetadata(i); 152 | console.log("Creating edition " + i); 153 | } 154 | } 155 | }; 156 | 157 | const createMetaData = () => { 158 | fs.stat(`${buildDir}/${metDataFile}`, (err) => { 159 | if(err == null || err.code === 'ENOENT') { 160 | fs.writeFileSync(`${buildDir}/${metDataFile}`, JSON.stringify(metadata, null, 2)); 161 | } else { 162 | console.log('Oh no, error: ', err.code); 163 | } 164 | }); 165 | }; 166 | 167 | module.exports = { buildSetup, createFiles, createMetaData }; 168 | -------------------------------------------------------------------------------- /src/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HashLips/generative-art-node/c959eb8cfd78c8272308acb77dba4645430004e4/src/preview.png --------------------------------------------------------------------------------