Procházet zdrojové kódy

:recycle: probably too big of an update | pubnub chat | sse notifications | planetscale connection script | added some env vars

tags/0.0.1
J před 4 roky
rodič
revize
1dc52ef5a1

+ 7
- 1
backend/.env.sample Zobrazit soubor

@@ -7,8 +7,14 @@ API_HOST=localhost
7 7
 API_PORT=3001
8 8
 APP_SECRET=mysecret
9 9
 
10
+USE_LOCAL_DB=true
11
+
10 12
 DB_ROOT_PASSWORD=root
11 13
 DB_USER=root
12 14
 DB_NAME=test
13 15
 DB_HOST=localhost
14
-DB_TYPE=mysql
16
+DB_TYPE=mysql
17
+DB_PORT=3306
18
+
19
+PSCALE_DB_BRANCH=main
20
+PSCALE_DB_NAME=planet-scale-db

+ 18
- 7
backend/knexfile.js Zobrazit soubor

@@ -1,15 +1,26 @@
1 1
 require('dotenv').config()
2 2
 
3
+const local = {
4
+    host: process.env.DB_HOST,
5
+    user: process.env.DB_USER,
6
+    password: process.env.DB_ROOT_PASSWORD,
7
+    database: process.env.DB_NAME,
8
+    port: process.env.DB_PORT
9
+}
10
+const pscale = {
11
+    host: process.env.PSCALE_DB_HOST ? process.env.PSCALE_DB_HOST : '127.0.0.1',
12
+    user: process.env.PSCALE_DB_USER ? process.env.PSCALE_DB_USER : 'root',
13
+    password: process.env.PSCALE_DB_PASSWORD ? process.env.PSCALE_DB_PASSWORD : '', 
14
+    database: process.env.PSCALE_DB_NAME,
15
+    port: process.env.PSCALE_DB_PORT ? process.env.PSCALE_DB_PORT : 3306
16
+}
17
+
18
+const connectionSettings = process.env.USE_LOCAL_DB == true ? local : pscale
19
+
3 20
 module.exports = {
4 21
     development: {
5 22
         client: process.env.DB_TYPE,
6
-        connection: {
7
-            host: process.env.DB_HOST,
8
-            user: process.env.DB_USER,
9
-            password: process.env.DB_ROOT_PASSWORD,
10
-            database: process.env.DB_NAME,
11
-            port: 3307
12
-        },
23
+        connection: connectionSettings,
13 24
         pool: {
14 25
             min: 2,
15 26
             max: 10

+ 1
- 65
backend/lib/plugins/notification.js Zobrazit soubor

@@ -1,69 +1,5 @@
1
-const Stream = require('stream')
2
-const PassThrough = Stream.PassThrough
3
-const Transform = Stream.Transform
4 1
 const NotificationRoute = require('../routes/notification')
5
-
6
-const stringifyEvent = function (event) {
7
-    let str = ''
8
-    const endl = '\r\n'
9
-    for (const i in event) {
10
-        let val = event[i]
11
-        if (val instanceof Buffer) { val = val.toString() }
12
-        if (typeof val === 'object') { val = JSON.stringify(val) }
13
-        str += i + ': ' + val + endl
14
-    }
15
-    str += endl
16
-    return str
17
-}
18
-
19
-class Transformer extends Transform {
20
-    constructor(options, objectMode) {
21
-        super({ objectMode })
22
-        options = options || {}
23
-        this.counter = 1
24
-        this.event = options.event || null
25
-        this.generateId = options.generateId ? options.generateId : () => {
26
-            return this.counter++
27
-        }
28
-    }
29
-    _transform (chunk, encoding, callback) {
30
-        const event = {
31
-            id: this.generateId(chunk),
32
-            data: chunk
33
-        }
34
-        if (this.event) { event.event = this.event }
35
-        this.push(stringifyEvent(event))
36
-        callback()
37
-    }
38
-    _flush(callback) {
39
-        this.push(stringifyEvent({ event: 'end', data: '' }))
40
-        callback()
41
-    }
42
-} 
43
-
44
-const writeEvent = function (event, stream) {
45
-    if (event) {
46
-        stream.write(stringifyEvent(event))
47
-    } else {
48
-        // closing time
49
-        stream.write(stringifyEvent({ event: 'end', data: '' }))
50
-        stream.end()
51
-    }
52
-}
53
-
54
-const onEvent = (event, h, streamOptions) => {
55
-    // We only support ObjectMode streams
56
-    if (!event._readableState.objectMode) return
57
-
58
-    const through = new Transformer(streamOptions, true)
59
-    const active = new PassThrough()
60
-    through.pipe(active)
61
-    event.pipe(through)
62
-    console.log(event)
63
-    return h.response(active)
64
-        .header('content-type', 'text/event-stream')
65
-        .header('content-encoding', 'identity')
66
-}
2
+const { onEvent } = require('../services/notification')
67 3
 
68 4
 module.exports = {
69 5
     name: 'notification-plugin',

+ 118
- 0
backend/lib/services/notification.js Zobrazit soubor

@@ -0,0 +1,118 @@
1
+/** Heavily lifted from: https://github.com/mtharrison/susie/blob/master/lib/index.js */
2
+
3
+const Stream = require('stream')
4
+const PassThrough = Stream.PassThrough
5
+const Transform = Stream.Transform
6
+
7
+const ENDER = { event: 'end', data: '' }
8
+
9
+/**
10
+ * Stringify a stream
11
+ * ?: I don't really get what this is doing
12
+ * @param {Stream} event
13
+ * @returns {string}
14
+ */
15
+const stringifyEvent = function (event) {
16
+    let str = ''
17
+    const endl = '\r\n'
18
+    for (const i in event) {
19
+        let val = event[i]
20
+        if (val instanceof Buffer) { val = val.toString() }
21
+        if (typeof val === 'object') { val = JSON.stringify(val) }
22
+        str += i + ': ' + val + endl
23
+    }
24
+    str += endl
25
+    return str
26
+}
27
+
28
+/**
29
+ * Transform extension
30
+ * ?: I don't really get what this is doing
31
+ * @param {object} options
32
+ * @param {object} objectMode 
33
+ */
34
+class Transformer extends Transform {
35
+    constructor(options, objectMode) {
36
+        super({ objectMode })
37
+        options = options || {}
38
+        this.counter = 1
39
+        this.event = options.event || null
40
+        this.generateId = options.generateId ? options.generateId : () => {
41
+            return this.counter++
42
+        }
43
+    }
44
+    _transform (chunk, encoding, callback) {
45
+        const event = {
46
+            id: this.generateId(chunk),
47
+            data: chunk
48
+        }
49
+        if (this.event) { event.event = this.event }
50
+        this.push(stringifyEvent(event))
51
+        callback()
52
+    }
53
+    _flush(callback) {
54
+        this.push(stringifyEvent(ENDER))
55
+        callback()
56
+    }
57
+} 
58
+
59
+/**
60
+ * Take an event stream and write content to another stream
61
+ * ?: Save this for future extension
62
+ * @param {Stream} event stream input
63
+ * @param {Stream} stream to write to
64
+ */
65
+const writeEvent = function (event, stream) {
66
+    if (event) {
67
+        stream.write(stringifyEvent(event))
68
+    } else {
69
+        // closing time
70
+        stream.write(stringifyEvent(ENDER))
71
+        stream.end()
72
+    }
73
+}
74
+
75
+/**
76
+ * Callback to decorate server toolkit (h)
77
+ * !: Currently we only support ObjectMode streams
78
+ * ?: I don't really get what this is doing
79
+ * @param {Stream} event stream input
80
+ * @param {Toolkit} h hapi common response toolkit
81
+ * @param {object} streamOptions
82
+ */
83
+const onEvent = (event, h, streamOptions) => {
84
+    // const state = h.request.plugins.notifications = h.request.plugins.notifications || {}
85
+    let active
86
+    if (event instanceof Stream.Readable) {
87
+        if (event._readableState.objectMode) {
88
+            const through = new Transformer(streamOptions, true)
89
+            active = new PassThrough()
90
+            through.pipe(active)
91
+            event.pipe(through)
92
+        }
93
+        // else {
94
+        //     stream = new Transformer(streamOptions, false)
95
+        //     event.pipe(stream)
96
+        // }
97
+        return h.response(active)
98
+            .header('content-type', 'text/event-stream')
99
+            .header('content-encoding', 'identity')
100
+    }
101
+    // Uncomment to do stream state stuff
102
+    // handle a first object arg
103
+    // if (!state.stream) {
104
+    //     active = new PassThrough()
105
+    //     state.stream = active
106
+    //     state.mode = 'object'
107
+    //     const response = h.response(active)
108
+    //         .header('content-type', 'text/event-stream')
109
+    //         .header('content-encoding', 'identity')
110
+    //     writeEvent(event, active)
111
+    //     return response
112
+    // }
113
+    // already have an object stream flowing, just write next event
114
+    // active = state.stream
115
+    // internals.writeEvent(event, active)
116
+}
117
+
118
+module.exports = { onEvent }

+ 2
- 1
backend/package.json Zobrazit soubor

@@ -5,7 +5,8 @@
5 5
   "main": "index.js",
6 6
   "scripts": {
7 7
     "start": "nodemon server",
8
-    "migrate": "knex migjrate:latest",
8
+    "connect": "USE_LOCAL_DB=false pscale connect $(grep '^PSCALE_DB_NAME' .env | cut -d '=' -f2) $(grep '^PSCALE_DB_BRANCH' .env | cut -d '=' -f2)",
9
+    "migrate": "knex migrate:latest",
9 10
     "unmigrate": "knex migrate:down",
10 11
     "reseed": "knex migrate:rollback --all && knex migrate:latest && knex seed:run",
11 12
     "generate": "node ./db/data-generator/index.js",

+ 3
- 0
frontend/.env.sample Zobrazit soubor

@@ -0,0 +1,3 @@
1
+VITE_PUBNUB_PUBLISH_KEY=pub-a-123467890-123467890
2
+VITE_PUBNUB_SUBSCRIBE_KEY=sub-a-123467890-123467890
3
+VITE_UUID_SECRET=00000000-0000-1111-0000-000000000000

+ 537
- 42
frontend/package-lock.json Zobrazit soubor

@@ -25,6 +25,14 @@
25 25
             "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.4.tgz",
26 26
             "integrity": "sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng=="
27 27
         },
28
+        "@babel/runtime": {
29
+            "version": "7.17.2",
30
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
31
+            "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
32
+            "requires": {
33
+                "regenerator-runtime": "^0.13.4"
34
+            }
35
+        },
28 36
         "@babel/types": {
29 37
             "version": "7.16.0",
30 38
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz",
@@ -242,6 +250,16 @@
242 250
             "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
243 251
             "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
244 252
         },
253
+        "@tootallnate/once": {
254
+            "version": "1.1.2",
255
+            "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
256
+            "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
257
+        },
258
+        "@tsconfig/node12": {
259
+            "version": "1.0.9",
260
+            "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
261
+            "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw=="
262
+        },
245 263
         "@types/istanbul-lib-coverage": {
246 264
             "version": "2.0.3",
247 265
             "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -457,6 +475,27 @@
457 475
             "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
458 476
             "dev": true
459 477
         },
478
+        "acorn-walk": {
479
+            "version": "8.2.0",
480
+            "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
481
+            "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
482
+        },
483
+        "agent-base": {
484
+            "version": "6.0.2",
485
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
486
+            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
487
+            "requires": {
488
+                "debug": "4"
489
+            }
490
+        },
491
+        "agentkeepalive": {
492
+            "version": "3.5.2",
493
+            "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz",
494
+            "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
495
+            "requires": {
496
+                "humanize-ms": "^1.2.1"
497
+            }
498
+        },
460 499
         "ajv": {
461 500
             "version": "6.12.6",
462 501
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -508,12 +547,25 @@
508 547
             "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==",
509 548
             "dev": true
510 549
         },
550
+        "ast-types": {
551
+            "version": "0.13.4",
552
+            "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
553
+            "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
554
+            "requires": {
555
+                "tslib": "^2.0.1"
556
+            }
557
+        },
511 558
         "async-validator": {
512 559
             "version": "4.0.7",
513 560
             "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz",
514 561
             "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==",
515 562
             "dev": true
516 563
         },
564
+        "asynckit": {
565
+            "version": "0.4.0",
566
+            "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
567
+            "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
568
+        },
517 569
         "autoprefixer": {
518 570
             "version": "10.2.5",
519 571
             "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.2.5.tgz",
@@ -543,6 +595,11 @@
543 595
             "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
544 596
             "dev": true
545 597
         },
598
+        "base64-js": {
599
+            "version": "1.5.1",
600
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
601
+            "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
602
+        },
546 603
         "big.js": {
547 604
             "version": "5.2.2",
548 605
             "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -622,11 +679,19 @@
622 679
                 "picocolors": "^1.0.0"
623 680
             }
624 681
         },
682
+        "buffer": {
683
+            "version": "6.0.3",
684
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
685
+            "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
686
+            "requires": {
687
+                "base64-js": "^1.3.1",
688
+                "ieee754": "^1.2.1"
689
+            }
690
+        },
625 691
         "bytes": {
626 692
             "version": "3.1.1",
627 693
             "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz",
628
-            "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==",
629
-            "dev": true
694
+            "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg=="
630 695
         },
631 696
         "call-bind": {
632 697
             "version": "1.0.2",
@@ -650,6 +715,16 @@
650 715
             "integrity": "sha512-YhF/hG6nqBEllymSIjLtR2iWDDnChvhnVJqp+vloyt2tEHFG1yBR+ac2B/rOw0qOK0m0lEXU2dv4E/sMk5P9Kg==",
651 716
             "dev": true
652 717
         },
718
+        "cbor-js": {
719
+            "version": "0.1.0",
720
+            "resolved": "https://registry.npmjs.org/cbor-js/-/cbor-js-0.1.0.tgz",
721
+            "integrity": "sha1-yAzmEg84fo+qdDcN/aIdlluPx/k="
722
+        },
723
+        "cbor-sync": {
724
+            "version": "1.0.4",
725
+            "resolved": "https://registry.npmjs.org/cbor-sync/-/cbor-sync-1.0.4.tgz",
726
+            "integrity": "sha512-GWlXN4wiz0vdWWXBU71Dvc1q3aBo0HytqwAZnXF1wOwjqNnDWA1vZ1gDMFLlqohak31VQzmhiYfiCX5QSSfagA=="
727
+        },
653 728
         "chalk": {
654 729
             "version": "2.4.2",
655 730
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -702,6 +777,19 @@
702 777
             "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
703 778
             "dev": true
704 779
         },
780
+        "combined-stream": {
781
+            "version": "1.0.8",
782
+            "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
783
+            "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
784
+            "requires": {
785
+                "delayed-stream": "~1.0.0"
786
+            }
787
+        },
788
+        "component-emitter": {
789
+            "version": "1.3.0",
790
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
791
+            "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
792
+        },
705 793
         "concat-map": {
706 794
             "version": "0.0.1",
707 795
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -733,6 +821,16 @@
733 821
             "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
734 822
             "dev": true
735 823
         },
824
+        "cookiejar": {
825
+            "version": "2.1.3",
826
+            "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz",
827
+            "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ=="
828
+        },
829
+        "core-util-is": {
830
+            "version": "1.0.3",
831
+            "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
832
+            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
833
+        },
736 834
         "cross-spawn": {
737 835
             "version": "7.0.3",
738 836
             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -864,6 +962,11 @@
864 962
             "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz",
865 963
             "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A=="
866 964
         },
965
+        "data-uri-to-buffer": {
966
+            "version": "3.0.1",
967
+            "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
968
+            "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og=="
969
+        },
867 970
         "date-fns": {
868 971
             "version": "2.26.0",
869 972
             "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.26.0.tgz",
@@ -880,7 +983,6 @@
880 983
             "version": "4.3.2",
881 984
             "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
882 985
             "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
883
-            "dev": true,
884 986
             "requires": {
885 987
                 "ms": "2.1.2"
886 988
             }
@@ -888,14 +990,28 @@
888 990
         "deep-is": {
889 991
             "version": "0.1.4",
890 992
             "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
891
-            "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
892
-            "dev": true
993
+            "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
994
+        },
995
+        "degenerator": {
996
+            "version": "3.0.2",
997
+            "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz",
998
+            "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==",
999
+            "requires": {
1000
+                "ast-types": "^0.13.2",
1001
+                "escodegen": "^1.8.1",
1002
+                "esprima": "^4.0.0",
1003
+                "vm2": "^3.9.8"
1004
+            }
1005
+        },
1006
+        "delayed-stream": {
1007
+            "version": "1.0.0",
1008
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1009
+            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
893 1010
         },
894 1011
         "depd": {
895 1012
             "version": "1.1.2",
896 1013
             "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
897
-            "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
898
-            "dev": true
1014
+            "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
899 1015
         },
900 1016
         "diff-sequences": {
901 1017
             "version": "26.6.2",
@@ -963,6 +1079,55 @@
963 1079
             "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
964 1080
             "dev": true
965 1081
         },
1082
+        "escodegen": {
1083
+            "version": "1.14.3",
1084
+            "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
1085
+            "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
1086
+            "requires": {
1087
+                "esprima": "^4.0.1",
1088
+                "estraverse": "^4.2.0",
1089
+                "esutils": "^2.0.2",
1090
+                "optionator": "^0.8.1",
1091
+                "source-map": "~0.6.1"
1092
+            },
1093
+            "dependencies": {
1094
+                "levn": {
1095
+                    "version": "0.3.0",
1096
+                    "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
1097
+                    "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
1098
+                    "requires": {
1099
+                        "prelude-ls": "~1.1.2",
1100
+                        "type-check": "~0.3.2"
1101
+                    }
1102
+                },
1103
+                "optionator": {
1104
+                    "version": "0.8.3",
1105
+                    "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
1106
+                    "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
1107
+                    "requires": {
1108
+                        "deep-is": "~0.1.3",
1109
+                        "fast-levenshtein": "~2.0.6",
1110
+                        "levn": "~0.3.0",
1111
+                        "prelude-ls": "~1.1.2",
1112
+                        "type-check": "~0.3.2",
1113
+                        "word-wrap": "~1.2.3"
1114
+                    }
1115
+                },
1116
+                "prelude-ls": {
1117
+                    "version": "1.1.2",
1118
+                    "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
1119
+                    "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
1120
+                },
1121
+                "type-check": {
1122
+                    "version": "0.3.2",
1123
+                    "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
1124
+                    "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
1125
+                    "requires": {
1126
+                        "prelude-ls": "~1.1.2"
1127
+                    }
1128
+                }
1129
+            }
1130
+        },
966 1131
         "eslint": {
967 1132
             "version": "8.3.0",
968 1133
             "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.3.0.tgz",
@@ -1230,6 +1395,11 @@
1230 1395
                 }
1231 1396
             }
1232 1397
         },
1398
+        "esprima": {
1399
+            "version": "4.0.1",
1400
+            "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
1401
+            "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
1402
+        },
1233 1403
         "esquery": {
1234 1404
             "version": "1.4.0",
1235 1405
             "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
@@ -1267,8 +1437,7 @@
1267 1437
         "estraverse": {
1268 1438
             "version": "4.3.0",
1269 1439
             "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
1270
-            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
1271
-            "dev": true
1440
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
1272 1441
         },
1273 1442
         "estree-walker": {
1274 1443
             "version": "2.0.2",
@@ -1278,8 +1447,7 @@
1278 1447
         "esutils": {
1279 1448
             "version": "2.0.3",
1280 1449
             "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
1281
-            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
1282
-            "dev": true
1450
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
1283 1451
         },
1284 1452
         "evtd": {
1285 1453
             "version": "0.2.3",
@@ -1335,8 +1503,12 @@
1335 1503
         "fast-levenshtein": {
1336 1504
             "version": "2.0.6",
1337 1505
             "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
1338
-            "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
1339
-            "dev": true
1506
+            "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
1507
+        },
1508
+        "fast-safe-stringify": {
1509
+            "version": "2.1.1",
1510
+            "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
1511
+            "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
1340 1512
         },
1341 1513
         "fastq": {
1342 1514
             "version": "1.13.0",
@@ -1356,6 +1528,11 @@
1356 1528
                 "flat-cache": "^3.0.4"
1357 1529
             }
1358 1530
         },
1531
+        "file-uri-to-path": {
1532
+            "version": "2.0.0",
1533
+            "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz",
1534
+            "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg=="
1535
+        },
1359 1536
         "fill-range": {
1360 1537
             "version": "7.0.1",
1361 1538
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1387,12 +1564,37 @@
1387 1564
             "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==",
1388 1565
             "dev": true
1389 1566
         },
1567
+        "form-data": {
1568
+            "version": "3.0.1",
1569
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
1570
+            "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
1571
+            "requires": {
1572
+                "asynckit": "^0.4.0",
1573
+                "combined-stream": "^1.0.8",
1574
+                "mime-types": "^2.1.12"
1575
+            }
1576
+        },
1577
+        "formidable": {
1578
+            "version": "1.2.6",
1579
+            "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz",
1580
+            "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ=="
1581
+        },
1390 1582
         "fraction.js": {
1391 1583
             "version": "4.0.13",
1392 1584
             "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz",
1393 1585
             "integrity": "sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==",
1394 1586
             "dev": true
1395 1587
         },
1588
+        "fs-extra": {
1589
+            "version": "8.1.0",
1590
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
1591
+            "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
1592
+            "requires": {
1593
+                "graceful-fs": "^4.2.0",
1594
+                "jsonfile": "^4.0.0",
1595
+                "universalify": "^0.1.0"
1596
+            }
1597
+        },
1396 1598
         "fs.realpath": {
1397 1599
             "version": "1.0.0",
1398 1600
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1406,6 +1608,33 @@
1406 1608
             "dev": true,
1407 1609
             "optional": true
1408 1610
         },
1611
+        "ftp": {
1612
+            "version": "0.3.10",
1613
+            "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
1614
+            "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=",
1615
+            "requires": {
1616
+                "readable-stream": "1.1.x",
1617
+                "xregexp": "2.0.0"
1618
+            },
1619
+            "dependencies": {
1620
+                "readable-stream": {
1621
+                    "version": "1.1.14",
1622
+                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
1623
+                    "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
1624
+                    "requires": {
1625
+                        "core-util-is": "~1.0.0",
1626
+                        "inherits": "~2.0.1",
1627
+                        "isarray": "0.0.1",
1628
+                        "string_decoder": "~0.10.x"
1629
+                    }
1630
+                },
1631
+                "string_decoder": {
1632
+                    "version": "0.10.31",
1633
+                    "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
1634
+                    "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
1635
+                }
1636
+            }
1637
+        },
1409 1638
         "function-bind": {
1410 1639
             "version": "1.1.1",
1411 1640
             "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@@ -1438,6 +1667,19 @@
1438 1667
                 "has-symbols": "^1.0.1"
1439 1668
             }
1440 1669
         },
1670
+        "get-uri": {
1671
+            "version": "3.0.2",
1672
+            "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz",
1673
+            "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==",
1674
+            "requires": {
1675
+                "@tootallnate/once": "1",
1676
+                "data-uri-to-buffer": "3",
1677
+                "debug": "4",
1678
+                "file-uri-to-path": "2",
1679
+                "fs-extra": "^8.1.0",
1680
+                "ftp": "^0.3.10"
1681
+            }
1682
+        },
1441 1683
         "glob": {
1442 1684
             "version": "7.2.0",
1443 1685
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
@@ -1461,6 +1703,11 @@
1461 1703
                 "is-glob": "^4.0.3"
1462 1704
             }
1463 1705
         },
1706
+        "graceful-fs": {
1707
+            "version": "4.2.9",
1708
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
1709
+            "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
1710
+        },
1464 1711
         "has": {
1465 1712
             "version": "1.0.3",
1466 1713
             "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -1516,7 +1763,6 @@
1516 1763
             "version": "1.8.1",
1517 1764
             "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
1518 1765
             "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==",
1519
-            "dev": true,
1520 1766
             "requires": {
1521 1767
                 "depd": "~1.1.2",
1522 1768
                 "inherits": "2.0.4",
@@ -1525,11 +1771,37 @@
1525 1771
                 "toidentifier": "1.0.1"
1526 1772
             }
1527 1773
         },
1774
+        "http-proxy-agent": {
1775
+            "version": "4.0.1",
1776
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
1777
+            "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
1778
+            "requires": {
1779
+                "@tootallnate/once": "1",
1780
+                "agent-base": "6",
1781
+                "debug": "4"
1782
+            }
1783
+        },
1784
+        "https-proxy-agent": {
1785
+            "version": "5.0.0",
1786
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
1787
+            "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
1788
+            "requires": {
1789
+                "agent-base": "6",
1790
+                "debug": "4"
1791
+            }
1792
+        },
1793
+        "humanize-ms": {
1794
+            "version": "1.2.1",
1795
+            "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
1796
+            "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
1797
+            "requires": {
1798
+                "ms": "^2.0.0"
1799
+            }
1800
+        },
1528 1801
         "iconv-lite": {
1529 1802
             "version": "0.4.24",
1530 1803
             "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1531 1804
             "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1532
-            "dev": true,
1533 1805
             "requires": {
1534 1806
                 "safer-buffer": ">= 2.1.2 < 3"
1535 1807
             }
@@ -1546,6 +1818,11 @@
1546 1818
             "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
1547 1819
             "dev": true
1548 1820
         },
1821
+        "ieee754": {
1822
+            "version": "1.2.1",
1823
+            "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1824
+            "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
1825
+        },
1549 1826
         "ignore": {
1550 1827
             "version": "4.0.6",
1551 1828
             "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -1587,8 +1864,12 @@
1587 1864
         "inherits": {
1588 1865
             "version": "2.0.4",
1589 1866
             "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1590
-            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1591
-            "dev": true
1867
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1868
+        },
1869
+        "ip": {
1870
+            "version": "1.1.5",
1871
+            "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
1872
+            "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
1592 1873
         },
1593 1874
         "is-core-module": {
1594 1875
             "version": "2.3.0",
@@ -1646,6 +1927,11 @@
1646 1927
                 "has-tostringtag": "^1.0.0"
1647 1928
             }
1648 1929
         },
1930
+        "isarray": {
1931
+            "version": "0.0.1",
1932
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
1933
+            "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
1934
+        },
1649 1935
         "isexe": {
1650 1936
             "version": "2.0.0",
1651 1937
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1775,6 +2061,14 @@
1775 2061
                 "minimist": "^1.2.0"
1776 2062
             }
1777 2063
         },
2064
+        "jsonfile": {
2065
+            "version": "4.0.0",
2066
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
2067
+            "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
2068
+            "requires": {
2069
+                "graceful-fs": "^4.1.6"
2070
+            }
2071
+        },
1778 2072
         "jstransformer": {
1779 2073
             "version": "1.0.0",
1780 2074
             "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
@@ -1795,6 +2089,11 @@
1795 2089
                 "type-check": "~0.4.0"
1796 2090
             }
1797 2091
         },
