diff --git a/.gitignore b/.gitignore index 0926825..367d769 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ baseline.json # Ignore .history for the xyz.local-history VSCode extension .history +.secret diff --git a/package-lock.json b/package-lock.json index 74b4e09..5d8d00a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1553,7 +1553,6 @@ "version": "7.9.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.4" }, @@ -1561,8 +1560,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" } } }, @@ -1865,6 +1863,51 @@ } } }, + "@supabase/postgrest-js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-0.17.0.tgz", + "integrity": "sha512-7Dt7ALli+bOQK51JMolraI08sJg2UweNuGFghr8MrX4nc3WoDwL5PP6fNZwy+j/7f7nvvM6s1OUtqNTvqiW+5Q==", + "requires": { + "superagent": "^5.2.1" + } + }, + "@supabase/realtime-js": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-0.9.0.tgz", + "integrity": "sha512-aYkVsD2hNgD7QPPBV+LALJTexNf8pVhIh9qJC13NnOLYZpudtHbof+rg0dgq5+GIhYa8HzqUMdf+OwwlQVJgsw==", + "requires": { + "@babel/runtime": "^7.9.2", + "query-string": "^6.12.1", + "websocket": "^1.0.31" + }, + "dependencies": { + "query-string": { + "version": "6.13.6", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.6.tgz", + "integrity": "sha512-/WWZ7d9na6s2wMEGdVCVgKWE9Rt7nYyNIf7k8xmHXcesPMlEzicWo3lbYwHyA4wBktI2KrXxxZeACLbE84hvSQ==", + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" + } + } + }, + "@supabase/supabase-js": { + "version": "0.36.5", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-0.36.5.tgz", + "integrity": "sha512-iiY5lDIrbhQjT8grRgXbUfIU5omD8CfNI4Iio3z/DHjsdrzYNf9o0/kRAzVVITPOuqlN9g0QhPt7bzRQKxLbwA==", + "requires": { + "@supabase/postgrest-js": "^0.17.0", + "@supabase/realtime-js": "^0.9.0", + "superagent": "^5.2.1" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -2604,8 +2647,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -3237,6 +3279,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, + "optional": true, "requires": { "hoek": "2.x.x" } @@ -3431,7 +3474,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", - "dev": true + "dev": true, + "optional": true }, "buffer-xor": { "version": "1.0.3", @@ -3439,6 +3483,14 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, + "bufferutil": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.1.tgz", + "integrity": "sha512-xowrxvpxojqkagPcWRQVXZl0YXhRhAtBEIq3VoER1NH5Mw1n1o0ojdspp+GS2J//2gCVyrzQDApQ4unGF+QOoA==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, "buildmail": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", @@ -3952,7 +4004,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3978,8 +4029,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "component-inherit": { "version": "0.0.3", @@ -4136,6 +4186,11 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -4688,7 +4743,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -4757,8 +4811,7 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { "version": "1.1.1", @@ -4971,8 +5024,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "depd": { "version": "1.1.2", @@ -5438,7 +5490,6 @@ "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.3", @@ -5449,7 +5500,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -5475,7 +5525,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" @@ -5796,7 +5845,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, "requires": { "type": "^2.0.0" }, @@ -5804,8 +5852,7 @@ "type": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", - "dev": true + "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==" } } }, @@ -5963,6 +6010,11 @@ "dev": true, "optional": true }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -6167,6 +6219,11 @@ "mime-types": "^2.1.12" } }, + "formidable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -6727,7 +6784,8 @@ "version": "2.16.3", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true + "dev": true, + "optional": true }, "homedir-polyfill": { "version": "1.0.3", @@ -7007,6 +7065,7 @@ "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", "dev": true, + "optional": true, "requires": { "httpreq": ">=0.4.22", "underscore": "~1.7.0" @@ -7016,7 +7075,8 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", - "dev": true + "dev": true, + "optional": true }, "https-browserify": { "version": "1.0.0", @@ -7556,7 +7616,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true + "dev": true, + "optional": true }, "is-regex": { "version": "1.1.1", @@ -7600,8 +7661,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -8535,13 +8595,15 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", - "dev": true + "dev": true, + "optional": true }, "libmime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", "dev": true, + "optional": true, "requires": { "iconv-lite": "0.4.15", "libbase64": "0.1.0", @@ -8552,7 +8614,8 @@ "version": "0.4.15", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", - "dev": true + "dev": true, + "optional": true } } }, @@ -8560,7 +8623,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", - "dev": true + "dev": true, + "optional": true }, "license-webpack-plugin": { "version": "2.2.0", @@ -9146,8 +9210,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { "version": "4.0.2", @@ -9186,14 +9249,12 @@ "mime-db": { "version": "1.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", - "dev": true + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { "version": "2.1.27", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", - "dev": true, "requires": { "mime-db": "1.44.0" } @@ -9521,8 +9582,7 @@ "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "nice-try": { "version": "1.0.5", @@ -9547,6 +9607,11 @@ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", "dev": true }, + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==" + }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -9658,13 +9723,15 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", - "dev": true + "dev": true, + "optional": true }, "nodemailer-shared": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", "dev": true, + "optional": true, "requires": { "nodemailer-fetch": "1.6.0" } @@ -9697,7 +9764,8 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", - "dev": true + "dev": true, + "optional": true }, "normalize-package-data": { "version": "2.5.0", @@ -11510,7 +11578,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "dev": true, + "optional": true }, "prepend-http": { "version": "1.0.4", @@ -13389,6 +13458,7 @@ "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", "dev": true, + "optional": true, "requires": { "httpntlm": "1.6.1", "nodemailer-shared": "1.1.0" @@ -13889,6 +13959,11 @@ "chalk": "^2.0.1" } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -14115,7 +14190,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -14282,6 +14356,61 @@ } } }, + "superagent": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-5.3.1.tgz", + "integrity": "sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "dependencies": { + "form-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==" + }, + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + }, + "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" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -14730,14 +14859,14 @@ "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, + "optional": true, "requires": { "prelude-ls": "~1.1.2" } @@ -14764,6 +14893,14 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "3.9.7", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", @@ -14807,7 +14944,8 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true + "dev": true, + "optional": true }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", @@ -15135,6 +15273,14 @@ } } }, + "utf-8-validate": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.2.tgz", + "integrity": "sha512-SwV++i2gTD5qh2XqaPzBnNX88N6HdyhQrNNRykvcS0QKvItV9u3vPEJr+X5Hhfb1JC0r0e1alL0iB09rY8+nmw==", + "requires": { + "node-gyp-build": "~3.7.0" + } + }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", @@ -15155,8 +15301,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util-promisify": { "version": "2.1.0", @@ -15339,13 +15484,15 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -15364,6 +15511,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -15396,6 +15544,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -15408,6 +15557,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -15442,6 +15592,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -15451,6 +15602,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -16368,6 +16520,34 @@ "webpack-sources": "^1.3.0" } }, + "websocket": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.32.tgz", + "integrity": "sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==", + "requires": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "websocket-driver": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", @@ -16570,6 +16750,11 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", diff --git a/package.json b/package.json index 9e7c60e..ed2944e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@angular/platform-browser-dynamic": "^10.0.0", "@angular/router": "^10.0.0", "@ng-bootstrap/ng-bootstrap": "7.0.0", + "@supabase/supabase-js": "^0.36.5", "bootstrap": "4.5.2", "core-js": "3.6.4", "recordrtc": "^5.6.1", diff --git a/src/app/api/supabase/supa.service.spec.ts b/src/app/api/supabase/supa.service.spec.ts new file mode 100644 index 0000000..5fac222 --- /dev/null +++ b/src/app/api/supabase/supa.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { SupaService } from './supa.service'; + +describe('SupaService', () => { + let service: SupaService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(SupaService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/api/supabase/supa.service.ts b/src/app/api/supabase/supa.service.ts new file mode 100644 index 0000000..1546e33 --- /dev/null +++ b/src/app/api/supabase/supa.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { createClient, SupabaseClient } from '@supabase/supabase-js' +import { environment } from '../../../environments/environment' + + +@Injectable({ + providedIn: 'root' +}) +export class SupaService { + client: SupabaseClient; + + constructor() { + // Create a single supabase client for interacting with your database + this.client = createClient(environment.supa_url, environment.supa_key); + console.log('supa', this.client) + } +} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 0000000..f6a49fa --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,38 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule, Routes } from '@angular/router'; +// Components +import { HuddleComponent } from './huddle/huddle.component'; +import { LoginComponent } from './login/login.component'; +import { SignupComponent } from './signup/signup.component'; +import { AuthGuard } from './authguard.service'; + +const routes: Routes = [ + { + path: 'huddle', + component: HuddleComponent, + canActivate: [AuthGuard] + }, + { + path: 'login', + component: LoginComponent, + }, + { + path: 'signup', + component: SignupComponent, + }, + { path: '**', redirectTo: '/huddle', pathMatch: 'full' }, +] + +@NgModule({ + declarations: [], + imports: [ + CommonModule, + RouterModule.forRoot(routes, { + useHash: true, + onSameUrlNavigation: 'reload', + }) + ], + exports: [RouterModule] +}) +export class AppRoutingModule { } diff --git a/src/app/app.component.html b/src/app/app.component.html index d5bc967..2878dbc 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,48 +2,5 @@ ASYNC HUDDLE
-
-
- -
-
-
-
-

