From 68b65bc53f3b077dad6b10851d0fd7f73cc0e9e4 Mon Sep 17 00:00:00 2001 From: JasterV Date: Fri, 18 Mar 2022 16:03:06 +0100 Subject: [PATCH] first commit --- .gitignore | 145 +++++++++++++++++++ index.js | 19 +++ lib.js | 67 +++++++++ package-lock.json | 347 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 20 +++ 5 files changed, 598 insertions(+) create mode 100644 .gitignore create mode 100644 index.js create mode 100644 lib.js create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4eb78c5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,145 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/node +# Edit at https://www.toptal.com/developers/gitignore?templates=node + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +# End of https://www.toptal.com/developers/gitignore/api/node \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..128312c --- /dev/null +++ b/index.js @@ -0,0 +1,19 @@ +const { download, hash, calculateSimilarity } = require("./lib"); + +const URL1 = + "https://res.cloudinary.com/demo/image/upload/f_auto,q_auto/w_400/koala1.jpg"; +const URL2 = "https://res.cloudinary.com/demo/image/upload/h_180/koala2.jpg"; +const URL3 = "https://res.cloudinary.com/demo/image/upload/h_180/koala4.jpg"; + +async function main() { + console.log("Urls", { URL1, URL3 }); + const image1 = await download(URL1); + const image2 = await download(URL3); + const hash1 = await hash(image1); + const hash2 = await hash(image2); + console.log("Hashes", { hash1, hash2 }); + const similarity = calculateSimilarity(hash1, hash2); + console.log("similarity", { similarity }); +} + +main().catch((err) => console.log(err)); diff --git a/lib.js b/lib.js new file mode 100644 index 0000000..949a5ad --- /dev/null +++ b/lib.js @@ -0,0 +1,67 @@ +const blockhash = require("blockhash-core"); +const { getImageData, imageFromBuffer } = require("@canvas/image"); +const axios = require("axios").default; + +async function hash(buffer) { + const image = await imageFromBuffer(buffer); + const hash = await blockhash.bmvbhash(getImageData(image), 8); + return hexToBin(hash); +} + +async function download(url) { + const response = await axios.get(url, { responseType: "stream" }); + const stream = response.data; + const chunks = []; + for await (let chunk of stream) { + chunks.push(chunk); + } + const buffer = Buffer.concat(chunks); + return buffer; +} + +function calculateSimilarity(hash1, hash2) { + let similarity = 0; + const hash1Array = hash1.split(""); + hash1Array.forEach((bit, index) => { + hash2[index] === bit ? similarity++ : null; + }); + return similarity / hash1.length; +} + +function hexToBin(hexString) { + const hexBinLookup = { + 0: "0000", + 1: "0001", + 2: "0010", + 3: "0011", + 4: "0100", + 5: "0101", + 6: "0110", + 7: "0111", + 8: "1000", + 9: "1001", + a: "1010", + b: "1011", + c: "1100", + d: "1101", + e: "1110", + f: "1111", + A: "1010", + B: "1011", + C: "1100", + D: "1101", + E: "1110", + F: "1111", + }; + let result = ""; + for (let i = 0; i < hexString.length; i++) { + result += hexBinLookup[hexString[i]]; + } + return result; +} + +module.exports = { + hash, + download, + calculateSimilarity, +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..15347fd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,347 @@ +{ + "name": "phash-test", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "phash-test", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@canvas/image": "^1.0.1", + "axios": "^0.26.1", + "blockhash-core": "^0.1.0" + }, + "devDependencies": { + "@types/node": "^17.0.21" + } + }, + "node_modules/@canvas/image": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@canvas/image/-/image-1.0.1.tgz", + "integrity": "sha512-nQ6Qt/marzeQkFikxw32qMep5Rs1U/7DdjqHlCn8ck78IX56CFnXjdfRCXOiM4kx8yvS4SmcPXuJjfpczRjFqA==", + "dependencies": { + "@canvas/image-data": "^1.0.0", + "@cwasm/jpeg-turbo": "^0.1.1", + "@cwasm/lodepng": "^0.1.2", + "@cwasm/nsbmp": "^0.1.0", + "@cwasm/nsgif": "^0.1.0", + "@cwasm/webp": "^0.1.3", + "fast-base64-decode": "^1.0.0", + "fast-base64-encode": "^1.0.0", + "fast-base64-length": "^1.0.0", + "simple-get": "^3.1.0" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/@canvas/image-data": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.0.0.tgz", + "integrity": "sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==" + }, + "node_modules/@cwasm/jpeg-turbo": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@cwasm/jpeg-turbo/-/jpeg-turbo-0.1.3.tgz", + "integrity": "sha512-FkZxwwC6r4zhzlqM0nYGaMj/MDSrZPxLOdPdM6ySlgsMfOpNAZcLQkpNF4jP+DmsuUvRoeUD0YSMBvg3jYfK6w==", + "dependencies": { + "@canvas/image-data": "^1.0.0" + } + }, + "node_modules/@cwasm/lodepng": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@cwasm/lodepng/-/lodepng-0.1.6.tgz", + "integrity": "sha512-5ypNnlvlOpnSAYsTihEGt97vpSBM2TSuz4kN4hj7saKq5OQYCffmz5yH2ZYKnwETjjXCG8UeMm0TtF1KIihbXQ==", + "dependencies": { + "@canvas/image-data": "^1.0.0" + } + }, + "node_modules/@cwasm/nsbmp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@cwasm/nsbmp/-/nsbmp-0.1.2.tgz", + "integrity": "sha512-ZQGNDOI9ZxokqbNPmvcLKR8gBhfHjeFVuqE2eYysrbGiraQ93KeeIVrtiGKOMLW2JJOq9PbGBU0NX47qkpKWWA==", + "dependencies": { + "@canvas/image-data": "^1.0.0" + } + }, + "node_modules/@cwasm/nsgif": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@cwasm/nsgif/-/nsgif-0.1.2.tgz", + "integrity": "sha512-LOD5HlL0O5jpnIAl+dLSZcB3v0RBNBjtoaymdCEPe2kyKzaP20BF+jy/QUyOZogQsgMVjusZES3tgwwoiiJ2rA==", + "dependencies": { + "@canvas/image-data": "^1.0.0" + } + }, + "node_modules/@cwasm/webp": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@cwasm/webp/-/webp-0.1.5.tgz", + "integrity": "sha512-ceIZQkyxK+s7mmItNcWqqHdOBiJAxYxTnrnPNgUNjldB1M9j+Bp/3eVIVwC8rUFyN/zoFwuT0331pyY3ackaNA==", + "dependencies": { + "@canvas/image-data": "^1.0.0" + } + }, + "node_modules/@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/blockhash-core": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/blockhash-core/-/blockhash-core-0.1.0.tgz", + "integrity": "sha512-Cv7BgBo0jjVPaeuel4cvxf9LqIGsYNIPz9DAGvvrF9LRlEq9Q3HXu+S8bklPCae0sCxAXic4HGMoImf3FeO3Nw==" + }, + "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==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" + }, + "node_modules/fast-base64-encode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-encode/-/fast-base64-encode-1.0.0.tgz", + "integrity": "sha512-z2XCzVK4fde2cuTEHu2QGkLD6BPtJNKJPn0Z7oINvmhq/quUuIIVPYKUdN0gYeZqOyurjJjBH/bUzK5gafyHvw==" + }, + "node_modules/fast-base64-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-length/-/fast-base64-length-1.0.0.tgz", + "integrity": "sha512-MV+/ioblHx6SMjc/1l4EAnRJyAku6+6DxZ6RW0FoFCF1Aol/Ldb6FqwE3Kn3Ju1aam2m1KCIVoCljhgcG+Umzg==" + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "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==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "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" + } + ] + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + }, + "dependencies": { + "@canvas/image": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@canvas/image/-/image-1.0.1.tgz", + "integrity": "sha512-nQ6Qt/marzeQkFikxw32qMep5Rs1U/7DdjqHlCn8ck78IX56CFnXjdfRCXOiM4kx8yvS4SmcPXuJjfpczRjFqA==", + "requires": { + "@canvas/image-data": "^1.0.0", + "@cwasm/jpeg-turbo": "^0.1.1", + "@cwasm/lodepng": "^0.1.2", + "@cwasm/nsbmp": "^0.1.0", + "@cwasm/nsgif": "^0.1.0", + "@cwasm/webp": "^0.1.3", + "fast-base64-decode": "^1.0.0", + "fast-base64-encode": "^1.0.0", + "fast-base64-length": "^1.0.0", + "simple-get": "^3.1.0" + } + }, + "@canvas/image-data": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.0.0.tgz", + "integrity": "sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==" + }, + "@cwasm/jpeg-turbo": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@cwasm/jpeg-turbo/-/jpeg-turbo-0.1.3.tgz", + "integrity": "sha512-FkZxwwC6r4zhzlqM0nYGaMj/MDSrZPxLOdPdM6ySlgsMfOpNAZcLQkpNF4jP+DmsuUvRoeUD0YSMBvg3jYfK6w==", + "requires": { + "@canvas/image-data": "^1.0.0" + } + }, + "@cwasm/lodepng": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@cwasm/lodepng/-/lodepng-0.1.6.tgz", + "integrity": "sha512-5ypNnlvlOpnSAYsTihEGt97vpSBM2TSuz4kN4hj7saKq5OQYCffmz5yH2ZYKnwETjjXCG8UeMm0TtF1KIihbXQ==", + "requires": { + "@canvas/image-data": "^1.0.0" + } + }, + "@cwasm/nsbmp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@cwasm/nsbmp/-/nsbmp-0.1.2.tgz", + "integrity": "sha512-ZQGNDOI9ZxokqbNPmvcLKR8gBhfHjeFVuqE2eYysrbGiraQ93KeeIVrtiGKOMLW2JJOq9PbGBU0NX47qkpKWWA==", + "requires": { + "@canvas/image-data": "^1.0.0" + } + }, + "@cwasm/nsgif": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@cwasm/nsgif/-/nsgif-0.1.2.tgz", + "integrity": "sha512-LOD5HlL0O5jpnIAl+dLSZcB3v0RBNBjtoaymdCEPe2kyKzaP20BF+jy/QUyOZogQsgMVjusZES3tgwwoiiJ2rA==", + "requires": { + "@canvas/image-data": "^1.0.0" + } + }, + "@cwasm/webp": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@cwasm/webp/-/webp-0.1.5.tgz", + "integrity": "sha512-ceIZQkyxK+s7mmItNcWqqHdOBiJAxYxTnrnPNgUNjldB1M9j+Bp/3eVIVwC8rUFyN/zoFwuT0331pyY3ackaNA==", + "requires": { + "@canvas/image-data": "^1.0.0" + } + }, + "@types/node": { + "version": "17.0.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.21.tgz", + "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==", + "dev": true + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "blockhash-core": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/blockhash-core/-/blockhash-core-0.1.0.tgz", + "integrity": "sha512-Cv7BgBo0jjVPaeuel4cvxf9LqIGsYNIPz9DAGvvrF9LRlEq9Q3HXu+S8bklPCae0sCxAXic4HGMoImf3FeO3Nw==" + }, + "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==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" + }, + "fast-base64-encode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-encode/-/fast-base64-encode-1.0.0.tgz", + "integrity": "sha512-z2XCzVK4fde2cuTEHu2QGkLD6BPtJNKJPn0Z7oINvmhq/quUuIIVPYKUdN0gYeZqOyurjJjBH/bUzK5gafyHvw==" + }, + "fast-base64-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-length/-/fast-base64-length-1.0.0.tgz", + "integrity": "sha512-MV+/ioblHx6SMjc/1l4EAnRJyAku6+6DxZ6RW0FoFCF1Aol/Ldb6FqwE3Kn3Ju1aam2m1KCIVoCljhgcG+Umzg==" + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "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==" + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d609e54 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "phash-test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@canvas/image": "^1.0.1", + "axios": "^0.26.1", + "blockhash-core": "^0.1.0" + }, + "devDependencies": { + "@types/node": "^17.0.21" + } +} \ No newline at end of file