2092
+        "lil-uuid": {
2093
+            "version": "0.1.1",
2094
+            "resolved": "https://registry.npmjs.org/lil-uuid/-/lil-uuid-0.1.1.tgz",
2095
+            "integrity": "sha1-+e3PI/AOQr9D8PhD2Y2LU/M0HxY="
2096
+        },
1798 2097
         "loader-utils": {
1799 2098
             "version": "1.4.0",
1800 2099
             "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
@@ -1834,7 +2133,6 @@
1834 2133
             "version": "5.1.1",
1835 2134
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
1836 2135
             "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
1837
-            "dev": true,
1838 2136
             "requires": {
1839 2137
                 "yallist": "^3.0.2"
1840 2138
             }
@@ -1875,6 +2173,11 @@
1875 2173
             "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
1876 2174
             "dev": true
1877 2175
         },
2176
+        "methods": {
2177
+            "version": "1.1.2",
2178
+            "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
2179
+            "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
2180
+        },
1878 2181
         "micromatch": {
1879 2182
             "version": "4.0.4",
1880 2183
             "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
@@ -1885,17 +2188,20 @@
1885 2188
                 "picomatch": "^2.2.3"
1886 2189
             }
1887 2190
         },
2191
+        "mime": {
2192
+            "version": "2.6.0",
2193
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
2194
+            "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="
2195
+        },
1888 2196
         "mime-db": {
1889 2197
             "version": "1.51.0",
1890 2198
             "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
1891
-            "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
1892
-            "dev": true
2199
+            "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g=="
1893 2200
         },
