diff --git a/index.js b/index.js index 4bc9b04..41f0031 100644 --- a/index.js +++ b/index.js @@ -5,6 +5,7 @@ module.exports = { Canvabase, AssetLoader: require('./src/AssetLoader'), Spotify: require('./src/plugins/Spotify'), + Leaderboard: require('./src/plugins/Leaderboard'), Welcomer: require('./src/plugins/Welcomer'), write: Canvabase.write, author: require("./package.json").author, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..43303e5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,536 @@ +lockfileVersion: '6.0' + +dependencies: + '@napi-rs/canvas': + specifier: 0.1.35 + version: 0.1.35 + +devDependencies: + '@types/linkify-it': + specifier: ^3.0.2 + version: 3.0.4 + '@types/node': + specifier: ^18.11.18 + version: 18.18.8 + clean-jsdoc-theme: + specifier: ^4.1.10 + version: 4.2.14(jsdoc@4.0.2) + typescript: + specifier: ^4.9.4 + version: 4.9.5 + +packages: + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/parser@7.23.0: + resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.0 + dev: true + + /@babel/types@7.23.0: + resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.20: + resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jsdoc/salty@0.2.5: + resolution: {integrity: sha512-TfRP53RqunNe2HBobVBJ0VLhK1HbfvBYeTC1ahnN64PWvyYyGebmMiPkuwvD9fpw2ZbkoPb8Q7mwy0aR8Z9rvw==} + engines: {node: '>=v12.0.0'} + dependencies: + lodash: 4.17.21 + dev: true + + /@napi-rs/canvas-android-arm64@0.1.35: + resolution: {integrity: sha512-jBsiAX+S1Ps7xHuk0LCeDdZi4pD9gU3AK/M2dM5PHQnV12D+rmp5Ribu8rvPt2EpAgRYvUsyPSpjrQs/+hxHnA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-darwin-arm64@0.1.35: + resolution: {integrity: sha512-IY9uhVr5o412gHUmj7AvN+equsGtmi6L4hPN4p2VkQcSplpZgEQIgsgk5Oys91KjuQUSFG2Dr24Uv832k5xfcQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-darwin-x64@0.1.35: + resolution: {integrity: sha512-yY4s3H2wgAsQa/qAQaGiz43NWzLSdEAeZ3rATYhaAQg2vWd+uiU2FGBf5b7OOZwEQ8oGTa8qvwMATQ82K5hUlA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm-gnueabihf@0.1.35: + resolution: {integrity: sha512-ZY/ilgsm1jLhOkcVw9IEOPS5tGrqUbs0kBoWn5psolyeMNZW0o3fUMbyM/ebkb+8BeWTmLLrpx47kfaSOp05hA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm64-gnu@0.1.35: + resolution: {integrity: sha512-NUAsUnN8ZaBM9RGrETYKz1VCGuqMaszT2TYojM2MlAg2PwcOVeSGWfPG9ZYaobCr++LSY+PB4x2JKOhBwIRfkQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-arm64-musl@0.1.35: + resolution: {integrity: sha512-93RjEir8WomM8DbtvLTAmsaB11mc/kqR3lZM8dHqyIWEXhVJRKb8PEn52aa2EmWkINlqgyZgdx8Ch8QOzFC0bQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-x64-gnu@0.1.35: + resolution: {integrity: sha512-DEmNXbxUyLVD5cdJaG21cPMmexgkHq5hf1bnnGb4lIODjffR6appiLwEmFCYCRpujn+mH/ZrDRPc30zVEBTWLA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-linux-x64-musl@0.1.35: + resolution: {integrity: sha512-ZTenigydKsGOOU8JEFWsFVc9XF9D/bn+EPak1zJ/nj3HoUWxCLeoDZnKW9KrLyyBPueb9jnErT8rt1FtzK/mpQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas-win32-x64-msvc@0.1.35: + resolution: {integrity: sha512-XeT2emnlz/xgMh+i/lhuG7tHHQSnMM8wMyZEfq8lXQ6LrFWEEuTvhrJ7UWJKJ7KgSFIucJY8VC0Ea3M94kp0Cg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@napi-rs/canvas@0.1.35: + resolution: {integrity: sha512-D/NiDAPPfqrzDLRHJCQv0AZF6LBJx89FIg0ZUhoerkfi3ZIR0IjdCuul2MynHO+2bRvIH8jYA9maFksZyg4rVQ==} + engines: {node: '>= 10'} + optionalDependencies: + '@napi-rs/canvas-android-arm64': 0.1.35 + '@napi-rs/canvas-darwin-arm64': 0.1.35 + '@napi-rs/canvas-darwin-x64': 0.1.35 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.35 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.35 + '@napi-rs/canvas-linux-arm64-musl': 0.1.35 + '@napi-rs/canvas-linux-x64-gnu': 0.1.35 + '@napi-rs/canvas-linux-x64-musl': 0.1.35 + '@napi-rs/canvas-win32-x64-msvc': 0.1.35 + dev: false + + /@types/linkify-it@3.0.4: + resolution: {integrity: sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==} + dev: true + + /@types/markdown-it@12.2.3: + resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==} + dependencies: + '@types/linkify-it': 3.0.4 + '@types/mdurl': 1.0.4 + dev: true + + /@types/mdurl@1.0.4: + resolution: {integrity: sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==} + dev: true + + /@types/node@18.18.8: + resolution: {integrity: sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==} + dependencies: + undici-types: 5.26.5 + dev: true + + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.2 + dev: true + + /catharsis@0.9.0: + resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} + engines: {node: '>= 10'} + dependencies: + lodash: 4.17.21 + dev: true + + /clean-css@5.3.2: + resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} + engines: {node: '>= 10.0'} + dependencies: + source-map: 0.6.1 + dev: true + + /clean-jsdoc-theme@4.2.14(jsdoc@4.0.2): + resolution: {integrity: sha512-RtFKl0GKS9u3su2gnNH5L+k2g7AOZX1e8FH1zlFQf270LgSJsFFMkxTAR8/qeD0+r6jKTpvPq1JJSfhCtVnjVg==} + peerDependencies: + jsdoc: '>=3.x <=4.x' + dependencies: + '@jsdoc/salty': 0.2.5 + fs-extra: 10.1.0 + html-minifier-terser: 7.2.0 + jsdoc: 4.0.2 + klaw-sync: 6.0.0 + lodash: 4.17.21 + nanoid: 3.3.6 + showdown: 2.1.0 + dev: true + + /commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /entities@2.1.0: + resolution: {integrity: sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==} + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /html-minifier-terser@7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.2 + commander: 10.0.1 + entities: 4.5.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.23.0 + dev: true + + /js2xmlparser@4.0.2: + resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} + dependencies: + xmlcreate: 2.0.4 + dev: true + + /jsdoc@4.0.2: + resolution: {integrity: sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + '@babel/parser': 7.23.0 + '@jsdoc/salty': 0.2.5 + '@types/markdown-it': 12.2.3 + bluebird: 3.7.2 + catharsis: 0.9.0 + escape-string-regexp: 2.0.0 + js2xmlparser: 4.0.2 + klaw: 3.0.0 + markdown-it: 12.3.2 + markdown-it-anchor: 8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2) + marked: 4.3.0 + mkdirp: 1.0.4 + requizzle: 0.2.4 + strip-json-comments: 3.1.1 + underscore: 1.13.6 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /klaw-sync@6.0.0: + resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} + dependencies: + graceful-fs: 4.2.11 + dev: true + + /klaw@3.0.0: + resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} + dependencies: + graceful-fs: 4.2.11 + dev: true + + /linkify-it@3.0.3: + resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} + dependencies: + uc.micro: 1.0.6 + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.6.2 + dev: true + + /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): + resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + dependencies: + '@types/markdown-it': 12.2.3 + markdown-it: 12.3.2 + dev: true + + /markdown-it@12.3.2: + resolution: {integrity: sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 2.1.0 + linkify-it: 3.0.3 + mdurl: 1.0.1 + uc.micro: 1.0.6 + dev: true + + /marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + dev: true + + /mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + dev: true + + /param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dev: true + + /relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + dev: true + + /requizzle@0.2.4: + resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} + dependencies: + lodash: 4.17.21 + dev: true + + /showdown@2.1.0: + resolution: {integrity: sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==} + hasBin: true + dependencies: + commander: 9.5.0 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /terser@5.23.0: + resolution: {integrity: sha512-Iyy83LN0uX9ZZLCX4Qbu5JiHiWjOCTwrmM9InWOzVeM++KNWEsqV4YgN9U9E8AlohQ6Gs42ztczlWOG/lwDAMA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.11.2 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /uc.micro@1.0.6: + resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + dev: true + + /underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /xmlcreate@2.0.4: + resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} + dev: true diff --git a/src/AssetLoader.js b/src/AssetLoader.js index 968a8c9..3559e59 100644 --- a/src/AssetLoader.js +++ b/src/AssetLoader.js @@ -84,9 +84,9 @@ class AssetLoader { }); }; let dirs = []; - this.assetDirs.forEach((d) => { + for (const d of this.assetDirs) { dirs.push(mapDirectories(d)); - }); + } await Promise.allSettled(dirs); res(this); diff --git a/src/assets/fonts/Inter-Bold.ttf b/src/assets/fonts/Inter-Bold.ttf new file mode 100644 index 0000000..fe23eeb Binary files /dev/null and b/src/assets/fonts/Inter-Bold.ttf differ diff --git a/src/assets/fonts/Inter-Regular.ttf b/src/assets/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..5e4851f Binary files /dev/null and b/src/assets/fonts/Inter-Regular.ttf differ diff --git a/src/assets/fonts/Poppins.ttf b/src/assets/fonts/Poppins.ttf new file mode 100644 index 0000000..00559ee Binary files /dev/null and b/src/assets/fonts/Poppins.ttf differ diff --git a/src/plugins/Leaderboard.js b/src/plugins/Leaderboard.js new file mode 100644 index 0000000..3a5b933 --- /dev/null +++ b/src/plugins/Leaderboard.js @@ -0,0 +1,293 @@ +const canvas = require("@napi-rs/canvas"); +const { join } = require("path"); + +/** + * @example + * const leaderboard = new canvabase.Leaderboard() + .setOpacity(0.7) + .setScoreMessage("Score:" + .addBachground( + "image", + "https://i.imgur.com/h3b4KZI_d.webp?maxwidth=760&fidelity=grand" + ) + .setColors({ + box: "#212121", + username: "#ffffff", + score: "#ffffff", + firstRank: "#FFD700", + secondRank: "#C0C0C0", + thirdRank: "#CD7F32", + }) + .addUserData([ + { + top: 1, + avatar: "https://cdn.discordapp.com/embed/avatars/0.png", + tag: "DominikDominikDominikDomi3nikDominikDominik", + score: 5555, + }, + { + top: 2, + avatar: "https://cdn.discordapp.com/embed/avatars/1.png", + tag: "That Man", + score: 1337, + }, + { + top: 3, + avatar: "https://cdn.discordapp.com/embed/avatars/3.png", + tag: "Sky", + score: 1054, + }, + { + top: 4, + avatar: "https://cdn.discordapp.com/embed/avatars/4.png", + tag: "FortniteFriend", + score: 903, + }, + { + top: 5, + avatar: "https://cdn.discordapp.com/embed/avatars/5.png", + tag: "Forgetfulskybro", + score: 0, + }, + ]); + +leaderboard.build().then((img) => { + canvabase.write("./test/leaderboard.png", img); +}); +}) + + + }); + */ + +class Leaderboard { + constructor() {} + + /** + * .addUserData + * @param {Array||object} usersData [{ top: int, avatar: "string", tag: "string", score: int}] + * @returns {Leaderboard} + * @example addUserData([{ top: 1, avatar: "https://image.com/image.png", tag: "dominikdev", score: 5 }]) + */ + addUserData(usersData) { + if (usersData.length > 10) { + throw new Error("addUserData values cannot be greater than 10."); + } + this.usersData = usersData; + return this; + } + + /** + * .setScoreMessage + * @param {string} message Set Custom Score Message + * @returns {Leaderboard} + * @example setScoreMessage("Message") + */ + setScoreMessage(message) { + this.scoreMessage = message; + return this; + } + + /** + * .setColors + * @param {object} colors {box: "hexcolor", username: "hexcolor", score: "hexcolor", firstRank: "hexcolor", secondRank: "hexcolor", thirdRank: "hexcolor"} + * @returns {Leaderboard} + * @example setColors({ box: '#212121', username: '#ffffff', score: '#ffffff', firstRank: '#FFD700', secondRank: '#C0C0C0', thirdRank: '#CD7F32' }) + */ + setColors(colors) { + this.colors = colors; + return this; + } + + /** + * Sets the opacity of the element. + * + * @param {number} opacity The opacity value, must be between 0 and 1. + * @returns {Leaderboard} The calling object for chaining. + * @example setOpacity(0.6) + */ + setOpacity(opacity = 0) { + if (opacity < 0 || opacity > 1) { + throw new Error( + "The value of the opacity of setOpacity method must be between 0 and 1 (0 and 1 included)." + ); + } + + this.opacity = opacity; + return this; + } + + /** + * Sets the background of the element. + * + * @param {string} type The type of background: "image" or "color". + * @param {string} value The value of the background: an URL for an image or a hex color code. + * @returns {Leaderboard} The calling object for chaining. + * @example addBachground("image","https://image.com/image.png") + * @example addBachground("color","#ff2f") + */ + addBachground(type, value) { + if (!type || !value) { + throw new Error("Both arguments for addBachground are required."); + } + + if (type !== "color" && type !== "image") { + throw new Error( + "The first argument for addBachground must be 'color' or 'image'." + ); + } + + if (type === "color") { + if (!/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/.test(value)) { + throw new Error( + "Invalid color for the second argument in addBachground method. You must give a hexadecimal color." + ); + } + } + this.background = {}; + this.background.type = type; + this.background.background = value; + + return this; + } + + async build() { + let { background, usersData, colors, scoreMessage, opacity } = this; + + canvas.GlobalFonts.registerFromPath( + join(__dirname, "..", "assets", "fonts", "Poppins.ttf"), + "Poppins" + ); + + const fillRoundRect = (ctx, x, y, w, h, r, f, s) => { + if (typeof r === "number") + r = { + tl: r, + tr: r, + br: r, + bl: r, + }; + else { + let defaultRadius = { + tl: 0, + tr: 0, + br: 0, + bl: 0, + }; + for (let side in defaultRadius) { + r[side] = r[side] || defaultRadius[side]; + } + } + ctx.beginPath(); + ctx.moveTo(x + r.tl, y); + ctx.lineTo(x + w - r.tr, y); + ctx.quadraticCurveTo(x + w, y, x + w, y + r.tr); + ctx.lineTo(x + w, y + h - r.br); + ctx.quadraticCurveTo(x + w, y + h, x + w - r.br, y + h); + ctx.lineTo(x + r.bl, y + h); + ctx.quadraticCurveTo(x, y + h, x, y + h - r.bl); + ctx.lineTo(x, y + r.tl); + ctx.quadraticCurveTo(x, y, x + r.tl, y); + ctx.closePath(); + if (f) ctx.fill(); + if (s) ctx.stroke(); + }; + + let userLenght = usersData.length * 74.5; + + const canvasObject = canvas.createCanvas(680, userLenght); + const ctx = canvasObject.getContext("2d"); + + ctx.globalAlpha = 1; + + if (background.type === "color") { + ctx.beginPath(); + ctx.fillStyle = background.background; + ctx.fillRect(0, 0, canvasObject.width, canvasObject.height); + } else if (background.type === "image") { + try { + ctx.drawImage( + await canvas.loadImage(background.background), + 0, + 0, + canvasObject.width, + canvasObject.height + ); + } catch { + throw new Error( + "The image url provided in addBachground method is invalid." + ); + } + } + + if (usersData) { + let boxY = 0, + avatarY = 0, + tagY = 45, + xpY = 45, + levelY = 30, + rankY = 45; + for (let i = 0; i < usersData.length; i++) { + ctx.save(); + ctx.fillStyle = colors.box; + ctx.globalAlpha = opacity; + fillRoundRect(ctx, 0, boxY, canvasObject.width, 70, 15, true, false); + ctx.globalAlpha = 1; + + const avatar = await canvas.loadImage(usersData[i].avatar); + ctx.clip(); + ctx.drawImage(avatar, 0, avatarY, 70, 70); + ctx.shadowBlur = 10; + ctx.shadowOffsetX = 8; + ctx.shadowOffsetY = 6; + ctx.shadowColor = "#0a0a0a"; + + ctx.fillStyle = colors.username; + ctx.font = "bold 25px Poppins"; + ctx.textAlign = "left"; + ctx.fillText(usersData[i].tag.slice(0, 21), 80, tagY, 260); + + ctx.fillStyle = colors.score; + ctx.font = "bold 20px Poppins"; + ctx.textAlign = "left"; + ctx.fillText(`${usersData[i].score}`, 540, xpY, 200); + ctx.textAlign = "right"; + ctx.fillText(`${scoreMessage}`, 535, xpY, 200); + + if (usersData[i].top === 1) { + ctx.fillStyle = colors.firstRank; + } else if (usersData[i].top === 2) { + ctx.fillStyle = colors.secondRank; + } else if (usersData[i].top === 3) { + ctx.fillStyle = colors.thirdRank; + } + + ctx.font = "bold 30px Poppins"; + ctx.textAlign = "right"; + ctx.fillText("#" + usersData[i].top, 660, rankY, 75); + + boxY = boxY + 75; + avatarY = avatarY + 75; + tagY = tagY + 75; + xpY = xpY + 75; + levelY = levelY + 75; + rankY = rankY + 75; + ctx.restore(); + } + } else { + ctx.font = "bold 40px Poppins"; + ctx.fillStyle = "#ffffff"; + ctx.textAlign = "center"; + ctx.shadowBlur = 10; + ctx.shadowOffsetX = 8; + ctx.shadowOffsetY = 6; + ctx.shadowColor = "#0a0a0a"; + ctx.fillText("Not found!", 340, 370, 500); + } + + // returns the buffer Ara Ara + return canvasObject.encode("png"); + } +} + +module.exports = Leaderboard; diff --git a/test/Index.js b/test/Index.js index 7bd394e..628c1ec 100644 --- a/test/Index.js +++ b/test/Index.js @@ -5,23 +5,60 @@ const spotify = new canvabase.Spotify() .setArtist("SZA") .setAlbum("SOS") .setDuration(153946) - .setCover( - "https://i.scdn.co/image/ab67616d0000b27370dbc9f47669d120ad874ec1" - ); + .setCover("https://i.scdn.co/image/ab67616d0000b27370dbc9f47669d120ad874ec1"); -spotify.build().then((img) => { - canvabase.write("./test/spotifycard.png", img); -}); +//spotify.build().then((img) => { +// canvabase.write("./test/spotifycard.png", img); +//}); -const welcomer = new canvabase.Welcomer() -.setName("Dominik") -.setTitle("Welcome!") -//.addBackgrounds(["https://wallpapercave.com/wp/wp5128415.jpg", "https://wallpapercave.com/wp/wp11735586.jpg"]) -.addBackground("https://wallpapercave.com/wp/wp5128415.jpg") -.setAvatar("https://cdn.discordapp.com/avatars/1129276241397174322/eb285a4fc0ec3d78dea3cbbb6012e714.webp?size=80", "rounded") -.setPosition("left") -.setColor("#ffff") +const leaderboard = new canvabase.Leaderboard() + .setOpacity(0.7) + .setScoreMessage("Score:") + .addBachground( + "image", + "https://i.imgur.com/h3b4KZI_d.webp?maxwidth=760&fidelity=grand" + ) + .setColors({ + box: "#212121", + username: "#ffffff", + score: "#ffffff", + firstRank: "#FFD700", + secondRank: "#C0C0C0", + thirdRank: "#CD7F32", + }) + .addUserData([ + { + top: 1, + avatar: "https://cdn.discordapp.com/embed/avatars/0.png", + tag: "Dominik", + score: 5555, + }, + { + top: 2, + avatar: "https://cdn.discordapp.com/embed/avatars/1.png", + tag: "That Man", + score: 1337, + }, + { + top: 3, + avatar: "https://cdn.discordapp.com/embed/avatars/2.png", + tag: "Sky", + score: 1054, + }, + { + top: 4, + avatar: "https://cdn.discordapp.com/embed/avatars/4.png", + tag: "FortniteFriend", + score: 903, + }, + { + top: 5, + avatar: "https://cdn.discordapp.com/embed/avatars/5.png", + tag: "Forgetfulskybro", + score: 0, + }, + ]); -welcomer.build().then((img) => { - canvabase.write("./test/welcomercard.png", img); -}) \ No newline at end of file +leaderboard.build().then((img) => { + canvabase.write("./test/leaderboard.png", img); +});