diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..11a1fbfc --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: jondubois diff --git a/.gitignore b/.gitignore index 0d209a5b..d5700888 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ node_modules/ -sample/package-lock.json diff --git a/LICENSE b/LICENSE index 43ba6c43..52098be9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 SocketCluster +Copyright (c) 2013-2023 SocketCluster Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index d56034a7..e53f5053 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ See the 'releases' section for changes: https://github.com/SocketCluster/socketc (The MIT License) -Copyright (c) 2013-2019 SocketCluster.io +Copyright (c) 2013-2023 SocketCluster.io Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/app/Dockerfile b/app/Dockerfile index 5e55592b..6bb6681d 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -1,7 +1,7 @@ -FROM node:10-slim +FROM node:18.15.0-slim LABEL maintainer="Jonathan Gros-Dubois" -LABEL version="15.0.0" +LABEL version="19.2.0" LABEL description="Docker file for SocketCluster with support for clustering." RUN mkdir -p /usr/src/ diff --git a/app/kubernetes/scc-broker-deployment.yaml b/app/kubernetes/scc-broker-deployment.yaml index e95fc278..c15416b4 100644 --- a/app/kubernetes/scc-broker-deployment.yaml +++ b/app/kubernetes/scc-broker-deployment.yaml @@ -15,7 +15,7 @@ spec: containers: - name: scc-broker - image: 'socketcluster/scc-broker:v6.0.0' + image: 'socketcluster/scc-broker:v9.2.2' ports: - name: scc-broker diff --git a/app/kubernetes/scc-state-deployment.yaml b/app/kubernetes/scc-state-deployment.yaml index f20f683e..8f671320 100644 --- a/app/kubernetes/scc-state-deployment.yaml +++ b/app/kubernetes/scc-state-deployment.yaml @@ -15,7 +15,7 @@ spec: containers: - name: scc-state - image: 'socketcluster/scc-state:v6.0.0' + image: 'socketcluster/scc-state:v9.2.0' ports: - name: scc-state diff --git a/app/kubernetes/scc-worker-deployment.yaml b/app/kubernetes/scc-worker-deployment.yaml index 44f50792..29ce595e 100644 --- a/app/kubernetes/scc-worker-deployment.yaml +++ b/app/kubernetes/scc-worker-deployment.yaml @@ -15,7 +15,7 @@ spec: containers: - name: scc-worker - image: 'socketcluster/socketcluster:v15.0.0' + image: 'socketcluster/socketcluster:v19.2.0' ports: - name: scc-worker diff --git a/app/package-lock.json b/app/package-lock.json new file mode 100644 index 00000000..19d137f7 --- /dev/null +++ b/app/package-lock.json @@ -0,0 +1,2976 @@ +{ + "name": "socketcluster-sample", + "version": "1.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "socketcluster-sample", + "version": "1.0.1", + "dependencies": { + "eetase": "^7.0.1", + "express": "^4.16.3", + "morgan": "^1.7.0", + "nodemon": "^3.1.10", + "scc-broker-client": "^9.2.0", + "serve-static": "^1.13.2", + "socketcluster-client": "^19.2.7", + "socketcluster-server": "^19.2.0", + "uuid": "^9.0.1" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ag-auth": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ag-auth/-/ag-auth-2.1.0.tgz", + "integrity": "sha512-M4l+IErFmYPk0HAvolaPyvCMyn3oJ4aPHVMeVqlxJIynkHGhyTFiT+LX+jYY34pEdwM03TLkQUMHxpXBMuNmZg==", + "dependencies": { + "jsonwebtoken": "^9.0.0", + "sc-errors": "^3.0.0" + } + }, + "node_modules/ag-channel": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ag-channel/-/ag-channel-5.0.0.tgz", + "integrity": "sha512-bArHkdqQxynim981t8FLZM5TfA0v7p081OlFdOxs6clB79GSGcGlOQMDa31DT9F5VMjzqNiJmhfGwinvfU/3Zg==", + "dependencies": { + "consumable-stream": "^2.0.0" + } + }, + "node_modules/ag-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ag-request/-/ag-request-1.1.0.tgz", + "integrity": "sha512-d4K7QC1KnIpzcnUNNOeh1ddxmYMLiIdhdc1M8osxiHbZP/uoia4IINhhf2+1CrlnNJEPUoUH0Y58Sx0qeqoIvg==", + "dependencies": { + "sc-errors": "^3.0.0" + } + }, + "node_modules/ag-simple-broker": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ag-simple-broker/-/ag-simple-broker-6.0.1.tgz", + "integrity": "sha512-pDlHotEoC9uV2Uk8DrR570QXMiUd9QYwJZXWDlBJZEbYTHzMJLEJDJStxmn7Kp4eT7SIGoPFuzELYZyMYNZ2Kw==", + "dependencies": { + "ag-channel": "^5.0.0", + "async-stream-emitter": "^7.0.1", + "stream-demux": "^10.0.1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/async-stream-emitter": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/async-stream-emitter/-/async-stream-emitter-7.0.1.tgz", + "integrity": "sha512-1bgA3iZ80rCBX2LocvsyZPy0QB3/xM+CsXBze2HDHLmshOqx2JlAANGq23djaJ48e9fpcKzTzS1QM0hAKKI0UQ==", + "dependencies": { + "stream-demux": "^10.0.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "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/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "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-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/consumable-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-2.0.0.tgz", + "integrity": "sha512-I6WA2JVYXs/68rEvi1ie3rZjP6qusTVFEQkbzR+WC+fY56TpwiGTIDJETsrnlxv5CsnmK69ps6CkYvIbpEEqBA==" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "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/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/eetase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eetase/-/eetase-7.0.1.tgz", + "integrity": "sha512-1l0eaW64Fvow/4AYUP3G+HQiZQq/LCDKAFv7t0MIoUxh6MiR/Amq9kc3ZksFtN2MjThsl3KXhawwz2Hh78On1Q==", + "dependencies": { + "async-stream-emitter": "^7.0.1" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "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/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "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/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "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": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "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/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/linked-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-2.1.0.tgz", + "integrity": "sha512-0GK/ylO6e5cv1PCOIdTRHxOaCgQ+0jKwHt+cHzkiCAZlx0KM5Id1bBAPad6g2mkvBNp1pNdmG0cohFGfqjkv9A==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "dependencies": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nodemon": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "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/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "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/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sc-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-3.0.0.tgz", + "integrity": "sha512-rIqv2HTPb9DVreZwK/DV0ytRUqyw2DbDcoB9XTKjEQL7oMEQKsfPA8V8dGGr7p8ZYfmvaRIGZ4Wu5qwvs/hGDA==" + }, + "node_modules/sc-formatter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-4.0.0.tgz", + "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==" + }, + "node_modules/scc-broker-client": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/scc-broker-client/-/scc-broker-client-9.2.0.tgz", + "integrity": "sha512-fEHD4oPUoGbWyrqDUeEZHX1VsyZwgP7FR1+B+MLG1/lw1bX/aiEbn0BIdBiIHjaYjPUfec/pUzWBTszWXpnsEQ==", + "dependencies": { + "async-stream-emitter": "^7.0.1", + "skeleton-rendezvous": "^1.1.2", + "socketcluster-client": "^19.1.0" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/send/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/skeleton-rendezvous": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/skeleton-rendezvous/-/skeleton-rendezvous-1.1.2.tgz", + "integrity": "sha512-v2HAvdDDSmDtnbtz/bi+/voztLHm/a+uijK5ilAyBew4Uwy/B+BXVFiQN+Qssb/6spYIeKYjNPr6IJOa4pf37Q==" + }, + "node_modules/socketcluster-client": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-19.2.7.tgz", + "integrity": "sha512-c6caNOr/49FUjlVnQfXb0TasMnrqY1uN/uevT99xicF+7NkvGSNwjP6rlMP0v1ZZjz+MosT2/qJNDDc2b3v/Jw==", + "dependencies": { + "ag-auth": "^2.1.0", + "ag-channel": "^5.0.0", + "ag-request": "^1.1.0", + "async-stream-emitter": "^7.0.1", + "buffer": "^5.2.1", + "clone-deep": "^4.0.1", + "linked-list": "^2.1.0", + "sc-errors": "^3.0.0", + "sc-formatter": "^4.0.0", + "stream-demux": "^10.0.1", + "uuid": "^8.3.2", + "vinyl-buffer": "^1.0.1", + "ws": "^8.18.0" + } + }, + "node_modules/socketcluster-client/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/socketcluster-server": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/socketcluster-server/-/socketcluster-server-19.2.0.tgz", + "integrity": "sha512-BoQ+Fh+yBL5AHRsew+PV6nJvyvi/u+C4Uj3a6UJiLCVA2ZNTVBMkgXxjhyvzD9mowkJCs4WlKjR8XbKTpM/WuQ==", + "dependencies": { + "ag-auth": "^2.1.0", + "ag-request": "^1.1.0", + "ag-simple-broker": "^6.0.1", + "async-stream-emitter": "^7.0.1", + "base64id": "^2.0.0", + "clone-deep": "^4.0.1", + "sc-errors": "^3.0.0", + "sc-formatter": "^4.0.0", + "stream-demux": "^10.0.1", + "writable-consumable-stream": "^4.1.0", + "ws": "^8.18.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-demux": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/stream-demux/-/stream-demux-10.0.1.tgz", + "integrity": "sha512-QjTYLJWpZxZ6uL5R1JzgOzjvao8zDx78ec+uOjHNeVc/9TuasYLldoVrYARZeT1xI1hFYuiKf13IM8b4wamhHg==", + "dependencies": { + "consumable-stream": "^3.0.0", + "writable-consumable-stream": "^4.1.0" + } + }, + "node_modules/stream-demux/node_modules/consumable-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-3.0.0.tgz", + "integrity": "sha512-CnnsJ9OG9ouxAjt3pc63/DaerezRo/WudqU71pc5epaIUi7NHu2T4v+3f0nKbbCY7icS/TfQ1Satr9rwZ7Jwsg==" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "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/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vinyl-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz", + "integrity": "sha512-LRBE2/g3C1hSHL2k/FynSZcVTRhEw8sb08oKGt/0hukZXwrh2m8nfy+r5yLhGEk7eFFuclhyIuPct/Bxlxk6rg==", + "dependencies": { + "bl": "^1.2.1", + "through2": "^2.0.3" + } + }, + "node_modules/writable-consumable-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/writable-consumable-stream/-/writable-consumable-stream-4.1.0.tgz", + "integrity": "sha512-4cjCPd4Ayfbix0qqPCzMbnPPZKRh/cKeNCj05unybP3/sRkRAOxh7rSwbhxs3YB6G4/Z2p/2FRBEIQcTeB4jyw==", + "dependencies": { + "consumable-stream": "^3.0.0" + } + }, + "node_modules/writable-consumable-stream/node_modules/consumable-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-3.0.0.tgz", + "integrity": "sha512-CnnsJ9OG9ouxAjt3pc63/DaerezRo/WudqU71pc5epaIUi7NHu2T4v+3f0nKbbCY7icS/TfQ1Satr9rwZ7Jwsg==" + }, + "node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "ag-auth": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ag-auth/-/ag-auth-2.1.0.tgz", + "integrity": "sha512-M4l+IErFmYPk0HAvolaPyvCMyn3oJ4aPHVMeVqlxJIynkHGhyTFiT+LX+jYY34pEdwM03TLkQUMHxpXBMuNmZg==", + "requires": { + "jsonwebtoken": "^9.0.0", + "sc-errors": "^3.0.0" + } + }, + "ag-channel": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ag-channel/-/ag-channel-5.0.0.tgz", + "integrity": "sha512-bArHkdqQxynim981t8FLZM5TfA0v7p081OlFdOxs6clB79GSGcGlOQMDa31DT9F5VMjzqNiJmhfGwinvfU/3Zg==", + "requires": { + "consumable-stream": "^2.0.0" + } + }, + "ag-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ag-request/-/ag-request-1.1.0.tgz", + "integrity": "sha512-d4K7QC1KnIpzcnUNNOeh1ddxmYMLiIdhdc1M8osxiHbZP/uoia4IINhhf2+1CrlnNJEPUoUH0Y58Sx0qeqoIvg==", + "requires": { + "sc-errors": "^3.0.0" + } + }, + "ag-simple-broker": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ag-simple-broker/-/ag-simple-broker-6.0.1.tgz", + "integrity": "sha512-pDlHotEoC9uV2Uk8DrR570QXMiUd9QYwJZXWDlBJZEbYTHzMJLEJDJStxmn7Kp4eT7SIGoPFuzELYZyMYNZ2Kw==", + "requires": { + "ag-channel": "^5.0.0", + "async-stream-emitter": "^7.0.1", + "stream-demux": "^10.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async-stream-emitter": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/async-stream-emitter/-/async-stream-emitter-7.0.1.tgz", + "integrity": "sha512-1bgA3iZ80rCBX2LocvsyZPy0QB3/xM+CsXBze2HDHLmshOqx2JlAANGq23djaJ48e9fpcKzTzS1QM0hAKKI0UQ==", + "requires": { + "stream-demux": "^10.0.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "requires": { + "fill-range": "^7.1.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "requires": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + } + }, + "call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + } + }, + "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-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "consumable-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-2.0.0.tgz", + "integrity": "sha512-I6WA2JVYXs/68rEvi1ie3rZjP6qusTVFEQkbzR+WC+fY56TpwiGTIDJETsrnlxv5CsnmK69ps6CkYvIbpEEqBA==" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "requires": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "eetase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eetase/-/eetase-7.0.1.tgz", + "integrity": "sha512-1l0eaW64Fvow/4AYUP3G+HQiZQq/LCDKAFv7t0MIoUxh6MiR/Amq9kc3ZksFtN2MjThsl3KXhawwz2Hh78On1Q==", + "requires": { + "async-stream-emitter": "^7.0.1" + } + }, + "encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" + }, + "es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "requires": { + "es-errors": "^1.3.0" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "requires": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + } + }, + "get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "requires": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + } + }, + "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" + } + }, + "gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "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": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "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==" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + }, + "jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "linked-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-2.1.0.tgz", + "integrity": "sha512-0GK/ylO6e5cv1PCOIdTRHxOaCgQ+0jKwHt+cHzkiCAZlx0KM5Id1bBAPad6g2mkvBNp1pNdmG0cohFGfqjkv9A==" + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "nodemon": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", + "requires": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "requires": { + "ms": "^2.1.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "requires": { + "side-channel": "^1.0.6" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "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.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sc-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-3.0.0.tgz", + "integrity": "sha512-rIqv2HTPb9DVreZwK/DV0ytRUqyw2DbDcoB9XTKjEQL7oMEQKsfPA8V8dGGr7p8ZYfmvaRIGZ4Wu5qwvs/hGDA==" + }, + "sc-formatter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-4.0.0.tgz", + "integrity": "sha512-MgUIvuca+90fBrCWY5LdlU9YUWjlkPFwdpvmomcwQEu3t2id/6YHdG2nhB6o7nhRp4ocfmcXQTh00r/tJtynSg==" + }, + "scc-broker-client": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/scc-broker-client/-/scc-broker-client-9.2.0.tgz", + "integrity": "sha512-fEHD4oPUoGbWyrqDUeEZHX1VsyZwgP7FR1+B+MLG1/lw1bX/aiEbn0BIdBiIHjaYjPUfec/pUzWBTszWXpnsEQ==", + "requires": { + "async-stream-emitter": "^7.0.1", + "skeleton-rendezvous": "^1.1.2", + "socketcluster-client": "^19.1.0" + } + }, + "semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" + }, + "send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "requires": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "requires": { + "kind-of": "^6.0.2" + } + }, + "side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "requires": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + } + }, + "side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "requires": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + } + }, + "side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + } + }, + "side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "requires": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + } + }, + "simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "requires": { + "semver": "^7.5.3" + } + }, + "skeleton-rendezvous": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/skeleton-rendezvous/-/skeleton-rendezvous-1.1.2.tgz", + "integrity": "sha512-v2HAvdDDSmDtnbtz/bi+/voztLHm/a+uijK5ilAyBew4Uwy/B+BXVFiQN+Qssb/6spYIeKYjNPr6IJOa4pf37Q==" + }, + "socketcluster-client": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-19.2.7.tgz", + "integrity": "sha512-c6caNOr/49FUjlVnQfXb0TasMnrqY1uN/uevT99xicF+7NkvGSNwjP6rlMP0v1ZZjz+MosT2/qJNDDc2b3v/Jw==", + "requires": { + "ag-auth": "^2.1.0", + "ag-channel": "^5.0.0", + "ag-request": "^1.1.0", + "async-stream-emitter": "^7.0.1", + "buffer": "^5.2.1", + "clone-deep": "^4.0.1", + "linked-list": "^2.1.0", + "sc-errors": "^3.0.0", + "sc-formatter": "^4.0.0", + "stream-demux": "^10.0.1", + "uuid": "^8.3.2", + "vinyl-buffer": "^1.0.1", + "ws": "^8.18.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, + "socketcluster-server": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/socketcluster-server/-/socketcluster-server-19.2.0.tgz", + "integrity": "sha512-BoQ+Fh+yBL5AHRsew+PV6nJvyvi/u+C4Uj3a6UJiLCVA2ZNTVBMkgXxjhyvzD9mowkJCs4WlKjR8XbKTpM/WuQ==", + "requires": { + "ag-auth": "^2.1.0", + "ag-request": "^1.1.0", + "ag-simple-broker": "^6.0.1", + "async-stream-emitter": "^7.0.1", + "base64id": "^2.0.0", + "clone-deep": "^4.0.1", + "sc-errors": "^3.0.0", + "sc-formatter": "^4.0.0", + "stream-demux": "^10.0.1", + "writable-consumable-stream": "^4.1.0", + "ws": "^8.18.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "stream-demux": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/stream-demux/-/stream-demux-10.0.1.tgz", + "integrity": "sha512-QjTYLJWpZxZ6uL5R1JzgOzjvao8zDx78ec+uOjHNeVc/9TuasYLldoVrYARZeT1xI1hFYuiKf13IM8b4wamhHg==", + "requires": { + "consumable-stream": "^3.0.0", + "writable-consumable-stream": "^4.1.0" + }, + "dependencies": { + "consumable-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-3.0.0.tgz", + "integrity": "sha512-CnnsJ9OG9ouxAjt3pc63/DaerezRo/WudqU71pc5epaIUi7NHu2T4v+3f0nKbbCY7icS/TfQ1Satr9rwZ7Jwsg==" + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "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" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vinyl-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz", + "integrity": "sha512-LRBE2/g3C1hSHL2k/FynSZcVTRhEw8sb08oKGt/0hukZXwrh2m8nfy+r5yLhGEk7eFFuclhyIuPct/Bxlxk6rg==", + "requires": { + "bl": "^1.2.1", + "through2": "^2.0.3" + } + }, + "writable-consumable-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/writable-consumable-stream/-/writable-consumable-stream-4.1.0.tgz", + "integrity": "sha512-4cjCPd4Ayfbix0qqPCzMbnPPZKRh/cKeNCj05unybP3/sRkRAOxh7rSwbhxs3YB6G4/Z2p/2FRBEIQcTeB4jyw==", + "requires": { + "consumable-stream": "^3.0.0" + }, + "dependencies": { + "consumable-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/consumable-stream/-/consumable-stream-3.0.0.tgz", + "integrity": "sha512-CnnsJ9OG9ouxAjt3pc63/DaerezRo/WudqU71pc5epaIUi7NHu2T4v+3f0nKbbCY7icS/TfQ1Satr9rwZ7Jwsg==" + } + } + }, + "ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/app/package.json b/app/package.json index 899a8855..e30da26a 100644 --- a/app/package.json +++ b/app/package.json @@ -1,7 +1,8 @@ { "name": "socketcluster-sample", "description": "A sample SocketCluster app", - "version": "1.0.0", + "version": "1.0.1", + "type": "module", "contributors": [ { "name": "Jonathan Gros-Dubois", @@ -9,17 +10,15 @@ } ], "dependencies": { - "scc-broker-client": "^7.0.0", - "socketcluster-client": "^15.0.0", - "socketcluster-server": "^15.0.0", - "connect": "^3.6.6", - "eetase": "^3.0.1", + "eetase": "^7.0.1", "express": "^4.16.3", "morgan": "^1.7.0", - "nodemon": "^1.18.9", - "sc-errors": "^2.0.0", + "nodemon": "^3.1.10", + "scc-broker-client": "^9.2.0", "serve-static": "^1.13.2", - "uuid": "^3.3.2" + "socketcluster-client": "^19.2.7", + "socketcluster-server": "^19.2.0", + "uuid": "^9.0.1" }, "keywords": [ "websocket", diff --git a/app/public/Roboto-Light.ttf b/app/public/Roboto-Light.ttf new file mode 100644 index 00000000..219063a5 Binary files /dev/null and b/app/public/Roboto-Light.ttf differ diff --git a/app/public/favicon.ico b/app/public/favicon.ico index e286d116..949ddfe5 100644 Binary files a/app/public/favicon.ico and b/app/public/favicon.ico differ diff --git a/app/public/img/logo.png b/app/public/img/logo.png index fc8989a3..dde87ca4 100644 Binary files a/app/public/img/logo.png and b/app/public/img/logo.png differ diff --git a/app/public/index.html b/app/public/index.html index 0855bb4e..e7e49a83 100644 --- a/app/public/index.html +++ b/app/public/index.html @@ -2,10 +2,17 @@ SocketCluster - + - + + + +
+
SocketCluster
-
- Design is not just what it looks like and feels like. Design is how it works. — Steve Jobs -

- diff --git a/app/public/index.js b/app/public/index.js new file mode 100644 index 00000000..cfeadc25 --- /dev/null +++ b/app/public/index.js @@ -0,0 +1,16 @@ +import { create } from '/socketcluster-client.min.js'; + +// Initiate the connection to the server +let socket = create(); + +(async () => { + for await (let { error } of socket.listener('error')) { + console.error(error); + } +})(); + +(async () => { + for await (let event of socket.listener('connect')) { + console.log('Socket is connected'); + } +})(); diff --git a/app/public/socketcluster-client.js b/app/public/socketcluster-client.js deleted file mode 100644 index f3724915..00000000 --- a/app/public/socketcluster-client.js +++ /dev/null @@ -1,8074 +0,0 @@ -/** - * SocketCluster JavaScript client v15.0.0 - */ - (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.socketClusterClient = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { - if (this[propertyName] > maxTimeout) { - throw new InvalidArgumentsError( - `The ${propertyName} value provided exceeded the maximum amount allowed` - ); - } - }; - - verifyDuration('connectTimeout'); - verifyDuration('ackTimeout'); - verifyDuration('pingTimeout'); - - this.connectAttempts = 0; - - this.isBatching = false; - this.batchOnHandshake = opts.batchOnHandshake; - this.batchOnHandshakeDuration = opts.batchOnHandshakeDuration; - - this._batchingIntervalId = null; - this._outboundBuffer = new LinkedList(); - this._channelMap = {}; - - this._channelEventDemux = new StreamDemux(); - this._channelDataDemux = new StreamDemux(); - - this._receiverDemux = new StreamDemux(); - this._procedureDemux = new StreamDemux(); - - this.options = opts; - - this._cid = 1; - - this.options.callIdGenerator = () => { - return this._cid++; - }; - - if (this.options.autoReconnect) { - if (this.options.autoReconnectOptions == null) { - this.options.autoReconnectOptions = {}; - } - - // Add properties to the this.options.autoReconnectOptions object. - // We assign the reference to a reconnectOptions variable to avoid repetition. - let reconnectOptions = this.options.autoReconnectOptions; - if (reconnectOptions.initialDelay == null) { - reconnectOptions.initialDelay = 10000; - } - if (reconnectOptions.randomness == null) { - reconnectOptions.randomness = 10000; - } - if (reconnectOptions.multiplier == null) { - reconnectOptions.multiplier = 1.5; - } - if (reconnectOptions.maxDelay == null) { - reconnectOptions.maxDelay = 60000; - } - } - - if (this.options.subscriptionRetryOptions == null) { - this.options.subscriptionRetryOptions = {}; - } - - if (this.options.authEngine) { - this.auth = this.options.authEngine; - } else { - this.auth = new AuthEngine(); - } - - if (this.options.codecEngine) { - this.codec = this.options.codecEngine; - } else { - // Default codec engine - this.codec = formatter; - } - - if (this.options.protocol) { - let protocolOptionError = new InvalidArgumentsError( - 'The "protocol" option does not affect socketcluster-client - ' + - 'If you want to utilize SSL/TLS, use "secure" option instead' - ); - this._onError(protocolOptionError); - } - - this.options.query = opts.query || {}; - if (typeof this.options.query === 'string') { - this.options.query = querystring.parse(this.options.query); - } - - if (isBrowser && this.disconnectOnUnload && global.addEventListener && global.removeEventListener) { - this._handleBrowserUnload(); - } - - if (this.options.autoConnect) { - this.connect(); - } -} - -AGClientSocket.prototype = Object.create(AsyncStreamEmitter.prototype); - -AGClientSocket.CONNECTING = AGClientSocket.prototype.CONNECTING = AGTransport.prototype.CONNECTING; -AGClientSocket.OPEN = AGClientSocket.prototype.OPEN = AGTransport.prototype.OPEN; -AGClientSocket.CLOSED = AGClientSocket.prototype.CLOSED = AGTransport.prototype.CLOSED; - -AGClientSocket.AUTHENTICATED = AGClientSocket.prototype.AUTHENTICATED = 'authenticated'; -AGClientSocket.UNAUTHENTICATED = AGClientSocket.prototype.UNAUTHENTICATED = 'unauthenticated'; - -AGClientSocket.SUBSCRIBED = AGClientSocket.prototype.SUBSCRIBED = AGChannel.SUBSCRIBED; -AGClientSocket.PENDING = AGClientSocket.prototype.PENDING = AGChannel.PENDING; -AGClientSocket.UNSUBSCRIBED = AGClientSocket.prototype.UNSUBSCRIBED = AGChannel.UNSUBSCRIBED; - -AGClientSocket.ignoreStatuses = scErrors.socketProtocolIgnoreStatuses; -AGClientSocket.errorStatuses = scErrors.socketProtocolErrorStatuses; - -Object.defineProperty(AGClientSocket.prototype, 'isBufferingBatch', { - get: function () { - return this.transport.isBufferingBatch; - } -}); - -AGClientSocket.prototype.getBackpressure = function () { - return Math.max( - this.getAllListenersBackpressure(), - this.getAllReceiversBackpressure(), - this.getAllProceduresBackpressure(), - this.getAllChannelsBackpressure() - ); -}; - -AGClientSocket.prototype._handleBrowserUnload = async function () { - let unloadHandler = () => { - this.disconnect(); - }; - let isUnloadHandlerAttached = false; - - let attachUnloadHandler = () => { - if (!isUnloadHandlerAttached) { - isUnloadHandlerAttached = true; - global.addEventListener('beforeunload', unloadHandler, false); - } - }; - - let detachUnloadHandler = () => { - if (isUnloadHandlerAttached) { - isUnloadHandlerAttached = false; - global.removeEventListener('beforeunload', unloadHandler, false); - } - }; - - (async () => { - let consumer = this.listener('connecting').createConsumer(); - while (true) { - let packet = await consumer.next(); - if (packet.done) break; - attachUnloadHandler(); - } - })(); - - (async () => { - let consumer = this.listener('close').createConsumer(); - while (true) { - let packet = await consumer.next(); - if (packet.done) break; - detachUnloadHandler(); - } - })(); -}; - -AGClientSocket.prototype._setAuthToken = function (data) { - this._changeToAuthenticatedState(data.token); - - (async () => { - try { - await this.auth.saveToken(this.authTokenName, data.token, {}); - } catch (err) { - this._onError(err); - } - })(); -}; - -AGClientSocket.prototype._removeAuthToken = function (data) { - (async () => { - let oldAuthToken; - try { - oldAuthToken = await this.auth.removeToken(this.authTokenName); - } catch (err) { - // Non-fatal error - Do not close the connection - this._onError(err); - return; - } - this.emit('removeAuthToken', {oldAuthToken}); - })(); - - this._changeToUnauthenticatedStateAndClearTokens(); -}; - -AGClientSocket.prototype._privateDataHandlerMap = { - '#publish': function (data) { - let undecoratedChannelName = this._undecorateChannelName(data.channel); - let isSubscribed = this.isSubscribed(undecoratedChannelName, true); - - if (isSubscribed) { - this._channelDataDemux.write(undecoratedChannelName, data.data); - } - }, - '#kickOut': function (data) { - let undecoratedChannelName = this._undecorateChannelName(data.channel); - let channel = this._channelMap[undecoratedChannelName]; - if (channel) { - this.emit('kickOut', { - channel: undecoratedChannelName, - message: data.message - }); - this._channelEventDemux.write(`${undecoratedChannelName}/kickOut`, {message: data.message}); - this._triggerChannelUnsubscribe(channel); - } - }, - '#setAuthToken': function (data) { - if (data) { - this._setAuthToken(data); - } - }, - '#removeAuthToken': function (data) { - this._removeAuthToken(data); - } -}; - -AGClientSocket.prototype._privateRPCHandlerMap = { - '#setAuthToken': function (data, request) { - if (data) { - this._setAuthToken(data); - - request.end(); - } else { - request.error(new InvalidMessageError('No token data provided by #setAuthToken event')); - } - }, - '#removeAuthToken': function (data, request) { - this._removeAuthToken(data); - request.end(); - } -}; - -AGClientSocket.prototype.getState = function () { - return this.state; -}; - -AGClientSocket.prototype.getBytesReceived = function () { - return this.transport.getBytesReceived(); -}; - -AGClientSocket.prototype.deauthenticate = async function () { - (async () => { - let oldAuthToken; - try { - oldAuthToken = await this.auth.removeToken(this.authTokenName); - } catch (err) { - this._onError(err); - return; - } - this.emit('removeAuthToken', {oldAuthToken}); - })(); - - if (this.state !== this.CLOSED) { - this.transmit('#removeAuthToken'); - } - this._changeToUnauthenticatedStateAndClearTokens(); - await wait(0); -}; - -AGClientSocket.prototype.connect = function () { - if (this.state === this.CLOSED) { - this.pendingReconnect = false; - this.pendingReconnectTimeout = null; - clearTimeout(this._reconnectTimeoutRef); - - this.state = this.CONNECTING; - this.emit('connecting', {}); - - if (this.transport) { - this.transport.clearAllListeners(); - } - - let transportHandlers = { - onOpen: (value) => { - this.state = this.OPEN; - this._onOpen(value); - }, - onOpenAbort: (value) => { - if (this.state !== this.CLOSED) { - this.state = this.CLOSED; - this._destroy(value.code, value.reason, true); - } - }, - onClose: (value) => { - if (this.state !== this.CLOSED) { - this.state = this.CLOSED; - this._destroy(value.code, value.reason); - } - }, - onEvent: (value) => { - this.emit(value.event, value.data); - }, - onError: (value) => { - this._onError(value.error); - }, - onInboundInvoke: (value) => { - this._onInboundInvoke(value); - }, - onInboundTransmit: (value) => { - this._onInboundTransmit(value.event, value.data); - } - }; - - this.transport = new AGTransport(this.auth, this.codec, this.options, this.wsOptions, transportHandlers); - } -}; - -AGClientSocket.prototype.reconnect = function (code, reason) { - this.disconnect(code, reason); - this.connect(); -}; - -AGClientSocket.prototype.disconnect = function (code, reason) { - code = code || 1000; - - if (typeof code !== 'number') { - throw new InvalidArgumentsError('If specified, the code argument must be a number'); - } - - let isConnecting = this.state === this.CONNECTING; - if (isConnecting || this.state === this.OPEN) { - this.state = this.CLOSED; - this._destroy(code, reason, isConnecting); - this.transport.close(code, reason); - } else { - this.pendingReconnect = false; - this.pendingReconnectTimeout = null; - clearTimeout(this._reconnectTimeoutRef); - } -}; - -AGClientSocket.prototype._changeToUnauthenticatedStateAndClearTokens = function () { - if (this.authState !== this.UNAUTHENTICATED) { - let oldAuthState = this.authState; - let oldAuthToken = this.authToken; - let oldSignedAuthToken = this.signedAuthToken; - this.authState = this.UNAUTHENTICATED; - this.signedAuthToken = null; - this.authToken = null; - - let stateChangeData = { - oldAuthState, - newAuthState: this.authState - }; - this.emit('authStateChange', stateChangeData); - this.emit('deauthenticate', {oldSignedAuthToken, oldAuthToken}); - } -}; - -AGClientSocket.prototype._changeToAuthenticatedState = function (signedAuthToken) { - this.signedAuthToken = signedAuthToken; - this.authToken = this._extractAuthTokenData(signedAuthToken); - - if (this.authState !== this.AUTHENTICATED) { - let oldAuthState = this.authState; - this.authState = this.AUTHENTICATED; - let stateChangeData = { - oldAuthState, - newAuthState: this.authState, - signedAuthToken: signedAuthToken, - authToken: this.authToken - }; - if (!this.preparingPendingSubscriptions) { - this.processPendingSubscriptions(); - } - - this.emit('authStateChange', stateChangeData); - } - this.emit('authenticate', {signedAuthToken, authToken: this.authToken}); -}; - -AGClientSocket.prototype.decodeBase64 = function (encodedString) { - return Buffer.from(encodedString, 'base64').toString('utf8'); -}; - -AGClientSocket.prototype.encodeBase64 = function (decodedString) { - return Buffer.from(decodedString, 'utf8').toString('base64'); -}; - -AGClientSocket.prototype._extractAuthTokenData = function (signedAuthToken) { - let tokenParts = (signedAuthToken || '').split('.'); - let encodedTokenData = tokenParts[1]; - if (encodedTokenData != null) { - let tokenData = encodedTokenData; - try { - tokenData = this.decodeBase64(tokenData); - return JSON.parse(tokenData); - } catch (e) { - return tokenData; - } - } - return null; -}; - -AGClientSocket.prototype.getAuthToken = function () { - return this.authToken; -}; - -AGClientSocket.prototype.getSignedAuthToken = function () { - return this.signedAuthToken; -}; - -// Perform client-initiated authentication by providing an encrypted token string. -AGClientSocket.prototype.authenticate = async function (signedAuthToken) { - let authStatus; - - try { - authStatus = await this.invoke('#authenticate', signedAuthToken); - } catch (err) { - if (err.name !== 'BadConnectionError' && err.name !== 'TimeoutError') { - // In case of a bad/closed connection or a timeout, we maintain the last - // known auth state since those errors don't mean that the token is invalid. - this._changeToUnauthenticatedStateAndClearTokens(); - } - await wait(0); - throw err; - } - - if (authStatus && authStatus.isAuthenticated != null) { - // If authStatus is correctly formatted (has an isAuthenticated property), - // then we will rehydrate the authError. - if (authStatus.authError) { - authStatus.authError = scErrors.hydrateError(authStatus.authError); - } - } else { - // Some errors like BadConnectionError and TimeoutError will not pass a valid - // authStatus object to the current function, so we need to create it ourselves. - authStatus = { - isAuthenticated: this.authState, - authError: null - }; - } - - if (authStatus.isAuthenticated) { - this._changeToAuthenticatedState(signedAuthToken); - } else { - this._changeToUnauthenticatedStateAndClearTokens(); - } - - (async () => { - try { - await this.auth.saveToken(this.authTokenName, signedAuthToken, {}); - } catch (err) { - this._onError(err); - } - })(); - - await wait(0); - return authStatus; -}; - -AGClientSocket.prototype._tryReconnect = function (initialDelay) { - let exponent = this.connectAttempts++; - let reconnectOptions = this.options.autoReconnectOptions; - let timeout; - - if (initialDelay == null || exponent > 0) { - let initialTimeout = Math.round(reconnectOptions.initialDelay + (reconnectOptions.randomness || 0) * Math.random()); - - timeout = Math.round(initialTimeout * Math.pow(reconnectOptions.multiplier, exponent)); - } else { - timeout = initialDelay; - } - - if (timeout > reconnectOptions.maxDelay) { - timeout = reconnectOptions.maxDelay; - } - - clearTimeout(this._reconnectTimeoutRef); - - this.pendingReconnect = true; - this.pendingReconnectTimeout = timeout; - this._reconnectTimeoutRef = setTimeout(() => { - this.connect(); - }, timeout); -}; - -AGClientSocket.prototype._onOpen = function (status) { - if (this.isBatching) { - this._startBatching(); - } else if (this.batchOnHandshake) { - this._startBatching(); - setTimeout(() => { - if (!this.isBatching) { - this._stopBatching(); - } - }, this.batchOnHandshakeDuration); - } - this.preparingPendingSubscriptions = true; - - if (status) { - this.id = status.id; - this.pingTimeout = status.pingTimeout; - if (status.isAuthenticated) { - this._changeToAuthenticatedState(status.authToken); - } else { - this._changeToUnauthenticatedStateAndClearTokens(); - } - } else { - // This can happen if auth.loadToken (in transport.js) fails with - // an error - This means that the signedAuthToken cannot be loaded by - // the auth engine and therefore, we need to unauthenticate the client. - this._changeToUnauthenticatedStateAndClearTokens(); - } - - this.connectAttempts = 0; - - if (this.options.autoSubscribeOnConnect) { - this.processPendingSubscriptions(); - } - - // If the user invokes the callback while in autoSubscribeOnConnect mode, it - // won't break anything. - this.emit('connect', { - ...status, - processPendingSubscriptions: () => { - this.processPendingSubscriptions(); - } - }); - - if (this.state === this.OPEN) { - this._flushOutboundBuffer(); - } -}; - -AGClientSocket.prototype._onError = function (error) { - this.emit('error', {error}); -}; - -AGClientSocket.prototype._suspendSubscriptions = function () { - Object.keys(this._channelMap).forEach((channelName) => { - let channel = this._channelMap[channelName]; - this._triggerChannelUnsubscribe(channel, true); - }); -}; - -AGClientSocket.prototype._abortAllPendingEventsDueToBadConnection = function (failureType) { - let currentNode = this._outboundBuffer.head; - let nextNode; - - while (currentNode) { - nextNode = currentNode.next; - let eventObject = currentNode.data; - clearTimeout(eventObject.timeout); - delete eventObject.timeout; - currentNode.detach(); - currentNode = nextNode; - - let callback = eventObject.callback; - - if (callback) { - delete eventObject.callback; - let errorMessage = `Event "${eventObject.event}" was aborted due to a bad connection`; - let error = new BadConnectionError(errorMessage, failureType); - - callback.call(eventObject, error, eventObject); - } - // Cleanup any pending response callback in the transport layer too. - if (eventObject.cid) { - this.transport.cancelPendingResponse(eventObject.cid); - } - } -}; - -AGClientSocket.prototype._destroy = function (code, reason, openAbort) { - this.id = null; - this._cancelBatching(); - - if (this.transport) { - this.transport.clearAllListeners(); - } - - this.pendingReconnect = false; - this.pendingReconnectTimeout = null; - clearTimeout(this._reconnectTimeoutRef); - - this._suspendSubscriptions(); - - if (openAbort) { - this.emit('connectAbort', {code, reason}); - } else { - this.emit('disconnect', {code, reason}); - } - this.emit('close', {code, reason}); - - if (!AGClientSocket.ignoreStatuses[code]) { - let closeMessage; - if (reason) { - closeMessage = 'Socket connection closed with status code ' + code + ' and reason: ' + reason; - } else { - closeMessage = 'Socket connection closed with status code ' + code; - } - let err = new SocketProtocolError(AGClientSocket.errorStatuses[code] || closeMessage, code); - this._onError(err); - } - - this._abortAllPendingEventsDueToBadConnection(openAbort ? 'connectAbort' : 'disconnect'); - - // Try to reconnect - // on server ping timeout (4000) - // or on client pong timeout (4001) - // or on close without status (1005) - // or on handshake failure (4003) - // or on handshake rejection (4008) - // or on socket hung up (1006) - if (this.options.autoReconnect) { - if (code === 4000 || code === 4001 || code === 1005) { - // If there is a ping or pong timeout or socket closes without - // status, don't wait before trying to reconnect - These could happen - // if the client wakes up after a period of inactivity and in this case we - // want to re-establish the connection as soon as possible. - this._tryReconnect(0); - - // Codes 4500 and above will be treated as permanent disconnects. - // Socket will not try to auto-reconnect. - } else if (code !== 1000 && code < 4500) { - this._tryReconnect(); - } - } -}; - -AGClientSocket.prototype._onInboundTransmit = function (event, data) { - let handler = this._privateDataHandlerMap[event]; - if (handler) { - handler.call(this, data); - } else { - this._receiverDemux.write(event, data); - } -}; - -AGClientSocket.prototype._onInboundInvoke = function (request) { - let {procedure, data} = request; - let handler = this._privateRPCHandlerMap[procedure]; - if (handler) { - handler.call(this, data, request); - } else { - this._procedureDemux.write(procedure, request); - } -}; - -AGClientSocket.prototype.decode = function (message) { - return this.transport.decode(message); -}; - -AGClientSocket.prototype.encode = function (object) { - return this.transport.encode(object); -}; - -AGClientSocket.prototype._flushOutboundBuffer = function () { - let currentNode = this._outboundBuffer.head; - let nextNode; - - while (currentNode) { - nextNode = currentNode.next; - let eventObject = currentNode.data; - currentNode.detach(); - this.transport.transmitObject(eventObject); - currentNode = nextNode; - } -}; - -AGClientSocket.prototype._handleEventAckTimeout = function (eventObject, eventNode) { - if (eventNode) { - eventNode.detach(); - } - delete eventObject.timeout; - - let callback = eventObject.callback; - if (callback) { - delete eventObject.callback; - let error = new TimeoutError(`Event response for "${eventObject.event}" timed out`); - callback.call(eventObject, error, eventObject); - } - // Cleanup any pending response callback in the transport layer too. - if (eventObject.cid) { - this.transport.cancelPendingResponse(eventObject.cid); - } -}; - -AGClientSocket.prototype._processOutboundEvent = function (event, data, options, expectResponse) { - options = options || {}; - - if (this.state === this.CLOSED) { - this.connect(); - } - let eventObject = { - event - }; - - let promise; - - if (expectResponse) { - promise = new Promise((resolve, reject) => { - eventObject.callback = (err, data) => { - if (err) { - reject(err); - return; - } - resolve(data); - }; - }); - } else { - promise = Promise.resolve(); - } - - let eventNode = new LinkedList.Item(); - - if (this.options.cloneData) { - eventObject.data = cloneDeep(data); - } else { - eventObject.data = data; - } - eventNode.data = eventObject; - - let ackTimeout = options.ackTimeout == null ? this.ackTimeout : options.ackTimeout; - - eventObject.timeout = setTimeout(() => { - this._handleEventAckTimeout(eventObject, eventNode); - }, ackTimeout); - - this._outboundBuffer.append(eventNode); - if (this.state === this.OPEN) { - this._flushOutboundBuffer(); - } - return promise; -}; - -AGClientSocket.prototype.send = function (data) { - this.transport.send(data); -}; - -AGClientSocket.prototype.transmit = function (event, data, options) { - return this._processOutboundEvent(event, data, options); -}; - -AGClientSocket.prototype.invoke = function (event, data, options) { - return this._processOutboundEvent(event, data, options, true); -}; - -AGClientSocket.prototype.transmitPublish = function (channelName, data) { - let pubData = { - channel: this._decorateChannelName(channelName), - data - }; - return this.transmit('#publish', pubData); -}; - -AGClientSocket.prototype.invokePublish = function (channelName, data) { - let pubData = { - channel: this._decorateChannelName(channelName), - data - }; - return this.invoke('#publish', pubData); -}; - -AGClientSocket.prototype._triggerChannelSubscribe = function (channel, subscriptionOptions) { - let channelName = channel.name; - - if (channel.state !== AGChannel.SUBSCRIBED) { - let oldChannelState = channel.state; - channel.state = AGChannel.SUBSCRIBED; - - let stateChangeData = { - oldChannelState, - newChannelState: channel.state, - subscriptionOptions - }; - this._channelEventDemux.write(`${channelName}/subscribeStateChange`, stateChangeData); - this._channelEventDemux.write(`${channelName}/subscribe`, { - subscriptionOptions - }); - this.emit('subscribeStateChange', { - channel: channelName, - ...stateChangeData - }); - this.emit('subscribe', { - channel: channelName, - subscriptionOptions - }); - } -}; - -AGClientSocket.prototype._triggerChannelSubscribeFail = function (err, channel, subscriptionOptions) { - let channelName = channel.name; - let meetsAuthRequirements = !channel.options.waitForAuth || this.authState === this.AUTHENTICATED; - let hasChannel = !!this._channelMap[channelName]; - - if (hasChannel && meetsAuthRequirements) { - delete this._channelMap[channelName]; - - this._channelEventDemux.write(`${channelName}/subscribeFail`, { - error: err, - subscriptionOptions - }); - this.emit('subscribeFail', { - error: err, - channel: channelName, - subscriptionOptions: subscriptionOptions - }); - } -}; - -// Cancel any pending subscribe callback -AGClientSocket.prototype._cancelPendingSubscribeCallback = function (channel) { - if (channel._pendingSubscriptionCid != null) { - this.transport.cancelPendingResponse(channel._pendingSubscriptionCid); - delete channel._pendingSubscriptionCid; - } -}; - -AGClientSocket.prototype._decorateChannelName = function (channelName) { - if (this.channelPrefix) { - channelName = this.channelPrefix + channelName; - } - return channelName; -}; - -AGClientSocket.prototype._undecorateChannelName = function (decoratedChannelName) { - if (this.channelPrefix && decoratedChannelName.indexOf(this.channelPrefix) === 0) { - return decoratedChannelName.replace(this.channelPrefix, ''); - } - return decoratedChannelName; -}; - -AGClientSocket.prototype.startBatch = function () { - this.transport.startBatch(); -}; - -AGClientSocket.prototype.flushBatch = function () { - this.transport.flushBatch(); -}; - -AGClientSocket.prototype.cancelBatch = function () { - this.transport.cancelBatch(); -}; - -AGClientSocket.prototype._startBatching = function () { - if (this._batchingIntervalId != null) { - return; - } - this.startBatch(); - this._batchingIntervalId = setInterval(() => { - this.flushBatch(); - this.startBatch(); - }, this.options.batchInterval); -}; - -AGClientSocket.prototype.startBatching = function () { - this.isBatching = true; - this._startBatching(); -}; - -AGClientSocket.prototype._stopBatching = function () { - if (this._batchingIntervalId != null) { - clearInterval(this._batchingIntervalId); - } - this._batchingIntervalId = null; - this.flushBatch(); -}; - -AGClientSocket.prototype.stopBatching = function () { - this.isBatching = false; - this._stopBatching(); -}; - -AGClientSocket.prototype._cancelBatching = function () { - if (this._batchingIntervalId != null) { - clearInterval(this._batchingIntervalId); - } - this._batchingIntervalId = null; - this.cancelBatch(); -}; - -AGClientSocket.prototype.cancelBatching = function () { - this.isBatching = false; - this._cancelBatching(); -}; - -AGClientSocket.prototype._trySubscribe = function (channel) { - let meetsAuthRequirements = !channel.options.waitForAuth || this.authState === this.AUTHENTICATED; - - // We can only ever have one pending subscribe action at any given time on a channel - if ( - this.state === this.OPEN && - !this.preparingPendingSubscriptions && - channel._pendingSubscriptionCid == null && - meetsAuthRequirements - ) { - - let options = { - noTimeout: true - }; - - let subscriptionOptions = {}; - if (channel.options.waitForAuth) { - options.waitForAuth = true; - subscriptionOptions.waitForAuth = options.waitForAuth; - } - if (channel.options.data) { - subscriptionOptions.data = channel.options.data; - } - - channel._pendingSubscriptionCid = this.transport.invokeRaw( - '#subscribe', - { - channel: this._decorateChannelName(channel.name), - ...subscriptionOptions - }, - options, - (err) => { - if (err) { - if (err.name === 'BadConnectionError') { - // In case of a failed connection, keep the subscription - // as pending; it will try again on reconnect. - return; - } - delete channel._pendingSubscriptionCid; - this._triggerChannelSubscribeFail(err, channel, subscriptionOptions); - } else { - delete channel._pendingSubscriptionCid; - this._triggerChannelSubscribe(channel, subscriptionOptions); - } - } - ); - this.emit('subscribeRequest', { - channel: channel.name, - subscriptionOptions - }); - } -}; - -AGClientSocket.prototype.subscribe = function (channelName, options) { - options = options || {}; - let channel = this._channelMap[channelName]; - - let sanitizedOptions = { - waitForAuth: !!options.waitForAuth - }; - - if (options.priority != null) { - sanitizedOptions.priority = options.priority; - } - if (options.data !== undefined) { - sanitizedOptions.data = options.data; - } - - if (!channel) { - channel = { - name: channelName, - state: AGChannel.PENDING, - options: sanitizedOptions - }; - this._channelMap[channelName] = channel; - this._trySubscribe(channel); - } else if (options) { - channel.options = sanitizedOptions; - } - - let channelIterable = new AGChannel( - channelName, - this, - this._channelEventDemux, - this._channelDataDemux - ); - - return channelIterable; -}; - -AGClientSocket.prototype._triggerChannelUnsubscribe = function (channel, setAsPending) { - let channelName = channel.name; - - this._cancelPendingSubscribeCallback(channel); - - if (channel.state === AGChannel.SUBSCRIBED) { - let stateChangeData = { - oldChannelState: channel.state, - newChannelState: setAsPending ? AGChannel.PENDING : AGChannel.UNSUBSCRIBED - }; - this._channelEventDemux.write(`${channelName}/subscribeStateChange`, stateChangeData); - this._channelEventDemux.write(`${channelName}/unsubscribe`, {}); - this.emit('subscribeStateChange', { - channel: channelName, - ...stateChangeData - }); - this.emit('unsubscribe', {channel: channelName}); - } - - if (setAsPending) { - channel.state = AGChannel.PENDING; - } else { - delete this._channelMap[channelName]; - } -}; - -AGClientSocket.prototype._tryUnsubscribe = function (channel) { - if (this.state === this.OPEN) { - let options = { - noTimeout: true - }; - // If there is a pending subscribe action, cancel the callback - this._cancelPendingSubscribeCallback(channel); - - // This operation cannot fail because the TCP protocol guarantees delivery - // so long as the connection remains open. If the connection closes, - // the server will automatically unsubscribe the client and thus complete - // the operation on the server side. - let decoratedChannelName = this._decorateChannelName(channel.name); - this.transport.transmit('#unsubscribe', decoratedChannelName, options); - } -}; - -AGClientSocket.prototype.unsubscribe = function (channelName) { - let channel = this._channelMap[channelName]; - - if (channel) { - this._triggerChannelUnsubscribe(channel); - this._tryUnsubscribe(channel); - } -}; - -// ---- Receiver logic ---- - -AGClientSocket.prototype.receiver = function (receiverName) { - return this._receiverDemux.stream(receiverName); -}; - -AGClientSocket.prototype.closeReceiver = function (receiverName) { - this._receiverDemux.close(receiverName); -}; - -AGClientSocket.prototype.closeAllReceivers = function () { - this._receiverDemux.closeAll(); -}; - -AGClientSocket.prototype.killReceiver = function (receiverName) { - this._receiverDemux.kill(receiverName); -}; - -AGClientSocket.prototype.killAllReceivers = function () { - this._receiverDemux.killAll(); -}; - -AGClientSocket.prototype.killReceiverConsumer = function (consumerId) { - this._receiverDemux.killConsumer(consumerId); -}; - -AGClientSocket.prototype.getReceiverConsumerStats = function (consumerId) { - return this._receiverDemux.getConsumerStats(consumerId); -}; - -AGClientSocket.prototype.getReceiverConsumerStatsList = function (receiverName) { - return this._receiverDemux.getConsumerStatsList(receiverName); -}; - -AGClientSocket.prototype.getAllReceiversConsumerStatsList = function () { - return this._receiverDemux.getConsumerStatsListAll(); -}; - -AGClientSocket.prototype.getReceiverBackpressure = function (receiverName) { - return this._receiverDemux.getBackpressure(receiverName); -}; - -AGClientSocket.prototype.getAllReceiversBackpressure = function () { - return this._receiverDemux.getBackpressureAll(); -}; - -AGClientSocket.prototype.getReceiverConsumerBackpressure = function (consumerId) { - return this._receiverDemux.getConsumerBackpressure(consumerId); -}; - -AGClientSocket.prototype.hasReceiverConsumer = function (receiverName, consumerId) { - return this._receiverDemux.hasConsumer(receiverName, consumerId); -}; - -AGClientSocket.prototype.hasAnyReceiverConsumer = function (consumerId) { - return this._receiverDemux.hasConsumerAll(consumerId); -}; - -// ---- Procedure logic ---- - -AGClientSocket.prototype.procedure = function (procedureName) { - return this._procedureDemux.stream(procedureName); -}; - -AGClientSocket.prototype.closeProcedure = function (procedureName) { - this._procedureDemux.close(procedureName); -}; - -AGClientSocket.prototype.closeAllProcedures = function () { - this._procedureDemux.closeAll(); -}; - -AGClientSocket.prototype.killProcedure = function (procedureName) { - this._procedureDemux.kill(procedureName); -}; - -AGClientSocket.prototype.killAllProcedures = function () { - this._procedureDemux.killAll(); -}; - -AGClientSocket.prototype.killProcedureConsumer = function (consumerId) { - this._procedureDemux.killConsumer(consumerId); -}; - -AGClientSocket.prototype.getProcedureConsumerStats = function (consumerId) { - return this._procedureDemux.getConsumerStats(consumerId); -}; - -AGClientSocket.prototype.getProcedureConsumerStatsList = function (procedureName) { - return this._procedureDemux.getConsumerStatsList(procedureName); -}; - -AGClientSocket.prototype.getAllProceduresConsumerStatsList = function () { - return this._procedureDemux.getConsumerStatsListAll(); -}; - -AGClientSocket.prototype.getProcedureBackpressure = function (procedureName) { - return this._procedureDemux.getBackpressure(procedureName); -}; - -AGClientSocket.prototype.getAllProceduresBackpressure = function () { - return this._procedureDemux.getBackpressureAll(); -}; - -AGClientSocket.prototype.getProcedureConsumerBackpressure = function (consumerId) { - return this._procedureDemux.getConsumerBackpressure(consumerId); -}; - -AGClientSocket.prototype.hasProcedureConsumer = function (procedureName, consumerId) { - return this._procedureDemux.hasConsumer(procedureName, consumerId); -}; - -AGClientSocket.prototype.hasAnyProcedureConsumer = function (consumerId) { - return this._procedureDemux.hasConsumerAll(consumerId); -}; - -// ---- Channel logic ---- - -AGClientSocket.prototype.channel = function (channelName) { - let currentChannel = this._channelMap[channelName]; - - let channelIterable = new AGChannel( - channelName, - this, - this._channelEventDemux, - this._channelDataDemux - ); - - return channelIterable; -}; - -AGClientSocket.prototype.closeChannel = function (channelName) { - this.channelCloseOutput(channelName); - this.channelCloseAllListeners(channelName); -}; - -AGClientSocket.prototype.closeAllChannelOutputs = function () { - this._channelDataDemux.closeAll(); -}; - -AGClientSocket.prototype.closeAllChannelListeners = function () { - this._channelEventDemux.closeAll(); -}; - -AGClientSocket.prototype.closeAllChannels = function () { - this.closeAllChannelOutputs(); - this.closeAllChannelListeners(); -}; - -AGClientSocket.prototype.killChannel = function (channelName) { - this.channelKillOutput(channelName); - this.channelKillAllListeners(channelName); -}; - -AGClientSocket.prototype.killAllChannelOutputs = function () { - this._channelDataDemux.killAll(); -}; - -AGClientSocket.prototype.killAllChannelListeners = function () { - this._channelEventDemux.killAll(); -}; - -AGClientSocket.prototype.killAllChannels = function () { - this.killAllChannelOutputs(); - this.killAllChannelListeners(); -}; - -AGClientSocket.prototype.killChannelOutputConsumer = function (consumerId) { - this._channelDataDemux.killConsumer(consumerId); -}; - -AGClientSocket.prototype.killChannelListenerConsumer = function (consumerId) { - this._channelEventDemux.killConsumer(consumerId); -}; - -AGClientSocket.prototype.getChannelOutputConsumerStats = function (consumerId) { - return this._channelDataDemux.getConsumerStats(consumerId); -}; - -AGClientSocket.prototype.getChannelListenerConsumerStats = function (consumerId) { - return this._channelEventDemux.getConsumerStats(consumerId); -}; - -AGClientSocket.prototype.getAllChannelOutputsConsumerStatsList = function () { - return this._channelDataDemux.getConsumerStatsListAll(); -}; - -AGClientSocket.prototype.getAllChannelListenersConsumerStatsList = function () { - return this._channelEventDemux.getConsumerStatsListAll(); -}; - -AGClientSocket.prototype.getChannelBackpressure = function (channelName) { - return Math.max( - this.channelGetOutputBackpressure(channelName), - this.channelGetAllListenersBackpressure(channelName) - ); -}; - -AGClientSocket.prototype.getAllChannelOutputsBackpressure = function () { - return this._channelDataDemux.getBackpressureAll(); -}; - -AGClientSocket.prototype.getAllChannelListenersBackpressure = function () { - return this._channelEventDemux.getBackpressureAll(); -}; - -AGClientSocket.prototype.getAllChannelsBackpressure = function () { - return Math.max( - this.getAllChannelOutputsBackpressure(), - this.getAllChannelListenersBackpressure() - ); -}; - -AGClientSocket.prototype.getChannelListenerConsumerBackpressure = function (consumerId) { - return this._channelEventDemux.getConsumerBackpressure(consumerId); -}; - -AGClientSocket.prototype.getChannelOutputConsumerBackpressure = function (consumerId) { - return this._channelDataDemux.getConsumerBackpressure(consumerId); -}; - -AGClientSocket.prototype.hasAnyChannelOutputConsumer = function (consumerId) { - return this._channelDataDemux.hasConsumerAll(consumerId); -}; - -AGClientSocket.prototype.hasAnyChannelListenerConsumer = function (consumerId) { - return this._channelEventDemux.hasConsumerAll(consumerId); -}; - -AGClientSocket.prototype.getChannelState = function (channelName) { - let channel = this._channelMap[channelName]; - if (channel) { - return channel.state; - } - return AGChannel.UNSUBSCRIBED; -}; - -AGClientSocket.prototype.getChannelOptions = function (channelName) { - let channel = this._channelMap[channelName]; - if (channel) { - return {...channel.options}; - } - return {}; -}; - -AGClientSocket.prototype._getAllChannelStreamNames = function (channelName) { - let streamNamesLookup = this._channelEventDemux.getConsumerStatsListAll() - .filter((stats) => { - return stats.stream.indexOf(`${channelName}/`) === 0; - }) - .reduce((accumulator, stats) => { - accumulator[stats.stream] = true; - return accumulator; - }, {}); - return Object.keys(streamNamesLookup); -}; - -AGClientSocket.prototype.channelCloseOutput = function (channelName) { - this._channelDataDemux.close(channelName); -}; - -AGClientSocket.prototype.channelCloseListener = function (channelName, eventName) { - this._channelEventDemux.close(`${channelName}/${eventName}`); -}; - -AGClientSocket.prototype.channelCloseAllListeners = function (channelName) { - let listenerStreams = this._getAllChannelStreamNames(channelName) - .forEach((streamName) => { - this._channelEventDemux.close(streamName); - }); -}; - -AGClientSocket.prototype.channelKillOutput = function (channelName) { - this._channelDataDemux.kill(channelName); -}; - -AGClientSocket.prototype.channelKillListener = function (channelName, eventName) { - this._channelEventDemux.kill(`${channelName}/${eventName}`); -}; - -AGClientSocket.prototype.channelKillAllListeners = function (channelName) { - let listenerStreams = this._getAllChannelStreamNames(channelName) - .forEach((streamName) => { - this._channelEventDemux.kill(streamName); - }); -}; - -AGClientSocket.prototype.channelGetOutputConsumerStatsList = function (channelName) { - return this._channelDataDemux.getConsumerStatsList(channelName); -}; - -AGClientSocket.prototype.channelGetListenerConsumerStatsList = function (channelName, eventName) { - return this._channelEventDemux.getConsumerStatsList(`${channelName}/${eventName}`); -}; - -AGClientSocket.prototype.channelGetAllListenersConsumerStatsList = function (channelName) { - return this._getAllChannelStreamNames(channelName) - .map((streamName) => { - return this._channelEventDemux.getConsumerStatsList(streamName); - }) - .reduce((accumulator, statsList) => { - statsList.forEach((stats) => { - accumulator.push(stats); - }); - return accumulator; - }, []); -}; - -AGClientSocket.prototype.channelGetOutputBackpressure = function (channelName) { - return this._channelDataDemux.getBackpressure(channelName); -}; - -AGClientSocket.prototype.channelGetListenerBackpressure = function (channelName, eventName) { - return this._channelEventDemux.getBackpressure(`${channelName}/${eventName}`); -}; - -AGClientSocket.prototype.channelGetAllListenersBackpressure = function (channelName) { - let listenerStreamBackpressures = this._getAllChannelStreamNames(channelName) - .map((streamName) => { - return this._channelEventDemux.getBackpressure(streamName); - }); - return Math.max(...listenerStreamBackpressures.concat(0)); -}; - -AGClientSocket.prototype.channelHasOutputConsumer = function (channelName, consumerId) { - return this._channelDataDemux.hasConsumer(channelName, consumerId); -}; - -AGClientSocket.prototype.channelHasListenerConsumer = function (channelName, eventName, consumerId) { - return this._channelEventDemux.hasConsumer(`${channelName}/${eventName}`, consumerId); -}; - -AGClientSocket.prototype.channelHasAnyListenerConsumer = function (channelName, consumerId) { - return this._getAllChannelStreamNames(channelName) - .some((streamName) => { - return this._channelEventDemux.hasConsumer(streamName, consumerId); - }); -}; - -AGClientSocket.prototype.subscriptions = function (includePending) { - let subs = []; - Object.keys(this._channelMap).forEach((channelName) => { - if (includePending || this._channelMap[channelName].state === AGChannel.SUBSCRIBED) { - subs.push(channelName); - } - }); - return subs; -}; - -AGClientSocket.prototype.isSubscribed = function (channelName, includePending) { - let channel = this._channelMap[channelName]; - if (includePending) { - return !!channel; - } - return !!channel && channel.state === AGChannel.SUBSCRIBED; -}; - -AGClientSocket.prototype.processPendingSubscriptions = function () { - this.preparingPendingSubscriptions = false; - let pendingChannels = []; - - Object.keys(this._channelMap).forEach((channelName) => { - let channel = this._channelMap[channelName]; - if (channel.state === AGChannel.PENDING) { - pendingChannels.push(channel); - } - }); - - pendingChannels.sort((a, b) => { - let ap = a.options.priority || 0; - let bp = b.options.priority || 0; - if (ap > bp) { - return -1; - } - if (ap < bp) { - return 1; - } - return 0; - }); - - pendingChannels.forEach((channel) => { - this._trySubscribe(channel); - }); -}; - -module.exports = AGClientSocket; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./auth":1,"./transport":4,"./wait":5,"ag-channel":7,"async-stream-emitter":9,"buffer/":11,"linked-list":15,"lodash.clonedeep":16,"querystring":19,"sc-errors":21,"sc-formatter":22,"stream-demux":24}],3:[function(require,module,exports){ -(function (global){ -const AGClientSocket = require('./clientsocket'); -const uuid = require('uuid'); -const scErrors = require('sc-errors'); -const InvalidArgumentsError = scErrors.InvalidArgumentsError; - -function isUrlSecure() { - return global.location && location.protocol === 'https:'; -} - -function getPort(options, isSecureDefault) { - let isSecure = options.secure == null ? isSecureDefault : options.secure; - return options.port || (global.location && location.port ? location.port : isSecure ? 443 : 80); -} - -function create(options) { - options = options || {}; - - if (options.host && !options.host.match(/[^:]+:\d{2,5}/)) { - throw new InvalidArgumentsError( - 'The host option should include both' + - ' the hostname and the port number in the format "hostname:port"' - ); - } - - if (options.host && options.hostname) { - throw new InvalidArgumentsError( - 'The host option should already include' + - ' the hostname and the port number in the format "hostname:port"' + - ' - Because of this, you should never use host and hostname options together' - ); - } - - if (options.host && options.port) { - throw new InvalidArgumentsError( - 'The host option should already include' + - ' the hostname and the port number in the format "hostname:port"' + - ' - Because of this, you should never use host and port options together' - ); - } - - let isSecureDefault = isUrlSecure(); - - let opts = { - clientId: uuid.v4(), - port: getPort(options, isSecureDefault), - hostname: global.location && location.hostname || 'localhost', - secure: isSecureDefault - }; - - Object.assign(opts, options); - - return new AGClientSocket(opts); -} - -module.exports = { - create -}; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./clientsocket":2,"sc-errors":21,"uuid":25}],4:[function(require,module,exports){ -(function (global){ -const AGRequest = require('ag-request'); -const querystring = require('querystring'); - -let WebSocket; -let createWebSocket; - -if (global.WebSocket) { - WebSocket = global.WebSocket; - createWebSocket = function (uri, options) { - return new WebSocket(uri); - }; -} else { - WebSocket = require('ws'); - createWebSocket = function (uri, options) { - return new WebSocket(uri, null, options); - }; -} - -const scErrors = require('sc-errors'); -const TimeoutError = scErrors.TimeoutError; -const BadConnectionError = scErrors.BadConnectionError; - -function AGTransport(authEngine, codecEngine, options, wsOptions, handlers) { - this.state = this.CLOSED; - this.auth = authEngine; - this.codec = codecEngine; - this.options = options; - this.wsOptions = wsOptions; - this.protocolVersion = options.protocolVersion; - this.connectTimeout = options.connectTimeout; - this.pingTimeout = options.pingTimeout; - this.pingTimeoutDisabled = !!options.pingTimeoutDisabled; - this.callIdGenerator = options.callIdGenerator; - this.authTokenName = options.authTokenName; - this.isBufferingBatch = false; - - this._pingTimeoutTicker = null; - this._callbackMap = {}; - this._batchBuffer = []; - - if (!handlers) { - handlers = {}; - } - - this._onOpenHandler = handlers.onOpen || function () {}; - this._onOpenAbortHandler = handlers.onOpenAbort || function () {}; - this._onCloseHandler = handlers.onClose || function () {}; - this._onEventHandler = handlers.onEvent || function () {}; - this._onErrorHandler = handlers.onError || function () {}; - this._onInboundInvokeHandler = handlers.onInboundInvoke || function () {}; - this._onInboundTransmitHandler = handlers.onInboundTransmit || function () {}; - - // Open the connection. - - this.state = this.CONNECTING; - let uri = this.uri(); - - let wsSocket = createWebSocket(uri, wsOptions); - wsSocket.binaryType = this.options.binaryType; - - this.socket = wsSocket; - - wsSocket.onopen = () => { - this._onOpen(); - }; - - wsSocket.onclose = async (event) => { - let code; - if (event.code == null) { - // This is to handle an edge case in React Native whereby - // event.code is undefined when the mobile device is locked. - // TODO: This is not ideal since this condition could also apply to - // an abnormal close (no close control frame) which would be a 1006. - code = 1005; - } else { - code = event.code; - } - this._destroy(code, event.reason); - }; - - wsSocket.onmessage = (message, flags) => { - this._onMessage(message.data); - }; - - wsSocket.onerror = (error) => { - // The onclose event will be called automatically after the onerror event - // if the socket is connected - Otherwise, if it's in the middle of - // connecting, we want to close it manually with a 1006 - This is necessary - // to prevent inconsistent behavior when running the client in Node.js - // vs in a browser. - if (this.state === this.CONNECTING) { - this._destroy(1006); - } - }; - - this._connectTimeoutRef = setTimeout(() => { - this._destroy(4007); - this.socket.close(4007); - }, this.connectTimeout); - - if (this.protocolVersion === 1) { - this._handlePing = (message) => { - if (message === '#1') { - this._resetPingTimeout(); - if (this.socket.readyState === this.socket.OPEN) { - this.send('#2'); - } - return true; - } - return false; - }; - } else { - this._handlePing = (message) => { - if (message === '') { - this._resetPingTimeout(); - if (this.socket.readyState === this.socket.OPEN) { - this.send(''); - } - return true; - } - return false; - }; - } -} - -AGTransport.CONNECTING = AGTransport.prototype.CONNECTING = 'connecting'; -AGTransport.OPEN = AGTransport.prototype.OPEN = 'open'; -AGTransport.CLOSED = AGTransport.prototype.CLOSED = 'closed'; - -AGTransport.prototype.uri = function () { - let query = this.options.query || {}; - let schema = this.options.secure ? 'wss' : 'ws'; - - if (this.options.timestampRequests) { - query[this.options.timestampParam] = (new Date()).getTime(); - } - - query = querystring.encode(query); - - if (query.length) { - query = '?' + query; - } - - let host; - if (this.options.host) { - host = this.options.host; - } else { - let port = ''; - - if (this.options.port && ((schema === 'wss' && this.options.port !== 443) - || (schema === 'ws' && this.options.port !== 80))) { - port = ':' + this.options.port; - } - host = this.options.hostname + port; - } - - return schema + '://' + host + this.options.path + query; -}; - -AGTransport.prototype._onOpen = async function () { - clearTimeout(this._connectTimeoutRef); - this._resetPingTimeout(); - - let status; - - try { - status = await this._handshake(); - } catch (err) { - if (err.statusCode == null) { - err.statusCode = 4003; - } - this._onError(err); - this._destroy(err.statusCode, err.toString()); - this.socket.close(err.statusCode); - return; - } - - this.state = this.OPEN; - if (status) { - this.pingTimeout = status.pingTimeout; - } - this._resetPingTimeout(); - this._onOpenHandler(status); -}; - -AGTransport.prototype._handshake = async function () { - let token = await this.auth.loadToken(this.authTokenName); - // Don't wait for this.state to be 'open'. - // The underlying WebSocket (this.socket) is already open. - let options = { - force: true - }; - let status = await this.invoke('#handshake', {authToken: token}, options); - if (status) { - // Add the token which was used as part of authentication attempt - // to the status object. - status.authToken = token; - if (status.authError) { - status.authError = scErrors.hydrateError(status.authError); - } - } - return status; -}; - -AGTransport.prototype._abortAllPendingEventsDueToBadConnection = function (failureType) { - Object.keys(this._callbackMap || {}).forEach((i) => { - let eventObject = this._callbackMap[i]; - delete this._callbackMap[i]; - - clearTimeout(eventObject.timeout); - delete eventObject.timeout; - - let errorMessage = `Event "${eventObject.event}" was aborted due to a bad connection`; - let badConnectionError = new BadConnectionError(errorMessage, failureType); - - let callback = eventObject.callback; - delete eventObject.callback; - - callback.call(eventObject, badConnectionError, eventObject); - }); -}; - -AGTransport.prototype._destroy = function (code, reason) { - let protocolReason = scErrors.socketProtocolErrorStatuses[code]; - if (!reason && scErrors.socketProtocolErrorStatuses[code]) { - reason = scErrors.socketProtocolErrorStatuses[code]; - } - delete this.socket.onopen; - delete this.socket.onclose; - delete this.socket.onmessage; - delete this.socket.onerror; - - clearTimeout(this._connectTimeoutRef); - clearTimeout(this._pingTimeoutTicker); - - if (this.state === this.OPEN) { - this.state = this.CLOSED; - this._abortAllPendingEventsDueToBadConnection('disconnect'); - this._onCloseHandler({code, reason}); - } else if (this.state === this.CONNECTING) { - this.state = this.CLOSED; - this._abortAllPendingEventsDueToBadConnection('connectAbort'); - this._onOpenAbortHandler({code, reason}); - } else if (this.state === this.CLOSED) { - this._abortAllPendingEventsDueToBadConnection('connectAbort'); - } -}; - -AGTransport.prototype._processInboundPacket = function (packet, message) { - if (packet && packet.event != null) { - if (packet.cid == null) { - this._onInboundTransmitHandler({...packet}); - } else { - let request = new AGRequest(this, packet.cid, packet.event, packet.data); - this._onInboundInvokeHandler(request); - } - } else if (packet && packet.rid != null) { - let eventObject = this._callbackMap[packet.rid]; - if (eventObject) { - clearTimeout(eventObject.timeout); - delete eventObject.timeout; - delete this._callbackMap[packet.rid]; - - if (eventObject.callback) { - let rehydratedError = scErrors.hydrateError(packet.error); - eventObject.callback(rehydratedError, packet.data); - } - } - } else { - this._onEventHandler({event: 'raw', data: {message}}); - } -}; - -AGTransport.prototype._onMessage = function (message) { - this._onEventHandler({event: 'message', data: {message}}); - - if (this._handlePing(message)) { - return; - } - - let packet = this.decode(message); - - if (Array.isArray(packet)) { - let len = packet.length; - for (let i = 0; i < len; i++) { - this._processInboundPacket(packet[i], message); - } - } else { - this._processInboundPacket(packet, message); - } -}; - -AGTransport.prototype._onError = function (error) { - this._onErrorHandler({error}); -}; - -AGTransport.prototype._resetPingTimeout = function () { - if (this.pingTimeoutDisabled) { - return; - } - - let now = (new Date()).getTime(); - clearTimeout(this._pingTimeoutTicker); - this._pingTimeoutTicker = setTimeout(() => { - this._destroy(4000); - this.socket.close(4000); - }, this.pingTimeout); -}; - -AGTransport.prototype.clearAllListeners = function () { - this._onOpenHandler = function () {}; - this._onOpenAbortHandler = function () {}; - this._onCloseHandler = function () {}; - this._onEventHandler = function () {}; - this._onErrorHandler = function () {}; - this._onInboundInvokeHandler = function () {}; - this._onInboundTransmitHandler = function () {}; -}; - -AGTransport.prototype.startBatch = function () { - this.isBufferingBatch = true; - this._batchBuffer = []; -}; - -AGTransport.prototype.flushBatch = function () { - this.isBufferingBatch = false; - if (!this._batchBuffer.length) { - return; - } - let serializedBatch = this.serializeObject(this._batchBuffer); - this._batchBuffer = []; - this.send(serializedBatch); -}; - -AGTransport.prototype.cancelBatch = function () { - this.isBufferingBatch = false; - this._batchBuffer = []; -}; - -AGTransport.prototype.getBytesReceived = function () { - return this.socket.bytesReceived; -}; - -AGTransport.prototype.close = function (code, reason) { - if (this.state === this.OPEN || this.state === this.CONNECTING) { - code = code || 1000; - this._destroy(code, reason); - this.socket.close(code, reason); - } -}; - -AGTransport.prototype.transmitObject = function (eventObject) { - let simpleEventObject = { - event: eventObject.event, - data: eventObject.data - }; - - if (eventObject.callback) { - simpleEventObject.cid = eventObject.cid = this.callIdGenerator(); - this._callbackMap[eventObject.cid] = eventObject; - } - - this.sendObject(simpleEventObject); - - return eventObject.cid || null; -}; - -AGTransport.prototype._handleEventAckTimeout = function (eventObject) { - if (eventObject.cid) { - delete this._callbackMap[eventObject.cid]; - } - delete eventObject.timeout; - - let callback = eventObject.callback; - if (callback) { - delete eventObject.callback; - let error = new TimeoutError(`Event response for "${eventObject.event}" timed out`); - callback.call(eventObject, error, eventObject); - } -}; - -AGTransport.prototype.transmit = function (event, data, options) { - let eventObject = { - event, - data - }; - - if (this.state === this.OPEN || options.force) { - this.transmitObject(eventObject); - } - return Promise.resolve(); -}; - -AGTransport.prototype.invokeRaw = function (event, data, options, callback) { - let eventObject = { - event, - data, - callback - }; - - if (!options.noTimeout) { - eventObject.timeout = setTimeout(() => { - this._handleEventAckTimeout(eventObject); - }, this.options.ackTimeout); - } - let cid = null; - if (this.state === this.OPEN || options.force) { - cid = this.transmitObject(eventObject); - } - return cid; -}; - -AGTransport.prototype.invoke = function (event, data, options) { - return new Promise((resolve, reject) => { - this.invokeRaw(event, data, options, (err, data) => { - if (err) { - reject(err); - return; - } - resolve(data); - }); - }); -}; - -AGTransport.prototype.cancelPendingResponse = function (cid) { - delete this._callbackMap[cid]; -}; - -AGTransport.prototype.decode = function (message) { - return this.codec.decode(message); -}; - -AGTransport.prototype.encode = function (object) { - return this.codec.encode(object); -}; - -AGTransport.prototype.send = function (data) { - if (this.socket.readyState !== this.socket.OPEN) { - this._destroy(1005); - } else { - this.socket.send(data); - } -}; - -AGTransport.prototype.serializeObject = function (object) { - let str; - try { - str = this.encode(object); - } catch (error) { - this._onError(error); - return null; - } - return str; -}; - -AGTransport.prototype.sendObject = function (object) { - if (this.isBufferingBatch) { - this._batchBuffer.push(object); - return; - } - let str = this.serializeObject(object); - if (str != null) { - this.send(str); - } -}; - -module.exports = AGTransport; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"ag-request":8,"querystring":19,"sc-errors":21,"ws":6}],5:[function(require,module,exports){ -function wait(duration) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, duration); - }); -} - -module.exports = wait; - -},{}],6:[function(require,module,exports){ -let global; -if (typeof WorkerGlobalScope !== 'undefined') { - global = self; -} else { - global = typeof window !== 'undefined' && window || (function() { return this; })(); -} - -const WebSocket = global.WebSocket || global.MozWebSocket; - -/** - * WebSocket constructor. - * - * The third `opts` options object gets ignored in web browsers, since it's - * non-standard, and throws a TypeError if passed to the constructor. - * See: https://github.com/einaros/ws/issues/227 - * - * @param {String} uri - * @param {Array} protocols (optional) - * @param {Object} opts (optional) - * @api public - */ - -function ws(uri, protocols, opts) { - let instance; - if (protocols) { - instance = new WebSocket(uri, protocols); - } else { - instance = new WebSocket(uri); - } - return instance; -} - -if (WebSocket) ws.prototype = WebSocket.prototype; - -module.exports = WebSocket ? ws : null; - -},{}],7:[function(require,module,exports){ -const ConsumableStream = require('consumable-stream'); - -class AGChannel extends ConsumableStream { - constructor(name, client, eventDemux, dataDemux) { - super(); - this.PENDING = AGChannel.PENDING; - this.SUBSCRIBED = AGChannel.SUBSCRIBED; - this.UNSUBSCRIBED = AGChannel.UNSUBSCRIBED; - - this.name = name; - this.client = client; - - this._eventDemux = eventDemux; - this._dataStream = dataDemux.stream(this.name); - } - - createConsumer(timeout) { - return this._dataStream.createConsumer(timeout); - } - - listener(eventName) { - return this._eventDemux.stream(`${this.name}/${eventName}`); - } - - close() { - this.client.closeChannel(this.name); - } - - kill() { - this.client.killChannel(this.name); - } - - killOutputConsumer(consumerId) { - if (this.hasOutputConsumer(consumerId)) { - this.client.killChannelOutputConsumer(consumerId); - } - } - - killListenerConsumer(consumerId) { - if (this.hasAnyListenerConsumer(consumerId)) { - this.client.killChannelListenerConsumer(consumerId); - } - } - - getOutputConsumerStats(consumerId) { - if (this.hasOutputConsumer(consumerId)) { - return this.client.getChannelOutputConsumerStats(consumerId); - } - return undefined; - } - - getListenerConsumerStats(consumerId) { - if (this.hasAnyListenerConsumer(consumerId)) { - return this.client.getChannelListenerConsumerStats(consumerId); - } - return undefined; - } - - getBackpressure() { - return this.client.getChannelBackpressure(this.name); - } - - getListenerConsumerBackpressure(consumerId) { - if (this.hasAnyListenerConsumer(consumerId)) { - return this.client.getChannelListenerConsumerBackpressure(consumerId); - } - return 0; - } - - getOutputConsumerBackpressure(consumerId) { - if (this.hasOutputConsumer(consumerId)) { - return this.client.getChannelOutputConsumerBackpressure(consumerId); - } - return 0; - } - - closeOutput() { - this.client.channelCloseOutput(this.name); - } - - closeListener(eventName) { - this.client.channelCloseListener(this.name, eventName); - } - - closeAllListeners() { - this.client.channelCloseAllListeners(this.name); - } - - killOutput() { - this.client.channelKillOutput(this.name); - } - - killListener(eventName) { - this.client.channelKillListener(this.name, eventName); - } - - killAllListeners() { - this.client.channelKillAllListeners(this.name); - } - - getOutputConsumerStatsList() { - return this.client.channelGetOutputConsumerStatsList(this.name); - } - - getListenerConsumerStatsList(eventName) { - return this.client.channelGetListenerConsumerStatsList(this.name, eventName); - } - - getAllListenersConsumerStatsList() { - return this.client.channelGetAllListenersConsumerStatsList(this.name); - } - - getOutputBackpressure() { - return this.client.channelGetOutputBackpressure(this.name); - } - - getListenerBackpressure(eventName) { - return this.client.channelGetListenerBackpressure(this.name, eventName); - } - - getAllListenersBackpressure() { - return this.client.channelGetAllListenersBackpressure(this.name); - } - - hasOutputConsumer(consumerId) { - return this.client.channelHasOutputConsumer(this.name, consumerId); - } - - hasListenerConsumer(eventName, consumerId) { - return this.client.channelHasListenerConsumer(this.name, eventName, consumerId); - } - - hasAnyListenerConsumer(consumerId) { - return this.client.channelHasAnyListenerConsumer(this.name, consumerId); - } - - get state() { - return this.client.getChannelState(this.name); - } - - set state(value) { - throw new Error('Cannot directly set channel state'); - } - - get options() { - return this.client.getChannelOptions(this.name); - } - - set options(value) { - throw new Error('Cannot directly set channel options'); - } - - subscribe(options) { - this.client.subscribe(this.name, options); - } - - unsubscribe() { - this.client.unsubscribe(this.name); - } - - isSubscribed(includePending) { - return this.client.isSubscribed(this.name, includePending); - } - - transmitPublish(data) { - return this.client.transmitPublish(this.name, data); - } - - invokePublish(data) { - return this.client.invokePublish(this.name, data); - } -} - -AGChannel.PENDING = 'pending'; -AGChannel.SUBSCRIBED = 'subscribed'; -AGChannel.UNSUBSCRIBED = 'unsubscribed'; - -module.exports = AGChannel; - -},{"consumable-stream":12}],8:[function(require,module,exports){ -const scErrors = require('sc-errors'); -const InvalidActionError = scErrors.InvalidActionError; - -function AGRequest(socket, id, procedureName, data) { - this.socket = socket; - this.id = id; - this.procedure = procedureName; - this.data = data; - this.sent = false; - - this._respond = (responseData, options) => { - if (this.sent) { - throw new InvalidActionError(`Response to request ${this.id} has already been sent`); - } - this.sent = true; - this.socket.sendObject(responseData, options); - }; - - this.end = (data, options) => { - let responseData = { - rid: this.id - }; - if (data !== undefined) { - responseData.data = data; - } - this._respond(responseData, options); - }; - - this.error = (error, options) => { - let responseData = { - rid: this.id, - error: scErrors.dehydrateError(error) - }; - this._respond(responseData, options); - }; -} - -module.exports = AGRequest; - -},{"sc-errors":21}],9:[function(require,module,exports){ -const StreamDemux = require('stream-demux'); - -function AsyncStreamEmitter() { - this._listenerDemux = new StreamDemux(); -} - -AsyncStreamEmitter.prototype.emit = function (eventName, data) { - this._listenerDemux.write(eventName, data); -}; - -AsyncStreamEmitter.prototype.listener = function (eventName) { - return this._listenerDemux.stream(eventName); -}; - -AsyncStreamEmitter.prototype.closeListener = function (eventName) { - this._listenerDemux.close(eventName); -}; - -AsyncStreamEmitter.prototype.closeAllListeners = function () { - this._listenerDemux.closeAll(); -}; - -AsyncStreamEmitter.prototype.getListenerConsumerStats = function (consumerId) { - return this._listenerDemux.getConsumerStats(consumerId); -}; - -AsyncStreamEmitter.prototype.getListenerConsumerStatsList = function (eventName) { - return this._listenerDemux.getConsumerStatsList(eventName); -}; - -AsyncStreamEmitter.prototype.getAllListenersConsumerStatsList = function () { - return this._listenerDemux.getConsumerStatsListAll(); -}; - -AsyncStreamEmitter.prototype.killListener = function (eventName) { - this._listenerDemux.kill(eventName); -}; - -AsyncStreamEmitter.prototype.killAllListeners = function () { - this._listenerDemux.killAll(); -}; - -AsyncStreamEmitter.prototype.killListenerConsumer = function (consumerId) { - this._listenerDemux.killConsumer(consumerId); -}; - -AsyncStreamEmitter.prototype.getListenerBackpressure = function (eventName) { - return this._listenerDemux.getBackpressure(eventName); -}; - -AsyncStreamEmitter.prototype.getAllListenersBackpressure = function () { - return this._listenerDemux.getBackpressureAll(); -}; - -AsyncStreamEmitter.prototype.getListenerConsumerBackpressure = function (consumerId) { - return this._listenerDemux.getConsumerBackpressure(consumerId); -}; - -AsyncStreamEmitter.prototype.hasListenerConsumer = function (eventName, consumerId) { - return this._listenerDemux.hasConsumer(eventName, consumerId); -}; - -AsyncStreamEmitter.prototype.hasAnyListenerConsumer = function (consumerId) { - return this._listenerDemux.hasConsumerAll(consumerId); -}; - -module.exports = AsyncStreamEmitter; - -},{"stream-demux":24}],10:[function(require,module,exports){ -'use strict' - -exports.byteLength = byteLength -exports.toByteArray = toByteArray -exports.fromByteArray = fromByteArray - -var lookup = [] -var revLookup = [] -var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array - -var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -for (var i = 0, len = code.length; i < len; ++i) { - lookup[i] = code[i] - revLookup[code.charCodeAt(i)] = i -} - -// Support decoding URL-safe base64 strings, as Node.js does. -// See: https://en.wikipedia.org/wiki/Base64#URL_applications -revLookup['-'.charCodeAt(0)] = 62 -revLookup['_'.charCodeAt(0)] = 63 - -function getLens (b64) { - var len = b64.length - - if (len % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // Trim off extra bytes after placeholder bytes are found - // See: https://github.com/beatgammit/base64-js/issues/42 - var validLen = b64.indexOf('=') - if (validLen === -1) validLen = len - - var placeHoldersLen = validLen === len - ? 0 - : 4 - (validLen % 4) - - return [validLen, placeHoldersLen] -} - -// base64 is 4/3 + up to two characters of the original data -function byteLength (b64) { - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} - -function _byteLength (b64, validLen, placeHoldersLen) { - return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen -} - -function toByteArray (b64) { - var tmp - var lens = getLens(b64) - var validLen = lens[0] - var placeHoldersLen = lens[1] - - var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) - - var curByte = 0 - - // if there are placeholders, only get up to the last complete 4 chars - var len = placeHoldersLen > 0 - ? validLen - 4 - : validLen - - var i - for (i = 0; i < len; i += 4) { - tmp = - (revLookup[b64.charCodeAt(i)] << 18) | - (revLookup[b64.charCodeAt(i + 1)] << 12) | - (revLookup[b64.charCodeAt(i + 2)] << 6) | - revLookup[b64.charCodeAt(i + 3)] - arr[curByte++] = (tmp >> 16) & 0xFF - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } - - if (placeHoldersLen === 2) { - tmp = - (revLookup[b64.charCodeAt(i)] << 2) | - (revLookup[b64.charCodeAt(i + 1)] >> 4) - arr[curByte++] = tmp & 0xFF - } - - if (placeHoldersLen === 1) { - tmp = - (revLookup[b64.charCodeAt(i)] << 10) | - (revLookup[b64.charCodeAt(i + 1)] << 4) | - (revLookup[b64.charCodeAt(i + 2)] >> 2) - arr[curByte++] = (tmp >> 8) & 0xFF - arr[curByte++] = tmp & 0xFF - } - - return arr -} - -function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + - lookup[num >> 12 & 0x3F] + - lookup[num >> 6 & 0x3F] + - lookup[num & 0x3F] -} - -function encodeChunk (uint8, start, end) { - var tmp - var output = [] - for (var i = start; i < end; i += 3) { - tmp = - ((uint8[i] << 16) & 0xFF0000) + - ((uint8[i + 1] << 8) & 0xFF00) + - (uint8[i + 2] & 0xFF) - output.push(tripletToBase64(tmp)) - } - return output.join('') -} - -function fromByteArray (uint8) { - var tmp - var len = uint8.length - var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes - var parts = [] - var maxChunkLength = 16383 // must be multiple of 3 - - // go through the array every three bytes, we'll deal with trailing stuff later - for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { - parts.push(encodeChunk( - uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) - )) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - if (extraBytes === 1) { - tmp = uint8[len - 1] - parts.push( - lookup[tmp >> 2] + - lookup[(tmp << 4) & 0x3F] + - '==' - ) - } else if (extraBytes === 2) { - tmp = (uint8[len - 2] << 8) + uint8[len - 1] - parts.push( - lookup[tmp >> 10] + - lookup[(tmp >> 4) & 0x3F] + - lookup[(tmp << 2) & 0x3F] + - '=' - ) - } - - return parts.join('') -} - -},{}],11:[function(require,module,exports){ -(function (Buffer){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - -'use strict' - -var base64 = require('base64-js') -var ieee754 = require('ieee754') -var customInspectSymbol = - (typeof Symbol === 'function' && typeof Symbol.for === 'function') - ? Symbol.for('nodejs.util.inspect.custom') - : null - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 - -var K_MAX_LENGTH = 0x7fffffff -exports.kMaxLength = K_MAX_LENGTH - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Print warning and recommend using `buffer` v4.x which has an Object - * implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * We report that the browser does not support typed arrays if the are not subclassable - * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` - * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support - * for __proto__ and has a buggy typed array implementation. - */ -Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() - -if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && - typeof console.error === 'function') { - console.error( - 'This browser lacks typed array (Uint8Array) support which is required by ' + - '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' - ) -} - -function typedArraySupport () { - // Can typed array instances can be augmented? - try { - var arr = new Uint8Array(1) - var proto = { foo: function () { return 42 } } - Object.setPrototypeOf(proto, Uint8Array.prototype) - Object.setPrototypeOf(arr, proto) - return arr.foo() === 42 - } catch (e) { - return false - } -} - -Object.defineProperty(Buffer.prototype, 'parent', { - enumerable: true, - get: function () { - if (!Buffer.isBuffer(this)) return undefined - return this.buffer - } -}) - -Object.defineProperty(Buffer.prototype, 'offset', { - enumerable: true, - get: function () { - if (!Buffer.isBuffer(this)) return undefined - return this.byteOffset - } -}) - -function createBuffer (length) { - if (length > K_MAX_LENGTH) { - throw new RangeError('The value "' + length + '" is invalid for option "size"') - } - // Return an augmented `Uint8Array` instance - var buf = new Uint8Array(length) - Object.setPrototypeOf(buf, Buffer.prototype) - return buf -} - -/** - * The Buffer constructor returns instances of `Uint8Array` that have their - * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of - * `Uint8Array`, so the returned instances will have all the node `Buffer` methods - * and the `Uint8Array` methods. Square bracket notation works as expected -- it - * returns a single octet. - * - * The `Uint8Array` prototype remains unmodified. - */ - -function Buffer (arg, encodingOrOffset, length) { - // Common case. - if (typeof arg === 'number') { - if (typeof encodingOrOffset === 'string') { - throw new TypeError( - 'The "string" argument must be of type string. Received type number' - ) - } - return allocUnsafe(arg) - } - return from(arg, encodingOrOffset, length) -} - -// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 -if (typeof Symbol !== 'undefined' && Symbol.species != null && - Buffer[Symbol.species] === Buffer) { - Object.defineProperty(Buffer, Symbol.species, { - value: null, - configurable: true, - enumerable: false, - writable: false - }) -} - -Buffer.poolSize = 8192 // not used by this implementation - -function from (value, encodingOrOffset, length) { - if (typeof value === 'string') { - return fromString(value, encodingOrOffset) - } - - if (ArrayBuffer.isView(value)) { - return fromArrayLike(value) - } - - if (value == null) { - throw new TypeError( - 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + - 'or Array-like Object. Received type ' + (typeof value) - ) - } - - if (isInstance(value, ArrayBuffer) || - (value && isInstance(value.buffer, ArrayBuffer))) { - return fromArrayBuffer(value, encodingOrOffset, length) - } - - if (typeof value === 'number') { - throw new TypeError( - 'The "value" argument must not be of type number. Received type number' - ) - } - - var valueOf = value.valueOf && value.valueOf() - if (valueOf != null && valueOf !== value) { - return Buffer.from(valueOf, encodingOrOffset, length) - } - - var b = fromObject(value) - if (b) return b - - if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && - typeof value[Symbol.toPrimitive] === 'function') { - return Buffer.from( - value[Symbol.toPrimitive]('string'), encodingOrOffset, length - ) - } - - throw new TypeError( - 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + - 'or Array-like Object. Received type ' + (typeof value) - ) -} - -/** - * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError - * if value is a number. - * Buffer.from(str[, encoding]) - * Buffer.from(array) - * Buffer.from(buffer) - * Buffer.from(arrayBuffer[, byteOffset[, length]]) - **/ -Buffer.from = function (value, encodingOrOffset, length) { - return from(value, encodingOrOffset, length) -} - -// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: -// https://github.com/feross/buffer/pull/148 -Object.setPrototypeOf(Buffer.prototype, Uint8Array.prototype) -Object.setPrototypeOf(Buffer, Uint8Array) - -function assertSize (size) { - if (typeof size !== 'number') { - throw new TypeError('"size" argument must be of type number') - } else if (size < 0) { - throw new RangeError('The value "' + size + '" is invalid for option "size"') - } -} - -function alloc (size, fill, encoding) { - assertSize(size) - if (size <= 0) { - return createBuffer(size) - } - if (fill !== undefined) { - // Only pay attention to encoding if it's a string. This - // prevents accidentally sending in a number that would - // be interpretted as a start offset. - return typeof encoding === 'string' - ? createBuffer(size).fill(fill, encoding) - : createBuffer(size).fill(fill) - } - return createBuffer(size) -} - -/** - * Creates a new filled Buffer instance. - * alloc(size[, fill[, encoding]]) - **/ -Buffer.alloc = function (size, fill, encoding) { - return alloc(size, fill, encoding) -} - -function allocUnsafe (size) { - assertSize(size) - return createBuffer(size < 0 ? 0 : checked(size) | 0) -} - -/** - * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. - * */ -Buffer.allocUnsafe = function (size) { - return allocUnsafe(size) -} -/** - * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. - */ -Buffer.allocUnsafeSlow = function (size) { - return allocUnsafe(size) -} - -function fromString (string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8' - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - - var length = byteLength(string, encoding) | 0 - var buf = createBuffer(length) - - var actual = buf.write(string, encoding) - - if (actual !== length) { - // Writing a hex string, for example, that contains invalid characters will - // cause everything after the first invalid character to be ignored. (e.g. - // 'abxxcd' will be treated as 'ab') - buf = buf.slice(0, actual) - } - - return buf -} - -function fromArrayLike (array) { - var length = array.length < 0 ? 0 : checked(array.length) | 0 - var buf = createBuffer(length) - for (var i = 0; i < length; i += 1) { - buf[i] = array[i] & 255 - } - return buf -} - -function fromArrayBuffer (array, byteOffset, length) { - if (byteOffset < 0 || array.byteLength < byteOffset) { - throw new RangeError('"offset" is outside of buffer bounds') - } - - if (array.byteLength < byteOffset + (length || 0)) { - throw new RangeError('"length" is outside of buffer bounds') - } - - var buf - if (byteOffset === undefined && length === undefined) { - buf = new Uint8Array(array) - } else if (length === undefined) { - buf = new Uint8Array(array, byteOffset) - } else { - buf = new Uint8Array(array, byteOffset, length) - } - - // Return an augmented `Uint8Array` instance - Object.setPrototypeOf(buf, Buffer.prototype) - - return buf -} - -function fromObject (obj) { - if (Buffer.isBuffer(obj)) { - var len = checked(obj.length) | 0 - var buf = createBuffer(len) - - if (buf.length === 0) { - return buf - } - - obj.copy(buf, 0, 0, len) - return buf - } - - if (obj.length !== undefined) { - if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { - return createBuffer(0) - } - return fromArrayLike(obj) - } - - if (obj.type === 'Buffer' && Array.isArray(obj.data)) { - return fromArrayLike(obj.data) - } -} - -function checked (length) { - // Note: cannot use `length < K_MAX_LENGTH` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= K_MAX_LENGTH) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') - } - return length | 0 -} - -function SlowBuffer (length) { - if (+length != length) { // eslint-disable-line eqeqeq - length = 0 - } - return Buffer.alloc(+length) -} - -Buffer.isBuffer = function isBuffer (b) { - return b != null && b._isBuffer === true && - b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false -} - -Buffer.compare = function compare (a, b) { - if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength) - if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength) - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError( - 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array' - ) - } - - if (a === b) return 0 - - var x = a.length - var y = b.length - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i] - y = b[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'latin1': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.concat = function concat (list, length) { - if (!Array.isArray(list)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - - if (list.length === 0) { - return Buffer.alloc(0) - } - - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; ++i) { - length += list[i].length - } - } - - var buffer = Buffer.allocUnsafe(length) - var pos = 0 - for (i = 0; i < list.length; ++i) { - var buf = list[i] - if (isInstance(buf, Uint8Array)) { - buf = Buffer.from(buf) - } - if (!Buffer.isBuffer(buf)) { - throw new TypeError('"list" argument must be an Array of Buffers') - } - buf.copy(buffer, pos) - pos += buf.length - } - return buffer -} - -function byteLength (string, encoding) { - if (Buffer.isBuffer(string)) { - return string.length - } - if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) { - return string.byteLength - } - if (typeof string !== 'string') { - throw new TypeError( - 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + - 'Received type ' + typeof string - ) - } - - var len = string.length - var mustMatch = (arguments.length > 2 && arguments[2] === true) - if (!mustMatch && len === 0) return 0 - - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'latin1': - case 'binary': - return len - case 'utf8': - case 'utf-8': - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) { - return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8 - } - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - - // No need to verify that "this.length <= MAX_UINT32" since it's a read-only - // property of a typed array. - - // This behaves neither like String nor Uint8Array in that we set start/end - // to their upper/lower bounds if the value passed is out of range. - // undefined is handled specially as per ECMA-262 6th Edition, - // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. - if (start === undefined || start < 0) { - start = 0 - } - // Return early if start > this.length. Done here to prevent potential uint32 - // coercion fail below. - if (start > this.length) { - return '' - } - - if (end === undefined || end > this.length) { - end = this.length - } - - if (end <= 0) { - return '' - } - - // Force coersion to uint32. This will also coerce falsey/NaN values to 0. - end >>>= 0 - start >>>= 0 - - if (end <= start) { - return '' - } - - if (!encoding) encoding = 'utf8' - - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) - - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) - - case 'ascii': - return asciiSlice(this, start, end) - - case 'latin1': - case 'binary': - return latin1Slice(this, start, end) - - case 'base64': - return base64Slice(this, start, end) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } - } -} - -// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package) -// to detect a Buffer instance. It's not possible to use `instanceof Buffer` -// reliably in a browserify context because there could be multiple different -// copies of the 'buffer' package in use. This method works even for Buffer -// instances that were created from another copy of the `buffer` package. -// See: https://github.com/feross/buffer/issues/154 -Buffer.prototype._isBuffer = true - -function swap (b, n, m) { - var i = b[n] - b[n] = b[m] - b[m] = i -} - -Buffer.prototype.swap16 = function swap16 () { - var len = this.length - if (len % 2 !== 0) { - throw new RangeError('Buffer size must be a multiple of 16-bits') - } - for (var i = 0; i < len; i += 2) { - swap(this, i, i + 1) - } - return this -} - -Buffer.prototype.swap32 = function swap32 () { - var len = this.length - if (len % 4 !== 0) { - throw new RangeError('Buffer size must be a multiple of 32-bits') - } - for (var i = 0; i < len; i += 4) { - swap(this, i, i + 3) - swap(this, i + 1, i + 2) - } - return this -} - -Buffer.prototype.swap64 = function swap64 () { - var len = this.length - if (len % 8 !== 0) { - throw new RangeError('Buffer size must be a multiple of 64-bits') - } - for (var i = 0; i < len; i += 8) { - swap(this, i, i + 7) - swap(this, i + 1, i + 6) - swap(this, i + 2, i + 5) - swap(this, i + 3, i + 4) - } - return this -} - -Buffer.prototype.toString = function toString () { - var length = this.length - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) -} - -Buffer.prototype.toLocaleString = Buffer.prototype.toString - -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim() - if (this.length > max) str += ' ... ' - return '' -} -if (customInspectSymbol) { - Buffer.prototype[customInspectSymbol] = Buffer.prototype.inspect -} - -Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { - if (isInstance(target, Uint8Array)) { - target = Buffer.from(target, target.offset, target.byteLength) - } - if (!Buffer.isBuffer(target)) { - throw new TypeError( - 'The "target" argument must be one of type Buffer or Uint8Array. ' + - 'Received type ' + (typeof target) - ) - } - - if (start === undefined) { - start = 0 - } - if (end === undefined) { - end = target ? target.length : 0 - } - if (thisStart === undefined) { - thisStart = 0 - } - if (thisEnd === undefined) { - thisEnd = this.length - } - - if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { - throw new RangeError('out of range index') - } - - if (thisStart >= thisEnd && start >= end) { - return 0 - } - if (thisStart >= thisEnd) { - return -1 - } - if (start >= end) { - return 1 - } - - start >>>= 0 - end >>>= 0 - thisStart >>>= 0 - thisEnd >>>= 0 - - if (this === target) return 0 - - var x = thisEnd - thisStart - var y = end - start - var len = Math.min(x, y) - - var thisCopy = this.slice(thisStart, thisEnd) - var targetCopy = target.slice(start, end) - - for (var i = 0; i < len; ++i) { - if (thisCopy[i] !== targetCopy[i]) { - x = thisCopy[i] - y = targetCopy[i] - break - } - } - - if (x < y) return -1 - if (y < x) return 1 - return 0 -} - -// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, -// OR the last index of `val` in `buffer` at offset <= `byteOffset`. -// -// Arguments: -// - buffer - a Buffer to search -// - val - a string, Buffer, or number -// - byteOffset - an index into `buffer`; will be clamped to an int32 -// - encoding - an optional encoding, relevant is val is a string -// - dir - true for indexOf, false for lastIndexOf -function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { - // Empty buffer means no match - if (buffer.length === 0) return -1 - - // Normalize byteOffset - if (typeof byteOffset === 'string') { - encoding = byteOffset - byteOffset = 0 - } else if (byteOffset > 0x7fffffff) { - byteOffset = 0x7fffffff - } else if (byteOffset < -0x80000000) { - byteOffset = -0x80000000 - } - byteOffset = +byteOffset // Coerce to Number. - if (numberIsNaN(byteOffset)) { - // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer - byteOffset = dir ? 0 : (buffer.length - 1) - } - - // Normalize byteOffset: negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = buffer.length + byteOffset - if (byteOffset >= buffer.length) { - if (dir) return -1 - else byteOffset = buffer.length - 1 - } else if (byteOffset < 0) { - if (dir) byteOffset = 0 - else return -1 - } - - // Normalize val - if (typeof val === 'string') { - val = Buffer.from(val, encoding) - } - - // Finally, search either indexOf (if dir is true) or lastIndexOf - if (Buffer.isBuffer(val)) { - // Special case: looking for empty string/buffer always fails - if (val.length === 0) { - return -1 - } - return arrayIndexOf(buffer, val, byteOffset, encoding, dir) - } else if (typeof val === 'number') { - val = val & 0xFF // Search for a byte value [0-255] - if (typeof Uint8Array.prototype.indexOf === 'function') { - if (dir) { - return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) - } else { - return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) - } - } - return arrayIndexOf(buffer, [val], byteOffset, encoding, dir) - } - - throw new TypeError('val must be string, number or Buffer') -} - -function arrayIndexOf (arr, val, byteOffset, encoding, dir) { - var indexSize = 1 - var arrLength = arr.length - var valLength = val.length - - if (encoding !== undefined) { - encoding = String(encoding).toLowerCase() - if (encoding === 'ucs2' || encoding === 'ucs-2' || - encoding === 'utf16le' || encoding === 'utf-16le') { - if (arr.length < 2 || val.length < 2) { - return -1 - } - indexSize = 2 - arrLength /= 2 - valLength /= 2 - byteOffset /= 2 - } - } - - function read (buf, i) { - if (indexSize === 1) { - return buf[i] - } else { - return buf.readUInt16BE(i * indexSize) - } - } - - var i - if (dir) { - var foundIndex = -1 - for (i = byteOffset; i < arrLength; i++) { - if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === valLength) return foundIndex * indexSize - } else { - if (foundIndex !== -1) i -= i - foundIndex - foundIndex = -1 - } - } - } else { - if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength - for (i = byteOffset; i >= 0; i--) { - var found = true - for (var j = 0; j < valLength; j++) { - if (read(arr, i + j) !== read(val, j)) { - found = false - break - } - } - if (found) return i - } - } - - return -1 -} - -Buffer.prototype.includes = function includes (val, byteOffset, encoding) { - return this.indexOf(val, byteOffset, encoding) !== -1 -} - -Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, true) -} - -Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { - return bidirectionalIndexOf(this, val, byteOffset, encoding, false) -} - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - var strLen = string.length - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; ++i) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (numberIsNaN(parsed)) return i - buf[offset + i] = parsed - } - return i -} - -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} - -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} - -function latin1Write (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) -} - -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} - -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset >>> 0 - if (isFinite(length)) { - length = length >>> 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - } else { - throw new Error( - 'Buffer.write(string, encoding, offset[, length]) is no longer supported' - ) - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('Attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' - - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) - - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) - - case 'ascii': - return asciiWrite(this, string, offset, length) - - case 'latin1': - case 'binary': - return latin1Write(this, string, offset, length) - - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) - - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) - - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true - } - } -} - -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 - - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint - - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } - - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } - - res.push(codePoint) - i += bytesPerSequence - } - - return decodeCodePointsArray(res) -} - -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 - -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } - - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) - } - return res -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i] & 0x7F) - } - return ret -} - -function latin1Slice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; ++i) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; ++i) { - out += hexSliceLookupTable[buf[i]] - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256)) - } - return res -} - -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len - } - - if (end < start) end = start - - var newBuf = this.subarray(start, end) - // Return an augmented `Uint8Array` instance - Object.setPrototypeOf(newBuf, Buffer.prototype) - - return newBuf -} - -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') -} - -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - - return val -} - -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) - } - - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul - } - - return val -} - -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} - -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} - -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} - -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} - -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) - - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul - } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} - -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} - -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} - -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} - -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} - -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} - -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} - -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - offset = offset >>> 0 - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} - -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') - if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') - if (offset + ext > buf.length) throw new RangeError('Index out of range') -} - -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - byteLength = byteLength >>> 0 - if (!noAssert) { - var maxBytes = Math.pow(2, 8 * byteLength) - 1 - checkInt(this, value, offset, byteLength, maxBytes, 0) - } - - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - return offset + 2 -} - -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - return offset + 2 -} - -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - return offset + 4 -} - -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - return offset + 4 -} - -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = 0 - var mul = 1 - var sub = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - var limit = Math.pow(2, (8 * byteLength) - 1) - - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } - - var i = byteLength - 1 - var mul = 1 - var sub = 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { - sub = 1 - } - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } - - return offset + byteLength -} - -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} - -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - return offset + 2 -} - -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - return offset + 2 -} - -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - return offset + 4 -} - -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - return offset + 4 -} - -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (offset + ext > buf.length) throw new RangeError('Index out of range') - if (offset < 0) throw new RangeError('Index out of range') -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - value = +value - offset = offset >>> 0 - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer') - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start - - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 - - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('Index out of range') - if (end < 0) throw new RangeError('sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start - } - - var len = end - start - - if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') { - // Use built-in when available, missing from IE11 - this.copyWithin(targetStart, start, end) - } else if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (var i = len - 1; i >= 0; --i) { - target[i + targetStart] = this[i + start] - } - } else { - Uint8Array.prototype.set.call( - target, - this.subarray(start, end), - targetStart - ) - } - - return len -} - -// Usage: -// buffer.fill(number[, offset[, end]]) -// buffer.fill(buffer[, offset[, end]]) -// buffer.fill(string[, offset[, end]][, encoding]) -Buffer.prototype.fill = function fill (val, start, end, encoding) { - // Handle string cases: - if (typeof val === 'string') { - if (typeof start === 'string') { - encoding = start - start = 0 - end = this.length - } else if (typeof end === 'string') { - encoding = end - end = this.length - } - if (encoding !== undefined && typeof encoding !== 'string') { - throw new TypeError('encoding must be a string') - } - if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { - throw new TypeError('Unknown encoding: ' + encoding) - } - if (val.length === 1) { - var code = val.charCodeAt(0) - if ((encoding === 'utf8' && code < 128) || - encoding === 'latin1') { - // Fast path: If `val` fits into a single byte, use that numeric value. - val = code - } - } - } else if (typeof val === 'number') { - val = val & 255 - } else if (typeof val === 'boolean') { - val = Number(val) - } - - // Invalid ranges are not set to a default, so can range check early. - if (start < 0 || this.length < start || this.length < end) { - throw new RangeError('Out of range index') - } - - if (end <= start) { - return this - } - - start = start >>> 0 - end = end === undefined ? this.length : end >>> 0 - - if (!val) val = 0 - - var i - if (typeof val === 'number') { - for (i = start; i < end; ++i) { - this[i] = val - } - } else { - var bytes = Buffer.isBuffer(val) - ? val - : Buffer.from(val, encoding) - var len = bytes.length - if (len === 0) { - throw new TypeError('The value "' + val + - '" is invalid for argument "value"') - } - for (i = 0; i < end - start; ++i) { - this[i + start] = bytes[i % len] - } - } - - return this -} - -// HELPER FUNCTIONS -// ================ - -var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g - -function base64clean (str) { - // Node takes equal signs as end of the Base64 encoding - str = str.split('=')[0] - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = str.trim().replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] - - for (var i = 0; i < length; ++i) { - codePoint = string.charCodeAt(i) - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } - - // valid lead - leadSurrogate = codePoint - - continue - } - - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } - - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - } - - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } - } - - return bytes -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; ++i) { - if ((units -= 2) < 0) break - - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; ++i) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} - -// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass -// the `instanceof` check but they should be treated as of that type. -// See: https://github.com/feross/buffer/issues/166 -function isInstance (obj, type) { - return obj instanceof type || - (obj != null && obj.constructor != null && obj.constructor.name != null && - obj.constructor.name === type.name) -} -function numberIsNaN (obj) { - // For IE11 support - return obj !== obj // eslint-disable-line no-self-compare -} - -// Create lookup table for `toString('hex')` -// See: https://github.com/feross/buffer/issues/219 -var hexSliceLookupTable = (function () { - var alphabet = '0123456789abcdef' - var table = new Array(256) - for (var i = 0; i < 16; ++i) { - var i16 = i * 16 - for (var j = 0; j < 16; ++j) { - table[i16 + j] = alphabet[i] + alphabet[j] - } - } - return table -})() - -}).call(this,require("buffer").Buffer) -},{"base64-js":10,"buffer":11,"ieee754":13}],12:[function(require,module,exports){ -class ConsumableStream { - async next(timeout) { - let asyncIterator = this.createConsumer(timeout); - let result = await asyncIterator.next(); - asyncIterator.return(); - return result; - } - - async once(timeout) { - let result = await this.next(timeout); - if (result.done) { - // If stream was ended, this function should never resolve. - await new Promise(() => {}); - } - return result.value; - } - - createConsumer() { - throw new TypeError('Method must be overriden by subclass'); - } - - createConsumable(timeout) { - let asyncIterator = this.createConsumer(timeout); - return { - [Symbol.asyncIterator]: () => { - return asyncIterator; - } - } - } - - [Symbol.asyncIterator]() { - return this.createConsumer(); - } -} - -module.exports = ConsumableStream; - -},{}],13:[function(require,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = (nBytes * 8) - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = (nBytes * 8) - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - - value = Math.abs(value) - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 - } - - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = ((value * c) - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 -} - -},{}],14:[function(require,module,exports){ -'use strict'; - -/** - * Constants. - */ - -var errorMessage; - -errorMessage = 'An argument without append, prepend, ' + - 'or detach methods was given to `List'; - -/** - * Creates a new List: A linked list is a bit like an Array, but - * knows nothing about how many items are in it, and knows only about its - * first (`head`) and last (`tail`) items. Each item (e.g. `head`, `tail`, - * &c.) knows which item comes before or after it (its more like the - * implementation of the DOM in JavaScript). - * @global - * @private - * @constructor - * @class Represents an instance of List. - */ - -function List(/*items...*/) { - if (arguments.length) { - return List.from(arguments); - } -} - -var ListPrototype; - -ListPrototype = List.prototype; - -/** - * Creates a new list from the arguments (each a list item) passed in. - * @name List.of - * @param {...ListItem} [items] - Zero or more items to attach. - * @returns {list} - A new instance of List. - */ - -List.of = function (/*items...*/) { - return List.from.call(this, arguments); -}; - -/** - * Creates a new list from the given array-like object (each a list item) - * passed in. - * @name List.from - * @param {ListItem[]} [items] - The items to append. - * @returns {list} - A new instance of List. - */ -List.from = function (items) { - var list = new this(), length, iterator, item; - - if (items && (length = items.length)) { - iterator = -1; - - while (++iterator < length) { - item = items[iterator]; - - if (item !== null && item !== undefined) { - list.append(item); - } - } - } - - return list; -}; - -/** - * List#head - * Default to `null`. - */ -ListPrototype.head = null; - -/** - * List#tail - * Default to `null`. - */ -ListPrototype.tail = null; - -/** - * Returns the list's items as an array. This does *not* detach the items. - * @name List#toArray - * @returns {ListItem[]} - An array of (still attached) ListItems. - */ -ListPrototype.toArray = function () { - var item = this.head, - result = []; - - while (item) { - result.push(item); - item = item.next; - } - - return result; -}; - -/** - * Prepends the given item to the list: Item will be the new first item - * (`head`). - * @name List#prepend - * @param {ListItem} item - The item to prepend. - * @returns {ListItem} - An instance of ListItem (the given item). - */ -ListPrototype.prepend = function (item) { - if (!item) { - return false; - } - - if (!item.append || !item.prepend || !item.detach) { - throw new Error(errorMessage + '#prepend`.'); - } - - var self, head; - - // Cache self. - self = this; - - // If self has a first item, defer prepend to the first items prepend - // method, and return the result. - head = self.head; - - if (head) { - return head.prepend(item); - } - - // ...otherwise, there is no `head` (or `tail`) item yet. - - // Detach the prependee. - item.detach(); - - // Set the prependees parent list to reference self. - item.list = self; - - // Set self's first item to the prependee, and return the item. - self.head = item; - - return item; -}; - -/** - * Appends the given item to the list: Item will be the new last item (`tail`) - * if the list had a first item, and its first item (`head`) otherwise. - * @name List#append - * @param {ListItem} item - The item to append. - * @returns {ListItem} - An instance of ListItem (the given item). - */ - -ListPrototype.append = function (item) { - if (!item) { - return false; - } - - if (!item.append || !item.prepend || !item.detach) { - throw new Error(errorMessage + '#append`.'); - } - - var self, head, tail; - - // Cache self. - self = this; - - // If self has a last item, defer appending to the last items append - // method, and return the result. - tail = self.tail; - - if (tail) { - return tail.append(item); - } - - // If self has a first item, defer appending to the first items append - // method, and return the result. - head = self.head; - - if (head) { - return head.append(item); - } - - // ...otherwise, there is no `tail` or `head` item yet. - - // Detach the appendee. - item.detach(); - - // Set the appendees parent list to reference self. - item.list = self; - - // Set self's first item to the appendee, and return the item. - self.head = item; - - return item; -}; - -/** - * Creates a new ListItem: A linked list item is a bit like DOM node: - * It knows only about its "parent" (`list`), the item before it (`prev`), - * and the item after it (`next`). - * @global - * @private - * @constructor - * @class Represents an instance of ListItem. - */ - -function ListItem() {} - -List.Item = ListItem; - -var ListItemPrototype = ListItem.prototype; - -ListItemPrototype.next = null; - -ListItemPrototype.prev = null; - -ListItemPrototype.list = null; - -/** - * Detaches the item operated on from its parent list. - * @name ListItem#detach - * @returns {ListItem} - The item operated on. - */ -ListItemPrototype.detach = function () { - // Cache self, the parent list, and the previous and next items. - var self = this, - list = self.list, - prev = self.prev, - next = self.next; - - // If the item is already detached, return self. - if (!list) { - return self; - } - - // If self is the last item in the parent list, link the lists last item - // to the previous item. - if (list.tail === self) { - list.tail = prev; - } - - // If self is the first item in the parent list, link the lists first item - // to the next item. - if (list.head === self) { - list.head = next; - } - - // If both the last and first items in the parent list are the same, - // remove the link to the last item. - if (list.tail === list.head) { - list.tail = null; - } - - // If a previous item exists, link its next item to selfs next item. - if (prev) { - prev.next = next; - } - - // If a next item exists, link its previous item to selfs previous item. - if (next) { - next.prev = prev; - } - - // Remove links from self to both the next and previous items, and to the - // parent list. - self.prev = self.next = self.list = null; - - // Return self. - return self; -}; - -/** - * Prepends the given item *before* the item operated on. - * @name ListItem#prepend - * @param {ListItem} item - The item to prepend. - * @returns {ListItem} - The item operated on, or false when that item is not - * attached. - */ -ListItemPrototype.prepend = function (item) { - if (!item || !item.append || !item.prepend || !item.detach) { - throw new Error(errorMessage + 'Item#prepend`.'); - } - - // Cache self, the parent list, and the previous item. - var self = this, - list = self.list, - prev = self.prev; - - // If self is detached, return false. - if (!list) { - return false; - } - - // Detach the prependee. - item.detach(); - - // If self has a previous item... - if (prev) { - // ...link the prependees previous item, to selfs previous item. - item.prev = prev; - - // ...link the previous items next item, to self. - prev.next = item; - } - - // Set the prependees next item to self. - item.next = self; - - // Set the prependees parent list to selfs parent list. - item.list = list; - - // Set the previous item of self to the prependee. - self.prev = item; - - // If self is the first item in the parent list, link the lists first item - // to the prependee. - if (self === list.head) { - list.head = item; - } - - // If the the parent list has no last item, link the lists last item to - // self. - if (!list.tail) { - list.tail = self; - } - - // Return the prependee. - return item; -}; - -/** - * Appends the given item *after* the item operated on. - * @name ListItem#append - * @param {ListItem} item - The item to append. - * @returns {ListItem} - The item operated on, or false when that item is not - * attached. - */ -ListItemPrototype.append = function (item) { - // If item is falsey, return false. - if (!item || !item.append || !item.prepend || !item.detach) { - throw new Error(errorMessage + 'Item#append`.'); - } - - // Cache self, the parent list, and the next item. - var self = this, - list = self.list, - next = self.next; - - // If self is detached, return false. - if (!list) { - return false; - } - - // Detach the appendee. - item.detach(); - - // If self has a next item... - if (next) { - // ...link the appendees next item, to selfs next item. - item.next = next; - - // ...link the next items previous item, to the appendee. - next.prev = item; - } - - // Set the appendees previous item to self. - item.prev = self; - - // Set the appendees parent list to selfs parent list. - item.list = list; - - // Set the next item of self to the appendee. - self.next = item; - - // If the the parent list has no last item or if self is the parent lists - // last item, link the lists last item to the appendee. - if (self === list.tail || !list.tail) { - list.tail = item; - } - - // Return the appendee. - return item; -}; - -/** - * Expose `List`. - */ - -module.exports = List; - -},{}],15:[function(require,module,exports){ -'use strict'; - -module.exports = require('./_source/linked-list.js'); - -},{"./_source/linked-list.js":14}],16:[function(require,module,exports){ -(function (global){ -/** - * lodash (Custom Build) - * Build: `lodash modularize exports="npm" -o ./` - * Copyright jQuery Foundation and other contributors - * Released under MIT license - * Based on Underscore.js 1.8.3 - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ - -/** Used as the size to enable large array optimizations. */ -var LARGE_ARRAY_SIZE = 200; - -/** Used to stand-in for `undefined` hash values. */ -var HASH_UNDEFINED = '__lodash_hash_undefined__'; - -/** Used as references for various `Number` constants. */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - weakMapTag = '[object WeakMap]'; - -var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - -/** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). - */ -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - -/** Used to match `RegExp` flags from their coerced string values. */ -var reFlags = /\w*$/; - -/** Used to detect host constructors (Safari). */ -var reIsHostCtor = /^\[object .+?Constructor\]$/; - -/** Used to detect unsigned integer values. */ -var reIsUint = /^(?:0|[1-9]\d*)$/; - -/** Used to identify `toStringTag` values supported by `_.clone`. */ -var cloneableTags = {}; -cloneableTags[argsTag] = cloneableTags[arrayTag] = -cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = -cloneableTags[boolTag] = cloneableTags[dateTag] = -cloneableTags[float32Tag] = cloneableTags[float64Tag] = -cloneableTags[int8Tag] = cloneableTags[int16Tag] = -cloneableTags[int32Tag] = cloneableTags[mapTag] = -cloneableTags[numberTag] = cloneableTags[objectTag] = -cloneableTags[regexpTag] = cloneableTags[setTag] = -cloneableTags[stringTag] = cloneableTags[symbolTag] = -cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = -cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; -cloneableTags[errorTag] = cloneableTags[funcTag] = -cloneableTags[weakMapTag] = false; - -/** Detect free variable `global` from Node.js. */ -var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - -/** Detect free variable `self`. */ -var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - -/** Used as a reference to the global object. */ -var root = freeGlobal || freeSelf || Function('return this')(); - -/** Detect free variable `exports`. */ -var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - -/** Detect free variable `module`. */ -var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - -/** Detect the popular CommonJS extension `module.exports`. */ -var moduleExports = freeModule && freeModule.exports === freeExports; - -/** - * Adds the key-value `pair` to `map`. - * - * @private - * @param {Object} map The map to modify. - * @param {Array} pair The key-value pair to add. - * @returns {Object} Returns `map`. - */ -function addMapEntry(map, pair) { - // Don't return `map.set` because it's not chainable in IE 11. - map.set(pair[0], pair[1]); - return map; -} - -/** - * Adds `value` to `set`. - * - * @private - * @param {Object} set The set to modify. - * @param {*} value The value to add. - * @returns {Object} Returns `set`. - */ -function addSetEntry(set, value) { - // Don't return `set.add` because it's not chainable in IE 11. - set.add(value); - return set; -} - -/** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ -function arrayEach(array, iteratee) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; -} - -/** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ -function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; -} - -/** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ -function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array ? array.length : 0; - - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; -} - -/** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ -function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; -} - -/** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ -function getValue(object, key) { - return object == null ? undefined : object[key]; -} - -/** - * Checks if `value` is a host object in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a host object, else `false`. - */ -function isHostObject(value) { - // Many host objects are `Object` objects that can coerce to strings - // despite having improperly defined `toString` methods. - var result = false; - if (value != null && typeof value.toString != 'function') { - try { - result = !!(value + ''); - } catch (e) {} - } - return result; -} - -/** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ -function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; -} - -/** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ -function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; -} - -/** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ -function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; -} - -/** Used for built-in method references. */ -var arrayProto = Array.prototype, - funcProto = Function.prototype, - objectProto = Object.prototype; - -/** Used to detect overreaching core-js shims. */ -var coreJsData = root['__core-js_shared__']; - -/** Used to detect methods masquerading as native. */ -var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; -}()); - -/** Used to resolve the decompiled source of functions. */ -var funcToString = funcProto.toString; - -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; - -/** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ -var objectToString = objectProto.toString; - -/** Used to detect if a method is native. */ -var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); - -/** Built-in value references. */ -var Buffer = moduleExports ? root.Buffer : undefined, - Symbol = root.Symbol, - Uint8Array = root.Uint8Array, - getPrototype = overArg(Object.getPrototypeOf, Object), - objectCreate = Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice; - -/* Built-in method references for those with the same name as other `lodash` methods. */ -var nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeKeys = overArg(Object.keys, Object); - -/* Built-in method references that are verified to be native. */ -var DataView = getNative(root, 'DataView'), - Map = getNative(root, 'Map'), - Promise = getNative(root, 'Promise'), - Set = getNative(root, 'Set'), - WeakMap = getNative(root, 'WeakMap'), - nativeCreate = getNative(Object, 'create'); - -/** Used to detect maps, sets, and weakmaps. */ -var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - -/** Used to convert symbols to primitives and strings. */ -var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; - -/** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Hash(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; -} - -/** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; -} - -/** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; -} - -/** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function hashHas(key) { - var data = this.__data__; - return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); -} - -/** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ -function hashSet(key, value) { - var data = this.__data__; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; -} - -// Add methods to `Hash`. -Hash.prototype.clear = hashClear; -Hash.prototype['delete'] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; - -/** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function ListCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ -function listCacheClear() { - this.__data__ = []; -} - -/** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - return true; -} - -/** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; -} - -/** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} - -/** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ -function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; -} - -// Add methods to `ListCache`. -ListCache.prototype.clear = listCacheClear; -ListCache.prototype['delete'] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; - -/** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function MapCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } -} - -/** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ -function mapCacheClear() { - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; -} - -/** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function mapCacheDelete(key) { - return getMapData(this, key)['delete'](key); -} - -/** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} - -/** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} - -/** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ -function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; -} - -// Add methods to `MapCache`. -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype['delete'] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; - -/** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ -function Stack(entries) { - this.__data__ = new ListCache(entries); -} - -/** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ -function stackClear() { - this.__data__ = new ListCache; -} - -/** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ -function stackDelete(key) { - return this.__data__['delete'](key); -} - -/** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ -function stackGet(key) { - return this.__data__.get(key); -} - -/** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ -function stackHas(key) { - return this.__data__.has(key); -} - -/** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ -function stackSet(key, value) { - var cache = this.__data__; - if (cache instanceof ListCache) { - var pairs = cache.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - return this; - } - cache = this.__data__ = new MapCache(pairs); - } - cache.set(key, value); - return this; -} - -// Add methods to `Stack`. -Stack.prototype.clear = stackClear; -Stack.prototype['delete'] = stackDelete; -Stack.prototype.get = stackGet; -Stack.prototype.has = stackHas; -Stack.prototype.set = stackSet; - -/** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ -function arrayLikeKeys(value, inherited) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - // Safari 9 makes `arguments.length` enumerable in strict mode. - var result = (isArray(value) || isArguments(value)) - ? baseTimes(value.length, String) - : []; - - var length = result.length, - skipIndexes = !!length; - - for (var key in value) { - if ((inherited || hasOwnProperty.call(value, key)) && - !(skipIndexes && (key == 'length' || isIndex(key, length)))) { - result.push(key); - } - } - return result; -} - -/** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ -function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - object[key] = value; - } -} - -/** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ -function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; -} - -/** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ -function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); -} - -/** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {boolean} [isFull] Specify a clone including symbols. - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ -function baseClone(value, isDeep, isFull, customizer, key, object, stack) { - var result; - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - if (isHostObject(value)) { - return object ? value : {}; - } - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, baseClone, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (!isArr) { - var props = isFull ? getAllKeys(value) : keys(value); - } - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); - }); - return result; -} - -/** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ -function baseCreate(proto) { - return isObject(proto) ? objectCreate(proto) : {}; -} - -/** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ -function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); -} - -/** - * The base implementation of `getTag`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -function baseGetTag(value) { - return objectToString.call(value); -} - -/** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ -function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} - -/** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; -} - -/** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ -function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var result = new buffer.constructor(buffer.length); - buffer.copy(result); - return result; -} - -/** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ -function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; -} - -/** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ -function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); -} - -/** - * Creates a clone of `map`. - * - * @private - * @param {Object} map The map to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned map. - */ -function cloneMap(map, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); - return arrayReduce(array, addMapEntry, new map.constructor); -} - -/** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ -function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; -} - -/** - * Creates a clone of `set`. - * - * @private - * @param {Object} set The set to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned set. - */ -function cloneSet(set, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); - return arrayReduce(array, addSetEntry, new set.constructor); -} - -/** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ -function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; -} - -/** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ -function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); -} - -/** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ -function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; -} - -/** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ -function copyObject(source, props, object, customizer) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - assignValue(object, key, newValue === undefined ? source[key] : newValue); - } - return object; -} - -/** - * Copies own symbol properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ -function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); -} - -/** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ -function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); -} - -/** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ -function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; -} - -/** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ -function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; -} - -/** - * Creates an array of the own enumerable symbol properties of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ -var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; - -/** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ -var getTag = baseGetTag; - -// Fallback for data views, maps, sets, and weak maps in IE 11, -// for data views in Edge < 14, and promises in Node.js. -if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = objectToString.call(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : undefined; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; -} - -/** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ -function initCloneArray(array) { - var length = array.length, - result = array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; -} - -/** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; -} - -/** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ -function initCloneByTag(object, tag, cloneFunc, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case dataViewTag: - return cloneDataView(object, isDeep); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); - - case mapTag: - return cloneMap(object, isDeep, cloneFunc); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - return cloneRegExp(object); - - case setTag: - return cloneSet(object, isDeep, cloneFunc); - - case symbolTag: - return cloneSymbol(object); - } -} - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); -} - -/** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ -function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); -} - -/** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ -function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); -} - -/** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ -function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; -} - -/** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to process. - * @returns {string} Returns the source code. - */ -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; -} - -/** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ -function cloneDeep(value) { - return baseClone(value, true, true); -} - -/** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ -function eq(value, other) { - return value === other || (value !== value && other !== other); -} - -/** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ -function isArguments(value) { - // Safari 8.1 makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); -} - -/** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ -var isArray = Array.isArray; - -/** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ -function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); -} - -/** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ -function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); -} - -/** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ -var isBuffer = nativeIsBuffer || stubFalse; - -/** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ -function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8-9 which returns 'object' for typed array and other constructors. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ -function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ -function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -/** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ -function isObjectLike(value) { - return !!value && typeof value == 'object'; -} - -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); -} - -/** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ -function stubArray() { - return []; -} - -/** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ -function stubFalse() { - return false; -} - -module.exports = cloneDeep; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],17:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } - - var regexp = /\+/g; - qs = qs.split(sep); - - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; - } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; - } - - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } - - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); - - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } - } - - return obj; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{}],18:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - - case 'boolean': - return v ? 'true' : 'false'; - - case 'number': - return isFinite(v) ? v : ''; - - default: - return ''; - } -}; - -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return map(obj[k], function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); - - } - - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} - -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; - -},{}],19:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); - -},{"./decode":17,"./encode":18}],20:[function(require,module,exports){ -// Based on https://github.com/dscape/cycle/blob/master/cycle.js - -module.exports = function decycle(object) { -// Make a deep copy of an object or array, assuring that there is at most -// one instance of each object or array in the resulting structure. The -// duplicate references (which might be forming cycles) are replaced with -// an object of the form -// {$ref: PATH} -// where the PATH is a JSONPath string that locates the first occurance. -// So, -// var a = []; -// a[0] = a; -// return JSON.stringify(JSON.decycle(a)); -// produces the string '[{"$ref":"$"}]'. - -// JSONPath is used to locate the unique object. $ indicates the top level of -// the object or array. [NUMBER] or [STRING] indicates a child member or -// property. - - var objects = [], // Keep a reference to each unique object or array - paths = []; // Keep the path to each unique object or array - - return (function derez(value, path) { - -// The derez recurses through the object, producing the deep copy. - - var i, // The loop counter - name, // Property name - nu; // The new object or array - -// typeof null === 'object', so go on if this value is really an object but not -// one of the weird builtin objects. - - if (typeof value === 'object' && value !== null && - !(value instanceof Boolean) && - !(value instanceof Date) && - !(value instanceof Number) && - !(value instanceof RegExp) && - !(value instanceof String)) { - -// If the value is an object or array, look to see if we have already -// encountered it. If so, return a $ref/path object. This is a hard way, -// linear search that will get slower as the number of unique objects grows. - - for (i = 0; i < objects.length; i += 1) { - if (objects[i] === value) { - return {$ref: paths[i]}; - } - } - -// Otherwise, accumulate the unique value and its path. - - objects.push(value); - paths.push(path); - -// If it is an array, replicate the array. - - if (Object.prototype.toString.apply(value) === '[object Array]') { - nu = []; - for (i = 0; i < value.length; i += 1) { - nu[i] = derez(value[i], path + '[' + i + ']'); - } - } else { - -// If it is an object, replicate the object. - - nu = {}; - for (name in value) { - if (Object.prototype.hasOwnProperty.call(value, name)) { - nu[name] = derez(value[name], - path + '[' + JSON.stringify(name) + ']'); - } - } - } - return nu; - } - return value; - }(object, '$')); -}; - -},{}],21:[function(require,module,exports){ -var decycle = require('./decycle'); - -var isStrict = (function () { return !this; })(); - -function AuthTokenExpiredError(message, expiry) { - this.name = 'AuthTokenExpiredError'; - this.message = message; - this.expiry = expiry; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -AuthTokenExpiredError.prototype = Object.create(Error.prototype); - - -function AuthTokenInvalidError(message) { - this.name = 'AuthTokenInvalidError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -AuthTokenInvalidError.prototype = Object.create(Error.prototype); - - -function AuthTokenNotBeforeError(message, date) { - this.name = 'AuthTokenNotBeforeError'; - this.message = message; - this.date = date; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -AuthTokenNotBeforeError.prototype = Object.create(Error.prototype); - - -// For any other auth token error. -function AuthTokenError(message) { - this.name = 'AuthTokenError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -AuthTokenError.prototype = Object.create(Error.prototype); - -// For any other auth error; not specifically related to the auth token itself. -function AuthError(message) { - this.name = 'AuthError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -AuthError.prototype = Object.create(Error.prototype); - - -function SilentMiddlewareBlockedError(message, type) { - this.name = 'SilentMiddlewareBlockedError'; - this.message = message; - this.type = type; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -SilentMiddlewareBlockedError.prototype = Object.create(Error.prototype); - - -function InvalidActionError(message) { - this.name = 'InvalidActionError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -InvalidActionError.prototype = Object.create(Error.prototype); - -function InvalidArgumentsError(message) { - this.name = 'InvalidArgumentsError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -InvalidArgumentsError.prototype = Object.create(Error.prototype); - -function InvalidOptionsError(message) { - this.name = 'InvalidOptionsError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -InvalidOptionsError.prototype = Object.create(Error.prototype); - - -function InvalidMessageError(message) { - this.name = 'InvalidMessageError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -InvalidMessageError.prototype = Object.create(Error.prototype); - - -function SocketProtocolError(message, code) { - this.name = 'SocketProtocolError'; - this.message = message; - this.code = code; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -SocketProtocolError.prototype = Object.create(Error.prototype); - - -function ServerProtocolError(message) { - this.name = 'ServerProtocolError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -ServerProtocolError.prototype = Object.create(Error.prototype); - -function HTTPServerError(message) { - this.name = 'HTTPServerError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -HTTPServerError.prototype = Object.create(Error.prototype); - - -function ResourceLimitError(message) { - this.name = 'ResourceLimitError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -ResourceLimitError.prototype = Object.create(Error.prototype); - - -function TimeoutError(message) { - this.name = 'TimeoutError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -TimeoutError.prototype = Object.create(Error.prototype); - - -function BadConnectionError(message, type) { - this.name = 'BadConnectionError'; - this.message = message; - this.type = type; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -BadConnectionError.prototype = Object.create(Error.prototype); - - -function BrokerError(message) { - this.name = 'BrokerError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -BrokerError.prototype = Object.create(Error.prototype); - - -function ProcessExitError(message, code) { - this.name = 'ProcessExitError'; - this.message = message; - this.code = code; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -ProcessExitError.prototype = Object.create(Error.prototype); - - -function UnknownError(message) { - this.name = 'UnknownError'; - this.message = message; - if (Error.captureStackTrace && !isStrict) { - Error.captureStackTrace(this, arguments.callee); - } else { - this.stack = (new Error()).stack; - } -} -UnknownError.prototype = Object.create(Error.prototype); - - -// Expose all error types. - -module.exports = { - AuthTokenExpiredError: AuthTokenExpiredError, - AuthTokenInvalidError: AuthTokenInvalidError, - AuthTokenNotBeforeError: AuthTokenNotBeforeError, - AuthTokenError: AuthTokenError, - AuthError: AuthError, - SilentMiddlewareBlockedError: SilentMiddlewareBlockedError, - InvalidActionError: InvalidActionError, - InvalidArgumentsError: InvalidArgumentsError, - InvalidOptionsError: InvalidOptionsError, - InvalidMessageError: InvalidMessageError, - SocketProtocolError: SocketProtocolError, - ServerProtocolError: ServerProtocolError, - HTTPServerError: HTTPServerError, - ResourceLimitError: ResourceLimitError, - TimeoutError: TimeoutError, - BadConnectionError: BadConnectionError, - BrokerError: BrokerError, - ProcessExitError: ProcessExitError, - UnknownError: UnknownError -}; - -module.exports.socketProtocolErrorStatuses = { - 1001: 'Socket was disconnected', - 1002: 'A WebSocket protocol error was encountered', - 1003: 'Server terminated socket because it received invalid data', - 1005: 'Socket closed without status code', - 1006: 'Socket hung up', - 1007: 'Message format was incorrect', - 1008: 'Encountered a policy violation', - 1009: 'Message was too big to process', - 1010: 'Client ended the connection because the server did not comply with extension requirements', - 1011: 'Server encountered an unexpected fatal condition', - 4000: 'Server ping timed out', - 4001: 'Client pong timed out', - 4002: 'Server failed to sign auth token', - 4003: 'Failed to complete handshake', - 4004: 'Client failed to save auth token', - 4005: 'Did not receive #handshake from client before timeout', - 4006: 'Failed to bind socket to message broker', - 4007: 'Client connection establishment timed out', - 4008: 'Server rejected handshake from client', - 4009: 'Server received a message before the client handshake' -}; - -module.exports.socketProtocolIgnoreStatuses = { - 1000: 'Socket closed normally', - 1001: 'Socket hung up' -}; - -// Properties related to error domains cannot be serialized. -var unserializableErrorProperties = { - domain: 1, - domainEmitter: 1, - domainThrown: 1 -}; - -// Convert an error into a JSON-compatible type which can later be hydrated -// back to its *original* form. -module.exports.dehydrateError = function dehydrateError(error, includeStackTrace) { - var dehydratedError; - - if (error && typeof error === 'object') { - dehydratedError = { - message: error.message - }; - if (includeStackTrace) { - dehydratedError.stack = error.stack; - } - for (var i in error) { - if (!unserializableErrorProperties[i]) { - dehydratedError[i] = error[i]; - } - } - } else if (typeof error === 'function') { - dehydratedError = '[function ' + (error.name || 'anonymous') + ']'; - } else { - dehydratedError = error; - } - - return decycle(dehydratedError); -}; - -// Convert a dehydrated error back to its *original* form. -module.exports.hydrateError = function hydrateError(error) { - var hydratedError = null; - if (error != null) { - if (typeof error === 'object') { - hydratedError = new Error(error.message); - for (var i in error) { - if (error.hasOwnProperty(i)) { - hydratedError[i] = error[i]; - } - } - } else { - hydratedError = error; - } - } - return hydratedError; -}; - -module.exports.decycle = decycle; - -},{"./decycle":20}],22:[function(require,module,exports){ -(function (global){ -var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -var validJSONStartRegex = /^[ \n\r\t]*[{\[]/; - -var arrayBufferToBase64 = function (arraybuffer) { - var bytes = new Uint8Array(arraybuffer); - var len = bytes.length; - var base64 = ''; - - for (var i = 0; i < len; i += 3) { - base64 += base64Chars[bytes[i] >> 2]; - base64 += base64Chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += base64Chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += base64Chars[bytes[i + 2] & 63]; - } - - if ((len % 3) === 2) { - base64 = base64.substring(0, base64.length - 1) + '='; - } else if (len % 3 === 1) { - base64 = base64.substring(0, base64.length - 2) + '=='; - } - - return base64; -}; - -var binaryToBase64Replacer = function (key, value) { - if (global.ArrayBuffer && value instanceof global.ArrayBuffer) { - return { - base64: true, - data: arrayBufferToBase64(value) - }; - } else if (global.Buffer) { - if (value instanceof global.Buffer){ - return { - base64: true, - data: value.toString('base64') - }; - } - // Some versions of Node.js convert Buffers to Objects before they are passed to - // the replacer function - Because of this, we need to rehydrate Buffers - // before we can convert them to base64 strings. - if (value && value.type === 'Buffer' && Array.isArray(value.data)) { - var rehydratedBuffer; - if (global.Buffer.from) { - rehydratedBuffer = global.Buffer.from(value.data); - } else { - rehydratedBuffer = new global.Buffer(value.data); - } - return { - base64: true, - data: rehydratedBuffer.toString('base64') - }; - } - } - return value; -}; - -// Decode the data which was transmitted over the wire to a JavaScript Object in a format which SC understands. -// See encode function below for more details. -module.exports.decode = function (input) { - if (input == null) { - return null; - } - // Leave ping or pong message as is - if (input === '#1' || input === '#2') { - return input; - } - var message = input.toString(); - - // Performance optimization to detect invalid JSON packet sooner. - if (!validJSONStartRegex.test(message)) { - return message; - } - - try { - return JSON.parse(message); - } catch (err) {} - return message; -}; - -// Encode a raw JavaScript object (which is in the SC protocol format) into a format for -// transfering it over the wire. In this case, we just convert it into a simple JSON string. -// If you want to create your own custom codec, you can encode the object into any format -// (e.g. binary ArrayBuffer or string with any kind of compression) so long as your decode -// function is able to rehydrate that object back into its original JavaScript Object format -// (which adheres to the SC protocol). -// See https://github.com/SocketCluster/socketcluster/blob/master/socketcluster-protocol.md -// for details about the SC protocol. -module.exports.encode = function (object) { - // Leave ping or pong message as is - if (object === '#1' || object === '#2') { - return object; - } - return JSON.stringify(object, binaryToBase64Replacer); -}; - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],23:[function(require,module,exports){ -const ConsumableStream = require('consumable-stream'); - -class DemuxedConsumableStream extends ConsumableStream { - constructor(streamDemux, name) { - super(); - this.name = name; - this._streamDemux = streamDemux; - } - - createConsumer(timeout) { - return this._streamDemux.createConsumer(this.name, timeout); - } -} - -module.exports = DemuxedConsumableStream; - -},{"consumable-stream":12}],24:[function(require,module,exports){ -const WritableConsumableStream = require('writable-consumable-stream'); -const DemuxedConsumableStream = require('./demuxed-consumable-stream'); - -class StreamDemux { - constructor() { - this._mainStream = new WritableConsumableStream(); - } - - write(streamName, value) { - this._mainStream.write({ - stream: streamName, - data: { - value, - done: false - } - }); - } - - close(streamName, value) { - this._mainStream.write({ - stream: streamName, - data: { - value, - done: true - } - }); - } - - closeAll(value) { - this._mainStream.close(value); - } - - writeToConsumer(consumerId, value) { - this._mainStream.writeToConsumer(consumerId, { - consumerId, - data: { - value, - done: false - } - }); - } - - closeConsumer(consumerId, value) { - this._mainStream.closeConsumer(consumerId, { - consumerId, - data: { - value, - done: true - } - }); - } - - getConsumerStats(consumerId) { - return this._mainStream.getConsumerStats(consumerId); - } - - getConsumerStatsList(streamName) { - let consumerList = this._mainStream.getConsumerStatsList(); - return consumerList.filter((consumerStats) => { - return consumerStats.stream === streamName; - }); - } - - getConsumerStatsListAll() { - return this._mainStream.getConsumerStatsList(); - } - - kill(streamName, value) { - let consumerList = this.getConsumerStatsList(streamName); - let len = consumerList.length; - for (let i = 0; i < len; i++) { - this.killConsumer(consumerList[i].id, value); - } - } - - killAll(value) { - this._mainStream.kill(value); - } - - killConsumer(consumerId, value) { - this._mainStream.killConsumer(consumerId, value); - } - - getBackpressure(streamName) { - let consumerList = this.getConsumerStatsList(streamName); - let len = consumerList.length; - - let maxBackpressure = 0; - for (let i = 0; i < len; i++) { - let consumer = consumerList[i]; - if (consumer.backpressure > maxBackpressure) { - maxBackpressure = consumer.backpressure; - } - } - return maxBackpressure; - } - - getBackpressureAll() { - return this._mainStream.getBackpressure(); - } - - getConsumerBackpressure(consumerId) { - return this._mainStream.getConsumerBackpressure(consumerId); - } - - hasConsumer(streamName, consumerId) { - let consumerStats = this._mainStream.getConsumerStats(consumerId); - return !!consumerStats && consumerStats.stream === streamName; - } - - hasConsumerAll(consumerId) { - return this._mainStream.hasConsumer(consumerId); - } - - createConsumer(streamName, timeout) { - let mainStreamConsumer = this._mainStream.createConsumer(timeout); - - let consumerNext = mainStreamConsumer.next; - mainStreamConsumer.next = async function () { - while (true) { - let packet = await consumerNext.apply(this, arguments); - if (packet.value) { - if ( - packet.value.stream === streamName || - packet.value.consumerId === this.id - ) { - if (packet.value.data.done) { - this.return(); - } - return packet.value.data; - } - } - if (packet.done) { - return packet; - } - } - }; - - let consumerGetStats = mainStreamConsumer.getStats; - mainStreamConsumer.getStats = function () { - let stats = consumerGetStats.apply(this, arguments); - stats.stream = streamName; - return stats; - }; - - let consumerApplyBackpressure = mainStreamConsumer.applyBackpressure; - mainStreamConsumer.applyBackpressure = function (packet) { - if (packet.value) { - if ( - packet.value.stream === streamName || - packet.value.consumerId === this.id - ) { - consumerApplyBackpressure.apply(this, arguments); - - return; - } - } - if (packet.done) { - consumerApplyBackpressure.apply(this, arguments); - } - }; - - let consumerReleaseBackpressure = mainStreamConsumer.releaseBackpressure; - mainStreamConsumer.releaseBackpressure = function (packet) { - if (packet.value) { - if ( - packet.value.stream === streamName || - packet.value.consumerId === this.id - ) { - consumerReleaseBackpressure.apply(this, arguments); - - return; - } - } - if (packet.done) { - consumerReleaseBackpressure.apply(this, arguments); - } - }; - - return mainStreamConsumer; - } - - stream(streamName) { - return new DemuxedConsumableStream(this, streamName); - } -} - -module.exports = StreamDemux; - -},{"./demuxed-consumable-stream":23,"writable-consumable-stream":31}],25:[function(require,module,exports){ -var v1 = require('./v1'); -var v4 = require('./v4'); - -var uuid = v4; -uuid.v1 = v1; -uuid.v4 = v4; - -module.exports = uuid; - -},{"./v1":28,"./v4":29}],26:[function(require,module,exports){ -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([ - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]] - ]).join(''); -} - -module.exports = bytesToUuid; - -},{}],27:[function(require,module,exports){ -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - -},{}],28:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -// **`v1()` - Generate time-based UUID** -// -// Inspired by https://github.com/LiosK/UUID.js -// and http://docs.python.org/library/uuid.html - -var _nodeId; -var _clockseq; - -// Previous uuid creation time -var _lastMSecs = 0; -var _lastNSecs = 0; - -// See https://github.com/uuidjs/uuid for API details -function v1(options, buf, offset) { - var i = buf && offset || 0; - var b = buf || []; - - options = options || {}; - var node = options.node || _nodeId; - var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; - - // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 - if (node == null || clockseq == null) { - var seedBytes = rng(); - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5] - ]; - } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; - } - } - - // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. - var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime(); - - // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock - var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; - - // Time since last uuid creation (in msecs) - var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000; - - // Per 4.2.1.2, Bump clockseq on clock regression - if (dt < 0 && options.clockseq === undefined) { - clockseq = clockseq + 1 & 0x3fff; - } - - // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0; - } - - // Per 4.2.1.2 Throw error if too many uuids are requested - if (nsecs >= 10000) { - throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec'); - } - - _lastMSecs = msecs; - _lastNSecs = nsecs; - _clockseq = clockseq; - - // Per 4.1.4 - Convert from unix epoch to Gregorian epoch - msecs += 12219292800000; - - // `time_low` - var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; - b[i++] = tl >>> 24 & 0xff; - b[i++] = tl >>> 16 & 0xff; - b[i++] = tl >>> 8 & 0xff; - b[i++] = tl & 0xff; - - // `time_mid` - var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff; - b[i++] = tmh >>> 8 & 0xff; - b[i++] = tmh & 0xff; - - // `time_high_and_version` - b[i++] = tmh >>> 24 & 0xf | 0x10; // include version - b[i++] = tmh >>> 16 & 0xff; - - // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) - b[i++] = clockseq >>> 8 | 0x80; - - // `clock_seq_low` - b[i++] = clockseq & 0xff; - - // `node` - for (var n = 0; n < 6; ++n) { - b[i + n] = node[n]; - } - - return buf ? buf : bytesToUuid(b); -} - -module.exports = v1; - -},{"./lib/bytesToUuid":26,"./lib/rng":27}],29:[function(require,module,exports){ -var rng = require('./lib/rng'); -var bytesToUuid = require('./lib/bytesToUuid'); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - -},{"./lib/bytesToUuid":26,"./lib/rng":27}],30:[function(require,module,exports){ -class Consumer { - constructor(stream, id, startNode, timeout) { - this.id = id; - this._backpressure = 0; - this.stream = stream; - this.currentNode = startNode; - this.timeout = timeout; - this._isIterating = false; - this.stream.setConsumer(this.id, this); - } - - getStats() { - let stats = { - id: this.id, - backpressure: this._backpressure - }; - if (this.timeout != null) { - stats.timeout = this.timeout; - } - return stats; - } - - resetBackpressure() { - this._backpressure = 0; - } - - applyBackpressure(packet) { - this._backpressure++; - } - - releaseBackpressure(packet) { - this._backpressure--; - } - - getBackpressure() { - return this._backpressure; - } - - write(packet) { - if (this._timeoutId !== undefined) { - clearTimeout(this._timeoutId); - delete this._timeoutId; - } - this.applyBackpressure(packet); - if (this._resolve) { - this._resolve(); - delete this._resolve; - } - } - - kill(value) { - if (this._timeoutId !== undefined) { - clearTimeout(this._timeoutId); - delete this._timeoutId; - } - if (this._isIterating) { - this._killPacket = {value, done: true}; - this.applyBackpressure(this._killPacket); - } else { - this.stream.removeConsumer(this.id); - this.resetBackpressure(); - } - if (this._resolve) { - this._resolve(); - delete this._resolve; - } - } - - async _waitForNextItem(timeout) { - return new Promise((resolve, reject) => { - this._resolve = resolve; - let timeoutId; - if (timeout !== undefined) { - // Create the error object in the outer scope in order - // to get the full stack trace. - let error = new Error('Stream consumer iteration timed out'); - (async () => { - let delay = wait(timeout); - timeoutId = delay.timeoutId; - await delay.promise; - error.name = 'TimeoutError'; - delete this._resolve; - reject(error); - })(); - } - this._timeoutId = timeoutId; - }); - } - - async next() { - this._isIterating = true; - this.stream.setConsumer(this.id, this); - - while (true) { - if (!this.currentNode.next) { - try { - await this._waitForNextItem(this.timeout); - } catch (error) { - this._isIterating = false; - this.stream.removeConsumer(this.id); - throw error; - } - } - if (this._killPacket) { - this._isIterating = false; - this.stream.removeConsumer(this.id); - this.resetBackpressure(); - let killPacket = this._killPacket; - delete this._killPacket; - - return killPacket; - } - - this.currentNode = this.currentNode.next; - this.releaseBackpressure(this.currentNode.data); - - if (this.currentNode.consumerId && this.currentNode.consumerId !== this.id) { - continue; - } - - if (this.currentNode.data.done) { - this._isIterating = false; - this.stream.removeConsumer(this.id); - } - - return this.currentNode.data; - } - } - - return() { - delete this.currentNode; - this._isIterating = false; - this.stream.removeConsumer(this.id); - this.resetBackpressure(); - return {}; - } -} - -function wait(timeout) { - let timeoutId; - let promise = new Promise((resolve) => { - timeoutId = setTimeout(resolve, timeout); - }); - return {timeoutId, promise}; -} - -module.exports = Consumer; - -},{}],31:[function(require,module,exports){ -const ConsumableStream = require('consumable-stream'); -const Consumer = require('./consumer'); - -class WritableConsumableStream extends ConsumableStream { - constructor() { - super(); - this.nextConsumerId = 1; - this._consumers = {}; - - // Tail node of a singly linked list. - this._tailNode = { - next: null, - data: { - value: undefined, - done: false - } - }; - } - - _write(value, done, consumerId) { - let dataNode = { - data: {value, done}, - next: null - }; - if (consumerId) { - dataNode.consumerId = consumerId; - } - this._tailNode.next = dataNode; - this._tailNode = dataNode; - - let consumerList = Object.values(this._consumers); - let len = consumerList.length; - - for (let i = 0; i < len; i++) { - let consumer = consumerList[i]; - consumer.write(dataNode.data); - } - } - - write(value) { - this._write(value, false); - } - - close(value) { - this._write(value, true); - } - - writeToConsumer(consumerId, value) { - this._write(value, false, consumerId); - } - - closeConsumer(consumerId, value) { - this._write(value, true, consumerId); - } - - kill(value) { - let consumerIdList = Object.keys(this._consumers); - let len = consumerIdList.length; - for (let i = 0; i < len; i++) { - this.killConsumer(consumerIdList[i], value); - } - } - - killConsumer(consumerId, value) { - let consumer = this._consumers[consumerId]; - if (!consumer) { - return; - } - consumer.kill(value); - } - - getBackpressure() { - let consumerList = Object.values(this._consumers); - let len = consumerList.length; - - let maxBackpressure = 0; - for (let i = 0; i < len; i++) { - let consumer = consumerList[i]; - let backpressure = consumer.getBackpressure(); - if (backpressure > maxBackpressure) { - maxBackpressure = backpressure; - } - } - return maxBackpressure; - } - - getConsumerBackpressure(consumerId) { - let consumer = this._consumers[consumerId]; - if (consumer) { - return consumer.getBackpressure(); - } - return 0; - } - - hasConsumer(consumerId) { - return !!this._consumers[consumerId]; - } - - setConsumer(consumerId, consumer) { - this._consumers[consumerId] = consumer; - if (!consumer.currentNode) { - consumer.currentNode = this._tailNode; - } - } - - removeConsumer(consumerId) { - delete this._consumers[consumerId]; - } - - getConsumerStats(consumerId) { - let consumer = this._consumers[consumerId]; - if (consumer) { - return consumer.getStats(); - } - return undefined; - } - - getConsumerStatsList() { - let consumerStats = []; - let consumerList = Object.values(this._consumers); - let len = consumerList.length; - for (let i = 0; i < len; i++) { - let consumer = consumerList[i]; - consumerStats.push(consumer.getStats()); - } - return consumerStats; - } - - createConsumer(timeout) { - return new Consumer(this, this.nextConsumerId++, this._tailNode, timeout); - } -} - -module.exports = WritableConsumableStream; - -},{"./consumer":30,"consumable-stream":12}],"socketcluster-client":[function(require,module,exports){ -const AGClientSocket = require('./lib/clientsocket'); -const factory = require('./lib/factory'); -const version = '15.0.0'; - -module.exports.factory = factory; -module.exports.AGClientSocket = AGClientSocket; - -module.exports.create = function (options) { - return factory.create({...options, version}); -}; - -module.exports.version = version; - -},{"./lib/clientsocket":2,"./lib/factory":3}]},{},["socketcluster-client"])("socketcluster-client") -}); diff --git a/app/public/socketcluster-client.min.js b/app/public/socketcluster-client.min.js new file mode 100644 index 00000000..509d8692 --- /dev/null +++ b/app/public/socketcluster-client.min.js @@ -0,0 +1,21 @@ +function t(t,e){return e.forEach((function(e){e&&"string"!=typeof e&&!Array.isArray(e)&&Object.keys(e).forEach((function(r){if("default"!==r&&!(r in t)){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}}))})),Object.freeze(t)}function e(t){if(t.__esModule)return t;var e=t.default;if("function"==typeof e){var r=function t(){return this instanceof t?Reflect.construct(e,arguments,this.constructor):e.apply(this,arguments)};r.prototype=e.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(t).forEach((function(e){var n=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(r,e,n.get?n:{enumerable:!0,get:function(){return t[e]}})})),r}var r={};var n=class{async next(t){let e=this.createConsumer(t),r=await e.next();return e.return(),r}async once(t){let e=await this.next(t);if(e.done){if(null!=t){let t=new Error("Stream consumer operation timed out early because stream ended");throw t.name="TimeoutError",t}await new Promise((()=>{}))}return e.value}createConsumer(){throw new TypeError("Method must be overriden by subclass")}[Symbol.asyncIterator](){return this.createConsumer()}};let o=class{constructor(t,e,r,n){this.id=e,this._backpressure=0,this.currentNode=r,this.timeout=n,this.isAlive=!0,this.stream=t,this.stream.setConsumer(this.id,this)}getStats(){let t={id:this.id,backpressure:this._backpressure};return null!=this.timeout&&(t.timeout=this.timeout),t}_resetBackpressure(){this._backpressure=0}applyBackpressure(t){this._backpressure++}releaseBackpressure(t){this._backpressure--}getBackpressure(){return this._backpressure}clearActiveTimeout(){clearTimeout(this._timeoutId),delete this._timeoutId}write(t){void 0!==this._timeoutId&&this.clearActiveTimeout(t),this.applyBackpressure(t),this._resolve&&(this._resolve(),delete this._resolve)}kill(t){this._killPacket={value:t,done:!0},void 0!==this._timeoutId&&this.clearActiveTimeout(this._killPacket),this._destroy(),this._resolve&&(this._resolve(),delete this._resolve)}_destroy(){this.isAlive=!1,this._resetBackpressure(),this.stream.removeConsumer(this.id)}async _waitForNextItem(t){return new Promise(((e,r)=>{let n;if(this._resolve=e,void 0!==t){let e=new Error("Stream consumer iteration timed out");(async()=>{let o=function(t){let e,r=new Promise((r=>{e=setTimeout(r,t)}));return{timeoutId:e,promise:r}}(t);n=o.timeoutId,await o.promise,e.name="TimeoutError",delete this._resolve,r(e)})()}this._timeoutId=n}))}async next(){for(this.stream.setConsumer(this.id,this);;){if(!this.currentNode.next)try{await this._waitForNextItem(this.timeout)}catch(t){throw this._destroy(),t}if(this._killPacket){this._destroy();let t=this._killPacket;return delete this._killPacket,t}if(this.currentNode=this.currentNode.next,this.releaseBackpressure(this.currentNode.data),!this.currentNode.consumerId||this.currentNode.consumerId===this.id)return this.currentNode.data.done&&this._destroy(),this.currentNode.data}}return(){return delete this.currentNode,this._destroy(),{}}[Symbol.asyncIterator](){return this}};const i=n,s=o;var a=class extends i{constructor(t){super(),t=t||{},this._nextConsumerId=1,this.generateConsumerId=t.generateConsumerId,this.generateConsumerId||(this.generateConsumerId=()=>this._nextConsumerId++),this.removeConsumerCallback=t.removeConsumerCallback,this._consumers=new Map,this.tailNode={next:null,data:{value:void 0,done:!1}}}_write(t,e,r){let n={data:{value:t,done:e},next:null};r&&(n.consumerId=r),this.tailNode.next=n,this.tailNode=n;for(let t of this._consumers.values())t.write(n.data)}write(t){this._write(t,!1)}close(t){this._write(t,!0)}writeToConsumer(t,e){this._write(e,!1,t)}closeConsumer(t,e){this._write(e,!0,t)}kill(t){for(let e of this._consumers.keys())this.killConsumer(e,t)}killConsumer(t,e){let r=this._consumers.get(t);r&&r.kill(e)}getBackpressure(){let t=0;for(let e of this._consumers.values()){let r=e.getBackpressure();r>t&&(t=r)}return t}getConsumerBackpressure(t){let e=this._consumers.get(t);return e?e.getBackpressure():0}hasConsumer(t){return this._consumers.has(t)}setConsumer(t,e){this._consumers.set(t,e),e.currentNode||(e.currentNode=this.tailNode)}removeConsumer(t){let e=this._consumers.delete(t);return this.removeConsumerCallback&&this.removeConsumerCallback(t),e}getConsumerStats(t){let e=this._consumers.get(t);if(e)return e.getStats()}getConsumerStatsList(){let t=[];for(let e of this._consumers.values())t.push(e.getStats());return t}createConsumer(t){return new s(this,this.generateConsumerId(),this.tailNode,t)}getConsumerList(){return[...this._consumers.values()]}getConsumerCount(){return this._consumers.size}};const u=class{async next(t){let e=this.createConsumer(t),r=await e.next();return e.return(),r}async once(t){let e=await this.next(t);if(e.done){if(null!=t){let t=new Error("Stream consumer operation timed out early because stream ended");throw t.name="TimeoutError",t}await new Promise((()=>{}))}return e.value}createConsumer(){throw new TypeError("Method must be overriden by subclass")}[Symbol.asyncIterator](){return this.createConsumer()}};var c=class extends u{constructor(t,e){super(),this._streamDemux=t,this.name=e}createConsumer(t){return this._streamDemux.createConsumer(this.name,t)}};const h=a,l=c;var p=class{constructor(){this.streams={},this._nextConsumerId=1,this.generateConsumerId=()=>this._nextConsumerId++}write(t,e){this.streams[t]&&this.streams[t].write(e)}close(t,e){this.streams[t]&&this.streams[t].close(e)}closeAll(t){for(let e of Object.values(this.streams))e.close(t)}writeToConsumer(t,e){for(let r of Object.values(this.streams))if(r.hasConsumer(t))return r.writeToConsumer(t,e)}closeConsumer(t,e){for(let r of Object.values(this.streams))if(r.hasConsumer(t))return r.closeConsumer(t,e)}getConsumerStats(t){for(let[e,r]of Object.entries(this.streams))if(r.hasConsumer(t))return{...r.getConsumerStats(t),stream:e}}getConsumerStatsList(t){return this.streams[t]?this.streams[t].getConsumerStatsList().map((e=>({...e,stream:t}))):[]}getConsumerStatsListAll(){let t=[];for(let e of Object.keys(this.streams)){let r=this.getConsumerStatsList(e);for(let e of r)t.push(e)}return t}kill(t,e){this.streams[t]&&this.streams[t].kill(e)}killAll(t){for(let e of Object.values(this.streams))e.kill(t)}killConsumer(t,e){for(let r of Object.values(this.streams))if(r.hasConsumer(t))return r.killConsumer(t,e)}getBackpressure(t){return this.streams[t]?this.streams[t].getBackpressure():0}getBackpressureAll(){return Object.values(this.streams).reduce(((t,e)=>Math.max(t,e.getBackpressure())),0)}getConsumerBackpressure(t){for(let e of Object.values(this.streams))if(e.hasConsumer(t))return e.getConsumerBackpressure(t);return 0}hasConsumer(t,e){return!!this.streams[t]&&this.streams[t].hasConsumer(e)}hasConsumerAll(t){return Object.values(this.streams).some((e=>e.hasConsumer(t)))}getConsumerCount(t){return this.streams[t]?this.streams[t].getConsumerCount():0}getConsumerCountAll(){return Object.values(this.streams).reduce(((t,e)=>t+e.getConsumerCount()),0)}createConsumer(t,e){return this.streams[t]||(this.streams[t]=new h({generateConsumerId:this.generateConsumerId,removeConsumerCallback:()=>{this.getConsumerCount(t)||delete this.streams[t]}})),this.streams[t].createConsumer(e)}stream(t){return new l(this,t)}unstream(t){delete this.streams[t]}};const f=p;function m(t){this._listenerDemux=new f}m.prototype.emit=function(t,e){this._listenerDemux.write(t,e)},m.prototype.listener=function(t){return this._listenerDemux.stream(t)},m.prototype.closeListener=function(t){this._listenerDemux.close(t)},m.prototype.closeAllListeners=function(){this._listenerDemux.closeAll()},m.prototype.removeListener=function(t){this._listenerDemux.unstream(t)},m.prototype.getListenerConsumerStats=function(t){return this._listenerDemux.getConsumerStats(t)},m.prototype.getListenerConsumerStatsList=function(t){return this._listenerDemux.getConsumerStatsList(t)},m.prototype.getAllListenersConsumerStatsList=function(){return this._listenerDemux.getConsumerStatsListAll()},m.prototype.getListenerConsumerCount=function(t){return this._listenerDemux.getConsumerCount(t)},m.prototype.getAllListenersConsumerCount=function(){return this._listenerDemux.getConsumerCountAll()},m.prototype.killListener=function(t){this._listenerDemux.kill(t)},m.prototype.killAllListeners=function(){this._listenerDemux.killAll()},m.prototype.killListenerConsumer=function(t){this._listenerDemux.killConsumer(t)},m.prototype.getListenerBackpressure=function(t){return this._listenerDemux.getBackpressure(t)},m.prototype.getAllListenersBackpressure=function(){return this._listenerDemux.getBackpressureAll()},m.prototype.getListenerConsumerBackpressure=function(t){return this._listenerDemux.getConsumerBackpressure(t)},m.prototype.hasListenerConsumer=function(t,e){return this._listenerDemux.hasConsumer(t,e)},m.prototype.hasAnyListenerConsumer=function(t){return this._listenerDemux.hasConsumerAll(t)};var d=m;const y=class{async next(t){let e=this.createConsumer(t),r=await e.next();return e.return(),r}async once(t){let e=await this.next(t);return e.done&&await new Promise((()=>{})),e.value}createConsumer(){throw new TypeError("Method must be overriden by subclass")}[Symbol.asyncIterator](){return this.createConsumer()}};let g=class t extends y{constructor(e,r,n,o){super(),this.PENDING=t.PENDING,this.SUBSCRIBED=t.SUBSCRIBED,this.UNSUBSCRIBED=t.UNSUBSCRIBED,this.name=e,this.client=r,this._eventDemux=n,this._dataStream=o.stream(this.name)}createConsumer(t){return this._dataStream.createConsumer(t)}listener(t){return this._eventDemux.stream(`${this.name}/${t}`)}close(){this.client.closeChannel(this.name)}kill(){this.client.killChannel(this.name)}killOutputConsumer(t){this.hasOutputConsumer(t)&&this.client.killChannelOutputConsumer(t)}killListenerConsumer(t){this.hasAnyListenerConsumer(t)&&this.client.killChannelListenerConsumer(t)}getOutputConsumerStats(t){if(this.hasOutputConsumer(t))return this.client.getChannelOutputConsumerStats(t)}getListenerConsumerStats(t){if(this.hasAnyListenerConsumer(t))return this.client.getChannelListenerConsumerStats(t)}getBackpressure(){return this.client.getChannelBackpressure(this.name)}getListenerConsumerBackpressure(t){return this.hasAnyListenerConsumer(t)?this.client.getChannelListenerConsumerBackpressure(t):0}getOutputConsumerBackpressure(t){return this.hasOutputConsumer(t)?this.client.getChannelOutputConsumerBackpressure(t):0}closeOutput(){this.client.channelCloseOutput(this.name)}closeListener(t){this.client.channelCloseListener(this.name,t)}closeAllListeners(){this.client.channelCloseAllListeners(this.name)}killOutput(){this.client.channelKillOutput(this.name)}killListener(t){this.client.channelKillListener(this.name,t)}killAllListeners(){this.client.channelKillAllListeners(this.name)}getOutputConsumerStatsList(){return this.client.channelGetOutputConsumerStatsList(this.name)}getListenerConsumerStatsList(t){return this.client.channelGetListenerConsumerStatsList(this.name,t)}getAllListenersConsumerStatsList(){return this.client.channelGetAllListenersConsumerStatsList(this.name)}getOutputBackpressure(){return this.client.channelGetOutputBackpressure(this.name)}getListenerBackpressure(t){return this.client.channelGetListenerBackpressure(this.name,t)}getAllListenersBackpressure(){return this.client.channelGetAllListenersBackpressure(this.name)}hasOutputConsumer(t){return this.client.channelHasOutputConsumer(this.name,t)}hasListenerConsumer(t,e){return this.client.channelHasListenerConsumer(this.name,t,e)}hasAnyListenerConsumer(t){return this.client.channelHasAnyListenerConsumer(this.name,t)}get state(){return this.client.getChannelState(this.name)}set state(t){throw new Error("Cannot directly set channel state")}get options(){return this.client.getChannelOptions(this.name)}set options(t){throw new Error("Cannot directly set channel options")}subscribe(t){this.client.subscribe(this.name,t)}unsubscribe(){this.client.unsubscribe(this.name)}isSubscribed(t){return this.client.isSubscribed(this.name,t)}transmitPublish(t){return this.client.transmitPublish(this.name,t)}invokePublish(t){return this.client.invokePublish(this.name,t)}};g.PENDING="pending",g.SUBSCRIBED="subscribed",g.UNSUBSCRIBED="unsubscribed";var b=g;function v(){this._internalStorage={},this.isLocalStorageEnabled=this._checkLocalStorageEnabled()}v.prototype._checkLocalStorageEnabled=function(){let t;try{localStorage.setItem("__scLocalStorageTest",1),localStorage.removeItem("__scLocalStorageTest")}catch(e){t=e}return!t},v.prototype.saveToken=function(t,e,r){return this.isLocalStorageEnabled?localStorage.setItem(t,e):this._internalStorage[t]=e,Promise.resolve(e)},v.prototype.removeToken=function(t){let e=this.loadToken(t);return this.isLocalStorageEnabled?localStorage.removeItem(t):delete this._internalStorage[t],e},v.prototype.loadToken=function(t){let e;return e=this.isLocalStorageEnabled?localStorage.getItem(t):this._internalStorage[t]||null,Promise.resolve(e)};var k=v,E={};const C="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",_=/^[ \n\r\t]*[{\[]/;let w=function(t){let e=new Uint8Array(t),r=e.length,n="";for(let t=0;t>2],n+=C[(3&e[t])<<4|e[t+1]>>4],n+=C[(15&e[t+1])<<2|e[t+2]>>6],n+=C[63&e[t+2]];return r%3==2?n=n.substring(0,n.length-1)+"=":r%3==1&&(n=n.substring(0,n.length-2)+"=="),n},S=function(t,e){if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer)return{base64:!0,data:w(e)};if("undefined"!=typeof Buffer){if(e instanceof Buffer)return{base64:!0,data:e.toString("base64")};if(e&&"Buffer"===e.type&&Array.isArray(e.data)){let t;return t=Buffer.from?Buffer.from(e.data):new Buffer(e.data),{base64:!0,data:t.toString("base64")}}}return e};E.decode=function(t){if(null==t)return null;if("#1"===t||"#2"===t)return t;let e=t.toString();if(!_.test(e))return e;try{return JSON.parse(e)}catch(t){}return e},E.encode=function(t){return"#1"===t||"#2"===t?t:JSON.stringify(t,S)};var A={exports:{}};const T=function(t){var e=[],r=[];return function t(n,o){var i,s,a;if(!("object"!=typeof n||null===n||n instanceof Boolean||n instanceof Date||n instanceof Number||n instanceof RegExp||n instanceof String)){for(i=0;i{if(this.sent)throw new Z(`Response to request ${this.id} has already been sent`);this.sent=!0,this.socket.sendObject(t,e)},this.end=(t,e)=>{let r={rid:this.id};void 0!==t&&(r.data=t),this._respond(r,e)},this.error=(t,e)=>{let r={rid:this.id,error:X.dehydrateError(t)};this._respond(r,e)}};let rt;if("undefined"!=typeof WebSocket)rt=function(t,e){return new WebSocket(t)};else{let t=function(){if(tt)return Q;let t;tt=1,t="undefined"!=typeof WorkerGlobalScope?self:"undefined"!=typeof window&&window||function(){return this}();const e=t.WebSocket||t.MozWebSocket;function r(t,r,n){let o;return o=r?new e(t,r):new e(t),o}return e&&(r.prototype=e.prototype),Q=e?r:null}();rt=function(e,r){return new t(e,[],r)}}const nt=J,ot=nt.TimeoutError,it=nt.BadConnectionError;function st(t,e,r,n,o){this.state=this.CLOSED,this.auth=t,this.codec=e,this.options=r,this.wsOptions=n,this.protocolVersion=r.protocolVersion,this.connectTimeout=r.connectTimeout,this.pingTimeout=r.pingTimeout,this.pingTimeoutDisabled=!!r.pingTimeoutDisabled,this.callIdGenerator=r.callIdGenerator,this.authTokenName=r.authTokenName,this.isBufferingBatch=!1,this._pingTimeoutTicker=null,this._callbackMap={},this._batchBuffer=[],this.lastPingTimestamp=Date.now(),o||(o={}),this._onOpenHandler=o.onOpen||function(){},this._onOpenAbortHandler=o.onOpenAbort||function(){},this._onCloseHandler=o.onClose||function(){},this._onEventHandler=o.onEvent||function(){},this._onErrorHandler=o.onError||function(){},this._onInboundInvokeHandler=o.onInboundInvoke||function(){},this._onInboundTransmitHandler=o.onInboundTransmit||function(){},this.state=this.CONNECTING;let i=this.uri(),s=rt(i,n);s.binaryType=this.options.binaryType,this.socket=s,s.onopen=()=>{this._onOpen()},s.onclose=async t=>{let e;e=null==t.code?1005:t.code,this._destroy(e,t.reason)},s.onmessage=(t,e)=>{this._onMessage(t.data)},s.onerror=t=>{this.state===this.CONNECTING&&this._destroy(1006)},this._connectTimeoutRef=setTimeout((()=>{this._destroy(4007),this.socket.close(4007)}),this.connectTimeout),1===this.protocolVersion?this._handlePing=t=>"#1"===t&&(this._resetPingTimeout(),this.socket.readyState===this.socket.OPEN&&this.send("#2"),!0):this._handlePing=t=>""===t&&(this._resetPingTimeout(),this.socket.readyState===this.socket.OPEN&&this.send(""),!0)}st.CONNECTING=st.prototype.CONNECTING="connecting",st.OPEN=st.prototype.OPEN="open",st.CLOSED=st.prototype.CLOSED="closed",st.computeURI=function(t){let e,r=t.query||{};e=null==t.protocolScheme?t.secure?"wss":"ws":t.protocolScheme,t.timestampRequests&&(r[t.timestampParam]=(new Date).getTime());let n,o,i=new URLSearchParams;for(let[t,e]of Object.entries(r))if(Array.isArray(e))for(let r of e)i.append(t,r);else i.set(t,e);if(r=i.toString(),r.length&&(r="?"+r),null==t.socketPath){if(t.host)n=t.host;else{let r="";t.port&&("wss"===e&&443!==t.port||"ws"===e&&80!==t.port)&&(r=":"+t.port),n=t.hostname+r}o=t.path}else n=t.socketPath,o=`:${t.path}`;return e+"://"+n+o+r},st.prototype.uri=function(){return st.computeURI(this.options)},st.prototype._onOpen=async function(){let t;clearTimeout(this._connectTimeoutRef),this._resetPingTimeout();try{t=await this._handshake()}catch(t){return null==t.statusCode&&(t.statusCode=4003),this._onError(t),this._destroy(t.statusCode,t.toString()),void this.socket.close(t.statusCode)}this.state=this.OPEN,t&&(this.pingTimeout=t.pingTimeout),this._resetPingTimeout(),this._onOpenHandler(t)},st.prototype._handshake=async function(){let t=await this.auth.loadToken(this.authTokenName),e=await this.invoke("#handshake",{authToken:t},{force:!0});return e&&(e.authToken=t,e.authError&&(e.authError=nt.hydrateError(e.authError))),e},st.prototype._abortAllPendingEventsDueToBadConnection=function(t,e,r){Object.keys(this._callbackMap||{}).forEach((n=>{let o=this._callbackMap[n];delete this._callbackMap[n],clearTimeout(o.timeout),delete o.timeout;let i=`Event ${o.event} was aborted due to a bad connection`,s=new it(i,t,e,r),a=o.callback;a&&(delete o.callback,a.call(o,s,o))}))},st.prototype._destroy=function(t,e){!e&&nt.socketProtocolErrorStatuses[t]&&(e=nt.socketProtocolErrorStatuses[t]),delete this.socket.onopen,delete this.socket.onclose,delete this.socket.onmessage,delete this.socket.onerror,clearTimeout(this._connectTimeoutRef),clearTimeout(this._pingTimeoutTicker),this.state===this.OPEN?(this.state=this.CLOSED,this._abortAllPendingEventsDueToBadConnection("disconnect",t,e),this._onCloseHandler({code:t,reason:e})):this.state===this.CONNECTING?(this.state=this.CLOSED,this._abortAllPendingEventsDueToBadConnection("connectAbort",t,e),this._onOpenAbortHandler({code:t,reason:e})):this.state===this.CLOSED&&this._abortAllPendingEventsDueToBadConnection("connectAbort",t,e)},st.prototype._processInboundPacket=function(t,e){if(t&&"string"==typeof t.event)if("number"==typeof t.cid){let e=new et(this,t.cid,t.event,t.data);this._onInboundInvokeHandler(e)}else this._onInboundTransmitHandler({...t});else if(t&&"number"==typeof t.rid){let e=this._callbackMap[t.rid];if(e&&(clearTimeout(e.timeout),delete e.timeout,delete this._callbackMap[t.rid],e.callback)){let r=nt.hydrateError(t.error);e.callback(r,t.data)}}else this._onEventHandler({event:"raw",data:{message:e}})},st.prototype._onMessage=function(t){if(this._onEventHandler({event:"message",data:{message:t}}),this._handlePing(t))return;let e=this.decode(t);if(Array.isArray(e)){let r=e.length;for(let n=0;n=this.pingTimeout},st.prototype._resetPingTimeout=function(){this.lastPingTimestamp=Date.now(),this.pingTimeoutDisabled||(clearTimeout(this._pingTimeoutTicker),this._pingTimeoutTicker=setTimeout((()=>{this._destroy(4e3),this.socket.close(4e3)}),this.pingTimeout))},st.prototype.clearAllListeners=function(){this._onOpenHandler=function(){},this._onOpenAbortHandler=function(){},this._onCloseHandler=function(){},this._onEventHandler=function(){},this._onErrorHandler=function(){},this._onInboundInvokeHandler=function(){},this._onInboundTransmitHandler=function(){}},st.prototype.startBatch=function(){this.isBufferingBatch=!0,this._batchBuffer=[]},st.prototype.flushBatch=function(){if(this.isBufferingBatch=!1,!this._batchBuffer.length)return;let t=this.serializeObject(this._batchBuffer);this._batchBuffer=[],this.send(t)},st.prototype.cancelBatch=function(){this.isBufferingBatch=!1,this._batchBuffer=[]},st.prototype.getBytesReceived=function(){return this.socket.bytesReceived},st.prototype.close=function(t,e){this.state!==this.OPEN&&this.state!==this.CONNECTING||(t=t||1e3,this._destroy(t,e),this.socket.close(t,e))},st.prototype.transmitObject=function(t){let e={event:t.event,data:t.data};return t.callback&&(e.cid=t.cid=this.callIdGenerator(),this._callbackMap[t.cid]=t),this.sendObject(e),t.cid||null},st.prototype._handleEventAckTimeout=function(t){t.cid&&delete this._callbackMap[t.cid],delete t.timeout;let e=t.callback;if(e){delete t.callback;let r=new ot(`Event response for ${t.event} event timed out`);e.call(t,r,t)}},st.prototype.transmit=function(t,e,r){let n={event:t,data:e};return(this.state===this.OPEN||r.force)&&this.transmitObject(n),Promise.resolve()},st.prototype.invokeRaw=function(t,e,r,n){let o={event:t,data:e,callback:n};r.noTimeout||(o.timeout=setTimeout((()=>{this._handleEventAckTimeout(o)}),this.options.ackTimeout));let i=null;return(this.state===this.OPEN||r.force)&&(i=this.transmitObject(o)),i},st.prototype.invoke=function(t,e,r){return new Promise(((n,o)=>{this.invokeRaw(t,e,r,((t,e)=>{t?o(t):n(e)}))}))},st.prototype.cancelPendingResponse=function(t){delete this._callbackMap[t]},st.prototype.decode=function(t){return this.codec.decode(t)},st.prototype.encode=function(t){return this.codec.encode(t)},st.prototype.send=function(t){this.socket.readyState!==this.socket.OPEN?this._destroy(1005):this.socket.send(t)},st.prototype.serializeObject=function(t){let e;try{e=this.encode(t)}catch(t){return this._onError(t),null}return e},st.prototype.sendObject=function(t){if(this.isBufferingBatch)return void this._batchBuffer.push(t);let e=this.serializeObject(t);null!=e&&this.send(e)};var at=st,ut=mt;mt.Item=yt;var ct=mt.prototype,ht=yt.prototype,lt=gt.prototype,pt="undefined"==typeof Symbol?void 0:Symbol.iterator;ct.tail=ct.head=null,mt.of=function(){return dt(new this,arguments)},mt.from=function(t){return dt(new this,t)},ct.toArray=function(){var t=this.head,e=[];for(;t;)e.push(t),t=t.next;return e},ct.prepend=function(t){var e=this,r=e.head;if(!t)return!1;if(!t.append||!t.prepend||!t.detach)throw new Error(ft+"#prepend`.");if(r)return r.prepend(t);return t.detach(),t.list=e,e.head=t,e.size++,t},ct.append=function(t){if(!t)return!1;if(!t.append||!t.prepend||!t.detach)throw new Error(ft+"#append`.");var e=this,r=e.head,n=e.tail;if(n)return n.append(t);if(r)return r.append(t);return t.detach(),t.list=e,e.head=t,e.size++,t},void 0!==pt&&(ct[pt]=function(){return new gt(this.head)}),ht.next=ht.prev=ht.list=null,ht.prepend=function(t){if(!(t&&t.append&&t.prepend&&t.detach))throw new Error(ft+"Item#prepend`.");var e=this,r=e.list,n=e.prev;if(!r)return!1;t.detach(),n&&(t.prev=n,n.next=t);t.next=e,t.list=r,e.prev=t,e===r.head&&(r.head=t);r.tail||(r.tail=e);return r.size++,t},ht.append=function(t){if(!(t&&t.append&&t.prepend&&t.detach))throw new Error(ft+"Item#append`.");var e=this,r=e.list,n=e.next;if(!r)return!1;t.detach(),n&&(t.next=n,n.prev=t);t.prev=e,t.list=r,e.next=t,e!==r.tail&&r.tail||(r.tail=t);return r.size++,t},ht.detach=function(){var t=this,e=t.list,r=t.prev,n=t.next;if(!e)return t;e.tail===t&&(e.tail=r);e.head===t&&(e.head=n);e.tail===e.head&&(e.tail=null);r&&(r.next=n);n&&(n.prev=r);return t.prev=t.next=t.list=null,e.size--,t},lt.next=function(){var t=this.item;return this.value=t,this.done=!t,this.item=t?t.next:void 0,this};var ft="An argument without append, prepend, or detach methods was given to `List";function mt(){this.size=0,0!==arguments.length&&dt(this,arguments)}function dt(t,e){var r,n,o,i;if(!e)return t;if(void 0!==pt&&e[pt])for(i=e[pt](),o={};!o.done;)o=i.next(),t.append(o&&o.value);else for(r=e.length,n=-1;++n + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */(t))return"buffer";if(function(t){try{if("number"==typeof t.length&&"function"==typeof t.callee)return!0}catch(t){if(-1!==t.message.indexOf("callee"))return!0}return!1}(t))return"arguments";if(function(t){return t instanceof Date||"function"==typeof t.toDateString&&"function"==typeof t.getDate&&"function"==typeof t.setDate}(t))return"date";if(function(t){return t instanceof Error||"string"==typeof t.message&&t.constructor&&"number"==typeof t.constructor.stackTraceLimit}(t))return"error";if(function(t){return t instanceof RegExp||"string"==typeof t.flags&&"boolean"==typeof t.ignoreCase&&"boolean"==typeof t.multiline&&"boolean"==typeof t.global}(t))return"regexp";switch(kt(t)){case"Symbol":return"symbol";case"Promise":return"promise";case"WeakMap":return"weakmap";case"WeakSet":return"weakset";case"Map":return"map";case"Set":return"set";case"Int8Array":return"int8array";case"Uint8Array":return"uint8array";case"Uint8ClampedArray":return"uint8clampedarray";case"Int16Array":return"int16array";case"Uint16Array":return"uint16array";case"Int32Array":return"int32array";case"Uint32Array":return"uint32array";case"Float32Array":return"float32array";case"Float64Array":return"float64array"}if(function(t){return"function"==typeof t.throw&&"function"==typeof t.return&&"function"==typeof t.next}(t))return"generator";switch(e=bt.call(t)){case"[object Object]":return"object";case"[object Map Iterator]":return"mapiterator";case"[object Set Iterator]":return"setiterator";case"[object String Iterator]":return"stringiterator";case"[object Array Iterator]":return"arrayiterator"}return e.slice(8,-1).toLowerCase().replace(/\s/g,"")};function kt(t){return"function"==typeof t.constructor?t.constructor.name:null}const Et=Symbol.prototype.valueOf,Ct=vt;var _t=function(t,e){switch(Ct(t)){case"array":return t.slice();case"object":return Object.assign({},t);case"date":return new t.constructor(Number(t));case"map":return new Map(t);case"set":return new Set(t);case"buffer":return function(t){const e=t.length,r=Buffer.allocUnsafe?Buffer.allocUnsafe(e):Buffer.from(e);return t.copy(r),r}(t);case"symbol":return function(t){return Et?Object(Et.call(t)):{}}(t);case"arraybuffer":return function(t){const e=new t.constructor(t.byteLength);return new Uint8Array(e).set(new Uint8Array(t)),e}(t);case"float32array":case"float64array":case"int16array":case"int32array":case"int8array":case"uint16array":case"uint32array":case"uint8clampedarray":case"uint8array":return function(t,e){return new t.constructor(t.buffer,t.byteOffset,t.length)}(t);case"regexp":return function(t){const e=void 0!==t.flags?t.flags:/\w+$/.exec(t)||void 0,r=new t.constructor(t.source,e);return r.lastIndex=t.lastIndex,r}(t);case"error":return Object.create(t);default:return t}},wt=function(t){return null!=t&&"object"==typeof t&&!1===Array.isArray(t)}; +/*! + * isobject + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */function St(t){return!0===wt(t)&&"[object Object]"===Object.prototype.toString.call(t)}const At=_t,Tt=vt,Bt=function(t){var e,r;return!1!==St(t)&&("function"==typeof(e=t.constructor)&&(!1!==St(r=e.prototype)&&!1!==r.hasOwnProperty("isPrototypeOf")))};function Ot(t,e){switch(Tt(t)){case"object":return function(t,e){if("function"==typeof e)return e(t);if(e||Bt(t)){const r=new t.constructor;for(let n in t)r[n]=Ot(t[n],e);return r}return t}(t,e);case"array":return function(t,e){const r=new t.constructor(t.length);for(let n=0;n0?o-4:o;for(r=0;r>16&255,s[a++]=e>>8&255,s[a++]=255&e;2===i&&(e=Nt[t.charCodeAt(r)]<<2|Nt[t.charCodeAt(r+1)]>>4,s[a++]=255&e);1===i&&(e=Nt[t.charCodeAt(r)]<<10|Nt[t.charCodeAt(r+1)]<<4|Nt[t.charCodeAt(r+2)]>>2,s[a++]=e>>8&255,s[a++]=255&e);return s},fromByteArray:function(t){for(var e,r=t.length,n=r%3,o=[],i=16383,s=0,a=r-n;sa?a:s+i));1===n?(e=t[r-1],o.push(Lt[e>>2]+Lt[e<<4&63]+"==")):2===n&&(e=(t[r-2]<<8)+t[r-1],o.push(Lt[e>>10]+Lt[e>>4&63]+Lt[e<<2&63]+"="));return o.join("")}},Lt=[],Nt=[],Pt="undefined"!=typeof Uint8Array?Uint8Array:Array,Ut="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Rt=0;Rt<64;++Rt)Lt[Rt]=Ut[Rt],Nt[Ut.charCodeAt(Rt)]=Rt;function jt(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");return-1===r&&(r=e),[r,r===e?0:4-r%4]}function Mt(t,e,r){for(var n,o,i=[],s=e;s>18&63]+Lt[o>>12&63]+Lt[o>>6&63]+Lt[63&o]);return i.join("")}Nt["-".charCodeAt(0)]=62,Nt["_".charCodeAt(0)]=63;var Ht={}; +/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */Ht.read=function(t,e,r,n,o){var i,s,a=8*o-n-1,u=(1<>1,h=-7,l=r?o-1:0,p=r?-1:1,f=t[e+l];for(l+=p,i=f&(1<<-h)-1,f>>=-h,h+=a;h>0;i=256*i+t[e+l],l+=p,h-=8);for(s=i&(1<<-h)-1,i>>=-h,h+=n;h>0;s=256*s+t[e+l],l+=p,h-=8);if(0===i)i=1-c;else{if(i===u)return s?NaN:1/0*(f?-1:1);s+=Math.pow(2,n),i-=c}return(f?-1:1)*s*Math.pow(2,i-n)},Ht.write=function(t,e,r,n,o,i){var s,a,u,c=8*i-o-1,h=(1<>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:i-1,m=n?1:-1,d=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,s=h):(s=Math.floor(Math.log(e)/Math.LN2),e*(u=Math.pow(2,-s))<1&&(s--,u*=2),(e+=s+l>=1?p/u:p*Math.pow(2,1-l))*u>=2&&(s++,u/=2),s+l>=h?(a=0,s=h):s+l>=1?(a=(e*u-1)*Math.pow(2,o),s+=l):(a=e*Math.pow(2,l-1)*Math.pow(2,o),s=0));o>=8;t[r+f]=255&a,f+=m,a/=256,o-=8);for(s=s<0;t[r+f]=255&s,f+=m,s/=256,c-=8);t[r+f-m]|=128*d}, +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +function(t){var e=xt,r=Ht,n="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=s,t.SlowBuffer=function(t){+t!=t&&(t=0);return s.alloc(+t)},t.INSPECT_MAX_BYTES=50;var o=2147483647;function i(t){if(t>o)throw new RangeError('The value "'+t+'" is invalid for option "size"');var e=new Uint8Array(t);return Object.setPrototypeOf(e,s.prototype),e}function s(t,e,r){if("number"==typeof t){if("string"==typeof e)throw new TypeError('The "string" argument must be of type string. Received type number');return c(t)}return a(t,e,r)}function a(t,e,r){if("string"==typeof t)return function(t,e){"string"==typeof e&&""!==e||(e="utf8");if(!s.isEncoding(e))throw new TypeError("Unknown encoding: "+e);var r=0|f(t,e),n=i(r),o=n.write(t,e);o!==r&&(n=n.slice(0,o));return n}(t,e);if(ArrayBuffer.isView(t))return function(t){if(M(t,Uint8Array)){var e=new Uint8Array(t);return l(e.buffer,e.byteOffset,e.byteLength)}return h(t)}(t);if(null==t)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t);if(M(t,ArrayBuffer)||t&&M(t.buffer,ArrayBuffer))return l(t,e,r);if("undefined"!=typeof SharedArrayBuffer&&(M(t,SharedArrayBuffer)||t&&M(t.buffer,SharedArrayBuffer)))return l(t,e,r);if("number"==typeof t)throw new TypeError('The "value" argument must not be of type number. Received type number');var n=t.valueOf&&t.valueOf();if(null!=n&&n!==t)return s.from(n,e,r);var o=function(t){if(s.isBuffer(t)){var e=0|p(t.length),r=i(e);return 0===r.length||t.copy(r,0,0,e),r}if(void 0!==t.length)return"number"!=typeof t.length||H(t.length)?i(0):h(t);if("Buffer"===t.type&&Array.isArray(t.data))return h(t.data)}(t);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof t[Symbol.toPrimitive])return s.from(t[Symbol.toPrimitive]("string"),e,r);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t)}function u(t){if("number"!=typeof t)throw new TypeError('"size" argument must be of type number');if(t<0)throw new RangeError('The value "'+t+'" is invalid for option "size"')}function c(t){return u(t),i(t<0?0:0|p(t))}function h(t){for(var e=t.length<0?0:0|p(t.length),r=i(e),n=0;n=o)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o.toString(16)+" bytes");return 0|t}function f(t,e){if(s.isBuffer(t))return t.length;if(ArrayBuffer.isView(t)||M(t,ArrayBuffer))return t.byteLength;if("string"!=typeof t)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof t);var r=t.length,n=arguments.length>2&&!0===arguments[2];if(!n&&0===r)return 0;for(var o=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":return U(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return R(t).length;default:if(o)return n?-1:U(t).length;e=(""+e).toLowerCase(),o=!0}}function m(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return B(this,e,r);case"utf8":case"utf-8":return w(this,e,r);case"ascii":return A(this,e,r);case"latin1":case"binary":return T(this,e,r);case"base64":return _(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function d(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function y(t,e,r,n,o){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),H(r=+r)&&(r=o?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(o)return-1;r=t.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof e&&(e=s.from(e,n)),s.isBuffer(e))return 0===e.length?-1:g(t,e,r,n,o);if("number"==typeof e)return e&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):g(t,[e],r,n,o);throw new TypeError("val must be string, number or Buffer")}function g(t,e,r,n,o){var i,s=1,a=t.length,u=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;s=2,a/=2,u/=2,r/=2}function c(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(o){var h=-1;for(i=r;ia&&(r=a-u),i=r;i>=0;i--){for(var l=!0,p=0;po&&(n=o):n=o;var i=e.length;n>i/2&&(n=i/2);for(var s=0;s>8,o=r%256,i.push(o),i.push(n);return i}(e,t.length-r),t,r,n)}function _(t,r,n){return 0===r&&n===t.length?e.fromByteArray(t):e.fromByteArray(t.slice(r,n))}function w(t,e,r){r=Math.min(t.length,r);for(var n=[],o=e;o239?4:c>223?3:c>191?2:1;if(o+l<=r)switch(l){case 1:c<128&&(h=c);break;case 2:128==(192&(i=t[o+1]))&&(u=(31&c)<<6|63&i)>127&&(h=u);break;case 3:i=t[o+1],s=t[o+2],128==(192&i)&&128==(192&s)&&(u=(15&c)<<12|(63&i)<<6|63&s)>2047&&(u<55296||u>57343)&&(h=u);break;case 4:i=t[o+1],s=t[o+2],a=t[o+3],128==(192&i)&&128==(192&s)&&128==(192&a)&&(u=(15&c)<<18|(63&i)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(h=u)}null===h?(h=65533,l=1):h>65535&&(h-=65536,n.push(h>>>10&1023|55296),h=56320|1023&h),n.push(h),o+=l}return function(t){var e=t.length;if(e<=S)return String.fromCharCode.apply(String,t);var r="",n=0;for(;nn.length?s.from(i).copy(n,o):Uint8Array.prototype.set.call(n,i,o);else{if(!s.isBuffer(i))throw new TypeError('"list" argument must be an Array of Buffers');i.copy(n,o)}o+=i.length}return n},s.byteLength=f,s.prototype._isBuffer=!0,s.prototype.swap16=function(){var t=this.length;if(t%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var e=0;er&&(e+=" ... "),""},n&&(s.prototype[n]=s.prototype.inspect),s.prototype.compare=function(t,e,r,n,o){if(M(t,Uint8Array)&&(t=s.from(t,t.offset,t.byteLength)),!s.isBuffer(t))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof t);if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),e<0||r>t.length||n<0||o>this.length)throw new RangeError("out of range index");if(n>=o&&e>=r)return 0;if(n>=o)return-1;if(e>=r)return 1;if(this===t)return 0;for(var i=(o>>>=0)-(n>>>=0),a=(r>>>=0)-(e>>>=0),u=Math.min(i,a),c=this.slice(n,o),h=t.slice(e,r),l=0;l>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}var o=this.length-e;if((void 0===r||r>o)&&(r=o),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return b(this,t,e,r);case"utf8":case"utf-8":return v(this,t,e,r);case"ascii":case"latin1":case"binary":return k(this,t,e,r);case"base64":return E(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,t,e,r);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},s.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var S=4096;function A(t,e,r){var n="";r=Math.min(t.length,r);for(var o=e;on)&&(r=n);for(var o="",i=e;ir)throw new RangeError("Trying to access beyond buffer length")}function D(t,e,r,n,o,i){if(!s.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>o||et.length)throw new RangeError("Index out of range")}function x(t,e,r,n,o,i){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function L(t,e,n,o,i){return e=+e,n>>>=0,i||x(t,0,n,4),r.write(t,e,n,o,23,4),n+4}function N(t,e,n,o,i){return e=+e,n>>>=0,i||x(t,0,n,8),r.write(t,e,n,o,52,8),n+8}s.prototype.slice=function(t,e){var r=this.length;(t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e>>=0,e>>>=0,r||I(t,e,this.length);for(var n=this[t],o=1,i=0;++i>>=0,e>>>=0,r||I(t,e,this.length);for(var n=this[t+--e],o=1;e>0&&(o*=256);)n+=this[t+--e]*o;return n},s.prototype.readUint8=s.prototype.readUInt8=function(t,e){return t>>>=0,e||I(t,1,this.length),this[t]},s.prototype.readUint16LE=s.prototype.readUInt16LE=function(t,e){return t>>>=0,e||I(t,2,this.length),this[t]|this[t+1]<<8},s.prototype.readUint16BE=s.prototype.readUInt16BE=function(t,e){return t>>>=0,e||I(t,2,this.length),this[t]<<8|this[t+1]},s.prototype.readUint32LE=s.prototype.readUInt32LE=function(t,e){return t>>>=0,e||I(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},s.prototype.readUint32BE=s.prototype.readUInt32BE=function(t,e){return t>>>=0,e||I(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},s.prototype.readIntLE=function(t,e,r){t>>>=0,e>>>=0,r||I(t,e,this.length);for(var n=this[t],o=1,i=0;++i=(o*=128)&&(n-=Math.pow(2,8*e)),n},s.prototype.readIntBE=function(t,e,r){t>>>=0,e>>>=0,r||I(t,e,this.length);for(var n=e,o=1,i=this[t+--n];n>0&&(o*=256);)i+=this[t+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*e)),i},s.prototype.readInt8=function(t,e){return t>>>=0,e||I(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},s.prototype.readInt16LE=function(t,e){t>>>=0,e||I(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},s.prototype.readInt16BE=function(t,e){t>>>=0,e||I(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},s.prototype.readInt32LE=function(t,e){return t>>>=0,e||I(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},s.prototype.readInt32BE=function(t,e){return t>>>=0,e||I(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},s.prototype.readFloatLE=function(t,e){return t>>>=0,e||I(t,4,this.length),r.read(this,t,!0,23,4)},s.prototype.readFloatBE=function(t,e){return t>>>=0,e||I(t,4,this.length),r.read(this,t,!1,23,4)},s.prototype.readDoubleLE=function(t,e){return t>>>=0,e||I(t,8,this.length),r.read(this,t,!0,52,8)},s.prototype.readDoubleBE=function(t,e){return t>>>=0,e||I(t,8,this.length),r.read(this,t,!1,52,8)},s.prototype.writeUintLE=s.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e>>>=0,r>>>=0,n)||D(this,t,e,r,Math.pow(2,8*r)-1,0);var o=1,i=0;for(this[e]=255&t;++i>>=0,r>>>=0,n)||D(this,t,e,r,Math.pow(2,8*r)-1,0);var o=r-1,i=1;for(this[e+o]=255&t;--o>=0&&(i*=256);)this[e+o]=t/i&255;return e+r},s.prototype.writeUint8=s.prototype.writeUInt8=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,1,255,0),this[e]=255&t,e+1},s.prototype.writeUint16LE=s.prototype.writeUInt16LE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,2,65535,0),this[e]=255&t,this[e+1]=t>>>8,e+2},s.prototype.writeUint16BE=s.prototype.writeUInt16BE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,2,65535,0),this[e]=t>>>8,this[e+1]=255&t,e+2},s.prototype.writeUint32LE=s.prototype.writeUInt32LE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,4,4294967295,0),this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t,e+4},s.prototype.writeUint32BE=s.prototype.writeUInt32BE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,4,4294967295,0),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},s.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var o=Math.pow(2,8*r-1);D(this,t,e,r,o-1,-o)}var i=0,s=1,a=0;for(this[e]=255&t;++i>0)-a&255;return e+r},s.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var o=Math.pow(2,8*r-1);D(this,t,e,r,o-1,-o)}var i=r-1,s=1,a=0;for(this[e+i]=255&t;--i>=0&&(s*=256);)t<0&&0===a&&0!==this[e+i+1]&&(a=1),this[e+i]=(t/s>>0)-a&255;return e+r},s.prototype.writeInt8=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,1,127,-128),t<0&&(t=255+t+1),this[e]=255&t,e+1},s.prototype.writeInt16LE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,2,32767,-32768),this[e]=255&t,this[e+1]=t>>>8,e+2},s.prototype.writeInt16BE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,2,32767,-32768),this[e]=t>>>8,this[e+1]=255&t,e+2},s.prototype.writeInt32LE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,4,2147483647,-2147483648),this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24,e+4},s.prototype.writeInt32BE=function(t,e,r){return t=+t,e>>>=0,r||D(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},s.prototype.writeFloatLE=function(t,e,r){return L(this,t,e,!0,r)},s.prototype.writeFloatBE=function(t,e,r){return L(this,t,e,!1,r)},s.prototype.writeDoubleLE=function(t,e,r){return N(this,t,e,!0,r)},s.prototype.writeDoubleBE=function(t,e,r){return N(this,t,e,!1,r)},s.prototype.copy=function(t,e,r,n){if(!s.isBuffer(t))throw new TypeError("argument should be a Buffer");if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e>>=0,r=void 0===r?this.length:r>>>0,t||(t=0),"number"==typeof t)for(i=e;i55295&&r<57344){if(!o){if(r>56319){(e-=3)>-1&&i.push(239,191,189);continue}if(s+1===n){(e-=3)>-1&&i.push(239,191,189);continue}o=r;continue}if(r<56320){(e-=3)>-1&&i.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(e-=3)>-1&&i.push(239,191,189);if(o=null,r<128){if((e-=1)<0)break;i.push(r)}else if(r<2048){if((e-=2)<0)break;i.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function R(t){return e.toByteArray(function(t){if((t=(t=t.split("=")[0]).trim().replace(P,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function j(t,e,r,n){for(var o=0;o=e.length||o>=t.length);++o)e[o+r]=t[o];return o}function M(t,e){return t instanceof e||null!=t&&null!=t.constructor&&null!=t.constructor.name&&t.constructor.name===e.name}function H(t){return t!=t}var G=function(){for(var t="0123456789abcdef",e=new Array(256),r=0;r<16;++r)for(var n=16*r,o=0;o<16;++o)e[n+o]=t[r]+t[o];return e}()}(Dt);const Gt=p,$t=d,Ft=b,zt=k,qt=E,Vt=at,Wt=ut,Kt=It,Yt=Dt.Buffer,Jt=function(t){return new Promise((e=>{setTimeout((()=>{e()}),t)}))},Xt=J,Zt=Xt.InvalidArgumentsError,Qt=Xt.InvalidMessageError,te=Xt.SocketProtocolError,ee=Xt.TimeoutError,re=Xt.BadConnectionError;function ne(t){$t.call(this);let e=Object.assign({path:"/socketcluster/",secure:!1,protocolScheme:null,socketPath:null,autoConnect:!0,autoReconnect:!0,autoSubscribeOnConnect:!0,connectTimeout:2e4,ackTimeout:1e4,timestampRequests:!1,timestampParam:"t",binaryType:"arraybuffer",batchOnHandshake:!1,batchOnHandshakeDuration:100,batchInterval:50,protocolVersion:2,wsOptions:{},cloneData:!1},t);null==e.authTokenName&&(e.authTokenName=this._generateAuthTokenNameFromURI(e)),this.id=null,this.version=e.version||null,this.protocolVersion=e.protocolVersion,this.state=this.CLOSED,this.authState=this.UNAUTHENTICATED,this.signedAuthToken=null,this.authToken=null,this.pendingReconnect=!1,this.pendingReconnectTimeout=null,this.preparingPendingSubscriptions=!1,this.clientId=e.clientId,this.wsOptions=e.wsOptions,this.connectTimeout=e.connectTimeout,this.ackTimeout=e.ackTimeout,this.channelPrefix=e.channelPrefix||null,this.authTokenName=e.authTokenName,e.pingTimeout=e.connectTimeout,this.pingTimeout=e.pingTimeout,this.pingTimeoutDisabled=!!e.pingTimeoutDisabled;let r=Math.pow(2,31)-1,n=t=>{if(this[t]>r)throw new Zt(`The ${t} value provided exceeded the maximum amount allowed`)};if(n("connectTimeout"),n("ackTimeout"),n("pingTimeout"),this.connectAttempts=0,this.isBatching=!1,this.batchOnHandshake=e.batchOnHandshake,this.batchOnHandshakeDuration=e.batchOnHandshakeDuration,this._batchingIntervalId=null,this._outboundBuffer=new Wt,this._channelMap={},this._channelEventDemux=new Gt,this._channelDataDemux=new Gt,this._receiverDemux=new Gt,this._procedureDemux=new Gt,this.options=e,this._cid=1,this.options.callIdGenerator=()=>this._cid++,this.options.autoReconnect){null==this.options.autoReconnectOptions&&(this.options.autoReconnectOptions={});let t=this.options.autoReconnectOptions;null==t.initialDelay&&(t.initialDelay=1e4),null==t.randomness&&(t.randomness=1e4),null==t.multiplier&&(t.multiplier=1.5),null==t.maxDelay&&(t.maxDelay=6e4)}if(null==this.options.subscriptionRetryOptions&&(this.options.subscriptionRetryOptions={}),this.options.authEngine?this.auth=this.options.authEngine:this.auth=new zt,this.options.codecEngine?this.codec=this.options.codecEngine:this.codec=qt,this.options.protocol){let t=new Zt("The protocol option does not affect socketcluster-client - If you want to utilize SSL/TLS, use the secure option instead");this._onError(t)}if(this.options.query=e.query||{},"string"==typeof this.options.query){let t=new URLSearchParams(this.options.query),e={};for(let[r,n]of t.entries()){let t=e[r];null==t?e[r]=n:(Array.isArray(t)||(e[r]=[t]),e[r].push(n))}this.options.query=e}this.options.autoConnect&&this.connect()}ne.prototype=Object.create($t.prototype),ne.CONNECTING=ne.prototype.CONNECTING=Vt.prototype.CONNECTING,ne.OPEN=ne.prototype.OPEN=Vt.prototype.OPEN,ne.CLOSED=ne.prototype.CLOSED=Vt.prototype.CLOSED,ne.AUTHENTICATED=ne.prototype.AUTHENTICATED="authenticated",ne.UNAUTHENTICATED=ne.prototype.UNAUTHENTICATED="unauthenticated",ne.SUBSCRIBED=ne.prototype.SUBSCRIBED=Ft.SUBSCRIBED,ne.PENDING=ne.prototype.PENDING=Ft.PENDING,ne.UNSUBSCRIBED=ne.prototype.UNSUBSCRIBED=Ft.UNSUBSCRIBED,ne.ignoreStatuses=Xt.socketProtocolIgnoreStatuses,ne.errorStatuses=Xt.socketProtocolErrorStatuses,Object.defineProperty(ne.prototype,"isBufferingBatch",{get:function(){return this.transport.isBufferingBatch}}),ne.prototype.uri=function(){return Vt.computeURI(this.options)},ne.prototype.getBackpressure=function(){return Math.max(this.getAllListenersBackpressure(),this.getAllReceiversBackpressure(),this.getAllProceduresBackpressure(),this.getAllChannelsBackpressure())},ne.prototype._generateAuthTokenNameFromURI=function(t){return`socketcluster.authToken${t.host?`.${t.host}`:`.${t.hostname||"localhost"}${t.port?`:${t.port}`:""}`}`},ne.prototype._setAuthToken=function(t){this._changeToAuthenticatedState(t.token),(async()=>{try{await this.auth.saveToken(this.authTokenName,t.token,{})}catch(t){this._onError(t)}})()},ne.prototype._removeAuthToken=function(t){(async()=>{let t;try{t=await this.auth.removeToken(this.authTokenName)}catch(t){return void this._onError(t)}this.emit("removeAuthToken",{oldAuthToken:t})})(),this._changeToUnauthenticatedStateAndClearTokens()},ne.prototype._privateDataHandlerMap={"#publish":function(t){if("string"!=typeof t.channel)return;let e=this._undecorateChannelName(t.channel);this.isSubscribed(e,!0)&&this._channelDataDemux.write(e,t.data)},"#kickOut":function(t){if("string"!=typeof t.channel)return;let e=this._undecorateChannelName(t.channel),r=this._channelMap[e];r&&(this.emit("kickOut",{channel:e,message:t.message}),this._channelEventDemux.write(`${e}/kickOut`,{message:t.message}),this._triggerChannelUnsubscribe(r))},"#setAuthToken":function(t){t&&this._setAuthToken(t)},"#removeAuthToken":function(t){this._removeAuthToken(t)}},ne.prototype._privateRPCHandlerMap={"#setAuthToken":function(t,e){if(t)this._setAuthToken(t),e.end();else{let t=new Qt("No token data provided by #setAuthToken event");delete t.stack,e.error(t)}},"#removeAuthToken":function(t,e){this._removeAuthToken(t),e.end()}},ne.prototype.getState=function(){return this.state},ne.prototype.getBytesReceived=function(){return this.transport.getBytesReceived()},ne.prototype.deauthenticate=async function(){(async()=>{let t;try{t=await this.auth.removeToken(this.authTokenName)}catch(t){return void this._onError(t)}this.emit("removeAuthToken",{oldAuthToken:t})})(),this.state!==this.CLOSED&&this.transmit("#removeAuthToken"),this._changeToUnauthenticatedStateAndClearTokens(),await Jt(0)},ne.prototype.connect=function(t){if(t&&(this.state!==this.CLOSED&&this.disconnect(1e3,"Socket was disconnected by the client to initiate a new connection"),this.options={...this.options,...t},null==this.options.authTokenName&&(this.options.authTokenName=this._generateAuthTokenNameFromURI(this.options))),this.state===this.CLOSED){this.pendingReconnect=!1,this.pendingReconnectTimeout=null,clearTimeout(this._reconnectTimeoutRef),this.state=this.CONNECTING,this.emit("connecting",{}),this.transport&&this.transport.clearAllListeners();let t={onOpen:t=>{this.state=this.OPEN,this._onOpen(t)},onOpenAbort:t=>{this.state!==this.CLOSED&&(this.state=this.CLOSED,this._destroy(t.code,t.reason,!0))},onClose:t=>{this.state!==this.CLOSED&&(this.state=this.CLOSED,this._destroy(t.code,t.reason))},onEvent:t=>{this.emit(t.event,t.data)},onError:t=>{this._onError(t.error)},onInboundInvoke:t=>{this._onInboundInvoke(t)},onInboundTransmit:t=>{this._onInboundTransmit(t.event,t.data)}};this.transport=new Vt(this.auth,this.codec,this.options,this.wsOptions,t)}},ne.prototype.reconnect=function(t,e){this.disconnect(t,e),this.connect()},ne.prototype.disconnect=function(t,e){if("number"!=typeof(t=t||1e3))throw new Zt("If specified, the code argument must be a number");let r=this.state===this.CONNECTING;r||this.state===this.OPEN?(this.state=this.CLOSED,this._destroy(t,e,r),this.transport.close(t,e)):(this.pendingReconnect=!1,this.pendingReconnectTimeout=null,clearTimeout(this._reconnectTimeoutRef))},ne.prototype._changeToUnauthenticatedStateAndClearTokens=function(){if(this.authState!==this.UNAUTHENTICATED){let t=this.authState,e=this.authToken,r=this.signedAuthToken;this.authState=this.UNAUTHENTICATED,this.signedAuthToken=null,this.authToken=null;let n={oldAuthState:t,newAuthState:this.authState};this.emit("authStateChange",n),this.emit("deauthenticate",{oldSignedAuthToken:r,oldAuthToken:e})}},ne.prototype._changeToAuthenticatedState=function(t){if(this.signedAuthToken=t,this.authToken=this._extractAuthTokenData(t),this.authState!==this.AUTHENTICATED){let e=this.authState;this.authState=this.AUTHENTICATED;let r={oldAuthState:e,newAuthState:this.authState,signedAuthToken:t,authToken:this.authToken};this.preparingPendingSubscriptions||this.processPendingSubscriptions(),this.emit("authStateChange",r)}this.emit("authenticate",{signedAuthToken:t,authToken:this.authToken})},ne.prototype.decodeBase64=function(t){return Yt.from(t,"base64").toString("utf8")},ne.prototype.encodeBase64=function(t){return Yt.from(t,"utf8").toString("base64")},ne.prototype._extractAuthTokenData=function(t){if("string"!=typeof t)return null;let e=t.split(".")[1];if(null!=e){let t=e;try{return t=this.decodeBase64(t),JSON.parse(t)}catch(e){return t}}return null},ne.prototype.getAuthToken=function(){return this.authToken},ne.prototype.getSignedAuthToken=function(){return this.signedAuthToken},ne.prototype.authenticate=async function(t){let e;try{e=await this.invoke("#authenticate",t)}catch(t){throw"BadConnectionError"!==t.name&&"TimeoutError"!==t.name&&this._changeToUnauthenticatedStateAndClearTokens(),await Jt(0),t}return e&&null!=e.isAuthenticated?e.authError&&(e.authError=Xt.hydrateError(e.authError)):e={isAuthenticated:this.authState,authError:null},e.isAuthenticated?this._changeToAuthenticatedState(t):this._changeToUnauthenticatedStateAndClearTokens(),(async()=>{try{await this.auth.saveToken(this.authTokenName,t,{})}catch(t){this._onError(t)}})(),await Jt(0),e},ne.prototype._tryReconnect=function(t){let e,r=this.connectAttempts++,n=this.options.autoReconnectOptions;if(null==t||r>0){let t=Math.round(n.initialDelay+(n.randomness||0)*Math.random());e=Math.round(t*Math.pow(n.multiplier,r))}else e=t;e>n.maxDelay&&(e=n.maxDelay),clearTimeout(this._reconnectTimeoutRef),this.pendingReconnect=!0,this.pendingReconnectTimeout=e,this._reconnectTimeoutRef=setTimeout((()=>{this.connect()}),e)},ne.prototype._onOpen=function(t){this.isBatching?this._startBatching():this.batchOnHandshake&&(this._startBatching(),setTimeout((()=>{this.isBatching||this._stopBatching()}),this.batchOnHandshakeDuration)),this.preparingPendingSubscriptions=!0,t?(this.id=t.id,this.pingTimeout=t.pingTimeout,t.isAuthenticated?this._changeToAuthenticatedState(t.authToken):this._changeToUnauthenticatedStateAndClearTokens()):this._changeToUnauthenticatedStateAndClearTokens(),this.connectAttempts=0,this.options.autoSubscribeOnConnect&&this.processPendingSubscriptions(),this.emit("connect",{...t,processPendingSubscriptions:()=>{this.processPendingSubscriptions()}}),this.state===this.OPEN&&this._flushOutboundBuffer()},ne.prototype._onError=function(t){this.emit("error",{error:t})},ne.prototype._suspendSubscriptions=function(){Object.keys(this._channelMap).forEach((t=>{let e=this._channelMap[t];this._triggerChannelUnsubscribe(e,!0)}))},ne.prototype._abortAllPendingEventsDueToBadConnection=function(t,e,r){let n,o=this._outboundBuffer.head;for(;o;){n=o.next;let i=o.data;clearTimeout(i.timeout),delete i.timeout,o.detach(),o=n;let s=i.callback;if(s){delete i.callback;let n=`Event ${i.event} was aborted due to a bad connection`,o=new re(n,t,e,r);s.call(i,o,i)}i.cid&&this.transport.cancelPendingResponse(i.cid)}},ne.prototype._destroy=function(t,e,r){if(this.id=null,this._cancelBatching(),this.transport&&this.transport.clearAllListeners(),this.pendingReconnect=!1,this.pendingReconnectTimeout=null,clearTimeout(this._reconnectTimeoutRef),this._suspendSubscriptions(),r?this.emit("connectAbort",{code:t,reason:e}):this.emit("disconnect",{code:t,reason:e}),this.emit("close",{code:t,reason:e}),!ne.ignoreStatuses[t]){let r;r="string"==typeof e?"Socket connection closed with status code "+t+" and reason: "+e:"Socket connection closed with status code "+t;let n=new te(ne.errorStatuses[t]||r,t);this._onError(n)}this._abortAllPendingEventsDueToBadConnection(r?"connectAbort":"disconnect",t,e),this.options.autoReconnect&&(4e3===t||4001===t||1005===t?this._tryReconnect(0):1e3!==t&&t<4500&&this._tryReconnect())},ne.prototype._onInboundTransmit=function(t,e){let r=this._privateDataHandlerMap[t];r?r.call(this,e||{}):this._receiverDemux.write(t,e)},ne.prototype._onInboundInvoke=function(t){let{procedure:e,data:r}=t,n=this._privateRPCHandlerMap[e];n?n.call(this,r,t):this._procedureDemux.write(e,t)},ne.prototype.decode=function(t){return this.transport.decode(t)},ne.prototype.encode=function(t){return this.transport.encode(t)},ne.prototype._flushOutboundBuffer=function(){let t,e=this._outboundBuffer.head;for(;e;){t=e.next;let r=e.data;r.callback||(clearTimeout(r.timeout),delete r.timeout),e.detach(),this.transport.transmitObject(r),e=t}},ne.prototype._handleEventAckTimeout=function(t,e){e&&e.detach(),delete t.timeout;let r=t.callback;if(r){delete t.callback;let e=new ee(`Event response for ${t.event} event timed out`);r.call(t,e,t)}t.cid&&this.transport.cancelPendingResponse(t.cid)},ne.prototype._processOutboundEvent=function(t,e,r,n){r=r||{},this.transport&&this.transport.isStale()&&this.disconnect(1e3,"Stale socket was disconnected by the client to initiate a new connection"),this.state===this.CLOSED&&this.connect();let o,i={event:t};o=n?new Promise(((t,e)=>{i.callback=(r,n)=>{r?e(r):t(n)}})):Promise.resolve();let s=new Wt.Item;this.options.cloneData?i.data=Kt(e):i.data=e,s.data=i;let a=null==r.ackTimeout?this.ackTimeout:r.ackTimeout;return i.timeout=setTimeout((()=>{this._handleEventAckTimeout(i,s)}),a),this._outboundBuffer.append(s),this.state===this.OPEN&&this._flushOutboundBuffer(),o},ne.prototype.send=function(t){this.transport.send(t)},ne.prototype.transmit=function(t,e,r){return this._processOutboundEvent(t,e,r)},ne.prototype.invoke=function(t,e,r){return this._processOutboundEvent(t,e,r,!0)},ne.prototype.transmitPublish=function(t,e){let r={channel:this._decorateChannelName(t),data:e};return this.transmit("#publish",r)},ne.prototype.invokePublish=function(t,e){let r={channel:this._decorateChannelName(t),data:e};return this.invoke("#publish",r)},ne.prototype._triggerChannelSubscribe=function(t,e){let r=t.name;if(t.state!==Ft.SUBSCRIBED){let n=t.state;t.state=Ft.SUBSCRIBED;let o={oldChannelState:n,newChannelState:t.state,subscriptionOptions:e};this._channelEventDemux.write(`${r}/subscribeStateChange`,o),this._channelEventDemux.write(`${r}/subscribe`,{subscriptionOptions:e}),this.emit("subscribeStateChange",{channel:r,...o}),this.emit("subscribe",{channel:r,subscriptionOptions:e})}},ne.prototype._triggerChannelSubscribeFail=function(t,e,r){let n=e.name,o=!e.options.waitForAuth||this.authState===this.AUTHENTICATED;!!this._channelMap[n]&&o&&(delete this._channelMap[n],this._channelEventDemux.write(`${n}/subscribeFail`,{error:t,subscriptionOptions:r}),this.emit("subscribeFail",{error:t,channel:n,subscriptionOptions:r}))},ne.prototype._cancelPendingSubscribeCallback=function(t){null!=t._pendingSubscriptionCid&&(this.transport.cancelPendingResponse(t._pendingSubscriptionCid),delete t._pendingSubscriptionCid)},ne.prototype._decorateChannelName=function(t){return this.channelPrefix&&(t=this.channelPrefix+t),t},ne.prototype._undecorateChannelName=function(t){return this.channelPrefix&&0===t.indexOf(this.channelPrefix)?t.replace(this.channelPrefix,""):t},ne.prototype.startBatch=function(){this.transport.startBatch()},ne.prototype.flushBatch=function(){this.transport.flushBatch()},ne.prototype.cancelBatch=function(){this.transport.cancelBatch()},ne.prototype._startBatching=function(){null==this._batchingIntervalId&&(this.startBatch(),this._batchingIntervalId=setInterval((()=>{this.flushBatch(),this.startBatch()}),this.options.batchInterval))},ne.prototype.startBatching=function(){this.isBatching=!0,this._startBatching()},ne.prototype._stopBatching=function(){null!=this._batchingIntervalId&&clearInterval(this._batchingIntervalId),this._batchingIntervalId=null,this.flushBatch()},ne.prototype.stopBatching=function(){this.isBatching=!1,this._stopBatching()},ne.prototype._cancelBatching=function(){null!=this._batchingIntervalId&&clearInterval(this._batchingIntervalId),this._batchingIntervalId=null,this.cancelBatch()},ne.prototype.cancelBatching=function(){this.isBatching=!1,this._cancelBatching()},ne.prototype._trySubscribe=function(t){let e=!t.options.waitForAuth||this.authState===this.AUTHENTICATED;if(this.state===this.OPEN&&!this.preparingPendingSubscriptions&&null==t._pendingSubscriptionCid&&e){let e={noTimeout:!0},r={};t.options.waitForAuth&&(e.waitForAuth=!0,r.waitForAuth=e.waitForAuth),t.options.data&&(r.data=t.options.data),t._pendingSubscriptionCid=this.transport.invokeRaw("#subscribe",{channel:this._decorateChannelName(t.name),...r},e,(e=>{if(e){if("BadConnectionError"===e.name)return;delete t._pendingSubscriptionCid,this._triggerChannelSubscribeFail(e,t,r)}else delete t._pendingSubscriptionCid,this._triggerChannelSubscribe(t,r)})),this.emit("subscribeRequest",{channel:t.name,subscriptionOptions:r})}},ne.prototype.subscribe=function(t,e){e=e||{};let r=this._channelMap[t],n={waitForAuth:!!e.waitForAuth};return null!=e.priority&&(n.priority=e.priority),void 0!==e.data&&(n.data=e.data),r?e&&(r.options=n):(r={name:t,state:Ft.PENDING,options:n},this._channelMap[t]=r,this._trySubscribe(r)),new Ft(t,this,this._channelEventDemux,this._channelDataDemux)},ne.prototype._triggerChannelUnsubscribe=function(t,e){let r=t.name;if(this._cancelPendingSubscribeCallback(t),t.state===Ft.SUBSCRIBED){let n={oldChannelState:t.state,newChannelState:e?Ft.PENDING:Ft.UNSUBSCRIBED};this._channelEventDemux.write(`${r}/subscribeStateChange`,n),this._channelEventDemux.write(`${r}/unsubscribe`,{}),this.emit("subscribeStateChange",{channel:r,...n}),this.emit("unsubscribe",{channel:r})}e?t.state=Ft.PENDING:delete this._channelMap[r]},ne.prototype._tryUnsubscribe=function(t){if(this.state===this.OPEN){let e={noTimeout:!0};this._cancelPendingSubscribeCallback(t);let r=this._decorateChannelName(t.name);this.transport.transmit("#unsubscribe",r,e)}},ne.prototype.unsubscribe=function(t){let e=this._channelMap[t];e&&(this._triggerChannelUnsubscribe(e),this._tryUnsubscribe(e))},ne.prototype.receiver=function(t){return this._receiverDemux.stream(t)},ne.prototype.closeReceiver=function(t){this._receiverDemux.close(t)},ne.prototype.closeAllReceivers=function(){this._receiverDemux.closeAll()},ne.prototype.killReceiver=function(t){this._receiverDemux.kill(t)},ne.prototype.killAllReceivers=function(){this._receiverDemux.killAll()},ne.prototype.killReceiverConsumer=function(t){this._receiverDemux.killConsumer(t)},ne.prototype.getReceiverConsumerStats=function(t){return this._receiverDemux.getConsumerStats(t)},ne.prototype.getReceiverConsumerStatsList=function(t){return this._receiverDemux.getConsumerStatsList(t)},ne.prototype.getAllReceiversConsumerStatsList=function(){return this._receiverDemux.getConsumerStatsListAll()},ne.prototype.getReceiverBackpressure=function(t){return this._receiverDemux.getBackpressure(t)},ne.prototype.getAllReceiversBackpressure=function(){return this._receiverDemux.getBackpressureAll()},ne.prototype.getReceiverConsumerBackpressure=function(t){return this._receiverDemux.getConsumerBackpressure(t)},ne.prototype.hasReceiverConsumer=function(t,e){return this._receiverDemux.hasConsumer(t,e)},ne.prototype.hasAnyReceiverConsumer=function(t){return this._receiverDemux.hasConsumerAll(t)},ne.prototype.procedure=function(t){return this._procedureDemux.stream(t)},ne.prototype.closeProcedure=function(t){this._procedureDemux.close(t)},ne.prototype.closeAllProcedures=function(){this._procedureDemux.closeAll()},ne.prototype.killProcedure=function(t){this._procedureDemux.kill(t)},ne.prototype.killAllProcedures=function(){this._procedureDemux.killAll()},ne.prototype.killProcedureConsumer=function(t){this._procedureDemux.killConsumer(t)},ne.prototype.getProcedureConsumerStats=function(t){return this._procedureDemux.getConsumerStats(t)},ne.prototype.getProcedureConsumerStatsList=function(t){return this._procedureDemux.getConsumerStatsList(t)},ne.prototype.getAllProceduresConsumerStatsList=function(){return this._procedureDemux.getConsumerStatsListAll()},ne.prototype.getProcedureBackpressure=function(t){return this._procedureDemux.getBackpressure(t)},ne.prototype.getAllProceduresBackpressure=function(){return this._procedureDemux.getBackpressureAll()},ne.prototype.getProcedureConsumerBackpressure=function(t){return this._procedureDemux.getConsumerBackpressure(t)},ne.prototype.hasProcedureConsumer=function(t,e){return this._procedureDemux.hasConsumer(t,e)},ne.prototype.hasAnyProcedureConsumer=function(t){return this._procedureDemux.hasConsumerAll(t)},ne.prototype.channel=function(t){return this._channelMap[t],new Ft(t,this,this._channelEventDemux,this._channelDataDemux)},ne.prototype.closeChannel=function(t){this.channelCloseOutput(t),this.channelCloseAllListeners(t)},ne.prototype.closeAllChannelOutputs=function(){this._channelDataDemux.closeAll()},ne.prototype.closeAllChannelListeners=function(){this._channelEventDemux.closeAll()},ne.prototype.closeAllChannels=function(){this.closeAllChannelOutputs(),this.closeAllChannelListeners()},ne.prototype.killChannel=function(t){this.channelKillOutput(t),this.channelKillAllListeners(t)},ne.prototype.killAllChannelOutputs=function(){this._channelDataDemux.killAll()},ne.prototype.killAllChannelListeners=function(){this._channelEventDemux.killAll()},ne.prototype.killAllChannels=function(){this.killAllChannelOutputs(),this.killAllChannelListeners()},ne.prototype.killChannelOutputConsumer=function(t){this._channelDataDemux.killConsumer(t)},ne.prototype.killChannelListenerConsumer=function(t){this._channelEventDemux.killConsumer(t)},ne.prototype.getChannelOutputConsumerStats=function(t){return this._channelDataDemux.getConsumerStats(t)},ne.prototype.getChannelListenerConsumerStats=function(t){return this._channelEventDemux.getConsumerStats(t)},ne.prototype.getAllChannelOutputsConsumerStatsList=function(){return this._channelDataDemux.getConsumerStatsListAll()},ne.prototype.getAllChannelListenersConsumerStatsList=function(){return this._channelEventDemux.getConsumerStatsListAll()},ne.prototype.getChannelBackpressure=function(t){return Math.max(this.channelGetOutputBackpressure(t),this.channelGetAllListenersBackpressure(t))},ne.prototype.getAllChannelOutputsBackpressure=function(){return this._channelDataDemux.getBackpressureAll()},ne.prototype.getAllChannelListenersBackpressure=function(){return this._channelEventDemux.getBackpressureAll()},ne.prototype.getAllChannelsBackpressure=function(){return Math.max(this.getAllChannelOutputsBackpressure(),this.getAllChannelListenersBackpressure())},ne.prototype.getChannelListenerConsumerBackpressure=function(t){return this._channelEventDemux.getConsumerBackpressure(t)},ne.prototype.getChannelOutputConsumerBackpressure=function(t){return this._channelDataDemux.getConsumerBackpressure(t)},ne.prototype.hasAnyChannelOutputConsumer=function(t){return this._channelDataDemux.hasConsumerAll(t)},ne.prototype.hasAnyChannelListenerConsumer=function(t){return this._channelEventDemux.hasConsumerAll(t)},ne.prototype.getChannelState=function(t){let e=this._channelMap[t];return e?e.state:Ft.UNSUBSCRIBED},ne.prototype.getChannelOptions=function(t){let e=this._channelMap[t];return e?{...e.options}:{}},ne.prototype._getAllChannelStreamNames=function(t){let e=this._channelEventDemux.getConsumerStatsListAll().filter((e=>0===e.stream.indexOf(`${t}/`))).reduce(((t,e)=>(t[e.stream]=!0,t)),{});return Object.keys(e)},ne.prototype.channelCloseOutput=function(t){this._channelDataDemux.close(t)},ne.prototype.channelCloseListener=function(t,e){this._channelEventDemux.close(`${t}/${e}`)},ne.prototype.channelCloseAllListeners=function(t){this._getAllChannelStreamNames(t).forEach((t=>{this._channelEventDemux.close(t)}))},ne.prototype.channelKillOutput=function(t){this._channelDataDemux.kill(t)},ne.prototype.channelKillListener=function(t,e){this._channelEventDemux.kill(`${t}/${e}`)},ne.prototype.channelKillAllListeners=function(t){this._getAllChannelStreamNames(t).forEach((t=>{this._channelEventDemux.kill(t)}))},ne.prototype.channelGetOutputConsumerStatsList=function(t){return this._channelDataDemux.getConsumerStatsList(t)},ne.prototype.channelGetListenerConsumerStatsList=function(t,e){return this._channelEventDemux.getConsumerStatsList(`${t}/${e}`)},ne.prototype.channelGetAllListenersConsumerStatsList=function(t){return this._getAllChannelStreamNames(t).map((t=>this._channelEventDemux.getConsumerStatsList(t))).reduce(((t,e)=>(e.forEach((e=>{t.push(e)})),t)),[])},ne.prototype.channelGetOutputBackpressure=function(t){return this._channelDataDemux.getBackpressure(t)},ne.prototype.channelGetListenerBackpressure=function(t,e){return this._channelEventDemux.getBackpressure(`${t}/${e}`)},ne.prototype.channelGetAllListenersBackpressure=function(t){let e=this._getAllChannelStreamNames(t).map((t=>this._channelEventDemux.getBackpressure(t)));return Math.max(...e.concat(0))},ne.prototype.channelHasOutputConsumer=function(t,e){return this._channelDataDemux.hasConsumer(t,e)},ne.prototype.channelHasListenerConsumer=function(t,e,r){return this._channelEventDemux.hasConsumer(`${t}/${e}`,r)},ne.prototype.channelHasAnyListenerConsumer=function(t,e){return this._getAllChannelStreamNames(t).some((t=>this._channelEventDemux.hasConsumer(t,e)))},ne.prototype.subscriptions=function(t){let e=[];return Object.keys(this._channelMap).forEach((r=>{(t||this._channelMap[r].state===Ft.SUBSCRIBED)&&e.push(r)})),e},ne.prototype.isSubscribed=function(t,e){let r=this._channelMap[t];return e?!!r:!!r&&r.state===Ft.SUBSCRIBED},ne.prototype.processPendingSubscriptions=function(){this.preparingPendingSubscriptions=!1;let t=[];Object.keys(this._channelMap).forEach((e=>{let r=this._channelMap[e];r.state===Ft.PENDING&&t.push(r)})),t.sort(((t,e)=>{let r=t.options.priority||0,n=e.options.priority||0;return r>n?-1:r{this._trySubscribe(t)}))};var oe,ie=ne,se=new Uint8Array(16);function ae(){if(!oe&&!(oe="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return oe(se)}var ue=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function ce(t){return"string"==typeof t&&ue.test(t)}for(var he,le,pe=[],fe=0;fe<256;++fe)pe.push((fe+256).toString(16).substr(1));function me(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=(pe[t[e+0]]+pe[t[e+1]]+pe[t[e+2]]+pe[t[e+3]]+"-"+pe[t[e+4]]+pe[t[e+5]]+"-"+pe[t[e+6]]+pe[t[e+7]]+"-"+pe[t[e+8]]+pe[t[e+9]]+"-"+pe[t[e+10]]+pe[t[e+11]]+pe[t[e+12]]+pe[t[e+13]]+pe[t[e+14]]+pe[t[e+15]]).toLowerCase();if(!ce(r))throw TypeError("Stringified UUID is invalid");return r}var de=0,ye=0;function ge(t){if(!ce(t))throw TypeError("Invalid UUID");var e,r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r}function be(t,e,r){function n(t,n,o,i){if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));for(var e=[],r=0;r>>9<<4)+1}function ke(t,e){var r=(65535&t)+(65535&e);return(t>>16)+(e>>16)+(r>>16)<<16|65535&r}function Ee(t,e,r,n,o,i){return ke((s=ke(ke(e,t),ke(n,i)))<<(a=o)|s>>>32-a,r);var s,a}function Ce(t,e,r,n,o,i,s){return Ee(e&r|~e&n,t,e,o,i,s)}function _e(t,e,r,n,o,i,s){return Ee(e&n|r&~n,t,e,o,i,s)}function we(t,e,r,n,o,i,s){return Ee(e^r^n,t,e,o,i,s)}function Se(t,e,r,n,o,i,s){return Ee(r^(e|~n),t,e,o,i,s)}var Ae=be("v3",48,(function(t){if("string"==typeof t){var e=unescape(encodeURIComponent(t));t=new Uint8Array(e.length);for(var r=0;r>5]>>>o%32&255,s=parseInt(n.charAt(i>>>4&15)+n.charAt(15&i),16);e.push(s)}return e}(function(t,e){t[e>>5]|=128<>5]|=(255&t[n/8])<>>32-e}var Ie=be("v5",80,(function(t){var e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if("string"==typeof t){var n=unescape(encodeURIComponent(t));t=[];for(var o=0;o>>0;v=b,b=g,g=Oe(y,30)>>>0,y=d,d=C}r[0]=r[0]+d>>>0,r[1]=r[1]+y>>>0,r[2]=r[2]+g>>>0,r[3]=r[3]+b>>>0,r[4]=r[4]+v>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]})),De=Ie;var xe=Object.freeze({__proto__:null,NIL:"00000000-0000-0000-0000-000000000000",parse:ge,stringify:me,v1:function(t,e,r){var n=e&&r||0,o=e||new Array(16),i=(t=t||{}).node||he,s=void 0!==t.clockseq?t.clockseq:le;if(null==i||null==s){var a=t.random||(t.rng||ae)();null==i&&(i=he=[1|a[0],a[1],a[2],a[3],a[4],a[5]]),null==s&&(s=le=16383&(a[6]<<8|a[7]))}var u=void 0!==t.msecs?t.msecs:Date.now(),c=void 0!==t.nsecs?t.nsecs:ye+1,h=u-de+(c-ye)/1e4;if(h<0&&void 0===t.clockseq&&(s=s+1&16383),(h<0||u>de)&&void 0===t.nsecs&&(c=0),c>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");de=u,ye=c,le=s;var l=(1e4*(268435455&(u+=122192928e5))+c)%4294967296;o[n++]=l>>>24&255,o[n++]=l>>>16&255,o[n++]=l>>>8&255,o[n++]=255&l;var p=u/4294967296*1e4&268435455;o[n++]=p>>>8&255,o[n++]=255&p,o[n++]=p>>>24&15|16,o[n++]=p>>>16&255,o[n++]=s>>>8|128,o[n++]=255&s;for(var f=0;f<6;++f)o[n+f]=i[f];return e||me(o)},v3:Te,v4:function(t,e,r){var n=(t=t||{}).random||(t.rng||ae)();if(n[6]=15&n[6]|64,n[8]=63&n[8]|128,e){r=r||0;for(var o=0;o<16;++o)e[r+o]=n[o];return e}return me(n)},v5:De,validate:ce,version:function(t){if(!ce(t))throw TypeError("Invalid UUID");return parseInt(t.substr(14,1),16)}});const Le=ie,Ne=e(xe),Pe=J.InvalidArgumentsError;function Ue(t,e){let r=null==t.secure?e:t.secure;return t.port||("undefined"!=typeof location&&location.port?location.port:r?443:80)}const Re=ie,je={create:function(t){if((t=t||{}).host&&!t.host.match(/[^:]+:\d{2,5}/))throw new Pe("The host option should include both the hostname and the port number in the hostname:port format");if(t.host&&t.hostname)throw new Pe("The host option should already include the hostname and the port number in the hostname:port format - Because of this, you should never use host and hostname options together");if(t.host&&t.port)throw new Pe("The host option should already include the hostname and the port number in the hostname:port format - Because of this, you should never use host and port options together");let e="undefined"!=typeof location&&"https:"===location.protocol,r={clientId:Ne.v4(),port:Ue(t,e),hostname:"undefined"!=typeof location&&location.hostname||"localhost",secure:e};return Object.assign(r,t),new Le(r)}},Me="19.2.7";var He=r.factory=je,Ge=r.AGClientSocket=Re,$e=r.create=function(t){return je.create({...t,version:Me})},Fe=r.version=Me,ze=t({__proto__:null,AGClientSocket:Ge,create:$e,default:r,factory:He,version:Fe},[r]);const{factory:qe,AGClientSocket:Ve,create:We,version:Ke}=ze;export{Ve as AGClientSocket,We as create,qe as factory,Ke as version}; diff --git a/app/server.js b/app/server.js index cdcd6a56..bb131a7b 100644 --- a/app/server.js +++ b/app/server.js @@ -1,12 +1,16 @@ -const http = require('http'); -const eetase = require('eetase'); -const socketClusterServer = require('socketcluster-server'); -const express = require('express'); -const serveStatic = require('serve-static'); -const path = require('path'); -const morgan = require('morgan'); -const uuid = require('uuid'); -const sccBrokerClient = require('scc-broker-client'); +import http from 'http'; +import eetase from 'eetase'; +import socketClusterServer from 'socketcluster-server'; +import express from 'express'; +import serveStatic from 'serve-static'; +import path from 'path'; +import morgan from 'morgan'; +import { v4 as uuidv4 } from 'uuid'; +import sccBrokerClient from 'scc-broker-client'; +import { fileURLToPath } from 'url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); const ENVIRONMENT = process.env.ENV || 'dev'; const SOCKETCLUSTER_PORT = process.env.SOCKETCLUSTER_PORT || 8000; @@ -14,7 +18,7 @@ const SOCKETCLUSTER_WS_ENGINE = process.env.SOCKETCLUSTER_WS_ENGINE || 'ws'; const SOCKETCLUSTER_SOCKET_CHANNEL_LIMIT = Number(process.env.SOCKETCLUSTER_SOCKET_CHANNEL_LIMIT) || 1000; const SOCKETCLUSTER_LOG_LEVEL = process.env.SOCKETCLUSTER_LOG_LEVEL || 2; -const SCC_INSTANCE_ID = uuid.v4(); +const SCC_INSTANCE_ID = uuidv4(); const SCC_STATE_SERVER_HOST = process.env.SCC_STATE_SERVER_HOST || null; const SCC_STATE_SERVER_PORT = process.env.SCC_STATE_SERVER_PORT || null; const SCC_MAPPING_ENGINE = process.env.SCC_MAPPING_ENGINE || null; @@ -60,7 +64,7 @@ expressApp.get('/health-check', (req, res) => { // SocketCluster/WebSocket connection handling loop. (async () => { - for await (let {socket} of agServer.listener('connection')) { + for await (let { socket } of agServer.listener('connection')) { // Handle socket connection. } })(); @@ -69,7 +73,7 @@ httpServer.listen(SOCKETCLUSTER_PORT); if (SOCKETCLUSTER_LOG_LEVEL >= 1) { (async () => { - for await (let {error} of agServer.listener('error')) { + for await (let { error } of agServer.listener('error')) { console.error(error); } })(); @@ -81,7 +85,7 @@ if (SOCKETCLUSTER_LOG_LEVEL >= 2) { ); (async () => { - for await (let {warning} of agServer.listener('warning')) { + for await (let { warning } of agServer.listener('warning')) { console.warn(warning); } })(); @@ -115,7 +119,7 @@ if (SCC_STATE_SERVER_HOST) { if (SOCKETCLUSTER_LOG_LEVEL >= 1) { (async () => { - for await (let {error} of sccClient.listener('error')) { + for await (let { error } of sccClient.listener('error')) { error.name = 'SCCError'; console.error(error); } diff --git a/bin/actions/create.js b/bin/actions/create.js new file mode 100644 index 00000000..0887b7eb --- /dev/null +++ b/bin/actions/create.js @@ -0,0 +1,214 @@ +const fs = require('fs-extra'); +const { spawn } = require('child_process'); +const YAML = require('yamljs'); + +const { + destDir, + fileExistsSync, + appDir, + getSCCWorkerDeploymentDefPath, + sanitizeYAML, + clientFileDestPath, + clientFileSourcePath, +} = require('../lib'); + +const copyDirRecursive = (src, dest, opts) => { + try { + fs.copySync(src, dest); + return true; + } catch (e) { + opts.errorLog( + 'Failed to create necessary files. Please check your permissions and try again.', + ); + } + return false; +}; + +const createSuccess = (destinationDir, opts) => { + console.log( + 'Installing app dependencies using npm. This could take a while...', + ); + + const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm'; + const options = { + cwd: destinationDir, + maxBuffer: Infinity, + }; + + const npmProcess = spawn(npmCommand, ['install'], options); + + npmProcess.stdout.on('data', (data) => { + process.stdout.write(data); + }); + + npmProcess.stderr.on('data', (data) => { + process.stderr.write(data); + }); + + npmProcess.on('close', (code) => { + const clientFileDestination = clientFileDestPath(destinationDir); + const clientFileSource = clientFileSourcePath(destinationDir); + + if (code) { + opts.errorLog( + `Failed to install npm dependencies. Exited with code ${code}.`, + ); + } else { + try { + fs.writeFileSync( + clientFileDestination, + fs.readFileSync(clientFileSource), + ); + opts.successLog( + `SocketCluster app "${destinationDir}" was setup successfully.`, + ); + } catch (err) { + opts.errorLog( + `Failed to copy file from "${clientFileSource}" to "${clientFileDestination}" - Try copying it manually.`, + code, + ); + } + } + }); + + npmProcess.stdin.end(); +}; + +const setupMessage = function () { + console.log('Creating app structure...'); +}; + +const confirmReplaceSetup = function (confirm, destinationDir, opts) { + const rmdirRecursive = function (dirname) { + try { + fs.removeSync(dirname); + return true; + } catch (e) { + opts.errorLog( + `Failed to remove existing directory at ${dirPath}. This directory may be used by another program or you may not have the permission to remove it.`, + ); + } + return false; + }; + + if (confirm) { + setupMessage(); + if ( + rmdirRecursive(destinationDir) && + copyDirRecursive(appDir, destinationDir, opts) + ) { + createSuccess(null, this); + } else { + this.errorLog(); + } + } else { + this.errorLog('SocketCluster "create" action was aborted.'); + } +}; + +const create = async function (app, options) { + const destinationDir = destDir(app); + + let transformK8sConfigs = function () { + return new Promise((resolve, reject) => { + let kubernetesTargetDir = destinationDir + '/kubernetes'; + let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath( + kubernetesTargetDir, + ); + try { + let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, { + encoding: 'utf8', + }); + let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker); + + deploymentConfSCCWorker.spec.template.spec.volumes = [ + { + name: 'app-src-volume', + emptyDir: {}, + }, + ]; + + let containers = deploymentConfSCCWorker.spec.template.spec.containers; + let templateSpec = deploymentConfSCCWorker.spec.template.spec; + + if (!templateSpec.initContainers) { + templateSpec.initContainers = []; + } + let initContainers = templateSpec.initContainers; + let appSrcContainerIndex; + containers.forEach((value, index) => { + if (value && value.name == 'scc-worker') { + appSrcContainerIndex = index; + return; + } + }); + if (!containers[appSrcContainerIndex].volumeMounts) { + containers[appSrcContainerIndex].volumeMounts = []; + } + containers[appSrcContainerIndex].volumeMounts.push({ + mountPath: '/usr/src/app', + name: 'app-src-volume', + }); + initContainers.push({ + name: 'app-src-container', + image: '', // image name will be generated during deployment + volumeMounts: [ + { + mountPath: '/usr/dest', + name: 'app-src-volume', + }, + ], + command: ['cp', '-a', '/usr/src/.', '/usr/dest/'], + }); + let formattedYAMLString = sanitizeYAML( + YAML.stringify(deploymentConfSCCWorker, Infinity, 2), + ); + fs.writeFileSync(kubeConfSCCWorker, formattedYAMLString); + } catch (err) { + reject(err); + } + resolve(); + }); + }; + + if (app) { + if (fileExistsSync(destinationDir)) { + if (options.force) { + confirmReplaceSetup(true, destinationDir, this); + } else { + let message = `There is already a directory at ${destinationDir}. Do you want to overwrite it?`; + if ( + await this.promptConfirm( + message, + { default: true }, + confirmReplaceSetup, + ) + ) { + createSuccess(destinationDir, this); + } + } + } else { + setupMessage(); + if (copyDirRecursive(appDir, destinationDir, this)) { + try { + await transformK8sConfigs(); + createSuccess(destinationDir, this); + } catch (err) { + this.errorLog( + `Failed to format Kubernetes configs. Failed to create SocketCluster app. ${err}`, + ); + } + } else { + this.errorLog('Failed to create SocketCluster app.'); + } + } + } else { + this.errorLog( + 'The "create" command requires a valid as argument.', + ); + showCorrectUsage(); + process.exit(); + } +}; + +module.exports = { create }; diff --git a/bin/actions/docker.js b/bin/actions/docker.js new file mode 100644 index 00000000..b3d7adb4 --- /dev/null +++ b/bin/actions/docker.js @@ -0,0 +1,129 @@ +const path = require('path'); +const { execSync, exec } = require('child_process'); +const scVersion = require('../../package.json').version; + +const { parsePackageFile } = require('../lib'); + +const dockerStop = async function (arg) { + let appName = arg; + if (!appName) { + let appPath = '.'; + let pkg = parsePackageFile(appPath); + appName = pkg.name; + } + try { + execSync(`docker stop ${appName}`); + execSync(`docker rm ${appName}`); + this.successLog(`App '${appName}' was stopped.`); + } catch (e) { + this.errorLog(`Failed to stop app '${appName}'.`); + } + process.exit(); +}; + +const dockerRestart = async function (arg) { + let appName = arg; + if (!appName) { + let appPath = '.'; + let pkg = parsePackageFile(appPath); + appName = pkg.name; + } + try { + execSync(`docker stop ${appName}`, { stdio: 'ignore' }); + this.successLog(`App '${appName}' was stopped.`, null, true); + } catch (e) {} + try { + execSync(`docker start ${appName}`); + this.successLog(`App '${appName}' is running.`); + } catch (e) { + this.errorLog(`Failed to start app '${appName}'.`); + } + process.exit(); +}; + +const dockerRun = async function (arg, options) { + let appPath = arg || '.'; + let absoluteAppPath = path.resolve(appPath); + let pkg = parsePackageFile(appPath); + let appName = pkg.name; + + let portNumber = Number(options.p) || 8000; + let envVarList; + if (options.e === undefined) { + envVarList = []; + } else if (!Array.isArray(options.e)) { + envVarList = [options.e]; + } else { + envVarList = options.e; + } + let envFlagList = envVarList.map((value) => { + return `-e "${value}"`; + }); + let envFlagString = envFlagList.join(' '); + if (envFlagList.length > 0) { + envFlagString += ' '; + } + + try { + execSync(`docker stop ${appName}`, { stdio: 'ignore' }); + execSync(`docker rm ${appName}`, { stdio: 'ignore' }); + } catch (e) {} + + let dockerCommand = + `docker run -d -p ${portNumber}:8000 -v ${absoluteAppPath}:/usr/src/app/ ` + + `${envFlagString}--name ${appName} socketcluster/socketcluster:v${scVersion} `; + try { + execSync(dockerCommand, { stdio: 'inherit' }); + this.successLog( + `App "${appName}" is running at http://localhost:${portNumber}`, + ); + } catch (e) { + this.errorLog(`Failed to start app "${appName}".`); + } + process.exit(); +}; + +const dockerList = async function () { + const commandRawArgsString = ''; + + let command = exec(`docker ps${commandRawArgsString}`, (err) => { + if (err) { + this.errorLog(`Failed to list active containers. ` + err); + } + process.exit(); + }); + command.stdout.pipe(process.stdout); + command.stderr.pipe(process.stderr); +}; + +const dockerLogs = async function (arg, options) { + let appName; + let commandRawArgsString = ''; + if (options.f) commandRawArgsString = ' -f'; + if (arg) { + appName = arg; + } + + if (!appName) { + let appPath = '.'; + let pkg = parsePackageFile(appPath); + appName = pkg.name; + } + + let command = exec(`docker logs ${appName}${commandRawArgsString}`, (err) => { + if (err) { + this.errorLog(`Failed to get logs for '${appName}' app. ` + err); + } + process.exit(); + }); + command.stdout.pipe(process.stdout); + command.stderr.pipe(process.stderr); +}; + +module.exports = { + dockerRestart, + dockerRun, + dockerStop, + dockerList, + dockerLogs, +}; diff --git a/bin/actions/index.js b/bin/actions/index.js new file mode 100644 index 00000000..f923cb50 --- /dev/null +++ b/bin/actions/index.js @@ -0,0 +1,9 @@ +const create = require('./create'); +const docker = require('./docker'); +const k8s = require('./k8s'); + +module.exports = { + ...create, + ...docker, + ...k8s, +}; diff --git a/bin/actions/k8s.js b/bin/actions/k8s.js new file mode 100644 index 00000000..e50500b9 --- /dev/null +++ b/bin/actions/k8s.js @@ -0,0 +1,519 @@ +const path = require('path'); +const { execSync } = require('child_process'); +const fs = require('fs-extra'); +const YAML = require('yamljs'); + +const { + parsePackageFile, + parseJSONFile, + getSCCWorkerDeploymentDefPath, + getSCCBrokerDeploymentDefPath, + sanitizeYAML, +} = require('../lib'); + +const DEFAULT_TLS_SECRET_NAME = 'scc-tls-credentials'; + +let dockerUsername, dockerPassword; +let saveDockerAuthDetails = null; + +let tlsSecretName = null; +let tlsKeyPath = null; +let tlsCertPath = null; + +const uploadTLSSecret = function ( + secretName, + privateKeyPath, + certFilePath, + errorLogger, +) { + try { + execSync( + `kubectl create secret tls ${secretName} --key ${privateKeyPath} --cert ${certFilePath}`, + { stdio: 'inherit' }, + ); + } catch (err) { + errorLogger( + 'Failed to upload TLS key and certificate pair to Kubernetes. ' + + 'You can try using the following command to upload them manually: ' + + `kubectl create secret tls ${secretName} --key ${privateKeyPath} --cert ${certFilePath}`, + ); + return false; + } + return true; +}; + +const removeTLSSecret = function (secretName, errorLogger) { + try { + execSync(`kubectl delete secret ${secretName}`, { stdio: 'inherit' }); + } catch (err) { + errorLogger( + `Failed to remove TLS key and certificate pair "${secretName}" from Kubernetes. ` + + 'You can try using the following command to remove them manually: ' + + `kubectl delete secret ${secretName}`, + ); + return false; + } + return true; +}; + +const k8sDeployAndDeployUpdate = async function (arg1, options, updateRequest) { + let dockerImageName, dockerDefaultImageName; + let dockerDefaultImageVersionTag = 'v1.0.0'; + let nextVersionTag; + + const self = this + + let appPath = arg1 || '.'; + let pkg = parsePackageFile(appPath); + let appName = pkg.name; + + let isUpdate = updateRequest; + + let failedToDeploy = (err) => { + this.errorLog(`Failed to deploy the '${appName}' app. ${err.message}`); + process.exit(); + }; + + let socketClusterK8sConfigFilePath = appPath + '/socketcluster-k8s.json'; + let socketClusterK8sConfig = parseJSONFile(socketClusterK8sConfigFilePath); + + let addAuthDetailsToSocketClusterK8s = function ( + socketClusterK8sConfigJSON, + username, + password, + ) { + if (!socketClusterK8sConfigJSON.docker) { + socketClusterK8sConfigJSON.docker = {}; + } + socketClusterK8sConfigJSON.docker.auth = Buffer.from( + `${username}:${password}`, + 'utf8', + ).toString('base64'); + }; + + let saveSocketClusterK8sConfigFile = function (socketClusterK8sConfigJSON) { + fs.writeFileSync( + socketClusterK8sConfigFilePath, + JSON.stringify(socketClusterK8sConfigJSON, null, 2), + ); + }; + + let parseVersionTag = function (fullImageName) { + let matches = fullImageName.match(/:[^:]*$/); + if (!matches) { + return ''; + } + return matches[0] || ''; + }; + + let setImageVersionTag = function (imageName, versionTag) { + if (versionTag.indexOf(':') !== 0) { + versionTag = ':' + versionTag; + } + return imageName.replace(/(\/[^\/:]*)(:[^:]*)?$/g, `$1${versionTag}`); + }; + + let promptDockerAuthDetails = async () => { + let username, password; + + // Check if username is specified + if (dockerUsername == null) { + username = await this.promptInput('Enter your Docker registry username:'); + dockerUsername = username.toLowerCase(); + } + + // Check if password is specified + if (dockerPassword == null) { + password = await this.promptInput( + 'Enter your Docker registry password:', + true, + ); + dockerPassword = password; + } + + const confirmation = await this.promptConfirm( + `Would you like to save your Docker registry username and password as Base64 to ${socketClusterK8sConfigFilePath}?`, + { default: true }, + ); + + if (confirmation) { + saveDockerAuthDetails = confirmation; + } + + return Promise.resolve({ + username: dockerUsername, + password: dockerPassword, + saveDockerAuthDetails, + }); + }; + + let performDeployment = function ( + dockerConfig, + versionTag, + username, + password, + ) { + let dockerLoginCommand = `docker login -u "${username}" -p "${password}"`; + + let fullVersionTag; + if (versionTag) { + fullVersionTag = `:${versionTag}`; + } else { + fullVersionTag = parseVersionTag(dockerConfig.imageName); + } + dockerConfig.imageName = setImageVersionTag( + dockerConfig.imageName, + fullVersionTag, + ); + if (saveDockerAuthDetails) { + addAuthDetailsToSocketClusterK8s( + socketClusterK8sConfig, + username, + password, + ); + } + try { + saveSocketClusterK8sConfigFile(socketClusterK8sConfig); + execSync(`docker build -t ${dockerConfig.imageName} .`, { + stdio: 'inherit', + }); + execSync(`${dockerLoginCommand}; docker push ${dockerConfig.imageName}`, { + stdio: 'inherit', + }); + + if (tlsSecretName && tlsKeyPath && tlsCertPath) { + uploadTLSSecret(tlsSecretName, tlsKeyPath, tlsCertPath, warningMessage); + } + + let kubernetesDirPath = appPath + '/kubernetes'; + + let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath(kubernetesDirPath); + let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, { + encoding: 'utf8', + }); + + let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker); + + let initContainersSCCWorker = + deploymentConfSCCWorker.spec.template.spec.initContainers; + initContainersSCCWorker.forEach((value, index) => { + if (value) { + if (value.name === 'app-src-container') { + initContainersSCCWorker[index].image = dockerConfig.imageName; + } + } + }); + + let formattedYAMLStringSCCWorker = sanitizeYAML( + YAML.stringify(deploymentConfSCCWorker, Infinity, 2), + ); + fs.writeFileSync(kubeConfSCCWorker, formattedYAMLStringSCCWorker); + + let kubeConfSCCBroker = getSCCBrokerDeploymentDefPath(kubernetesDirPath); + let kubeConfContentSCCBroker = fs.readFileSync(kubeConfSCCBroker, { + encoding: 'utf8', + }); + + let deploymentConfSCCBroker = YAML.parse(kubeConfContentSCCBroker); + + let formattedYAMLStringSCCBroker = sanitizeYAML( + YAML.stringify(deploymentConfSCCBroker, Infinity, 2), + ); + fs.writeFileSync(kubeConfSCCBroker, formattedYAMLStringSCCBroker); + + let ingressKubeFileName = 'scc-ingress.yaml'; + let sccWorkerDeploymentFileName = 'scc-worker-deployment.yaml'; + + let deploySuccess = () => { + self.successLog( + `The '${appName}' app was deployed successfully - You should be able to access it online ` + + `once it has finished booting up. This can take a while depending on your platform.`, + ); + process.exit(); + }; + + if (isUpdate) { + try { + execSync( + `kubectl replace -f ${kubernetesDirPath}/${sccWorkerDeploymentFileName}`, + { stdio: 'inherit' }, + ); + } catch (err) {} + + deploySuccess(); + } else { + let kubeFiles = fs.readdirSync(kubernetesDirPath); + let serviceAndDeploymentKubeFiles = kubeFiles.filter( + (configFilePath) => { + return configFilePath != ingressKubeFileName; + }, + ); + serviceAndDeploymentKubeFiles.forEach((configFilePath) => { + let absolutePath = path.resolve(kubernetesDirPath, configFilePath); + execSync(`kubectl create -f ${absolutePath}`, { stdio: 'inherit' }); + }); + + // Wait a few seconds before deploying ingress (due to a bug in some environments). + setTimeout(() => { + try { + execSync( + `kubectl create -f ${kubernetesDirPath}/${ingressKubeFileName}`, + { stdio: 'inherit' }, + ); + deploySuccess(); + } catch (err) { + failedToDeploy(err); + } + }, 7000); + } + } catch (err) { + failedToDeploy(err); + } + }; + + let incrementVersion = function (versionString) { + return versionString.replace(/[^.]$/, (match) => { + return parseInt(match) + 1; + }); + }; + + let pushToDockerImageRepo = async () => { + let versionTagString = parseVersionTag( + socketClusterK8sConfig.docker.imageName, + ).replace(/^:/, ''); + if (versionTagString) { + if (isUpdate) { + nextVersionTag = incrementVersion(versionTagString); + } else { + nextVersionTag = versionTagString; + } + } else { + nextVersionTag = dockerDefaultImageVersionTag; + } + + const versionTag = await this.promptInput( + `Enter the Docker version tag for this deployment (Default: ${nextVersionTag}):`, + ); + + socketClusterK8sConfig.docker.imageName = setImageVersionTag( + socketClusterK8sConfig.docker.imageName, + nextVersionTag, + ); + let dockerConfig = socketClusterK8sConfig.docker; + + if (dockerConfig.auth) { + let authParts = Buffer.from(dockerConfig.auth, 'base64') + .toString('utf8') + .split(':'); + dockerUsername = authParts[0]; + dockerPassword = authParts[1]; + performDeployment( + dockerConfig, + versionTag, + dockerUsername, + dockerPassword, + ); + } else { + if (!dockerUsername || !dockerPassword) { + const { username, password } = await promptDockerAuthDetails(); + performDeployment(dockerConfig, versionTag, username, password); + } else { + performDeployment( + dockerConfig, + versionTag, + dockerUsername, + dockerPassword, + ); + } + } + }; + + // If configuration file exists + if ( + socketClusterK8sConfig.docker && + socketClusterK8sConfig.docker.imageRepo + ) { + let versionTagString = parseVersionTag( + socketClusterK8sConfig.docker.imageName, + ).replace(/^:/, ''); + if (versionTagString) { + if (isUpdate) { + nextVersionTag = incrementVersion(versionTagString); + } else { + nextVersionTag = versionTagString; + } + } else { + nextVersionTag = dockerDefaultImageVersionTag; + } + + const versionTag = await this.promptInput( + `Enter the Docker version tag for this deployment (Default: ${nextVersionTag}):`, + ); + + socketClusterK8sConfig.docker.imageName = setImageVersionTag( + socketClusterK8sConfig.docker.imageName, + nextVersionTag, + ); + let dockerConfig = socketClusterK8sConfig.docker; + + if (dockerConfig.auth) { + let authParts = Buffer.from(dockerConfig.auth, 'base64') + .toString('utf8') + .split(':'); + dockerUsername = authParts[0]; + dockerPassword = authParts[1]; + performDeployment( + dockerConfig, + versionTag, + dockerUsername, + dockerPassword, + ); + } else { + const { username, password } = await promptDockerAuthDetails(); + + performDeployment(dockerConfig, versionTag, username, password); + } + // If configuration file doesn't exist + } else { + let saveSocketClusterK8sConfigs = function () { + socketClusterK8sConfig.docker = { + imageRepo: 'https://index.docker.io/v1/', + imageName: dockerImageName, + }; + + if (saveDockerAuthDetails) { + addAuthDetailsToSocketClusterK8s( + socketClusterK8sConfig, + dockerUsername, + dockerPassword, + ); + } + + try { + saveSocketClusterK8sConfigFile(socketClusterK8sConfig); + } catch (err) { + failedToDeploy(err); + } + pushToDockerImageRepo(); + }; + + const provideKeyAndCert = await this.promptConfirm( + 'Would you like to upload a TLS private key and certificate to your cluster? (both must be unencrypted)', + { default: true }, + ); + + if (provideKeyAndCert) { + const secretName = + (await this.promptInput( + `Insert a TLS secretName for Kubernetes (or press enter to leave it as "${DEFAULT_TLS_SECRET_NAME}" - Recommended):`, + )) || DEFAULT_TLS_SECRET_NAME; + const privateKeyPath = await this.promptInput( + 'Insert the path to a private key file to upload to K8s (or press enter to cancel):', + ); + + if (!privateKeyPath) { + return; + } + + const certFilePath = await this.promptInput( + 'Insert the path to a certificate file to upload to K8s (or press enter to cancel):', + ); + + if (!certFilePath) { + return; + } + + tlsSecretName = secretName; + tlsKeyPath = privateKeyPath; + tlsCertPath = certFilePath; + } + + await promptDockerAuthDetails(); + + dockerDefaultImageName = `${dockerUsername}/${appName}`; + + let imageName = await this.promptInput( + `Enter the Docker image name without the version tag (Or press enter for default: ${dockerDefaultImageName}):`, + ); + + imageName = imageName || dockerDefaultImageName; + let slashes = imageName.match(/\//g) || []; + if (slashes.length !== 1) { + failedToDeploy( + new Error( + 'Invalid Docker image name; it must be in the format organizationName/projectName', + ), + ); + } + dockerImageName = setImageVersionTag( + imageName, + dockerDefaultImageVersionTag, + ); + + // Save config file + saveSocketClusterK8sConfigs(); + } +}; + +const k8sUndeploy = async function (arg1) { + let appPath = arg1 || '.'; + + let pkg = parsePackageFile(appPath); + let appName = pkg.name; + + let kubernetesDirPath = appPath + '/kubernetes'; + let kubeFiles = fs.readdirSync(kubernetesDirPath); + kubeFiles.forEach((configFilePath) => { + let absolutePath = path.resolve(kubernetesDirPath, configFilePath); + try { + execSync(`kubectl delete -f ${absolutePath}`, { stdio: 'inherit' }); + } catch (err) {} + }); + + this.successLog(`The '${appName}' app was undeployed successfully.`); + + process.exit(); +}; + +const k8sAddSecret = async function (arg, options) { + let secretName = options.s || DEFAULT_TLS_SECRET_NAME; + let privateKeyPath = options.k; + let certFilePath = options.c; + + if (privateKeyPath == null || certFilePath == null) { + this.errorLog( + `Failed to upload secret. Both a key file path (-k) and a certificate file path (-c) must be provided.`, + ); + } else { + let success = uploadTLSSecret( + secretName, + privateKeyPath, + certFilePath, + this.errorLog, + ); + if (success) { + this.successLog( + `The private key and cert pair were added to your cluster under the secret name "${secretName}".`, + ); + } + } + process.exit(); +}; + +const k8sRemoveSecret = async function (arg, options) { + const secretName = options.s || DEFAULT_TLS_SECRET_NAME; + const success = removeTLSSecret(secretName, this.errorLog); + if (success) { + this.successLog( + `The private key and cert pair under the secret name "${secretName}" were removed from your cluster.`, + ); + } + process.exit(); +}; + +module.exports = { + k8sAddSecret, + k8sDeployAndDeployUpdate, + k8sRemoveSecret, + k8sUndeploy, +}; diff --git a/bin/cli.js b/bin/cli.js index b5209fd9..6a38bc9e 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -1,794 +1,89 @@ #!/usr/bin/env node -const fs = require('fs-extra'); -const path = require('path'); -const argv = require('minimist')(process.argv.slice(2)); -const childProcess = require('child_process'); -const inquirer = require('inquirer'); -const prompt = inquirer.createPromptModule(); -const exec = childProcess.exec; -const execSync = childProcess.execSync; -const spawn = childProcess.spawn; -const fork = childProcess.fork; -const YAML = require('yamljs'); - -const DEFAULT_TLS_SECRET_NAME = 'scc-tls-credentials'; - -let command = argv._[0]; -let commandRawArgs = process.argv.slice(3); -let commandRawArgsString = commandRawArgs.join(' '); -if (commandRawArgsString.length) { - commandRawArgsString = ' ' + commandRawArgsString; +const { REPLClient } = require('@maartennnn/cli-builder'); +const actions = require('./actions'); + +let helpFooter = + 'Note that the app-name/app-path in the commands above is optional (except for create) - If not provided, ' + + 'socketcluster will use the current working directory as the app path.'; + +const cli = new REPLClient({ + binCommand: 'socketcluster', + enableInteractive: false, + helpFooter, + actions, +}); + +if (cli.argv.v || cli.argv.version) { + cli.successLog(`Version: ${require('../package.json').version}`); + process.exit(0); } -let arg1 = argv._[1]; -let force = argv.force ? true : false; - -let dockerUsername, dockerPassword; -let saveDockerAuthDetails = null; - -let tlsSecretName = null; -let tlsKeyPath = null; -let tlsCertPath = null; - -let fileExistsSync = function (filePath) { - try { - fs.accessSync(filePath, fs.constants.F_OK); - } catch (err) { - return false; - } - return true; -}; - -let parseJSONFile = function (filePath) { - try { - if (fileExistsSync(filePath)) { - return JSON.parse(fs.readFileSync(filePath, {encoding: 'utf8'})); - } - } catch (e) {} - - return {}; -}; - -let parsePackageFile = function (moduleDir) { - let packageFile = path.join(moduleDir, 'package.json'); - return parseJSONFile(packageFile); -}; - -let errorMessage = function (message) { - console.log(`\x1b[31m[Error]\x1b[0m ${message}`); -}; - -let successMessage = function (message) { - console.log(`\x1b[32m[Success]\x1b[0m ${message}`); -}; - -let warningMessage = function (message) { - console.log(`\x1b[33m[Warning]\x1b[0m ${message}`); -}; - -let showCorrectUsage = function () { - console.log('Usage: socketcluster [options] [command]\n'); - console.log('Options:'); - console.log(" -v Get the version of the current SocketCluster installation"); - console.log(' --help Get info on how to use this command'); - console.log(' --force Force all necessary directory modifications without prompts'); - console.log(); - console.log('Commands:'); - console.log(' create Create a new boilerplate app in your working directory'); - console.log(' run [requires docker] Run the app at path inside a container on your local machine'); - console.log(' restart [requires docker] Restart the app at path'); - console.log(' stop [requires docker] Stop the app'); - console.log(' list [requires docker] List all running Docker containers on your local machine'); - console.log(' logs [requires docker] Get logs for the specified app'); - console.log(' -f Follow the logs'); - console.log(' deploy [requires kubectl] Deploy the app at path to your Kubernetes cluster'); - console.log(' deploy-update [requires kubectl] Deploy update to an app which was previously deployed'); - console.log(' undeploy [requires kubectl] Shutdown all core app services running on your cluster'); - console.log(' add-secret [requires kubectl] Upload a TLS key and cert pair to your cluster'); - console.log(` -s Optional secret name; defaults to "${DEFAULT_TLS_SECRET_NAME}"`); - console.log(' -k Path to a key file'); - console.log(' -c Path to a certificate file'); - console.log(' remove-secret [requires kubectl] Remove a TLS key and cert pair from your cluster'); - console.log(` -s Optional secret name; defaults to "${DEFAULT_TLS_SECRET_NAME}"`); - console.log(''); - let extraMessage = 'Note that the app-name/app-path in the commands above is optional (except for create) - If not provided, ' + - 'socketcluster will use the current working directory as the app path.'; - console.log(extraMessage); -}; - -let failedToRemoveDirMessage = function (dirPath) { - errorMessage( - `Failed to remove existing directory at ${dirPath}. This directory may be used by another program or you may not have the permission to remove it.` - ); -}; - -let failedToCreateMessage = function () { - errorMessage('Failed to create necessary files. Please check your permissions and try again.'); -}; - -let promptInput = function (message, callback, secret) { - prompt([ - { - type: secret ? 'password' : 'input', - message: message, - name: 'result', - default: null - } - ]).then((answers) => { - callback(answers.result); - }).catch((err) => { - errorMessage(err.message); - process.exit(); - }); -}; - -let promptConfirm = function (message, options, callback) { - let promptOptions = { - type: 'confirm', - message: message, - name: 'result' - }; - if (options && options.default) { - promptOptions.default = options.default; - } - prompt([ - promptOptions - ]).then((answers) => { - callback(answers.result); - }).catch((err) => { - errorMessage(err.message); - process.exit(); - }); -}; - -let copyDirRecursive = function (src, dest) { - try { - fs.copySync(src, dest); - return true; - } catch (e) { - failedToCreateMessage(); - } - return false; -}; - -let rmdirRecursive = function (dirname) { - try { - fs.removeSync(dirname); - return true; - } catch (e) { - failedToRemoveDirMessage(dirname); - } - return false; -}; - -let sanitizeYAML = function (yamlString) { - return yamlString.replace(/emptyDir: ?(null)?\n/g, 'emptyDir: {}\n'); -}; - -if (argv.help) { - showCorrectUsage(); - process.exit(); -}; - -if (argv.v) { - let agDir = `${__dirname}/../`; - let agPkg = parsePackageFile(agDir); - console.log('v' + agPkg.version); - process.exit(); -}; - -let wd = process.cwd(); - -let appDir = `${__dirname}/../app`; -let destDir = path.normalize(`${wd}/${arg1}`); -let clientFileSourcePath = path.normalize(`${destDir}/node_modules/socketcluster-client/socketcluster-client.js`); -let clientFileDestPath = path.normalize(`${destDir}/public/socketcluster-client.js`); -let deploymentYAMLRegex = /-deployment\.yaml$/; - -let createFail = function (error) { - if (error) { - errorMessage(`Failed to create SocketCluster app. ${error}`); - } else { - errorMessage('Failed to create SocketCluster app.'); - } - process.exit(); -}; - -let createSuccess = function () { - console.log('Installing app dependencies using npm. This could take a while...'); - - let npmCommand = (process.platform === "win32" ? "npm.cmd" : "npm"); - let options = { - cwd: destDir, - maxBuffer: Infinity - }; - - let npmProcess = spawn(npmCommand, ['install'], options); - - npmProcess.stdout.on('data', (data) => { - process.stdout.write(data); - }); - - npmProcess.stderr.on('data', (data) => { - process.stderr.write(data); - }); - - npmProcess.on('close', (code) => { - if (code) { - errorMessage(`Failed to install npm dependencies. Exited with code ${code}.`); - } else { - try { - fs.writeFileSync(clientFileDestPath, fs.readFileSync(clientFileSourcePath)); - successMessage(`SocketCluster app "${destDir}" was setup successfully.`); - } catch (err) { - warningMessage( - `Failed to copy file from "${clientFileSourcePath}" to "${clientFileDestPath}" - Try copying it manually.` - ); - } - } - process.exit(code); - }); - - npmProcess.stdin.end(); -}; - -let setupMessage = function () { - console.log('Creating app structure...'); -}; - -let confirmReplaceSetup = function (confirm) { - if (confirm) { - setupMessage(); - if (rmdirRecursive(destDir) && copyDirRecursive(appDir, destDir)) { - createSuccess(); - } else { - createFail(); - } - } else { - errorMessage('SocketCluster "create" action was aborted.'); - process.exit(); - } -}; - -let getSCCWorkerDeploymentDefPath = function (kubernetesTargetDir) { - return `${kubernetesTargetDir}/scc-worker-deployment.yaml`; -}; - -let getSCCBrokerDeploymentDefPath = function (kubernetesTargetDir) { - return `${kubernetesTargetDir}/scc-broker-deployment.yaml`; -}; - -let promptSecret = function (callback) { - promptInput(`Insert a TLS secretName for Kubernetes (or press enter to leave it as "${DEFAULT_TLS_SECRET_NAME}" - Recommended):`, (secretName) => { - secretName = secretName || DEFAULT_TLS_SECRET_NAME; - promptInput('Insert the path to a private key file to upload to K8s (or press enter to cancel):', (privateKeyPath) => { - if (!privateKeyPath) { - callback(); - return; - } - promptInput('Insert the path to a certificate file to upload to K8s (or press enter to cancel):', (certFilePath) => { - if (!certFilePath) { - callback(); - return; - } - tlsSecretName = secretName; - tlsKeyPath = privateKeyPath; - tlsCertPath = certFilePath; - callback(secretName, privateKeyPath, certFilePath); - }); - }); - }); -}; - -let promptK8sTLSCredentials = function (callback) { - promptConfirm('Would you like to upload a TLS private key and certificate to your cluster? (both must be unencrypted)', {default: true}, (provideKeyAndCert) => { - if (provideKeyAndCert) { - promptSecret(callback); - } else { - callback(); - } - }); -}; - -let uploadTLSSecret = function (secretName, privateKeyPath, certFilePath, errorLogger) { - try { - execSync(`kubectl create secret tls ${secretName} --key ${privateKeyPath} --cert ${certFilePath}`, {stdio: 'inherit'}); - } catch (err) { - errorLogger( - 'Failed to upload TLS key and certificate pair to Kubernetes. ' + - 'You can try using the following command to upload them manually: ' + - `kubectl create secret tls ${secretName} --key ${privateKeyPath} --cert ${certFilePath}` - ); - return false; - } - return true; -}; - -let removeTLSSecret = function (secretName, errorLogger) { - try { - execSync(`kubectl delete secret ${secretName}`, {stdio: 'inherit'}); - } catch (err) { - errorLogger( - `Failed to remove TLS key and certificate pair "${secretName}" from Kubernetes. ` + - 'You can try using the following command to remove them manually: ' + - `kubectl delete secret ${secretName}` - ); - return false; - } - return true; -}; - -if (command === 'create') { - let transformK8sConfigs = function (callback) { - let kubernetesTargetDir = destDir + '/kubernetes'; - let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath(kubernetesTargetDir); - try { - let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, {encoding: 'utf8'}); - let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker); - - deploymentConfSCCWorker.spec.template.spec.volumes = [{ - name: 'app-src-volume', - emptyDir: {} - }]; - let containers = deploymentConfSCCWorker.spec.template.spec.containers; - let templateSpec = deploymentConfSCCWorker.spec.template.spec; - if (!templateSpec.initContainers) { - templateSpec.initContainers = []; - } - let initContainers = templateSpec.initContainers; - let appSrcContainerIndex; - containers.forEach((value, index) => { - if (value && value.name == 'scc-worker') { - appSrcContainerIndex = index; - return; - } - }); - if (!containers[appSrcContainerIndex].volumeMounts) { - containers[appSrcContainerIndex].volumeMounts = []; - } - containers[appSrcContainerIndex].volumeMounts.push({ - mountPath: '/usr/src/app', - name: 'app-src-volume' - }); - initContainers.push({ - name: 'app-src-container', - image: '', // image name will be generated during deployment - volumeMounts: [{ - mountPath: '/usr/dest', - name: 'app-src-volume' - }], - command: ['cp', '-a', '/usr/src/.', '/usr/dest/'] - }); - let formattedYAMLString = sanitizeYAML(YAML.stringify(deploymentConfSCCWorker, Infinity, 2)); - fs.writeFileSync(kubeConfSCCWorker, formattedYAMLString); - } catch (err) { - callback(err); - return; - } - callback(); - }; - - if (arg1) { - if (fileExistsSync(destDir)) { - if (force) { - confirmReplaceSetup(true); - } else { - let message = `There is already a directory at ${destDir}. Do you want to overwrite it?`; - promptConfirm(message, {default: true}, confirmReplaceSetup); - } - } else { - setupMessage(); - if (copyDirRecursive(appDir, destDir)) { - transformK8sConfigs((err) => { - if (err) { - createFail(`Failed to format Kubernetes configs. ${err}`); - } else { - createSuccess(); - } - }); - } else { - createFail(); - } - } - } else { - errorMessage('The "create" command requires a valid as argument.'); - showCorrectUsage(); - process.exit(); - } -} else if (command === 'run') { - let appPath = arg1 || '.'; - let absoluteAppPath = path.resolve(appPath); - let pkg = parsePackageFile(appPath); - let appName = pkg.name; - - let portNumber = Number(argv.p) || 8000; - let envVarList; - if (argv.e === undefined) { - envVarList = []; - } else if (!Array.isArray(argv.e)) { - envVarList = [argv.e]; - } else { - envVarList = argv.e; - } - let envFlagList = envVarList.map((value) => { - return `-e "${value}"`; - }); - let envFlagString = envFlagList.join(' '); - if (envFlagList.length > 0) { - envFlagString += ' '; - } - - try { - execSync(`docker stop ${appName}`, {stdio: 'ignore'}); - execSync(`docker rm ${appName}`, {stdio: 'ignore'}); - } catch (e) {} - - let dockerCommand = `docker run -d -p ${portNumber}:8000 -v ${absoluteAppPath}:/usr/src/app/ ` + - `${envFlagString}--name ${appName} socketcluster/socketcluster:v15.0.0`; - try { - execSync(dockerCommand, {stdio: 'inherit'}); - successMessage(`App "${appName}" is running at http://localhost:${portNumber}`); - } catch (e) { - errorMessage(`Failed to start app "${appName}".`); - } - process.exit(); -} else if (command === 'restart') { - let appName = arg1; - if (!appName) { - let appPath = '.'; - let absoluteAppPath = path.resolve(appPath); - let pkg = parsePackageFile(appPath); - appName = pkg.name; - } - try { - execSync(`docker stop ${appName}`, {stdio: 'ignore'}); - successMessage(`App '${appName}' was stopped.`); - } catch (e) {} - try { - execSync(`docker start ${appName}`); - successMessage(`App '${appName}' is running.`); - } catch (e) { - errorMessage(`Failed to start app '${appName}'.`); - } - process.exit(); -} else if (command === 'stop') { - let appName = arg1; - if (!appName) { - let appPath = '.'; - let absoluteAppPath = path.resolve(appPath); - let pkg = parsePackageFile(appPath); - appName = pkg.name; - } - try { - execSync(`docker stop ${appName}`); - execSync(`docker rm ${appName}`); - successMessage(`App '${appName}' was stopped.`); - } catch (e) { - errorMessage(`Failed to stop app '${appName}'.`); - } - process.exit(); -} else if (command === 'list') { - let command = exec(`docker ps${commandRawArgsString}`, (err) => { - if (err) { - errorMessage(`Failed to list active containers. ` + err); - } - process.exit(); - }); - command.stdout.pipe(process.stdout); - command.stderr.pipe(process.stderr); -} else if (command === 'logs') { - let appName = arg1; - if (!appName) { - let appPath = '.'; - let absoluteAppPath = path.resolve(appPath); - let pkg = parsePackageFile(appPath); - appName = pkg.name; - } - let command = exec(`docker logs ${appName}${commandRawArgsString}`, (err) => { - if (err) { - errorMessage(`Failed to get logs for '${appName}' app. ` + err); - } - process.exit(); - }); - command.stdout.pipe(process.stdout); - command.stderr.pipe(process.stderr); -} else if (command === 'deploy' || command === 'deploy-update') { - let appPath = arg1 || '.'; - let absoluteAppPath = path.resolve(appPath); - let pkg = parsePackageFile(appPath); - let appName = pkg.name; - - let isUpdate = (command === 'deploy-update'); - - let targetCPUUtilization = 50; - let maxPodsPerService = 10; - - let failedToDeploy = function (err) { - errorMessage(`Failed to deploy the '${appName}' app. ${err.message}`); - process.exit(); - }; - - let socketClusterK8sConfigFilePath = appPath + '/socketcluster-k8s.json'; - let socketClusterK8sConfig = parseJSONFile(socketClusterK8sConfigFilePath); - - let addAuthDetailsToSocketClusterK8s = function (socketClusterK8sConfigJSON, username, password) { - if (!socketClusterK8sConfigJSON.docker) { - socketClusterK8sConfigJSON.docker = {}; - } - socketClusterK8sConfigJSON.docker.auth = Buffer.from(`${username}:${password}`, 'utf8').toString('base64'); - }; - - let saveSocketClusterK8sConfigFile = function (socketClusterK8sConfigJSON) { - fs.writeFileSync(socketClusterK8sConfigFilePath, JSON.stringify(socketClusterK8sConfigJSON, null, 2)); - }; - - let parseVersionTag = function (fullImageName) { - let matches = fullImageName.match(/:[^:]*$/); - if (!matches) { - return ''; - } - return matches[0] || ''; - }; - - let setImageVersionTag = function (imageName, versionTag) { - if (versionTag.indexOf(':') != 0) { - versionTag = ':' + versionTag; - } - return imageName.replace(/(\/[^\/:]*)(:[^:]*)?$/g, `$1${versionTag}`); - }; - - let promptDockerAuthDetails = function (callback) { - let handleSaveDockerAuthDetails = function (saveAuthDetails) { - saveDockerAuthDetails = saveAuthDetails; - callback(dockerUsername, dockerPassword, saveDockerAuthDetails); - }; - - let promptSaveAuthDetails = function () { - promptConfirm(`Would you like to save your Docker registry username and password as Base64 to ${socketClusterK8sConfigFilePath}?`, {default: true}, handleSaveDockerAuthDetails); - }; - - let handlePassword = function (password) { - dockerPassword = password; - if (saveDockerAuthDetails != null) { - handleSaveDockerAuthDetails(saveDockerAuthDetails); - return; - } - promptSaveAuthDetails(); - }; - - let handleUsername = function (username) { - dockerUsername = username; - if (dockerPassword != null) { - handlePassword(dockerPassword); - return; - } - promptInput('Enter your Docker registry password:', handlePassword, true); - }; - - let promptUsername = function () { - if (dockerUsername != null) { - handleUsername(dockerUsername); - return; - } - promptInput('Enter your Docker registry username:', handleUsername); - }; - - promptUsername(); - }; - - let performDeployment = function (dockerConfig, versionTag, username, password) { - let dockerLoginCommand = `docker login -u ${username} -p ${password}`; - - let fullVersionTag; - if (versionTag) { - fullVersionTag = `:${versionTag}`; - } else { - fullVersionTag = parseVersionTag(dockerConfig.imageName); - } - dockerConfig.imageName = setImageVersionTag(dockerConfig.imageName, fullVersionTag); - if (saveDockerAuthDetails) { - addAuthDetailsToSocketClusterK8s(socketClusterK8sConfig, username, password); - } - try { - saveSocketClusterK8sConfigFile(socketClusterK8sConfig); - - execSync(`docker build -t ${dockerConfig.imageName} .`, {stdio: 'inherit'}); - execSync(`${dockerLoginCommand}; docker push ${dockerConfig.imageName}`, {stdio: 'inherit'}); - - if (tlsSecretName && tlsKeyPath && tlsCertPath) { - uploadTLSSecret(tlsSecretName, tlsKeyPath, tlsCertPath, warningMessage); - } - - let kubernetesDirPath = appPath + '/kubernetes'; - - let kubeConfSCCWorker = getSCCWorkerDeploymentDefPath(kubernetesDirPath); - let kubeConfContentSCCWorker = fs.readFileSync(kubeConfSCCWorker, {encoding: 'utf8'}); - - let deploymentConfSCCWorker = YAML.parse(kubeConfContentSCCWorker); - - let initContainersSCCWorker = deploymentConfSCCWorker.spec.template.spec.initContainers; - initContainersSCCWorker.forEach((value, index) => { - if (value) { - if (value.name === 'app-src-container') { - initContainersSCCWorker[index].image = dockerConfig.imageName; - } - } - }); - - let formattedYAMLStringSCCWorker = sanitizeYAML(YAML.stringify(deploymentConfSCCWorker, Infinity, 2)); - fs.writeFileSync(kubeConfSCCWorker, formattedYAMLStringSCCWorker); - - let kubeConfSCCBroker = getSCCBrokerDeploymentDefPath(kubernetesDirPath); - let kubeConfContentSCCBroker = fs.readFileSync(kubeConfSCCBroker, {encoding: 'utf8'}); - - let deploymentConfSCCBroker = YAML.parse(kubeConfContentSCCBroker); - - let formattedYAMLStringSCCBroker = sanitizeYAML(YAML.stringify(deploymentConfSCCBroker, Infinity, 2)); - fs.writeFileSync(kubeConfSCCBroker, formattedYAMLStringSCCBroker); - - let ingressKubeFileName = 'scc-ingress.yaml'; - let agcWorkerDeploymentFileName = 'scc-worker-deployment.yaml'; - - let deploySuccess = () => { - successMessage( - `The '${appName}' app was deployed successfully - You should be able to access it online ` + - `once it has finished booting up. This can take a while depending on your platform.` - ); - process.exit(); - }; - - if (isUpdate) { - try { - execSync(`kubectl replace -f ${kubernetesDirPath}/${agcWorkerDeploymentFileName}`, {stdio: 'inherit'}); - } catch (err) {} - - deploySuccess(); - } else { - let kubeFiles = fs.readdirSync(kubernetesDirPath); - let serviceAndDeploymentKubeFiles = kubeFiles.filter((configFilePath) => { - return configFilePath != ingressKubeFileName; - }); - serviceAndDeploymentKubeFiles.forEach((configFilePath) => { - let absolutePath = path.resolve(kubernetesDirPath, configFilePath); - execSync(`kubectl create -f ${absolutePath}`, {stdio: 'inherit'}); - }); - - // Wait a few seconds before deploying ingress (due to a bug in some environments). - setTimeout(() => { - try { - execSync(`kubectl create -f ${kubernetesDirPath}/${ingressKubeFileName}`, {stdio: 'inherit'}); - deploySuccess(); - } catch (err) { - failedToDeploy(err); - } - }, 7000); - } - } catch (err) { - failedToDeploy(err); - } - }; - - let handleDockerVersionTagAndPushToDockerImageRepo = function (versionTag) { - let dockerConfig = socketClusterK8sConfig.docker; - - if (dockerConfig.auth) { - let authParts = Buffer.from(dockerConfig.auth, 'base64').toString('utf8').split(':'); - dockerUsername = authParts[0]; - dockerPassword = authParts[1]; - performDeployment(dockerConfig, versionTag, dockerUsername, dockerPassword); - } else { - promptDockerAuthDetails((username, password) => { - performDeployment(dockerConfig, versionTag, username, password); - }); - } - }; - - let incrementVersion = function (versionString) { - return versionString.replace(/[^.]$/, (match) => { - return parseInt(match) + 1; - }); - }; - - let pushToDockerImageRepo = function () { - let versionTagString = parseVersionTag(socketClusterK8sConfig.docker.imageName).replace(/^:/, ''); - let nextVersionTag; - if (versionTagString) { - if (isUpdate) { - nextVersionTag = incrementVersion(versionTagString); - socketClusterK8sConfig.docker.imageName = setImageVersionTag(socketClusterK8sConfig.docker.imageName, nextVersionTag); - } else { - nextVersionTag = versionTagString; - } - } else { - nextVersionTag = '""'; - } - - promptInput(`Enter the Docker version tag for this deployment (Default: ${nextVersionTag}):`, handleDockerVersionTagAndPushToDockerImageRepo); - }; - - if (socketClusterK8sConfig.docker && socketClusterK8sConfig.docker.imageRepo) { - pushToDockerImageRepo(); - } else { - let dockerImageName, dockerDefaultImageName, dockerDefaultImageVersionTag; - - let saveSocketClusterK8sConfigs = function () { - socketClusterK8sConfig.docker = { - imageRepo: 'https://index.docker.io/v1/', - imageName: dockerImageName - }; - if (saveDockerAuthDetails) { - addAuthDetailsToSocketClusterK8s(socketClusterK8sConfig, dockerUsername, dockerPassword); - } - try { - saveSocketClusterK8sConfigFile(socketClusterK8sConfig); - } catch (err) { - failedToDeploy(err); - } - pushToDockerImageRepo(); - }; - - let handleDockerImageName = function (imageName) { - if (imageName) { - dockerImageName = imageName; - } else { - dockerImageName = setImageVersionTag(dockerDefaultImageName, dockerDefaultImageVersionTag); - } - saveSocketClusterK8sConfigs(); - }; - - let promptDockerImageName = function () { - dockerDefaultImageName = `${dockerUsername}/${appName}`; - dockerDefaultImageVersionTag = 'v1.0.0'; - - promptInput(`Enter the Docker image name without the version tag (Or press enter for default: ${dockerDefaultImageName}):`, handleDockerImageName); - }; - - promptK8sTLSCredentials(() => { - promptDockerAuthDetails(promptDockerImageName); - }); - } -} else if (command === 'undeploy') { - let appPath = arg1 || '.'; - - let pkg = parsePackageFile(appPath); - let appName = pkg.name; - - let kubernetesDirPath = appPath + '/kubernetes'; - let kubeFiles = fs.readdirSync(kubernetesDirPath); - kubeFiles.forEach((configFilePath) => { - let absolutePath = path.resolve(kubernetesDirPath, configFilePath); - try { - execSync(`kubectl delete -f ${absolutePath}`, {stdio: 'inherit'}); - } catch (err) {} - }); - - successMessage(`The '${appName}' app was undeployed successfully.`); - - process.exit(); -} else if (command === 'add-secret') { - let secretName = argv.s || DEFAULT_TLS_SECRET_NAME; - let privateKeyPath = argv.k; - let certFilePath = argv.c; - - if (privateKeyPath == null || certFilePath == null) { - errorMessage(`Failed to upload secret. Both a key file path (-k) and a certificate file path (-c) must be provided.`); - } else { - let success = uploadTLSSecret(secretName, privateKeyPath, certFilePath, errorMessage); - if (success) { - successMessage(`The private key and cert pair were added to your cluster under the secret name "${secretName}".`); - } - } - process.exit(); -} else if (command === 'remove-secret') { - let secretName = argv.s || DEFAULT_TLS_SECRET_NAME; - let success = removeTLSSecret(secretName, errorMessage); - if (success) { - successMessage(`The private key and cert pair under the secret name "${secretName}" were removed from your cluster.`); - } - process.exit(); -} else { - errorMessage(`"${command}" is not a valid SocketCluster command.`); - showCorrectUsage(); - process.exit(); -} +// CLI ACTIONS CAN BE FOUND IN BIN/ACTIONS/. THESE ARE MOUNTED VIA THE REPLCIENT +const commands = { + execute: () => cli.errorLog('Input not recognized try socketcluster -h'), + create: { + execute: async ({ argument, options }) => await cli.actions.create(argument, options), + help: 'Create a new boilerplate app in your working directory', + input: '', + }, + run: { + execute: async ({ argument, options }) => await cli.actions.dockerRun(argument, options), + help: '[requires docker] Run the app at path inside a container on your local machine', + input: '', + }, + restart: { + execute: async ({ argument, options }) => await cli.actions.dockerRestart(argument, options), + help: '[requires docker] Restart the app at path', + input: '', + }, + stop: { + execute: async ({ argument, options }) => await cli.actions.dockerStop(argument, options), + help: '[requires docker] Stop the app', + input: '', + }, + list: { + execute: async () => await cli.actions.dockerList(), + help: '[requires docker] List all running Docker containers on your local machine', + }, + logs: { + execute: async ({ argument, options }) => + await cli.actions.dockerLogs(argument, options), + help: '[requires docker] Get logs for the specified app', + input: '', + options: [{ option: 'f', help: 'Follow the logs' }], + }, + deploy: { + execute: async ({ argument, options }) => + await cli.actions.k8sDeployAndDeployUpdate(argument, options), + help: '[requires kubectl] Deploy the app at path to your Kubernetes cluster', + input: '', + }, + deployUpdate: { + execute: async ({ argument, options }) => + await cli.actions.k8sDeployAndDeployUpdate(argument, options, true), + help: '[requires kubectl] Deploy update to an app which was previously deployed', + input: '', + }, + undeploy: { + execute: async ({ argument, options }) => await cli.actions.k8sUndeploy(argument, options, true), + help: '[requires kubectl] Shutdown all core app services running on your cluster', + input: '', + }, + addSecret: { + execute: async ({ argument, options }) => await cli.actions.k8sAddSecret(argument, options), + help: '[requires kubectl] Upload a TLS key and cert pair to your cluster', + options: [ + { option: 's', help: 'Optional secret name' }, + { option: 'k', help: 'Path to a key file' }, + { option: 'c', help: 'Path to a certificate file' }, + ], + }, + removeSecret: { + execute: async ({ argument, options }) => await cli.actions.k8sRemoveSecret(argument, options), + help: '[requires kubectl] Remove a TLS key and cert pair from your cluster', + options: [{ option: 's', help: 'Optional secret name' }], + }, +}; + +cli.run(commands); diff --git a/bin/lib/index.js b/bin/lib/index.js new file mode 100644 index 00000000..3ed71a05 --- /dev/null +++ b/bin/lib/index.js @@ -0,0 +1,64 @@ +const path = require('path'); +const fs = require('fs-extra'); + +const sanitizeYAML = function (yamlString) { + return yamlString.replace(/emptyDir: ?(null)?\n/g, 'emptyDir: {}\n'); +}; + +const wd = process.cwd(); + +const appDir = `${__dirname}/../../app`; +const destDir = (app) => path.normalize(`${wd}/${app}`); + +const clientFileSourcePath = (dir) => path.normalize( + `${dir}/node_modules/socketcluster-client/socketcluster-client.min.js`, +); + +const clientFileDestPath = (dir) => path.normalize( + `${dir}/public/socketcluster-client.min.js`, +); + +const getSCCWorkerDeploymentDefPath = function (kubernetesTargetDir) { + return `${kubernetesTargetDir}/scc-worker-deployment.yaml`; +}; + +const getSCCBrokerDeploymentDefPath = function (kubernetesTargetDir) { + return `${kubernetesTargetDir}/scc-broker-deployment.yaml`; +}; + +let fileExistsSync = function (filePath) { + try { + fs.accessSync(filePath, fs.constants.F_OK); + } catch (err) { + return false; + } + return true; +}; + +let parseJSONFile = function (filePath) { + try { + if (fileExistsSync(filePath)) { + return JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' })); + } + } catch (e) {} + + return {}; +}; + +let parsePackageFile = function (moduleDir) { + let packageFile = path.join(moduleDir, 'package.json'); + return parseJSONFile(packageFile); +}; + +module.exports = { + sanitizeYAML, + getSCCBrokerDeploymentDefPath, + getSCCWorkerDeploymentDefPath, + appDir, + destDir, + clientFileDestPath, + clientFileSourcePath, + fileExistsSync, + parseJSONFile, + parsePackageFile, +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..167c66ad --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1310 @@ +{ + "name": "socketcluster", + "version": "19.1.4", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "socketcluster", + "version": "19.1.4", + "license": "MIT", + "dependencies": { + "@maartennnn/cli-builder": "^2.3.0", + "fs-extra": "^7.0.1", + "yamljs": "^0.3.0" + }, + "bin": { + "socketcluster": "bin/cli.js" + } + }, + "node_modules/@maartennnn/cli-builder": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@maartennnn/cli-builder/-/cli-builder-2.3.0.tgz", + "integrity": "sha512-FLbsaDhKpit+7/sillXfg9+3lsx2YtZqT1mdH0ks/HdjIltOKA1bhvGK+5YimTm1/0+DDiR9ot10axfWXoavAg==", + "dependencies": { + "fs-extra": "^10.1.0", + "inquirer": "^8.2.4", + "minimist": "^1.2.6" + }, + "bin": { + "cli-builder": "bin/example-cli.js" + } + }, + "node_modules/@maartennnn/cli-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@maartennnn/cli-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@maartennnn/cli-builder/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "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/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "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/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "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/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + } + }, + "dependencies": { + "@maartennnn/cli-builder": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@maartennnn/cli-builder/-/cli-builder-2.3.0.tgz", + "integrity": "sha512-FLbsaDhKpit+7/sillXfg9+3lsx2YtZqT1mdH0ks/HdjIltOKA1bhvGK+5YimTm1/0+DDiR9ot10axfWXoavAg==", + "requires": { + "fs-extra": "^10.1.0", + "inquirer": "^8.2.4", + "minimist": "^1.2.6" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==" + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==" + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, + "rxjs": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "requires": { + "tslib": "^2.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + } + } +} diff --git a/package.json b/package.json index 0652c6f9..ddba2691 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socketcluster", - "version": "15.0.0", + "version": "19.2.0", "description": "Highly scalable realtime framework with support for async/await", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -22,9 +22,8 @@ }, "homepage": "https://socketcluster.io/", "dependencies": { + "@maartennnn/cli-builder": "^2.3.0", "fs-extra": "^7.0.1", - "inquirer": "^6.2.1", - "minimist": "^1.2.0", "yamljs": "^0.3.0" }, "bin": { diff --git a/scc-guide.md b/scc-guide.md index 8009bf20..992b7fdf 100644 --- a/scc-guide.md +++ b/scc-guide.md @@ -23,7 +23,7 @@ Note that SCC can continue to operate without any disruption of service while th ## Running on Kubernetes (recommended) -Running on Kubernetes (K8s) is easy; you just need to run all the `.yaml` files from the `kubernetes/` directory from the SocketCluster repo (https://github.com/SocketCluster/socketcluster/tree/master/kubernetes) using the `kubectl` command (one at a time): +Running on Kubernetes (K8s) is easy; you just need to run all the `.yaml` files from the `kubernetes/` directory from the SocketCluster repo (https://github.com/SocketCluster/socketcluster/tree/master/app/kubernetes) using the `kubectl` command (one at a time): ``` kubectl create -f diff --git a/socketcluster-protocol.md b/socketcluster-protocol.md new file mode 100644 index 00000000..133d6e21 --- /dev/null +++ b/socketcluster-protocol.md @@ -0,0 +1,660 @@ +## SocketCluster Protocol Overview + +SocketCluster protocol is implemented on top of the WebSockets protocol and consists of multiple components: +- [Handshake](#Handshake) +- [Connection health check (ping/pong)](#Connection-health-check-pingpong) +- [Event layer](#Event-layer) +- [Pub/Sub layer](#PubSub-layer) +- [Authentication layer](#Authentication-layer) + +Minimal requirements for a simple SocketCluster compatible client are to implement: +Handshake, ping/pong and (at least partially) the Event layer. + +Pub/Sub and Authentication layers are completely optional. + + +### Contrast between Protocol V1 and V2 + +- SocketCluster <=v14 uses Protocol v1. + SocketCluster >=v15 uses Protocol v2 by default and supports `protocolVersion` configuration option, which allows it to work with Protocol v1. + +- SocketCluster <=v14 doesn't send back Handshake event response, if `cid` is not specified in Handshake event. + SocketCluster >=v15 always sends back Handshake event response, regardles of `cid` presence. If `cid` is not present in Handshake event, `rid` is omitted from Handshake event response. + +- In SocketCluster >=v15 `#disconnect` event is deprecated and no longer in use. + +- Protocol V1 uses `'#1'` and `'#2'` for [ping/pong](#Connection-health-check-pingpong) + Protocol V2 uses empty strings `''` for both. + +- In Protocol V1 all event names starting with symbol `#` are considered reserved for special control events. + In Protocol V2 only a handful of event names starting with symbol `#` are considered reserved. + + +### Reserved event names + +Protocol V1: + +- All event names starting with symbol `#` + +Protocol V2: +- [`#handshake`](#Handshake) +- [`#publish`](#Publish) +- [`#subscribe`](#Subscribe) +- [`#unsubscribe`](#Unsubscribe) +- [`#kickOut`](#Kick-out) +- [`#authenticate`](#Authentication-event) +- [`#setAuthToken`](#Token-acquisition) +- [`#removeAuthToken`](#Deathentication) + + +### Call ID & Response ID + +`cid` - Call ID +`rid` - Response ID + +Some events require acknowledgement from another side of communication, in other words they expect event responses. +In order to track which event responses belong to which events, `cid` and `rid` exist in SocketCluster Protocol. + + +`cid` must be unique for each event sent, during the whole socket connection lifetime. +Call IDs originated from server and Call IDs originated from client are two different sets of ids and are being appointed and tracked separately. + +`cid`, included in events sent from `socketcluster-server` to a SocketCluster client, for each new socket connection, will always start with number `1` and will be incremented with each event sent. + +In your custom SocketCluster client you could use something like `UUID` strings for `cid` but, for efficiency, it's recommended to also use number `1` and increment it with each subsequent event sent. + + +Some special events expect no response, hence `cid` for them is not required and ignored if present. + + +## Handshake + +As soon as you establish a WebSocket connection, you are to send a special Handshake event for `socketcluster-server` to initiate the socket. +Clients are not allowed to interact with the server before Handshake. + +#### **Handshake event** is a JSON-encoded string with the following structure: + +```js +{ + event: '#handshake' + + // [optional] A JSON-compatible Object + data: { }, + + // [optional] Call ID + cid: 1 +} +``` + +#### **Handshake event response** is a JSON-encoded string with the following structure: + +```js +{ + data: { + // A unique ID, assigned to this socket connection by the server + id: 'Y7gRvz-hVW_uXx5qAAH', + + // Value of `pingTimeout` configuration option of the server + pingTimeout: 20000, // ms + + // Look at the Authentication layer overview for more information + isAuthenticated: false + } + + // [optional] Response ID + rid: 1, +} +``` + +`socketcluster-server` <=v14: +- If `cid` was specified in the Handshake event, `socketcluster-server` will send back Handshake event response with matching `rid`. +If `cid` was not specified, no Handshake event response will be sent. + +`socketcluster-server` >=v15: +- Whether or not `cid` was specified in the Handshake event, `socketcluster-server` will always send back Handshake event response. +If `cid` was specified in the Handshake event, Handshake event response will include matching `rid`. +If `cid` was not specified, `rid` will be omitted. + + +## Connection health check (ping/pong) + +`socketcluster-server` periodically sends ping messages to connected clients to check whether or not a connection is still alive. +A SocketCluster client has to answer every ping message with pong message as soon as possible. + +#### **Protocol V1:** +Ping message (from server) is a String: `'#1'` +Pong message (from client) is a String: `'#2'` +#### **Protocol V2:** +Ping message (from server) is an empty String: `''` +Pong message (from client) is an empty String: `''` + +Ping/pong mechanism is required to account for cases when a connection might be closed without sending a proper SocketCluster `#disconnect`\* event or WebSockets `Close` control frame. +For example, if a user's internet drops out suddenly, there would be no way to tell that the `socket` is no longer connected otherwise. + +\* \- In Protocol V2 `#disconnect` event is deprecated and no longer in use. + + +## Event layer + +Event layer is responsible for `one-to-one` communication between a particular socket connection and the server. + +### Basic part +Basic part of the Event layer is responsible for transmitting and receiving user-defined events. +API example from JavaScript `socketcluster-client` v17: +```js +// Transmit an event to the server +socket.transmit('eventName', data) + +// Receive events from the server +for await (const data of socket.receiver('eventName')) { + console.info('received data', data) +} +``` +For more in depth knowledge on API visit https://socketcluster.io/docs/basic-usage + + +#### **Transmitted event** is a JSON-encoded string with the following structure: + +```js +{ + // Arbitrary name of the event* + event: 'eventName', + + // [optional] Any JSON-compatible data + data: eventData, +} +``` +\* \- Some event names starting with `'#'` are [reserved for special control events](#Reserved-event-names) in SocketCluster Protocol. + +Transmitted events never expect responses. +Even if `action.TRANSMIT` was blocked within `agServer.MIDDLEWARE_INBOUND`, no response will be sent. + + +### Advanced part + +Advanced part of the Event layer is responsible for invoking and processing **Remote Procedure Calls**. +API example from JavaScript `socketcluster-client` v17: +```js +// Invoke a remote procedure on the server +const responseData = await socket.invoke('procedureName', data) + +// Process remote procedure calls from the server +for await (const request of socket.procedure('procedureName')) { + console.info('received data', request.data) + request.end(dataToReturnToServer) +} +``` + +Transmitted events and RPC are similar in structure. They share the same property `event` for their names, but they are different entities. +In order to invoke a RPC, a SocketCluster client should send a RPC request. +Unlike transmitted events, every RPC request must include a unique `cid` (Call ID), because every RPC request expects a RPC response with matching `rid` (Response ID) from another side of communication. + +#### **RPC request** is a JSON-encoded string with the following structure: +```js +{ + // Call ID + cid: 12345, + + // Arbitrary name of the procedure* + event: 'procedureName', + + // [optional] Any JSON-compatible data + data: procedureData +} +``` +\* \- Some procedure names starting with `'#'` are [reserved for special control events](#Reserved-event-names) in SocketCluster Protocol. + + +When the RPC request is processed, a RPC response should be sent back. + +#### **Successful RPC response** is a JSON-encoded string with the following structure: + +```js +{ + // Response ID + rid: 12345, + + // [optional] Any JSON-compatible data + data: responseData +} +``` + +If the RPC request was blocked within `agServer.MIDDLEWARE_INBOUND`, then the argument, which was provided to the `action.block(err)` method, will be included into the RPC response as `error` property. +If no argument was provided to the `action.block()` method, the `error` will contain default SocketCluster `SilentMiddlewareBlockedError`: + +#### **Unsuccessful RPC response** is a JSON-encoded string with the following structure: +```js +{ + rid: 12345, + + error: { + message: 'The invoke AGAction was blocked by inbound middleware', + name: 'SilentMiddlewareBlockedError', + type: 'inbound' + } +} +``` + +Every RPC response must include `rid` exactly matching `cid` of the respective RPC. +As an example, let's invoke a RPC from the server side. +API example from `socketcluster-server` v17: +```js +try { + const responseData = await socket.invoke('procedureName', data) +} catch (err) { + if (err.name === 'TimeoutError') { + // ... + } +} +``` + +If no response with matching `rid` will be received from a client, the `socket.invoke` method will throw `TimeoutError`, after time interval specified in `ackTimeout` configuration option of the server. + +Most of the [SocketCluster clients](https://github.com/SocketCluster/client-drivers) follow the same logic. +A SocketCluster client sets a timer (alike `setTimeout`) for each RPC sent, with consideration of `cid`. Those timers expose a `TimeoutError` when are finished. And if the client receives a RPC response with `rid` matching `cid` of one of the ongoing timers, the client destroys the timer before it fires up. + + +## Pub/Sub layer + +Pub/Sub layer is responsible for `one-to-many` communication between a particular socket connection or a particular SocketCluster worker and unlimited amount of connected sockets, which are subscribed to a Pub/Sub channel. + +### Subscribe + +In order to subscribe a socket connection to a Pub/Sub channel, a SocketCluster client should send to server a subscription request. +API example from JavaScript `socketcluster-client` v17: +```js +const channel = socket.subscribe('channelName') +for await (const message of channel) { + console.info(message) +} +``` +For more in depth knowledge on API visit https://socketcluster.io/docs/basic-usage + +#### **Subscription request** is a JSON-encoded string with the following structure: + +```js +{ + event: '#subscribe', + + data: { + // Arbitrary name of a Pub/Sub channel to subscribe to + channel: 'channelName' + }, + + cid: 12345 +} +``` + +When subscription request will be processed, `socketcluster-server` will send back subscription response with matching `rid`. So the client would know it's successfully subscribed to the channel. + +#### **Successful subscription response** is a JSON-encoded string with the following structure: +```js +{ + rid: 12345 +} +``` + +If the subscription request was blocked within `agServer.MIDDLEWARE_INBOUND`, then the argument, which was provided to the `action.block(err)` method, will be included into the subscription response as `error` property. +If no argument was provided to the `action.block()` method, the `error` will contain default SocketCluster `SilentMiddlewareBlockedError`: + +#### **Unsuccessful subscription response** is a JSON-encoded string with the following structure: + +```js +{ + rid: 12345, + + error: { + message: 'The subscribe AGAction was blocked by inbound middleware', + name: 'SilentMiddlewareBlockedError', + type: 'inbound' + } +} +``` + + +### Publish + +In order to publish a message to a Pub/Sub channel, a SocketCluster client should send to server a publish request. +API example from JavaScript `socketcluster-client` v17: +```js +// transmitPublish includes `cid` +socket.transmitPublish('channelName', messageData) + +// invokePublish does not include `cid` +const responseData = await socket.invokePublish('channelName', messageData) +``` + +#### **Publish request** is a JSON-encoded string with the following structure: + +```js +{ + event: '#publish', + + data: { + // Name of the channel to publish message to + channel: 'channelName', + // [optional] Any JSON-compatible data + data: messageData + }, + + // [optional] Call ID + cid: 12345 +} +``` + +If `cid` was specified, `socketcluster-server` will send back publish response with matching `rid`. So the client would know the sent message was successfully published to the channel. + +#### **Successful publish response** is a JSON-encoded string with the following structure: + +```js +{ + rid: 12345 +} +``` + +If `cid` was specified and the publish request was blocked within `agServer.MIDDLEWARE_INBOUND`, then the argument, which was provided to the `action.block(err)` method, will be included into the publish response as `error` property. +If no argument was provided to the `action.block()` method, the `error` will contain default SocketCluster `SilentMiddlewareBlockedError`: + +#### **Unsuccessful publish response** is a JSON-encoded string with the following structure: + +```js +{ + rid: 12345, + + error: { + message: 'The publishIn AGAction was blocked by inbound middleware', + name: 'SilentMiddlewareBlockedError', + type: 'inbound' + } +} +``` + + +If `cid` was not specified in the publish request, no publish response will be sent even if the request was unsuccessful. + +### Unsubscribe + +In order to unsubscribe a socket connection from a Pub/Sub channel, a SocketCluster client should send to server an unsubscription event. + +#### **Unsubscription event** is a JSON-encoded string with the following structure: + +```js +{ + event: '#unsubscribe', + + // Name of a Pub/Sub channel to unsubscribe from + data: 'channelName', + + // [optional] Call ID + cid: 12345 +} +``` + +When unsubscription event will be processed, `socketcluster-server` will send back unsubscription event response with matching `rid`. So the client would know it's successfully unsubscribed from the channel. + +#### **Unsubscription event response** is a JSON-encoded string with the following structure: + +```js +{ + rid: 12345 +} +``` + +If no `cid` was specified in the unsubscription event, no unsubscription event response will be sent back. + +### Kick out + +It's possible, from server side, to forcibly unsubscribe a socket connection from one or more particular Pub/Sub channels or from all Pub/Sub channels at once. +API example from `socketcluster-server` v17: +```js +socket.kickOut(['channelName', 'channelName2'], 'custom message') +``` +In that case a SocketCluster client will receive a special `#kickOut` event. Or multiple events, if it was kicked from multiple channels. One per each channel it was kicked from. + +#### **kickOut event** is a JSON-encoded string with the following structure: + +```js +{ + event: '#kickOut', + + data: { + // Name of the Pub/Sub channel the socket connection was kicked from + channel: 'channelName', + + // [optional] If a message has been provided to the socket.kickOut method + message: 'custom message' + } +} +``` + + +## Authentication layer + +Authentication layer is responsible for means of acquiring and storing an authentication token on client side, as well as for transfering previously acquired authentication token to server for processing. + +Authentication process in SocketCluster is deeply customizable. You could implement and use in your SocketCluster client virtually any authentication strategy for your application. +Here let's review the default SocketCluster authentication strategy, which uses JWT as the authentication token and transfers it to server via WebSockets connection within Handshake event. + +### Token acquisition + +For more in depth knowledge on authentication process visit https://socketcluster.io/docs/authentication +API example from `socketcluster-server` v17: +```js +socket.setAuthToken({username: 'Alice', channels: []}) +``` +When `setAuthToken` method is called on the server side, a SocketCluster client will receive a JSON-encoded string with the following structure: + +```js +{ + event: '#setAuthToken', + + data: { + token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkFsaWNlIiwiY2hhbm5lbHMiOltdLCJUaGFua1lvdUZvckNob29zaW5nU29ja2V0Q2x1c3RlciI6dHJ1ZSwiaWF0IjoxNjc0NzMxODc3LCJleHAiOjE2NzQ4MTgyNzd9.MzQ0QQzofbtlnzvPbeTgtpcvg8Sh6cY8EwXqNXHj5ns' + } +} +``` +Receiving `#setAuthToken` event on the client side means the socket connection is now authenticated. A SocketCluster client is supposed to store the acquired token somewhere locally for later use. If the client was already authenticated, it's supposed to replace previously stored token with the new one. + +### Transfer token to server for processing + +In the default authentication strategy this could be done in two ways: +- [By including authentication token within Handshake event](#Authentication-within-Handshake) +- [By sending Authentication event](#Authentication-event) + +### Authentication within Handshake + +The most practical way is to include previously acquired authentication token within the Handshake event. +This way `socketcluster-server` will automatically pick up the token and your client will become authenticated right away. + +#### **Handshake event** is a JSON-encoded string with the following structure: + +```js +{ + event: '#handshake', + + data: { + authToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkFsaWNlIiwiY2hhbm5lbHMiOltdLCJUaGFua1lvdUZvckNob29zaW5nU29ja2V0Q2x1c3RlciI6dHJ1ZSwiaWF0IjoxNjc0NzMxODc3LCJleHAiOjE2NzQ4MTgyNzd9.MzQ0QQzofbtlnzvPbeTgtpcvg8Sh6cY8EwXqNXHj5ns' + }, + + // [optional] Call ID + cid: 1 +} +``` + +Depending on success of authentication process, Handshake event response may include different information. +If provided `authToken` is valid and not expired, a SocketCluster client will receive Handshake event response with no `authError` property included. + +#### **Handshake event response** is a JSON-encoded string with the following structure: + +```js +{ + // [optional] Response ID + rid: 1, + + data: { + // A unique ID, assigned to this socket connection by the server + id: 'ZnY2picItxGyKbzeAAAE', + + // Value of `pingTimeout` configuration option of the server + pingTimeout: 20000, // ms + + // If true, then `#setAuthToken` event will be received immediately after + isAuthenticated: true + } +} +``` + +If any errors will occur during authentication process, for example the provided `authToken` is invalid or expired, or Handshake was blocked in the server middleware, then Handshake event response will include `authError` property describing the occured error. [More about authentication errors](#Authentication-errors) + +#### **Handshake event response** is a JSON-encoded string with the following structure: + +```js +{ + // [optional] Response ID + rid: 1, + + data: { + // A unique ID, assigned to this socket connection by the server + id: 'Y7Uw-jHCJP_gld4QAAAA', + + // Value of `pingTimeout` configuration option of the server + pingTimeout: 20000, // ms + + // If false, then `#removeAuthToken` event will be received immediately after + isAuthenticated: false, + + authError: { + name: 'ErrorName', + message: 'error message', + isBadToken: true + } + } +} +``` + +### Authentication event + +Instead of including authentication token within Handshake event, a SocketCluster client could send special Authentication event any time after Handshake. +This could be useful if authentication token somehow becomes available in your client after Handshake. +As an example, if you use JavaScript `socketcluster-client` in a web browser and get multiple tabs opened, you could acquire authentication token in one tab and, when `authToken` becomes available in the `localStorage`, other tabs would send to server the `authToken` within Authentication event, for their socket connections to also become authenticated, without need for page reload. + +#### **Authentication event** is a JSON-encoded string with the following structure: +```js +{ + event: '#authenticate', + + // A String with an authentication token + data: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IkFsaWNlIiwiY2hhbm5lbHMiOltdLCJUaGFua1lvdUZvckNob29zaW5nU29ja2V0Q2x1c3RlciI6dHJ1ZSwiaWF0IjoxNjc0NzMxODc3LCJleHAiOjE2NzQ4MTgyNzd9.MzQ0QQzofbtlnzvPbeTgtpcvg8Sh6cY8EwXqNXHj5ns', + + // [optional] Call ID + cid: 12345 +} +``` + +Depending on success of authentication process, Authentication event response may include different information. +If `authToken` is valid and not expired, a SocketCluster client will receive successful Authentication event response, which means socket connection is now authenticated. +If `cid` was specified in Authentication event, Authentication event response will also include matching `rid`. + +#### **Successful Authentication event response** is a JSON-encoded string with the following structure: + +```js +{ + // [optional] Response ID + rid: 12345, + + data: { + isAuthenticated: true, + authError: null + } +} +``` +If any errors will occur during authentication process, for example authentication token is invalid or expired, Authentication event response will include `error` property describing the occured error. [More about authentication errors](#Authentication-errors) + +#### **Unsuccessful Authentication event response** is a JSON-encoded string with the following structure: + +```js +{ + // [optional] Response ID + rid: 12345, + + // If error is present, then `#removeAuthToken` event will be received immediately after + error: { + name: 'ErrorName', + message: 'error message', + isBadToken: true + } +} +``` + +### Deathentication + +When you deauthenticate a socket connection from server side, a SocketCluster client will receive special `#removeAuthToken` event. It means the socket connection is no longer authenticated. +Also Deauthentication event could be received immediately after sending Handshake or Authentication event, if `authToken` provided within Handshake or Authentication event is invalid. +API example from `socketcluster-server` v17: +```js +socket.deauthenticate() +``` + +#### **Deauthentication event** is a JSON-encoded string with the following structure: +```js +{ + event: '#removeAuthToken' +} +``` + +No response is expected for Deauthentication event. + +If a SocketCluster client intends to deauthenticate, it should send to server identical Deauthentication event. + +In both cases the client should remove previously stored authentication token, as well as to perform any other operations you deem necessary, like routing client to login screen to start over the [token acquisition process](#Token-acquisition) + +--- + +### Authentication errors + +By default authentication errors consist of `name`, `message` and `isBadToken`. But they also could include additional information depending on the error type. Or to have various content in case of user-defined errors. + +When you block an authentication action (`action.type === action.AUTHENTICATE`) within the server middleware (`agServer.MIDDLEWARE_INBOUND`), the error object you pass to the `action.block(err)` method becomes the authentication error, which your client will receive. +For more in depth knowledge on API visit https://socketcluster.io/docs/middleware-and-authorization + +`name:` +Could be either one of the SocketCluster error names or a user-defined error name. + +All possible SocketCluster errors are listed in [SC-errors](https://github.com/SocketCluster/sc-errors/blob/master/index.js) module. +List of the `name`s which are relevant to the authentication process, in order of frequency occurring are: + +- AuthTokenExpiredError +- AuthTokenInvalidError +- AuthTokenError +- AuthTokenNotBeforeError + +`message:` +Could be originated from SocketCluster or from underlying libraries like `jsonwebtoken`. It also could be a user-defined error message. +List of all the possible error `message`s is hard to come by, but some of them you could find in [JWT Readme](https://github.com/auth0/node-jsonwebtoken/blob/e1fa9dcc12054a8681db4e6373da1b30cf7016e3/README.md#jsonwebtokenerror) + +`isBadToken:` +If an authentication error was caused by an expired or invalid or malformed JWT or by incorrect JWT signature, `isBadToken` will be `true`. If the authentication error was caused by any other reason, it will be `false`. + +As an example, the two most frequently occurring errors are: +```js +authError: { + name: 'AuthTokenExpiredError', + message: 'jwt expired', + expiry: '2023-01-01T01:23:45.000Z', + isBadToken: true +} + +authError: { + name: 'AuthTokenInvalidError', + message: 'invalid token', + isBadToken: true +} +``` + +Any authentication error will always cause a SocketCluster client to receive [`#removeAuthToken`](#Deathentication) event immediately after the event response, which contained the error. + +--- + +Thank you for your time implementing custom SocketCluster client! :heart: +If you have completed one, please, open a pull request to add your client to the [list of SocketCluster clients](https://github.com/SocketCluster/client-drivers) +If you encounter any errors or have any questions, feel free to ask for help in [SocketCluster Gitter chat room](https://gitter.im/SocketCluster/socketcluster)