1894 2201
         "mime-types": {
1895 2202
             "version": "2.1.34",
1896 2203
             "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
1897 2204
             "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
1898
-            "dev": true,
1899 2205
             "requires": {
1900 2206
                 "mime-db": "1.51.0"
1901 2207
             }
@@ -1918,8 +2224,7 @@
1918 2224
         "ms": {
1919 2225
             "version": "2.1.2",
1920 2226
             "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1921
-            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1922
-            "dev": true
2227
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
1923 2228
         },
1924 2229
         "naive-ui": {
1925 2230
             "version": "2.20.3",
@@ -1960,6 +2265,11 @@
1960 2265
             "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
1961 2266
             "dev": true
1962 2267
         },
2268
+        "netmask": {
2269
+            "version": "2.0.2",
2270
+            "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
2271
+            "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
2272
+        },
1963 2273
         "node-releases": {
1964 2274
             "version": "2.0.1",
1965 2275
             "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
@@ -2016,6 +2326,32 @@
2016 2326
                 "word-wrap": "^1.2.3"
2017 2327
             }
2018 2328
         },
2329
+        "pac-proxy-agent": {
2330
+            "version": "5.0.0",
2331
+            "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz",
2332
+            "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==",
2333
+            "requires": {
2334
+                "@tootallnate/once": "1",
2335
+                "agent-base": "6",
2336
+                "debug": "4",
2337
+                "get-uri": "3",
2338
+                "http-proxy-agent": "^4.0.1",
2339
+                "https-proxy-agent": "5",
2340
+                "pac-resolver": "^5.0.0",
2341
+                "raw-body": "^2.2.0",
2342
+                "socks-proxy-agent": "5"
2343
+            }
2344
+        },
2345
+        "pac-resolver": {
2346
+            "version": "5.0.0",
2347
+            "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.0.tgz",
2348
+            "integrity": "sha512-H+/A6KitiHNNW+bxBKREk2MCGSxljfqRX76NjummWEYIat7ldVXRU3dhRIE3iXZ0nvGBk6smv3nntxKkzRL8NA==",
2349
+            "requires": {
2350
+                "degenerator": "^3.0.1",
2351
+                "ip": "^1.1.5",
2352
+                "netmask": "^2.0.1"
2353
+            }
2354
+        },
2019 2355
         "parent-module": {
2020 2356
             "version": "1.0.1",
2021 2357
             "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -3246,6 +3582,42 @@
3246 3582
                 "asap": "~2.0.3"
3247 3583
             }
