diff --git a/simplq/package-lock.json b/simplq/package-lock.json index 241b95d7..4236d548 100644 --- a/simplq/package-lock.json +++ b/simplq/package-lock.json @@ -1318,6 +1318,722 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" }, + "@firebase/analytics": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.7.2.tgz", + "integrity": "sha512-YxLsPojufkfe3FFg6imOMQdfdJwu5hig17jnldpdmqemj1gOIwE/peTBrksP4rxnIra26XhsBRppcPcVQyxMNQ==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/installations": "0.5.2", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/analytics-compat": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.1.3.tgz", + "integrity": "sha512-FpaJ4sbJnryCRBkKIE45L2wGt2oCmlRK+AZc4JQHw20vb8Mf1WG1qGO+FGNoFev3lJSAd21tyhoLdPvbCTnOZQ==", + "requires": { + "@firebase/analytics": "0.7.2", + "@firebase/analytics-types": "0.7.0", + "@firebase/component": "0.5.7", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/analytics-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.7.0.tgz", + "integrity": "sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ==" + }, + "@firebase/app": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.4.tgz", + "integrity": "sha512-XBrZb60m7N1XqmRhSJWADDD3J/0j9wM2VhxC5KUEtFA9SWfTn9Z3EWGtRGz7ahrMkgPJsmo0fXpvUh6cY8pQvQ==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.4.2.tgz", + "integrity": "sha512-DFYt22lUMvvncN3v6x9ZRE2/HHBQdRQyYtHwakAcZrRUALJiU16iDwl2CABuW4JKytTmMj+xXo0fjSIRWtwT/w==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check-compat": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.1.3.tgz", + "integrity": "sha512-ka5ggmfucQDwEJTcFsXPJJ+ygPZz4Q44D5yb0sksfOAsUSpzAR83jDSxebOgTvvk+axNCFamxOsrZEV6KKDjEg==", + "requires": { + "@firebase/app-check": "0.4.2", + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-check-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.1.0.tgz", + "integrity": "sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA==" + }, + "@firebase/app-compat": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.5.tgz", + "integrity": "sha512-GJURp5Nn8dEm72/y13Z+XMvWmMomsYViNxw6VKYqVH9f9VKnJ46Q8zYtx2ePvOuj7pAqsfwNkvAdAFYcveTe9g==", + "requires": { + "@firebase/app": "0.7.4", + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/app-types": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" + }, + "@firebase/auth": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.18.3.tgz", + "integrity": "sha512-uS67CzypGu52H94mkptJ/lpoc0xAtVDksb/4+4HdSRwekxMt5EtyEdLMy8MH73Vk3MwTQWyTEsHEbwrGgk42pQ==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "node-fetch": "2.6.5", + "selenium-webdriver": "4.0.0-rc-1", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/auth-compat": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.1.6.tgz", + "integrity": "sha512-+HNIsti29ZX4AgLH4KdI+DAesX9DOywcmHFbVJtOE6Ow8v2d8NFTi66fa4LEU7HLCvj9YpeiEpHHLs4NamJ1tw==", + "requires": { + "@firebase/auth": "0.18.3", + "@firebase/auth-types": "0.11.0", + "@firebase/component": "0.5.7", + "@firebase/util": "1.4.0", + "node-fetch": "2.6.5", + "selenium-webdriver": "^4.0.0-beta.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" + }, + "@firebase/auth-types": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.11.0.tgz", + "integrity": "sha512-q7Bt6cx+ySj9elQHTsKulwk3+qDezhzRBFC9zlQ1BjgMueUOnGMcvqmU0zuKlQ4RhLSH7MNAdBV2znVaoN3Vxw==" + }, + "@firebase/component": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.7.tgz", + "integrity": "sha512-CiAHUPXh2hn/lpzMShNmfAxHNQhKQwmQUJSYMPCjf2bCCt4Z2vLGpS+UWEuNFm9Zf8LNmkS+Z+U/s4Obi5carg==", + "requires": { + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz", + "integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==", + "requires": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "dependencies": { + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database-compat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz", + "integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/database": "0.12.2", + "@firebase/database-types": "0.9.1", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/database-types": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.1.tgz", + "integrity": "sha512-RUixK/YrbpxbfdE+nYP0wMcEsz1xPTnafP0q3UlSS/+fW744OITKtR1J0cMRaXbvY7EH0wUVTNVkrtgxYY8IgQ==", + "requires": { + "@firebase/app-types": "0.7.0", + "@firebase/util": "1.4.0" + } + }, + "@firebase/firestore": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.1.1.tgz", + "integrity": "sha512-hFl+Me6F+GhtEaMsmwruOVoaJfoYinjCKyhaXzQT/jUsoBzKUBCd6MKMjYD+D+y1deAmdkFJcRNxPV7CsgF2aw==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "@firebase/webchannel-wrapper": "0.6.0", + "@grpc/grpc-js": "^1.3.2", + "@grpc/proto-loader": "^0.6.0", + "node-fetch": "2.6.5", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/firestore-compat": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.1.4.tgz", + "integrity": "sha512-NuV0cKXE1EAxNkZxRXYjFsBPiXljuq0W3NeKyQYZTmYsVVJ215KHdR/RHAUA+1ZOfrfT2NgoZpBmE7LpYeLwXA==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/firestore": "3.1.1", + "@firebase/firestore-types": "2.5.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/firestore-types": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-2.5.0.tgz", + "integrity": "sha512-I6c2m1zUhZ5SH0cWPmINabDyH5w0PPFHk2UHsjBpKdZllzJZ2TwTkXbDtpHUZNmnc/zAa0WNMNMvcvbb/xJLKA==" + }, + "@firebase/functions": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.7.3.tgz", + "integrity": "sha512-LxLbR9UtULLKMWSs6vtlte2Ka5tBDPGeGwX8Mto2uAtaNdrkoWKdhiJ4OTQx1YTCRIbTQnTg3t50NO8afzTEcQ==", + "requires": { + "@firebase/app-check-interop-types": "0.1.0", + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.7", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.4.0", + "node-fetch": "2.6.5", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/functions-compat": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.1.4.tgz", + "integrity": "sha512-mC/z0uJbGk/RRskabvvDylpMHMsNNwNIxrjBJy3J8ADZUqpJTMuT4gq+pHlPemYqLBZuN8TffIZNVPajXxqc+Q==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/functions": "0.7.3", + "@firebase/functions-types": "0.5.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/functions-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.5.0.tgz", + "integrity": "sha512-qza0M5EwX+Ocrl1cYI14zoipUX4gI/Shwqv0C1nB864INAD42Dgv4v94BCyxGHBg2kzlWy8PNafdP7zPO8aJQA==" + }, + "@firebase/installations": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.5.2.tgz", + "integrity": "sha512-k43qItRUnjIhAcxFRhGrox2ZBY/CFJOizB30hej9HuWOFv4qXoMZOmLtKzyjskFhRn/HW8iBUVguNFAEf6iehw==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/util": "1.4.0", + "idb": "3.0.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/logger": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.0.tgz", + "integrity": "sha512-7oQ+TctqekfgZImWkKuda50JZfkmAKMgh5qY4aR4pwRyqZXuJXN1H/BKkHvN1y0S4XWtF0f/wiCLKHhyi1ppPA==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.2.tgz", + "integrity": "sha512-v95cny/HsupEvFiewsobjEtQ8ItMCPsg+29VLP51SIS3Ix7Kg2TJLZ2tfHkESRFazIhf2+GNwR8hdXoajqz2og==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/installations": "0.5.2", + "@firebase/messaging-interop-types": "0.1.0", + "@firebase/util": "1.4.0", + "idb": "3.0.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging-compat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.2.tgz", + "integrity": "sha512-ORxqIlnstjRhTpQsX7A0K9ifBTrqI7MNdWwCRbhvTh7GkzmhMe7ht+YAALrdvHD3Qty49UFrHznaIbF7Gr+nwA==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/messaging": "0.9.2", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/messaging-interop-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.1.0.tgz", + "integrity": "sha512-DbvUl/rXAZpQeKBnwz0NYY5OCqr2nFA0Bj28Fmr3NXGqR4PAkfTOHuQlVtLO1Nudo3q0HxAYLa68ZDAcuv2uKQ==" + }, + "@firebase/performance": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.5.2.tgz", + "integrity": "sha512-xHrt/BNiln3OIW9hyqKwck0x4C7Km+XKYQsP8cPDBh8AWFh//DB0ta7DuMXw7JGIuyKpK2D3iq5aQNS0MzMvSw==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/installations": "0.5.2", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/performance-compat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.1.2.tgz", + "integrity": "sha512-L9rt89eIPaucGsO/bwF199mS5+BV3kHTfK1Fr1vCmGL87kLpV8DKVccKc7Z0ZwQelfMvXOGy5jVqH/sHhiQAYg==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/performance": "0.5.2", + "@firebase/performance-types": "0.1.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/performance-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.1.0.tgz", + "integrity": "sha512-6p1HxrH0mpx+622Ql6fcxFxfkYSBpE3LSuwM7iTtYU2nw91Hj6THC8Bc8z4nboIq7WvgsT/kOTYVVZzCSlXl8w==" + }, + "@firebase/polyfill": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", + "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", + "requires": { + "core-js": "3.6.5", + "promise-polyfill": "8.1.3", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + }, + "promise-polyfill": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", + "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "@firebase/remote-config": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.3.1.tgz", + "integrity": "sha512-31nZ0NEcARw1wYKIpoAx63rA0ao28e9zYNrlSC08mBiouSOxu69lthiO0V1ZrFqR/iW9+7M2MqnOUhJ6/LYEwQ==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/installations": "0.5.2", + "@firebase/logger": "0.3.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/remote-config-compat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.1.2.tgz", + "integrity": "sha512-j+joqwZAOO1L3pTlK8aQ3M+781ZbbOtV/TNpU4Tulqq+Psfjlx5SOYVfuF8njbbWGPLhLReFwmEjyE3jnm9hrQ==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/logger": "0.3.0", + "@firebase/remote-config": "0.3.1", + "@firebase/remote-config-types": "0.2.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/remote-config-types": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.2.0.tgz", + "integrity": "sha512-hqK5sCPeZvcHQ1D6VjJZdW6EexLTXNMJfPdTwbD8NrXUw6UjWC4KWhLK/TSlL0QPsQtcKRkaaoP+9QCgKfMFPw==" + }, + "@firebase/storage": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.8.4.tgz", + "integrity": "sha512-Flv25G8J4hp9wa9qTy9UoaBRl2Vcsr+FGaK6RaRUAzoMw2PA46ZPt/DChJZWxKgpmOq/7HyRc8qNTwqqDJt7dA==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/util": "1.4.0", + "node-fetch": "2.6.5", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/storage-compat": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.1.4.tgz", + "integrity": "sha512-EV14tdnjm5yewGBgsUarGPzRUgqQX26+NVHIW1AoT+bMoODlL5ypYGv2/QA9Phi7JBvo5cAcTe4stEsu3CTF0g==", + "requires": { + "@firebase/component": "0.5.7", + "@firebase/storage": "0.8.4", + "@firebase/storage-types": "0.6.0", + "@firebase/util": "1.4.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/storage-types": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.6.0.tgz", + "integrity": "sha512-1LpWhcCb1ftpkP/akhzjzeFxgVefs6eMD2QeKiJJUGH1qOiows2w5o0sKCUSQrvrRQS1lz3SFGvNR1Ck/gqxeA==" + }, + "@firebase/util": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.4.0.tgz", + "integrity": "sha512-Qn58d+DVi1nGn0bA9RV89zkz0zcbt6aUcRdyiuub/SuEvjKYstWmHcHwh1C0qmE1wPf9a3a+AuaRtduaGaRT7A==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + } + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.6.0.tgz", + "integrity": "sha512-Pz4+7HPzKvOFI1ICQ6pyUv/VgStEWq9IGiVaaV1cQLi66NIA1mD5INnY4CDNoVAxlkuZvDEUZ+cVHLQ8iwA2hQ==" + }, + "@grpc/grpc-js": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.1.tgz", + "integrity": "sha512-/chkA48TdAvATHA7RXJPeHQLdfFhpu51974s8htjO/XTDHA41j5+SkR5Io+lr9XsLmkZD6HxLyRAFGmA9wjO2w==", + "requires": { + "@grpc/proto-loader": "^0.6.4", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz", + "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.10.0", + "yargs": "^16.1.1" + }, + "dependencies": { + "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" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "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==" + }, + "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==" + }, + "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==" + }, + "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" + } + }, + "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" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==" + } + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1723,6 +2439,60 @@ "integrity": "sha512-DvJbbn3dUgMxDnJLH+RZQPnXak1h4ZVYQ7CWiFWjQwBFkVajT4rfw2PdpHLTSTwxrYfnoEXkuBiwkDm6tPMQeA==", "dev": true }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@reach/router": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.3.4.tgz", @@ -4789,6 +5559,11 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/long": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + }, "@types/markdown-to-jsx": { "version": "6.11.3", "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz", @@ -10958,6 +11733,39 @@ "parse-filepath": "^1.0.1" } }, + "firebase": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.1.3.tgz", + "integrity": "sha512-OZA60idIzSE5c01qWUDH2plhe+s4VrwbPurAh1KxvPEhMdZSOVK3zrBFHbc7nczFYWRDQpWU6v7gTHAVSANHQg==", + "requires": { + "@firebase/analytics": "0.7.2", + "@firebase/analytics-compat": "0.1.3", + "@firebase/app": "0.7.4", + "@firebase/app-check": "0.4.2", + "@firebase/app-check-compat": "0.1.3", + "@firebase/app-compat": "0.1.5", + "@firebase/app-types": "0.7.0", + "@firebase/auth": "0.18.3", + "@firebase/auth-compat": "0.1.6", + "@firebase/database": "0.12.2", + "@firebase/database-compat": "0.1.2", + "@firebase/firestore": "3.1.1", + "@firebase/firestore-compat": "0.1.4", + "@firebase/functions": "0.7.3", + "@firebase/functions-compat": "0.1.4", + "@firebase/installations": "0.5.2", + "@firebase/messaging": "0.9.2", + "@firebase/messaging-compat": "0.1.2", + "@firebase/performance": "0.5.2", + "@firebase/performance-compat": "0.1.2", + "@firebase/polyfill": "0.3.36", + "@firebase/remote-config": "0.3.1", + "@firebase/remote-config-compat": "0.1.2", + "@firebase/storage": "0.8.4", + "@firebase/storage-compat": "0.1.4", + "@firebase/util": "1.4.0" + } + }, "flagged-respawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", @@ -12380,6 +13188,11 @@ "postcss": "^7.0.14" } }, + "idb": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/idb/-/idb-3.0.2.tgz", + "integrity": "sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==" + }, "identity-obj-proxy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", @@ -12403,6 +13216,11 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, "immer": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz", @@ -13986,6 +14804,17 @@ "object.assign": "^4.1.0" } }, + "jszip": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", + "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, "junk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", @@ -14116,6 +14945,14 @@ "type-check": "~0.3.2" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -14619,6 +15456,11 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -14850,6 +15692,11 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -15534,6 +16381,35 @@ "minimatch": "^3.0.2" } }, + "node-fetch": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, "node-forge": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", @@ -17696,6 +18572,26 @@ "xtend": "^4.0.0" } }, + "protobufjs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", + "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -19618,6 +20514,40 @@ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, + "selenium-webdriver": { + "version": "4.0.0-rc-1", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-rc-1.tgz", + "integrity": "sha512-bcrwFPRax8fifRP60p7xkWDGSJJoMkPAzufMlk5K2NyLPht/YZzR2WcIk1+3gR8VOCLlst1P2PI+MXACaFzpIw==", + "requires": { + "jszip": "^3.6.0", + "rimraf": "^3.0.2", + "tmp": "^0.2.1", + "ws": ">=7.4.6" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "ws": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" + } + } + }, "selfsigned": { "version": "1.10.8", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", @@ -19800,6 +20730,11 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", diff --git a/simplq/package.json b/simplq/package.json index 0b95f413..279a37ce 100644 --- a/simplq/package.json +++ b/simplq/package.json @@ -15,6 +15,7 @@ "aos": "^2.3.4", "axios": "^0.21.1", "components": "^0.1.0", + "firebase": "^9.1.3", "google-libphonenumber": "^3.2.13", "moment": "^2.29.1", "node-sass": "^4.14.1", diff --git a/simplq/public/firebase-messaging-sw.js b/simplq/public/firebase-messaging-sw.js new file mode 100644 index 00000000..27542159 --- /dev/null +++ b/simplq/public/firebase-messaging-sw.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// Give the service worker access to Firebase Messaging. +// Note that you can only use Firebase Messaging here. Other Firebase libraries +// are not available in the service worker. +importScripts('https://www.gstatic.com/firebasejs/9.1.3/firebase-app-compat.js'); +importScripts('https://www.gstatic.com/firebasejs/9.1.3/firebase-messaging-compat.js'); + +// Initialize the Firebase app in the service worker by passing in +// your app's Firebase config object. +// https://firebase.google.com/docs/web/setup#config-object +firebase.initializeApp({ + apiKey: 'AIzaSyCCW7gmWZli24N61NShh-8ALxVy3WtjqNU', + authDomain: 'simplq-fe712.firebaseapp.com', + projectId: 'simplq-fe712', + storageBucket: 'simplq-fe712.appspot.com', + messagingSenderId: '348531792421', + appId: '1:348531792421:web:c481f1740405522d0f3dcc', + measurementId: 'G-8N2SDV8VF5', +}); + +// Retrieve an instance of Firebase Messaging so that it can handle background +// messages. +const messaging = firebase.messaging(); diff --git a/simplq/src/api/auth.js b/simplq/src/api/auth.js index c70c4997..fe5fdb88 100644 --- a/simplq/src/api/auth.js +++ b/simplq/src/api/auth.js @@ -1,10 +1,10 @@ import { useAuth0 } from '@auth0/auth0-react'; import { v4 as uuidv4 } from 'uuid'; import axios from 'axios'; -import * as Sentry from '@sentry/react'; // config.js is generated at runtime, so disabling eslint warning /* eslint-disable import/no-unresolved, import/extensions */ +import { raiseException } from 'services/alerts'; import { baseURL } from '../config'; const ANONYMOUS_DEVICE_ID_KEY = 'anonymous-device-id'; @@ -53,14 +53,9 @@ const useMakeAuthedRequest = () => { Authorization: await getAuthHeaderValue(auth), }, }).catch((error) => { - // log error to sentry for alerting - let eventId; - Sentry.withScope((scope) => { - scope.setTag('Caught-at', 'API request'); - eventId = Sentry.captureException(error); - }); - // eslint-disable-next-line no-console - console.log(`Sentry exception captured, event id is ${eventId}`); + // log error to alerting + raiseException(error, 'API request'); + // In case of request failure, extract error from response body if (error.response) { // Response has been received from the server diff --git a/simplq/src/api/requestFactory/index.js b/simplq/src/api/requestFactory/index.js index d6cd121d..e3464cc9 100644 --- a/simplq/src/api/requestFactory/index.js +++ b/simplq/src/api/requestFactory/index.js @@ -36,3 +36,5 @@ export { notifyToken, getTokenByContactNumber, } from './token'; + +export { linkDevice, unlinkDevice } from './owner'; diff --git a/simplq/src/api/requestFactory/owner.js b/simplq/src/api/requestFactory/owner.js new file mode 100644 index 00000000..a4d17777 --- /dev/null +++ b/simplq/src/api/requestFactory/owner.js @@ -0,0 +1,21 @@ +/** + * Subscribe to backend for notifications + * + * @param {String} deviceId - device token that identifies this device + * @returns {Object} request - partial axios request without baseURL + */ +export const linkDevice = (deviceId) => ({ + method: 'put', + url: `/owner/link?deviceId=${deviceId}`, +}); + +/** + * Unsubscribe to backend for notifications + * + * @param {String} deviceId - device token that identifies this device + * @returns {Object} request - partial axios request without baseURL + */ +export const unlinkDevice = (deviceId) => ({ + method: 'patch', + url: `/owner/unlink?deviceId=${deviceId}`, +}); diff --git a/simplq/src/components/ErrorHandler.jsx b/simplq/src/components/ErrorHandler.jsx index f6796dde..1cae1e25 100644 --- a/simplq/src/components/ErrorHandler.jsx +++ b/simplq/src/components/ErrorHandler.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import * as Sentry from '@sentry/react'; +import { raiseException } from 'services/alerts'; import PageNotFound from './pages/PageNotFound'; // eslint-disable-next-line import/prefer-default-export @@ -19,17 +19,8 @@ export class ErrorBoundary extends React.Component { } componentDidCatch(error, errorInfo) { - // You can also log the error to an error reporting service - // logErrorToMyService(error, errorInfo); - // log error to sentry for alerting - let eventId; - Sentry.withScope((scope) => { - scope.setTag('Caught-at', 'Error Boundary'); - scope.setExtras(errorInfo); - eventId = Sentry.captureException(error); - }); - // eslint-disable-next-line no-console - console.log(`Sentry exception captured, event id is ${eventId}`); + // log the error to our error reporting service + raiseException(error, 'Error Boundary', errorInfo); } render() { diff --git a/simplq/src/components/pages/Join/JoinForm.jsx b/simplq/src/components/pages/Join/JoinForm.jsx index d9677f35..450083b7 100644 --- a/simplq/src/components/pages/Join/JoinForm.jsx +++ b/simplq/src/components/pages/Join/JoinForm.jsx @@ -13,6 +13,7 @@ import StepLabel from '@material-ui/core/StepLabel'; import Typography from '@material-ui/core/Typography'; import { useJoinQueue } from 'store/asyncActions'; import { useGetTokenByContactNumber } from 'store/asyncActions/getTokenByContactNumber'; +import { useRegisterForNotifications } from 'services/notification/firebase'; import styles from './JoinForm.module.scss'; import Checkbox from '../../common/Checkbox/Checkbox'; import { selectQueueInfo } from '../../../store/queueInfo'; @@ -29,7 +30,9 @@ export function JoinQueueForm({ queueId, isAdminPage, buttonText }) { const [activeStep, setActiveStep] = React.useState(0); const queueInfo = useSelector(selectQueueInfo); const [saveToLocalStorage, setSaveToLocalStorage] = useState(true); + const [notifyDevice, setNotifyDevice] = useState(true); const getTokenByContactNumber = useCallback(useGetTokenByContactNumber(), []); + const registerForNotifications = useCallback(useRegisterForNotifications(), []); const { notifyByEmail } = useSelector(selectQueueInfo); const collectEmail = !!notifyByEmail; @@ -141,6 +144,10 @@ export function JoinQueueForm({ queueId, isAdminPage, buttonText }) { localStorage.removeItem('email'); } + if (notifyDevice) { + registerForNotifications(); + } + joinQueueHandler(); // reset to first step on queue page (pages/Admin/AddMember.jsx) if (isAdminPage) setActiveStep(0); @@ -226,6 +233,14 @@ export function JoinQueueForm({ queueId, isAdminPage, buttonText }) { setSaveToLocalStorage(!saveToLocalStorage); }} /> + { + setNotifyDevice(!notifyDevice); + }} + />
diff --git a/simplq/src/components/pages/TokenStatus/NotificationContainer.jsx b/simplq/src/components/pages/TokenStatus/NotificationContainer.jsx index c9441a52..99eea3e4 100644 --- a/simplq/src/components/pages/TokenStatus/NotificationContainer.jsx +++ b/simplq/src/components/pages/TokenStatus/NotificationContainer.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import Switch from '@material-ui/core/Switch'; import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined'; -import { setNotificationPreference } from 'services/notification'; +import { setNotificationPreference } from 'services/notification/system'; import styles from './status.module.scss'; export default () => { diff --git a/simplq/src/index.jsx b/simplq/src/index.jsx index ac3613d2..c1fe1390 100644 --- a/simplq/src/index.jsx +++ b/simplq/src/index.jsx @@ -3,8 +3,6 @@ import ReactDOM from 'react-dom'; import './index.css'; import { createTheme, ThemeProvider } from '@material-ui/core/styles'; import { Provider } from 'react-redux'; -import * as Sentry from '@sentry/react'; -import { Integrations } from '@sentry/tracing'; import AOS from 'aos'; import { Auth0Provider } from '@auth0/auth0-react'; import { store } from './store'; @@ -13,12 +11,6 @@ import Layout from './components/Layout/Layout'; AOS.init(); -Sentry.init({ - dsn: 'https://b95e1a087d284ecca9a50909d2a792e8@o444913.ingest.sentry.io/5420492', - integrations: [new Integrations.BrowserTracing()], - tracesSampleRate: 1.0, -}); - const theme = createTheme({ palette: { primary: { diff --git a/simplq/src/services/alerts/index.js b/simplq/src/services/alerts/index.js new file mode 100644 index 00000000..e986ded7 --- /dev/null +++ b/simplq/src/services/alerts/index.js @@ -0,0 +1,35 @@ +import * as Sentry from '@sentry/react'; +import { Integrations } from '@sentry/tracing'; + +Sentry.init({ + dsn: 'https://b95e1a087d284ecca9a50909d2a792e8@o444913.ingest.sentry.io/5420492', + integrations: [new Integrations.BrowserTracing()], + tracesSampleRate: 1.0, +}); + +/** + * Send exception to monitoring framework. + * + * @param {Exception} ex - exception that was captured. + * @param {string} caughtAt - Optional. A tag indicating where the exception was caught. + * @param {object} extras - Optional. Set an object that will be merged sent as extra data with the event. + */ +export function raiseException(ex, caughtAt, extras) { + Sentry.withScope((scope) => { + if (caughtAt) { + scope.setTag('Caught-at', caughtAt); + } + if (extras) { + scope.setExtras(extras); + } + + const eventId = Sentry.captureException(ex); + + // eslint-disable-next-line no-console + console.log(`Sentry exception captured, event id is ${eventId}`); + // eslint-disable-next-line no-console + console.error(ex); + }); +} + +export default raiseException; diff --git a/simplq/src/services/notification/firebase.js b/simplq/src/services/notification/firebase.js new file mode 100644 index 00000000..3c9f7a0d --- /dev/null +++ b/simplq/src/services/notification/firebase.js @@ -0,0 +1,47 @@ +import { getMessaging, getToken } from 'firebase/messaging'; +import { initializeApp } from 'firebase/app'; +import { setErrorPopupMessage } from 'store/appSlice'; +import { store } from 'store'; +import { raiseException } from 'services/alerts'; +import { useLinkDevice } from 'store/asyncActions'; + +// Public key generated from firebase console +const vapidKey = + 'BCAlBO-AnqZIo_3MEiR5zEwJTFNNWBR6MdmZ5RpStXxTN6vfgUV2mL3c_hz8vQkcQ2bb_a7IMlGUhAnaw3eBZm4'; +// Firebase configuration +const firebaseConfig = { + apiKey: 'AIzaSyCCW7gmWZli24N61NShh-8ALxVy3WtjqNU', + authDomain: 'simplq-fe712.firebaseapp.com', + projectId: 'simplq-fe712', + storageBucket: 'simplq-fe712.appspot.com', + messagingSenderId: '348531792421', + appId: '1:348531792421:web:c481f1740405522d0f3dcc', + measurementId: 'G-8N2SDV8VF5', +}; + +// Initialize Firebase +const firebaseApp = initializeApp(firebaseConfig); +const messaging = getMessaging(firebaseApp); + +/** + * React hook that lets you register for notifications. + */ +export function useRegisterForNotifications() { + const linkDevice = useLinkDevice(); + + const registerForNotifications = () => { + getToken(messaging, { vapidKey }) + .then((deviceId) => { + store.dispatch(linkDevice(deviceId)); + }) + .catch((ex) => { + store.dispatch(setErrorPopupMessage('An error occurred while setting up notifcations.')); + raiseException(ex, 'firebase/registerNotifications'); + }); + }; + + return registerForNotifications; +} + +// TODO +export function useDeregisterNotifications() {} diff --git a/simplq/src/services/notification.js b/simplq/src/services/notification/system.js similarity index 100% rename from simplq/src/services/notification.js rename to simplq/src/services/notification/system.js diff --git a/simplq/src/store/appSlice.js b/simplq/src/store/appSlice.js index 89920419..363b8127 100644 --- a/simplq/src/store/appSlice.js +++ b/simplq/src/store/appSlice.js @@ -1,6 +1,6 @@ /* eslint-disable no-param-reassign */ import { createSlice } from '@reduxjs/toolkit'; -import { createQueue, deleteQueue, joinQueue } from 'store/asyncActions'; +import { createQueue, deleteQueue, joinQueue, linkDevice } from 'store/asyncActions'; function isRejectedAction(action) { return action.type.endsWith('rejected'); @@ -11,7 +11,9 @@ const appSlice = createSlice({ initialState: { errorText: '', infoText: '', - notificationPermission: null, // This state value is initialised by the notification service. + // This value is initilised at start by services/notification/system.js + notificationPermission: null, + firebaseNotificationDeviceId: null, }, reducers: { setErrorPopupMessage: (state, action) => { @@ -44,6 +46,10 @@ const appSlice = createSlice({ .addCase(deleteQueue.fulfilled, (state, action) => { state.infoText = `Deleted ${action.payload.queueName}`; }) + .addCase(linkDevice.fulfilled, (state, action) => { + state.notificationPermission = true; + state.firebaseNotificationDeviceId = action.payload.deviceId; + }) .addMatcher(isRejectedAction, (state, action) => { // All failed network calls are handled here state.errorText = action.error.message; diff --git a/simplq/src/store/asyncActions/index.js b/simplq/src/store/asyncActions/index.js index 7286b98b..6eab8455 100644 --- a/simplq/src/store/asyncActions/index.js +++ b/simplq/src/store/asyncActions/index.js @@ -5,6 +5,8 @@ * in separate files and can depend on each other. */ +export { linkDevice, useLinkDevice } from './linkDevice'; + export { getUserQueues, useGetUserQueues } from './getUserQueues'; export { getUserTokens, useGetUserTokens } from './getUserTokens'; export { deleteQueue, useDeleteQueue } from './deleteQueue'; diff --git a/simplq/src/store/asyncActions/linkDevice.js b/simplq/src/store/asyncActions/linkDevice.js new file mode 100644 index 00000000..529e745f --- /dev/null +++ b/simplq/src/store/asyncActions/linkDevice.js @@ -0,0 +1,24 @@ +import { createAsyncThunk } from '@reduxjs/toolkit'; +import { useMakeAuthedRequest } from 'api/auth'; +import * as RequestFactory from 'api/requestFactory'; + +const typePrefix = 'linkDevice/action'; + +/** + * A hook to access the linkDevice async action creator. + * + * @returns — linkDevice async action creator + */ +const useLinkDevice = () => { + const makeAuthedRequest = useMakeAuthedRequest(); + + const linkDevice = createAsyncThunk(typePrefix, async (deviceId) => { + return makeAuthedRequest(RequestFactory.linkDevice(deviceId)); + }); + + return linkDevice; +}; + +const linkDevice = createAsyncThunk(typePrefix); + +export { linkDevice, useLinkDevice };