{{user.name}}

-

{{user.submit_time | date :'dd.MM. HH:mm' }}

-
-
-
+
- - - - \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss index efae403..e69de29 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,50 +0,0 @@ -.storyImage { - width: 200px; - height: 200px; - border-radius: 50%; - background-repeat: no-repeat; - background-position: center; - background-size: cover; - margin: 0 auto; -} -.storyImage.hasStory:before { - content: ""; - position: relative; - right: 1%; - bottom: 1%; - z-index: -1; - border-radius: inherit; - background: -webkit-gradient( - linear, - left top, - right top, - from(red), - to(orange) - ); - background: linear-gradient(to right, red, orange); - width: 205px; - height: 205px; - margin: 0 auto; - display: block; -} -.modal-body { - height: 90vh; -} -.modal-body video { - width: 100%; - height: auto; - overflow-y: hidden; -} -.modal-body .close { - margin: 0 auto; -} -.modal-body .control { - position: absolute; - top: 20px; -} -.modal-body .control.right { - right: 20px; -} -.modal-body .control.left { - left: 20px; -} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 78702e9..1eaee2d 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,4 @@ -import { Component, ViewChild } from "@angular/core"; -import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; +import { Component } from "@angular/core"; @Component({ selector: "app-root", @@ -7,81 +6,4 @@ import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; styleUrls: ["./app.component.scss"] }) export class AppComponent { - @ViewChild("content") content; - @ViewChild("activeStory") video; - users = [ - { - name: "Jan", - image: "https://www.supercardating.com/doc/image.rhtm/profile-pic2.jpg", - submit_time: 1601655386668, - story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_beagle.mp4" - }, - { - name: "Bob", - image: - "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.4oYqJqInuQd2TAlPPdggLgHaHa%26pid%3DApi&f=1", - submit_time: null, - story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_golden.mp4" - }, - { - name: "Angela", - image: - "https://writestylesonline.com/wp-content/uploads/2019/01/What-To-Wear-For-Your-Professional-Profile-Picture-or-Headshot.jpg", - submit_time: 1601655386668, - story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_frenchie.mp4" - } - ]; - selectedUser; - - constructor(private modalService: NgbModal) {} - - playStory(user) { - if (!user.submit_time || !user.story_link) { - return; - } - this.modalService.open(this.content, { centered: true }); - this.selectedUser = user; - } - - prevUser(modal: NgbModalRef) { - let index: number = this.users.findIndex( - (u) => u.name === this.selectedUser.name - ); - if (index < 1) { - modal.close(); - return; - } - while ( - !this.users[index - 1].story_link || - !this.users[index - 1].submit_time - ) { - index--; - if (index === 0) { - modal.close(); - return; - } - } - this.selectedUser = this.users[index - 1]; - } - - nextUser(modal: NgbModalRef) { - let index: number = this.users.findIndex( - (u) => u.name === this.selectedUser.name - ); - if (index === -1 || index === this.users.length - 1) { - modal.close(); - return; - } - while ( - !this.users[index + 1].story_link || - !this.users[index + 1].submit_time - ) { - if (index === -1 || index === this.users.length - 1) { - modal.close(); - return; - } - index++; - } - this.selectedUser = this.users[index + 1]; - } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index a60cfa8..d5bf855 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,14 +1,36 @@ import { BrowserModule } from "@angular/platform-browser"; import { NgModule } from "@angular/core"; -import { AppComponent } from "./app.component"; import { NgbModalModule } from "@ng-bootstrap/ng-bootstrap"; +import { AppRoutingModule } from './app-routing.module'; + +import { SupaService } from './api/supabase/supa.service'; +import { AuthGuard } from './authguard.service'; + +import { AppComponent } from "./app.component"; import { RecorderComponent } from './recorder/recorder.component'; +import { LoginComponent } from './login/login.component'; +import { SignupComponent } from './signup/signup.component'; +import { HuddleComponent } from './huddle/huddle.component'; @NgModule({ - declarations: [AppComponent, RecorderComponent], - imports: [BrowserModule, NgbModalModule], - providers: [], - bootstrap: [AppComponent] + declarations: [ + AppComponent, + RecorderComponent, + HuddleComponent, + LoginComponent, + SignupComponent + ], + imports: [ + BrowserModule, + NgbModalModule, + AppRoutingModule], + providers: [ + SupaService, + AuthGuard, + ], + bootstrap: [ + AppComponent + ] }) export class AppModule {} diff --git a/src/app/authguard.service.spec.ts b/src/app/authguard.service.spec.ts new file mode 100644 index 0000000..9049600 --- /dev/null +++ b/src/app/authguard.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthguardService } from './authguard.service'; + +describe('AuthguardService', () => { + let service: AuthguardService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthguardService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/authguard.service.ts b/src/app/authguard.service.ts new file mode 100644 index 0000000..19a7d70 --- /dev/null +++ b/src/app/authguard.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; +import { Observable } from 'rxjs'; +import { SupaService } from './api/supabase/supa.service'; + + +@Injectable() +export class AuthGuard implements CanActivate { + constructor( + private router: Router, + private supa: SupaService + ) {} + + canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { + + /* Try to auth with the server. If authed resolve to true, else resolve to false */ + return this.supa.client.auth.user() + .then(() => true) + .catch(() => { + this.router.navigate(['/login']); + return false; + }); + } +} diff --git a/src/app/huddle/huddle.component.html b/src/app/huddle/huddle.component.html new file mode 100644 index 0000000..4327aea --- /dev/null +++ b/src/app/huddle/huddle.component.html @@ -0,0 +1,44 @@ +
+
+ +
+
+
+
+

{{user.name}}

+

{{user.submit_time | date :'dd.MM. HH:mm' }}

+
+
+
+ + + + \ No newline at end of file diff --git a/src/app/huddle/huddle.component.scss b/src/app/huddle/huddle.component.scss new file mode 100644 index 0000000..2847ca5 --- /dev/null +++ b/src/app/huddle/huddle.component.scss @@ -0,0 +1,55 @@ +.storyImage { + width: 200px; + height: 200px; + border-radius: 50%; + background-repeat: no-repeat; + background-position: center; + background-size: cover; + margin: 0 auto; +} + +.storyImage.hasStory:before { + content: ""; + position: relative; + right: 1%; + bottom: 1%; + z-index: -1; + border-radius: inherit; + background: -webkit-gradient(linear, + left top, + right top, + from(red), + to(orange)); + background: linear-gradient(to right, red, orange); + width: 205px; + height: 205px; + margin: 0 auto; + display: block; +} + +.modal-body { + height: 90vh; +} + +.modal-body video { + width: 100%; + height: auto; + overflow-y: hidden; +} + +.modal-body .close { + margin: 0 auto; +} + +.modal-body .control { + position: absolute; + top: 20px; +} + +.modal-body .control.right { + right: 20px; +} + +.modal-body .control.left { + left: 20px; +} \ No newline at end of file diff --git a/src/app/huddle/huddle.component.spec.ts b/src/app/huddle/huddle.component.spec.ts new file mode 100644 index 0000000..0cdef35 --- /dev/null +++ b/src/app/huddle/huddle.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HuddleComponent } from './huddle.component'; + +describe('HuddleComponent', () => { + let component: HuddleComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HuddleComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HuddleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/huddle/huddle.component.ts b/src/app/huddle/huddle.component.ts new file mode 100644 index 0000000..25f3297 --- /dev/null +++ b/src/app/huddle/huddle.component.ts @@ -0,0 +1,91 @@ +import { Component, OnInit, ViewChild } from "@angular/core"; +import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; + +@Component({ + selector: 'app-huddle', + templateUrl: './huddle.component.html', + styleUrls: ['./huddle.component.scss'] +}) +export class HuddleComponent implements OnInit { + @ViewChild("content") content; + @ViewChild("activeStory") video; + users = [ + { + name: "Jan", + image: "https://www.supercardating.com/doc/image.rhtm/profile-pic2.jpg", + submit_time: 1601655386668, + story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_beagle.mp4" + }, + { + name: "Bob", + image: + "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse1.mm.bing.net%2Fth%3Fid%3DOIP.4oYqJqInuQd2TAlPPdggLgHaHa%26pid%3DApi&f=1", + submit_time: null, + story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_golden.mp4" + }, + { + name: "Angela", + image: + "https://writestylesonline.com/wp-content/uploads/2019/01/What-To-Wear-For-Your-Professional-Profile-Picture-or-Headshot.jpg", + submit_time: 1601655386668, + story_link: "https://erjb.s3.nl-ams.scw.cloud/ttk_frenchie.mp4" + } + ]; + selectedUser; + + constructor(private modalService: NgbModal) {} + + ngOnInit() { + + } + + playStory(user) { + if (!user.submit_time || !user.story_link) { + return; + } + this.modalService.open(this.content, { centered: true }); + this.selectedUser = user; + } + + prevUser(modal: NgbModalRef) { + let index: number = this.users.findIndex( + (u) => u.name === this.selectedUser.name + ); + if (index < 1) { + modal.close(); + return; + } + while ( + !this.users[index - 1].story_link || + !this.users[index - 1].submit_time + ) { + index--; + if (index === 0) { + modal.close(); + return; + } + } + this.selectedUser = this.users[index - 1]; + } + + nextUser(modal: NgbModalRef) { + let index: number = this.users.findIndex( + (u) => u.name === this.selectedUser.name + ); + if (index === -1 || index === this.users.length - 1) { + modal.close(); + return; + } + while ( + !this.users[index + 1].story_link || + !this.users[index + 1].submit_time + ) { + if (index === -1 || index === this.users.length - 1) { + modal.close(); + return; + } + index++; + } + this.selectedUser = this.users[index + 1]; + } +} diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html new file mode 100644 index 0000000..147cfc4 --- /dev/null +++ b/src/app/login/login.component.html @@ -0,0 +1 @@ +

login works!

diff --git a/src/app/login/login.component.scss b/src/app/login/login.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/login/login.component.spec.ts b/src/app/login/login.component.spec.ts new file mode 100644 index 0000000..d2c0e6c --- /dev/null +++ b/src/app/login/login.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts new file mode 100644 index 0000000..c74528f --- /dev/null +++ b/src/app/login/login.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.scss'] +}) +export class LoginComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/recorder/recorder.component.html b/src/app/recorder/recorder.component.html index 5aadad5..d5b1144 100644 --- a/src/app/recorder/recorder.component.html +++ b/src/app/recorder/recorder.component.html @@ -12,7 +12,7 @@ - +