3248 3584
         },
3585
+        "proxy-agent": {
3586
+            "version": "5.0.0",
3587
+            "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz",
3588
+            "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==",
3589
+            "requires": {
3590
+                "agent-base": "^6.0.0",
3591
+                "debug": "4",
3592
+                "http-proxy-agent": "^4.0.0",
3593
+                "https-proxy-agent": "^5.0.0",
3594
+                "lru-cache": "^5.1.1",
3595
+                "pac-proxy-agent": "^5.0.0",
3596
+                "proxy-from-env": "^1.0.0",
3597
+                "socks-proxy-agent": "^5.0.0"
3598
+            }
3599
+        },
3600
+        "proxy-from-env": {
3601
+            "version": "1.1.0",
3602
+            "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
3603
+            "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
3604
+        },
3605
+        "pubnub": {
3606
+            "version": "5.0.0",
3607
+            "resolved": "https://registry.npmjs.org/pubnub/-/pubnub-5.0.0.tgz",
3608
+            "integrity": "sha512-oia2VLlO7088nMfDKZbw4RWdbhgiO2YVOlEm26fvrfZL5/MZHwb/QPM+x3Xgyw4+lrGmdzotf3JGFsufqpjLaw==",
3609
+            "requires": {
3610
+                "@babel/runtime": "^7.10.5",
3611
+                "@tsconfig/node12": "^1.0.9",
3612
+                "agentkeepalive": "^3.5.2",
3613
+                "buffer": "^6.0.3",
3614
+                "cbor-js": "^0.1.0",
3615
+                "cbor-sync": "^1.0.4",
3616
+                "lil-uuid": "^0.1.1",
3617
+                "superagent": "^6.1.0",
3618
+                "superagent-proxy": "^3.0.0"
3619
+            }
3620
+        },
3249 3621
         "pug": {
3250 3622
             "version": "3.0.2",
3251 3623
             "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz",
@@ -3388,8 +3760,7 @@
3388 3760
         "qs": {
3389 3761
             "version": "6.9.6",
3390 3762
             "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz",
3391
-            "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==",
3392
-            "dev": true
3763
+            "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ=="
3393 3764
         },
3394 3765
         "queue-microtask": {
3395 3766
             "version": "1.2.3",
@@ -3401,7 +3772,6 @@
3401 3772
             "version": "2.4.2",
3402 3773
             "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz",
3403 3774
             "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==",
3404
-            "dev": true,
3405 3775
             "requires": {
3406 3776
                 "bytes": "3.1.1",
3407 3777
                 "http-errors": "1.8.1",
@@ -3424,6 +3794,21 @@
3424 3794
                 "pify": "^2.3.0"
3425 3795
             }
3426 3796
         },
3797
+        "readable-stream": {
3798
+            "version": "3.6.0",
3799
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
3800
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
3801
+            "requires": {
3802
+                "inherits": "^2.0.3",
3803
+                "string_decoder": "^1.1.1",
3804
+                "util-deprecate": "^1.0.1"
3805
+            }
3806
+        },
3807
+        "regenerator-runtime": {
3808
+            "version": "0.13.9",
3809
+            "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
3810
+            "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
3811
+        },
3427 3812
         "regexpp": {
3428 3813
             "version": "3.2.0",
3429 3814
             "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
@@ -3485,11 +3870,15 @@
3485 3870
                 "queue-microtask": "^1.2.2"
3486 3871
             }
3487 3872
         },
