commit 5d937a68b129e6085f5f623b709d829e49297b03 Author: vorotamoroz Date: Tue Apr 12 17:40:52 2022 +0900 initial (POC, but looks like works) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5f2ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +dat/** +!dat/.gitempty +!dat/config.sample.json +node_modules +dist/* +.idea/* +.vscode/* +utils/** +vault/** + diff --git a/dat/.gitempty b/dat/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/dat/config.sample.json b/dat/config.sample.json new file mode 100644 index 0000000..3292195 --- /dev/null +++ b/dat/config.sample.json @@ -0,0 +1,19 @@ +{ + "config_1": { + "server": { + "uri": "http://localhost:5984/private1_vault", + "auth": { + "username": "username_of_private_vault", + "password": "password_of_private_vault", + "passphrase": "passphrase_of_private_vault" + }, + "path": "shared/" + }, + "local": { + "path": "./export", + "processor": "utils/build.sh", + "initialScan": false + }, + "auto_reconnect": true + } +} diff --git a/esbuild.config.mjs b/esbuild.config.mjs new file mode 100644 index 0000000..59983f8 --- /dev/null +++ b/esbuild.config.mjs @@ -0,0 +1,38 @@ +import esbuild from "esbuild"; +import process from "process"; +import builtins from "builtin-modules"; + +const banner = `/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ +`; + +const prod = process.argv[2] === "production"; + +esbuild + .build({ + banner: { + js: banner, + }, + entryPoints: ["src/index.ts"], + bundle: true, + external: [...builtins, "./node_modules/*", "src/pouchdb.js"], + format: "cjs", + watch: false, + target: "node16", + logLevel: "info", + sourcemap: prod ? false : "inline", + treeShaking: true, + plugins: [ + // sveltePlugin({ + // preprocess: sveltePreprocess(), + // compilerOptions: { css: true }, + // }), + ], + outfile: "dist/index.js", + }) + .catch((e) => { + console.dir(e); + process.exit(1); + }); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..93c0f40 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2394 @@ +{ + "name": "filesystem-livesync", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "filesystem-livesync", + "version": "0.0.1", + "license": "ISC", + "dependencies": { + "chokidar": "^3.5.3", + "pouchdb": "^7.2.2", + "pouchdb-adapter-http": "^7.2.2", + "pouchdb-adapter-leveldb": "^7.2.2", + "pouchdb-core": "^7.2.2", + "pouchdb-mapreduce": "^7.2.2", + "pouchdb-node": "^7.2.2", + "pouchdb-replication": "^7.2.2", + "xxhash-wasm": "^1.0.1" + }, + "devDependencies": { + "@tsconfig/node16": "^1.0.2", + "@types/node": "^17.0.18", + "@types/pouchdb": "^6.4.0", + "builtin-modules": "^3.2.0", + "esbuild": "^0.14.22", + "ts-node": "^10.5.0", + "typescript": "^4.5.5" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/debug": { + "version": "4.1.7", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.31", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.18", + "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", + "dev": true + }, + "node_modules/@types/pouchdb": { + "version": "6.4.0", + "integrity": "sha512-eGCpX+NXhd5VLJuJMzwe3L79fa9+IDTrAG3CPaf4s/31PD56hOrhDJTSmRELSXuiqXr6+OHzzP0PldSaWsFt7w==", + "dev": true, + "dependencies": { + "@types/pouchdb-adapter-cordova-sqlite": "*", + "@types/pouchdb-adapter-fruitdown": "*", + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-idb": "*", + "@types/pouchdb-adapter-leveldb": "*", + "@types/pouchdb-adapter-localstorage": "*", + "@types/pouchdb-adapter-memory": "*", + "@types/pouchdb-adapter-node-websql": "*", + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-browser": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-http": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-node": "*", + "@types/pouchdb-replication": "*" + } + }, + "node_modules/@types/pouchdb-adapter-cordova-sqlite": { + "version": "1.0.1", + "integrity": "sha512-nqlXpW1ho3KBg1mUQvZgH2755y3z/rw4UA7ZJCPMRTHofxGMY8izRVw5rHBL4/7P615or0J2udpRYxgkT3D02g==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-fruitdown": { + "version": "6.1.3", + "integrity": "sha512-Wz1Z1JLOW1hgmFQjqnSkmyyfH7by/iWb4abKn684WMvQfmxx6BxKJpJ4+eulkVPQzzgMMSgU1MpnQOm9FgRkbw==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-http": { + "version": "6.1.3", + "integrity": "sha512-9Z4TLbF/KJWy/D2sWRPBA+RNU0odQimfdvlDX+EY7rGcd3aVoH8qjD/X0Xcd/0dfBH5pKrNIMFFQgW/TylRCmA==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-idb": { + "version": "6.1.4", + "integrity": "sha512-KIAXbkF4uYUz0ZwfNEFLtEkK44mEWopAsD76UhucH92XnJloBysav+TjI4FFfYQyTjoW3S1s6V+Z14CUJZ0F6w==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-leveldb": { + "version": "6.1.3", + "integrity": "sha512-ex8NFqQGFwEpFi7AaZ5YofmuemfZNsL3nTFZBUCAKYMBkazQij1pe2ILLStSvJr0XS0qxgXjCEW19T5Wqiiskg==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-localstorage": { + "version": "6.1.3", + "integrity": "sha512-oor040tye1KKiGLWYtIy7rRT7C2yoyX3Tf6elEJRpjOA7Ja/H8lKc4LaSh9ATbptIcES6MRqZDxtp7ly9hsW3Q==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-memory": { + "version": "6.1.3", + "integrity": "sha512-gVbsIMzDzgZYThFVT4eVNsmuZwVm/4jDxP1sjlgc3qtDIxbtBhGgyNfcskwwz9Zu5Lv1avkDsIWvcxQhnvRlHg==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-node-websql": { + "version": "6.1.3", + "integrity": "sha512-F/P+os6Jsa7CgHtH64+Z0HfwIcj0hIRB5z8gNhF7L7dxPWoAfkopK5H2gydrP3sQrlGyN4WInF+UJW/Zu1+FKg==", + "dev": true, + "dependencies": { + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-adapter-websql": { + "version": "6.1.4", + "integrity": "sha512-zMJQCtXC40hBsIDRn0GhmpeGMK0f9l/OGWfLguvczROzxxcOD7REI+e6SEmX7gJKw5JuMvlfuHzkQwjmvSJbtg==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-browser": { + "version": "6.1.3", + "integrity": "sha512-EdYowrWxW9SWBMX/rux2eq7dbHi5Zeyzz+FF/IAsgQKnUxgeCO5VO2j4zTzos0SDyJvAQU+EYRc11r7xGn5tvA==", + "dev": true, + "dependencies": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-idb": "*", + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-replication": "*" + } + }, + "node_modules/@types/pouchdb-core": { + "version": "7.0.10", + "integrity": "sha512-mKhjLlWWXyV3PTTjDhzDV1kc2dolO7VYFa75IoKM/hr8Er9eo8RIbS7mJLfC8r/C3p6ihZu9yZs1PWC1LQ0SOA==", + "dev": true, + "dependencies": { + "@types/debug": "*", + "@types/pouchdb-find": "*" + } + }, + "node_modules/@types/pouchdb-find": { + "version": "6.3.7", + "integrity": "sha512-b2dr9xoZRK5Mwl8UiRA9l5j9mmCxNfqXuu63H1KZHwJLILjoIIz7BntCvM0hnlnl7Q8P8wORq0IskuaMq5Nnnw==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-http": { + "version": "6.1.3", + "integrity": "sha512-0e9E5SqNOyPl/3FnEIbENssB4FlJsNYuOy131nxrZk36S+y1R/6qO7ZVRypWpGTqBWSuVd7gCsq2UDwO/285+w==", + "dev": true, + "dependencies": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-mapreduce": { + "version": "6.1.6", + "integrity": "sha512-YubC1pKmQGbPrZzYP5vUNrlafMTkO2+AZIumLB39Lkw1rYFxa4pwiKlygtDgJD2Gy+6A5Nu3ShTPrB3kPOXFyg==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*" + } + }, + "node_modules/@types/pouchdb-node": { + "version": "6.1.4", + "integrity": "sha512-wnTCH8X1JOPpNOfVhz8HW0AvmdHh6pt40MuRj0jQnK7QEHsHS79WujsKTKSOF8QXtPwpvCNSsI7ut7H7tfxxJQ==", + "dev": true, + "dependencies": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-leveldb": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-replication": "*" + } + }, + "node_modules/@types/pouchdb-replication": { + "version": "6.4.3", + "integrity": "sha512-Dsyy8EhKGBIQAECKelfvufDjRO5Rsy8RlujVllbjHzu3OGu8cNP92/bykeXXC3hTgvrp5Kviqhh9VON1Iw+M3Q==", + "dev": true, + "dependencies": { + "@types/pouchdb-core": "*", + "@types/pouchdb-find": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-leveldown": { + "version": "6.2.3", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/acorn": { + "version": "8.7.0", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argsarray": { + "version": "0.0.1", + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/create-require": { + "version": "1.1.1", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/double-ended-queue": { + "version": "2.1.0-0", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "node_modules/encoding-down": { + "version": "6.3.0", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/end-stream": { + "version": "0.1.0", + "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", + "dependencies": { + "write-stream": "~0.4.3" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/esbuild": { + "version": "0.14.22", + "integrity": "sha512-CjFCFGgYtbFOPrwZNJf7wsuzesx8kqwAffOlbYcFDLFuUtP8xloK1GH+Ai13Qr0RZQf9tE7LMTHJ2iVGJ1SKZA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "esbuild-android-arm64": "0.14.22", + "esbuild-darwin-64": "0.14.22", + "esbuild-darwin-arm64": "0.14.22", + "esbuild-freebsd-64": "0.14.22", + "esbuild-freebsd-arm64": "0.14.22", + "esbuild-linux-32": "0.14.22", + "esbuild-linux-64": "0.14.22", + "esbuild-linux-arm": "0.14.22", + "esbuild-linux-arm64": "0.14.22", + "esbuild-linux-mips64le": "0.14.22", + "esbuild-linux-ppc64le": "0.14.22", + "esbuild-linux-riscv64": "0.14.22", + "esbuild-linux-s390x": "0.14.22", + "esbuild-netbsd-64": "0.14.22", + "esbuild-openbsd-64": "0.14.22", + "esbuild-sunos-64": "0.14.22", + "esbuild-windows-32": "0.14.22", + "esbuild-windows-64": "0.14.22", + "esbuild-windows-arm64": "0.14.22" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.22", + "integrity": "sha512-AxjIDcOmx17vr31C5hp20HIwz1MymtMjKqX4qL6whPj0dT9lwxPexmLj6G1CpR3vFhui6m75EnBEe4QL82SYqw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fetch-cookie": { + "version": "0.10.1", + "integrity": "sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g==", + "dependencies": { + "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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/immediate": { + "version": "3.3.0", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, + "node_modules/inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/level": { + "version": "6.0.1", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "dependencies": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + }, + "engines": { + "node": ">=8.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-js": { + "version": "5.0.2", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "dependencies": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-write-stream": { + "version": "1.0.0", + "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", + "dependencies": { + "end-stream": "~0.1.0" + } + }, + "node_modules/leveldown": { + "version": "5.6.0", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "hasInstallScript": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ltgt": { + "version": "2.2.1", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + }, + "node_modules/make-error": { + "version": "1.3.6", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/napi-macros": { + "version": "2.0.0", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + }, + "node_modules/node-fetch": { + "version": "2.6.0", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.1.1", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pouchdb": { + "version": "7.2.2", + "integrity": "sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw==", + "dependencies": { + "abort-controller": "3.0.0", + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "clone-buffer": "1.0.0", + "double-ended-queue": "2.1.0-0", + "fetch-cookie": "0.10.1", + "immediate": "3.3.0", + "inherits": "2.0.4", + "level": "6.0.1", + "level-codec": "9.0.2", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "levelup": "4.4.0", + "ltgt": "2.2.1", + "node-fetch": "2.6.0", + "readable-stream": "1.1.14", + "spark-md5": "3.0.1", + "through2": "3.0.2", + "uuid": "8.1.0", + "vuvuzela": "1.0.3" + } + }, + "node_modules/pouchdb-abstract-mapreduce": { + "version": "7.2.2", + "integrity": "sha512-7HWN/2yV2JkwMnGnlp84lGvFtnm0Q55NiBUdbBcaT810+clCGKvhssBCrXnmwShD1SXTwT83aszsgiSfW+SnBA==", + "dependencies": { + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collate": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-mapreduce-utils": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-adapter-http": { + "version": "7.2.2", + "integrity": "sha512-6Z6umJq7b5sRXwDM3CLfHrGhJPMR02M5osUxkwH1PpqcTF0EXPJvX+PtzTjSPcXWfaK6kgH3zNrRKQDdpzjI9A==", + "dependencies": { + "argsarray": "0.0.1", + "pouchdb-binary-utils": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-adapter-leveldb": { + "version": "7.2.2", + "integrity": "sha512-f0m1ZbP5wvnEQIVy7Po89Hhh0mrkkf5LEEZJ3H54pdqpE1ebuJ3WorI3J3CsBXAh4i3PBNR/6SsmO7YhQONsjQ==", + "dependencies": { + "level": "6.0.1", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "pouchdb-adapter-leveldb-core": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2", + "through2": "3.0.2" + } + }, + "node_modules/pouchdb-adapter-leveldb-core": { + "version": "7.2.2", + "integrity": "sha512-K9UGf1Ivwe87mjrMqN+1D07tO/DfU7ariVDrGffuOjvl+3BcvUF25IWrxsBObd4iPOYCH7NVQWRpojhBgxULtQ==", + "dependencies": { + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "double-ended-queue": "2.1.0-0", + "levelup": "4.4.0", + "pouchdb-adapter-utils": "7.2.2", + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-json": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2", + "sublevel-pouchdb": "7.2.2", + "through2": "3.0.2" + } + }, + "node_modules/pouchdb-adapter-utils": { + "version": "7.2.2", + "integrity": "sha512-2CzZkTyTyHZkr3ePiWFMTiD5+56lnembMjaTl8ohwegM0+hYhRyJux0biAZafVxgIL4gnCUC4w2xf6WVztzKdg==", + "dependencies": { + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-binary-utils": { + "version": "7.2.2", + "integrity": "sha512-shacxlmyHbUrNfE6FGYpfyAJx7Q0m91lDdEAaPoKZM3SzAmbtB1i+OaDNtYFztXjJl16yeudkDb3xOeokVL3Qw==", + "dependencies": { + "buffer-from": "1.1.1" + } + }, + "node_modules/pouchdb-changes-filter": { + "version": "7.2.2", + "integrity": "sha512-1txJnTtL/C7zrq+spLt3pH9EDHTWmLLwp2zx8zUQrkt6eQtuLuXUI7G84xe+hfpU0rQvUzp/APYMnko0/6Rw0A==", + "dependencies": { + "pouchdb-errors": "7.2.2", + "pouchdb-selector-core": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-checkpointer": { + "version": "7.2.2", + "integrity": "sha512-O2i0vjLnZwcuSI41omrdaiyPWofCRLPBs+Sw5ad/GtYQbvxRt0CJEqYCrOaDnAsgIVoRG5PK/9gDzszv2CQsvg==", + "dependencies": { + "pouchdb-collate": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-collate": { + "version": "7.2.2", + "integrity": "sha512-/SMY9GGasslknivWlCVwXMRMnQ8myKHs4WryQ5535nq1Wj/ehpqWloMwxEQGvZE1Sda3LOm7/5HwLTcB8Our+w==" + }, + "node_modules/pouchdb-collections": { + "version": "7.2.2", + "integrity": "sha512-6O9zyAYlp3UdtfneiMYuOCWdUCQNo2bgdjvNsMSacQX+3g8WvIoFQCYJjZZCpTttQGb+MHeRMr8m2U95lhJTew==" + }, + "node_modules/pouchdb-core": { + "version": "7.2.2", + "integrity": "sha512-AnMmSH+xx12Vk6oASDRQoElXfV9fSn8MIwfus0oa2lqkxowx4bvidofZbhZfKEiE6QgKwFEOBzs56MS3znI8TQ==", + "dependencies": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-changes-filter": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-errors": { + "version": "7.2.2", + "integrity": "sha512-6GQsiWc+7uPfgEHeavG+7wuzH3JZW29Dnrvz8eVbDFE50kVFxNDVm3EkYHskvo5isG7/IkOx7PV7RPTA3keG3g==", + "dependencies": { + "inherits": "2.0.4" + } + }, + "node_modules/pouchdb-fetch": { + "version": "7.2.2", + "integrity": "sha512-lUHmaG6U3zjdMkh8Vob9GvEiRGwJfXKE02aZfjiVQgew+9SLkuOxNw3y2q4d1B6mBd273y1k2Lm0IAziRNxQnA==", + "dependencies": { + "abort-controller": "3.0.0", + "fetch-cookie": "0.10.1", + "node-fetch": "2.6.0" + } + }, + "node_modules/pouchdb-generate-replication-id": { + "version": "7.2.2", + "integrity": "sha512-kBr9jTM3/qEQQDhraXdIhhy+OSi18X6pMJnWCSaT43194XuWZltnjH1Hty0aJ0U9s1UanyxqZwrb7wJT6QUpzg==", + "dependencies": { + "pouchdb-collate": "7.2.2", + "pouchdb-md5": "7.2.2" + } + }, + "node_modules/pouchdb-json": { + "version": "7.2.2", + "integrity": "sha512-3b2S2ynN+aoB7aCNyDZc/4c0IAdx/ir3nsHB+/RrKE9cM3QkQYbnnE3r/RvOD1Xvr6ji/KOCBie+Pz/6sxoaug==", + "dependencies": { + "vuvuzela": "1.0.3" + } + }, + "node_modules/pouchdb-mapreduce": { + "version": "7.2.2", + "integrity": "sha512-uDXEzznnZmCz3YJQ2AwVhiUDCYOaIypg1EZ2VmYOCoJnUPfmOp6LY/MPBug/sqq/BDrQCUIEtKs+Sva/L6m8xg==", + "dependencies": { + "pouchdb-abstract-mapreduce": "7.2.2", + "pouchdb-mapreduce-utils": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-mapreduce-utils": { + "version": "7.2.2", + "integrity": "sha512-rAllb73hIkU8rU2LJNbzlcj91KuulpwQu804/F6xF3fhZKC/4JQMClahk+N/+VATkpmLxp1zWmvmgdlwVU4HtQ==", + "dependencies": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-collections": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-md5": { + "version": "7.2.2", + "integrity": "sha512-c/RvLp2oSh8PLAWU5vFBnp6ejJABIdKqboZwRRUrWcfGDf+oyX8RgmJFlYlzMMOh4XQLUT1IoaDV8cwlsuryZw==", + "dependencies": { + "pouchdb-binary-utils": "7.2.2", + "spark-md5": "3.0.1" + } + }, + "node_modules/pouchdb-merge": { + "version": "7.2.2", + "integrity": "sha512-6yzKJfjIchBaS7Tusuk8280WJdESzFfQ0sb4jeMUNnrqs4Cx3b0DIEOYTRRD9EJDM+je7D3AZZ4AT0tFw8gb4A==" + }, + "node_modules/pouchdb-node": { + "version": "7.2.2", + "integrity": "sha512-r1JenKn+HWXAK8EMcoWp8rXzeBVGcnPd/IOiOHwac36rUAZkKBFrWnS1jkJcbJcghIFxTn1w9tL0HBdaR1PFSg==", + "dependencies": { + "abort-controller": "3.0.0", + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "clone-buffer": "1.0.0", + "double-ended-queue": "2.1.0-0", + "fetch-cookie": "0.10.1", + "inherits": "2.0.4", + "level": "6.0.1", + "level-codec": "9.0.2", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "levelup": "4.4.0", + "ltgt": "2.2.1", + "node-fetch": "2.6.0", + "readable-stream": "1.1.14", + "through2": "3.0.2", + "uuid": "8.1.0", + "vuvuzela": "1.0.3" + } + }, + "node_modules/pouchdb-node/node_modules/readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pouchdb-node/node_modules/string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/pouchdb-replication": { + "version": "7.2.2", + "integrity": "sha512-+Q2zqXWaHPOut0jGMABplmlML+8jUzkefyxZXgU6bXSbC9kEJCBAkjaFeZsF10HpsQZ9tHZ577g5EOqj7V1lTQ==", + "dependencies": { + "inherits": "2.0.4", + "pouchdb-checkpointer": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-generate-replication-id": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-selector-core": { + "version": "7.2.2", + "integrity": "sha512-XYKCNv9oiNmSXV5+CgR9pkEkTFqxQGWplnVhO3W9P154H08lU0ZoNH02+uf+NjZ2kjse7Q1fxV4r401LEcGMMg==", + "dependencies": { + "pouchdb-collate": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "node_modules/pouchdb-utils": { + "version": "7.2.2", + "integrity": "sha512-XmeM5ioB4KCfyB2MGZXu1Bb2xkElNwF1qG+zVFbQsKQij0zvepdOUfGuWvLRHxTOmt4muIuSOmWZObZa3NOgzQ==", + "dependencies": { + "argsarray": "0.0.1", + "clone-buffer": "1.0.0", + "immediate": "3.3.0", + "inherits": "2.0.4", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-md5": "7.2.2", + "uuid": "8.1.0" + } + }, + "node_modules/pouchdb/node_modules/readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pouchdb/node_modules/string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/prr": { + "version": "1.0.1", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "node_modules/psl": { + "version": "1.8.0", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/punycode": { + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/spark-md5": { + "version": "3.0.1", + "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/sublevel-pouchdb": { + "version": "7.2.2", + "integrity": "sha512-y5uYgwKDgXVyPZceTDGWsSFAhpSddY29l9PJbXqMJLfREdPmQTY8InpatohlEfCXX7s1LGcrfYAhxPFZaJOLnQ==", + "dependencies": { + "inherits": "2.0.4", + "level-codec": "9.0.2", + "ltgt": "2.2.1", + "readable-stream": "1.1.14" + } + }, + "node_modules/sublevel-pouchdb/node_modules/readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/sublevel-pouchdb/node_modules/string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/through2": { + "version": "3.0.2", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-node": { + "version": "10.5.0", + "integrity": "sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "4.5.5", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/uuid": { + "version": "8.1.0", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, + "node_modules/vuvuzela": { + "version": "1.0.3", + "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" + }, + "node_modules/write-stream": { + "version": "0.4.3", + "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", + "dependencies": { + "readable-stream": "~0.0.2" + } + }, + "node_modules/write-stream/node_modules/readable-stream": { + "version": "0.0.4", + "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" + }, + "node_modules/xtend": { + "version": "4.0.2", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/xxhash-wasm": { + "version": "1.0.1", + "integrity": "sha512-Lc9CTvDrH2vRoiaUzz25q7lRaviMhz90pkx6YxR9EPYtF99yOJnv2cB+CQ0hp/TLoqrUsk8z/W2EN31T568Azw==" + }, + "node_modules/yn": { + "version": "3.1.1", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/debug": { + "version": "4.1.7", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/ms": { + "version": "0.7.31", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "@types/node": { + "version": "17.0.18", + "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", + "dev": true + }, + "@types/pouchdb": { + "version": "6.4.0", + "integrity": "sha512-eGCpX+NXhd5VLJuJMzwe3L79fa9+IDTrAG3CPaf4s/31PD56hOrhDJTSmRELSXuiqXr6+OHzzP0PldSaWsFt7w==", + "dev": true, + "requires": { + "@types/pouchdb-adapter-cordova-sqlite": "*", + "@types/pouchdb-adapter-fruitdown": "*", + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-idb": "*", + "@types/pouchdb-adapter-leveldb": "*", + "@types/pouchdb-adapter-localstorage": "*", + "@types/pouchdb-adapter-memory": "*", + "@types/pouchdb-adapter-node-websql": "*", + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-browser": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-http": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-node": "*", + "@types/pouchdb-replication": "*" + } + }, + "@types/pouchdb-adapter-cordova-sqlite": { + "version": "1.0.1", + "integrity": "sha512-nqlXpW1ho3KBg1mUQvZgH2755y3z/rw4UA7ZJCPMRTHofxGMY8izRVw5rHBL4/7P615or0J2udpRYxgkT3D02g==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-fruitdown": { + "version": "6.1.3", + "integrity": "sha512-Wz1Z1JLOW1hgmFQjqnSkmyyfH7by/iWb4abKn684WMvQfmxx6BxKJpJ4+eulkVPQzzgMMSgU1MpnQOm9FgRkbw==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-http": { + "version": "6.1.3", + "integrity": "sha512-9Z4TLbF/KJWy/D2sWRPBA+RNU0odQimfdvlDX+EY7rGcd3aVoH8qjD/X0Xcd/0dfBH5pKrNIMFFQgW/TylRCmA==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-idb": { + "version": "6.1.4", + "integrity": "sha512-KIAXbkF4uYUz0ZwfNEFLtEkK44mEWopAsD76UhucH92XnJloBysav+TjI4FFfYQyTjoW3S1s6V+Z14CUJZ0F6w==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-leveldb": { + "version": "6.1.3", + "integrity": "sha512-ex8NFqQGFwEpFi7AaZ5YofmuemfZNsL3nTFZBUCAKYMBkazQij1pe2ILLStSvJr0XS0qxgXjCEW19T5Wqiiskg==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-localstorage": { + "version": "6.1.3", + "integrity": "sha512-oor040tye1KKiGLWYtIy7rRT7C2yoyX3Tf6elEJRpjOA7Ja/H8lKc4LaSh9ATbptIcES6MRqZDxtp7ly9hsW3Q==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-memory": { + "version": "6.1.3", + "integrity": "sha512-gVbsIMzDzgZYThFVT4eVNsmuZwVm/4jDxP1sjlgc3qtDIxbtBhGgyNfcskwwz9Zu5Lv1avkDsIWvcxQhnvRlHg==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-node-websql": { + "version": "6.1.3", + "integrity": "sha512-F/P+os6Jsa7CgHtH64+Z0HfwIcj0hIRB5z8gNhF7L7dxPWoAfkopK5H2gydrP3sQrlGyN4WInF+UJW/Zu1+FKg==", + "dev": true, + "requires": { + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-adapter-websql": { + "version": "6.1.4", + "integrity": "sha512-zMJQCtXC40hBsIDRn0GhmpeGMK0f9l/OGWfLguvczROzxxcOD7REI+e6SEmX7gJKw5JuMvlfuHzkQwjmvSJbtg==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-browser": { + "version": "6.1.3", + "integrity": "sha512-EdYowrWxW9SWBMX/rux2eq7dbHi5Zeyzz+FF/IAsgQKnUxgeCO5VO2j4zTzos0SDyJvAQU+EYRc11r7xGn5tvA==", + "dev": true, + "requires": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-idb": "*", + "@types/pouchdb-adapter-websql": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-replication": "*" + } + }, + "@types/pouchdb-core": { + "version": "7.0.10", + "integrity": "sha512-mKhjLlWWXyV3PTTjDhzDV1kc2dolO7VYFa75IoKM/hr8Er9eo8RIbS7mJLfC8r/C3p6ihZu9yZs1PWC1LQ0SOA==", + "dev": true, + "requires": { + "@types/debug": "*", + "@types/pouchdb-find": "*" + } + }, + "@types/pouchdb-find": { + "version": "6.3.7", + "integrity": "sha512-b2dr9xoZRK5Mwl8UiRA9l5j9mmCxNfqXuu63H1KZHwJLILjoIIz7BntCvM0hnlnl7Q8P8wORq0IskuaMq5Nnnw==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-http": { + "version": "6.1.3", + "integrity": "sha512-0e9E5SqNOyPl/3FnEIbENssB4FlJsNYuOy131nxrZk36S+y1R/6qO7ZVRypWpGTqBWSuVd7gCsq2UDwO/285+w==", + "dev": true, + "requires": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-mapreduce": { + "version": "6.1.6", + "integrity": "sha512-YubC1pKmQGbPrZzYP5vUNrlafMTkO2+AZIumLB39Lkw1rYFxa4pwiKlygtDgJD2Gy+6A5Nu3ShTPrB3kPOXFyg==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*" + } + }, + "@types/pouchdb-node": { + "version": "6.1.4", + "integrity": "sha512-wnTCH8X1JOPpNOfVhz8HW0AvmdHh6pt40MuRj0jQnK7QEHsHS79WujsKTKSOF8QXtPwpvCNSsI7ut7H7tfxxJQ==", + "dev": true, + "requires": { + "@types/pouchdb-adapter-http": "*", + "@types/pouchdb-adapter-leveldb": "*", + "@types/pouchdb-core": "*", + "@types/pouchdb-mapreduce": "*", + "@types/pouchdb-replication": "*" + } + }, + "@types/pouchdb-replication": { + "version": "6.4.3", + "integrity": "sha512-Dsyy8EhKGBIQAECKelfvufDjRO5Rsy8RlujVllbjHzu3OGu8cNP92/bykeXXC3hTgvrp5Kviqhh9VON1Iw+M3Q==", + "dev": true, + "requires": { + "@types/pouchdb-core": "*", + "@types/pouchdb-find": "*" + } + }, + "abort-controller": { + "version": "3.0.0", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "abstract-leveldown": { + "version": "6.2.3", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "requires": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "acorn": { + "version": "8.7.0", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argsarray": { + "version": "0.0.1", + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" + }, + "base64-js": { + "version": "1.5.1", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.1", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "builtin-modules": { + "version": "3.2.0", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "clone-buffer": { + "version": "1.0.0", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + }, + "core-util-is": { + "version": "1.0.3", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "create-require": { + "version": "1.1.1", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "deferred-leveldown": { + "version": "5.3.0", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "requires": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + } + }, + "diff": { + "version": "4.0.2", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "double-ended-queue": { + "version": "2.1.0-0", + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + }, + "encoding-down": { + "version": "6.3.0", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "requires": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + } + }, + "end-stream": { + "version": "0.1.0", + "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", + "requires": { + "write-stream": "~0.4.3" + } + }, + "errno": { + "version": "0.1.8", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "requires": { + "prr": "~1.0.1" + } + }, + "esbuild": { + "version": "0.14.22", + "integrity": "sha512-CjFCFGgYtbFOPrwZNJf7wsuzesx8kqwAffOlbYcFDLFuUtP8xloK1GH+Ai13Qr0RZQf9tE7LMTHJ2iVGJ1SKZA==", + "dev": true, + "requires": { + "esbuild-android-arm64": "0.14.22", + "esbuild-darwin-64": "0.14.22", + "esbuild-darwin-arm64": "0.14.22", + "esbuild-freebsd-64": "0.14.22", + "esbuild-freebsd-arm64": "0.14.22", + "esbuild-linux-32": "0.14.22", + "esbuild-linux-64": "0.14.22", + "esbuild-linux-arm": "0.14.22", + "esbuild-linux-arm64": "0.14.22", + "esbuild-linux-mips64le": "0.14.22", + "esbuild-linux-ppc64le": "0.14.22", + "esbuild-linux-riscv64": "0.14.22", + "esbuild-linux-s390x": "0.14.22", + "esbuild-netbsd-64": "0.14.22", + "esbuild-openbsd-64": "0.14.22", + "esbuild-sunos-64": "0.14.22", + "esbuild-windows-32": "0.14.22", + "esbuild-windows-64": "0.14.22", + "esbuild-windows-arm64": "0.14.22" + } + }, + "esbuild-windows-64": { + "version": "0.14.22", + "integrity": "sha512-AxjIDcOmx17vr31C5hp20HIwz1MymtMjKqX4qL6whPj0dT9lwxPexmLj6G1CpR3vFhui6m75EnBEe4QL82SYqw==", + "dev": true, + "optional": true + }, + "event-target-shim": { + "version": "5.0.1", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "fetch-cookie": { + "version": "0.10.1", + "integrity": "sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g==", + "requires": { + "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "immediate": { + "version": "3.3.0", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, + "inherits": { + "version": "2.0.4", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "isarray": { + "version": "0.0.1", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "level": { + "version": "6.0.1", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "requires": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + } + }, + "level-codec": { + "version": "9.0.2", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "requires": { + "buffer": "^5.6.0" + } + }, + "level-concat-iterator": { + "version": "2.0.1", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" + }, + "level-errors": { + "version": "2.0.1", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "requires": { + "errno": "~0.1.1" + } + }, + "level-iterator-stream": { + "version": "4.0.2", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + } + }, + "level-js": { + "version": "5.0.2", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "requires": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + } + }, + "level-packager": { + "version": "5.1.1", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "requires": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + } + }, + "level-supports": { + "version": "1.0.1", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "requires": { + "xtend": "^4.0.2" + } + }, + "level-write-stream": { + "version": "1.0.0", + "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", + "requires": { + "end-stream": "~0.1.0" + } + }, + "leveldown": { + "version": "5.6.0", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "requires": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + } + }, + "levelup": { + "version": "4.4.0", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "requires": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + } + }, + "ltgt": { + "version": "2.2.1", + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + }, + "make-error": { + "version": "1.3.6", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "napi-macros": { + "version": "2.0.0", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + }, + "node-fetch": { + "version": "2.6.0", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "node-gyp-build": { + "version": "4.1.1", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pouchdb": { + "version": "7.2.2", + "integrity": "sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw==", + "requires": { + "abort-controller": "3.0.0", + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "clone-buffer": "1.0.0", + "double-ended-queue": "2.1.0-0", + "fetch-cookie": "0.10.1", + "immediate": "3.3.0", + "inherits": "2.0.4", + "level": "6.0.1", + "level-codec": "9.0.2", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "levelup": "4.4.0", + "ltgt": "2.2.1", + "node-fetch": "2.6.0", + "readable-stream": "1.1.14", + "spark-md5": "3.0.1", + "through2": "3.0.2", + "uuid": "8.1.0", + "vuvuzela": "1.0.3" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "pouchdb-abstract-mapreduce": { + "version": "7.2.2", + "integrity": "sha512-7HWN/2yV2JkwMnGnlp84lGvFtnm0Q55NiBUdbBcaT810+clCGKvhssBCrXnmwShD1SXTwT83aszsgiSfW+SnBA==", + "requires": { + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collate": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-mapreduce-utils": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-adapter-http": { + "version": "7.2.2", + "integrity": "sha512-6Z6umJq7b5sRXwDM3CLfHrGhJPMR02M5osUxkwH1PpqcTF0EXPJvX+PtzTjSPcXWfaK6kgH3zNrRKQDdpzjI9A==", + "requires": { + "argsarray": "0.0.1", + "pouchdb-binary-utils": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-adapter-leveldb": { + "version": "7.2.2", + "integrity": "sha512-f0m1ZbP5wvnEQIVy7Po89Hhh0mrkkf5LEEZJ3H54pdqpE1ebuJ3WorI3J3CsBXAh4i3PBNR/6SsmO7YhQONsjQ==", + "requires": { + "level": "6.0.1", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "pouchdb-adapter-leveldb-core": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2", + "through2": "3.0.2" + } + }, + "pouchdb-adapter-leveldb-core": { + "version": "7.2.2", + "integrity": "sha512-K9UGf1Ivwe87mjrMqN+1D07tO/DfU7ariVDrGffuOjvl+3BcvUF25IWrxsBObd4iPOYCH7NVQWRpojhBgxULtQ==", + "requires": { + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "double-ended-queue": "2.1.0-0", + "levelup": "4.4.0", + "pouchdb-adapter-utils": "7.2.2", + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-json": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2", + "sublevel-pouchdb": "7.2.2", + "through2": "3.0.2" + } + }, + "pouchdb-adapter-utils": { + "version": "7.2.2", + "integrity": "sha512-2CzZkTyTyHZkr3ePiWFMTiD5+56lnembMjaTl8ohwegM0+hYhRyJux0biAZafVxgIL4gnCUC4w2xf6WVztzKdg==", + "requires": { + "pouchdb-binary-utils": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-md5": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-binary-utils": { + "version": "7.2.2", + "integrity": "sha512-shacxlmyHbUrNfE6FGYpfyAJx7Q0m91lDdEAaPoKZM3SzAmbtB1i+OaDNtYFztXjJl16yeudkDb3xOeokVL3Qw==", + "requires": { + "buffer-from": "1.1.1" + } + }, + "pouchdb-changes-filter": { + "version": "7.2.2", + "integrity": "sha512-1txJnTtL/C7zrq+spLt3pH9EDHTWmLLwp2zx8zUQrkt6eQtuLuXUI7G84xe+hfpU0rQvUzp/APYMnko0/6Rw0A==", + "requires": { + "pouchdb-errors": "7.2.2", + "pouchdb-selector-core": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-checkpointer": { + "version": "7.2.2", + "integrity": "sha512-O2i0vjLnZwcuSI41omrdaiyPWofCRLPBs+Sw5ad/GtYQbvxRt0CJEqYCrOaDnAsgIVoRG5PK/9gDzszv2CQsvg==", + "requires": { + "pouchdb-collate": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-collate": { + "version": "7.2.2", + "integrity": "sha512-/SMY9GGasslknivWlCVwXMRMnQ8myKHs4WryQ5535nq1Wj/ehpqWloMwxEQGvZE1Sda3LOm7/5HwLTcB8Our+w==" + }, + "pouchdb-collections": { + "version": "7.2.2", + "integrity": "sha512-6O9zyAYlp3UdtfneiMYuOCWdUCQNo2bgdjvNsMSacQX+3g8WvIoFQCYJjZZCpTttQGb+MHeRMr8m2U95lhJTew==" + }, + "pouchdb-core": { + "version": "7.2.2", + "integrity": "sha512-AnMmSH+xx12Vk6oASDRQoElXfV9fSn8MIwfus0oa2lqkxowx4bvidofZbhZfKEiE6QgKwFEOBzs56MS3znI8TQ==", + "requires": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-changes-filter": "7.2.2", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-fetch": "7.2.2", + "pouchdb-merge": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-errors": { + "version": "7.2.2", + "integrity": "sha512-6GQsiWc+7uPfgEHeavG+7wuzH3JZW29Dnrvz8eVbDFE50kVFxNDVm3EkYHskvo5isG7/IkOx7PV7RPTA3keG3g==", + "requires": { + "inherits": "2.0.4" + } + }, + "pouchdb-fetch": { + "version": "7.2.2", + "integrity": "sha512-lUHmaG6U3zjdMkh8Vob9GvEiRGwJfXKE02aZfjiVQgew+9SLkuOxNw3y2q4d1B6mBd273y1k2Lm0IAziRNxQnA==", + "requires": { + "abort-controller": "3.0.0", + "fetch-cookie": "0.10.1", + "node-fetch": "2.6.0" + } + }, + "pouchdb-generate-replication-id": { + "version": "7.2.2", + "integrity": "sha512-kBr9jTM3/qEQQDhraXdIhhy+OSi18X6pMJnWCSaT43194XuWZltnjH1Hty0aJ0U9s1UanyxqZwrb7wJT6QUpzg==", + "requires": { + "pouchdb-collate": "7.2.2", + "pouchdb-md5": "7.2.2" + } + }, + "pouchdb-json": { + "version": "7.2.2", + "integrity": "sha512-3b2S2ynN+aoB7aCNyDZc/4c0IAdx/ir3nsHB+/RrKE9cM3QkQYbnnE3r/RvOD1Xvr6ji/KOCBie+Pz/6sxoaug==", + "requires": { + "vuvuzela": "1.0.3" + } + }, + "pouchdb-mapreduce": { + "version": "7.2.2", + "integrity": "sha512-uDXEzznnZmCz3YJQ2AwVhiUDCYOaIypg1EZ2VmYOCoJnUPfmOp6LY/MPBug/sqq/BDrQCUIEtKs+Sva/L6m8xg==", + "requires": { + "pouchdb-abstract-mapreduce": "7.2.2", + "pouchdb-mapreduce-utils": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-mapreduce-utils": { + "version": "7.2.2", + "integrity": "sha512-rAllb73hIkU8rU2LJNbzlcj91KuulpwQu804/F6xF3fhZKC/4JQMClahk+N/+VATkpmLxp1zWmvmgdlwVU4HtQ==", + "requires": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-collections": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-md5": { + "version": "7.2.2", + "integrity": "sha512-c/RvLp2oSh8PLAWU5vFBnp6ejJABIdKqboZwRRUrWcfGDf+oyX8RgmJFlYlzMMOh4XQLUT1IoaDV8cwlsuryZw==", + "requires": { + "pouchdb-binary-utils": "7.2.2", + "spark-md5": "3.0.1" + } + }, + "pouchdb-merge": { + "version": "7.2.2", + "integrity": "sha512-6yzKJfjIchBaS7Tusuk8280WJdESzFfQ0sb4jeMUNnrqs4Cx3b0DIEOYTRRD9EJDM+je7D3AZZ4AT0tFw8gb4A==" + }, + "pouchdb-node": { + "version": "7.2.2", + "integrity": "sha512-r1JenKn+HWXAK8EMcoWp8rXzeBVGcnPd/IOiOHwac36rUAZkKBFrWnS1jkJcbJcghIFxTn1w9tL0HBdaR1PFSg==", + "requires": { + "abort-controller": "3.0.0", + "argsarray": "0.0.1", + "buffer-from": "1.1.1", + "clone-buffer": "1.0.0", + "double-ended-queue": "2.1.0-0", + "fetch-cookie": "0.10.1", + "inherits": "2.0.4", + "level": "6.0.1", + "level-codec": "9.0.2", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "levelup": "4.4.0", + "ltgt": "2.2.1", + "node-fetch": "2.6.0", + "readable-stream": "1.1.14", + "through2": "3.0.2", + "uuid": "8.1.0", + "vuvuzela": "1.0.3" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "pouchdb-replication": { + "version": "7.2.2", + "integrity": "sha512-+Q2zqXWaHPOut0jGMABplmlML+8jUzkefyxZXgU6bXSbC9kEJCBAkjaFeZsF10HpsQZ9tHZ577g5EOqj7V1lTQ==", + "requires": { + "inherits": "2.0.4", + "pouchdb-checkpointer": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-generate-replication-id": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-selector-core": { + "version": "7.2.2", + "integrity": "sha512-XYKCNv9oiNmSXV5+CgR9pkEkTFqxQGWplnVhO3W9P154H08lU0ZoNH02+uf+NjZ2kjse7Q1fxV4r401LEcGMMg==", + "requires": { + "pouchdb-collate": "7.2.2", + "pouchdb-utils": "7.2.2" + } + }, + "pouchdb-utils": { + "version": "7.2.2", + "integrity": "sha512-XmeM5ioB4KCfyB2MGZXu1Bb2xkElNwF1qG+zVFbQsKQij0zvepdOUfGuWvLRHxTOmt4muIuSOmWZObZa3NOgzQ==", + "requires": { + "argsarray": "0.0.1", + "clone-buffer": "1.0.0", + "immediate": "3.3.0", + "inherits": "2.0.4", + "pouchdb-collections": "7.2.2", + "pouchdb-errors": "7.2.2", + "pouchdb-md5": "7.2.2", + "uuid": "8.1.0" + } + }, + "prr": { + "version": "1.0.1", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "psl": { + "version": "1.8.0", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "2.1.1", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "readable-stream": { + "version": "3.6.0", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "spark-md5": { + "version": "3.0.1", + "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==" + }, + "string_decoder": { + "version": "1.3.0", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "sublevel-pouchdb": { + "version": "7.2.2", + "integrity": "sha512-y5uYgwKDgXVyPZceTDGWsSFAhpSddY29l9PJbXqMJLfREdPmQTY8InpatohlEfCXX7s1LGcrfYAhxPFZaJOLnQ==", + "requires": { + "inherits": "2.0.4", + "level-codec": "9.0.2", + "ltgt": "2.2.1", + "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "through2": { + "version": "3.0.2", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "4.0.0", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "ts-node": { + "version": "10.5.0", + "integrity": "sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "4.5.5", + "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "8.1.0", + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" + }, + "v8-compile-cache-lib": { + "version": "3.0.0", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, + "vuvuzela": { + "version": "1.0.3", + "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" + }, + "write-stream": { + "version": "0.4.3", + "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", + "requires": { + "readable-stream": "~0.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "0.0.4", + "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" + } + } + }, + "xtend": { + "version": "4.0.2", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "xxhash-wasm": { + "version": "1.0.1", + "integrity": "sha512-Lc9CTvDrH2vRoiaUzz25q7lRaviMhz90pkx6YxR9EPYtF99yOJnv2cB+CQ0hp/TLoqrUsk8z/W2EN31T568Azw==" + }, + "yn": { + "version": "3.1.1", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..34189f4 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "name": "filesystem-livesync", + "version": "0.0.1", + "description": "", + "main": "index.js", + "type": "commonjs", + "scripts": { + "dev": "node esbuild.config.mjs && node dist/index.js", + "build": "node esbuild.config.mjs production" + }, + "author": "", + "license": "ISC", + "dependencies": { + "chokidar": "^3.5.3", + "pouchdb": "^7.2.2", + "pouchdb-adapter-http": "^7.2.2", + "pouchdb-adapter-leveldb": "^7.2.2", + "pouchdb-core": "^7.2.2", + "pouchdb-mapreduce": "^7.2.2", + "pouchdb-node": "^7.2.2", + "pouchdb-replication": "^7.2.2", + "xxhash-wasm": "^1.0.1" + }, + "devDependencies": { + "@tsconfig/node16": "^1.0.2", + "@types/node": "^17.0.18", + "@types/pouchdb": "^6.4.0", + "builtin-modules": "^3.2.0", + "esbuild": "^0.14.22", + "ts-node": "^10.5.0", + "typescript": "^4.5.5" + } +} diff --git a/src/e2ee.ts b/src/e2ee.ts new file mode 100644 index 0000000..98a0b8d --- /dev/null +++ b/src/e2ee.ts @@ -0,0 +1,175 @@ +import { Logger } from "./logger"; +import { LOG_LEVEL } from "./types"; +import { webcrypto as crypto } from "crypto"; + +export type encodedData = [encryptedData: string, iv: string, salt: string]; +export type KeyBuffer = { + index: string; + key: CryptoKey; + salt: Uint8Array; +}; + +let KeyBuffs: KeyBuffer[] = []; +let decKeyBuffs: KeyBuffer[] = []; + +const KEY_RECYCLE_COUNT = 100; +let recycleCount = KEY_RECYCLE_COUNT; + +let semiStaticFieldBuffer: Uint8Array; +const nonceBuffer: Uint32Array = new Uint32Array(1); + +export async function getKeyForEncrypt(passphrase: string): Promise<[CryptoKey, Uint8Array]> { + // For performance, the plugin reuses the key KEY_RECYCLE_COUNT times. + const f = KeyBuffs.find((e) => e.index == passphrase); + if (f) { + recycleCount--; + if (recycleCount > 0) { + return [f.key, f.salt]; + } + KeyBuffs = KeyBuffs.filter((e) => e != f); + recycleCount = KEY_RECYCLE_COUNT; + } + const xpassphrase = new TextEncoder().encode(passphrase); + const digest = await crypto.subtle.digest({ name: "SHA-256" }, xpassphrase); + const keyMaterial = await crypto.subtle.importKey("raw", digest, { name: "PBKDF2" }, false, ["deriveKey"]); + const salt = crypto.getRandomValues(new Uint8Array(16)); + const key = await crypto.subtle.deriveKey( + { + name: "PBKDF2", + salt, + iterations: 100000, + hash: "SHA-256", + }, + keyMaterial, + { name: "AES-GCM", length: 256 }, + false, + ["encrypt"] + ); + KeyBuffs.push({ + index: passphrase, + key, + salt, + }); + while (KeyBuffs.length > 50) { + KeyBuffs.shift(); + } + return [key, salt]; +} + +export async function getKeyForDecryption(passphrase: string, salt: Uint8Array): Promise<[CryptoKey, Uint8Array]> { + const bufKey = passphrase + uint8ArrayToHexString(salt); + const f = decKeyBuffs.find((e) => e.index == bufKey); + if (f) { + return [f.key, f.salt]; + } + const xpassphrase = new TextEncoder().encode(passphrase); + const digest = await crypto.subtle.digest({ name: "SHA-256" }, xpassphrase); + const keyMaterial = await crypto.subtle.importKey("raw", digest, { name: "PBKDF2" }, false, ["deriveKey"]); + const key = await crypto.subtle.deriveKey( + { + name: "PBKDF2", + salt, + iterations: 100000, + hash: "SHA-256", + }, + keyMaterial, + { name: "AES-GCM", length: 256 }, + false, + ["decrypt"] + ); + decKeyBuffs.push({ + index: bufKey, + key, + salt, + }); + while (decKeyBuffs.length > 50) { + decKeyBuffs.shift(); + } + return [key, salt]; +} + +function getSemiStaticField(reset?: boolean) { + // return fixed field of iv. + if (semiStaticFieldBuffer != null && !reset) { + return semiStaticFieldBuffer; + } + semiStaticFieldBuffer = crypto.getRandomValues(new Uint8Array(12)); + return semiStaticFieldBuffer; +} + +function getNonce() { + // This is nonce, so do not send same thing. + nonceBuffer[0]++; + if (nonceBuffer[0] > 10000) { + // reset semi-static field. + getSemiStaticField(true); + } + return nonceBuffer; +} + +function uint8ArrayToHexString(src: Uint8Array): string { + return Array.from(src) + .map((e: number): string => `00${e.toString(16)}`.slice(-2)) + .join(""); +} +function hexStringToUint8Array(src: string): Uint8Array { + const srcArr = [...src]; + const arr = srcArr.reduce((acc, _, i) => (i % 2 ? acc : [...acc, srcArr.slice(i, i + 2).join("")]), [] as string[]).map((e) => parseInt(e, 16)); + return Uint8Array.from(arr); +} +function btoa(src: string): string { + return Buffer.from(src, "binary").toString("base64"); +} +function atob(src: string): string { + return Buffer.from(src, "base64").toString("binary"); +} +export async function encrypt(input: string, passphrase: string) { + const [key, salt] = await getKeyForEncrypt(passphrase); + // Create initial vector with semifixed part and incremental part + // I think it's not good against related-key attacks. + const fixedPart = getSemiStaticField(); + const invocationPart = getNonce(); + const iv = Uint8Array.from([...fixedPart, ...new Uint8Array(invocationPart.buffer)]); + const plainStringified: string = JSON.stringify(input); + const plainStringBuffer: Uint8Array = new TextEncoder().encode(plainStringified); + const encryptedDataArrayBuffer = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, plainStringBuffer); + + const encryptedData = btoa(Array.from(new Uint8Array(encryptedDataArrayBuffer), (char) => String.fromCharCode(char)).join("")); + + //return data with iv and salt. + const response: encodedData = [encryptedData, uint8ArrayToHexString(iv), uint8ArrayToHexString(salt)]; + const ret = JSON.stringify(response); + return ret; +} + +export async function decrypt(encryptedResult: string, passphrase: string): Promise { + try { + const [encryptedData, ivString, salt]: encodedData = JSON.parse(encryptedResult); + const [key] = await getKeyForDecryption(passphrase, hexStringToUint8Array(salt)); + const iv = hexStringToUint8Array(ivString); + // decode base 64, it should increase speed and i should with in MAX_DOC_SIZE_BIN, so it won't OOM. + const encryptedDataBin = atob(encryptedData); + const encryptedDataArrayBuffer = Uint8Array.from(encryptedDataBin.split(""), (char) => char.charCodeAt(0)); + const plainStringBuffer: ArrayBuffer = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, encryptedDataArrayBuffer); + const plainStringified = new TextDecoder().decode(plainStringBuffer); + const plain = JSON.parse(plainStringified); + return plain; + } catch (ex) { + Logger("Couldn't decode! You should wrong the passphrases", LOG_LEVEL.VERBOSE); + Logger(ex, LOG_LEVEL.VERBOSE); + throw ex; + } +} + +export async function testCrypt() { + const src = "supercalifragilisticexpialidocious"; + const encoded = await encrypt(src, "passwordTest"); + const decrypted = await decrypt(encoded, "passwordTest"); + if (src != decrypted) { + Logger("WARNING! Your device would not support encryption.", LOG_LEVEL.VERBOSE); + return false; + } else { + Logger("CRYPT LOGIC OK", LOG_LEVEL.VERBOSE); + return true; + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..c865857 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,542 @@ +import { decrypt, encrypt } from "./e2ee.js"; +import chokidar from "chokidar"; +//@ts-ignore +import { PouchDB as PouchDB_src } from "./pouchdb.js"; +import * as fs from "fs/promises"; +import * as path from "path"; +import * as util from "util"; +import { exec } from "child_process"; + +import { Logger } from "./logger.js"; +import { configFile, connectConfig, eachConf, Entry, EntryLeaf, LoadedEntry, LOG_LEVEL, MAX_DOC_SIZE, MAX_DOC_SIZE_BIN, NewEntry, PlainEntry } from "./types.js"; +import { Stats } from "fs"; +import { addTouchedFile, isKnownFile, isPlainText, isTouchedFile, path2unix } from "./util.js"; + +const xxhash = require("xxhash-wasm"); + +const PouchDB: PouchDB.Static<{}> = PouchDB_src; + +const statFile = "./dat/stat.json"; + +let running: { [key: string]: boolean } = {}; + +let h32Raw: (inputBuffer: Uint8Array, seed?: number | undefined) => number; +let h32: (input: string, seed?: number) => string; + +let syncStat: { [key: string]: string }; +let saveStatTimer: NodeJS.Timeout | undefined = undefined; +let saveStatCount: 0; + +function log(log: any) { + Logger(log, LOG_LEVEL.INFO); +} + +function delay(ms: number): Promise { + return new Promise((res) => setTimeout(() => res(), ms)); +} + +async function saveStat() { + await fs.writeFile(statFile, JSON.stringify(syncStat)); +} +function triggerSaveStat() { + if (saveStatTimer == undefined) clearTimeout(saveStatTimer); + if (saveStatCount > 25) { + saveStatTimer = undefined; + saveStatCount = 0; + saveStat(); + } else { + saveStatCount++; + saveStatTimer = setTimeout(() => { + saveStat(); + }, 500); + } +} + +let processorTimer: NodeJS.Timeout | undefined = undefined; +async function runEngine() { + let processors = [...waitingProcessorList]; + waitingProcessorList = []; + log("Run external commands."); + const execPromise = util.promisify(exec); + const procs = processors.map((e) => execPromise(e)); + let results = await Promise.allSettled(procs); + for (const result of results) { + if (result.status == "rejected") { + log(`Failed! Reason:${result.reason}`); + } else { + log(`OK: stdout:${result.value.stdout}`); + log(`OK: stderr:${result.value.stderr}`); + } + } +} +let waitingProcessorList: string[] = []; +function triggerProcessor(procs: string) { + if (procs == "") return; + waitingProcessorList = Array.from(new Set([...waitingProcessorList, procs])); + if (processorTimer == undefined) clearTimeout(processorTimer); + processorTimer = setTimeout(() => { + runEngine(); + }, 500); +} + +async function main() { + log("LiveSync-classroom starting up."); + let xx = await xxhash(); + h32Raw = xx.h32Raw; + h32 = xx.h32ToString; + let config: configFile = JSON.parse((await fs.readFile("./dat/config.json")) + ""); + + try { + syncStat = JSON.parse((await fs.readFile(statFile)) + ""); + } catch (ex) { + log("could not read pervious sync status, initialized."); + syncStat = {}; + } + + for (const conf of Object.entries(config)) { + setTimeout(() => eachProc(conf[0], conf[1]), 100); + } +} + +let hashCache: { + [key: string]: string; +} = {}; +let hashCacheRev: { + [key: string]: string; +} = {}; + +// putDBEntry:COPIED FROM obsidian-livesync +async function putDBEntry(note: LoadedEntry, passphrase: string, database: PouchDB.Database) { + let leftData = note.data; + const savenNotes = []; + let processed = 0; + let made = 0; + let skiped = 0; + let pieceSize = MAX_DOC_SIZE_BIN; + let plainSplit = false; + let cacheUsed = 0; + const userpasswordHash = h32Raw(new TextEncoder().encode(passphrase)); + if (isPlainText(note._id)) { + pieceSize = MAX_DOC_SIZE; + plainSplit = true; + } + const newLeafs: EntryLeaf[] = []; + do { + // To keep low bandwith and database size, + // Dedup pieces on database. + // from 0.1.10, for best performance. we use markdown delimiters + // 1. \n[^\n]{longLineThreshold}[^\n]*\n -> long sentence shuld break. + // 2. \n\n shold break + // 3. \r\n\r\n should break + // 4. \n# should break. + let cPieceSize = pieceSize; + if (plainSplit) { + let minimumChunkSize = 20; //default + if (minimumChunkSize < 10) minimumChunkSize = 10; + let longLineThreshold = 250; //default + if (longLineThreshold < 100) longLineThreshold = 100; + cPieceSize = 0; + // lookup for next splittion . + // we're standing on "\n" + do { + const n1 = leftData.indexOf("\n", cPieceSize + 1); + const n2 = leftData.indexOf("\n\n", cPieceSize + 1); + const n3 = leftData.indexOf("\r\n\r\n", cPieceSize + 1); + const n4 = leftData.indexOf("\n#", cPieceSize + 1); + if (n1 == -1 && n2 == -1 && n3 == -1 && n4 == -1) { + cPieceSize = MAX_DOC_SIZE; + break; + } + + if (n1 > longLineThreshold) { + // long sentence is an established piece + cPieceSize = n1; + } else { + // cPieceSize = Math.min.apply([n2, n3, n4].filter((e) => e > 1)); + // ^ heavy. + if (n1 > 0 && cPieceSize < n1) cPieceSize = n1; + if (n2 > 0 && cPieceSize < n2) cPieceSize = n2 + 1; + if (n3 > 0 && cPieceSize < n3) cPieceSize = n3 + 3; + // Choose shorter, empty line and \n# + if (n4 > 0 && cPieceSize > n4) cPieceSize = n4 + 0; + cPieceSize++; + } + } while (cPieceSize < minimumChunkSize); + } + + // piece size determined. + const piece = leftData.substring(0, cPieceSize); + leftData = leftData.substring(cPieceSize); + processed++; + let leafid = ""; + // Get hash of piece. + let hashedPiece = ""; + let needMake = true; + if (typeof hashCache[piece] !== "undefined") { + hashedPiece = ""; + leafid = hashCache[piece]; + needMake = false; + skiped++; + cacheUsed++; + } else { + if (passphrase != "") { + // When encryption has been enabled, make hash to be different between each passphrase to avoid inferring password. + hashedPiece = "+" + (h32Raw(new TextEncoder().encode(piece)) ^ userpasswordHash).toString(16); + } else { + hashedPiece = h32(piece); + } + leafid = "h:" + hashedPiece; + + //have to make + const savePiece = await encrypt(piece, passphrase); + + const d: EntryLeaf = { + _id: leafid, + data: savePiece, + type: "leaf", + }; + newLeafs.push(d); + hashCache[piece] = leafid; + hashCacheRev[leafid] = piece; + made++; + } + savenNotes.push(leafid); + } while (leftData != ""); + let saved = true; + if (newLeafs.length > 0) { + try { + const result = await database.bulkDocs(newLeafs); + for (const item of result) { + if ((item as any).ok) { + Logger(`save ok:id:${item.id} rev:${item.rev}`, LOG_LEVEL.VERBOSE); + } else { + if ((item as any).status && (item as any).status == 409) { + // conflicted, but it would be ok in childrens. + } else { + Logger(`save failed:id:${item.id} rev:${item.rev}`, LOG_LEVEL.NOTICE); + Logger(item); + // this.disposeHashCache(); + saved = false; + } + } + } + } catch (ex) { + Logger("ERROR ON SAVING LEAVES:", LOG_LEVEL.NOTICE); + Logger(ex, LOG_LEVEL.NOTICE); + saved = false; + } + } + if (saved) { + Logger(`note content saven, pieces:${processed} new:${made}, skip:${skiped}, cache:${cacheUsed}`); + const newDoc: PlainEntry | NewEntry = { + NewNote: true, + children: savenNotes, + _id: note._id, + ctime: note.ctime, + mtime: note.mtime, + size: note.size, + type: plainSplit ? "plain" : "newnote", + }; + // Here for upsert logic, + try { + const old = await database.get(newDoc._id); + if (!old.type || old.type == "notes" || old.type == "newnote" || old.type == "plain") { + // simple use rev for new doc + newDoc._rev = old._rev; + } + } catch (ex: any) { + if (ex.status && ex.status == 404) { + // NO OP/ + } else { + throw ex; + } + } + const r = await database.put(newDoc, { force: true }); + Logger(`note saved:${newDoc._id}:${r.rev}`); + } else { + Logger(`note coud not saved:${note._id}`); + } +} +async function eachProc(syncKey: string, config: eachConf) { + log(`${syncKey} started`); + + const serverURI = config.server.uri; + const serverAuth = config.server.auth; + const serverPath = config.server.path; + + const exportPath = config.local?.path ?? ""; + const processor = config.local?.processor ?? ""; + + const remote = new PouchDB(serverURI, { auth: serverAuth }); + + async function sanityCheck() { + let mr = await remote.info(); + log("Main Remote Database"); + log(mr); + } + + if (!(syncKey in syncStat)) { + syncStat[syncKey] = "now"; + } + + try { + await sanityCheck(); + } catch (ex) { + log("Error on checking database"); + log(ex); + process.exit(-1); + } + log("Start Database watching"); + + function openConnection(e: connectConfig, auto_reconnect: boolean) { + Logger(`Connecting ${e.syncKey} with auto_reconnect:${auto_reconnect}`); + e.fromDB + .changes({ + live: true, + include_docs: true, + style: "all_docs", + since: syncStat[syncKey], + filter: (doc, _) => { + return doc._id.startsWith(e.fromPrefix) && isVaildDoc(doc._id); + }, + }) + .on("change", async function (change) { + if (change.doc?._id.startsWith(e.fromPrefix) && isVaildDoc(change.doc._id)) { + let x = await transferDoc(e.syncKey, e.fromDB, change.doc, e.fromPrefix, e.passphrase, exportPath); + if (x) { + syncStat[syncKey] = change.seq + ""; + triggerSaveStat(); + triggerProcessor(processor); + } + } + }) + .on("error", function (err) { + Logger("Error"); + Logger(err); + if (auto_reconnect) { + Logger("Performing auto_reconnect"); + setTimeout(() => { + openConnection(e, auto_reconnect); + }, 1000); + } + }) + .on("complete", (result) => { + Logger("Connection completed"); + Logger(result); + if (auto_reconnect) { + Logger("Performing auto_reconnect"); + setTimeout(() => { + openConnection(e, auto_reconnect); + }, 10000); + } + }); + } + + log("start vault watching"); + const watcher = chokidar.watch(config.local.path, { ignoreInitial: !config.local.initialScan }); + const vaultPath = path.posix.normalize(config.local.path); + + const db_add = async (pathSrc: string, stat: Stats) => { + const id = serverPath + path2unix(path.relative(path.resolve(vaultPath), path.resolve(pathSrc))); + const docId = id.startsWith("_") ? "/" + id : id; + try { + let doc = (await remote.get(docId)) as NewEntry; + if (doc.mtime) { + const mtime_srv = ~~(doc.mtime / 1000); + const mtime_loc = ~~(stat.mtime.getTime() / 1000); + if (mtime_loc == mtime_srv) { + log(`Should be not modified on ${pathSrc}`); + return; + } + } + } catch (ex: any) { + if (ex.status && ex.status == 404) { + // NO OP. + } else { + throw ex; + } + } + let content = ""; + let datatype: "newnote" | "plain" = "newnote"; + const d = await fs.readFile(pathSrc); + if (!isPlainText(pathSrc)) { + // const contentBin = await this.app.vault.readBinary(file); + // content = await arrayBufferToBase64(contentBin); + content = d.toString("base64"); + datatype = "newnote"; + } else { + content = d.toString(); + datatype = "plain"; + } + const newNote: LoadedEntry = { + _id: docId, + children: [], + ctime: stat.ctime.getTime(), + mtime: stat.mtime.getTime(), + size: stat.size, + datatype: datatype, + data: content, + // type: "plain", + }; + await putDBEntry(newNote, conf.passphrase, remote as PouchDB.Database); + }; + const db_delete = async (pathSrc: string) => { + const id = serverPath + path2unix(path.relative(path.resolve(vaultPath), path.resolve(pathSrc))); + const docId = id.startsWith("_") ? "/" + id : id; + try { + let oldNote: any = await remote.get(docId); + oldNote._deleted = true; + await remote.put(oldNote); + addTouchedFile(pathSrc, 0); + } catch (ex: any) { + if (ex.status && ex.status == 404) { + // NO OP. + } else { + throw ex; + } + } + }; + watcher.on("change", async (pathSrc: string, stat: Stats) => { + const filePath = pathSrc; + log(`Detected:change:${filePath}`); + const mtime = ~~(stat.mtime.getTime() / 1000); + if (isTouchedFile(filePath, mtime)) { + log("Self-detect"); + return; + } + addTouchedFile(pathSrc, mtime); + await db_add(pathSrc, stat); + }); + watcher.on("unlink", async (pathSrc: string, stat: Stats) => { + const filePath = pathSrc; + log(`Detected:delete:${filePath}`); + if (isTouchedFile(filePath, 0)) { + log("self-detect"); + } + await db_delete(pathSrc); + }); + watcher.on("add", async (pathSrc: string, stat: Stats) => { + const filePath = pathSrc; + log(`Detected:created:${filePath}`); + const mtime = ~~(stat.mtime.getTime() / 1000); + if (isTouchedFile(filePath, mtime)) { + log("Self-detect"); + return; + } + addTouchedFile(pathSrc, mtime); + await db_add(pathSrc, stat); + + // this.watchVaultChange(path, stat); + }); + let conf: connectConfig = { + syncKey: syncKey, + fromDB: remote, + fromPrefix: serverPath, + passphrase: serverAuth.passphrase, + }; + openConnection(conf, config.auto_reconnect ?? false); +} + +async function getChildren(children: string[], db: PouchDB.Database) { + let items = await db.allDocs({ include_docs: true, keys: [...children] }); + return items.rows.map((e) => e.doc); +} + +function isVaildDoc(id: string): boolean { + if (id == "obsydian_livesync_version") return false; + if (id.indexOf(":") !== -1) return false; + return true; +} + +async function transferDoc(syncKey: string, fromDB: PouchDB.Database, fromDoc: PouchDB.Core.ExistingDocument, fromPrefix: string, passphrase: string, exportPath: string): Promise { + const docKey = `${syncKey}: ${fromDoc._id} (${fromDoc._rev})`; + while (running[syncKey]) { + await delay(100); + } + try { + running[syncKey] = true; + if (isKnownFile(syncKey, fromDoc._id, fromDoc._rev)) { + return true; + } + log(`doc:${docKey} begin Transfer`); + let continue_count = 3; + try { + const docName = fromDoc._id.substring(fromPrefix.length); + let sendDoc: PouchDB.Core.ExistingDocument & { children?: string[]; type?: string; mtime?: number } = { ...fromDoc, _id: docName.startsWith("_") ? "/" + docName : docName }; + let retry = false; + const userpasswordHash = h32Raw(new TextEncoder().encode(passphrase)); + do { + if (retry) { + continue_count--; + if (continue_count == 0) { + log(`doc:${docKey} retry failed`); + return false; + } + await delay(1500); + } + if (sendDoc._deleted && exportPath != "") { + const writePath = path.join(exportPath, docName); + log(`doc:${docKey}: Deleted, so delete from ${writePath}`); + addTouchedFile(writePath, 0); + await fs.unlink(writePath); + } + retry = false; + if (!sendDoc.children) { + log(`doc:${docKey}: Warning! document doesn't have chunks, skipped`); + return false; + } + let cx = sendDoc.children; + let children = await getChildren(cx, fromDB); + + if (children.includes(undefined)) { + log(`doc:${docKey}: Warning! there's missing chunks, skipped`); + return false; + } else { + children = children.filter((e) => !!e); + for (const v of children) { + delete (v as any)?._rev; + } + + let decrypted_children = + passphrase == "" + ? children + : ( + await Promise.allSettled( + children.map(async (e: any) => { + e.data = await decrypt(e.data, passphrase); + return e; + }) + ) + ).map((e) => (e.status == "fulfilled" ? e.value : null)); + // If exporting is enabled, write contents to the real file. + if (exportPath != "" && !sendDoc._deleted) { + const writePath = path.join(exportPath, docName); + const dirName = path.dirname(writePath); + log(`doc:${docKey}: Exporting to ${writePath}`); + await fs.mkdir(dirName, { recursive: true }); + const dt_plain = decrypted_children.map((e) => e.data).join(""); + const mtime = sendDoc.mtime ?? new Date().getTime(); + const tmtime = ~~(mtime / 1000); + addTouchedFile(writePath, tmtime); + if (sendDoc.type == "plain") { + await fs.writeFile(writePath, dt_plain); + await fs.utimes(writePath, tmtime, tmtime); + } else { + const dt_bin = Buffer.from(dt_plain, "base64"); + await fs.writeFile(writePath, dt_bin, { encoding: "binary" }); + await fs.utimes(writePath, tmtime, tmtime); + } + } + } + } while (retry); + } catch (ex) { + log("Exception on transfer doc"); + log(ex); + } + } finally { + running[syncKey] = false; + } + return false; +} + +main().then((_) => {}); diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 0000000..df862d8 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,13 @@ +import { LOG_LEVEL } from "./types"; + +// eslint-disable-next-line require-await +export let Logger: (message: any, level?: LOG_LEVEL) => void = (message, _) => { + const timestamp = new Date().toLocaleString(); + const messagecontent = typeof message == "string" ? message : message instanceof Error ? `${message.name}:${message.message}` : JSON.stringify(message, null, 2); + const newmessage = timestamp + "->" + messagecontent; + console.log(newmessage); +}; + +export function setLogger(loggerFun: (message: any, level?: LOG_LEVEL) => Promise) { + Logger = loggerFun; +} diff --git a/src/pouchdb.js b/src/pouchdb.js new file mode 100644 index 0000000..7f6e1c2 --- /dev/null +++ b/src/pouchdb.js @@ -0,0 +1,7 @@ + +const pouchdb_src = require("pouchdb-core").plugin(require("pouchdb-adapter-leveldb")).plugin(require("pouchdb-adapter-http")).plugin(require("pouchdb-mapreduce")).plugin(require("pouchdb-replication")); +const PouchDB = pouchdb_src; +/** + * @type {PouchDB.Static<>} + */ +export { PouchDB }; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..01a33fc --- /dev/null +++ b/src/types.ts @@ -0,0 +1,93 @@ +export const LOG_LEVEL = { + VERBOSE: 1, + INFO: 10, + NOTICE: 100, + URGENT: 1000, +} as const; +export type LOG_LEVEL = typeof LOG_LEVEL[keyof typeof LOG_LEVEL]; + +export interface config { + uri: string; + auth: { + username: string; + password: string; + passphrase: string; + }; + path: string; +} +export interface localConfig { + path: string; + initialScan: boolean; + processor: string; +} + +export interface eachConf { + server: config; + local: localConfig; + auto_reconnect?: boolean; +} + +export interface configFile { + [key: string]: eachConf; +} +export interface connectConfig { + syncKey: string; + fromDB: PouchDB.Database; + fromPrefix: string; + passphrase: string; +} + +//---LiveSync's data + +export const MAX_DOC_SIZE = 1000; // for .md file, but if delimiters exists. use that before. +export const MAX_DOC_SIZE_BIN = 102400; // 100kb + +export interface EntryLeaf { + _id: string; + data: string; + _deleted?: boolean; + type: "leaf"; + _rev?: string; +} + +export interface Entry { + _id: string; + data: string; + _rev?: string; + ctime: number; + mtime: number; + size: number; + _deleted?: boolean; + _conflicts?: string[]; + type?: "notes"; +} + +export interface NewEntry { + _id: string; + children: string[]; + _rev?: string; + ctime: number; + mtime: number; + size: number; + _deleted?: boolean; + _conflicts?: string[]; + NewNote: true; + type: "newnote"; +} +export interface PlainEntry { + _id: string; + children: string[]; + _rev?: string; + ctime: number; + mtime: number; + size: number; + _deleted?: boolean; + NewNote: true; + _conflicts?: string[]; + type: "plain"; +} + +export type LoadedEntry = Entry & { + children: string[]; + datatype: "plain" | "newnote"; +}; diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..9e0344f --- /dev/null +++ b/src/util.ts @@ -0,0 +1,37 @@ +import path from "path"; + +export function isPlainText(filename: string): boolean { + if (filename.endsWith(".md")) return true; + if (filename.endsWith(".txt")) return true; + if (filename.endsWith(".svg")) return true; + if (filename.endsWith(".html")) return true; + if (filename.endsWith(".csv")) return true; + if (filename.endsWith(".css")) return true; + if (filename.endsWith(".js")) return true; + if (filename.endsWith(".xml")) return true; + + return false; +} + +export const path2unix = (pathStr: string) => pathStr.split(path.sep).join(path.posix.sep); + +let known_files: string[] = []; +let touchedFile: string[] = []; +export function addKnownFile(syncKey: string, id: string, rev: string) { + known_files.push(`${syncKey}-${id}-${rev}`); + known_files = known_files.slice(-50); +} +export function isKnownFile(syncKey: string, id: string, rev: string) { + return known_files.indexOf(`${syncKey}-${id}-${rev}`) !== -1; +} +export function addTouchedFile(pathSrc: string, mtime: number) { + const targetFile = path.resolve(pathSrc); + const key = `${targetFile}-${~~(mtime / 10)}`; + touchedFile.push(key); + touchedFile = touchedFile.slice(-50); +} +export function isTouchedFile(pathSrc: string, mtime: number) { + const targetFile = path.resolve(pathSrc); + const key = `${targetFile}-${~~(mtime / 10)}`; + return touchedFile.indexOf(key) !== -1; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5669244 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@tsconfig/node16/tsconfig.json", + "compilerOptions": { + "target": "es2017", + "module": "esnext", + "moduleResolution": "node", + "outDir": "dist" + }, + "include": ["src"], + "exclude": ["node_modules", "src/pouchdb.js"] +}