diff --git a/package-lock.json b/package-lock.json index 549ab775..c8129efb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "memory-cache": "^0.2.0", "node-chartist": "^1.0.5", "open-graph-scraper": "^4.7.1", + "png-js": "^1.0.0", "prismjs": "^1.23.0", "puppeteer": "^8.0.0", "rss-parser": "^3.12.0", @@ -39,6 +40,9 @@ "jest": "^26.6.3", "libxmljs2": "^0.26.6", "nodemon": "^2.0.7" + }, + "optionalDependencies": { + "gifencoder": "^2.0.1" } }, "node_modules/@actions/core": { @@ -1890,7 +1894,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "devOptional": true }, "node_modules/accepts": { "version": "1.3.7", @@ -2109,13 +2113,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "devOptional": true }, "node_modules/are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, + "devOptional": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -2845,6 +2849,64 @@ "integrity": "sha512-iDUOH+oFeBYk5XawYsPtsx/8fFpndAPUQJC7gBTfxHM8xw5nOZv7ceAD4frS1MKCLUac7QL5wdAJiFQlDRjXlA==", "dev": true }, + "node_modules/canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.7.0.tgz", + "integrity": "sha512-pzCxtkHb+5su5MQjTtepMDlIOtaXo277x0C0u3nMOxtkhTyQ+h2yNKhlROAaDllWgRyePAUitC08sXw26Eb6aw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "nan": "^2.14.0", + "node-pre-gyp": "^0.15.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/canvas/node_modules/node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/canvas/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/canvas/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -3056,7 +3118,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -3192,7 +3254,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "devOptional": true }, "node_modules/content-disposition": { "version": "0.5.3", @@ -3433,7 +3495,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, + "devOptional": true, "engines": { "node": ">=4.0.0" } @@ -3529,7 +3591,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "devOptional": true }, "node_modules/depd": { "version": "1.1.2", @@ -3553,7 +3615,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, + "devOptional": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -4808,7 +4870,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, + "devOptional": true, "dependencies": { "minipass": "^2.6.0" } @@ -4846,7 +4908,7 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, + "devOptional": true, "dependencies": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -4862,7 +4924,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -4871,7 +4933,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, + "devOptional": true, "dependencies": { "number-is-nan": "^1.0.0" }, @@ -4883,7 +4945,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, + "devOptional": true, "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4897,7 +4959,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + "devOptional": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -4961,6 +5023,15 @@ "assert-plus": "^1.0.0" } }, + "node_modules/gifencoder": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gifencoder/-/gifencoder-2.0.1.tgz", + "integrity": "sha512-x19DcyWY10SkshBpokqFOo/HBht9GB75evRYvaLMbez9p+yB/o+kt0fK9AwW59nFiAMs2UUQsjv1lX/hvu9Ong==", + "optional": true, + "dependencies": { + "canvas": "^2.2.0" + } + }, "node_modules/gifwrap": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", @@ -5123,7 +5194,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "devOptional": true }, "node_modules/has-value": { "version": "1.0.0", @@ -5362,7 +5433,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, + "devOptional": true, "dependencies": { "minimatch": "^3.0.4" } @@ -5440,7 +5511,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "devOptional": true }, "node_modules/ip-regex": { "version": "2.1.0", @@ -7905,7 +7976,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, + "devOptional": true, "dependencies": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7915,13 +7986,13 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true }, "node_modules/minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, + "devOptional": true, "dependencies": { "minipass": "^2.9.0" } @@ -7988,7 +8059,7 @@ "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true + "devOptional": true }, "node_modules/nanomatch": { "version": "1.2.13", @@ -8022,7 +8093,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", - "dev": true, + "devOptional": true, "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -8039,7 +8110,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "devOptional": true, "dependencies": { "ms": "^2.1.1" } @@ -8048,7 +8119,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "devOptional": true }, "node_modules/negotiator": { "version": "0.6.2", @@ -8346,7 +8417,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, + "devOptional": true, "dependencies": { "abbrev": "1", "osenv": "^0.1.4" @@ -8397,7 +8468,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, + "devOptional": true, "dependencies": { "npm-normalize-package-bin": "^1.0.1" } @@ -8406,13 +8477,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true + "devOptional": true }, "node_modules/npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, + "devOptional": true, "dependencies": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1", @@ -8444,7 +8515,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, + "devOptional": true, "dependencies": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -8464,7 +8535,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8492,7 +8563,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8663,7 +8734,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8672,7 +8743,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -8681,7 +8752,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, + "devOptional": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -9094,6 +9165,11 @@ "node": ">=8" } }, + "node_modules/png-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz", + "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==" + }, "node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -9387,7 +9463,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, + "devOptional": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -9402,7 +9478,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.10.0" } @@ -10059,7 +10135,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "devOptional": true }, "node_modules/set-value": { "version": "2.0.1", @@ -10142,7 +10218,62 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "devOptional": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/simple-git": { "version": "2.36.0", @@ -10905,7 +11036,7 @@ "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, + "devOptional": true, "dependencies": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -10962,7 +11093,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true }, "node_modules/term-size": { "version": "2.2.1", @@ -11710,7 +11841,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, + "devOptional": true, "dependencies": { "string-width": "^1.0.2 || 2" } @@ -11719,7 +11850,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -11728,7 +11859,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, + "devOptional": true, "engines": { "node": ">=4" } @@ -11737,7 +11868,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, + "devOptional": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -11750,7 +11881,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, + "devOptional": true, "dependencies": { "ansi-regex": "^3.0.0" }, @@ -13668,7 +13799,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "devOptional": true }, "accepts": { "version": "1.3.7", @@ -13845,13 +13976,13 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "devOptional": true }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, + "devOptional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -14452,6 +14583,52 @@ "integrity": "sha512-iDUOH+oFeBYk5XawYsPtsx/8fFpndAPUQJC7gBTfxHM8xw5nOZv7ceAD4frS1MKCLUac7QL5wdAJiFQlDRjXlA==", "dev": true }, + "canvas": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.7.0.tgz", + "integrity": "sha512-pzCxtkHb+5su5MQjTtepMDlIOtaXo277x0C0u3nMOxtkhTyQ+h2yNKhlROAaDllWgRyePAUitC08sXw26Eb6aw==", + "optional": true, + "requires": { + "nan": "^2.14.0", + "node-pre-gyp": "^0.15.0", + "simple-get": "^3.0.3" + }, + "dependencies": { + "node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "optional": true + } + } + }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -14631,7 +14808,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "devOptional": true }, "collect-v8-coverage": { "version": "1.0.1", @@ -14743,7 +14920,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "devOptional": true }, "content-disposition": { "version": "0.5.3", @@ -14940,7 +15117,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "devOptional": true }, "deep-is": { "version": "0.1.3", @@ -15014,7 +15191,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "devOptional": true }, "depd": { "version": "1.1.2", @@ -15035,7 +15212,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true + "devOptional": true }, "detect-newline": { "version": "3.1.0", @@ -16044,7 +16221,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, + "devOptional": true, "requires": { "minipass": "^2.6.0" } @@ -16076,7 +16253,7 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, + "devOptional": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -16092,13 +16269,13 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "devOptional": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, + "devOptional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -16107,7 +16284,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, + "devOptional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -16118,7 +16295,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, + "devOptional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -16166,6 +16343,15 @@ "assert-plus": "^1.0.0" } }, + "gifencoder": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gifencoder/-/gifencoder-2.0.1.tgz", + "integrity": "sha512-x19DcyWY10SkshBpokqFOo/HBht9GB75evRYvaLMbez9p+yB/o+kt0fK9AwW59nFiAMs2UUQsjv1lX/hvu9Ong==", + "optional": true, + "requires": { + "canvas": "^2.2.0" + } + }, "gifwrap": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.2.tgz", @@ -16303,7 +16489,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "devOptional": true }, "has-value": { "version": "1.0.0", @@ -16497,7 +16683,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, + "devOptional": true, "requires": { "minimatch": "^3.0.4" } @@ -16557,7 +16743,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "devOptional": true }, "ip-regex": { "version": "2.1.0", @@ -18538,7 +18724,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, + "devOptional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -18548,7 +18734,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true } } }, @@ -18556,7 +18742,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, + "devOptional": true, "requires": { "minipass": "^2.9.0" } @@ -18613,7 +18799,7 @@ "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true + "devOptional": true }, "nanomatch": { "version": "1.2.13", @@ -18644,7 +18830,7 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", - "dev": true, + "devOptional": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -18655,7 +18841,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, + "devOptional": true, "requires": { "ms": "^2.1.1" } @@ -18664,7 +18850,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "devOptional": true } } }, @@ -18935,7 +19121,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, + "devOptional": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" @@ -18976,7 +19162,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, + "devOptional": true, "requires": { "npm-normalize-package-bin": "^1.0.1" } @@ -18985,13 +19171,13 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true + "devOptional": true }, "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, + "devOptional": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1", @@ -19019,7 +19205,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, + "devOptional": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -19039,7 +19225,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "devOptional": true }, "nwmatcher": { "version": "1.4.4", @@ -19061,7 +19247,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "devOptional": true }, "object-copy": { "version": "0.1.0", @@ -19197,19 +19383,19 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "devOptional": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "devOptional": true }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, + "devOptional": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -19548,6 +19734,11 @@ "find-up": "^4.0.0" } }, + "png-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz", + "integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==" + }, "pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -19784,7 +19975,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, + "devOptional": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -19796,7 +19987,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "devOptional": true } } }, @@ -20343,7 +20534,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "devOptional": true }, "set-value": { "version": "2.0.1", @@ -20413,7 +20604,41 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "devOptional": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "optional": true + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "optional": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + }, + "dependencies": { + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true + } + } }, "simple-git": { "version": "2.36.0", @@ -21033,7 +21258,7 @@ "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, + "devOptional": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -21048,7 +21273,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "devOptional": true } } }, @@ -21698,7 +21923,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, + "devOptional": true, "requires": { "string-width": "^1.0.2 || 2" }, @@ -21707,19 +21932,19 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "devOptional": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "devOptional": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, + "devOptional": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -21729,7 +21954,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, + "devOptional": true, "requires": { "ansi-regex": "^3.0.0" } diff --git a/package.json b/package.json index f27a325c..31339342 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "memory-cache": "^0.2.0", "node-chartist": "^1.0.5", "open-graph-scraper": "^4.7.1", + "png-js": "^1.0.0", "prismjs": "^1.23.0", "puppeteer": "^8.0.0", "rss-parser": "^3.12.0", @@ -58,5 +59,8 @@ "testEnvironment": "node", "testTimeout": 60000, "transform": {} + }, + "optionalDependencies": { + "gifencoder": "^2.0.1" } } diff --git a/source/app/metrics/utils.mjs b/source/app/metrics/utils.mjs index 2964d3d7..27f5f7b1 100644 --- a/source/app/metrics/utils.mjs +++ b/source/app/metrics/utils.mjs @@ -1,5 +1,6 @@ //Imports import fs from "fs/promises" + import fss from "fs" import os from "os" import paths from "path" import url from "url" @@ -13,6 +14,8 @@ import opengraph from "open-graph-scraper" import rss from "rss-parser" import nodechartist from "node-chartist" + import GIFEncoder from "gifencoder" + import PNG from "png-js" //Exports export {fs, os, paths, url, util, processes, axios, puppeteer, git, opengraph, rss} @@ -257,7 +260,7 @@ await new Promise(solve => setTimeout(solve, seconds*1000)) //eslint-disable-line no-promise-executor-return } -/**Create gif from puppeteer browser */ +/**Create record from puppeteer browser */ export async function record({page, width, height, frames, scale = 1, quality = 80, x = 0, y = 0, delay = 150}) { //Register images frames const images = [] @@ -271,4 +274,33 @@ //Post-processing console.debug("metrics/record > applying post-processing") return Promise.all(images.map(async buffer => (await jimp.read(buffer)).scale(scale).quality(quality).getBase64Async("image/png"))) + } + +/**Create gif from puppeteer browser*/ + export async function gif({page, width, height, frames, x = 0, y = 0, repeat = true, delay = 150, quality = 10}) { + //Create temporary stream + const path = paths.join(os.tmpdir(), `${Math.round(Math.random()*1000000000)}.gif`) + console.debug(`metrics/puppeteergif > set write stream to "${path}"`) + if (fss.existsSync(path)) + await fs.unlink(path) + //Create encoder + const encoder = new GIFEncoder(width, height) + encoder.createWriteStream().pipe(fss.createWriteStream(path)) + encoder.start() + encoder.setRepeat(repeat ? 0 : -1) + encoder.setDelay(delay) + encoder.setQuality(quality) + //Register frames + for (let i = 0; i < frames; i++) { + const buffer = new PNG(await page.screenshot({clip:{width, height, x, y}})) + encoder.addFrame(await new Promise(solve => buffer.decode(pixels => solve(pixels)))) //eslint-disable-line no-promise-executor-return + if (frames%10 === 0) + console.debug(`metrics/puppeteergif > processed ${i}/${frames} frames`) + } + console.debug(`metrics/puppeteergif > processed ${frames}/${frames} frames`) + //Close encoder and convert to base64 + encoder.finish() + const result = await fs.readFile(path, "base64") + await fs.unlink(path) + return `data:image/gif;base64,${result}` } \ No newline at end of file diff --git a/source/plugins/skyline/README.md b/source/plugins/skyline/README.md index 3d8336af..139e3285 100644 --- a/source/plugins/skyline/README.md +++ b/source/plugins/skyline/README.md @@ -22,7 +22,8 @@ This uses puppeteer to generate collect image frames, and use CSS animations to with: # ... other options plugin_skyline: yes - plugin_skyline_year: 0 # Set to 0 to display current year - plugin_skyline_frames: 60 # Use 60 frames (half-loop) - plugin_skyline_quality: 0.5 # Scale-down quality by half to reduce file-size (⚠️ higher quality increase file size) + plugin_skyline_year: 0 # Set to 0 to display current year + plugin_skyline_frames: 60 # Use 60 frames (half-loop) + plugin_skyline_quality: 0.5 # Set image quality + plugin_skyline_compatibility: yes # Support additional browsers (⚠️ increases file size and reduce optimization) ``` \ No newline at end of file diff --git a/source/plugins/skyline/index.mjs b/source/plugins/skyline/index.mjs index 135a676b..96068539 100644 --- a/source/plugins/skyline/index.mjs +++ b/source/plugins/skyline/index.mjs @@ -7,7 +7,7 @@ return null //Load inputs - let {year, frames, quality} = imports.metadata.plugins.skyline.inputs({data, account, q}) + let {year, frames, quality, compatibility} = imports.metadata.plugins.skyline.inputs({data, account, q}) if (Number.isNaN(year)) { year = new Date().getFullYear() console.debug(`metrics/compute/${login}/plugins > skyline > year set to ${year}`) @@ -32,13 +32,13 @@ //Generate gif console.debug(`metrics/compute/${login}/plugins > skyline > generating frames`) - const framed = await imports.record({page, width, height, frames, scale:quality}) + const animation = compatibility ? await imports.record({page, width, height, frames, scale:quality}) : await imports.gif({page, width, height, frames, quality:Math.max(1, quality*20)}) //Close puppeteer await browser.close() //Results - return {frames:framed} + return {animation, width, height, compatibility} } //Handle errors catch (error) { diff --git a/source/plugins/skyline/metadata.yml b/source/plugins/skyline/metadata.yml index 4fd866c8..bba5e336 100644 --- a/source/plugins/skyline/metadata.yml +++ b/source/plugins/skyline/metadata.yml @@ -29,10 +29,16 @@ inputs: max: 120 # Image quality - # Note that it significantly increases output filesize (up to a few Mb) which can cause render/loading issues plugin_skyline_quality: description: Image quality type: number default: 0.5 min: 0.1 - max: 1 \ No newline at end of file + max: 1 + + # This uses CSS animations instead of GIF to support a wider range of browser like FireFox and Safari + # Using this mode significantly increase file size as each frame is encoded separately + plugin_skyline_compatibility: + description: Compatibility mode + type: boolean + default: no diff --git a/source/plugins/skyline/tests.yml b/source/plugins/skyline/tests.yml index 15ba0bf1..1a3746ef 100644 --- a/source/plugins/skyline/tests.yml +++ b/source/plugins/skyline/tests.yml @@ -7,6 +7,16 @@ modes: - action +- name: Skyline plugin (compatibility) + uses: lowlighter/metrics@latest + with: + token: NOT_NEEDED + plugin_skyline: yes + plugin_skyline_compatibility: yes + timeout: 1800000 + modes: + - action + - name: Skyline plugin (complete) uses: lowlighter/metrics@latest with: diff --git a/source/templates/classic/partials/skyline.ejs b/source/templates/classic/partials/skyline.ejs index 2e20854b..e81d0f96 100644 --- a/source/templates/classic/partials/skyline.ejs +++ b/source/templates/classic/partials/skyline.ejs @@ -12,44 +12,52 @@ <%= plugins.skyline.error.message %> <% } else { %> -
-
- <% for (const frame of plugins.skyline.frames) { %> -
- -
- <% } %> + <% if (plugins.skyline.compatibility) { %> +
+
+ <% for (const frame of plugins.skyline.animation) { %> +
+ +
+ <% } %> +
+
+ <% { const n = plugins.skyline.animation.length, width = plugins.skyline.width, height = plugins.skyline.height %> + + <% } %> + <% } else { %> +
+ + +
-
- <% { const n = plugins.skyline.frames.length, width = 454, height = 284 %> - <% } %> <% } %> diff --git a/source/templates/classic/style.css b/source/templates/classic/style.css index 6b2e6aea..bc5c8470 100644 --- a/source/templates/classic/style.css +++ b/source/templates/classic/style.css @@ -911,6 +911,14 @@ color: #666666; } +/* Skyline */ + .skyline-animation { + margin: 2px 13px 6px; + border-radius: 10px; + background-color: #030D21; + overflow: hidden; + } + /* Charts */ .ct-line { stroke-width: 2px !important;