3873
+        "safe-buffer": {
3874
+            "version": "5.2.1",
3875
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
3876
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
3877
+        },
3488 3878
         "safer-buffer": {
3489 3879
             "version": "2.1.2",
3490 3880
             "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
3491
-            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
3492
-            "dev": true
3881
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
3493 3882
         },
3494 3883
         "seemly": {
3495 3884
             "version": "0.3.2",
@@ -3509,8 +3898,7 @@
3509 3898
         "setprototypeof": {
3510 3899
             "version": "1.2.0",
3511 3900
             "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
3512
-            "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
3513
-            "dev": true
3901
+            "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
3514 3902
         },
3515 3903
         "shebang-command": {
3516 3904
             "version": "2.0.0",
@@ -3527,6 +3915,30 @@
3527 3915
             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
3528 3916
             "dev": true
3529 3917
         },
3918
+        "smart-buffer": {
3919
+            "version": "4.2.0",
3920
+            "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
3921
+            "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
3922
+        },
3923
+        "socks": {
3924
+            "version": "2.6.2",
3925
+            "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
3926
+            "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
3927
+            "requires": {
3928
+                "ip": "^1.1.5",
3929
+                "smart-buffer": "^4.2.0"
3930
+            }
3931
+        },
3932
+        "socks-proxy-agent": {
3933
+            "version": "5.0.1",
3934
+            "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz",
3935
+            "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==",
3936
+            "requires": {
3937
+                "agent-base": "^6.0.2",
3938
+                "debug": "4",
3939
+                "socks": "^2.3.3"
3940
+            }
3941
+        },
3530 3942
         "source-map": {
3531 3943
             "version": "0.6.1",
3532 3944
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -3541,8 +3953,7 @@
3541 3953
         "statuses": {
3542 3954
             "version": "1.5.0",
3543 3955
             "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
3544
-            "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
3545
-            "dev": true
3956
+            "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
3546 3957
         },
3547 3958
         "string-hash": {
3548 3959
             "version": "1.1.3",
@@ -3550,6 +3961,14 @@
3550 3961
             "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=",
3551 3962
             "dev": true
3552 3963
         },
3964
+        "string_decoder": {
3965
+            "version": "1.3.0",
3966
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
3967
+            "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
3968
+            "requires": {
3969
+                "safe-buffer": "~5.2.0"
3970
+            }
3971
+        },
3553 3972
         "strip-ansi": {
3554 3973
             "version": "3.0.1",
3555 3974
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
@@ -3574,6 +3993,56 @@
3574 3993
                 "postcss": "^8.1.6"
3575 3994
             }
3576 3995
         },
3996
+        "superagent": {
3997
+            "version": "6.1.0",
3998
+            "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz",
3999
+            "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==",
4000
+            "requires": {
4001
+                "component-emitter": "^1.3.0",
4002
+                "cookiejar": "^2.1.2",
4003
+                "debug": "^4.1.1",
4004
+                "fast-safe-stringify": "^2.0.7",
4005
+                "form-data": "^3.0.0",
4006
+                "formidable": "^1.2.2",
4007
+                "methods": "^1.1.2",
4008
+                "mime": "^2.4.6",
4009
+                "qs": "^6.9.4",
4010
+                "readable-stream": "^3.6.0",
4011
+                "semver": "^7.3.2"
4012
+            },
4013
+            "dependencies": {
4014
+                "lru-cache": {
4015
+                    "version": "6.0.0",
4016
+                    "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
4017
+                    "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
4018
+                    "requires": {
4019
+                        "yallist": "^4.0.0"
4020
+                    }
4021
+                },
4022
+                "semver": {
4023
+                    "version": "7.3.5",
4024
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
4025
+                    "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
4026
+                    "requires": {
4027
+                        "lru-cache": "^6.0.0"
4028
+                    }
4029
+                },
4030
+                "yallist": {
4031
+                    "version": "4.0.0",
4032
+                    "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
4033
+                    "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
4034
+                }
4035
+            }
4036
+        },
4037
+        "superagent-proxy": {
4038
+            "version": "3.0.0",
4039
+            "resolved": "https://registry.npmjs.org/superagent-proxy/-/superagent-proxy-3.0.0.tgz",
4040
+            "integrity": "sha512-wAlRInOeDFyd9pyonrkJspdRAxdLrcsZ6aSnS+8+nu4x1aXbz6FWSTT9M6Ibze+eG60szlL7JA8wEIV7bPWuyQ==",
4041
+            "requires": {
4042
+                "debug": "^4.3.2",
4043
+                "proxy-agent": "^5.0.0"
4044
+            }
4045
+        },
3577 4046
         "supports-color": {
3578 4047
             "version": "6.1.0",
3579 4048
             "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
@@ -3612,8 +4081,7 @@
3612 4081
         "toidentifier": {
3613 4082
             "version": "1.0.1",
3614 4083
             "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
3615
-            "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
3616
-            "dev": true
4084
+            "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
3617 4085
         },
3618 4086
         "token-stream": {
3619 4087
             "version": "1.0.0",
@@ -3627,6 +4095,11 @@
3627 4095
             "integrity": "sha512-wv9lBoPaeWsOgBSX09cpDi1HcO/A3aNfY+Qhvu8JnOSvVfSTmcXMKGrg9g8oTgWA8YLVqq+wt8p+eQvAhqKqlQ==",
3628 4096
             "dev": true
3629 4097
         },
4098
+        "tslib": {
4099
+            "version": "2.3.1",
4100
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
4101
+            "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
4102
+        },
3630 4103
         "type-check": {
3631 4104
             "version": "0.4.0",
3632 4105
             "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -3658,11 +4131,15 @@
3658 4131
             "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
3659 4132
             "dev": true
3660 4133
         },
4134
+        "universalify": {
4135
+            "version": "0.1.2",
4136
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
4137
+            "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
4138
+        },
3661 4139
         "unpipe": {
3662 4140
             "version": "1.0.0",
3663 4141
             "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
3664
-            "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
3665
-            "dev": true
4142
+            "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
3666 4143
         },
3667 4144
         "uri-js": {
3668 4145
             "version": "4.4.1",
@@ -3676,8 +4153,7 @@
3676 4153
         "util-deprecate": {
3677 4154
             "version": "1.0.2",
3678 4155
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
3679
-            "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
3680
-            "dev": true
4156
+            "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
3681 4157
         },
3682 4158
         "v8-compile-cache": {
3683 4159
             "version": "2.3.0",
@@ -3744,6 +4220,22 @@
3744 4220
                 }
3745 4221
             }
3746 4222
         },
4223
+        "vm2": {
4224
+            "version": "3.9.8",
4225
+            "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.8.tgz",
4226
+            "integrity": "sha512-/1PYg/BwdKzMPo8maOZ0heT7DLI0DAFTm7YQaz/Lim9oIaFZsJs3EdtalvXuBfZwczNwsYhju75NW4d6E+4q+w==",
4227
+            "requires": {
4228
+                "acorn": "^8.7.0",
4229
+                "acorn-walk": "^8.2.0"
4230
+            },
4231
+            "dependencies": {
4232
+                "acorn": {
4233
+                    "version": "8.7.0",
4234
+                    "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
4235
+                    "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ=="
4236
+                }
4237
+            }
4238
+        },
3747 4239
         "void-elements": {
3748 4240
             "version": "3.1.0",
3749 4241
             "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
@@ -3888,8 +4380,7 @@
3888 4380
         "word-wrap": {
3889 4381
             "version": "1.2.3",
3890 4382
             "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
3891
-            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
3892
-            "dev": true
4383
+            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
3893 4384
         },
3894 4385
         "wrappy": {
3895 4386
             "version": "1.0.2",
@@ -3897,11 +4388,15 @@
3897 4388
             "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
3898 4389
             "dev": true
3899 4390
         },
4391
+        "xregexp": {
4392
+            "version": "2.0.0",
4393
+            "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
4394
+            "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM="
4395
+        },
3900 4396
         "yallist": {
3901 4397
             "version": "3.1.1",
3902 4398
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
3903
-            "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
3904
-            "dev": true
4399
+            "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
3905 4400
         }
3906 4401
     }
3907 4402
 }

+ 1
- 0
frontend/package.json Zobrazit soubor

@@ -10,6 +10,7 @@
10 10
     },
11 11
     "dependencies": {
12 12
         "joi": "^17.4.0",
13
+        "pubnub": "^5.0.0",
13 14
         "vue": "^3.0.5",
14 15
         "vue-router": "^4.0.12"
15 16
     },

+ 1
- 1
frontend/src/App.vue Zobrazit soubor

@@ -6,7 +6,7 @@ router-view
6 6
 import * as sss from '@/sss/import.css'
7 7
 
8 8
 export default {
9
-    name: 'app',
9
+    name: 'app'
10 10
 }
11 11
 </script>
12 12
 

+ 93
- 0
frontend/src/services/chat.service.js Zobrazit soubor

@@ -0,0 +1,93 @@
1
+import PubNub from 'pubnub'
2
+
3
+/** 
4
+ * Provider method holder
5
+ * We always reference this object so
6
+ * we don't have to hardcode provider specific
7
+ * methods for doing chat things.
8
+ * 
9
+ * This gets overloaded later in the program
10
+ */
11
+const providerMethods = {
12
+    publish: () => console.error('no provider publish method set'),
13
+    subscribe: () => console.error('no provider subscribe method set'),
14
+    listen: () => console.error('no provider listen method set')
15
+}
16
+
17
+/** 
18
+ * Breaking out as much pubnub specific flavor
19
+ */
20
+const setupPubnub = async uuid => {
21
+    if(!uuid) return console.error('no pubnub uuid set')
22
+    
23
+    const pubnubClient = await new PubNub({
24
+        publishKey: import.meta.env.VITE_PUBNUB_PUBLISH_KEY,
25
+        subscribeKey: import.meta.env.VITE_PUBNUB_SUBSCRIBE_KEY,
26
+        uuid
27
+    })
28
+    // Pass pubnub specific methods to our placeholder obj
29
+    providerMethods['publish'] = pubnubClient.publish
30
+    providerMethods['subscribe'] = pubnubClient.subscribe
31
+    providerMethods['listen'] = pubnubClient.addListener
32
+
33
+    return pubnubClient
34
+}
35
+
36
+
37
+class ChatMessage {
38
+    constructor({ title, description }) {
39
+        this.title = title,
40
+        this.description = description
41
+    }
42
+}
43
+
44
+const testMessage = new ChatMessage({
45
+    title: "testing",
46
+    description: "hello world!",
47
+})
48
+const MAIN_CHANNEL = 'hello_world'
49
+
50
+class Chatter {
51
+    constructor() {
52
+        this.groupings = {}
53
+        this.provider = null
54
+        this.uuid = null
55
+
56
+        // Setup the main channel
57
+        this.subscriptions = [MAIN_CHANNEL]
58
+        
59
+        this.listeners = {
60
+            status: async e => {
61
+                if (e.category !== "PNConnectedCategory") return
62
+                await this._publish(this.subscriptions[0], testMessage)
63
+            },
64
+            message: this._onMessage,
65
+            presence: this._onPresence
66
+        }
67
+    }
68
+    async _onMessage(e) {
69
+        console.log(e.message.title)
70
+        console.log(e.message.description)
71
+    }
72
+    async _onPresence(e) {
73
+        return
74
+    }
75
+    async setup(uuid) {
76
+        this.uuid = uuid
77
+        this.provider = await setupPubnub(this.uuid)
78
+
79
+        this._listenFor({ listeners: this.listeners })
80
+        this._subscribe(this.subscriptions)
81
+    }
82
+    async _publish(channel, message) {
83
+        return await providerMethods['publish']({ channel, message })
84
+    }
85
+    _subscribe(channels) {
86
+        providerMethods['subscribe']({ channels })
87
+    }
88
+    _listenFor({ listeners }) {
89
+        providerMethods['listen'](listeners)
90
+    }
91
+}
92
+
93
+export { Chatter }

+ 28
- 0
frontend/src/services/notification.service.js Zobrazit soubor

@@ -0,0 +1,28 @@
1
+import { remote } from '../utils/db'
2
+
3
+class Toaster {
4
+    constructor(profileId) {
5
+        this.url = `${remote}/notification/${profileId}/subscribe`
6
+        this.source = null
7
+        this.source = new EventSource(this.url)
8
+        this.listenFor('end', message => this.source.close)
9
+    }
10
+    listenFor(event, callback) {
11
+        this.source.addEventListener(event, callback)
12
+    }
13
+}
14
+
15
+class StonkAlert extends Toaster {
16
+    constructor(profileId) {
17
+        super(profileId)
18
+
19
+        this.stonks = {}
20
+        this.listenFor('stonk', message => {
21
+            const parsed = JSON.parse(message.data)
22
+            this.stonks[parsed.name] = parsed
23
+            console.log('updated:', this.stonks)
24
+        })
25
+    }
26
+}
27
+
28
+export { Toaster, StonkAlert }

+ 7
- 2
frontend/src/services/queue.service.js Zobrazit soubor

@@ -6,9 +6,14 @@ const fetchQueueByProfileId = async profileId => {
6 6
     const queue = await db.get(
7 7
         `/profile/${profileId}/queue?include_profile=true`,
8 8
     )
9
-    return queue.map(profileData => {
9
+    
10
+    if(!queue?.length) {
11
+        console.error('could not retrieve match queue. Please take the survey and rescore.')
12
+    }
13
+
14
+    return queue ? queue.map(profileData => {
10 15
         return new Profile({ email: null, ...profileData })
11
-    })
16
+    }) : []
12 17
 }
13 18
 
14 19
 const updateQueueByProfileId = async (profileId, targetId, reinsert) => {

+ 2
- 21
frontend/src/utils/db.js Zobrazit soubor

@@ -26,7 +26,7 @@ class Connector {
26 26
         const header = { ...headerTemplate }
27 27
         header.method = 'GET'
28 28
         try {
29
-            console.log(`${remote}${endpoint}`)
29
+            // console.log(`${remote}${endpoint}`)
30 30
             let res = await fetch(`${remote}${endpoint}`, header)
31 31
             if (!res.ok) {
32 32
                 throw Error(res.statusText)
@@ -73,23 +73,4 @@ class Connector {
73 73
 }
74 74
 const db = new Connector()
75 75
 
76
-class Toaster {
77
-    constructor({ profileId }) {
78
-        this.url = `${remote}/notification/${profileId}/subscribe`
79
-        
80
-    }
81
-    connect() {
82
-        this.source = new EventSource(`${remote}/notification/${profileId}/subscribe`)
83
-        this.source.onmessage = e => {
84
-            console.log("Data", + e.data)
85
-        }
86
-        this.source.onerror = e => {
87
-            console.error("EventSource failed.", e)
88
-        }
89
-        this.source.addEventListener('end', e => {
90
-            this.close()
91
-        })
92
-    }
93
-}
94
-
95
-export { Connector, db, Toaster }
76
+export { Connector, db, remote }

+ 11
- 11
frontend/src/views/home.vue Zobrazit soubor

@@ -12,7 +12,8 @@ import sidebar from '../components/Sidebar.vue'
12 12
 import mainNav from '../components/MainNav.vue'
13 13
 import profileCardList from '../components/ProfileCardList.vue'
14 14
 import { fetchQueueByProfileId } from '../services'
15
-import { Toaster } from '../utils/db'
15
+import { StonkAlert } from '../services/notification.service'
16
+import { Chatter } from '../services/chat.service'
16 17
 
17 18
 import batch_10 from '../../../backend/db/generated/_batch_10.js.ref'
18 19
 import batch_20 from '../../../backend/db/generated/_batch_20.js.ref'
@@ -27,6 +28,7 @@ export default {
27 28
         mypid: null,
28 29
     }),
29 30
     mounted() {
31
+        this.setupChatter()
30 32
         this.setupToaster()
31 33
     },
32 34
     async created() {
@@ -42,16 +44,14 @@ export default {
42 44
     },
43 45
     methods: {
44 46
         setupToaster() {
45
-            const stocks = {}
46
-            const source = new EventSource(`http://localhost:3001/api/notification/${this.mypid}/subscribe`)
47
-            source.addEventListener('stonk', function (message) {
48
-                console.log('updated:', message)
49
-                const data = JSON.parse(message.data)
50
-                stocks[data.name] = data
51
-            })
52
-            source.addEventListener('end', function (message) {
53
-                this.close()
54
-            })
47
+            const t = new StonkAlert(this.mypid)
48
+        },
49
+        setupChatter() {
50
+            const c = new Chatter()
51
+            const testAccountUUID = import.meta.env.VITE_TEST_ACCOUNT_UUID
52
+            c.setup(testAccountUUID)
53
+            console.log('---')
54
+            console.log(c)
55 55
         },
56 56
         processQueue(queueList) {
57 57
             const formattedList = []

Načítá se…
Zrušit
Uložit