From da4b3e7b3c90914db142efd429757582522c8132 Mon Sep 17 00:00:00 2001 From: Youngjae Heo Date: Wed, 5 Apr 2023 20:15:37 -0400 Subject: [PATCH] merge from dev --- .github/workflows/prettier.yml | 10 + .gitignore | 1 + 3dworld/.dockerignore | 3 + 3dworld/.editorconfig | 16 + 3dworld/.gitignore | 45 + 3dworld/.vscode/extensions.json | 4 + 3dworld/.vscode/launch.json | 20 + 3dworld/.vscode/tasks.json | 42 + 3dworld/Dockerfile | 8 + 3dworld/README.md | 27 + 3dworld/angular.json | 98 + 3dworld/package-lock.json | 12288 ++++++++++++++++ 3dworld/package.json | 47 + 3dworld/src/app/app-routing.module.ts | 50 + 3dworld/src/app/app.component.html | 2 + 3dworld/src/app/app.component.scss | 0 3dworld/src/app/app.component.spec.ts | 33 + 3dworld/src/app/app.component.ts | 10 + 3dworld/src/app/app.module.ts | 71 + .../chunk-form/chunk-form.component.html | 11 + .../chunk-form/chunk-form.component.scss | 0 .../chunk-form/chunk-form.component.spec.ts | 22 + .../chunk-form/chunk-form.component.ts | 37 + .../comment-div/comment-div.component.html | 12 + .../comment-div/comment-div.component.scss | 4 + .../comment-div/comment-div.component.spec.ts | 22 + .../comment-div/comment-div.component.ts | 20 + .../comment-view/comment-view.component.html | 8 + .../comment-view/comment-view.component.scss | 13 + .../comment-view.component.spec.ts | 22 + .../comment-view/comment-view.component.ts | 26 + .../commentform/commentform.component.html | 33 + .../commentform/commentform.component.scss | 0 .../commentform/commentform.component.spec.ts | 22 + .../commentform/commentform.component.ts | 45 + .../component/header/header.component.html | 27 + .../component/header/header.component.scss | 91 + .../component/header/header.component.spec.ts | 22 + .../app/component/header/header.component.ts | 59 + .../notificationdiv.component.html | 7 + .../notificationdiv.component.scss | 8 + .../notificationdiv.component.spec.ts | 22 + .../notificationdiv.component.ts | 11 + .../upload-form/upload-form.component.html | 21 + .../upload-form/upload-form.component.scss | 4 + .../upload-form/upload-form.component.spec.ts | 22 + .../upload-form/upload-form.component.ts | 36 + .../app/component/vote/vote.component.html | 6 + .../app/component/vote/vote.component.scss | 13 + .../src/app/component/vote/vote.component.ts | 23 + .../world-object/world-object.component.html | 62 + .../world-object/world-object.component.scss | 48 + .../world-object.component.spec.ts | 22 + .../world-object/world-object.component.ts | 426 + .../worlddiv/worlddiv.component.html | 14 + .../worlddiv/worlddiv.component.scss | 12 + .../worlddiv/worlddiv.component.spec.ts | 22 + .../component/worlddiv/worlddiv.component.ts | 18 + 3dworld/src/app/guards/auth0.guard.spec.ts | 16 + 3dworld/src/app/guards/auth0.guard.ts | 43 + 3dworld/src/app/guards/session.guard.spec.ts | 16 + 3dworld/src/app/guards/session.guard.ts | 38 + .../app/pages/credits/credits.component.html | 37 + .../app/pages/credits/credits.component.scss | 0 .../pages/credits/credits.component.spec.ts | 22 + .../app/pages/credits/credits.component.ts | 8 + .../src/app/pages/index/index.component.html | 13 + .../src/app/pages/index/index.component.scss | 16 + .../app/pages/index/index.component.spec.ts | 22 + .../src/app/pages/index/index.component.ts | 63 + .../app/pages/profile/profile.component.html | 77 + .../app/pages/profile/profile.component.scss | 24 + .../pages/profile/profile.component.spec.ts | 22 + .../app/pages/profile/profile.component.ts | 74 + .../app/pages/sign-in/sign-in.component.html | 1 + .../app/pages/sign-in/sign-in.component.scss | 0 .../pages/sign-in/sign-in.component.spec.ts | 22 + .../app/pages/sign-in/sign-in.component.ts | 37 + .../app/pages/sign-up/sign-up.component.html | 19 + .../app/pages/sign-up/sign-up.component.scss | 0 .../pages/sign-up/sign-up.component.spec.ts | 22 + .../app/pages/sign-up/sign-up.component.ts | 44 + .../world-view/world-view.component.html | 1 + .../world-view/world-view.component.scss | 0 .../world-view/world-view.component.spec.ts | 22 + .../pages/world-view/world-view.component.ts | 18 + .../app/pages/worlds/worlds.component.html | 8 + .../app/pages/worlds/worlds.component.scss | 14 + .../app/pages/worlds/worlds.component.spec.ts | 22 + .../src/app/pages/worlds/worlds.component.ts | 18 + 3dworld/src/app/services/api.service.spec.ts | 16 + 3dworld/src/app/services/api.service.ts | 202 + .../app/services/liveworld.service.spec.ts | 16 + 3dworld/src/app/services/liveworld.service.ts | 142 + .../app/services/notification.service.spec.ts | 16 + .../src/app/services/notification.service.ts | 17 + 3dworld/src/assets/.gitkeep | 0 3dworld/src/assets/demo.png | Bin 0 -> 163412 bytes 3dworld/src/assets/down-arrow.png | Bin 0 -> 838 bytes 3dworld/src/assets/up-arrow.png | Bin 0 -> 845 bytes .../environments/environment.development.ts | 11 + 3dworld/src/environments/environment.ts | 11 + 3dworld/src/favicon.ico | Bin 0 -> 948 bytes 3dworld/src/index.html | 13 + 3dworld/src/main.ts | 7 + 3dworld/src/styles.scss | 170 + 3dworld/src/three.js | 32 + 3dworld/tsconfig.app.json | 11 + 3dworld/tsconfig.json | 31 + 3dworld/tsconfig.spec.json | 9 + README.md | 54 + backend/.dockerignore | 1 + backend/.env.bak | 7 + backend/.gitignore | 9 + backend/Dockerfile | 13 + backend/adminInit.js | 25 + backend/app.js | 137 + backend/config.js | 14 + backend/datasource.js | 46 + backend/middleware/auth.js | 21 + backend/models/comments.js | 31 + backend/models/gridfiles.js | 4 + backend/models/notifications.js | 45 + backend/models/users.js | 48 + backend/models/worlds.js | 44 + backend/package-lock.json | 3558 +++++ backend/package.json | 41 + backend/routers/comments_router.js | 152 + backend/routers/notifications_router.js | 28 + backend/routers/users_router.js | 165 + backend/routers/utils.js | 60 + backend/routers/worlds_router.js | 365 + backend/socketio/notifications.js | 81 + config/proxy.conf | 5 + docker-compose.yml.bak | 75 + 135 files changed, 20540 insertions(+) create mode 100644 .github/workflows/prettier.yml create mode 100644 .gitignore create mode 100644 3dworld/.dockerignore create mode 100644 3dworld/.editorconfig create mode 100644 3dworld/.gitignore create mode 100644 3dworld/.vscode/extensions.json create mode 100644 3dworld/.vscode/launch.json create mode 100644 3dworld/.vscode/tasks.json create mode 100644 3dworld/Dockerfile create mode 100644 3dworld/README.md create mode 100644 3dworld/angular.json create mode 100644 3dworld/package-lock.json create mode 100644 3dworld/package.json create mode 100644 3dworld/src/app/app-routing.module.ts create mode 100644 3dworld/src/app/app.component.html create mode 100644 3dworld/src/app/app.component.scss create mode 100644 3dworld/src/app/app.component.spec.ts create mode 100644 3dworld/src/app/app.component.ts create mode 100644 3dworld/src/app/app.module.ts create mode 100644 3dworld/src/app/component/chunk-form/chunk-form.component.html create mode 100644 3dworld/src/app/component/chunk-form/chunk-form.component.scss create mode 100644 3dworld/src/app/component/chunk-form/chunk-form.component.spec.ts create mode 100644 3dworld/src/app/component/chunk-form/chunk-form.component.ts create mode 100644 3dworld/src/app/component/comment-view/comment-div/comment-div.component.html create mode 100644 3dworld/src/app/component/comment-view/comment-div/comment-div.component.scss create mode 100644 3dworld/src/app/component/comment-view/comment-div/comment-div.component.spec.ts create mode 100644 3dworld/src/app/component/comment-view/comment-div/comment-div.component.ts create mode 100644 3dworld/src/app/component/comment-view/comment-view.component.html create mode 100644 3dworld/src/app/component/comment-view/comment-view.component.scss create mode 100644 3dworld/src/app/component/comment-view/comment-view.component.spec.ts create mode 100644 3dworld/src/app/component/comment-view/comment-view.component.ts create mode 100644 3dworld/src/app/component/commentform/commentform.component.html create mode 100644 3dworld/src/app/component/commentform/commentform.component.scss create mode 100644 3dworld/src/app/component/commentform/commentform.component.spec.ts create mode 100644 3dworld/src/app/component/commentform/commentform.component.ts create mode 100644 3dworld/src/app/component/header/header.component.html create mode 100644 3dworld/src/app/component/header/header.component.scss create mode 100644 3dworld/src/app/component/header/header.component.spec.ts create mode 100644 3dworld/src/app/component/header/header.component.ts create mode 100644 3dworld/src/app/component/notificationdiv/notificationdiv.component.html create mode 100644 3dworld/src/app/component/notificationdiv/notificationdiv.component.scss create mode 100644 3dworld/src/app/component/notificationdiv/notificationdiv.component.spec.ts create mode 100644 3dworld/src/app/component/notificationdiv/notificationdiv.component.ts create mode 100644 3dworld/src/app/component/upload-form/upload-form.component.html create mode 100644 3dworld/src/app/component/upload-form/upload-form.component.scss create mode 100644 3dworld/src/app/component/upload-form/upload-form.component.spec.ts create mode 100644 3dworld/src/app/component/upload-form/upload-form.component.ts create mode 100644 3dworld/src/app/component/vote/vote.component.html create mode 100644 3dworld/src/app/component/vote/vote.component.scss create mode 100644 3dworld/src/app/component/vote/vote.component.ts create mode 100644 3dworld/src/app/component/world-object/world-object.component.html create mode 100644 3dworld/src/app/component/world-object/world-object.component.scss create mode 100644 3dworld/src/app/component/world-object/world-object.component.spec.ts create mode 100644 3dworld/src/app/component/world-object/world-object.component.ts create mode 100644 3dworld/src/app/component/worlddiv/worlddiv.component.html create mode 100644 3dworld/src/app/component/worlddiv/worlddiv.component.scss create mode 100644 3dworld/src/app/component/worlddiv/worlddiv.component.spec.ts create mode 100644 3dworld/src/app/component/worlddiv/worlddiv.component.ts create mode 100644 3dworld/src/app/guards/auth0.guard.spec.ts create mode 100644 3dworld/src/app/guards/auth0.guard.ts create mode 100644 3dworld/src/app/guards/session.guard.spec.ts create mode 100644 3dworld/src/app/guards/session.guard.ts create mode 100644 3dworld/src/app/pages/credits/credits.component.html create mode 100644 3dworld/src/app/pages/credits/credits.component.scss create mode 100644 3dworld/src/app/pages/credits/credits.component.spec.ts create mode 100644 3dworld/src/app/pages/credits/credits.component.ts create mode 100644 3dworld/src/app/pages/index/index.component.html create mode 100644 3dworld/src/app/pages/index/index.component.scss create mode 100644 3dworld/src/app/pages/index/index.component.spec.ts create mode 100644 3dworld/src/app/pages/index/index.component.ts create mode 100644 3dworld/src/app/pages/profile/profile.component.html create mode 100644 3dworld/src/app/pages/profile/profile.component.scss create mode 100644 3dworld/src/app/pages/profile/profile.component.spec.ts create mode 100644 3dworld/src/app/pages/profile/profile.component.ts create mode 100644 3dworld/src/app/pages/sign-in/sign-in.component.html create mode 100644 3dworld/src/app/pages/sign-in/sign-in.component.scss create mode 100644 3dworld/src/app/pages/sign-in/sign-in.component.spec.ts create mode 100644 3dworld/src/app/pages/sign-in/sign-in.component.ts create mode 100644 3dworld/src/app/pages/sign-up/sign-up.component.html create mode 100644 3dworld/src/app/pages/sign-up/sign-up.component.scss create mode 100644 3dworld/src/app/pages/sign-up/sign-up.component.spec.ts create mode 100644 3dworld/src/app/pages/sign-up/sign-up.component.ts create mode 100644 3dworld/src/app/pages/world-view/world-view.component.html create mode 100644 3dworld/src/app/pages/world-view/world-view.component.scss create mode 100644 3dworld/src/app/pages/world-view/world-view.component.spec.ts create mode 100644 3dworld/src/app/pages/world-view/world-view.component.ts create mode 100644 3dworld/src/app/pages/worlds/worlds.component.html create mode 100644 3dworld/src/app/pages/worlds/worlds.component.scss create mode 100644 3dworld/src/app/pages/worlds/worlds.component.spec.ts create mode 100644 3dworld/src/app/pages/worlds/worlds.component.ts create mode 100644 3dworld/src/app/services/api.service.spec.ts create mode 100644 3dworld/src/app/services/api.service.ts create mode 100644 3dworld/src/app/services/liveworld.service.spec.ts create mode 100644 3dworld/src/app/services/liveworld.service.ts create mode 100644 3dworld/src/app/services/notification.service.spec.ts create mode 100644 3dworld/src/app/services/notification.service.ts create mode 100644 3dworld/src/assets/.gitkeep create mode 100644 3dworld/src/assets/demo.png create mode 100644 3dworld/src/assets/down-arrow.png create mode 100644 3dworld/src/assets/up-arrow.png create mode 100644 3dworld/src/environments/environment.development.ts create mode 100644 3dworld/src/environments/environment.ts create mode 100644 3dworld/src/favicon.ico create mode 100644 3dworld/src/index.html create mode 100644 3dworld/src/main.ts create mode 100644 3dworld/src/styles.scss create mode 100644 3dworld/src/three.js create mode 100644 3dworld/tsconfig.app.json create mode 100644 3dworld/tsconfig.json create mode 100644 3dworld/tsconfig.spec.json create mode 100644 README.md create mode 100644 backend/.dockerignore create mode 100644 backend/.env.bak create mode 100644 backend/.gitignore create mode 100644 backend/Dockerfile create mode 100644 backend/adminInit.js create mode 100644 backend/app.js create mode 100644 backend/config.js create mode 100644 backend/datasource.js create mode 100644 backend/middleware/auth.js create mode 100644 backend/models/comments.js create mode 100644 backend/models/gridfiles.js create mode 100644 backend/models/notifications.js create mode 100644 backend/models/users.js create mode 100644 backend/models/worlds.js create mode 100644 backend/package-lock.json create mode 100644 backend/package.json create mode 100644 backend/routers/comments_router.js create mode 100644 backend/routers/notifications_router.js create mode 100644 backend/routers/users_router.js create mode 100644 backend/routers/utils.js create mode 100644 backend/routers/worlds_router.js create mode 100644 backend/socketio/notifications.js create mode 100644 config/proxy.conf create mode 100644 docker-compose.yml.bak diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml new file mode 100644 index 00000000..e63d8090 --- /dev/null +++ b/.github/workflows/prettier.yml @@ -0,0 +1,10 @@ +name: Run Prettier +on: [push] +jobs: + lint: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Run Prettier + run: npm install prettier && npx prettier --check . diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..412c2574 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +docker-compose.yml \ No newline at end of file diff --git a/3dworld/.dockerignore b/3dworld/.dockerignore new file mode 100644 index 00000000..11a60a6c --- /dev/null +++ b/3dworld/.dockerignore @@ -0,0 +1,3 @@ +**/node_modules +**/.angular +**/.dist \ No newline at end of file diff --git a/3dworld/.editorconfig b/3dworld/.editorconfig new file mode 100644 index 00000000..59d9a3a3 --- /dev/null +++ b/3dworld/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/3dworld/.gitignore b/3dworld/.gitignore new file mode 100644 index 00000000..1ea95b8a --- /dev/null +++ b/3dworld/.gitignore @@ -0,0 +1,45 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db + +# env's +src/environments/ \ No newline at end of file diff --git a/3dworld/.vscode/extensions.json b/3dworld/.vscode/extensions.json new file mode 100644 index 00000000..77b37457 --- /dev/null +++ b/3dworld/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/3dworld/.vscode/launch.json b/3dworld/.vscode/launch.json new file mode 100644 index 00000000..740e35a0 --- /dev/null +++ b/3dworld/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "pwa-chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/3dworld/.vscode/tasks.json b/3dworld/.vscode/tasks.json new file mode 100644 index 00000000..a298b5bd --- /dev/null +++ b/3dworld/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/3dworld/Dockerfile b/3dworld/Dockerfile new file mode 100644 index 00000000..b98a11ad --- /dev/null +++ b/3dworld/Dockerfile @@ -0,0 +1,8 @@ +FROM node:latest as build +WORKDIR /usr/local/app +COPY ./ /usr/local/app +RUN npm install +RUN npm run build +FROM nginx:latest +COPY --from=build /usr/local/app/dist/3dworld /usr/share/nginx/html +EXPOSE 80 \ No newline at end of file diff --git a/3dworld/README.md b/3dworld/README.md new file mode 100644 index 00000000..204094c9 --- /dev/null +++ b/3dworld/README.md @@ -0,0 +1,27 @@ +# 3dworld + +This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.2.0. + +## Development server + +Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. + +## Code scaffolding + +Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. + +## Build + +Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. + +## Running unit tests + +Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). + +## Running end-to-end tests + +Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. + +## Further help + +To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. diff --git a/3dworld/angular.json b/3dworld/angular.json new file mode 100644 index 00000000..c8e395f7 --- /dev/null +++ b/3dworld/angular.json @@ -0,0 +1,98 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "3dworld": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/3dworld", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.development.ts" + } + ] + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "browserTarget": "3dworld:build:production" + }, + "development": { + "browserTarget": "3dworld:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "3dworld:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "inlineStyleLanguage": "scss", + "assets": ["src/favicon.ico", "src/assets"], + "styles": ["src/styles.scss"], + "scripts": [] + } + } + } + } + }, + "cli": { + "analytics": "3740b000-9bfe-4013-b744-ceb2d600918f" + } +} diff --git a/3dworld/package-lock.json b/3dworld/package-lock.json new file mode 100644 index 00000000..e0d0ffb2 --- /dev/null +++ b/3dworld/package-lock.json @@ -0,0 +1,12288 @@ +{ + "name": "3dworld", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "3dworld", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^15.2.0", + "@angular/common": "^15.2.0", + "@angular/compiler": "^15.2.0", + "@angular/core": "^15.2.0", + "@angular/forms": "^15.2.0", + "@angular/platform-browser": "^15.2.0", + "@angular/platform-browser-dynamic": "^15.2.0", + "@angular/router": "^15.2.0", + "@auth0/auth0-angular": "^2.0.1", + "jszip": "^3.10.1", + "ng-process-env": "^15.0.1", + "ngx-socket-io": "^4.4.0", + "npo-api-interceptor": "^1.9.0", + "rxjs": "~7.8.0", + "sharedb": "^3.3.0", + "three": "^0.150.1", + "tslib": "^2.3.0", + "zone.js": "~0.12.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^15.2.0", + "@angular/cli": "~15.2.0", + "@angular/compiler-cli": "^15.2.0", + "@types/jasmine": "~4.3.0", + "@types/node": "^18.15.6", + "@types/three": "^0.149.0", + "jasmine-core": "~4.5.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.0.0", + "typescript": "~4.9.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1502.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "15.2.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/rxjs": { + "version": "6.6.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/@angular-devkit/build-angular": { + "version": "15.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.2.0", + "@angular-devkit/architect": "0.1502.1", + "@angular-devkit/build-webpack": "0.1502.1", + "@angular-devkit/core": "15.2.1", + "@babel/core": "7.20.12", + "@babel/generator": "7.20.14", + "@babel/helper-annotate-as-pure": "7.18.6", + "@babel/helper-split-export-declaration": "7.18.6", + "@babel/plugin-proposal-async-generator-functions": "7.20.7", + "@babel/plugin-transform-async-to-generator": "7.20.7", + "@babel/plugin-transform-runtime": "7.19.6", + "@babel/preset-env": "7.20.2", + "@babel/runtime": "7.20.13", + "@babel/template": "7.20.7", + "@discoveryjs/json-ext": "0.5.7", + "@ngtools/webpack": "15.2.1", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.13", + "babel-loader": "9.1.2", + "babel-plugin-istanbul": "6.1.1", + "browserslist": "4.21.5", + "cacache": "17.0.4", + "chokidar": "3.5.3", + "copy-webpack-plugin": "11.0.0", + "critters": "0.0.16", + "css-loader": "6.7.3", + "esbuild-wasm": "0.17.8", + "glob": "8.1.0", + "https-proxy-agent": "5.0.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "karma-source-map-support": "1.4.0", + "less": "4.1.3", + "less-loader": "11.1.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.2.1", + "magic-string": "0.29.0", + "mini-css-extract-plugin": "2.7.2", + "open": "8.4.1", + "ora": "5.4.1", + "parse5-html-rewriting-stream": "7.0.0", + "piscina": "3.2.0", + "postcss": "8.4.21", + "postcss-loader": "7.0.2", + "resolve-url-loader": "5.0.0", + "rxjs": "6.6.7", + "sass": "1.58.1", + "sass-loader": "13.2.0", + "semver": "7.3.8", + "source-map-loader": "4.0.1", + "source-map-support": "0.5.21", + "terser": "5.16.3", + "text-table": "0.2.0", + "tree-kill": "1.2.2", + "tslib": "2.5.0", + "webpack": "5.75.0", + "webpack-dev-middleware": "6.0.1", + "webpack-dev-server": "4.11.1", + "webpack-merge": "5.8.0", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.17.8" + }, + "peerDependencies": { + "@angular/compiler-cli": "^15.0.0", + "@angular/localize": "^15.0.0", + "@angular/platform-server": "^15.0.0", + "@angular/service-worker": "^15.0.0", + "karma": "^6.3.0", + "ng-packagr": "^15.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=4.8.2 <5.0" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { + "version": "6.6.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1502.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1502.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^4.0.0" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { + "version": "6.6.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/@angular-devkit/core": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "rxjs": "6.6.7", + "source-map": "0.7.4" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "6.6.7", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/core/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@angular-devkit/schematics": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "15.2.1", + "jsonc-parser": "3.2.0", + "magic-string": "0.29.0", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "6.6.7", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/@angular/animations": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "15.2.1" + } + }, + "node_modules/@angular/cli": { + "version": "15.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1502.1", + "@angular-devkit/core": "15.2.1", + "@angular-devkit/schematics": "15.2.1", + "@schematics/angular": "15.2.1", + "@yarnpkg/lockfile": "1.1.0", + "ansi-colors": "4.1.3", + "ini": "3.0.1", + "inquirer": "8.2.4", + "jsonc-parser": "3.2.0", + "npm-package-arg": "10.1.0", + "npm-pick-manifest": "8.0.1", + "open": "8.4.1", + "ora": "5.4.1", + "pacote": "15.1.0", + "resolve": "1.22.1", + "semver": "7.3.8", + "symbol-observable": "4.0.0", + "yargs": "17.6.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "15.2.1", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/core": "15.2.1" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + } + } + }, + "node_modules/@angular/compiler-cli": { + "version": "15.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.19.3", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^3.0.0", + "convert-source-map": "^1.5.1", + "dependency-graph": "^0.11.0", + "magic-string": "^0.27.0", + "reflect-metadata": "^0.1.2", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/main-ngcc.js" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/compiler": "15.2.1", + "typescript": ">=4.8.2 <5.0" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.19.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", + "@babel/helper-module-transforms": "^7.19.0", + "@babel/helpers": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/compiler-cli/node_modules/magic-string": { + "version": "0.27.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@angular/core": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.11.4 || ~0.12.0 || ~0.13.0" + } + }, + "node_modules/@angular/forms": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "15.2.1", + "@angular/core": "15.2.1", + "@angular/platform-browser": "15.2.1", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/animations": "15.2.1", + "@angular/common": "15.2.1", + "@angular/core": "15.2.1" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "15.2.1", + "@angular/compiler": "15.2.1", + "@angular/core": "15.2.1", + "@angular/platform-browser": "15.2.1" + } + }, + "node_modules/@angular/router": { + "version": "15.2.1", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": "15.2.1", + "@angular/core": "15.2.1", + "@angular/platform-browser": "15.2.1", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@assemblyscript/loader": { + "version": "0.10.1", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@auth0/auth0-angular": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@auth0/auth0-spa-js": "^2.0.1", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@angular/common": ">=13", + "@angular/core": ">=13", + "@angular/router": ">=13" + } + }, + "node_modules/@auth0/auth0-spa-js": { + "version": "2.0.4", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.14", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.20.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.20.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.20.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.19.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/runtime": { + "version": "7.20.13", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.1", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.2", + "@babel/types": "^7.21.2", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.21.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.8", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@ngtools/webpack": { + "version": "15.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^15.0.0", + "typescript": ">=4.8.2 <5.0", + "webpack": "^5.54.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "4.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^6.0.0", + "lru-cache": "^7.4.4", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^8.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/@npmcli/git/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/move-file/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^6.0.0", + "node-gyp": "^9.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@schematics/angular": { + "version": "15.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "15.2.1", + "@angular-devkit/schematics": "15.2.1", + "jsonc-parser": "3.2.0" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "license": "MIT" + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.17.0.tgz", + "integrity": "sha512-RMSSvSfs9kb0VzkvQ2NWobwnj7TxCA9vI/IjR9bDHqgAyVbu2T0DN4wiKVqomyDWqO7dPr/tErSfq7urQ1Q37g==", + "dependencies": { + "fast-glob": "^3.2.11", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tufjs/models": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^6.1.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "6.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.13", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.21.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.51", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/http-proxy": { + "version": "1.17.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "4.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "18.15.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.6.tgz", + "integrity": "sha512-YErOafCZpK4g+Rp3Q/PBgZNAsWKGunQTm9FA3/Pbcm0VCriTEzcrutQ/SxSc0rytAp0NoFWue669jmKhEtd0sA==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/three": { + "version": "0.149.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.149.0.tgz", + "integrity": "sha512-fgNBm9LWc65ER/W0cvoXdC0iMy7Ke9e2CONmEr6Jt8sDSY3sw4DgOubZfmdZ747dkPhbQrgRQAWwDEr2S/7IEg==", + "dev": true, + "dependencies": { + "@types/webxr": "*" + } + }, + "node_modules/@types/webxr": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.1.tgz", + "integrity": "sha512-xlFXPfgJR5vIuDefhaHuUM9uUgvPaXB6GKdXy2gdEh8gBWQZ2ul24AJz3foUd8NNKlSTQuWYJpCb1/pL81m1KQ==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abab": { + "version": "2.0.6", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.8", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "acorn": "^3.0.4" + } + }, + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "devOptional": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/array-unique": { + "version": "0.3.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha512-t0OgO06uolEcMUvV8+yHc9Pc9pazh8wi/Dtyok/sQwvcr8iFV+P86IfAzK7upUDhI4oavhVREMY7iSWtm38LeA==" + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.13", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-regex": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/babel-code-frame/node_modules/strip-ansi": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-loader": { + "version": "9.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^3.3.2", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-messages": { + "version": "6.23.0", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.22.0" + } + }, + "node_modules/babel-plugin-es6-promise": { + "version": "1.1.1", + "license": "ISC", + "dependencies": { + "babel-template": "^6.7.0", + "babel-types": "^6.7.2" + }, + "peerDependencies": { + "es6-promise": "^4" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "license": "MIT", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "license": "MIT" + }, + "node_modules/babel-template": { + "version": "6.26.0", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse": { + "version": "6.26.0", + "license": "MIT", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/babel-traverse/node_modules/globals": { + "version": "9.18.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/babel-types": { + "version": "6.26.0", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "node_modules/babel-types/node_modules/to-fast-properties": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babylon": { + "version": "6.18.0", + "license": "MIT", + "bin": { + "babylon": "bin/babylon.js" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/base": { + "version": "0.11.2", + "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/boom": { + "version": "7.3.0", + "license": "BSD-3-Clause", + "dependencies": { + "hoek": "6.x.x" + } + }, + "node_modules/boom/node_modules/hoek": { + "version": "6.1.3", + "license": "BSD-3-Clause" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/builtins": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "17.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^8.0.1", + "lru-cache": "^7.7.1", + "minipass": "^4.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caller-path": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/caller-path/node_modules/callsites": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001462", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "3.5.3", + "devOptional": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/circular-json": { + "version": "0.3.3", + "license": "MIT" + }, + "node_modules/class-utils": { + "version": "0.3.6", + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/code-block-writer": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", + "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==" + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "2.0.19", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/commondir": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.4.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/core-js": { + "version": "2.6.12", + "hasInstallScript": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.29.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.21.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/critters": { + "version": "0.0.16", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "chalk": "^4.1.0", + "css-select": "^4.2.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "postcss": "^8.3.7", + "pretty-bytes": "^5.3.0" + } + }, + "node_modules/critters/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/critters/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/critters/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/critters/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/critters/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/critters/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cryptiles": { + "version": "4.1.3", + "license": "BSD-3-Clause", + "dependencies": { + "boom": "7.x.x" + } + }, + "node_modules/css-loader": { + "version": "6.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.19", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-property": { + "version": "0.2.5", + "license": "MIT", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.323", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.4.1", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz", + "integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.6", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/entities": { + "version": "2.2.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "dev": true, + "license": "MIT" + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.17.8", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.8", + "@esbuild/android-arm64": "0.17.8", + "@esbuild/android-x64": "0.17.8", + "@esbuild/darwin-arm64": "0.17.8", + "@esbuild/darwin-x64": "0.17.8", + "@esbuild/freebsd-arm64": "0.17.8", + "@esbuild/freebsd-x64": "0.17.8", + "@esbuild/linux-arm": "0.17.8", + "@esbuild/linux-arm64": "0.17.8", + "@esbuild/linux-ia32": "0.17.8", + "@esbuild/linux-loong64": "0.17.8", + "@esbuild/linux-mips64el": "0.17.8", + "@esbuild/linux-ppc64": "0.17.8", + "@esbuild/linux-riscv64": "0.17.8", + "@esbuild/linux-s390x": "0.17.8", + "@esbuild/linux-x64": "0.17.8", + "@esbuild/netbsd-x64": "0.17.8", + "@esbuild/openbsd-x64": "0.17.8", + "@esbuild/sunos-x64": "0.17.8", + "@esbuild/win32-arm64": "0.17.8", + "@esbuild/win32-ia32": "0.17.8", + "@esbuild/win32-x64": "0.17.8" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.17.8", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "4.19.1", + "license": "MIT", + "dependencies": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "5.5.2", + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/eslint/node_modules/ansi-escapes": { + "version": "3.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chardet": { + "version": "0.4.2", + "license": "MIT" + }, + "node_modules/eslint/node_modules/cli-cursor": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/cli-width": { + "version": "2.2.1", + "license": "ISC" + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "3.2.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "3.7.3", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint/node_modules/external-editor": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/eslint/node_modules/fast-deep-equal": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/eslint/node_modules/figures": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "3.3.10", + "license": "MIT" + }, + "node_modules/eslint/node_modules/inquirer": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "node_modules/eslint/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.3.1", + "license": "MIT" + }, + "node_modules/eslint/node_modules/lru-cache": { + "version": "4.1.5", + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/eslint/node_modules/mimic-fn": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/mute-stream": { + "version": "0.0.7", + "license": "ISC" + }, + "node_modules/eslint/node_modules/onetime": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/restore-cursor": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "5.7.1", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint/node_modules/string-width": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/yallist": { + "version": "2.1.2", + "license": "ISC" + }, + "node_modules/espree": { + "version": "3.5.4", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "5.7.4", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter-asyncresource": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.18.2", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.15.0", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "1.3.4", + "license": "MIT", + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flat-cache/node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/flat-cache/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flat-cache/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/gauge": { + "version": "4.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "13.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.7", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/has-value": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==", + "engines": { + "node": "*" + } + }, + "node_modules/hdr-histogram-js": { + "version": "2.0.3", + "dev": true, + "license": "BSD", + "dependencies": { + "@assemblyscript/loader": "^0.10.1", + "base64-js": "^1.2.0", + "pako": "^1.0.3" + } + }, + "node_modules/hdr-histogram-percentiles-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/hoek": { + "version": "4.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "6.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.3.3", + "dev": true, + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^6.1.6" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "6.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, + "node_modules/immutable": { + "version": "4.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ini": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/inquirer/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ipaddr.js": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "devOptional": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jasmine-core": { + "version": "4.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/jssha": { + "version": "2.3.1", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/karma": { + "version": "6.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.4.1", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma-coverage/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/karma/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/less": { + "version": "4.1.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "klona": "^2.0.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/log4js": { + "version": "6.9.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.29.0", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/@npmcli/fs": { + "version": "2.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/cacache": { + "version": "16.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-fetch-happen/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-fetch-happen/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "9.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-filename": { + "version": "2.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/unique-slug": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/map-cache": { + "version": "0.2.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/math-random": { + "version": "1.0.4", + "license": "MIT" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.4.13", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "5.1.6", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.4", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "dev": true, + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/needle": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "license": "MIT" + }, + "node_modules/ng-process-env": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/ng-process-env/-/ng-process-env-15.0.1.tgz", + "integrity": "sha512-KupEBFBQdq48md3EkpETkmWhnkT9iT7DkWUXk4M7zj5RtE+eh0C3IH6d2GObtK0D8CICmaRZSBMBT4eQfVVF2Q==", + "dependencies": { + "@angular-devkit/architect": "^0.1500.0", + "@angular-devkit/core": "^15.0.0", + "@angular-devkit/schematics": "^15.0.0", + "ts-morph": "^16.0.0", + "typescript": "4.8.4" + } + }, + "node_modules/ng-process-env/node_modules/@angular-devkit/architect": { + "version": "0.1500.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1500.5.tgz", + "integrity": "sha512-n1L3Q2d7HoWFRRqihu3BAUB5xZFfz8LqQoHpVNl6HN1ugtmvqDUDoKrpYVH9LCKCqfJW2Cxssy+FERiDsihIJQ==", + "dependencies": { + "@angular-devkit/core": "15.0.5", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/ng-process-env/node_modules/@angular-devkit/core": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.0.5.tgz", + "integrity": "sha512-SxLvbpqcQfb1qRykZjqRUG/8uC1FYpneyNV9S9YglXg4JhCFhfc9AnKxuu9Bm/O8V7FghOIlGWGglCdPHra0pw==", + "dependencies": { + "ajv": "8.11.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "rxjs": "6.6.7", + "source-map": "0.7.4" + }, + "engines": { + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/ng-process-env/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ng-process-env/node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/ng-process-env/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/ng-process-env/node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ngx-socket-io": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ngx-socket-io/-/ngx-socket-io-4.4.0.tgz", + "integrity": "sha512-0aD6J7n8Iwer5eQlHipAZMqVTV9RTHBPsMe372O4V1W+zRjK2PkjtsE6jFi5LZzJrCthQVDim8+6Kf6H1FA/qA==", + "dependencies": { + "core-js": "^3.0.0", + "reflect-metadata": "^0.1.10", + "socket.io": "^4.5.1", + "socket.io-client": "^4.5.1", + "tslib": "^2.3.0", + "zone.js": "~0.11.4" + }, + "peerDependencies": { + "@angular/common": "^15.0.0", + "@angular/core": "^15.0.0", + "rxjs": "^7.0.0" + } + }, + "node_modules/ngx-socket-io/node_modules/core-js": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.1.tgz", + "integrity": "sha512-+jwgnhg6cQxKYIIjGtAHq2nwUOolo9eoFZ4sHfUH09BLXBgxnH4gA0zEd+t+BO2cNB8idaBtZFcFTRjQJRJmAw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/ngx-socket-io/node_modules/zone.js": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.11.8.tgz", + "integrity": "sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA==", + "dependencies": { + "tslib": "^2.3.0" + } + }, + "node_modules/nice-napi": { + "version": "1.0.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "!win32" + ], + "dependencies": { + "node-addon-api": "^3.0.0", + "node-gyp-build": "^4.2.2" + } + }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "9.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/node-releases": { + "version": "2.0.10", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "5.0.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^6.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.0.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "10.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "14.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^4.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { + "version": "11.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^4.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^4.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npo-api-interceptor": { + "version": "1.9.0", + "license": "MIT", + "dependencies": { + "babel-plugin-es6-promise": "^1.1.1", + "braces": "^2.3.1", + "cryptiles": "^4.1.2", + "es6-promise": "4.2.8", + "eslint": "^4.18.2", + "handlebars": "^4.3.0", + "hoek": "^4.2.1", + "jssha": "2.3.1", + "lodash": "^4.17.12", + "nwmatcher": "^1.4.4", + "randomatic": "^3.0.0", + "tunnel-agent": "^0.6.0" + } + }, + "node_modules/npo-api-interceptor/node_modules/braces": { + "version": "2.3.2", + "license": "MIT", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npo-api-interceptor/node_modules/fill-range": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npo-api-interceptor/node_modules/is-number": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npo-api-interceptor/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npo-api-interceptor/node_modules/to-regex-range": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwmatcher": { + "version": "1.4.4", + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pacote": { + "version": "15.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^4.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^6.0.1", + "@npmcli/run-script": "^6.0.0", + "cacache": "^17.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^4.0.0", + "npm-package-arg": "^10.0.0", + "npm-packlist": "^7.0.0", + "npm-pick-manifest": "^8.0.0", + "npm-registry-fetch": "^14.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^6.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^1.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "4.4.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/parse5": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser/node_modules/entities": { + "version": "4.4.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-sax-parser/node_modules/parse5": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter-asyncresource": "^1.0.0", + "hdr-histogram-js": "^2.0.1", + "hdr-histogram-percentiles-obj": "^3.0.0" + }, + "optionalDependencies": { + "nice-napi": "^1.0.2" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.21", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proc-log": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/progress": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qjobs": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randomatic": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-package-json": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^8.0.1", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^5.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.1", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "devOptional": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-parser": { + "version": "2.2.11", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpp": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-uncached/node_modules/resolve-from": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "license": "MIT", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rx-lite": { + "version": "4.0.8" + }, + "node_modules/rx-lite-aggregates": { + "version": "4.0.8", + "dependencies": { + "rx-lite": "*" + } + }, + "node_modules/rxjs": { + "version": "7.8.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.58.1", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/sass-loader": { + "version": "13.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/send": { + "version": "0.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/set-value": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sharedb": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-3.3.0.tgz", + "integrity": "sha512-DBWY9OKdVkItqWiPYEAdfs8IZXmmqGhzR+KW6Ir4bIY37TBYrZ3pwviMZutk62EqNDe6FR4ktlH0cvIeswWq1A==", + "dependencies": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "node_modules/sharedb/node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "1.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "make-fetch-happen": "^11.0.1", + "tuf-js": "^1.0.0" + }, + "bin": { + "sigstore": "bin/sigstore.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/sigstore/node_modules/make-fetch-happen": { + "version": "11.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^4.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/sigstore/node_modules/minipass-fetch": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^4.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "license": "MIT", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/socket.io": { + "version": "4.6.1", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "license": "MIT", + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-client": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz", + "integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.4.0", + "socket.io-parser": "~4.2.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.2", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "10.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "license": "MIT", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/table": { + "version": "4.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "5.5.2", + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "node_modules/table/node_modules/ajv-keywords": { + "version": "2.1.1", + "license": "MIT", + "peerDependencies": { + "ajv": "^5.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/fast-deep-equal": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "0.3.1", + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.1.13", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^4.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.16.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/three": { + "version": "0.150.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.150.1.tgz", + "integrity": "sha512-5C1MqKUWaHYo13BX0Q64qcdwImgnnjSOFgBscOzAo8MYCzEtqfQqorEKMcajnA3FHy1yVlIe9AmaMQ0OQracNA==" + }, + "node_modules/through": { + "version": "2.3.8", + "license": "MIT" + }, + "node_modules/thunky": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-data-descriptor": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-descriptor": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-morph": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-16.0.0.tgz", + "integrity": "sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==", + "dependencies": { + "@ts-morph/common": "~0.17.0", + "code-block-writer": "^11.0.3" + } + }, + "node_modules/tslib": { + "version": "2.5.0", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "1.0.0", + "make-fetch-happen": "^11.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/tuf-js/node_modules/make-fetch-happen": { + "version": "11.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^17.0.0", + "http-cache-semantics": "^4.1.1", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^4.0.0", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/tuf-js/node_modules/minipass-fetch": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^4.0.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray": { + "version": "0.0.6", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "4.9.5", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.34", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "license": "MIT", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "license": "MIT" + }, + "node_modules/use": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.75.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.12", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.11.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/write": { + "version": "0.2.1", + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ws": { + "version": "8.11.0", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/zone.js": { + "version": "0.12.0", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + } + } + } +} diff --git a/3dworld/package.json b/3dworld/package.json new file mode 100644 index 00000000..919a084a --- /dev/null +++ b/3dworld/package.json @@ -0,0 +1,47 @@ +{ + "name": "3dworld", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^15.2.0", + "@angular/common": "^15.2.0", + "@angular/compiler": "^15.2.0", + "@angular/core": "^15.2.0", + "@angular/forms": "^15.2.0", + "@angular/platform-browser": "^15.2.0", + "@angular/platform-browser-dynamic": "^15.2.0", + "@angular/router": "^15.2.0", + "@auth0/auth0-angular": "^2.0.1", + "jszip": "^3.10.1", + "ng-process-env": "^15.0.1", + "ngx-socket-io": "^4.4.0", + "npo-api-interceptor": "^1.9.0", + "rxjs": "~7.8.0", + "sharedb": "^3.3.0", + "three": "^0.150.1", + "tslib": "^2.3.0", + "zone.js": "~0.12.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^15.2.0", + "@angular/cli": "~15.2.0", + "@angular/compiler-cli": "^15.2.0", + "@types/jasmine": "~4.3.0", + "@types/node": "^18.15.6", + "@types/three": "^0.149.0", + "jasmine-core": "~4.5.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.1.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.0.0", + "typescript": "~4.9.4" + } +} diff --git a/3dworld/src/app/app-routing.module.ts b/3dworld/src/app/app-routing.module.ts new file mode 100644 index 00000000..5c3c2046 --- /dev/null +++ b/3dworld/src/app/app-routing.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { IndexComponent } from './pages/index/index.component'; +import { SignInComponent } from './pages/sign-in/sign-in.component'; +import { SignUpComponent } from './pages/sign-up/sign-up.component'; +import { AuthGuard } from '@auth0/auth0-angular'; +import { Auth0Guard } from './guards/auth0.guard'; +import { SessionGuard } from './guards/session.guard'; +import { WorldsComponent } from './pages/worlds/worlds.component'; +import { WorldViewComponent } from './pages/world-view/world-view.component'; +import { WorldObjectComponent } from './component/world-object/world-object.component'; +import { ProfileComponent } from './pages/profile/profile.component'; +import { CreditsComponent } from './pages/credits/credits.component'; + +const routes: Routes = [ + { + path: '', + component: IndexComponent, + }, + { + path: 'worlds', + component: WorldsComponent, + canActivate: [Auth0Guard, SessionGuard], + }, + { + path: 'world-view', + component: WorldViewComponent, + canActivate: [Auth0Guard, SessionGuard], + }, + { + path: 'profile', + component: ProfileComponent, + canActivate: [Auth0Guard, SessionGuard], + }, + { + path: 'world-object', + component: WorldObjectComponent, + canActivate: [Auth0Guard], + }, + { + path: 'credits', + component: CreditsComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes, { useHash: true })], + exports: [RouterModule], +}) +export class AppRoutingModule {} diff --git a/3dworld/src/app/app.component.html b/3dworld/src/app/app.component.html new file mode 100644 index 00000000..1e157542 --- /dev/null +++ b/3dworld/src/app/app.component.html @@ -0,0 +1,2 @@ + + diff --git a/3dworld/src/app/app.component.scss b/3dworld/src/app/app.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/app.component.spec.ts b/3dworld/src/app/app.component.spec.ts new file mode 100644 index 00000000..81798b7f --- /dev/null +++ b/3dworld/src/app/app.component.spec.ts @@ -0,0 +1,33 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title '3dworld'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('3dworld'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('.content span')?.textContent).toContain( + '3dworld app is running!' + ); + }); +}); diff --git a/3dworld/src/app/app.component.ts b/3dworld/src/app/app.component.ts new file mode 100644 index 00000000..dfec4e57 --- /dev/null +++ b/3dworld/src/app/app.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'], +}) +export class AppComponent { + title = '3dworld'; +} diff --git a/3dworld/src/app/app.module.ts b/3dworld/src/app/app.module.ts new file mode 100644 index 00000000..c3af3ae7 --- /dev/null +++ b/3dworld/src/app/app.module.ts @@ -0,0 +1,71 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { HeaderComponent } from './component/header/header.component'; +import { IndexComponent } from './pages/index/index.component'; +import { SignInComponent } from './pages/sign-in/sign-in.component'; +import { AuthModule } from '@auth0/auth0-angular'; +import { environment } from 'src/environments/environment'; + +import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'; +import { SignUpComponent } from './pages/sign-up/sign-up.component'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { SocketIoConfig, SocketIoModule } from 'ngx-socket-io'; + +import { WorldObjectComponent } from './component/world-object/world-object.component'; +import { WorldsComponent } from './pages/worlds/worlds.component'; +import { WorlddivComponent } from './component/worlddiv/worlddiv.component'; +import { CommentformComponent } from './component/commentform/commentform.component'; +import { UploadFormComponent } from './component/upload-form/upload-form.component'; +import { WorldViewComponent } from './pages/world-view/world-view.component'; +import { CommentViewComponent } from './component/comment-view/comment-view.component'; +import { CommentDivComponent } from './component/comment-view/comment-div/comment-div.component'; +import { ChunkFormComponent } from './component/chunk-form/chunk-form.component'; +import { ProfileComponent } from './pages/profile/profile.component'; +import { NotificationdivComponent } from './component/notificationdiv/notificationdiv.component'; +import { CreditsComponent } from './pages/credits/credits.component'; + +const socketIoCfg: SocketIoConfig = { + url: environment.apiEndpoint, + options: { + transports: ['polling'], + autoConnect: false, + withCredentials: true, + }, +}; + +@NgModule({ + declarations: [ + AppComponent, + HeaderComponent, + IndexComponent, + SignInComponent, + SignUpComponent, + WorldObjectComponent, + WorldsComponent, + WorlddivComponent, + CommentformComponent, + UploadFormComponent, + WorldViewComponent, + CommentViewComponent, + CommentDivComponent, + ChunkFormComponent, + ProfileComponent, + NotificationdivComponent, + CreditsComponent, + ], + imports: [ + FormsModule, + ReactiveFormsModule, + HttpClientModule, + BrowserModule, + AppRoutingModule, + AuthModule.forRoot(environment.auth), + SocketIoModule.forRoot(socketIoCfg), + ], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/3dworld/src/app/component/chunk-form/chunk-form.component.html b/3dworld/src/app/component/chunk-form/chunk-form.component.html new file mode 100644 index 00000000..13c3e280 --- /dev/null +++ b/3dworld/src/app/component/chunk-form/chunk-form.component.html @@ -0,0 +1,11 @@ +
+ + +
diff --git a/3dworld/src/app/component/chunk-form/chunk-form.component.scss b/3dworld/src/app/component/chunk-form/chunk-form.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/component/chunk-form/chunk-form.component.spec.ts b/3dworld/src/app/component/chunk-form/chunk-form.component.spec.ts new file mode 100644 index 00000000..46665f80 --- /dev/null +++ b/3dworld/src/app/component/chunk-form/chunk-form.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChunkFormComponent } from './chunk-form.component'; + +describe('ChunkFormComponent', () => { + let component: ChunkFormComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ChunkFormComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ChunkFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/chunk-form/chunk-form.component.ts b/3dworld/src/app/component/chunk-form/chunk-form.component.ts new file mode 100644 index 00000000..9987be73 --- /dev/null +++ b/3dworld/src/app/component/chunk-form/chunk-form.component.ts @@ -0,0 +1,37 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; + +@Component({ + selector: 'app-chunk-form', + templateUrl: './chunk-form.component.html', + styleUrls: ['./chunk-form.component.scss'], +}) +export class ChunkFormComponent { + @Output() answer = new EventEmitter(); + @Input() worldId: string = ''; + @Input() chunkX: number = 0; + @Input() chunkZ: number = 0; + userInput = false; + form = new FormGroup({ + answer: new FormControl(false), + }); + + onSubmit() { + if (this.userInput) { + console.log('User answered yes.'); + this.answer.emit(true); + } else { + console.log('User answered no.'); + this.answer.emit(false); + } + } + + claimPlot(event: any): void { + this.userInput = event.target.checked; + } +} diff --git a/3dworld/src/app/component/comment-view/comment-div/comment-div.component.html b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.html new file mode 100644 index 00000000..9d0706d0 --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.html @@ -0,0 +1,12 @@ +
+ Author: {{ comment.author.displayName }} +
+
Rating: {{ comment.rating }}
+
Content: {{ comment.content }}
+
CreatedAt: {{ comment.createdAt }}
+
+ +
+
diff --git a/3dworld/src/app/component/comment-view/comment-div/comment-div.component.scss b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.scss new file mode 100644 index 00000000..eb57334f --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.scss @@ -0,0 +1,4 @@ +.text { + font-size: 15px; + color: white; +} diff --git a/3dworld/src/app/component/comment-view/comment-div/comment-div.component.spec.ts b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.spec.ts new file mode 100644 index 00000000..9323919a --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CommentDivComponent } from './comment-div.component'; + +describe('CommentDivComponent', () => { + let component: CommentDivComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CommentDivComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CommentDivComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/comment-view/comment-div/comment-div.component.ts b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.ts new file mode 100644 index 00000000..1ca6b66e --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-div/comment-div.component.ts @@ -0,0 +1,20 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; + +@Component({ + selector: 'app-comment-div', + templateUrl: './comment-div.component.html', + styleUrls: ['./comment-div.component.scss'], +}) +export class CommentDivComponent implements OnInit { + ngOnInit(): void { + this.mine = this.comment.author._id == this.userId; + } + mine: boolean = false; + @Output() deleted = new EventEmitter(); + @Input() userId: string = ''; + @Input() comment: any; + + deleteComment() { + this.deleted.emit(this.comment._id); + } +} diff --git a/3dworld/src/app/component/comment-view/comment-view.component.html b/3dworld/src/app/component/comment-view/comment-view.component.html new file mode 100644 index 00000000..c0a10e0c --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-view.component.html @@ -0,0 +1,8 @@ +
Ratings For Chunk (x,z) = ({{ x }},{{ z }})
+
+ +
diff --git a/3dworld/src/app/component/comment-view/comment-view.component.scss b/3dworld/src/app/component/comment-view/comment-view.component.scss new file mode 100644 index 00000000..2fb23608 --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-view.component.scss @@ -0,0 +1,13 @@ +.title { + font-size: 24px; + font-weight: bold; + padding: 10px 0px 10px 25px; + color: white; + background-color: #333; + border-radius: 7px 7px 0px 0px; +} + +.comments-container { + background-color: #444; + padding: 20px 10px 10px 10px; +} diff --git a/3dworld/src/app/component/comment-view/comment-view.component.spec.ts b/3dworld/src/app/component/comment-view/comment-view.component.spec.ts new file mode 100644 index 00000000..33774db7 --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-view.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CommentViewComponent } from './comment-view.component'; + +describe('CommentViewComponent', () => { + let component: CommentViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CommentViewComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CommentViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/comment-view/comment-view.component.ts b/3dworld/src/app/component/comment-view/comment-view.component.ts new file mode 100644 index 00000000..79d44bd3 --- /dev/null +++ b/3dworld/src/app/component/comment-view/comment-view.component.ts @@ -0,0 +1,26 @@ +import { + Component, + ElementRef, + EventEmitter, + Input, + OnInit, + Output, + ViewChild, +} from '@angular/core'; + +@Component({ + selector: 'app-comment-view', + templateUrl: './comment-view.component.html', + styleUrls: ['./comment-view.component.scss'], +}) +export class CommentViewComponent { + @Output() deleted = new EventEmitter(); + @Input() userId: string = ''; + @Input() comments: any = []; + @Input() x: number = 0; + @Input() z: number = 0; + + deleteComment(commentId: string) { + this.deleted.emit(commentId); + } +} diff --git a/3dworld/src/app/component/commentform/commentform.component.html b/3dworld/src/app/component/commentform/commentform.component.html new file mode 100644 index 00000000..4c3600c2 --- /dev/null +++ b/3dworld/src/app/component/commentform/commentform.component.html @@ -0,0 +1,33 @@ +
+
+ Post a Rating on Chunk(x,z) = ({{ chunkX }},{{ chunkZ }}) +
+ + +

Status: {{ commentForm.status }}

+ +
diff --git a/3dworld/src/app/component/commentform/commentform.component.scss b/3dworld/src/app/component/commentform/commentform.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/component/commentform/commentform.component.spec.ts b/3dworld/src/app/component/commentform/commentform.component.spec.ts new file mode 100644 index 00000000..23be3678 --- /dev/null +++ b/3dworld/src/app/component/commentform/commentform.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CommentformComponent } from './commentform.component'; + +describe('CommentformComponent', () => { + let component: CommentformComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CommentformComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CommentformComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/commentform/commentform.component.ts b/3dworld/src/app/component/commentform/commentform.component.ts new file mode 100644 index 00000000..e484764a --- /dev/null +++ b/3dworld/src/app/component/commentform/commentform.component.ts @@ -0,0 +1,45 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ApiService } from 'src/app/services/api.service'; + +@Component({ + selector: 'app-commentform', + templateUrl: './commentform.component.html', + styleUrls: ['./commentform.component.scss'], +}) +export class CommentformComponent { + @Output() newComment = new EventEmitter(); + @Input() worldId: string = ''; + @Input() chunkX: number = 0; + @Input() chunkZ: number = 0; + authorId: string = ''; + authorName: string = ''; + commentForm: FormGroup; + formGroup: any; + + constructor(private fb: FormBuilder, private api: ApiService) { + this.commentForm = this.fb.group({ + comment: ['', Validators.required], + ratings: [0, Validators.required], + }); + } + + ngOnInit(): void { + this.api.getMe().subscribe({ + next: (x: any) => { + this.authorId = x.userId; + this.authorName = x.displayName; + }, + error: (err: any) => console.error(err), + }); + } + + postComment() { + this.newComment.emit({ + comment: this.commentForm.value.comment, + rating: this.commentForm.value.ratings, + }); + + this.commentForm.reset(); + } +} diff --git a/3dworld/src/app/component/header/header.component.html b/3dworld/src/app/component/header/header.component.html new file mode 100644 index 00000000..5670e049 --- /dev/null +++ b/3dworld/src/app/component/header/header.component.html @@ -0,0 +1,27 @@ +
+ Buildverse + + + +
+ +
+ + + + +
+ +

diff --git a/3dworld/src/app/component/header/header.component.scss b/3dworld/src/app/component/header/header.component.scss new file mode 100644 index 00000000..cb2f76bf --- /dev/null +++ b/3dworld/src/app/component/header/header.component.scss @@ -0,0 +1,91 @@ +@import url("https://fonts.googleapis.com/css2?family=Comfortaa:wght@500&display=swap"); + +* { + box-sizing: border-box; + margin: 0; + padding: 0; + background-color: #24252a; +} + +button { + color: #edf0f1; + text-decoration: none; + font-size: 18px; + border: none; + cursor: pointer; + transition: all 0.3s ease 0s; +} + +header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 30px 10%; +} + +header #title { + color: #edf0f1; + font-family: "Comfortaa", sans-serif; + font-weight: 500; + font-size: 45px; + text-decoration: none; + cursor: pointer; +} + +#nav-container { + display: flex; + justify-content: space-between; + padding: 0px, 20px; +} + +#nav-container .nav-element button { + margin: 0px 25px; +} + +#nav-container .nav-element button:hover { + color: #ef2d5e; +} + +#error-box { + color: red; + visibility: hidden; +} + +#error-box::before { + content: "Error: "; +} + +.btn { + padding: 9px 25px; + background: rgba(239, 45, 94, 1); + border-radius: 50px; +} + +.btn:hover { + background: rgba(239, 45, 94, 0.8); +} + +.notification { + position: relative; + display: flex; + align-items: center; + justify-content: center; + color: #333333; + border: none; + outline: none; + border-radius: 50%; +} + +.notification-icon { + position: absolute; + top: -10px; + right: -10px; + width: 25px; + height: 25px; + background: red; + color: #ffffff; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; +} diff --git a/3dworld/src/app/component/header/header.component.spec.ts b/3dworld/src/app/component/header/header.component.spec.ts new file mode 100644 index 00000000..9cc48ab6 --- /dev/null +++ b/3dworld/src/app/component/header/header.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [HeaderComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/header/header.component.ts b/3dworld/src/app/component/header/header.component.ts new file mode 100644 index 00000000..b4f2c22c --- /dev/null +++ b/3dworld/src/app/component/header/header.component.ts @@ -0,0 +1,59 @@ +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; +import { AuthService } from '@auth0/auth0-angular'; +import { Location } from '@angular/common'; +import { ApiService } from 'src/app/services/api.service'; +import { NotificationService } from 'src/app/services/notification.service'; +import { Observable } from 'rxjs'; +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.scss'], +}) +export class HeaderComponent { + private notificationObserver!: Observable; + unseenCount = 0; + + constructor( + public auth: AuthService, + private location: Location, + private api: ApiService, + private router: Router, + private notification: NotificationService + ) {} + ngOnInit(): void { + this.notificationObserver = this.notification.getListener(); + } + + ngAfterViewInit(): void { + this.notificationObserver.subscribe((data) => { + if ('unseen' in data) { + this.unseenCount = data.unseen; + } else { + this.unseenCount++; + } + }); + } + + async loginWithRedirect(): Promise { + this.auth.loginWithRedirect({ + authorizationParams: { + redirect_uri: 'http://localhost:4200', + }, + }); + } + + goToWorlds() { + this.router.navigateByUrl('worlds'); + } + + goToProfile() { + this.unseenCount = 0; + this.router.navigateByUrl('profile'); + } + + signOut() { + this.auth.logout(); + this.api.signOut().subscribe(); + } +} diff --git a/3dworld/src/app/component/notificationdiv/notificationdiv.component.html b/3dworld/src/app/component/notificationdiv/notificationdiv.component.html new file mode 100644 index 00000000..ee55d413 --- /dev/null +++ b/3dworld/src/app/component/notificationdiv/notificationdiv.component.html @@ -0,0 +1,7 @@ +
+ {{ notification.sender }} rated {{ notification.rating }}★ +
+
In: {{ notification.worldName }}
+
+ At Chunk (x,z) = ({{ notification.chunk.x }},{{ notification.chunk.z }}) +
diff --git a/3dworld/src/app/component/notificationdiv/notificationdiv.component.scss b/3dworld/src/app/component/notificationdiv/notificationdiv.component.scss new file mode 100644 index 00000000..8b2f957c --- /dev/null +++ b/3dworld/src/app/component/notificationdiv/notificationdiv.component.scss @@ -0,0 +1,8 @@ +.world-title { + font-size: 26px; + font-weight: bold; +} + +.world-content { + font-size: 18px; +} diff --git a/3dworld/src/app/component/notificationdiv/notificationdiv.component.spec.ts b/3dworld/src/app/component/notificationdiv/notificationdiv.component.spec.ts new file mode 100644 index 00000000..44783a14 --- /dev/null +++ b/3dworld/src/app/component/notificationdiv/notificationdiv.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotificationdivComponent } from './notificationdiv.component'; + +describe('NotificationdivComponent', () => { + let component: NotificationdivComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [NotificationdivComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(NotificationdivComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/notificationdiv/notificationdiv.component.ts b/3dworld/src/app/component/notificationdiv/notificationdiv.component.ts new file mode 100644 index 00000000..67d1ebf0 --- /dev/null +++ b/3dworld/src/app/component/notificationdiv/notificationdiv.component.ts @@ -0,0 +1,11 @@ +import { Component, Input, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-notificationdiv', + templateUrl: './notificationdiv.component.html', + styleUrls: ['./notificationdiv.component.scss'], +}) +export class NotificationdivComponent implements OnInit { + @Input() notification!: any; + ngOnInit(): void {} +} diff --git a/3dworld/src/app/component/upload-form/upload-form.component.html b/3dworld/src/app/component/upload-form/upload-form.component.html new file mode 100644 index 00000000..1f0176b3 --- /dev/null +++ b/3dworld/src/app/component/upload-form/upload-form.component.html @@ -0,0 +1,21 @@ +
+
Upload a glTF zip file
+
+ + +
+ +
diff --git a/3dworld/src/app/component/upload-form/upload-form.component.scss b/3dworld/src/app/component/upload-form/upload-form.component.scss new file mode 100644 index 00000000..eb57334f --- /dev/null +++ b/3dworld/src/app/component/upload-form/upload-form.component.scss @@ -0,0 +1,4 @@ +.text { + font-size: 15px; + color: white; +} diff --git a/3dworld/src/app/component/upload-form/upload-form.component.spec.ts b/3dworld/src/app/component/upload-form/upload-form.component.spec.ts new file mode 100644 index 00000000..6623cfac --- /dev/null +++ b/3dworld/src/app/component/upload-form/upload-form.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UploadFormComponent } from './upload-form.component'; + +describe('UploadFormComponent', () => { + let component: UploadFormComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [UploadFormComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(UploadFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/upload-form/upload-form.component.ts b/3dworld/src/app/component/upload-form/upload-form.component.ts new file mode 100644 index 00000000..ce6730d2 --- /dev/null +++ b/3dworld/src/app/component/upload-form/upload-form.component.ts @@ -0,0 +1,36 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { ApiService } from 'src/app/services/api.service'; + +@Component({ + selector: 'app-upload-form', + templateUrl: './upload-form.component.html', + styleUrls: ['./upload-form.component.scss'], +}) +export class UploadFormComponent { + @Output() file = new EventEmitter(); + @Input() worldId: string = ''; + @Input() chunkX: number = 0; + @Input() chunkZ: number = 0; + realFile!: File; + uploadForm: FormGroup; + constructor(private fb: FormBuilder) { + this.uploadForm = this.fb.group({ + GLTFfile: [null, Validators.required], + }); + } + + newUpload(): void { + this.file.emit(this.realFile); + this.uploadForm.reset(); + } + + fileChange(event: any): void { + this.realFile = event.target.files[0]; + } +} diff --git a/3dworld/src/app/component/vote/vote.component.html b/3dworld/src/app/component/vote/vote.component.html new file mode 100644 index 00000000..f81a2ed4 --- /dev/null +++ b/3dworld/src/app/component/vote/vote.component.html @@ -0,0 +1,6 @@ +
+ {{ upvotes }} + + {{ downvotes }} + +
diff --git a/3dworld/src/app/component/vote/vote.component.scss b/3dworld/src/app/component/vote/vote.component.scss new file mode 100644 index 00000000..5628cba3 --- /dev/null +++ b/3dworld/src/app/component/vote/vote.component.scss @@ -0,0 +1,13 @@ +.upvote-button { + background-image: url(../../../assets/up-arrow.png); + background-color: transparent; + width: 64px; + height: 64px; +} + +.downvote-button { + background-image: url(../../../assets/down-arrow.png); + background-color: transparent; + width: 64px; + height: 64px; +} diff --git a/3dworld/src/app/component/vote/vote.component.ts b/3dworld/src/app/component/vote/vote.component.ts new file mode 100644 index 00000000..993ba471 --- /dev/null +++ b/3dworld/src/app/component/vote/vote.component.ts @@ -0,0 +1,23 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-vote', + templateUrl: './vote.component.html', + styleUrls: ['./vote.component.scss'], +}) +export class VoteComponent { + @Input() downvotes!: number; + @Input() upvotes!: number; + + constructor() {} + + //display the current vote + //prevent the user from voting more than once + voteDown() { + this.downvotes++; + } + + voteUp() { + this.upvotes++; + } +} diff --git a/3dworld/src/app/component/world-object/world-object.component.html b/3dworld/src/app/component/world-object/world-object.component.html new file mode 100644 index 00000000..a7539c67 --- /dev/null +++ b/3dworld/src/app/component/world-object/world-object.component.html @@ -0,0 +1,62 @@ +
+
+
+ +
+ + + + +
+
+ + + +
+
diff --git a/3dworld/src/app/component/world-object/world-object.component.scss b/3dworld/src/app/component/world-object/world-object.component.scss new file mode 100644 index 00000000..569b397a --- /dev/null +++ b/3dworld/src/app/component/world-object/world-object.component.scss @@ -0,0 +1,48 @@ +.content { + font-size: 24px; +} + +.canvas { + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + background-color: blue; + border: 2px solid #3c3d3f; + border-radius: 10px; + display: flex; +} + +.canvas-container-style { + width: 100%; + height: 80%; + max-width: 100%; + max-height: 80%; + display: flex; + border-radius: 10px; + margin: 5px; +} + +.container { + height: 100%; +} + +.hidden { + visibility: hidden !important; + height: 0px !important; +} + +#error { + color: red; +} + +.comment-containers-container { + margin: 20px 20px 30px 20px; +} + +.comment-button-container { + padding: 0px 10px 20px 10px; + background-color: #444; + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} diff --git a/3dworld/src/app/component/world-object/world-object.component.spec.ts b/3dworld/src/app/component/world-object/world-object.component.spec.ts new file mode 100644 index 00000000..621fe10d --- /dev/null +++ b/3dworld/src/app/component/world-object/world-object.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WorldObjectComponent } from './world-object.component'; + +describe('WorldObjectComponent', () => { + let component: WorldObjectComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [WorldObjectComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(WorldObjectComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/world-object/world-object.component.ts b/3dworld/src/app/component/world-object/world-object.component.ts new file mode 100644 index 00000000..6d91c67b --- /dev/null +++ b/3dworld/src/app/component/world-object/world-object.component.ts @@ -0,0 +1,426 @@ +import { AfterViewInit, Component, Input, OnDestroy } from '@angular/core'; + +import * as THREE from 'three'; +import * as JSZip from 'jszip'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import { ApiService } from '../../services/api.service'; +import { LiveWorldService } from '../../services/liveworld.service'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { + lastValueFrom, + forkJoin, + ReplaySubject, + tap, + takeUntil, + take, +} from 'rxjs'; +@Component({ + selector: 'app-world-object', + templateUrl: './world-object.component.html', + styleUrls: ['./world-object.component.scss'], +}) +export class WorldObjectComponent implements AfterViewInit, OnDestroy { + @Input() worldId!: string; + scene!: THREE.Scene; + camera!: THREE.PerspectiveCamera; + renderer!: THREE.WebGLRenderer; + raycaster!: THREE.Raycaster; + mouse!: THREE.Vector2; + models!: THREE.Group[]; + loadedChunks!: Map; + loadedCount!: number; + ambientLight!: THREE.AmbientLight; + controls!: OrbitControls; + loader!: GLTFLoader; + x!: number; + z!: number; + chunkSizeX!: number; + chunkSizeZ!: number; + chunkId!: string; + worldData!: any; + comments: any = []; + user: any; + commentPage: number = 0; + commentLimit: number = 10; + userId: string = ''; + canvas!: HTMLCanvasElement; + upvotes: number = 0; + downvotes: number = 0; + error: string = ''; + private onInitReplay = new ReplaySubject(1); + + constructor(private api: ApiService, private liveWorld: LiveWorldService) {} + + claimPlot(userInput: boolean): void { + const chunkIndex = this.worldData.world.chunks.findIndex( + (chunk: any) => chunk._id === this.chunkId + ); + if (userInput && !this.worldData.world.chunks[chunkIndex].claimed) { + this.worldData.world.chunks[chunkIndex].claimed = true; + this.worldData.world.chunks[chunkIndex].claimedBy = this.userId; + this.api.claimChunk(this.worldId, this.chunkId).subscribe((data) => { + document.querySelector('app-chunk-form')!.classList.add('hidden'); + }); + } + } + + vote(vote: Event): void {} + + getChunkFile(chunkId: string): Promise { + return lastValueFrom(this.api.getChunkFile(this.worldId, chunkId)).then( + (data) => { + return data; + } + ); + } + + createWorld(): void { + this.api + .createWorld('newWorld', 'newerWorld', 'no rules', 5, 4) + .subscribe((data) => {}); + } + + uploadModel(event: any): void { + document.querySelector('app-upload-form')!.classList.add('hidden'); + this.api + .uploadModel(this.worldId, this.chunkId, event) + .subscribe((data) => { + document.querySelector('app-upload-form')!.classList.add('hidden'); + }); + } + + onWindowResize() { + this.resizeCanvasToDisplaySize(this.canvas); + this.camera.aspect = this.canvas.width / this.canvas.height; + this.camera.updateProjectionMatrix(); + this.renderer.setSize(this.canvas.width, this.canvas.height); + } + + resizeCanvasToDisplaySize(canvas: HTMLCanvasElement) { + // to be in sync with the body max size, ensure height and width are not greater than 800px + let width = document.getElementById('canvas-container')!.clientWidth; + let height = (10 / 16) * width; + + // If it's resolution does not match change it + if (canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + return true; + } + + return false; + } + + loadSingleChunk( + data: any, + coordX: number, + coordZ: number, + init = true + ): void { + const zip = new JSZip(); + const loadingManager = new THREE.LoadingManager(); + const zipURL_to_URL: { [path: string]: string } = {}; + let gltfFile: JSZip.JSZipObject; + + zip + .loadAsync(data) + .then((zip: JSZip) => { + gltfFile = zip.file(/\.gltf$/i)[0]; + if (!gltfFile) { + throw new Error('GLTF file not found in zip'); + } + // extract all the files in the zip as Blobs + const fileDataPromises: Promise[] = []; + zip.forEach((relativePath, file) => { + fileDataPromises.push( + file.async('arraybuffer').then((data: ArrayBuffer) => { + const blob = new Blob([data]); + zipURL_to_URL[relativePath] = URL.createObjectURL(blob); + }) + ); + }); + return Promise.all(fileDataPromises); + }) + .then(() => { + loadingManager.setURLModifier((url: string) => { + if (url in zipURL_to_URL) { + return zipURL_to_URL[url]; + } + return url; + }); + this.loader = new GLTFLoader(loadingManager); + return gltfFile.async('arraybuffer'); // extract the GLTF file as a blob + }) + .then((gltfBlob: ArrayBuffer) => { + this.loader.parse(gltfBlob, '', (gltf) => { + this.resizeModel(gltf.scene, this.chunkSizeX); + const dimensions = this.getModelDimensions(gltf.scene); + const box = new THREE.Box3().setFromObject(gltf.scene, true); + const center = new THREE.Vector3(); + box.getCenter(center); + center.negate(); + gltf.scene.position.set(coordX, dimensions.y / 2, coordZ); + gltf.scene.position.add(center); + // Create a directional light and add it to the scene. + const heimsphere = new THREE.HemisphereLight(0xffffff, 0x000000, 1); + const directionlLight = new THREE.DirectionalLight(0xffffff, 1); + gltf.scene.add(directionlLight); + gltf.scene.add(heimsphere); + const length = this.worldData.world.chunks.length; + if (init) { + this.models.push(gltf.scene); + this.scene.add(gltf.scene); + this.loadedChunks.set(coordX + coordZ * length, this.loadedCount++); + } else { + const key = coordX + coordZ * length; + if (this.loadedChunks.get(key)) { + this.scene.remove(this.models[this.loadedChunks.get(key)!]); + this.models[this.loadedChunks.get(key)!] = gltf.scene; + this.scene.add(gltf.scene); + } + } + }); + }); + } + + private getModelDimensions(model: THREE.Group): THREE.Vector3 { + const box = new THREE.Box3().setFromObject(model); + const dimensions = new THREE.Vector3(); + box.getSize(dimensions); + return dimensions; + } + + private resizeModel(model: THREE.Group, chunkSize: any): void { + const dimensions = this.getModelDimensions(model); + const maxHorizontalDimension = Math.max(dimensions.x, dimensions.z); + const scale = ((chunkSize - 1) * 0.9) / maxHorizontalDimension; + model.scale.setScalar(scale); + } + + loadChunks(worldData: any): void { + let id = worldData.world._id; + let chunks = worldData.world.chunks; + + for (let x = 0; x < chunks.length; x++) { + const coordX = worldData.world.chunks[x].location.x; + const coordZ = worldData.world.chunks[x].location.z; + if (worldData.world.chunks[x].chunkFile != null) { + this.getChunkFile(worldData.world.chunks[x]._id).then((data) => { + this.loadSingleChunk(data, coordX, coordZ); + }); + } else { + const geometry = new THREE.BoxGeometry( + this.chunkSizeX - 1, + 0, + this.chunkSizeX - 1 + ); + const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); + const cube = new THREE.Mesh(geometry, material); + cube.position.set(coordX, 0, coordZ); + let group = new THREE.Group(); + group.add(cube); + this.scene.add(group); + this.models.push(group); // add each cube to the array + const length = this.worldData.world.chunks.length; + this.loadedChunks.set(coordX + coordZ * length, this.loadedCount++); + } + } + } + + deleteComment(event: string) { + this.api.deleteComment(event).subscribe((data) => { + this.getComments(0, this.commentLimit); + }); + } + newComment(event: any) { + this.api + .postComment( + this.worldId, + this.x, + this.z, + this.user.userId, + event.comment, + event.rating + ) + .subscribe({ + next: (data) => { + this.getComments(0, this.commentLimit); + this.commentPage = 0; + }, + error: (err) => { + this.error = `ERROR: ${err.status} ${err.error.error}`; + }, + }); + } + getComments(page: number, limit: number) { + this.commentPage = page; + this.api.getComments(this.worldId, this.x, this.z, page, limit).subscribe({ + next: (value) => { + this.comments = value; + }, + error: (err) => { + console.error(err); + }, + }); + } + + public onClick(event: MouseEvent): void { + const canvasBounds = this.canvas.getBoundingClientRect(); + // calculate mouse position in normalized device coordinates + // (-1 to +1) for both components + this.mouse.x = + ((event.clientX - canvasBounds.left) / this.canvas.width) * 2 - 1; + this.mouse.y = + -((event.clientY - canvasBounds.top) / this.canvas.height) * 2 + 1; + // update the picking ray with the camera and mouse position + this.raycaster.setFromCamera(this.mouse, this.camera); + // calculate objects intersecting the picking ray + const intersects = this.raycaster.intersectObjects(this.models, true); + + for (let i = 0; i < intersects.length; i++) { + // perform the desired action on the clicked cube(s) + //claim the cube by sending an api request to the server + let model = intersects[i].object; + const position = model.getWorldPosition(new THREE.Vector3()); + const numberX = Math.round(position.x / this.chunkSizeX); + const numberZ = Math.round(position.z / this.chunkSizeX); + this.x = numberX * this.chunkSizeX; + this.z = numberZ * this.chunkSizeX; + const length = this.worldData.world.chunks.length; + const arrayPosition = this.worldData.world.chunks.findIndex( + (chunk: any) => { + return chunk.location.x === this.x && chunk.location.z === this.z; + } + ); + this.chunkId = this.worldData.world.chunks[arrayPosition]._id; + //claim section + if (this.worldData.world.chunks[arrayPosition].claimedBy === null) { + document.querySelector('app-chunk-form')?.classList.remove('hidden'); + } else { + document.querySelector('app-chunk-form')?.classList.add('hidden'); + } + // comment section + if (this.worldData.world.chunks[arrayPosition].chunkFile != null) { + this.getComments(0, 10); + document + .querySelector('.comment-form-container') + ?.classList.remove('hidden'); + document + .querySelector('.comment-containers-container') + ?.classList.remove('hidden'); + } else { + document + .querySelector('.comment-form-container') + ?.classList.add('hidden'); + document + .querySelector('.comment-containers-container') + ?.classList.add('hidden'); + } + + //upload section + if ( + this.worldData.world.chunks[arrayPosition].claimedBy === + this.user.userId + ) { + document.querySelector('app-upload-form')?.classList.remove('hidden'); + } else { + document.querySelector('app-upload-form')?.classList.add('hidden'); + } + + break; + } + } + + public animate(): void { + this.controls.update(); + this.raycaster.setFromCamera(this.mouse, this.camera); + this.renderer.setSize(this.canvas.width, this.canvas.height); + this.renderer.clear(); + this.renderer.render(this.scene, this.camera); + requestAnimationFrame(this.animate.bind(this)); + } + + ngOnInit(): void { + forkJoin([ + this.api.getWorld(this.worldId), + this.api.getMe(), + this.liveWorld.connect(this.worldId), + ]) + .pipe( + tap((data) => { + this.onInitReplay.next(data); + }), + take(1) + ) + .subscribe(); + } + + ngAfterViewInit() { + this.canvas = document.getElementById('canvas') as HTMLCanvasElement; + this.resizeCanvasToDisplaySize(this.canvas); + + this.scene = new THREE.Scene(); + this.camera = new THREE.PerspectiveCamera( + 75, + this.canvas.width / this.canvas.height, + 0.1, + 1000 + ); + this.renderer = new THREE.WebGLRenderer({ + canvas: document.getElementById('canvas') as HTMLCanvasElement, + }); + + this.renderer.setSize(this.canvas.width, this.canvas.height); + this.controls = new OrbitControls(this.camera, this.renderer.domElement); + this.loader = new GLTFLoader(); + this.raycaster = new THREE.Raycaster(); + this.mouse = new THREE.Vector2(); + this.models = []; + this.loadedChunks = new Map(); + this.loadedCount = 0; + this.ambientLight = new THREE.AmbientLight(0x404040); + this.scene.add(this.ambientLight); + this.camera.position.y = 10; + this.camera.position.z = 10; + this.camera.position.x = 10; + + document + .getElementById('canvas') + ?.addEventListener('click', this.onClick.bind(this), false); + window.addEventListener('resize', this.onWindowResize.bind(this), false); + requestAnimationFrame(this.animate.bind(this)); + + this.onInitReplay.subscribe((data) => { + this.worldData = data[0]; + this.chunkSizeX = this.worldData.world.chunkSize.x; + this.user = data[1]; + this.userId = this.user.userId; + + const liveWorldData = this.liveWorld.getWorldData(); + if (liveWorldData) { + this.worldData.world.chunks = liveWorldData.chunks; + } + this.loadChunks(this.worldData); + + this.liveWorld.onWorldChange((ops: any) => { + const newWorldData = this.liveWorld.getWorldData(); + this.worldData.world.chunks = newWorldData.chunks; + const chunkIndex = ops[0].p[1]; + if (ops[0].p[2] === 'chunkFile') { + const coordX = this.worldData.world.chunks[chunkIndex].location.x; + const coordZ = this.worldData.world.chunks[chunkIndex].location.z; + this.getChunkFile(this.worldData.world.chunks[chunkIndex]._id).then( + (data) => { + this.loadSingleChunk(data, coordX, coordZ, false); + } + ); + } + }); + }); + } + + ngOnDestroy(): void { + //disconnect from the live world + this.liveWorld.disconnect(); + } +} diff --git a/3dworld/src/app/component/worlddiv/worlddiv.component.html b/3dworld/src/app/component/worlddiv/worlddiv.component.html new file mode 100644 index 00000000..cdf70c84 --- /dev/null +++ b/3dworld/src/app/component/worlddiv/worlddiv.component.html @@ -0,0 +1,14 @@ +
+
+
+ {{ world.name }} +
+
Description: {{ world.description }}
+
Rules: {{ world.rules }}
+
+ +
+
+
diff --git a/3dworld/src/app/component/worlddiv/worlddiv.component.scss b/3dworld/src/app/component/worlddiv/worlddiv.component.scss new file mode 100644 index 00000000..86913c37 --- /dev/null +++ b/3dworld/src/app/component/worlddiv/worlddiv.component.scss @@ -0,0 +1,12 @@ +.world-title { + font-size: 36px; + font-weight: bold; +} + +.world-content { + font-size: 16px; +} + +button { + margin: 10px 0px 0px 0px; +} diff --git a/3dworld/src/app/component/worlddiv/worlddiv.component.spec.ts b/3dworld/src/app/component/worlddiv/worlddiv.component.spec.ts new file mode 100644 index 00000000..503b859d --- /dev/null +++ b/3dworld/src/app/component/worlddiv/worlddiv.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WorlddivComponent } from './worlddiv.component'; + +describe('WorlddivComponent', () => { + let component: WorlddivComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [WorlddivComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(WorlddivComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/component/worlddiv/worlddiv.component.ts b/3dworld/src/app/component/worlddiv/worlddiv.component.ts new file mode 100644 index 00000000..b9c92c63 --- /dev/null +++ b/3dworld/src/app/component/worlddiv/worlddiv.component.ts @@ -0,0 +1,18 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { ActivatedRoute, Router, ParamMap } from '@angular/router'; + +@Component({ + selector: 'app-worlddiv', + templateUrl: './worlddiv.component.html', + styleUrls: ['./worlddiv.component.scss'], +}) +export class WorlddivComponent implements OnInit { + @Input() world!: any; + ngOnInit(): void {} + + constructor(private route: Router) {} + + visitWorld(worldId: string) { + this.route.navigate(['world-view'], { queryParams: { worldId: worldId } }); + } +} diff --git a/3dworld/src/app/guards/auth0.guard.spec.ts b/3dworld/src/app/guards/auth0.guard.spec.ts new file mode 100644 index 00000000..3c70711d --- /dev/null +++ b/3dworld/src/app/guards/auth0.guard.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { Auth0Guard } from './auth0.guard'; + +describe('Auth0Guard', () => { + let guard: Auth0Guard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(Auth0Guard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/guards/auth0.guard.ts b/3dworld/src/app/guards/auth0.guard.ts new file mode 100644 index 00000000..74975e6a --- /dev/null +++ b/3dworld/src/app/guards/auth0.guard.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + CanActivate, + RouterStateSnapshot, + UrlTree, +} from '@angular/router'; +import { AuthService } from '@auth0/auth0-angular'; +import { Observable } from 'rxjs'; +import { ApiService } from '../services/api.service'; + +@Injectable({ + providedIn: 'root', +}) +export class Auth0Guard implements CanActivate { + constructor(public auth: AuthService, private api: ApiService) {} + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): + | Observable + | Promise + | boolean + | UrlTree { + return new Promise((res) => { + this.auth.isAuthenticated$.subscribe((data) => { + if (data === true) { + res(true); + } else { + this.api.getMe().subscribe({ + next: (data) => { + res(false); + }, + error: (err) => { + res(false); + }, + }); + } + }); + }); + //return this.auth.isAuthenticated$; + } +} diff --git a/3dworld/src/app/guards/session.guard.spec.ts b/3dworld/src/app/guards/session.guard.spec.ts new file mode 100644 index 00000000..750ec2ee --- /dev/null +++ b/3dworld/src/app/guards/session.guard.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { SessionGuard } from './session.guard'; + +describe('SessionGuard', () => { + let guard: SessionGuard; + + beforeEach(() => { + TestBed.configureTestingModule({}); + guard = TestBed.inject(SessionGuard); + }); + + it('should be created', () => { + expect(guard).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/guards/session.guard.ts b/3dworld/src/app/guards/session.guard.ts new file mode 100644 index 00000000..15d46327 --- /dev/null +++ b/3dworld/src/app/guards/session.guard.ts @@ -0,0 +1,38 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + CanActivate, + RouterStateSnapshot, + UrlTree, +} from '@angular/router'; +import { AuthService } from '@auth0/auth0-angular'; +import { Observable } from 'rxjs'; +import { ApiService } from '../services/api.service'; + +@Injectable({ + providedIn: 'root', +}) +export class SessionGuard implements CanActivate { + constructor(private api: ApiService, public auth: AuthService) {} + canActivate( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): + | Observable + | Promise + | boolean + | UrlTree { + return new Promise((res) => { + this.api.getMe().subscribe({ + next: (value) => { + res(true); + }, + error: (err) => { + this.auth.logout().subscribe((data) => { + res(false); + }); + }, + }); + }); + } +} diff --git a/3dworld/src/app/pages/credits/credits.component.html b/3dworld/src/app/pages/credits/credits.component.html new file mode 100644 index 00000000..edf45f36 --- /dev/null +++ b/3dworld/src/app/pages/credits/credits.component.html @@ -0,0 +1,37 @@ +

+ buildverse.live credits: ChatGPT, Stackoverflow, ThreeJS documentation +

+ SketchFab Models: +

+ "One Piece - Monkey D. Luffy" (https://skfb.ly/68qpR) by BSEV5 is licensed + under Creative Commons Attribution + (http://creativecommons.org/licenses/by/4.0/). +
+ "TrashBot" (https://skfb.ly/oFAyS) by D3mtt is licensed under Creative Commons + Attribution (http://creativecommons.org/licenses/by/4.0/). +
+ "Leaning tower of Pisa" (https://skfb.ly/6ZCFH) by Aglaiapoulida is licensed + under Creative Commons Attribution + (http://creativecommons.org/licenses/by/4.0/). +
+ "Frog" (https://skfb.ly/6wIvC) by gooseg489 is licensed under Creative Commons + Attribution (http://creativecommons.org/licenses/by/4.0/). +
+ "Shiba" (https://skfb.ly/6WxVW) by zixisun02 is licensed under Creative + Commons Attribution (http://creativecommons.org/licenses/by/4.0/). +
+ "Shenron (Dragon Ball)" (https://skfb.ly/6GwJL) by Yanez Designs is licensed + under Creative Commons Attribution + (http://creativecommons.org/licenses/by/4.0/). +
+ "China Architecture" (https://skfb.ly/o6KzO) by elbertzhou2018 is licensed + under Creative Commons Attribution + (http://creativecommons.org/licenses/by/4.0/). +
+ "Chinese Architecture" (https://skfb.ly/IGpu) by tw.sharon.0714 is licensed + under Creative Commons Attribution + (http://creativecommons.org/licenses/by/4.0/). +

+ Disclaimer: Only glTF zip files that are small will work well for loading + quickly into the world. Larger files will take longer to load. +

diff --git a/3dworld/src/app/pages/credits/credits.component.scss b/3dworld/src/app/pages/credits/credits.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/pages/credits/credits.component.spec.ts b/3dworld/src/app/pages/credits/credits.component.spec.ts new file mode 100644 index 00000000..220b30c8 --- /dev/null +++ b/3dworld/src/app/pages/credits/credits.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreditsComponent } from './credits.component'; + +describe('CreditsComponent', () => { + let component: CreditsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CreditsComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CreditsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/credits/credits.component.ts b/3dworld/src/app/pages/credits/credits.component.ts new file mode 100644 index 00000000..f0005a75 --- /dev/null +++ b/3dworld/src/app/pages/credits/credits.component.ts @@ -0,0 +1,8 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-credits', + templateUrl: './credits.component.html', + styleUrls: ['./credits.component.scss'], +}) +export class CreditsComponent {} diff --git a/3dworld/src/app/pages/index/index.component.html b/3dworld/src/app/pages/index/index.component.html new file mode 100644 index 00000000..61e8af73 --- /dev/null +++ b/3dworld/src/app/pages/index/index.component.html @@ -0,0 +1,13 @@ +

Welcome to Buildverse!

+

+ BuildVerse is a 3D sandbox platform that allows players to add their creations + into a shared virtual world. Players can claim a plot of land and make changes + to it using a 3D modeling software of their choice, then submit this plot to + be displayed among other players' creations. +

+
+

Login/Signup to get started!

+
+

Created by Project3DWorld Team

+ Credits +
diff --git a/3dworld/src/app/pages/index/index.component.scss b/3dworld/src/app/pages/index/index.component.scss new file mode 100644 index 00000000..fcb93401 --- /dev/null +++ b/3dworld/src/app/pages/index/index.component.scss @@ -0,0 +1,16 @@ +.text { + text-align: center; +} + +p { + font-size: 24px; +} + +img { + margin: 20px; + width: 50%; +} +.img-container { + display: flex; + justify-content: center; +} diff --git a/3dworld/src/app/pages/index/index.component.spec.ts b/3dworld/src/app/pages/index/index.component.spec.ts new file mode 100644 index 00000000..13cc4261 --- /dev/null +++ b/3dworld/src/app/pages/index/index.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { IndexComponent } from './index.component'; + +describe('IndexComponent', () => { + let component: IndexComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [IndexComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(IndexComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/index/index.component.ts b/3dworld/src/app/pages/index/index.component.ts new file mode 100644 index 00000000..8058c12f --- /dev/null +++ b/3dworld/src/app/pages/index/index.component.ts @@ -0,0 +1,63 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthService } from '@auth0/auth0-angular'; +import { Auth0Client } from '@auth0/auth0-spa-js'; +import { ApiService } from 'src/app/services/api.service'; +import { Location } from '@angular/common'; +import { Route, Router } from '@angular/router'; +import { NotificationService } from 'src/app/services/notification.service'; +@Component({ + selector: 'app-index', + templateUrl: './index.component.html', + styleUrls: ['./index.component.scss'], +}) +export class IndexComponent implements OnInit { + constructor( + public auth: AuthService, + private api: ApiService, + private location: Location, + private router: Router, + private notification: NotificationService + ) {} + ngOnInit(): void { + this.api.getMe().subscribe({ + next: (data) => { + this.auth.isAuthenticated$.subscribe((data) => { + if (data === false) { + this.api.signOut().subscribe(); + } else { + this.notification.connect(); + } + }); + }, + error: (err) => { + if (err.status === 401) { + this.auth.isAuthenticated$.subscribe((data) => { + if (data === true) { + this.auth.user$.subscribe((data) => { + this.api.signIn(JSON.stringify(data, null, 2)).subscribe({ + next: (value) => {}, + error: (value) => { + this.api.signUp(JSON.stringify(data, null, 2)).subscribe({ + next: (value) => { + this.api + .signIn(JSON.stringify(data, null, 2)) + .subscribe(); + }, + error: (err) => { + console.error(err); + }, + }); + }, + }); + }); + } + }); + } + }, + }); + } + + goCredits(): void { + this.router.navigateByUrl('credits'); + } +} diff --git a/3dworld/src/app/pages/profile/profile.component.html b/3dworld/src/app/pages/profile/profile.component.html new file mode 100644 index 00000000..499aade0 --- /dev/null +++ b/3dworld/src/app/pages/profile/profile.component.html @@ -0,0 +1,77 @@ +
+
+
+

Welcome "{{ me.displayName }}"

+ +
+ +

Change Display Name

+
+ + +
+ +

Notifications

+
+
+ +
+
+ + +
+
+
+
+

You have claims in these worlds:

+
+ +
+
+ + +
+
+
diff --git a/3dworld/src/app/pages/profile/profile.component.scss b/3dworld/src/app/pages/profile/profile.component.scss new file mode 100644 index 00000000..c7daa114 --- /dev/null +++ b/3dworld/src/app/pages/profile/profile.component.scss @@ -0,0 +1,24 @@ +.world { + border-radius: 10px; + font-size: 20px; + color: white; + background: #24252a; + padding: 10px 20px 10px 20px; + margin: 10px; +} + +#change-display-name-form input { + margin: 0px 10px; + margin-top: -50px; + font-size: 16px; + padding: 3px; +} + +.message-content { + font-size: 24px; +} + +.center { + align-items: center; + text-align: center; +} diff --git a/3dworld/src/app/pages/profile/profile.component.spec.ts b/3dworld/src/app/pages/profile/profile.component.spec.ts new file mode 100644 index 00000000..b8b42769 --- /dev/null +++ b/3dworld/src/app/pages/profile/profile.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProfileComponent } from './profile.component'; + +describe('ProfileComponent', () => { + let component: ProfileComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ProfileComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(ProfileComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/profile/profile.component.ts b/3dworld/src/app/pages/profile/profile.component.ts new file mode 100644 index 00000000..16cb8613 --- /dev/null +++ b/3dworld/src/app/pages/profile/profile.component.ts @@ -0,0 +1,74 @@ +import { Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { AuthService } from '@auth0/auth0-angular'; +import { lastValueFrom } from 'rxjs'; +import { ApiService } from 'src/app/services/api.service'; + +@Component({ + selector: 'app-profile', + templateUrl: './profile.component.html', + styleUrls: ['./profile.component.scss'], +}) +export class ProfileComponent { + page: number = 0; + limit: number = 10; + user: any; + me: any = {}; + claims: any = []; + notifications: any = []; + notifPage: number = 0; + notifLimit: number = 10; + nameForm: FormGroup; + + constructor( + public auth: AuthService, + private api: ApiService, + private fb: FormBuilder + ) { + this.user = {}; + this.nameForm = this.fb.group({ + name: ['', Validators.required], + }); + } + + ngOnInit() { + this.auth.user$.subscribe((success) => { + this.user = success; + this.api.getMe().subscribe((data) => { + this.me = data; + this.nameForm.setValue({ name: this.me.displayName }); + }); + }); + + lastValueFrom(this.api.getMyClaims(0, this.limit)).then((data) => { + this.claims = data; + }); + lastValueFrom(this.api.getNotifications(0, this.limit)).then((data) => { + this.notifications = data; + }); + } + + getClaims(page: number, limit: number) { + this.api.getMyClaims(page, limit).subscribe((data) => { + this.claims = data; + this.page = page; + }); + } + + getNotifications(page: number, limit: number) { + this.api.getNotifications(page, limit).subscribe((data) => { + this.notifications = data; + this.notifPage = page; + }); + } + + changeDisplayName() { + this.api.changeDisplayName(this.nameForm.value.name).subscribe({ + next: (data: any) => { + this.me.displayName = data.displayName; + this.nameForm.setValue({ name: this.me.displayName }); + }, + error: (err) => console.error(err), + }); + } +} diff --git a/3dworld/src/app/pages/sign-in/sign-in.component.html b/3dworld/src/app/pages/sign-in/sign-in.component.html new file mode 100644 index 00000000..371a36b7 --- /dev/null +++ b/3dworld/src/app/pages/sign-in/sign-in.component.html @@ -0,0 +1 @@ +

sign-in works!

diff --git a/3dworld/src/app/pages/sign-in/sign-in.component.scss b/3dworld/src/app/pages/sign-in/sign-in.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/pages/sign-in/sign-in.component.spec.ts b/3dworld/src/app/pages/sign-in/sign-in.component.spec.ts new file mode 100644 index 00000000..73a65f1a --- /dev/null +++ b/3dworld/src/app/pages/sign-in/sign-in.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SignInComponent } from './sign-in.component'; + +describe('SignInComponent', () => { + let component: SignInComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SignInComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(SignInComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/sign-in/sign-in.component.ts b/3dworld/src/app/pages/sign-in/sign-in.component.ts new file mode 100644 index 00000000..5dbdb4de --- /dev/null +++ b/3dworld/src/app/pages/sign-in/sign-in.component.ts @@ -0,0 +1,37 @@ +import { Component, OnInit } from '@angular/core'; +import { Route, Router } from '@angular/router'; +import { AuthService } from '@auth0/auth0-angular'; +import { ApiService } from 'src/app/services/api.service'; +import { NotificationService } from 'src/app/services/notification.service'; +@Component({ + selector: 'app-sign-in', + templateUrl: './sign-in.component.html', + styleUrls: ['./sign-in.component.scss'], +}) +export class SignInComponent implements OnInit { + profileJson: string = ''; + + constructor( + private api: ApiService, + public auth: AuthService, + private router: Router, + private notification: NotificationService + ) {} + + ngOnInit(): void { + this.auth.user$.subscribe( + (profile) => ( + (this.profileJson = JSON.stringify(profile, null, 2)), + this.api.signIn(this.profileJson).subscribe({ + next: (value) => { + this.notification.connect(); + this.router.navigateByUrl(''); + }, + error: (err) => { + this.router.navigateByUrl('sign-up'); + }, + }) + ) + ); + } +} diff --git a/3dworld/src/app/pages/sign-up/sign-up.component.html b/3dworld/src/app/pages/sign-up/sign-up.component.html new file mode 100644 index 00000000..ea8ad568 --- /dev/null +++ b/3dworld/src/app/pages/sign-up/sign-up.component.html @@ -0,0 +1,19 @@ +
+
Choose a displayName
+ + +

displayName: {{ nameForm.value.name }}

+

Form Status: {{ nameForm.status }}

+

Sign Up Status: {{ signUpStatus }}

+
diff --git a/3dworld/src/app/pages/sign-up/sign-up.component.scss b/3dworld/src/app/pages/sign-up/sign-up.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/pages/sign-up/sign-up.component.spec.ts b/3dworld/src/app/pages/sign-up/sign-up.component.spec.ts new file mode 100644 index 00000000..b42a0447 --- /dev/null +++ b/3dworld/src/app/pages/sign-up/sign-up.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SignUpComponent } from './sign-up.component'; + +describe('SignUpComponent', () => { + let component: SignUpComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SignUpComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(SignUpComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/sign-up/sign-up.component.ts b/3dworld/src/app/pages/sign-up/sign-up.component.ts new file mode 100644 index 00000000..6a0c836d --- /dev/null +++ b/3dworld/src/app/pages/sign-up/sign-up.component.ts @@ -0,0 +1,44 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ApiRouteDefinition, AuthService } from '@auth0/auth0-angular'; +import { ApiService } from 'src/app/services/api.service'; +import { Router } from '@angular/router'; +@Component({ + selector: 'app-sign-up', + templateUrl: './sign-up.component.html', + styleUrls: ['./sign-up.component.scss'], +}) +export class SignUpComponent implements OnInit { + signUpStatus: string = `haven't tried yet`; + nameForm: FormGroup; + @Output() newName = new EventEmitter(); + profileJson: string = ''; + constructor( + private fb: FormBuilder, + private auth: AuthService, + private api: ApiService, + private router: Router + ) { + this.nameForm = this.fb.group({ + /** + * In Angular we can easily define a form field with validators, without installing 9 billion more + * packages. + * + * Add your fields here + */ + name: ['', Validators.required], + }); + } + + ngOnInit(): void { + this.auth.user$.subscribe( + (profile) => (this.profileJson = JSON.stringify(profile, null, 2)) + ); + } + + postMessage() { + this.newName.emit(this.nameForm.value.name); + if (this.profileJson.length !== 0) { + } + } +} diff --git a/3dworld/src/app/pages/world-view/world-view.component.html b/3dworld/src/app/pages/world-view/world-view.component.html new file mode 100644 index 00000000..67daeb1c --- /dev/null +++ b/3dworld/src/app/pages/world-view/world-view.component.html @@ -0,0 +1 @@ + diff --git a/3dworld/src/app/pages/world-view/world-view.component.scss b/3dworld/src/app/pages/world-view/world-view.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/app/pages/world-view/world-view.component.spec.ts b/3dworld/src/app/pages/world-view/world-view.component.spec.ts new file mode 100644 index 00000000..ed2ed3fc --- /dev/null +++ b/3dworld/src/app/pages/world-view/world-view.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WorldViewComponent } from './world-view.component'; + +describe('WorldViewComponent', () => { + let component: WorldViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [WorldViewComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(WorldViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/world-view/world-view.component.ts b/3dworld/src/app/pages/world-view/world-view.component.ts new file mode 100644 index 00000000..8a7ca495 --- /dev/null +++ b/3dworld/src/app/pages/world-view/world-view.component.ts @@ -0,0 +1,18 @@ +import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'app-world-view', + templateUrl: './world-view.component.html', + styleUrls: ['./world-view.component.scss'], +}) +export class WorldViewComponent implements OnInit { + constructor(private route: ActivatedRoute) {} + worldId!: string; + + ngOnInit(): void { + this.route.queryParams.subscribe((params) => { + this.worldId = params['worldId']; + }); + } +} diff --git a/3dworld/src/app/pages/worlds/worlds.component.html b/3dworld/src/app/pages/worlds/worlds.component.html new file mode 100644 index 00000000..7500f2b1 --- /dev/null +++ b/3dworld/src/app/pages/worlds/worlds.component.html @@ -0,0 +1,8 @@ +
+
+ +
+
diff --git a/3dworld/src/app/pages/worlds/worlds.component.scss b/3dworld/src/app/pages/worlds/worlds.component.scss new file mode 100644 index 00000000..3c0b8b79 --- /dev/null +++ b/3dworld/src/app/pages/worlds/worlds.component.scss @@ -0,0 +1,14 @@ +.world { + border-radius: 10px; + font-size: 20px; + color: white; + padding: 10px 20px 10px 20px; + margin: 10px; + text-align: center; + align-items: center; + background: #24252a; +} + +.message-content { + font-size: 24px; +} diff --git a/3dworld/src/app/pages/worlds/worlds.component.spec.ts b/3dworld/src/app/pages/worlds/worlds.component.spec.ts new file mode 100644 index 00000000..e203fe81 --- /dev/null +++ b/3dworld/src/app/pages/worlds/worlds.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WorldsComponent } from './worlds.component'; + +describe('WorldsComponent', () => { + let component: WorldsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [WorldsComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(WorldsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/pages/worlds/worlds.component.ts b/3dworld/src/app/pages/worlds/worlds.component.ts new file mode 100644 index 00000000..ed95a8c1 --- /dev/null +++ b/3dworld/src/app/pages/worlds/worlds.component.ts @@ -0,0 +1,18 @@ +import { Component } from '@angular/core'; +import { ApiService } from 'src/app/services/api.service'; + +@Component({ + selector: 'app-worlds', + templateUrl: './worlds.component.html', + styleUrls: ['./worlds.component.scss'], +}) +export class WorldsComponent { + worlds: any[] = []; + + constructor(private api: ApiService) {} + ngOnInit() { + this.api.getAllWorlds().subscribe((response) => { + this.worlds = Object.values(response)[0]; + }); + } +} diff --git a/3dworld/src/app/services/api.service.spec.ts b/3dworld/src/app/services/api.service.spec.ts new file mode 100644 index 00000000..c0310ae6 --- /dev/null +++ b/3dworld/src/app/services/api.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ApiService } from './api.service'; + +describe('ApiService', () => { + let service: ApiService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ApiService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/services/api.service.ts b/3dworld/src/app/services/api.service.ts new file mode 100644 index 00000000..3e742fb4 --- /dev/null +++ b/3dworld/src/app/services/api.service.ts @@ -0,0 +1,202 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { environment } from '../../environments/environment'; +import { Observable, Subscription } from 'rxjs'; +@Injectable({ + providedIn: 'root', +}) +export class ApiService { + endpoint = environment.apiEndpoint; + constructor(private http: HttpClient) {} + + signIn(profile: string) { + const profileJson = JSON.parse(profile); + if (profileJson?.sub) { + return this.http.post( + this.endpoint + '/api/users/signin', + { + sub: profileJson.sub, + }, + { withCredentials: true } + ); + } else { + return new Observable((observer) => { + observer.error(new Error('Something went wrong!')); + }); + } + } + + signUp(profile: string) { + const profileJson = JSON.parse(profile); + if (profileJson?.sub) { + return this.http.post( + this.endpoint + '/api/users/signup', + { + sub: profileJson.sub, + displayName: profileJson.name, + email: profileJson.email, + }, + { withCredentials: true } + ); + } else { + return new Observable((observer) => { + observer.error(new Error('Something went wrong!')); + }); + } + } + + signOut() { + return this.http.get(this.endpoint + '/api/users/signout', { + withCredentials: true, + }); + } + + getMe() { + return this.http.get(this.endpoint + '/api/users/me', { + withCredentials: true, + }); + } + + getMyClaims(page: number, limit: number) { + return this.http.get( + this.endpoint + `/api/users/myClaims/page=${page}&limit=${limit}`, + { + withCredentials: true, + } + ); + } + + changeDisplayName(name: string) { + return this.http.patch( + this.endpoint + `/api/users/displayName`, + { + displayName: name, + }, + { withCredentials: true } + ); + } + + //postComment + postComment( + worldId: string, + x: number, + z: number, + author: string, + content: string, + rating: number + ) { + return this.http.post( + this.endpoint + `/api/comments/`, + { + worldId: worldId, + author: author, + x: x, + z: z, + content: content, + rating: rating, + }, + { withCredentials: true } + ); + } + + getComments( + worldId: string, + x: number, + z: number, + page: number, + limit: number + ) { + return this.http.get( + this.endpoint + + `/api/comments/worldId=${worldId}&x=${x}&z=${z}&page=${page}&limit=${limit}`, + { withCredentials: true } + ); + } + + deleteComment(id: string) { + return this.http.delete(this.endpoint + `/api/comments/${id}`, { + withCredentials: true, + }); + } + //world apis + + //claim a chunk for a user + claimChunk(worldId: string, chunkId: string) { + return this.http.patch( + this.endpoint + '/api/worlds/' + worldId + '/chunks/' + chunkId, + {}, + { withCredentials: true } + ); + } + + getChunkFile(worldId: string, chunkId: string) { + return this.http.get( + this.endpoint + '/api/worlds/' + worldId + '/chunks/' + chunkId + '/file', + { withCredentials: true, responseType: 'blob' } + ); + } + + //get a world by id + getWorld(worldId: string) { + return this.http.get(this.endpoint + '/api/worlds/' + worldId, { + withCredentials: true, + }); + } + + //get all worlds + getAllWorlds() { + return this.http.get(this.endpoint + '/api/worlds', { + withCredentials: true, + }); + } + + //create a new world + createWorld( + worldName: string, + description: string, + rules: string, + chunksize: number, + numberOfChunks: number + ) { + let chunks = []; + + for (let i = 0; i < numberOfChunks; i++) { + for (let j = 0; j < numberOfChunks; j++) { + chunks.push({ x: i * chunksize, z: j * chunksize }); + } + } + + return this.http.post( + this.endpoint + '/api/worlds', + { + name: worldName, + chunkSize: { x: chunksize, y: chunksize, z: chunksize }, + description: description, + rules: rules, + chunks: chunks, + }, + { withCredentials: true } + ); + } + + //upload a gltf model to a chunk + //check how to send the file to backend + uploadModel(worldId: string, chunkId: string, model: File) { + let formData = new FormData(); + formData.append('chunkFile', model); + return this.http.post( + this.endpoint + '/api/worlds/' + worldId + '/chunks/' + chunkId + '/file', + formData, + { withCredentials: true } + ); + } + + getNotifications(page: number, limit: number) { + return this.http.get( + this.endpoint + `/api/notifications/page=${page}&limit=${limit}`, + { + withCredentials: true, + } + ); + } +} diff --git a/3dworld/src/app/services/liveworld.service.spec.ts b/3dworld/src/app/services/liveworld.service.spec.ts new file mode 100644 index 00000000..1deefd5e --- /dev/null +++ b/3dworld/src/app/services/liveworld.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { LiveWorldService } from './liveworld.service'; + +describe('LiveworldService', () => { + let service: LiveWorldService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(LiveWorldService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/services/liveworld.service.ts b/3dworld/src/app/services/liveworld.service.ts new file mode 100644 index 00000000..76d117d0 --- /dev/null +++ b/3dworld/src/app/services/liveworld.service.ts @@ -0,0 +1,142 @@ +import { Injectable } from '@angular/core'; +import { environment } from '../../environments/environment'; + +/** + * Example world data: + * { + * chunks: [ + * { + * _id: 'chunkid', + * upvotes: 0, + * downvotes: 0, + * chunkFile: 'fileid', + * claimedBy: 'userid' + * }, + * ... + * ] + * } + */ + +@Injectable({ + providedIn: 'root', +}) +export class LiveWorldService { + static Reaction = { + upvote: 'upvote', + downvote: 'downvote', + }; + private sharedb; + private worldDoc: any; + private socket: any; + private opQueue: any[] = []; + + constructor() { + this.sharedb = require('sharedb/lib/client'); + } + + async connect(worldId: string) { + /** + * Connect to the live world at url and id. Returns a promise that resolves + * when the connection is established. + */ + const url = environment.wsEndpoint + '/api/worlds/' + worldId + '/live'; + if (this.socket) { + this.socket.close(); + } + this.socket = new WebSocket(url); + + return new Promise((resolve, reject) => { + // add listener event for when the server closes the connection due to an error + this.socket.addEventListener('close', (event: any) => { + if (event.code >= 4000) { + reject({ + code: event.code, + reason: event.reason, + }); + } + }); + const connection = new this.sharedb.Connection(this.socket); + this.worldDoc = connection.get('live_worlds', worldId); + this.worldDoc.subscribe((err: any) => { + if (err) { + reject(err); + } else { + this.opQueue.forEach((op) => { + this.worldDoc.submitOp(op); + }); + this.opQueue = []; + resolve(); + } + }); + }); + } + + disconnect() { + if (this.socket) { + this.socket.close(); + this.worldDoc = null; + } + } + + getWorldData() { + /** + * Returns the current world data. Returns null if the world is not connected. + */ + if (!this.worldDoc) { + return null; + } + return this.worldDoc.data; + } + + addReaction(chunkId: string, reaction: any) { + /** + * Adds a reaction to the chunk with the given id. The reaction must be one of + * the values in LiveWorldService.Reaction. + */ + if (reaction !== 'upvote' && reaction !== 'downvote') { + return; + } + const chunkIndex = this.worldDoc.data.chunks.findIndex( + (chunk: any) => chunk._id === chunkId + ); + if (chunkIndex === -1) { + return; + } + this.submitOp({ p: ['chunks', chunkIndex, reaction], na: 1 }); + } + + removeReaction(chunkId: string, reaction: any) { + if (reaction !== 'upvote' && reaction !== 'downvote') { + return; + } + const chunkIndex = this.worldDoc.data.chunks.findIndex( + (chunk: any) => chunk._id === chunkId + ); + if (chunkIndex === -1) { + return; + } + this.submitOp({ p: ['chunks', chunkIndex, reaction], na: -1 }); + } + + private submitOp(op: any) { + if (this.worldDoc) { + this.worldDoc.submitOp(op); + } else { + this.opQueue.push(op); + } + } + + onWorldChange(callback: any) { + /** + * Registers a callback that is called whenever the world data changes. + * The callback is passed the `op` that was applied to the world. + * ie: callback({ p: ['chunks', 0, 'upvotes'], oi: 1 }) + */ + if (!this.worldDoc) { + return; + } + this.worldDoc.on('op', (op: any, source: any) => { + callback(op); + }); + } +} diff --git a/3dworld/src/app/services/notification.service.spec.ts b/3dworld/src/app/services/notification.service.spec.ts new file mode 100644 index 00000000..c4f2cd67 --- /dev/null +++ b/3dworld/src/app/services/notification.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { NotificationService } from './notification.service'; + +describe('NotificationService', () => { + let service: NotificationService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(NotificationService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/3dworld/src/app/services/notification.service.ts b/3dworld/src/app/services/notification.service.ts new file mode 100644 index 00000000..ff8aed26 --- /dev/null +++ b/3dworld/src/app/services/notification.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { Socket } from 'ngx-socket-io'; + +@Injectable({ + providedIn: 'root', +}) +export class NotificationService { + constructor(private socketio: Socket) {} + + connect() { + this.socketio.connect(); + } + + getListener() { + return this.socketio.fromEvent('notification'); + } +} diff --git a/3dworld/src/assets/.gitkeep b/3dworld/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/3dworld/src/assets/demo.png b/3dworld/src/assets/demo.png new file mode 100644 index 0000000000000000000000000000000000000000..99261e0541ac430b9332a1225b360ddf056cd827 GIT binary patch literal 163412 zcmeFYg;QM1^FF+SdkF4M@WtH;k`N$Ba9A9II|N%Cf6Nv&;0>kN$liLq)R;)sYp_$QXUM(kfkKeb(z;f{kQ8O``^;S&E>c~stULv3 zT$$2`hK9|Vc-xgv<`|R@LgLL7;c*N|D3Atj6mq*Y{d&9WQI5Ks;t&1-ViW3XR}uyF z*DVpB5B?mK{HZP|e>l7JZbPYz_`mjv*0IG?O76e5E=2(S_+O{uj5>^k?!RX78d&&W zPsAq<(C1PeGWjwSxa$phB0PXyF`hPxQ{k6LPxW{tqS= zCf~tI&z?OK7Jh*sc)CAJ;QkV?{xl-?)8>ByBWti&{v_<(fF`LyKTq^9_&f55Luy4}+%PKqP|CU*jw z@^d22oH|xH4Y1`I)sTk(8DHE(5ZUm7{$GJaP~`7Rm^I~~gO8J*-u)iAU;!X8;1{e2 zh7{ka*_DQ(zO`t2(QhYrOR)+v^UbWENv?UX_pE?!7uy{*YyaD+Kz~iu3VI<#_XBReZK*ko8V|XFi_V7uJs;_0PyGP~wHKTWJZBdaED21A! zQzuvR99-v^ZHM#)}Y6I zU)y|A%rIz;uNI>a0u7Z8pat2{+3~)~1=0`RgkfPiZC`WC8Y;r4!qU_-JNZw5FA#rJ zE^y4Nq|u~-C}FSbr_i#neercLvM^m!5MQkjwdhj%ZtY~#^SEw+ILNG&;*)fHqW(|c zc|}kykIVX8#qRbj>-T@2lrt8sGzBztc>lWUDdJ=@GDf$rgN2?Ux7>c#@*lQ8fjz)wfbTwEvt!F?KZJutP+bt3&xewN6yrZ}^`c*4>Vk1Sic?dO}9K*WI(+ZY%z6VH5 zFH=PWJ-jR#ZF3g;2C&7I9ikjccfvJ4nwEug7sd6zeR_oium6>UB*3NMfEy z!j$o)p1qWt_*Ae%KG5-9J`cnyo`#lGp83*FXnm$v;AC{`feWm=>#+4+r#)t%1Zk2a zv0o_CD@gnv2q7u^m9p3MMM_Xq+ab@)GnTSB%*+30>~_6s@RoCY)z%Y|czXWF`h6sN zq<%}tQtrEQWPiqgYchQ+qoyox-9EFaWX9ZWkg;deXPcK2|;`BfJZH_eo@~bRa*a$Jy zb;<8dPGtv}Id_b^+$ynl+n~WIc4f<8I05|V40t2;YW`1=IZR%MU0|ZurhJBo{eLVnCCQd&| zsK}o-euf&GmiX!ZL^QQ%B(Qy-g^85w-*2p!J25w_&h`WhmeG!=tgmFJ=fJ^(fgDm8 z<=Mz{Mo?>^C@bGQ$)*4dYcOZn4MC=d$MInAWTX8UZVTEFK+L*qwej3%X9VfY;^h1N zLh1Tpi@2UDz1;_7DnH8Ykbx+bJKBFH4gSxrnDv2~q`%`CI_6nH(*_0zo)hy)Z#jP6 zAP<~?G?E$3#+F9xA>&uJ1RpHYUYub8#mDY1KiRF>E8CTu^{?7U0fSI!YADmdS=f;b zM7eGG@rxZ|`Xb?8mhPzKqSyG_15#%EqaV2iv!=Ufp9CNNf0QxGgphg3jW|PuXlj#0 zkXt{P*WRH+36;MGeMA}!FD!_;!FQ$}~TgemLzM_F1Q= zz|m2L0}8M3@~U;Ke&AN1HQG(Bz}+ZdztWQYcLD4i5eGxn`JGirw>c)7X7=7a2-jGY zxUcGNV;_oLd)R?oNT-gYQixCk7WEw${bgu#tlDXowN^|zi_c)eREy;1*_k&KvW9+y zd0U(UPe2)iDL9_jfal9PByjz2~p3WRrmc@SM#G$KVcs8j{jrI=Tcw+3ib9uUNWX zeY<}{74v{s;ZCGxJ>HJ7hKdL|(R6XkUa!NCeL}lE*tZVO+FNxzjZDb0q@Brz1r;BP z^xI0Qr(jlSO}v$!B%GNjs`eX=_QC9SWkva{$R^td?WSzvgR|e7&8f1kN%S28(&Qjm z=7BZPQ`ga2z#eOHjB`KpNYE@sc@{sa4q6MAoq11?JiGwAlbsWbFyZ;j`~~v;L$551 zEh)O*V9-D8lfVrPj0Yv{5qM-=94}HPIDbMJM)IA$bGH6Kj*T7{>pnLv7QfM1I)A8O zJO$y$l4U|YGyuqwPS0Wr42La(ihkOCc0I)V%>}%WS;BLFT~zsSVbOB+_>fT{*%UfB z;;?oaP)nGGwB-lt3r@$z^jyvWX@U5qkeyJ}kf-kQn{!ja0w(s!I{G6o_`PM{ zG!N7I2XX=>97RfrCc4cO(R@)OxEm;7V3tc?MW~(aO$I@;>qujZbE2dxk_b&BBZiID030v;mD@lJJB*je-`yRA>E~?N(q(?J0we#grv-q<=t9P5Ykb1 zZs(83A;oa#!h_QYF}yfVPtZNQq`#1RdQP@~IcWTrdo%2Kku<@%2;p*O#DOp{C$7ofCwKvcczJb4tgUcEMit`GAgy6)ml| z%R$el4s&cQT?{R69xUga)(FG(BM2-!ZbXjhsJ79{AUC|P>P0)`3#NhNv7Z={GGMWK zx4Q5qR+3PmP2hg(h#>R}-LX&D$J62>|UUS*W{Q1$CHGcKxJW?C0@Z+so+ z__+gsKP+>%`ga9%S!tOOdf7KV)RhYq0QkUi5^vkXY_EP18a@g;4F3#=_5_*vV9+r? zv)%7Y%`!MUWMUTmH>~JY3heB&h+@2U!H%4=MeA3C!UhcZwa(9{TNr5~N_a2TX~?x~ z!w8PhBA??yri=!BeMqDBC)le5fGJ#ZB*Z&dj2KEnK@?kPH8rd);QkrlDDr!KmLIz%xLbMnyDTR^INt2G(BaNkM%ix-#tV3<$DnLt9uvI$+gp3*K+{ zjqRBgl5Da8FoTWhMnCx>J&i8aOq-1ZNOJw|OH9AR65dgZP4q33J@r=zkJJnA;- z*8=PHmB(W$c{yV%YpOC1sFi{@H~I!?*Q}7Wh}f9Eei_=S%;1NZ4fD@`&Gdl!j=>w| zu73B3uVG3BHl50^P0^19!b4QoE75bE!hbAx|h_%-a}gan0Z)@@rUi`O|*qAFQV*#n-E>Gmd90(9D+=&jsv1%AOaSx+~iIIw3o^5 z?IbuAUKdcjsP#P+nGA5fpYPN8A0O|Si#}6%s}LxbB1Wr=B2F<+vQbRskR9I0YiGs6JZ8+yoY?wNj9*(F*jp~YthiRntm;8;7=4@s z9B>BF?WX5dch@r#=VbC?^iziE4pQ4FUjg`?R@|U2wRX4%o;Oot=PTR(0QX-1Jh`3( z5aUd47dlhi<;_c+@PGN!48kJ%{MV)ln;%G2YNcu+q}5MnHNBUtDyb)3}7T~Tku8GeaIRXJ=;o+;($UgBe&>Iv+vTEux=q2fw04{yimE}5p zJxJZW%h7PsF5$~mN#up=X#7E>9lrI_AUF%D!Ke;qzYo?-BZ-fD=fXH)RWEH#Ynxy9 z)f~)%=2Gb=sNdkhEkeB!1?vcnkHOR9X_V<-%Lsgzv0G}rG-F)dg8zX!{P@GQ$-B&DhYmnYDAG&}v8o@HLPFO266jSG z6R~tbJnLT`4MuIy(b1|1`VyH(k}rbS{7B?3xGuP9q)7+@Jd31*Rk^M0vg0lLJ6Z7R z$}{c`8cbS*A`4Mc9*d_*@9fglFzxwAg@9pi`cXctG?aSZ9cZ=G*Wn5(Fv5>qWZW84 zWVWmJLdzKAc7g1*DtUAVD11f za>oIVi4WBU(lok+w06Wk8uuG0Ss=;u`(R|OWP%rvZaiU^5Ig!_i13M2GzgeN5{CC0 z_7(Qyi&PGK*P1Vb98SS=cx=jMV*cdZ&5L)OJw=m=*zDzNf>Qi(l2gMK0mouncPq(b z)nZsEl{R?w*a)Zoxzrp(EO(qrn<)U>$hni#qE1iBiqhn|!zELPV*Ej{dp^*t*- zd~}^Ik6H}Z0~exqKOqM<;nHB5kc(@LNhsg26Rz)~=aKJWA{bch>}!QD-FraUjy{~V z@;0@?GQ&*h4uZqp8)(&B-)jwIrUWU^Q2*snbpf2MkU9z#YyJA4bk-y=tM~YOd^AK(b5p?peI?esL^zr9v`6{^*!fNc1A0WVdcgQK|(UHk`!U; zm09l_a#=c|`Vn8*AP7JKOv8nHHFld`9XK}n9LCgtFqb*uZhZi(32p%5cC`3_~H2l_RkL=oKBr`qFi%Sp@Gem?7c;WleigcthJLm|k( z9yp6R?GE(7Yjbx@4A4ng4rnFV`Z6f?a9QKr>5gnSE`=t5hAx6R?O$mK^zeb@!)U|8 z!^2f06mlql$m{}S@+`uFu;j}MLvKsH^+tG|3%NyVN#&2k+H>SE+0p*)UDyA2v{W(*Ud3D`B zKQx*mO@nH9uXZBJ-B=e{@=>#Ytr}rTgWe-I)gZe-XPwd6eG~a*?puZ`U2t>G>94Dk?b>s~|C2VGLA%e7d!DN^QZ>sy%^O z(Qs#1Wf`rekNH`p`Cexi7T=d9gUS6xNF!XQ)+$_WUq-XcwV~QSVi#K-LWbbx&z5fI znw@3ecC?bJbbME0FUgSK_#QbbMjRpQkT!-fR3~;fRLUnH5PhI?XjI%v(wX`ho#X_e z$%7k^{;_mq_54k60@475hYwApmmM-> z#G1n$TB-vqY@UJ)e@O3XimA1Aebyb|>w3g5Oe1^OLMB}nUTT|0hjWLGYw*}|gvtbl z=lF+=wP!Ye9^9c{tgpKW$vRcK{`Yt?y7Boj%MJRqd0V)(!~m>&^HtD>H^x44+mS^V zQ~(MgS4WfaUBWxX?uUohjgDomxn43}4OU!FlT0H_d4U2UN9ST5o;bYb=&*PSpfEcv z3)6FaQx=p@Ve#?tpyjni){wUfComX=H+$e_$0r`QDb?Js7VigD;v z(Ja_kRYIICNS#J0Z5w=r>}dm-g937K#f9D{a#YO$*qNfYuO_LqPWSq2PSU3kg78rn zesheS#0*r67 zoVa}>AIs2k*OS`bgZtQi=(0Ax+qn6et#8xS{8YEPk-bqShvtPE8u&yyM`oKde9{y+ za;nIXH1D+I-s0CkF-Df@w6d|hA~}Iy((UW2{`XWkI=xD0MJ$Ifz449kU5#0}vx+f- zSt6BQzj99{OjEo2NNi1y6bqHXl!{xjfNo_>k^)b!fh#wlK8S0GjA0M^i1`YF+~!%uMp06y#=k2-`KcP$)6!FA|0 zw=*i(7rStu^^9X~hF?zWw;D5+cvx8Q7^>Gqd^vPtz|gCXaI6z6)6)We_u1z6?}9)D z*kB-Gr7v4{Hjvn;70u(k14>k=HMStE7*p1bia5EdAs6;^=pQ|GT>@TjLCr)34a881 z*Og(Duc#hxsS{syFQ+rF1ZBds4DM#4pjKS9!vMYMI~l=WBR-&<564JU;t9c`SGzl$ z1{TgJg7ZGS4mca=@REiam9v9>^ahl)@KR_1vi2MAJYkO92#02#rnYEPt-F=0W5KqO z`^zO&&P;mazBo-Ivgp$KGc1(gt;Rott0RSsNLVISwE0#?tt5gRtyF8I4)7g$iIbT) z1^p_-&GyM&*KEaeVUWT=(qD2DUg=pA0+a{-R|}AIGHy?G-fu4%5>hbr`{dC0VrB-= zjCyj0gSs9>(GOP@vqXb=J!%)fd_Jna#fa6StPU`11HBEbiJ8N1}`7Wh4^<4tovQX z9#-W&JQ_b{z9GMi|4ESN#N54zt?%J9$7Ni=M7d=~-83Y=K9TEs8_ae+yfBz9{53YA zkwdVxo4DXBxuWs;;9};?L4Gx5xZBJ(H(z@>D=`ik5AC(yLoWpGo9n zPuZ)uf^s49sZZvd433+Ll8#{=*lIIaVi*Qk4>HyZVYUY9KhIQ+z~;-HxTej+U3|rn zDbd;Y?KuuVw0`rik!|yVc40*GPAebp#pG39b#NghQ7;{v3AF>$JMQh3DVC)rAPa`< zcLb)XAY>du)P;wb!_#2uJD3bDjd9=eSqK@G!%?*0_?LbiV$+i_>Nl^gJ5I5BbiO0Y z>~2yDQ1x{Bc`gm!U(PF3)BRX=9a#x@INyS0BTmO8RL$LHS(?wHNd&sli!8D^_QEK zZ-~hCie0$PD|zE=kn~r8M9p?l0Sk)=+q=uxw#Z;Vrj0Wc4%GVAC~{@9?vq9jmn7<;9_T>}o|MF1&Z5F}^U7s;;0NZH!*G78P$WX^#IYi-gk} z$KBOIE-1-KtE&|r|Bkj$=x+jM9nO}z>|(57kW4D|B@0H@Dp_by* zM(}d4a^sF5oH`O!u8_t)eF~m|Eh@u+4~MZL68!nN?ZiWxX!TpimN%o@Ca7RLpNQ-~ z8CTJJj+$mWe>m?G2Z^YuUlaJt6K2wFtS`=`9LMUjDr&z2RCJ8m#v38kg0<#PuS(Z7 zl82fdBmj?htxI@nG>|a&UD31vfxY=(y(zJ+NTDF!B0fYp_GoROIO$+++hbX6-6X{E z9X$g!yIsf6wNxb5tM#b>8DLS=`bDWn60Y~~Id}=d4x0fow&8sbg zB*QowXc+X=B_KzkiONZA`d;_~D-K()oNQlNa~X+i+luR?b#Y@Iv;~h`hbLIJWvj$9 zQIQdTpOd>nMqCbj2gJl}9KqmL^&5-J_$QlP#WuBk0>$yD7Tr1CSr4zdTW8k7S_d_S zVPKhqZ^FT0r?kP1@iNxm6yf>n&P!U>H$9L~n0@QAPaQejPe>THFI_cry^T}7c%B}ytZ-_^^o`*qMqJU)Y%`Z3Ih-GD z4{=a7lMB?V2V%*d^QfXxp&Dee-8>s6hpRPPxbStDbD$}9`7>4W_|DJ-bc5wDQ1cQ-Q5xbrkXtk{j-) zUBwBJy(!*|%m>XM~6s2}dy4CA9VsWp z^9}o>p2F-;H6Q#b?E0aY^33v64e||3?pgILj_;Tc_}wTSbgDqvNs}j{2rOAGwgcHr zu>;v$>3O+@u4N99J`6Hg-KZ#*77GqDs0q5#$S9e_2@@l*y}V}O9W(PA;lDhd&k}PW zY5GAFULvKbZlzFfX0J$_yX8045~agFynlI*C8+J(;KMm2-rZJ=f2z3=bBXhhUiJ55 z-&Zlado@;!Z}II^?I1093sTIJ$YA!TDX?xPeDu-m7RPTZ{T}TTW+%ariQ7*sb0V!M zQR$#E1Xp-7P{g#ML3(-hMPY3kU^i@PWy$?^gAwni;|@V_`qVF+nB=@tIoIUhL+HXp{L0Y_e-_rS$OTHy3{(hI3rS`hIjjWw6 z^4O46-uNy0e@av@_zT^HHfgIZ{0~Vz zt+X{uNQ(J)ok-}Bcy5{%NgoQIX3sV?P9G6FGW(7f)(Ffhk8Y>A7s#>{e}tVc8FJ~( z^}cKE8TKgX<9#owuI1gmbe&}4tj1lTUM2j)(Y)ymc$QE zPfZoGWEMN8d)%_Jy{=)K`owpBPy1VYC9Dx#(Mr9U8;MC!e`qyFcPl7S@r46Ex(m%N znp!sUD{-!nn=q@fb#c0HUcT#xA8{h?$qAcd^_Pc&#k}y3*hnaxG@O(l*J%Ykhg)jo zGtUXw=oI9G2^4$@B;VKF{=R5(Sns*~mc$2M9<26}Bi1qNfwW)2Q88=BgM-z{*+pM<9aU#6KGXCgjMv^{7k93>QF4<#t zNYIz)NqLcIeO=!W=9(0no8GOG2PM+#!^oMaqUXUNEF-?luej@4fh-n#FQMF{n3NSV zgKG#zDXdAq(16FuDBnA_ufR>!l^KQQyBe6P!XQDXS~z#)P9 z1LUZxO>DCtm*PIhtm*~KZwmH5o~B>7l?pYy$BA-2E}eVCu(k_iBj$11_$h`ic6kP_ zUAkoO$uW-MKq6t+;dOB^i>5^bFM9rLR${=v+s+Y%r8;$OTRBzcYJ{d05&d=0s*Tqk zEp2@l+#UHnTV~(r+XoevkW8TGu73OQatIoz9p=EVn}?+VR`Ojuc?4eWf)!mA2& zUHR&>^8E+G$p84B8GaIE_`7uM-_C3e!Z0l9@WpO5~kN zI()gVC6T41B^*2mk4gb)1QyLaAYL`yoVKi;@S2?SI^CSZO;Y?2uJPqzOkL%~4ddOe za0p=i#O=2zrx?zg{7dfQvL8QxpwGm{ z5cuoM?(N^h1=s0NJ7x5e=G z9nGjy`KU8$b9a{m33)kr~a@-eH3iG5PM6y(AS6A1ANgf=KgOfrBvWXTi6M0U}%SLU+jaJ zPYWow)mNb1yOEMh1Xo}Ta_lxwPp#vEJmpS7b3iU~>xz{BmF{3nGn8{jFC*TG-p)HqTt5w94cWqMT)h&Nu@;P6BMKQEcW%#SX9w@_P6KVM^6!?po@hU06 zH_fr#UR>>Uo7%E%yH3~8%S+yk0XA5X^&th6CfVwAK&5cR2-z<0dQWLjr#`g*>0nsk z9N-Da1?N}^@haYTlL_7O>74U8adAe>gS^xx09r~Ysb#&`*&F~#AaCTPt;A1`RPp}J zrSeYX9DNwayvHL^A~*Fgr$^HQxbCN#K5`Z+!Uj{{DMeUR*G4|#b?fFX&~lM2Ni*%uoZT8+>w8oGWxlx%KHBar*}yNi z6g82?Qz$TxeNX8$Necg?8+F?-9aWk~*~9;Ax8t7tfDIFD2#FWIv)7B_z@hHVUYjK$`R9T~$ICbVGPdZl zukmC!E9cwa3nrsar4`X_z9qf1H@%0@F=NTTiN_NLt04mbm;dgI3m48?T&~w&o!hCw z3RV8X@7-;R2SCrA0!Db?0pYE1R%Kjb(*v%S?uB+qux$h7kDjIJ^dce7?rPOj7SRuq zYu;Cc=p|OFU%V$*O}hDpSN$f8n1oV#f-CbbY7Y6;5+Ww)N|?l5vZ%-98eKPVy{Ew zPTd=oLfz-lx3PRvK~+Rq-9BaSTY%nJM=}D%1QPzlE>McS`yoz744{S|zhg4?r}7sO zZYoPSox&s63*+tbJ=?@x$$)FENFWk5(*JQ+5(E>*|HOd(V(M<5($;TMrYfm2(W@r0 z!Ki)VDRvU;jqa4)ezF#wMXW19gMSKCwL0mukBTcI-e#VBd)2h@Q_GpDz)Z8-FJ-tq zTsN71j>NC$2a4E_Z$}C~NzFuk=vdq|#MmsjM_-0FpkDyL=0>1y3CEv8=iga>qn{$y za&W)owbFZD{@z;P+5nL>;usXx2>7k3Ep5oSQ^E@Mtj%G8;7Msyw^Sz0IT{OBht@3m z@n<&ZvU0YD{J<=H>vuyi@9U>DPku|ZtUN5@%KBx(OnBbc#e2Frs=aw%*MKksh+%%} z{Zz&Jh1dRv$xpp^VvPw2*POgv2-5gJ!i%VHRDh`1Tn&;)a}MG4WNBwqg?tMGLn(|5 z&y{?aJS#96^BEbJF14EY7#PqNeEXudD893u2Tr=dc?UO~+uMC&oyc9fgG}a^%0T6- z)g(qlqWxP!+Z1Ut*rN*pd$%St4K%LpmsRkju@HQEb*E z)vAN(o~(2d8gI~%-LK8m@&a*ItbFxbKD9JaA{jkyAf)v7nYirhHx!$K&|!Fu+iS;Z z2WPK$fddJ;5NsuyNMd(t&oL$v-_GKP@#U9+mJp_1h4mwY;pMeb=m0*IPW=Q&Nqd6p zR)bpBNLhVJP!usAPwkyIz;~@92dLgQvYq9Vl>ZIIhx7dvqheS^*a zWtXI9-`H{Gih@WSJ1r%bg>rXK3>oQC&OhVxBy< z>%xayc)PS+iVUCnMS~@5b?}+~>Ch$rkjJH+;{8`{lxp4ibZIJL=*3#BAFPyt8s!7- z(K2PcGD6o_gtl3L$G3%Hy4FN7e&koXGr3{5t&JqkoHu#pwyMOdmU;{>D)N~{MMlf* zHY=3yt7#vJ=w0^%FeWiU*T3mCoMOIiu@tFOXkhU<$CVS4Hud=pZm*=FVCb!c z$RoBE2P%ebGcPhecQAD}3-Tn7l?!E~Oy5Z??c_oK`0RXyRUXfZM)rw(33t?rg{+AD zkRac?o^;Uw&}L!yVr2|?1ZD&2hI9k96V}W=W4xXkWoF3Gk-Qn{lBX?H^oI1P2?vlt zqIQ1P!5yk>(W;U2z-fvBlRPzF!?=7mq%ZSAF}=-aEH{mOP~3_>^KY2Q@E457U#5-f z-1cCX-DYR9Iq0MAarzDJ0aJlek$UWzh~$93?fPg*7+W-0uk>4Ge^Y)oW48EvF~jC%conN z@5OCm!+KS(%`zm${(mP^w;qi!zV{OU4yMNqk^~|Ew z_I`Yn;BBx!oSi7qPchg3(dtQ2`6iMZPe#c}hMOV&2(v#f#MdSeG4%<6j$#)Mi{$

4S)bl>l?zL9s!_fd$q;k$=+^BcU&SP^)`uRQ%sWyH+($_Zn8ou`$S_E`N)i2^^hsvT6EhXG3bd@zKuUhTJUim7i z-^3203E&eG8(N8l$gI-cm#n{ghwz07_crZdg{?&u!FI5^#ob=6vC4G54EG4OKwmBY zTrw*u@d39oPXJ{OS4xXUNIt)wVh`=pC+C@$rx>Z+X-GuXtJ-Y&oJ;PTOPhOhKRXWi z8V#JoVVskX>$am*RvSI(-C_qLJRlga@i;j@+fBN?vikkJjGf-#U34Y8am!G1 z%4Q=cW<{Nz{6PB!>sL6mL-V~9SeY@P(77_($;hx&!zvyaCM^>0LbLYXvyd4&ube~( z`AW9DmXGlebH0?5i>lE?bzDy+Vx%(?cH!RpvO5d?x1kGF{whglH4Ym?LBTM%v;c?s zakRN@z}%d3ty7Gb8&ucq<5KmLx+#@ZJHLwNtVkIr7F}SinKSG}%e{K(th3eiodxHu zF;P%svRZ(bmyyW>&r6yW3_6{V`%W>?OB77v&?Vq&INuwHQs#E38KHdu`sexn!pMtN?$; z`@DU+=VM)&+}$Va9jwZ_ryOOpb3SR$bD0a6F9D}7ua?E3g-6#u!Hqf8aHL-<wJbc^;qE9#JSCf-aq0oZ0f?Q+i%XlIYR>ue6<4wmd znnRQ5&96N%p*~zm*Hi~%3F_gef6~~JH_m-xpm?<$@j~U4rlMu^Q#)Xr9ED7HYnE}_ z={1a$PqGR-%;@t6J<^6HUtnWa21p3?1(@_p6MN8bGWw?!2#Kds0b>&sMKd`xO|&ff zcLZ3<(-?o&T{D)JM7 zN$=L{|Ga(>+uIn!L}ViwV9EKoG0lk;yz-m7<%HVgH5(~Q z8aD?#|AC`Dz=q55^3CWLd$H9*`MWUn2X5it7#1dC+Mx3XzI&_#>b%vI!;XhX^MvdG zv3+QzPY8z0-9_(+%beBHPTXN($&1cKg@(#}Z`dHGE@ICjP~VRDXbYik9bbS?S}oXU zW%%ZB+2baBe3To2Ej9bOT4*3^#vOsiYt<_RZ_d>f8=QzLQAMQiX0b&38NNdF)u=Uv zH2u+k!O1#YkNp{GbLjzP(d#nxijNnwkRA9`3gq~d;uec^2^LEU&s_?&c*gqit$>w? z#VHw!eQ{T{eO8A_*kwb)!5;mDsG`@vH%OAy7{eUOL?t$J5L?PHutd84kC=c1iXAFD z@zL3)BwRAJlNd%yp*^M&h~G$+p@wmC<8!S5>vNS~{ZQ}$WyjZ>H!|4ptjz-TO~A#} zeC)-6N~k3is=$jDnCfzpLXLJz=gIymUNJEeY4#aa!KQYA_5bAZQ3bY6dUbv39Q(nN{;wf?MR?+ zGzk|@;xBuMrcxPljlf&zspKprb7dAv#Y}u+bxi?KS>6?>A|IM zz*9sN_90D>sPMk3@TT@_zkW70@ImA@@nKpZEL=nED81o0_3`quo9=B2NAZ@1@eSL3 z9V7GyC*2BKBWtzn_k|f*(_SC%In>1gTUCe6O}4v=cMl;SGgCo?e3XB}&+z0fLHC-i zw_L?^9ll{>IGf99Y``4YR={9>+pC*fg+Af_@(ro206cv0T$cZ80aOd}xq#TCvk3(| z(5##lkHx-0r(d3=v&X>cBX&t0iK@)GqZP~{yXk8IN5ZI)T}Dx(zHoo&Jj($TPfAb#aXnqQbHTcVKU+_bsC zbl2XrN^myo7q93;CWRv%zRP(2X|SvCI~J0nyTF#o9EA^FNS>;g-*UyJmo6+t9xfIP zj2b@e3Y{1wp%|gmAAX2@u=nX_NPMvoh>yG*)TdAVnBQ~kHw?D@M+vQsgB57^arJhw=%g$B&hs~ngRY!@5Ao$s17GmF8Xo2K5BPm3X z1C*k!?aJ}e#28I;Ho-E~uF%khbIN~*x|e_p*w%E7yLUCS21PeL=SR~w4l(D6Q5Nxv zjjBZY`a~6{Qw_&~xW0+xr-fXon;^lFrXbXZbBqUQKu)k~nM7>6FCT5Rmp5JGvu%`% zpfUu|fKvVqiXv--A2fQ00z-sK!<@ay;wThf#7%S?^VQeNc=Jmz=AKiU)7xl8n`a3F zJe@DO*#~=U4lU*kB`qK4<#XDP>4@09!BL|*WAAGz(g8RiLj*9fwyh}<+-@lSxrUf) zC$C`KWv4hVdu&WZTFZrFhf8KotM|IKC)8Ws1WEZH4I#lQ3c1Tf>=^XC%aL$69i+xt zbTl@2DbE`Ai|U#FQJuaOPbppJt^Zh7wk6Hi_L}=PI5VMku3;~DfnEq*;dQJ`yPc%u zrqnzmS$#wp660IZxeg@GQa#0{l#1-cB-vub--6qxEK=?!BRyl_@H zk0KcP|Co9Q_Bx<#Z8WxRv$35OyRn_djcwbuv63c@ZQE*W+vd$V=iB?a<1dVfS98p2 zhz$RFyD6PCnQgxSOCd<`?vA)H^>bihU7+lty09a8FsG1LcH9PYlK7Pe-TAku2?bx| z{Z4))%pcV%;X)~?EA$mTjys*w)+XWH9Q}I z*^Za(fu|WE=Yjrq?xe!a7mFj7 z;|;W+Hi>@hA!q&_`c)^;#SWqws)ZOB;tEV9ke zUqwM4uqR5GoKt0*U}6O#RSIlhc^T54$WYp{YT)g;)<d;Lu%Ll-5D`Ohaty8o z)}zC}TCcNicSAGuSQrxxFy+|2S=hA?lh@CO*ej3yVJF&+uqQHoz`<~PDe5_Af%OCk zThWNkdcb;D#0N7Q{Bt>t(W#Y5uTY9r(?k&iy$~Y`g$O)2JRUTEpjr&ch@Stv zL(vIYcmyUrbRG$)@2{uh?{?ed*B;r-LZ~T!lBYkZ=l6eV=6) zwqw`xu2r#oi}N@0wdLyr8x-H;{bfV9$pq`nl^qpv&DnK$#c>+G;R)!G^h}nVb{%)s z8qMW%jrXTacwE$JG^B~Qr&02TPQu>+lsH>#O-qPLWZfQPoF#jO0Av#+nYrE9OkPas z(}O3x0x^u|dVicBRiVyNT_C9aalYLN0MlF1tUqky_l9dLA-hx5ilI3Trrza;v}W}K zXSFM@SGqzAPg==_Lqpe@=kHQA&mu7|)ZwbrE-a|g2I&okNpNhQpgGlR@3>||5%C`a zLM<+GV;<(&eli7qj6f+Zmd0@``;}opFQFKR!j!p^lT z$#QF7StD3g&Mi|$Yh4nm^#?E(RumS%{glBqATGPVR>Pbt8|lAW-YA+{il|+Yhlu(} zLW=eqJu0jZ-e5FRlIpK-Og8qER_DcX{ycq8t5T)UP@8mGTeIgc6CIu{P$rdq+Avoi zRFv8AfTP8nAM4Y7F>v7L$FS@Zd(Yg%O7){dA#p%$5yHs&C4xbY8)!XvLq=aH^$M#L zV}cW<3}7nB;xY)@xfd=I6(XmHvyPhoc+!E#XMA%LynZmuha58lzrIWHGnhG#t>zaz zbWA<;@tqe(ubiC?ZB1q6xp5q@TXRVM?hI^n)>9%~fDGPQ$s2Nu_fyvunrJ|cjf6Iz zJ-Rg1Qv(UTuqTcD%X^0IZA$l1HGZ|pC~B%7Dzj8@?)bF1p$eOh{xgSFb$5;|ReH(v zib7#Kc5tgq_6j{{E0QjxvXBEpg=w^(Z9BvTFF!9Qr_Dhhq^wKWC^ndQlMpflk{l-g zNh9RWt@3Y1?y&J#5`8GKfH+P@)8h|2qxlVh@v~4n66%v)ya-4xlQvYN=ez0Yr;;ys zyFPM)-csL_32TJ>!c31?NK7>R-9%6JFgQ@>(JW(0rFdi4yy59{o zx*d>rF-ImAuBdK?@Vd)r1OXR?fw zDB>JC?c!Pg7m4;4oXppd{M5?vO1kIjne zdz5{L8Te_;w}22jk9{=qlWG#C#y9W^nYpRu7(}56a>S>o>kZtV>3a3g4KnNPf@lws zv&*(YQIu&%G|E-xYdQWD%upP^riif(c&h11)X=fn=YfhRk^a!&cnb-H>7AMVb#}mlt6p?Z#ct!V_B!A@aXUA200CYfD_nVsQ=e-*RuUCA=1V-8~?hj2U zpwgenLMvBU5)R?FL4qX1qodx1KvKwGzc@wB6k&B~REH=zFwET}qsl-d%@;{U+S=O4 z{z@LI4}N7KQc|N(s~N5F&nhDyh60n1i~8+LjQ@i=(H$MdCX%R=J!Meg;S;MUE@W79 ze<`?S|6%xEs>;1}TK^D${H(csw;Iz}eSV+^sDGlB-@b^i{Q^R+Lu3snwrxLtlIVw` z2G>U9UwdBxMbJp)Py_Y*lF4y;OGfgtfU6ns{yHfN*`OJ_@(~;EVzsX z$(hYuyEOs~K*DZ^O#P2Y?g)=R1ZsMTzp^?w6+n=8Y`ckDh{KP3o>1-u;n~5N4q~=I z&x5L{;QE>UBI<8(WscNO9+n>~;pxPQ$2f(jaysfRqK)bnduH$X|Z*la=%_kN-u5)Cj zOFfxRtKGOC^+<1IUd7su`({D7g5Za-#Z_UHAau#FC2`@kHxCEria1A zxj+cM0_#jeUfHE3p+6hHjf+?_TgaQ!Dgf2o0&UC?`B(SZbgl!ftjH=W0AYl3k0-XOLaU6wev$p#;bE z`+a`=s)69ny%LA1)BRnc)c0$<&l$#u95pyzQ;bGphb$beR}`&}EHs}uitN{bJ?;=$ zWREDx&HEFIk-k=${B9~6PHc2nfNm_~MkhKqv_FTR=CDVUCvE%ocn{L?bJ?Q*)ESuI zuEK}0EB`&3S_&n5$BpD?3+6Vz@O1T(lGlz?&2^H6+pH^&Zzcz_-7n)i5aN$p`g=ql zMGrTo8PE+_ql+f3ybpLfP3T2weIy_Dfdxb7LOI$odVbzm%#AMrf5q9yUZ);&B}XP@C zg~N$1P4lnEU_90T}UL1FsLy?5|5}uL*F!NTZ@lrP_Fh59qwS z>g8o+g$!hNP5#E6Y0%72+JKS@PrfyZ(&@B-errKtTb#VXJ_T%%15{!OTR-HI;{j@a+_MPagEP$pgnfuUVc{6>-It2 zvd5c)8F-&&+^gp3^~IWviORffz14*V=Vv0I&9d?Pxft`-<= zBcEu8c8}+D{o0id)m}}=P5arecw7a6+roVJdFbdAI~I_^CFd%*51anN_+INF@aScr z@LvQ*i%qYfj+zHjhLIx9X{nKL2ukX4ImN2hzJqKh+-zHXBP++$??hnIuB;SuD9zfRcX2v;Tmw#YLAT#dY+Jol26ZLoJkdmSe zU5IeI_x{EE$bjf*?9Lo?X`6oy9(Id?f{{;J=bwEY?wcn!ynpIHM#xhjuVWh~oe6qn zS#h$ZO53gg2>;Ve=eeIVWQ6Djjl$`*ewnlFq%&TIYkX{!CDf&WSVMtV`k=yS>#b;KAt)F?XRo#+T?aUU*TftwCGe%A}S@AV|pU1crIrcpJ)89u?H;-INKL8Q@>XQv_E^1@hp9n#Dm+7_A(YX+ z+xL`=E;hj8eEw%j%+_^$q~2vy$c&Sbp}Spd0}R;!(DbmlXt0X4sVFXgAXhaOMguXoVT z-BXP?AH zmB5JS<9MQadg}udN#Fr)v`Sxf2-2~N9Th`m)IfgIap_{!Ihay422aB=xREuRcWxU% z@h{L6=0ehG=7sxoIK3oIS39Px-eFpuQL_dE=8?|t3a+qq^nu!RXz&K@{=(9zxF~E& zqq){$mjB1mWU;$82Wt-1?BbxJEOpRinAGF_9+e7Aw__X{$$cJ)y)Ki|NsUVxhWe&x zAU~lBdW-nS%#F7r(nL^CN73eYo8$hUEc;AO0g#*_CP%hCJ`hb?B!w_3zKwd(Bsl(g zosoroZKrTfwHFo#@BG|yanyZZ+?T`~R`RJ29UWFT6>eBgBCEE*G=tvXKS*}|2H6l_ z*gslC6M7SlDsD(FMQ$HaWbad}l0Yhrp)=jugb}pk3@k59_xsoeDAM;iKi*$&WHk%@ zhKc;)FY8aUW98eA@5)}+J}l8r$&`QN!^dO)MCbfiV%Ym4gkh$tnCMKJ6p$P>1~jiDtcvDvoI1Qw}eexMQMO*X5;U!bNf=XN1}fWCatxH^AT042GeisAVoecqy{^C zDL72ST?C_g=$*{=UK3Gj`p1M&>}e1plh5WbBV!9gNbMBXNGbJs&k+ptOYCeLp@Q<$ zTYse*eH7si@Llm_WQ`f7qiN`}r?qLqvi4jPc-EE6cKu_yT2b33rnA^Sf{Si;tvf1JKzkA6AU_yS zkJyX~+FnF5RPf}R1Q^Jl-KODgE``nm5OVpgH>lb?Wr6W?S@|LII*#0Buq78_diXpcp$!M!y4|jC^xKaP{NZyqS{dv?-U7btq zfqf2?`Xj%_3xs!L@8O@0k=&N&a-4?MxP6yBe22OB-O2)Mw>s-H1uAm}L>PfeQPTpd zU}6zUyGz7zJ1Ec)q-fs)l`5(*7!eU%K-55gpGbjKiaDFLzMV)uLMc~$^*dVm(O*S@ zsB7ZI#PtH2ws&2bHT?tNaFhL{7pSeV{svwyC5rZHzz@dP>whgzb|QR{RsP4u$!Wow z&1G3X8DO!xyNL)zJWz1Jri)nNUa5$rDuQ>j{6%MO$j-QkcT=;lU&bxO!qm(xyqv+) zwooy4U_m()bz=v1bC#ySFJ}x8hcwyi@qEm^v78b536K}BcpUI&?6p~!Ns;ln#+)+Ys~Qs>6UiMfd`ENXAhI~=MLoS5MQGbc2*P^=p*_e1&)av-kWjsZ9Ds-)y!Gg(`e>P4mac0d@AQgmAv?XKLV# z2e7{nD0b9)kAYhjP9scDVgG(iwT8Bwn*Yu3ohfs-HuH=Fj&3u)*n%V%FU>pGLKz@( z!G@EBSg^q2AW%e@1AE8<#eUYPGoc;6M`}N|B@LaYd{p$ zvBS$5o&)7Apho(L{QTtBzJ`eW0=+P$6P1Wuo?V|7&mot~f?{4XX#IHKZFLoVh<(3P z$4(Y=;1~C>RD9nROeZv2l|o$6DGjLy#jk1ud!D`7vJF-F9tu%wspcY7pqXJOfp5i) zLx&^ ztosmD^qrEqHb)KiOga)%50gC^)7TDC{N#5Op)4AZrM$(E0ilHJ8-YKfL*gS!QC=1% zZgeAFNGDS>XDxZM`X6&4Xs3lFn8rPZ!*(M6!O~ZL7`=wE_vroU+k`CGNr>;cDRwpT zOl+WoT?>pqXlJq!&>Kr?K~t{UznnfPeFkeenu7W~sZ2!POg`+@$dopB=J+|RLP0nh zPX02M_q3BRKp7$%is68P70HYSE5*t!#jnfzG2?(85kwZ8b|kRe@fSX?r=_|K2TuD5s(Ak2hxErPpK)7l*WzmMYUhxAd zhKGA>eECJwIWvcxz$_e)bf4+-=~fcGNQ_;+{nL-=Yt?0$O9q?QK@zRl3tGDA0R^xy zc^%-o3(Y6(`mlo#yA7Ocn{)pp3;HorbY!sIfZzyLPOht@QMBP%gqv;uqyIz*gF*dA ze(ZTG3O0jO?88@PT$tb&@U|q$WaCVdLMMp-=vGZQxcQ5z8}Aus5B_nj<3lHIY%;II z0|Ij>MY&6gsUEoy-r&V$GzfEC$95$Gu9hpCKKeV1`M*6&j>p6u4@%GLyGf!|j^8rl zFL0#)ye#*mFSyhG-3&y6S1`r+kdE68|EaYw)YK4fsS_Cem)qPE67YOX_ItAg|CpE=H|8QCV@(9F{IlMeFOs!XTY9-57BR=L z2AV6t^EDCfFS_YQBUS1mo|h2ZH`m{^;T zEQ07zI~&L}fV1Vf#!B{L_eUHOG+5BiV2+YoXqbj(lX%z%o3Qgq zgOH&ggm7fT{+D95$VnjZn~haC*iBJsf2u;r(qO!O&(;eA`U4*Z-Id|vgiUX@Eqz9? znUiowxAb)+82{uNTcD7+OHZjAI#=C!Hh zD~i%`V5o>=WRVfjL&ek3_qBWv8v-3Pi7$4rueHCa;~LVrj0v)t&Bwaw3&UoOaiVID zK@3$9UL!fTGgmnCCzAIXP>BS*&C`8AVb89eF{jIeF}>}b=FjguT1`U%&ggD@rFsmN z?enc5xFJ-*IO5@0yoT5xo9>g)4Q(F)T)RL@*;M+#I;Yu`(XV6@Xeu3@86Fm&5;cb{ zrskPV0XZ!P5<_j~eIXn284&Bx2I%|#q^!8BN7ig*Do>JRxmL+|lz)Go&gGEt=>p5g zJ^vWC)ut8

iVYd=}@LUr55MUlDM0*|DPI%fp)`$ku5`2`aQ%pw1tR@QFl=ER`G~ zBNv98N367%|Ls=5icE*R96#TQKgy(_WaUi2sK8WKc~*kiL1ek}u92PP8o>CRgDZZC}%spI8INogHS4` zDGhZzr71uN_=$rr4knz8qGZhvLBxoQ!ANB33`-1uHYWkq-JR>Td1i0eBfLv=pw5LO z4+fidS>=o5O8szM=Rq-_=+*UQ(KK4x-5A)mi}NbAhRo-7J73-1_r*Bv6n}9Ugc{cg z4ZYIv7oEWnELliRKn+oCB2z!WRS)bP=^~ZB(D%ke2xeWh^<@@PR1~2p4usFCNRnW) zp&_$QGhLKW^m8PtpcL6>t+;=3J|~Fzny%%*hUQ_#cvCKPo|smxfDr?SS+a5bgj2g1;aT7Ch9b?FTi|-6m6~p*l?fb_4fH(IaFt{UIFUt_ z^wfG0E<1fFFpbTkRuGQM4>NW3J^RaKO}OB>>K1V5!+8DcFlNlj5sO>MN7B(Y=0g(7 zDeigg|KFnpf+$foYC-Mg;aXYNgc{svY!MBtW{7MxLP|We6_IMzX$C`h;SntU#+Upm znb;mR6VU>0cv|p?=5ST(3!Z6qY z6fqRyRW&71ec-I;ni_EbfT|O8?}wNL5IO9D%a_R|j>>rOea#OwqHixrk; z-T7Li2`+^f=y-hcdG%IJvSqyFGE?_I&ckMUou8jT&N^$i)W;h3?<%oS_@pk5f> zuJDbl^D$CfNFiNbJxZ$gKDuhwLoLHKp!r;>&8&xD!7_@)cwdNF3-()zDKeXQ=TWQ# zQoj7D)s8EbF7IQa#^=q|>+)xqT%)$A1wRhK7X0(^bsr z@LDf(31}esawpM0j4DJAOR}?AO{~2C=_~bY1a|Ppcli(Wg3PG3-`|;#jOMMQs5E1k zjF+kL?0%I*Kl+ICyhB*Ov~QIZCjEcCG#q&vNk>&UdJ*bc+1oF@dH?G>18p#U0i0nh zux@qag!mBU_=%AUaJGbmVqHSATvr#P+}?&^d+n(7*tGUZ-9}r~R3=`DZ=0GdS{zpi zBa)O?dPY2$6@%O)yeOU~k$b?QM#Gx@zhtB)|wcT9&(^&q5US?^}b|~%z!eKP9KO(l){a9FEx7Ea8hM&=v9Y?9-7AG?K@X7=3 zUpamvrfNKKg3W7rbg7$f}zDQ8n0UJN8^JM}E|X84s*r2n_eRq2E5i zF7P;FN7f%nN_$Bbq~rF7N^y+G=ul?)@b3_|V-PcA1K;k^NJOgeaVx~`X9IeDt>s_W zUuHRd0eguZ$>|{S}Rp(Uz4CI1OXohgT*X@%t$(xKFItw8c!M=(+5U? zp#(w8-?vgHz&XfnQx#f=^0)gMOryg~(0ltg8G2~=Po(z3YzrGiay_5$XJ$?!KubYt zw@24e`jG(9ldeikd}LhJDZpr)Ia~YQ0RYzSJ3#&U;=Ad40k&;Pq}v6l1JieOvR?W0 zzE4Si9XH6C4{r|tPt3g||8Z0dVgL#gkTx$E--j6S5X_hqwVOoQp~ zRq$=X!sND>f&O6V34A#MKkDUa20!rVt_#cda^hK?HQ`ptIMz-Xb?;IHfAKS_KyieW zvFD$YglDmJ_UJ`Zdi|E_I@hQymLT=nmNlaB4A@5-rN4vEJNu{@r1djL`5P9XY*Mew zp^W;Ri%41_f@!?_#XUk34KroDW^yg}h(C2&?0e@b{-itcLe<~rfxTUhk=*m+2j(^> z!QWTWo5oYC7rYxw(}bXbp~_`F;gUMm-=yiK8(`u69)DSV5`@xa-??JR{`@bDDTd+A z={=g=A{4;l!^ufH8%Vgp5Lbeig*jXruppc;5giKwkqtlpSwxK)yI{1FyRg-&%m)ef zof18ZgjIk7^j{g^LKdcsDfQUHK0Kyv-gkS@1){#))aSy4CfCqJr9X~)qkFk z=J=X*$~?x)hREy@#JU*@Pb&o+9N(=FIU4Q5IuE{_?8&j=TimWe4|)flIduc#B8aCf zP@Qn$v|8|E(O5%9&Lm&?>`8vX0dJL$qJ`ss2pIe$R@uQ`slG){yiLTx(Bt2^V$R0J zFq`~evAoxCWN$fmbab}oz`5oym#mhJ0Y3VlG~Yr>bsNev)#p;p%D4d;~TU&7w*GC?)yyqF@nH{$P%YRJhFbCG) zaRTbfS@0hcaRTv?Y8Km~?yIeDY|jbbmaHs*^$N`z?0!rP^lRYI!x5RwY78|T5pKMKA!>GNrloQNn0oGH1f&I|I2 z=RCgF8&Q=}Sln!I5dubik;_95=Wk7bR-d;=V%s`@mAIMM9ZM5J7o3ndB(xcX4rLdg z+FlQ#G%;{yp@#>{JCxsT8G;Q)WQN+RPc>g`yM=$mClGbG0&iy@L%aHCES7wHjS)@-b`O}Ep?}aq%mCjb+pOrgWdW@^8YvI>dFu)rm zolWBHhok&tez-yp3@^1A0fWgR5vNN}=tdT3i^Wb||64p{6Hfq&2k8L>>Hexx+3i}K zX)`)lg2DB$9R^HR5pu2H$INj@HM;S@_&mPK!0`Xwyhi%~9>C5xZvuKQvI%`@Po6+1e)S6ji)LB2sq&drWJJYU#KMr z!UBwzWMVb;;V9%{P&8CQQ86K8(IH_MTl_E(lhY|8>Z-Q@R)i$RApkd!HTR2Oj zowhi`*18OObGmJe9=V$8+TDH!=3^p}hlqPqh#PFdRF(G3K}Hv=N|oJt``!db7OgIB zwU$6F)!CoJ3_6)92^!<6Q$*{jM}~*?Ha+(??rkC9PAMV@lnsu@=CeLwb$yJU&Gr#n zG*637ZBAMg%w+5aZm@*Dy?b1kpGS5ufgpn_V8(8KKGodK_uPFpeDp|Iyy9uYq=Q-q zg|a$7+$W{=FWE4^g^eotc`-D(b66wgJ)$JDF%v*ngR<{>hswts*4@);|t1<=x_=+)Q^A`5y z*C&RDxToq2w?+rGpE!i~!Jb{odHIvv@6O)vG;^^3^36yd9>O67y)}Q3zNRXnu1>ay zGs}XhIyk=5Bj=Qrc_uCYt(uZE(C}PiuFHn&vg(d;|_eDU=Vm`(h4v9^g&!fp^f^VjI=Qr4xK@f3peD>xRW4= z`ezH_#QHmG_r&PG^Kgehvp@J`Mi9glRMo3SKj=_`*ma&RaLj$U!1-o|)wlo9L8ive z``)*@gZR+@d=Ty{1HRf_2G`_MkkP=w5-d@kv<%45weAx7Ih1Q$QPd-R_~qUh_#9_< z2JJQE1-Z6DmjMD5Z}V#u&|f>eO%^X!i^b)Juy*R-+;iPe{6-o_iJV$b4kGh@t z#aENu(TKb_hN?A&>j?L=!)Za`qhNTT)v2;Nm5qvysl{;n8;n!}2a3XBI5~~@bE;wC z14#DLK*6F8sbzbbjPxN{;E&~$_3@0vV7p%B=&W=kq#A}+7}SaWeecGsqj-CYn-(nQ zoQ5cB%#$g7W$CbF^4emG9~f#%QOfvTP9BtB9v+xq9^#l=j|N*E9g%jr`fAKqcDm{j zrm!@$l)T2gwWl&jgr`6cg?2_?6P;yJd?T&!cpug8i)h0G70Uqj{M_6hngTQ6 zeZEndH?+1ZQ4xgf7iEf=OoVcz&6}%y&5%MOIw|6xI!T=Ze?W$sB)`KH^Kd%2gV^F*}CXzKp!>HKNN_gAT>nWt5reh*%`TaCjR zi+~~HMvp|Nj-d=GV&{Y7DUJfdpOnlHi>!K#pFS^lpi9T*>b?qdd>#Ci~7iW8uRcEvxKt*E<%Re38h)<4B$*5gsx z2#4n;OhRP6q{{m+=|e>kXprpN=qQQd1M*P?fxSjwT*@;iB9!|f zU%te-i|e1~G*N3Rx(iuG^N9$5KW{_Q8X0t#2G34REVvaKPmQB{S6bnhv>OU9rBd=E zLQCwF#{S%crFa?dOmj7g1zF)f2Cs@YH|!RxB$xakI416WAb9^R#k;rT&L}}!!Bcn6 zb*L*;me*_h!Zg#){ySq)k~L+&3Hq__Q{YMT)Al_L>1HlhI`YfcA6}3j!Gb20=BGlv z=@rG2fHSu4o4m>Jcz-Xd{<47Bi@}xgzqhUE`vQ8A*1p16cCSz?fmPjN^8?ZJPfMZ= z&Qa&%`SnXOBr<;`sM}COlkhVpEeIeAt%F++j>WVhBB5p?IOF~l;KhbfGZpwzrDx*% z&d`G?#XL3{KF@HdJG7ed=}8tV29211bEag}yO`MjF9E)HQB?MKuB_UZZ)GW)aUAIk z!3y|%jm_57UUkhEE{ukcV6BI8#*IQY-X;0!XVgbH&j z1v&Yer<=)&miH1!`XXW|*S;BFDSXXl4EH;Nc>v=)pfM;Qf&XntHaLRdEY)T1;n5A8 zPGJz=3%5d4cTbRP7m3XcWEE=Pt8($Q=y1R~`Q{3;%Dn4iFCr}$bo=&>3F!NxL0Buf zBq+lvgKYOcsBO*A1C58*GxeNmilwK*c(D6NncrdQLiYh6Pv1d(I6;lYZ2aqgOW&yX zHs#28i2;n{M2dOZgmM6R@RO`SFtYeB%^MUD6R+i>mcq8bEHQ#0iSv{eD3vc>1s>j! z#3m00I3-Svor^@wWL251CtV2grAJF7Dcg4^;zl}s)mgsL!S)aNDVw>>$~^fZfScMW zcY{Wvh_?rwJg)W%M_wWQgCL~%RALV#){&e&nQxH*b=G|-;*l6!m5$V?QLauK(h3(Z z*TlL)N<$--8Aee)@jG8Q7Az7{ySI~lQ25mE)GTzw(4%mjMcfsj@ctrDbF@}-%iG~5 zH{WT+rtUG)!wWkZNyq8zXi+!8b-6n9R`uc66JnSbf=Sp>P?)g@J7B5>g%qf!>v*Ef zi#P7}Epy8`1)}W5n2I2%D9+3@r`W0sV}9Yy*`T zEl;Pp3EqQ<{gl{c3;Qq3jl?w7z=TTC!pLXm*Ob0BMF|bQUSB!zX<0iN>5r$Pf^&jZ zYUm0|lSn9&qT=z4(Ms_y~8k5!A z1L{*uDR}u#y_%PGsyh$*qH%&Pdm=w0wtlzU6S04Dc*rAl>_(b7vIDG#-2c>sRXq9l zoIV3@clRTvN6s`-jLb_*(Xq8-83fjr=K3G#qDCx9+Qi&vhHCwd0KT(xMqA*P)GQ>6a%fsk(y8y*EL&U`$=OU3#TbGU-lNx{Zg6=jWF=;SrvI|jl_GC*zoLpy@us|{A7(Zu_NL>6rVnO$ zkBnx2Ut^+UlFUK~wQ+#wiWb%*N;_APnWmC3Hm29-v_eEj6y76Lq;xJa?k>b-HzqE< zUa{S+N=O22ve&2D0Bs$QBYO?Kcx-X*9`Mn2p>+X~0n9>zq8fzeuQ?OyF}LAfty!&e zB?hRjez@&U#Bnwo{Y5%Y_HP1D4o{^=R{!E5%MCGBX$Z_97^C`rPHp^k9lvARZe^^L zP8*z*=5*#z`JuM#V(&fmLKS6NGOkuKCiw4nimbXbo7xXHcHYq>rpp4?gu8!7zw_f( z57b}0wm63Gu|cg+rgd;Oet$62g?l|QlbK9S8#4(G8tdfk&Q>Z+wJ@s{MSI+v+bRuIjnmL7V@F@-Km6 zBO~ya zYH9X=y@N2~4 ztV?LL)11V#${aPTle%isM!Wsd^6qKd;sE{u=palFts;m3G8F3#HsXIz($N%oo`3m|HAs5aE+q9%nB1AF*c-wVvbhR zzNo==Xl+)2eTx?|G{m~7y$!PEv62V6 zW|Aud(*;T$ zybOwTP&uS_luRrI+Z+lXm6R>$JR8dWckIa$$yS`rM3*xxnZ;p3;(dF%kT;$kLBbL$K+tU|F%X|9WVD?8g?v~>JgI=XM>^smNB(QbDiUq?q9+PL>qjzGrMYsM99nyRq|{XAt<$4YW~CHk8uumY)ZvTl{tD zzzz{WgBsaBGTF)~E-D%BD>|=RoNPRv!{~pHCJOBoN&(TFn@oi14lfq6$KrodT1=ZA z+uD?r0%0pL7Bx#sWv>@>8HY83#KXf^0$N7zdbSDXnZVV>=aYEf^WT<mu z?Mnf6AOhictge~T!~TteR&rMG;11ny6%pWeyLMDv^;E{OX^Ym0m%5m!H1OB&B+f2%yAL+uPGzvDl+EABd#$lMnQ9e?dP3Ww_J|#J5H2Yz%2ik`>)IRqx)7)Knb^JOQi)#7|I-4&xp|sx2?ixl8HbOYht6=NuvK=K>tn&I%=^sFvdI#S z)1+>=?~x5GEsk(M-j0^tHazz+83Ewr+kaye_uDIZg{NTawZ(YNsORy6Lh?Som>mI zd7l`{#vDMJ_`lVZ4#|>cbyu90!8ch-MhUM*d67AkkCPIy+kAJrq<;st~s!U+Gc;G z0(ig~nbvgJQxOMmz7#`OsTeDAmXTFNy7S}vmK$Q4|GH*NRKJ9NK)X$MLI-Y&0t-nq z%$_&({DTD=O$l6)Aw~?fYJKb@cbzN6>Iv0dg?Rl~Dg9f^2>;N+h^{2Z#?r_y z3oI?P5JoXptkE2j9|8ozM}(n4h~HOBTX7wdxaTv&VX~SEzz#IwiG78yAc8fD^ zd)q438mKa>CYnE`U%L*v0nU-lx)T}EV9B{<1Sr_1l@RYEXm_~OS{Ln8oN^j}nX9J_ zs`1kPKc?QXy|S?B7L9G&wr$&7(Tde^$F^-d>DW#>D;=Zbq+_#_j?I(j-S4yascU|i zKVV#SSB)Aq%KHK7JXf~&tJK$}lJ51eJhR$?1Q8~(zoV3GbP%JLiREP?;^r9Rzl>8G z32=}I|E33U7JSP(5IROQ_qMyRi_PYjq90x>k3A~zbPX%3JXI0=UT!pBPqWKUg-KF% z=eJHPFR+_@XV|Kvq${D81Jav-G5#y6*-z;jh1r7Lg?Gp1T72R~H-x>7xtW(8*_NV_ zQN^K!0Ca@?>ASZ4CaWqk_O2>AwVC)aYU>-H^>qjGe@mcfe)@#-TyGAD%6WpvA6Sc; zp>AEUu~-LUZFF!<=|CB_+g6H0yNVhZS;n7TUCTFtJTS45p){DoPkKTeVR%?9JPP*r zS0zyeLM$jKBy9&O#NK><70$NM3Um?=@2tv>`Y1w)4T1ltQ4%uo8^VOVontCdR5-N| zytlE1zaL;QnTY7V{M~r_z2vYH#YRuP-FCz1J!Kc}!lg4gqeJXnYD{5V$znAvRIe54 zbxKDhyDtzERwF04qpd*X_vRgA?)?iSMV*?_|I+n3y8vAPs~PWq9C7NsZJDGuCATF@Bxd}5lCs2t^A+YMs?!@@ z$PMiDmUsNaw;(hD@Yz!yW#3$QJ`nb^ST{4^28oAk5pG2lgtKIc-k&06_imDYBqBJAfylrMNmT^7W8hAe^ zUJ;#H^MjPR5Qln9Er1mXjPsT$aW_PN4?uI-$S*LzlE)O19$6?8&NQ4a<=!2? zt~ShZYcD=708?;PMHEP@7vWvrGP}32vN*6k} zDkGjG{;oMWDM zIj1KnH?nT>kYwyato(r*xj&D3Yv<@Jc%sVI=8~hTu8E|7sfUF_95%sEELeujVi2(1 zR=^JDIq2Ds<5r8odJ6F)iRrQo%s((q3J8HT__ZiZczPS%ow)u$iV>D&TrJkIaxv9` z`9^|BsZF5i?_t!5xRQ<1M8~8M={>%eCpR`-(8sm z61ZD;`5scvJlog`v!!kTDbI7{V!p7ixQ#d_LGOuT8sLRud1IDT=r5}_IorZ!1+?gu z*JmZ$9kLC65z(1o=Bad};=U})b5IH|+MF&Hom=0!S@q$?p}};;=c5@I)67=aEZzDm zIuKeB6GCgaQIbIO>63Cr_jw0bM6h)r8Svm5pS43g`<i~rZ|gNIn2 zTbK!u!vx}{m8<;u*JXdc73O@-?-U0+7%V{;g|c3#iY=H&(ZQih@iR-jb-EQ3IOTOX zRNU)15YLWT*^DIy-m!V%yFZ>ES`G@hB5=Vjq64XUH^frN@3Fy@8@ChWJD)hQ*)|CC7_r0BdBGFLm$e%IY!pu~UxkR;X&|jaXzDKv5~at@fX- zxqZM-kxlS=NN&$MXq-07a*BbuS>F$#+d}&95Pv8so=guyG@zeO`H#B9E-(~>>Ofd{ zkj25S&>LjkHZPL1C}HG$Bv%g$PaqtLmyAsd65rHMEH=JyrvANQhKsvp*_`rR`I;xjMl ztq=D}V`Z}mB32MxIta4%hBL#;UVI6m8gpdL?eYY~+41#LFSk=>jOFIc0Ac1eovPq1D z+HtO{t0p~JF1T2bbR;8>_QFWR{N2_+#x4e-+l5#u7Ghs%SK6(!K3G4g*I{q;UN=tH zli00^B1dKM3X-IJ%#o~UMBeBU(#tlUW9YI@mu?z zO!t(SXG`)gro~&$M=nVyah1|xrqC84>9q%fNB?zH6t^cJD#Q&;D_2U7J-^?u z4t!4g7CF;jjB8)gdLK4gg1FpxkaGXM9w5_RnJVSBz%-Zy-MZ{G4z)V%vG(F~s@D{j zF}zu}Zs3gJSf*OtEu!C0R-2i4w%U=?sgKKXe=d>}Rjf(>G|6~GNHvnj?Dr4V@hGBW zV=D7<4JJ&e$3CuzfJ4}Fh4<_BRv+m3pwe&5aUBpJ%|;QVpiQ&ylf)NTDAlY1am9JblHdC`p6d`Kbv3F7ntr)i48$DSjAVCD{ovx zMBz;chS!8+A0}dXuCT$%M8q2{kn+U+L@UvJ+`jz#*()*tgPc~Z&h?zLetyo+-ePcj zsk=DCEJWLJ;<6lYWSp204hL+?pT(urlR1a}w^Ma4t(~^m8M9$bjx!4D_?G-vSE08J zAbeR?XUIkv_~&PG=XHpq9*9nqPN-&K*QraJh{OEZb(DY1vm0@pA*A9jZAZrdpwbl6 z-d9`je?oI48U;=@GRT%zf?kjUPyVk9Z^QC6=cY7+p+H5elXRtm$dNo~@1w zj2PKmU0W=G%LCC|xc_sF8&m(lgEd<+m}GZvdB=a^Cu| z_fO&shal8GSo{^*VBTNVBDL?zX@9*edA+7=_rN&iH{Ccfy4b;e*1D~PdD(oP4s^*o zu}OTOXlMtZc3`mz1m$km1<fGi$HEke^%Am=iWrbxEf|J${hyR&D5d-%hr zKv~zG05{ZHlBD~Q$TZy?;tnLehxer3juYxVDV-{ruq{W`j( zGR!{RXw9z; zP5-NM!0wUpP<%@ytTCSH_7m30 z81-iq-|slTWiLjDW9-$wW3tV(AS|Yd=404({p^)-6aQCsomQ{&&tJ599+ITrPKs{+ zjlxI9zAcWh_yCaEU@}cWUyd*2)alG}T^6YKTiM(bf$o3~hbczs^i*ORQW8=T=!Q=` zA!kISM9D4&84FC%3fAw!HzKweKWh)pRJyIPceyW*>!`us(i@q?dDmZVqtcvu+GRv= zaYU1?^GQ8+3E2@rj#vIR?w#RN&# z6pIW)_r*NdsDsH(A#V1~5d+SwX$U&eT&nxwHX`#3H+zG;UrP+)`=-uYu*-UX#-)v6 zCEtRf+TNne^dF*3_X8V0wy3Ov_2ZD})jW$ra zx0N3HC$_E?#1*#6G&NP+{7|ksl)9}ug6NIZ|iP=Bd37L||cYL3njYkqw} zO(KE~m>puL6B3?6LWSw9Zgph1$xdNa!6eB0D2CR2(Jg6c({Sj0KMU^^+3%}Jx@6{( zF}TEIKg_Kqxv~*nh1F3i$B> zhS48~q~!^E=KuJ(48V}N5yQS%RhTPV;b)s@>4|tIc7()ndpgVYw&@J+=)e>=^ziS`*lOeo>pu2YvNPMSx9*uD8nOI$6Zd2G2!{Hm&VKjtz7X+79*q^XT9|3QN zetvQC+acP5RFrj0+Y*BKqeg&SLs#i(b6;4PRu#!1YTI1DaSsw~B&6NUr17O&;ytn` zYwVC>l2xm{cwIWfCZPNx*YP0KDFl@xx^t8Tw&>XUBg4}rDx0QVb+Egf$q2WR>r<$g z59CXn+17`@awk*fWB}WjX?0qM8bR3QQ=k*X?PBwe-cK6qLbd8w5O$E&0u}1VUK!-l zX~WM3F8CAGUeqhc_!i%5N07}~FHDg#vk&Y_h%XS`@VP}!Y^Ld?Y;aJ-fl=|uufYl%)5x~`!MJ37*)45St0SfhZGX)NdN+p~qKB=f&(DCPi zW3v-j(pV%2q>9+sPvFhKAgZQ(bh9-mtbaqGgvs??!(1 zw#sPmd{RnVxUy!|^S7k)N$T*Eq$drq^&&x(O59EuO8s?BBBrsoDhVw#+CnL@+yfeR zaVypM(JdmHRs3wGe=59{%~vf?hA4&GG3S}xlhY91zQHe>)mzE#ot7X{2@_- zRuQlhK^W}$yD6z|uKOqaDgG-Or(@f*Lg9>51<(S`0eLM<4kfX;!8&+P$3~2QuADLa z*k(Q&n(uMi1ooY^q|t)tDh-OAKD^VU&-*CRgAiA70F_VcN0O44MGHR5W}}_yS-^6# z#lz#BpUOQaq5VJgT?2M&lBOVh%>N0_*wT4T)zqTZ>%g+Oov8 zko4eDi+|S8_%3F9khb9_ck-s{$*~$KLy#$4`*}J?I4MlNo4A=56h(EReY~q~E24$9GTG7Q%a;UA zid^vn9AsNz;#t%b<$|gvGh@DNA&Kjf26py#_GKl?gm7f$WCU`YSV92(+`wp~fq_4r zQB`XJ;P#)G_bDnQ5xbF351ALcw4wpDdsvG7684vWDe~e@<&S$nZgDOCIH3skty;;YJbmb=`eh4|g zLu4L9vi>?zS!su?h+z{!Dd$j9l^sz?7s|M)UU05X}{T(!#dkj&1U8^_5e*;B`b_1#g;cds-A2Uo#OU42K#nLnq?^%VOI@% z!9l)=J*> zJ=lyYg|SwrrUmkPWM^!s5ujD8T=LFa(%u-~k_Pmlci8ftsxF+OWv$7u?MfK(jivDL z+Yht?Oc%3hO6RRt+{@A5ROO_V8l4GHXscvW#kMW^Xz*!8S0$Q;gzrv-Iv}&Z{6D}= z7uPlRa=-c0BkCG*$0UIfK0D*C9};Q2;s|~6%b%jiZHL`O7@`aaTjZvKtb=NT)^~UN zpfIsFc$q>MqojbYhh#Ux1~hED*eBSxbMRY=6K+ssu!%s|Kdjqow#Vyl z1n9`Aa=t-H_?7<*f<-!yl)p3m3%T^mtQuft*I`#QN9wNmb<_4dD)<9u8`%+$5q&UyTgW_*{LrKZ^>}V-0DoP4{$-2RC{S6B9YtL!e z0Rwo7UFYV(1rN~eHk}8!yU`7^w}^jk65jAGCrt|iw!T4{M&_o-FcwC`qt4E_y zT-|OHM4`$C_y6ur9Q;=c5OY$T%3LebqaHPMKv76u`24SiogMN2Y5Ni;Pnl>tHc=`W zyk9V9P=M*f8O-er!F&ke6E<253M8n^)dr;kSVu_%M_5EWP~cdi94fE8zD;~ob6WV4 zFyX($ly+0dKvKVS1Q=!&&E$7wrxhim6ft2Cq0Tqjh!m)Q;5if1TbpDDor=NKaT-u` zKbiss6m%Y>$B38*cQLqpXEUI5Z)ZKroBqgd8J7TAsikvpmj>_4>Fd;&&Em=l@DR$A zX8tumT#YM}OsLO4-bBSXg$^`4L8Z%Ak7!&Y2LRP@h%Dv*Ga+&z!j|`!Qc-e`>)&gd z9JfE(!hEjTe#X6|{Z6a|Y!p9;`_2WRC#v&0Zt!bh5%9S;j^vy#m&>WXn9B2Zh}8_F zZGZ4ku}fS`*4xn>HalsXbapujjDHx`$}T)^Aq_y&Ihv1+$2E#d0P$z5zt)*ZJN(dIhKL_`MPi#dN=3? zQ&AXxd~-0Wc(Bz?L|^_J%>3#EN5%v9B(Gk~5$)@!D$9k@a0&c+Xo9^uO5kmlu%foWkI4L{iMCye%S5KQ>W%|$wgSriS86t2fsmI z%15xwf#ylzYA6@7L#gd6_|rq7WYe!;32ao!8D(6t>2OD6V-1DDO|Dw~NM1l14sBl_ zn*dS`tGJK$w01IE5L~ME4n~>mHwg4-*D0Kn=^OG7ZBlD@$(^S!6?^7;?M9)R!I~q3 zxEOVq>q$|X6`hHNzlmzys@s&j3)6LT2;60xb3s;CxLZbG&+z}wlkcrjk9X|r6^%=D`JHsJ~9S?$ZPw|p#wjtS6) zjFTVPN!?Rqc(^QRva?%f?)P_uI_Uyj2O@H3LixLK^;0bByYQv=`WLHw{7-KDpLbfv zp?-I3D6y~X30<6|8~780p%43=D0nW8q^F=W{pY zrmU|tHXf3aY-W}q{@HJ=gYeDHX;lzp%@F6v5vZowuXHPEf;l8nMI(g z5jxZX0s~>`qDTh0wdV)RFi7>hV1ed-%g6f z5<$;}(qpWLl&bAwlJGj46Kn@xA$&TRt-JS^4z`3#1-67iMdwiG%Cr-y3(7+HG&|d! zdWC#H2JEk0Hf^iW&4w#mhNrP>l^y?3KE(FuiWZhVB`;-{^jdlDVdXoeMrtj<<=N6BIkCM{qBIt8P4CWcGE$MG4gmT5UKxT^2eW?4~I(#j*55Z$~!yd{yY23ApneXk`{!R8ZIXff3R9faJzzN%Cv!01- zQknS(H0u#uDc`jmE?4@JH~JmisDFH%9+r(K(S%=$1cg#-<%HD?NZ24P>ovAr5h&VF zy?v#)3I_6ReB?2z)Te+T7#c-#dfi zFINEI8qSgLfsT?ACwP^E&S?PZDroROuDJ`mfPK5b4NUA?e|a7l^nF?+bb<)TNzeRN zUOH@9y8)jlf~0F4%8n9%O|r=W$_;qc4ZfwX+1{JOMY*Z?({^*P?BeJ*O1Br{7q-bt zG{PNI*^zKndOZ4^`M3r7M&*pQ2;22?l<9Sv{2r&2iAMgH0PhLm&RE6WE5yMU<+{Bv zkh4)qLOX*QA~5NniGPTDzaHW?U(}yfly}U=BY_@W2%tdWueCAuJ-%qSqfmV*dOj-YNIn%Lei(^qX2u6 z_OZR4@O58|d8FT24KOHx%SW&-tOVTVz*aGvr?+=zzn^*7;H_%mGsXiKCTE8<9?2BZ zk&&_?sD_^urg&x&p~%R^=;)kWIzBpP@Q|eO!`fG>k=1Y00A3CWKrMFi{2aoejWdxJ zR%2ew~lsbP;T?YXpQldCTutyDFK`28fkh$>Vf{OcE zeGPg=POO#fprps>+JeDFM}fSkdOK?3H#d%^6Azk9fFkriG{;-^QgDG%HGbF>fH$~SLxwbXs$0slq>4TkD;4&Q#zIDH1f- z=!6HWx4&GC!QWWMpU=8iJ&xb=JZ}Yeei4ovt<3lbx{5Mx-8k+DJs`m_{dGJZ&c}>O zO520H+!||sO+ixD?(%VmB|T08tHdQXn$XPq*V<-pdRQ#Be)^JX_1MpD>;T`VNWk$u(XY(sB z`p~YZhQv&c&Il)HuK}Q!$sqRl<_*;$g&P+mmzm-=APyOr-pAm78l$`Tc|g2^i(;@M zMg>&`u^deH(Ugqjp{xabu!65Vj~5QkB`I{K`BCEHeXRyf!~K`XI^rHPq~@rcEcX6_ zU`|EEz+N;$<+OJ}95?gI*qE&(aIFM@%|rQ)n~utda4&%BPoK1~BIqA7XnFT6uS8O- zeWD(!V1MGlcW3h0^2C}6Y55+`A{ z_hj5hk9zabIXx-{Ue>M?nF5%Q#=dXaS~_I8nv-UrC^0lu#+iB&pTb+Itp$kh|-r>ha=Bv>sKUYMI`%cH7{1~G76f!cbr`wrl*q-)_!AxTEgk(K|Nr7I%q7q?rsmrcF>h+ZbiQT>57x@5Z_1^@W%)PZT{O;fE$v5#kZW9x9>hDJNv?csQ+tamQC3|}682-RZ zW|j(l0i7Qn>)UAXg8m4=!GrEd9kz{hNe#=v?5%=4Dd{W4eC)MSQ!MdpiO6NakD&f7 zCx(W`w^Ik@(Fp3Rohexf55BF7ST&N7xTSWLchjo;PSdSMPqW#fh)r|MLe zQ_})Rr}F(`wIEJist6scPM(S8XShk4`(2fs-(^2x|L`7z{`t4*ezB)VaC=UJ|2q}d z=ZeX#Y}qg@_73(v_N&{E&Y8xBm%qo!ErRM@`H^pyp8aKTD;^o8WlA3=td7;*wDRbi zMH2sF6-0m|uXyjX6K*5Re&yDqe|NZ){A3AtU1}Vg!+;I2sZ=6Q*_3$rW&$0Kpd<}p zCIG&vtOYr##=dj?L0_xER2@;4l5ppCCn?vXhLVNHqKSe;ue-2DBQET|i(xf1Ha6}h zwJ-1Dr}FGN`MP&N)S&iTSDtA?ZhNYgv0hbIBF^X2H0k(L)c2CuYFxYUIdHnlS@Za7 z=`^nl-xe!b3aZ#kk51Nh61~^j?ACU#QPKX>cU<@Q`qOmj z+4g8%Gv{|tJ9BcFxe@6ttKvlxG3&Vb8$#gwjVHPkIR!$pdK3~w2pd(DWC)!rgOZ7p zW1F}oKEt@0X;5Q^X8`#ins@VxS@hUDtx@r#xI$Xy!?;;fC4>|MnlOZT&@Bb>K<2$7 z7kMx(CpHeUO`yo;O$q``c*S9+%dr40^DX_pty;KddBo5Vb!Bgxg^l637n**5D*~&v z*RS$25D73w0}JxZ^cL0S<3Kc-E7!1<`jG?)Xov0q^}KyP?aqXdd*&neW&Vi0Ac2iPKgR)gfb`79??n>vw; zNOY<_A<;Ge>7UzTCoShczJ=QtWBVI_AXJec*`Bh-6`&EYoAQ%N=6StNEu92n+aAy5Fd zG!JxhLl_qjMgOFOtsZ_<0?I#3iq5JpgLQDWLV{KK$a(yL9+qV5uU7g!QUzv~ifOCN z{#oP-8=Bj95zBhy4pM-{q*`>bs~Gq9@*M_ybnrSUN~pNIVYP=LOFClHDkEoPk!W9A zCg(CM$$^m1x8bRH1BA60AH@aUIf~kdSwhJMT?}nMexDWX5EL{;ly~!fC+oAQ1*smf z604Dj4n|K$A@Gh2(b0fnnF3mtuRYhyw8YUT{pDMigA~lNGKp{wNTNM(6D$(49wBwe z5SHe&a@!U}3zMJ|^hSlfs4>uO1I!rOmaZ5k`499IQ+YKwu4N}93VHZsIWrEX92%d( zV1y`kH1!?r92IZ+xAM$n3=A}M$_x>~p`v6(9>`xEYBH?mOl))hmahw$3;V=oD?S7d z_=)bvgUh(=?YI6)GaW(5Lal)b_wVG%SYj}@k$SzJd42o0hTk57h@?u?>v$yW4b@cP zUl_jWal*~4PUHlNo=gs5UTky!e$W<98(F@sY7iL;e5smrp;8;J8$~f3za%H&TiJ2l zX!Ctj^lZ8)7lp0)gEkJ?iH740r76P`kSF-Sbd{obme5n3f!7-#+#~W}#M14D_p;Us;*WqPTIHM4@KNPM9DF@V%ckW!Jk-f6v-3va*P4cvc9u`h&sC)Pz*X$%DE+__cxwMf0eLH>vn4l8p6Fs5IyPd zp>a-?hm;Ko#-hjJ>EpXhL=&5kUdS8*Ql{yTp*37$K+Nd4Vi|Gq5BRQ76(VX5&$(w$k|(n%)9(}R9QR)wuKyR>Nba-IJ@%Rq#$yw@reIQGgfMDwK*l+)~|!6 zHn?Vk%A_uld7JznkBzE$so{!o^k5=#WLddqxKx*C>$bq|FPaw{509oDUyL7)X?X1C=%!DjOYrNBzsqu zL6YPdhV-TBgbTv@4n_pMD-)LLdEGL1gzwpW5!^#Z(9(Ch*SLbDvlnIUC z*RMvERQO5{>X2F)PI4A23Zwb0VSycjOnq03Bxs+Uy>q}C z7&+J94Z@|dK4BV`p_VY?az_zvg(irme6`a2F~X*Hv?3uxjiqG(&g)P;hpG6JbBk&z zL&q*F9xEBzmPv9c2tZxZfy1xCaTQkEo=}8DT{aSLKCbcRX+<=!Iz{BNIt3JQIk1#e zkEg!#{?$zTmyWFlT}y~Ohce?C-YsTw5wo(&m>{LS0!Mz2To%BQMO&jd(%(E@_vdEF zdXk=(_rqsT(i7rl-hm=mdUr8}pz-H9plJ3@a5PF^y8dq~p3jda(@lYkT^6Q@DC0a4 z4yvM%3g|L83JDm0^>#+WNH|F_CbB-*a!L+2Cxyx&tUmDhp(MC(B~6(49xCRTp?oIf z%lwxMLaT;oEa(a3*kZ4DFBlWJjeM$>yVOMT0qE*N;0$Gj+P?B1kxr#!ft(DgxGi5gDy393vG>l^JkIbFj% z=AqamBF$rnl?IK64DA=B$IF7KYzyspkeIXtMuJzwMEqRSRpDuXwy6|_giVko2z(hu z$3>yrkbGT?Hbav$UZoS2KJYrX(40z_)x5Y8Ce7=~sBmDd2W_vKwjUWWZ$E4JxlV+@ zO!WVx9NHLKym$ToJZAp^k+VnRG7B<_^<$auP9Gs~E~N~9#@Dj{w!3vidyT$Gwew>) zX$U1W9jA#0Gy-$Pyiqrxci;`tqhm@DpU-*HhhKt4rlVLgkOYDl#4zH}vjxhSO2)FW zy&}GlzW#!D7A@Ci zSznhugY@NcXSJ5|yvVk>Tn3|CUsp%Tyk3Cy&9?H&@QQlR{ZMW)d@&s6H+6!T0|UUp zgpOFw8i@e*>j;JOcoq9C*R3C1IU;yWFRqobfJi3j8fM@3I4j3Sg8_C(w>G3rTTeF> zSy*NK)NI^eqWe1e%8~Ep10hnxa34hL%YW5nTohfV97a|aR}@in9zEuqEn9Xq$3spH zC_6VJeUEd-pP{6!=^9|t`#_*dV>IiW9v^fSlf4@8|+7kMN!7)L0k6W1x&HcccXNuLA>-5ea=dpA3I(&kZGES>9R(k6v z6K@V$w~uIKST^KT+mwzA_U{(iV(lzINcB3s$gS{pmMm*r2-uY<73{JWNapX@{U3^* zpJ%9`f%VgPrXPVLYyG|mfM!rvd`K(He=4I&Oz7bMg33!F2{V0CeiCK6J#0enku$*NeWR-Y` zIytT@00?KMJi*UtK9cO)^I^fXG>js>m4Ah~YfNPi@!@0v5nG6yDFu8>KaqsXyOK2G zsUQ#0mj7&U9N!OAkl;n-H)9gbWoE08C4tiWP>0!0A`7A*JL)YzjcQhXFX7fOWxT8> zHVQS+Op||7^~MjA^&OY}x?+P(0tqZPhB|~nL20>2e;^~>!kIC>iy@06r8O=lAz{p` z%3+H~QORh~6iLi#Qt+`-bc&I&CPB^6qZ=B?7}Al$^so#8LRS}l<=IeXY85Q|TH0|C z80jBYOd@kp+)-+p&V= zA<@}9|2$+=+oZ}DwF7#5xK*y#AqYA8vvw2$I1T^a{&T+Lb8B(PgTPz~gpdQi5>!+W zGC@}nnNT%{96OnWYub^NrCBz*k(M^}!~DtwU*8B#hd8Dxm=NnmX|CMm{Lc%wvl?3x z*8AU7C6h-F{r25!LLe%+$U|B*nrqsLqt#hC%0cf3Le_nZC^8dZsA#AH2LsU@LLHXf zwrO5nb}t4D6YmE>C)v;nk0B*{vXl_msqYq?aVc)!9c0u!C?4H!9bSY|L2eCCik9nG z53&U9Me*&Q({{)_nruo}#V;~7oqR9!Ig($ar!HC2 zRn_^tuf0`8X>Xo;%rq6}P%#-mH~eGe*(L*m7cUcHMhyP@dL3_O_n&MRg&Dv6vCMwY zcvPa*zs8J{8OX4HLkV{-{2@ukO!PTZl_1?-2~CIycpAQOs=mdO;!InWJSp}Oba+b);^2@HdNDa33?bGgr@JI zb%k5XD`xs7fC`cm(>i?3|g0w0@VOu&x}$@;dWOk=D%;l~ zsLy+DmcGrkLBl4>8=>H%($z0rlj+I!?zHU{z{R%c=<}cZ(zN0saWwR{--C+^+*cnz z9xn^2)UWa*X>1wgO;q6}MBG*g61e#MT2gYj%%JQyIe=v1jh()ve^4L6ISwcIHUFr) z^9Q;6C>nd;4^W#W^2d)LcBcwLl@tM@<$s}g)j6xICn9ol(-atn`Z1$CrcEAM_-dp> zJ0o6dnmVL{pT!ns9DRZrwF|buRsV?z;fA3R-)9U$hews1MN4!WP5Q4EAj=qW-Q0$L zD2N<@hG#pg8FQYwrBrE75rp6Dxh3`1)G(MN zxBK~aCY~0oMc5ilmIf6Jtf-QUKWra#e^CUtf2CwGGAbs3cjWJc6XWERqvvZ+3c;cS zHWH~h+RNhT_@8=GxsaOWiCS%j!!BVe3$|FSmBbChe8LQhBrrn&o*=cZLO&&@^# zviYgV`<9Yk{#_pY^i6OztA<}n^I|+CCiTE(3xqLCn%d>-se0v4UHGK=X z*z%9T&C3eqcK`Ww?R4F2&vJyg?G+XKN9*l4FsZn310)#ujq=>?mjvVsOXSkJbFlcU zv+c293|JJz46rpwlh0&^pNKvkob{EYqx7vkCt%|uXL|IxHGZ54GJNr?X z_0A)!z~GH4PF_Q6;4k@OqHeSvl;G|ZxZmp%uaCH=d6c59@1d$^qo!c$P#kxoZLV~? zYYa{eeq*7Kh*(~J|GyqYe|KC*ui*ELmu7@B8(C-5P&Mm6G4n>+__KyZW(oZvuoZC= zk$NVNwa)DwNV3+j6wsYz)Hc(AC-qSV6uKlE+U#2$Z)&PJQ~KYd`~K4KUR>+zv+U^!qDS;% zo4=<_-2RNdDLy(}-63p;1^G{~bwl#llUB>o^!0< zRqeF2!bexBk&}bw@1Rc*X|B(@%I<8czHLI^c1{=GPbjo34!FltH^LQ8nt~rH z_DM>RQ5VIK-yELPgM*V>auJ+yPLW?bX8ua8E0;C=#E6za7b?}t>N%l9-v(p#hg^4d z5%TuS=AQTGknpnI`{ zm(9$A3$I(W%o$PXfBHorOz}Q@n_2SmZg>XgRxw1+VqIsGX8J37BJ%Xq7=Coz@5s-> zeCGsa{rMyrsfh@W`MH?({Nh=uar~>g<&sJsHCTo4aL%Le-zlA5C(N0j`bys{zEMGs z1gCcT+6RdAj89*jIzqIPi6HVFh}!>`!-LM)t$IK*m_g(p;U#s?{s>%=>Z}^t5JYME ztB9*!f9HA*?P(T1>?at?M)h)vw%H8FjK&RuJBJU&Yi*=-_HRanemjP917WNzUH5?6&ceoP4xSL|X8 zSPte7T^BbSsJ`wLWVa)t0%5_f=I=Gc5awDcppboU4Hz z^1WSLQ$E)qdMJS+53!2Fxt=F646DVWl(kxKhvZ;F$b1vb5rX=tI)6%Qy))v&DXFz@ zq8~MxBe4G^_9pj=V64xDdWT)Wd#Ul7dPkAYdw>OE1PYyuk7=7l67?Fu`~?6CMnHrv zotj16Rq8KUG0gAMI?F@?RILvTDxLuRBsQQ+0l0PWxn+bvE~ZDT^xiMFbp}o zkVV6d`(2xxsP-p^)0h7D9)~3~8$`W%gHe;6q573& zD7in2QR}{z?K(aXoIxnvk4AX5ekCAF#hLBKRX8Q-(t4wqEnewvvSy7$lbObnSVHwk zNiYUaHxRRxya?(#O&i)>nK2H7T3uFM){*TYP6_dw}+1(vHxU%H!zD=$Ex ztoR3|9odqyVBZhdVB+pi!XeZfFYlA5eaf$|R)yLBpK8O*i?0t&nzJf*Dy}B*U3QdC zifE2ce7=IJdg((KNihspccFQuAWNTIQ+BjQML|Ydt^kO@!Zu4#0{X}krQtOpI|TEs zUw?ETqA%;)^9SPZ&6NvR*qsfD@Z?`d4C@ujJZ#zc))@&nLne}*(DciDz9`1%A0qF` zcUsdd^;qSX4gvJ>2|1V0>hu|pc4Wp3%FL;y(Iv+6h>#$?ihO@H##)fguH`2Zk0M+y z#HB_xQH&y#TM(DO87v_VBtr9^uAp&|D7w$pW%M|Pv0SN}0#ePGeO%){(CAbj#jMsA z;5Fa0V5WW5^!CEU{(NxL9s6jgRSkGL{ZLKPK64{WK}(HO)0e95QrYTPc{#5t!gG6> zp&fRfuKV;CT4Cx5s>U!w2StrF=m03s?X&SEV9n7RQ|Q#gk{kRsV_xHT6eoe@bxSS( z31khA#7KwmkT3+-)AmhrqtqfsvKS~7iiEpJ?xFeF$ROf^f72t5v|5DJp^<(qA)^MT zdza<9`$QzKmvdiq5DWc^Wne&J5G??%lDg!L@Fd_&V9WP%E5LGtug6p6>4}2*JfFq> z0jr1OO2-IxhL55Xic;;f_SDd`x_=6L%jE~}JvLsrPOHZK>UPQA02o0ZV9Ml${P`#> z1}g-k598Nu6AUUMGz{;iv1-k6o0=jw>Qv;F0eWJPalEeJkr`(=Z?XT_V{a@I)1IPHZ_e()b1 z+4$rW^eNHlRrMG@T|DFh{%=JUlchstMo>k)&P@je8JHZ_!0)h2==F!wW4hQi0}RAS z&4=$>Dho-i3TbqFwJlhLi<$0`d^yaoTx=)XyslYC{yk;8_?_Wt)_Weg$Flo5b=bC; z{e20SLC-*OmKn-;XGCjEIA3EKmuU&t-awIQRRxP?B$DV?a!?Zm9K@1(WUbLytVu8{ zo6%Tq12F=*ou;yd`BE~v(%=&kq(ONoZvII4rdD@$*b3*i*v}DFu zQq%FJu~msm2VUmt+uR=7_{XvId6QEG(mrCUdA+xEjx@jScK?+j8&>G*Qazz0q7b+l zv4rPKv(PIRk!MY`7~1Q=Gsrk&L8cL0Kp(AJK@q<%rTsD{n4|9>%L~b2JR201$vcLf|+BAmfW*D$n zEJHuo>aM`t@4vx?a}~r~!~}FBg6Jgm-gR0-I)>F$i?C~Vc&KZ#`?&gcv-P6-RS-i;$<*!oW$CH{hY$pK>=)_2*rpbLf9wu zSOG?&z}|9)qy%v*FlL%gsz3a7xt>;kpLP}rQHzfi;jHl!l^iB?DT7BLkVvuuND_7` zMx;3%aCN@&_+W^izoTjAM$4bw-`!%BC#$BIadNx$w;;-D6;qLK@F zDqLE5dsx)UkP;1H1>IB|oBP3ET%D7#u5Mg*xiPDtx1YX<2M!1QJ{W0Vjy) zPG11jB&<#*Rz#f$2td`B=p;48g*h?);Z%HI4g<@d^uD3SY~pfF()JqS3$(ST-2Pn4 z8W>$}JwxmcA!X`@xEP?GqX+p+infpeNdeJpYjQ=N^1YMMPJv=UB8Uw4;)!cmgvz!d;F80aJYz zBOFRvQh{Jkf+nsGryKtV{8)q5{_e(cbYZjlUg;|HV4{D@XxUSpz+hfh*f}BGji<6f z!%vQCLdp^P!13C!%W8%V-^I(i`L!;W5{{REmuas~L5JT#VT1Vp8Xf=RybdTA_f+sU zMMPcIL;M zK1OL)E{E;3*Kfb(&K1U`>erTkt7{#I`97{ecs9na^#Xi(MZN^h6gS~x6Y<;GO$$`f zWJet0HML}L$u_eu%S)Blf@V<;meEN3N4*1u?!Q``|3~Y#3SgZr%xFS1C0z2|U!t3Q z@+0oB2Q~E%VpL>WvPoAZY>}YE?wYn+^_Y7T?@h_&=;X#Y^LF+F+<4~2!vTXG2wV4L zW&`VzW;70#O`mH*+CE}%)4$e(``U0#26<)iniv|8QPB%wWlAFmU}%061*sm)WQ9D2 z3%+N7D4>85p(gwn!p+MzAA)c$Oe$Nrh$aV>v?lJ_SUh&bzYi;F$gjugAX2WPU7v0N ze|WMArPKtBmqGM;Vi7AqXfH^_?^mrT3c*|n7#OC)>;VKth`<4UUI|xGiU;P2JwVtf zi&zl0?jwD)ck9&avDLv6PxOog+t2Zxo9&+BClKT3CG9H`uPFosEkp@UZ(J8oXF~8! zV$Ao6b~{jRFjo*H9~5@PeJLmx5L{pF8BZ98b0O|Xspb0!j!I*9=eXTvYltI1Z_Y=dT!?x2jl0?EdvF_%a)B}*qg*vbufd?6 zq?;tQdb>%K3%-{JHY>kjNXzSC$Pkeh%QHu_y}9Ogpbdt;HBy&5!>Cq*I}fpPI%i^H zL99h3L_nvnV_@^F99>$9_i$YMG~Cw*xn7uvO6%*aZ=9T;dDI&}a|^TGA3ncT?Y2$r zu`GeudhP4OpJD;ZD90j3a%6Da<}1aP9;j1lD0r(GC1U$2((iReQ%oRNyFyjzytn`= z{s?0@bk{S5*raJIbO@9GHChz(u(L6$Yt(s7)P_}k>vGeu0w3PViG+7MU^6h>1uK5o zIs{fgtz=mAl9>rI;ng%20%>Xet>?BqcRf0&-NDVkR71ilz9CV6CIhmhvxtV*8e!7Ae{}#y$+!}c?TOtt;hjPPpUJz_= z35;+>ndE)Gvy_Hmh5f77UN;2pGia{M?Hz9JeWP9ea$ti8y(=}Xj96-SnTD2@b~(UJ ztT&a=UYM-w9nlBo^JogNj$L_UoxpjBW4|i{7(_iFB~!=SQcv@elKv)P(q3xKYdFX? z@08E%nHy$=mw78l&~yzlQ{B67Y^y8ksVKX+=5pXD)I5t2Sz zgS$9uPh1hcPpP?H!gH_yCX^~cHW00hc69~Bbz{DlVv|*z8SWfK*bd0~IbaKGg*QIU z)-sOF4xrjbaMo4NV)K8|U3DIVoYQ~;7em`%QI_V^V5tYm{T14nZD_dRB&joBnZq|a z7tf|JQ<7e$T0Hb!{x%IJWk|!ufuad%2x{3w9Fa=ZI9!jvx6}F%sSiQQJ-!;AsR}!n z6N#V1rnvRFa;Un)N=@OF)idvu3HmvJLn^)y{(o)`@A&OQAZ~@=gkehG5`>7q#RV)A za>jGC8mJ6=> zretlc5!EX(fPp$l8J0Yz*h8+lp{GzYDct=EUYLm=;mf?@5Z12zmVGy7@^5hj%ZS=! zK|yNAup4gY`O>BdR_3!XidcVL_i|B~{;zjZP%i)v8Dq$gIy!w7VLIf~TC8j0lz3D$ zgHe!uQs19~d*Hzv9so&!ep<$Q$A$37M`!rqsa?UGAQPw#gt{l&m+{Zo>g_um{+HIy z_Z9MM@Y?`E0ibbz)h##W=PhWJ$9$6K+g1NY?LAolIC(zj!F$dMct!t2Q>rD&qcg3iW$`F3+p=r#`{^ z1H($4B(0%3i1vRjiP20}5O%dJAN>UPZFk zU9*n_TCmQ78L_$Z1uKMgo0k9Y#TRX)N_!ibtiYuXWYq{f(BGFKN{CoJsFi#@R5juL zth5R}c|_DXUjJ{3x}y=yf|@L!wtaZ2H|5_`!R<4ClYvZ&Ebxo7S7IhLvu@MD#$oWCg`$nNJ+%cR!DGcMv8S(MA?R#*;rkM&4r+}-kR7%TRNbE zj^WGNS?VGqtQbdX*?Bl4I#o;UQoYh?z2uPmWKEdIPUOTDT&~f)c*xD<-=OwD$<3a| z`TKz-MP(Q`W%Gnmambqxd-gfS~Mj%XkS=|9LrD4>YM2*Q2GBRJ-rsm-b^ zRS=qzq);(_B^HbjHOhlgu(OF74UjHA@*%KrtMDlr!0Y3 zalc%yCI_cPOH7>(h_gvt5QqJRQkZQJGqg01u>fTxICXL5rcc!yrM^<1Y-7od) z8m)cR#fl)>3u{St_+f!I#RlI*ze?6n(ZO{aEQ21she)d~E2ElUil+X3dp-I-dD%M{ z+4D?E4>TH&qQeN0#{{|N$u+AhBM1JXU~y?->iqZ&zdw}7>8I|i-aHI2<2BD4fF$p` zfeX3E-1ezTv6=Kddx^p| zvn61Dy{qD(?c!fb6QdJFc?9JhpE*yv!JlPI-7=f@W0%Qu@2u)}E3dZXBFk3s)vwG{ z9e4F*HVPlQHaw8K(|UF9!#8PU@WImz`AmINNIg|IkAR+pizR5_Agz22!wc~cwY#+T zH73=~hxl!j=Ko?GyzsW{14dmF39?4n&K|H55XT%kJ)djMgspRge3&nFAgI!6LmNeV z^+P0Jxfp_*1~$u~syj+~m4Z4reO}m22ji(WS-$5(xdLG2++E3Zi^NRrKT>78Wn36# zExxsx{bewpmW!3P^{df=X`fd{Lhnh6M8DN!lP^bq<{EmY3Y}m6_B}zEh_?E)*j|UI zMkFui%|Q!jlcI*d*2ZQew5epR*{F+b|D`A?$ZO@h5owpTqRg0Cp8c6L(2O&x+E@*a zN1suuQN>n+wH8_u{%cCh{^N21)q^=PQ4>e1tMFaD-%U*wObsc!T&?|AX4+}slTq*@ zcr7I(>9YAaPeGb|_m3@0mM4};)&*sxNgLDqWG{6xe-uB#d12+gRzG3f@6`ih0Oh{e zd(^Z=87JQutA(oZ_+no3lkbPiZ+V~3d#g_$?yhaMhtsm?8|)* z0YOzg#jAGP0~~G%K33{HQd$^=s&?H>^4ts9-UH@rj??(GBe#H_`5+1nob?iX9x5Z> zmTkXdHhmWETrR?elwiDke0k$`f8~v1xjn*TefDMXdOAioC8?CN;q5w-Uw^(dJ6tw_ zTEFMfZFuPUS=hiW5SIeSdxjPV8kze8*mi#F;g+i{=4usx1y6RkIxtkYRjr#Z2HRp0 zYz;n_CN@@p>RpsExolxW31hiJPkd2SCHUOWZ#6+?AFIrh#z7!iWLh$y$Nm?X->Z zm|-twClvT$%NPNp;E;Pfu;jheCQVSOe7I-{#f(f4w5U zEZ@eicn9CA(S~{0Y?JX3AF{Ih_{^yqGsY}s>4WOV^+{347g(OBsh(m0dT1O70c$MW zzzgwFO>lB=)syk?3$nejwxIBQ&?0Rq&AN8kcrhiL!yNPDel6Vl!{Ncf;n+XVvW0S+ z6A~s&<^Fya*eH>2Qz--5&9afy@BWjKn|!F*9cIBsSgw?f2KWW;CJ~4m)S_ zdx6*5=(&;4-6WMQw%&FhV1G@|ghnA_C}MQ>f`~dTAV}yLB?l&AD3&NLdxW(G-64#K znBwk3Wf}h0UkCP?;~xyIu&yA1xlRZC?)|7L#V-eh-TpzE-6Gpg4E~k4dbd=XOTn3* zEtkt3iGFdLcp3KQ7jl*Cz6e+PHO(O_6DLL|r!k>i5!jX1QgkNBGt>Ixb3Z=c#G`x0PaM>$5(HgmMB1G(S`icK`M*i_< za*(&!mh$7}&BIUZR5|5<@xQ>@xKJm@q=YtCoz4^Xj)9*=LJ}F7W}{yRl;k+a3{)Yv~9+m=BXZ-aX@a*>7qTd8P-y}P#Tc&Ad*np=Y zSZyl#WpuR865~xzU>CX<_b0wP*$pOMTgdkHPc<$?Qrk9JnsZ^nT-LRcr4V(q{PXpg zicmVY&m!x6z?rN1{xHT<8gX>twF$5hlm?~(&BlOkP5r4xU5aBq=X?+x+MGIo4I?bi zznD@*K`FLpA^$)GE{vJAK9W|s<2m?PSa%XJz^g_d-6e-$(5;bw%t>iSBh0^t_Wxq> zklBOJI-!%4;l}H{RZPE7_{M)2aiKm}BTtcx{dnEuj|N&xA0?kAt%#l{;-^SmpoGTz z!tNA`212!y`f9HQP56=$7ukxakvi~4wE|cu>2bYv_I|;p37H1#HGoxbK`A3XdA!m_ z-;X{RyZ4tM-(TCT4E44quBx;uT~8nyHpcqJlSPsz5EAG=I30eD5CC66 zaAh;TZqwbEuanZ$kDtu^vh97@a~p)*NR+{o>;+ATn37M6g`xUx+E$GW=Kr23o7EL@mqi!B6C-=r zWL(LU15ZucwmUQIv2w#Ldem>1c`=}*PX{|3`v6XyT&yM_^;-s@NKq^dKj@r2&2Mdr zXz5n#wW^Vj$~C~#4d2s#`Frc$1iZYL%vT}wF+LVV7FIf(=)P;y*Sqiq=7?IfQQ=RcGRLcOoBzyxL4LW!1}InW*Uo!{)0ry=PFG+!+d ztD@uQ)vI6|AQ!62j7?6zGMMu}+mM(c^PrSx`Se&wd*u~U*H0R6J^R)vH3Tj)qq zlv=w*8>{V)<~IG1V7yyV;oU!)?2d^T`O>K-Mt;xfZ#wHrMF1kZBN@kPXXNCH-5*Jx z9zvR&ajBdsN(e@XsM6z^`s3wp5l>j6g7y2N-mfMm%`KT0EiVeD9Z!`9ieTB@%%CrB zMY=MY*xoV9ObA}jB9&^K_m*;me6+~;nR5IWa|BbNg3fi@TVpT6SQ=Em&6>d zB!vL`*onL>;Nnle^UMP=qZunG)7RyErvzCtGbo$){v)({g4EjBH*g_L91AKfBse5Y z%BG;k$^vA$$4^kmZ6Ke=sHDpaQf-pnT3}1GH}OxK$(;C{KPD;P=b?=y}GDF1*Cpkefd}7SU6dxG+M{Atlx+F!%x`yKx@pke0rK9tMX8*lQr$6T-ytfL} zVS&USp;in)#5CY5?2#iat^$RHPAx07;CUjCD-8jGYnOjF z@TgPx-l))iWqb~a>*r?eIb}j&3Wz4)9b=mYm%9pSm?-(WuqgbrEr zN!~+Lbc5k+b!ymEgpGqckQ9((V9jK#H;KZr-I8?FjX$)htOIl5@HMTj0J>kY)?>0$ zqdcd-TXw$kz58j-iwa@$xLS8GS{9tMZnxTx*;3bot?JyU<>jk2+U8qE;2h&?r_4S} zroHhJL`jJ&`pHf&qzePzEaZVI_A00awu_NW=@8>o{lR)o$7#^$?i|sz6A<%dNN{U4 zwFA>7y78r$9Y}9ibTzwry=>@Z{kiH_1cWf*G^oK{yG|KE4K?m2)Y%Pv9B1`S-j+Xv zmMkF?kk=(V^HlxY5hR%sH5z|hqF(FmLf!oDt>WX@Oq^s4J)eCOR4JNjs;E%t_}L+e zHrN>U>4kf!YME2b?)SPmJ1C5w*6Zm}m^E<^Oj%x!l%yUc zdEolu%(pIVgnua2cjoMG&31xGjEMVPC0wsa2Fr%^UIJ0Ri36f2J$lFtA^G{7VYvSx zkpHVyD=KNMZ&=z)u5&S|qiXj|yeqA6g&#Cd88j5+=|O;!aaq&MmlqTd`lz>fsVD*2 zl~^>8biDAUNY%uRN?w_(&yvaE{yzS8Vnzxv$>PL2wfluRG#GVnQ~m9#gyX~v(*4Vp z66EVmoFmSnf3)pBOY7ST#qF`>(lew=eSg3a)Aa&-QGl-p=AKdxVytWcxyY)^kbPrB?a3{ac=5W-B8%$N;8mvaP{JrwF&dR5W`lw3u_t?y zvNrv5U0a))0exXC){u{j|Kj!8FbW`6UqdT=LeiWRw)Uh*hAJv=)J_jQf;czk`^4y2 zA2QQ>Y#d)cb-Vk!oGiXCUgKQo`EFI`>H<_qb$=27h$PJwDFhXSi9=`101!)-W`;R( zRi~!0kS4WV^A(CR%!7mf>fjX1ZSS*?zL~zcw-4IxNf8-p02x&dAVQ7%5V{PzPzYhgCjWhIRmX!~#77O3TetJ{_ zZ-{4v=t69W^qU#5MtcOASu10CV-}3(uT_tGPOhrgjW-WDy3Pri=`s!0HFD|XLofYX zC@4c*Mm-s#4p3o`ZZe1#%y^FR$;r;^Nns+)x(?V@*j{I%Koo$%gb5=kutU%4#=n+! zbg65~?B8i)lf#z4ROwZAEr=$8Bzu*3j?&YDPDxq&Iq&0p_A&Zy#giwx*PFPW6DGow zU@5#*KNho`VO0p!QMxNX&|qyx{W6wEXdS(w&qPU>k(^n%n2sD>8DPtFxjPG2C3*bF zG@MXoq0FpQ6YGoKAbc=Kyh%?>#->cdtgZW6c42=vdS7xTRp{nkE;4RSE*WXhqDseB zF{e72){q>f98^MwrdFF}5;i&#pAi4OYNBvhZ+yk6ZG4W(DTwvw>;eUd;7=ek1&+l` z9F-+DxWqC9^b5WM&i5PwInC&Vd+HbdqD<(^`IIsGc@)NyS^kL=-ckGM-IHZ8?2a>(yV;+kX<(8ZbMdM1 zyx~}3f{NlqGY1u5D8XDI9PdCW|1>1oXx@xX()U{)4h7gBLKWE6LuP-*Cg0k5EfKKa0;`wYfs7GOaL{K~>I~LdH=8_}qfu?28@HErCBv2#RZ2_uV}; z#YzxX6OkP96c?sKD(~(TnEo9TlXinrFqg>*`U8{b$nThI$sD^m^z(=m$r zVyf5sM4>1xj&rhUTf2olvT~S)M;!`(SuEKt8 zkKnDf32sdE?c8`8LDhM_W6^6F=zqG}IpY@lJO8~9n|J!CwlkOY@V6A}Cl=7zvDXuk z+nsStM$evr{x|YMT&G)mK2NSUg!3;VwUBxGfPf$Q>MSod$S6EGd{65Nzx`0Y4hJ}_ zgA<_a9a=1()oeY@za z#oZ7hg>QLtsbFOHh?trFR*EpqX9Qsq{J+7zYidyHg|F#)Cwp-xPEc~+NQ2VF=<+kp zY_kI#50$Z6KSJ;gb%00=U!+6?UkU}6@jgavGRn1k{wIUnuax^gW8*}5s6XvXmzT?z z`UEj=dUIAW`F>eUBo3(jX8aWaOEP&zkkfydnn`o|L?+(d9^X5TOhj0Ul7-062Lk|D zG^ub2p@7Xfk7{Y*;pwH;a|uTbAi%B?R3EU(fP#?3 z)apf9O)54VmQ-^)gRjh2KV0yax!w|ZhMu#`Lc2e4BI$u14#i zO;-DxQ!pw2GB)^fHb+f1hiw~j zPp*kY`0;0c-b+GKev`fOgH40Au+XHPd){5CxGRpEoTb)664nhl(4v$|8A{pU!{OqJ zD?04}ZXc4CZ9*+79& zt9>5kc8vq2+kxC#Dcqs4GaGiRRRNmSw7w{~7rWADPaDNGp%Hm&*sdcgh!_?yuY%Zj z1C5k7gg+1)@s1OkWcxg&-(~*=u_#C!M5dZ9^|y35U8^v*531y6lu|m;Qeruio7#>% zd#GQdaP0Y=%&P~^XM%b`m3qcqV>(~VsU=%6D%F{gu>5S0(iDQF)P-!Y#<>-E;N%B; zr7zuf^e7q{iJc-9&Vp6A1;jzx@L(Qz&KL`~sgL_IXZMRHaN~IvChkd*TNq{)eNlp! zDzzD(~&aGq@$E1B3Uz1bp9XG>s=q=T0zrS%pL1u=Axet<2vtqnXy3olYx> zil>^ae6ngLC6@$~QS*gr1X+*?JfJ^0F|jIxk^_kfd^s{LgfNWhyyn^%^<4jODstZJFZk29{{vCoBzhco&P+X(%u|{WohxT!{&@*sdkyOdb*RERPU;xL`Y6 z{!Ue7$5PRswsZlQSALzw>IJtaWCqEpKWEI*YRi|B#wjU;h%UPme`ZIPsHi>32LG++^~?5rz%xb~uH%iV3&Ir827M$4{UY$zq`>R8qDa!jMBY ziqv<+F{;R;^uMU~#4iPZSdkTr(96a!h%fjD5-Cx%wo{raO)WbM%?7C_a3ZpjniczD z`AG{4uD!&-#J03hNgrB(0knvQ^!;Pw2F-hi{RG-QGPj>AiLF1?BTpP>`^`<;MP$)6507xo24CM z%H{P)v_H?rV#6FPX7Bohes*JM##^@NOCQbr`3MaIKuoy5*l=%k_F7~8&ugB)#LyojljB+vL^@rq}`WOZ&wnRAJm1q5x*2Sc3 zZz$;uZ8BE6qa~lfC?{F}6^dGu_eYDTwt0oazBa|^t-)xv&KyR*P3!Htnq6v$lL?eV zaXr_GMLUCv37CGBMNm=`fG&1;B0+^QQJzTGw;ETx(Dr?Vq^sxIrNT~-axw49Wt@cS zKjyc=!eY<8k4mRvcV9vydnW!jWSM!5X`M`~H^JvyDNF|dn__;a+ynz)n|`YahsFXw@ zIn$5WeJbSNuS&lcjn86X&5s$m%1{Fc>@@>dc1WPSRLBQ5GlxmV{R7BCNRGU|8YZA- zR9+5veoic)S;QHXVW3gV#+qrVDMYijy8C0GDmMleXfyRUruNb!yI+dNQYj1Ta7dQh zksGuDu;Cdiu}{Z=E=a1*eZIf87YzT2o7UDjP{K_o>(Q_RWWlNOZxt3osX&sRjn;rjK@v?d{c^|Il)AAoe<9F6-5g_Dxv;j9lu zk6~ffj?(UJ_P|edrMy@~wMu>e6oH;UF8o5RN{3HhR~cHiM{q3HyBZY7xK^8dk-7h~fdmjFrc=Tz*w@6hQldR8?e3CTVMUeJWHvY2fyKVdO zDtqz`%HuXCc_{@J(@wu?I+p4 z5GN*%!;8WsL97@6);Stf06RJ+JyC|V9GRbwAp{ia4}Kt9D^{~Cm~bS2?-R4--3ho^ zL(cX!5{(`{Pp&y7wRR?5Qzt8!8OI zB5~EvaC{`lYq{zU4W>^r2f4}qyipgkPl$ej?h?4Ax&MBSu_~>iCR<&RX~m`FNjW!qc2=UFb@Op zrxG%wI@G3Wp|~&=Em7NcZzGSf7H0C+&{-*|tiR6V>9dlR!KJkmy7Q}fo0NwT& z2z^R_w9?^?eZ%(eOAq-_tZy?W`Zj}OOSH6q-!Fto2cWwZ^S20bBiv=^8BiS^lTw{-1|Y z&Vte=Q5w7b%)0?34q8l5eCCZKBeng?PB1mTS#bVi_3;4uEw$}cD6vEl@{h3IdHOSA zO1d6_S_7a0xF}N*4HV5ZyW8xdrtaER+Ucjf**8deVj17cT z{dbhhFg#O@=YI=f+9iY2GMkc7L^`I!+k=zp@hN!rjR(`;5 zm`n7O)Dfs0>cVV!;)))=sX`eRZ=556}Np}h;lwM@a|*?^?yl;;p1pd8uwzv zVcy2UXtDl~If;RuRI(qWh0bZ<^XnlEiEvPYomdxe16SL;872R{4)K0sV*R=7q0X8x574DNJSl*x%imybrh&7PPcP}b8Tzb&L@4Wzghu|U+ zF|BMX5v=sx*2<)@k;(7u$Lqgz7O>2UsceTJWYHOEHBS=;~w9b0xan>FyPO#nX{=>+04G#}(p|y!aoEu-xZ`ME=?alY97h|5t7LN%S8$XCD4^5e<<2K0+9TnHz&Tc)`af=p1!>q4n|_SY zwsyLI$dU2E7#RFC%iyPn^~-c3r9nZ<4?{821YDE+E$|}_e(q{{G|$Nx*L`G{Dzfgn zYwZ?;>9x`39*FX}AYSGgN#goD6dKKnk6F`DWG;@JgO|R-tqX^DM@1s-ew1p=BuRZU zy1Qe0Lk38#ypF|sHr+{CFHZKWLTfmLn=#)OZ-9~5Z-qTi(Zgliao&0ScP+W2>l*-b zTOwWai69*o*)dVGFcSLxqvY`ADv3q^qY`L96N@--D%$EC;o6B&hSG<{VqFQrJC1(O zI!*)Q7LpG>$v63&ekur67;m7C!H)^ua&DzYeJZ>at61yFmM9PwMYjwehezM40j=7O zggxbAJ2;fLoG!XB>i&p$qjHb0$}Gg7Mw$}mRRGh@jNgD=ft3{{)!rj)#t%0bFlOE(Zk3P{}U`HvG@E@}2#VwF6%+c8d%}%Yu^6KF#;tVwp-fnv%WWO3}odaQ^>cdlj+La?6mp6N+vM)7%wyB zIXG8_(fqHIOrL3foD-~Q#*h{ms;>@tu5M3sAQ=)$KVWk=Hq)n;yqF||cIziL<&p$( zY)0EIBBtHXu|eg+Jc{A7olL6u=MP1 z6A8Kg!vb7^>!PBY{&9?)m%+6`Rs%CbA?1z1;}1uX1XUi&93BRje(^Kq!y#n_MS>*; z^#{Yj6oO1i3Jh#WOhJReOMJ{)a3B`H(t?CpLBH?XC2_A9+WxSOwSE;bQsDH6QsD;qQ{bfxw!FKmdTfc6q=(zT$7(&mVLTGmfBpgeWK&T%IPxOEq z5W8}r9l{({;v}czz1eQ36%(Q3%7o0{5#aK*_9blN3SI89fxs5Eg-NRFaRM7;OWvmE z$<#C8g7>8Aj^?%!?n`zb01K!*rTycYK-{B~TH^802 zEdB18yp!1?-Rnk#_Z*nUdVoDh6N4&sZ*L|$1TE)CEml8bi=YHDVo{~Av$5?3Jd#B@ z)4Ff5nR#{Ns2TtBh|2fD{z5k+no~eI;flflJA=cwbTk`+hcGA+vkdZ%6O@K@>%9nZ z5h5pU-2nh476E8WXjBC~GJ_^vf#qtwMde&s*V(E2&)5q2G-!Q*@GWcf5Z(3)e;Axh^4y#&z%L%*Baj2>PIp_(_0hb-T zA<@41jOM#lf-N}O=*468!*bvUv^7IPBTT}j5oE8tpD`E8h`+S88##L zYeBH&xqVM}HpcXM{04&icGsVx9ES9=yYi(;m!7K%)o)Vae=Mpihp{G-vMkVsaiR4T z%wKpqrf(`EhP$O~D4+(_w2h~Jw~zFmJWsT96IoHTN`H^6M}q~!%yB!*EMah$Iu<5E zsfut8e||vf>y z9-ycnZ5TRLiRFI>tH;9_Rr`|))R^;9YsW&bNZX|Q8#7;biSzs@zZo#~{o))#mFfN5 z2LG9hmx~;a!|NHS`tp(z*<4i*#~GFU^*_ll$2*2cYpR`2=-yyYB^F!55U=me-O(qg898NbSBd(;FY_5G5A92!_vx$7YyoC=n|Gj zBs20NBeE1*LkGX#$XKZqh(t7p$KBA8xZp$Xa|G9hBp9q;=*@S)p&q18LS#A{yh%FL#G_h1iyrui~5>5IlKO+dnm)1U_E zC07qJV%9nM1Zkr=eJ?*M7>AoVw0p=2kL+NxGAXhwZ(QIUAma>NdYXFP>mwWFnhXvrAFI(;I_yK)~?7Tdi18)4E6a{S2cJhHUY(VLJ z5oMiL1>@2Tdu=$DEaWRt&orGjoNb8rF5Z8~SV}A4Qt%s`ZU0s{sXFF*&U~0ER zU$=jDFt)tMO`lh~{}fodrW%wcNN3zn_QR{OoDJZ$y=ZRyGfO)i*-gSkwmaALj6dgJ zfu^Mhi4lHI*|G629oGMzK2CVY|4_V@zK_ATRdZ4-ff#;cKU(9KhG-wBSxq^2RI>B zR!9eBg@(%9$dm_0NE1uOC@1h^R~X)@G@t1lkd@_~h2^G6PVwM%c;N#Q+L$4poqb<( zS_W3!L(pmWc4ZxlFm@0j;qIqz=5NCvw}TKx^Q{Ln>YPIx&$n}EgH@b7+xz0K31DW7 z4@DsP?OK1Nri2iJrluiiWet{sCL>52`dZ*M^*;W;G;Ba(3`+Bk`AwJ@#Dn3`F|6(at@mxNQPer5m79=Z->XWhZF3t@SMB zXv5EFOcF!cqxpcGtVaK?Z)rCzh%&tf)g_#%y?kGOsP+#1=R6*ysd2Kt*J~Lsj-86v z-&QU%XudxP$Ft;5>|<-TO=lw9KFEK*~X&JCtH-ve+-;6x=NtzgHkO!SF9L3aQK zK@Pi{6klcts9zMdUcbfy$@1zC;m!oy`=t%!6%tjyRM_{XU|0P@02$(7yJRa)p+p7X z2G#Y1yDn+WMQe)vLu1Gct8N|ma~&tSL`LT73V}eAXk_Rgm0>sZELP~ClVE;s+}A$< zjdWqaFSxLk*`0>i*pjMTatqJnoUJ+T84SD%R-aN)zCiH>7f^SPf@NJutPO1I3!G2e zdy&zod?0l0i17wqNfoVXyAe~sTk6A{)_Bqc-{K$0=`S5^ul+wOJ1@TU!ayYV+(Ncj z^AeW!CWzO%5QOvd-4>NNEzn#Zn>xICY`=~#tU1-T%UtRNQo=Dv2O8qd*{*X&l9A2> zo&_Kg^rQmKLH;|NYCLA)2Z89~GxeAI46J5`a-_uo!{=VIe_nPpta_Bc4aJVq&7;%k zqY2jeADUCPWdi}#xgna5jT%3R759nF;lP@_m11ntlcFX^DtD{rQWA@Eyn#OkC3Dej zsVM7qlEpn^cIUw@C#~~ZtUH+qS2_2Wt~n+~9K-H=^UY6G#b>Vz_m|0?ZfEf=2RZEz zS7Xuw)~AdaN2dKlawAPgF|(gQJjH*T{9~9nw}Q-VWR`9^!|1pjW!(sLsB0*fm%KRm zeI%f>BmztFNun5$6MFaV?q3oprpS*!{P3C#X(e%FYy*Xw7M+z42j*#&z2(fjB_!>B z4f>UANM4=sHmzU>(1EFqaLO_H_WO|E-APcfn1j=PYmk^#R4Kz?t_aqbzt1P=YShxW zd3k(xy)pIO2^omeQISs9s+=m^kwc>B^AI<*8z>|%gQTilxkPl&;nB6#so;P+{|2P5 z-^-drI+(Muc!5N8YK9F_QP3{P)fd!}*atr&SykbS@N-Z~moT3N^nJhO1CIEe)tou& z4Zd4r=byS|#<>LoQbBBPq|%ef!S*JZM$G8RWi3od;QF6cJe{dF_N_Q!Vz1wVQ3!eJ z0(OKFdBv#Mba?}Z6N-~6lBGt*8#Pq(%cD8<$0$1l8eQv8ZGzjfQopigT!dJ?Phhvt zI!O?5!4qmGQc9JDPR~O?#C?+}kJQrtsCXS=%Hf@^_|7(M(`$myvx_qzdFwiG zMJs4IqMzx*-67Pyq1X7>~z5G0v88JVPw&$)S*v;Fz_1%}>cp7*x zY`5~^^PCGy>&-?_3+`4bRTN{>G^z%m8mmpQSS&OtGcU|Ime*>(x!u zkf6WK&p1D?+0*bG95r%boxMt_wuJ=BVkx8NRd#=&WX^~vbs^!JF6f25DcnKhtfH>n z;OH6H0=Pm;t7ug5NkWD-0<3N2yD(qE{z4H4^Rt=K9z~ss%!h>RP!fF69V`?7u^XDg z?uzzFJfGd&mBkLz^0XKQ*8v5pgRkvdr>c+FOWeto=;Pd`6pb~Sp&J)BURcW)-%Te! zKAVXQ{A}>3nD74;TYW+lbn7AJN?&_pmIvm}TGoWn5B(-~boPYNHD$uL`TJa&8ws{0o)62SHa zdg;<1A}vTiyTQ)JXOUN8I<6z~O-7`n@Vk>s?bqvS`z&#oWKp2RVC zy%`L~e-AdDkBtqlga0W^!@mCY$lf*0@d}Jek8JV3qTkiekOmZr8e*4T`)J z;vNZk!8|!L-fAb4dKTcjWcu;OAQ0%5HowIYgt5ww_+r5(JD!Ah!`>Iq$RWS(kDpDa z#N^eM<1!cO$~jWlQ*%yfB1c&a$-}2>M$M?fRebAhn;-J;H*XF|koPzGBc&@eOF;IySpJrG7wypFa7Sh9YW#0I_5}Y(x`p3^~5YY?#x&TgIPh z_nUfy*mNORr!yxUwj8DvCHXUF$r!OY7-GooV1&0e6mjoqBOxE))QDsS${9LN)yWXy<9Lsvxo+(07j8_0v#h=gYg z%^}-D-Qf)-u3$9)>v$;%ciKXed=#-XmC;N7?K;?#nXp_JwQ;edhpFQv&JshSewdkO zTUVq|(;#G%tvtD+?8g{f_JRnyR#D`X7TOrN(xaa96fybH#D#zn3`7`z_Fkr)mF~rw zjiQ!{Z@F-^kX8@YZ=$ON0^RG7(7^u!3}}3pNR7M1^0c9L2AGmX0 zxfu%hIJWdOXOfVXCe|LxyF53&GoN@`$n>95S_6}@l^DAtdrKKj;k>_^Ry?KZHQ)Rb zAl_4~;md)3DbZ;w_KPK36r+`@bq@Sn(-o=w`WM<(M>zT`Sxwt_q@4gy8rQ0U(nj0T z8J!+5!nF?C-<{FR?waxC5j5xf;ln#rkNVqPWQG)v1$rc9wn#EoAFGsp9H>?O&s`=B zs|2OL==(8Lc0HeDXG+86SpUGU5a_$z#)Q<`+D?8dmdtO?jjoa-^uk~54zLaYo072v z(U6oSNi8{ku`9lJiMon~LErM*lq8{ODcO$n=%w;c>i93|p@NDDMQMVWDJ200ysbzw zOYSnrkm(l=Cf_z>Cx>bn*H`ZH6rQ`*4Zot*Vjoa=Q9G_Gy>N04gk)FYJ<=@zr~#)X z#z%CMw`OLDQ^>;L|3$2*i@i);Dl=dN$Q4=^&Iw>TODoVQLB86=_(y0a42_pE7eQcu za;p^Flon}$G`pG%M!BJ?PQO`OxG<`wvpL_>@=P|+I@X+x(+Pe|XoE>+&ZmRuV7ob5Ol2A(bwOUmoiT0Hn~@;+;pd6cEVzu>~M8b%;SfsEs5LOiMCnQygQ=mIS{ zw+sG8TgO`Vdb7o+gL&uyA^<~HpJrul?Cg$L489nyW*_91y2irEOYo|pNM~EtEukAM zvd)xoi@m|rv;kSDQQYh1%p1lWIx8V60t|1>1|PJN8hA%Y(V@n0Z+MPXAH)$|iNF8( zA@FFlLpxx3Y<$J6z;{Rlazy)c#e2gQ(u-t#=)L_aKhgHSetWf&BiVU=-~7{$a1~|f zuoquNSM)j>Si|H~x!RtZs^6N}$3!*!aAEOr-ctAHPwM<#y1*lD?Y^D6U zF)F;ULq?mg_T~?HvK`;3#{uuC2YS4V&1el4-c^W09D!W-3V`0~BD)S``OqXEq3)42 z2`eeb(VBOX`ndaAGN<#^TFCa|@{srrVPs3MB?ZSWkdK~Gp;Nt{ki)_1l9FeD?#w=D7e9j@>P)nnsx1AOg$ahBk zkk-N0v)sv|sd=^`0Y}g#K;UjcrxSu+ei-H+mAA<(dCNKm`7Ag6u$A>qAb609j8r*F zrx;y^NUqgW1`C6$;)5X&kFy{cpCw<* ziIIfFF|nFD4o!5*XwqeiNG#*RjLVS07&J`92%1x-)O5JqrlXS2G(ezCUgUf6wKd?lf{3)D+!#Dk*Rh?e~lkRki}9v zJIP;FHF0#!(mA?ocAn7J#mX)Q3n*e+$jPN$bgQa1Eh<&rZ+dRYmuXR3Ygo<^^m~U< zqLyh{M&$?oXs#@AFryM6*%_afzBnR8OU>zXTZ&_;_2@?JjO^Pc|6DCp&CY@;XYKjY z3goWJ1M;CKv*oObYI8^SyifHGwPx~|$~96L!BB4&ARWkh3Du_mt9f(iyzc1=>(kN) zOkk&G3-n$H9;D5yzmS>^!5S@IXa!zRb<9_ngvhh#%M#J8zM#3cDVtQUWHlT7#jEKS z>@8Fcat<^2Hb;c{hL3;682mm*qx|Q-dmw#tOvlOyJ=LFxKNFxYfRO4>Quy0=kvqHD znhsy9P%|!TfJ(ZCsm(sOESFbKA;xNYX8@v@fDHVdo^@eoXciU4S ztv(iW22`*)FBYyKme&niWb?zRgW>b`s%xX+0{i{_CF54}`~5>B6K+HNqry_QGQ^H8 zAu1#fbj~w^<)1Z^+bh@63CxJfP0)Y~M*4qofzhj&gmQ59bZqUq{d|5zYp*Blv<>Zg z+@~3Wl{r7_QD6eMSt0DUADaSk;nJAAK$IIP)R#UDXlg3k1DTHSQTZ*YVEOShNJ5mfmFNB#2)`^X`FkoI!y83n~`t6@PU6}L50h$ zas5e9Eli6e2~b+Wf77m$HcEK?T!c*zBeku|gYt}B0mP`)OW0Jj zh%!)|3FjFMMEayVwiIC^oZ>FFcsNc;z4}D3g>w=TG1Wp7=uyT$|4j1IN5#iQ$elIW z&HRueb_ZxItvQ5vgcga z2p}i5H%7Wx-UZ*NUV2Aq>XBnMm0X&2s&6Adf;OY^{=g&+>r^1}Qqf85#x z4#QUPz|LxjsyWi?8=3Y4Kk}F-oYa&%wj+dk+`6c}4vXZ>frCRk_~CU7ancfFx_htC?oXyI8JrA&FBi#}!ULzAG{nLv%}QOS zxW-yWQSPKERlS5bfy{Ifk7f@7qk$4D0eO#GcIxX>6FHehaD0Xvc{bT^S~h7}?Ql{w zBI-OiS(ZdlFshmQ2otMD$%=+J@sCjjl41!^`mXK6P3Wg3_>W^d2k?;j(W%pr-G+S9 z%tkrWY%iKM#&A^DN0!~oEX4P;%UI;|(ZzK9Y=-|;))RL0lDH!CPa`!RG*9s8 zG7_D%(wx5)?Y*TA3<%^daGC%18i~(>N<*81kaFVD2;BzlinKu{m~3e9=skl~Y*N~@ zh(I0u&`1*_DCZ~I-$uxpfh*;-RLpE{l*DZ2AYaO@L4YTBGfiD%$!Wh2-gr%TvtAJM zy}uybPlzKi&oTOC1NI;hV1g-Ti)#A=`?mk}*6GEX=suR-7sbQ&MH@1HjluCne}T^h z>v@r1mz1!NrPvVx!Y9I;-8t}n8kk^Dq8vyA1XQ2bOUr<;*n(FR z!^>qqp)6rw1fJa&K}_B1WCX}t#hdv$`msUxdaa!+xlUg=Ck<&Haw3+9_(c7>O#QqC zZTjYlc>d5LQ~)rwF-?C>YzF6?D31wJeqm*ikx-gTe=R85gy0ZAkv2ELl|pW)^SJBs zUJ2u)>=w{>t<& zWq9kC$Ii5-bC;07uBp27W+Cf{qD?}VBG_?RlYxX=mBU7(El49TRtkojOsX|y7vbGa z&7Hu&a-`dH#9?;BBG&e6dE(}LmJ&s7Mke-m=JU@gZ)$L?Qt~riZx6{6`vF=@YBX?K zQ%h-y+;mUm$P(6cFW!^3-)Kxei3wyeCDyiuL;7heCb7T`7#x_8{N zG2C)vUQr(^W@%Pt=CTNf+^@=yn$!w;bFhDdz zDN9UOcQP-jk#}7s14ay3h*IYi@9CPfOHry53mzsz3zhLzXjJ%OE6a_w>LQKtJxF!d zuqm5M&m9s94oy)ac!a3I_m5BN6+`Og!aB>&ao4xCwO4^SU~+T!Pl7_$!6F8jZiZ1l z;0!izTw%P&>E$%$5@*!1MnULWI6@a)dvKe#EvJCo?bJ6L$Eh7Ric-^h5A3)iHmYjP zZ^N`ltl23-LbwwB-R2L2hC zkuqc;<1+b!%+%rp8x5CV%?E&BYhs)19baj*B-0lWnSNRby0+_LG!82th#JoYxLJBB zDmF1Wq8Vw1*ssyx*XzpyuFdyZO5Ijc!D>DqW5zM%@T1W=L{eVM0oK1fRrx>JJCR%A z2H{7$jI!<(ypC(}`Nb4wl`}2RA34R3s{q^(EWPN_MluQ{o@}f`HK@T_rzT?$b^-rXh3Puf(R^JfQ{_0>kfQOUe9r9~&!kh;Puh zfU;Zdk{7d8+qle1`m^_k zUoIQTC6^87YvcX%qENx`uyyE*R>`ykR3^4;)ES|j-!lZGtZSq&6&44zg4y~817XTc zG6JS!#&)59!%Wf4q4u3s>T`nd;6DC+GiH-rj;pvw5(^)<#vuBtLA zW-``eoxO0%@V?6E-of=O2+)#v-l0L#CrGdn^cv+DGuI{;_zts?O@{*8G=Y0NEeZ)GA+xM~L;>X41qBMkPWe&J?Hiz-1asnQ~32Md)!z&J3Q8DzS zfb;aX#pAzbvN1~P+rE2iTY|WW6T)u-BBRq${H8v|_~IrAgKJ_*eTcCV=b*>E$lW|l$w01sMj@ZxIIc!WU&-Q(pUAR@eAWR(@T|w^7Y&gi) zXw$M;!7!s8Yp5`?{#J^x+^A32g)D5_M7!lWpJV$#dm_ng?(8HNvS=>KGx7r~P^0D3 zhX6Gp5uUOY?Z7^j5H_WGZm^j!9SVE-#mVetTr+S0K2eAgG7)`lZbQBV>dQqb4T>FS z9tArW!5SIM`9J>>UN=o&86%*LG)X^e=utw7!(0QZceM+UheoI&J0MAL;(q&rO3Vp7 zCA-^rOddqIc>{cD`xo@h2`te2K@8<`m)oPzU(I0EGL<|t$(Cdjzk_ni;Uk-$LHF(;4z^TF`gmx5>NZfNYGLxpQ&Iy-_-Qh0#ShNHm?xix4G1l&n$F#t_`<3E{rd1W-Q;i z;bp(nyN2l>n*irX9~bh@IL&{kM&DXSz*_YQfBA@G^TK;6azkfG&2c=~b^Xpf)WR+v z)F-oiW2v%`kAFoj#BeBM51|5&MzzDFzf7qjJ8_5D3udJ8U0mxj8dmW7ln!FyV^Z1{ z4$*@=OvY6t(aE)g^Uqy3Dz3FdBO=704W+HEV|U}(B$4sLU2vhHWRKn(q$j&18m$)! z70;B);XU{(gY#lcpcR$Q8Y@d&?QXr4ER?=e3m(j7mZi_ynO-*K9+yvS?-#tbdwg?d z$7&xe9<*3p4q~VqG88h%cUv>{5eL~}nDlTElX!WtBC)xL7;_kqp=8T1+Kk3{L<&z zdNlGG?lcP91}{PLfsh}(*C)`*&+q-}qTiVt!9TKlIQ~2W@YJxdf$NX7oCx8tLLq~L ztG1)SbP6GCx(rcdE>61PrW8VbQxI_4U~09uX_qqu0s-z9kV7JY*Bq=YC6@)8(|+xl zQV)2ygLdF`Mla08_C`idK4pkFnap4letP=?;d`{dKqpBor|qVW_k6a_v$1w-QEpw5 zVu%H+8$~_ENkN6i1hLX>&!yr{$VJ?*Gj?m+yxAD5ZauGx+r$c1FhOJqBA#X0%rvUKSX)G4&zRv5QK_}I=qRDHY z^#eIxM6;}G=4P`m+LgoLGA}}YVxqsLbhzNyVC>kZvb>-lqV;wOap4*MXo@+~{!>j= zk-c-|wNWA~u>4W%^X?Or#6Ka5C^nFduPr3f!b$}$=LOyWh5~;PXZa`)-_#pQ+~Z>0 z>%!F*Z%Kc@-UIn>wq-fD%NN)gArwH!_l{-%pn{&UKtO6B@gp@Yo4|NKwXfch`KdZyZ!2oap>9vtO1C3|DC}XKevhT++$-}Eu`;HT{LA3)4 zEaGDDWFw7P5H`|Gv4xlbrpb||M%aJl>y{)H0c`jPY-~&!ldb)^L!M_87NJ-*;u2!1 zty8j-Y4#jXeda=40P`s3Q)}(jldX!YI~|$uelcf`{LBfjCcS&P-9vjK|0%)ZI6>|= z<&nLnpCmCQNgIW|ANK#>pE@_BB)Id;%!s+Eh!O4}l#0sU(=!e_HhC2DWU{vXjPF83 zv{b}PWTBk>c)iwb+JgBWrnVJ1gzRy=oJS8I@M*G8m4-qXzB{OVWm|pBUG261a8J|N zB&?bgD9WK=Pl5(-#c$KlE6$Hy$aH-jC3`)3brltL{aFZNMe=5?U|A;%WNN<`1H>mV z93X+8N>T0a$6(896WJ@xMW_zaIL<7I+Chx4GIh-LKan_0?)8}qQw;e27g=U%`5A1c z6}TL;--@?le9jhYpC2jUp(Sx>;>|%0Wa?ja+XwxTB`k61>KVtd9ytazx$-c@n4af>7mO zZDD-VI1IQB^~aAQ9vUu6zqxvx^(LyKwLUCY1pO_Wd997Ghp(d?iUQw^X`}p_ydJUL z&qI**bl8Ho8PT?)aT~97-=r}5ZYrC~A0a=dwHwvTerD4KHz}2wMPyyM@4*Ld+z@j2 zd>!5L#xTfqt?oZ#`g7VfJ=VPa0(^fi3diknQki&?fgInlPvt!dsy;(Kwz+* z&&9DU^n~|7EF&3$2S!b8R+3wrSmoin*&W(7P86SQ5sQn3_*mbvvSH$-)J7NZVUU2y zat|BtU1SI@2IZ3Y*)r0A2uzzHzpE|V123t%G-Iv-Yzct&dTct}R;b)Wu`5j9LN z|DuSum^J#s>iK#a+?J5n*3mk`qs{@C)tN2aj% z+CP(WVZ2pK*^xkVwEvT?ECL7jvFqy$uULV|rWwQ=+F^b8&Ccj)NSa+JRpp*)fNCZ& zfojHrp_zTv0J>Xr7t*r`4& zGtlcfBp%`}9|PY0H}A;#3zuUJ{c6%iOsULcs|ton`dbLN$NQ?0S!oi>9#;xe2AsK_ zZ^fz(7&LUpoo6Q9F8|DtSqMexL_3yuFHknTR*oI~2H|aUtQ)*pDK%L?Q83xz#O~SH z=&Fml6i3T0DL%C&-BB(k5EQBVlUvY2?a^3XxhdJ@66(K&8N!{%OuT}&J%)fDqfBbk z*85Bzmnp85)qXqv99SNuuXgE{2}fQIUoF?O;*nO!Ivr!q{WpD{eiHfhA+hQfbfV8Z zB&fOB{*_I+Ih^r}T{!ERD)su@oo;nzG` zPi;Hr&A0Tj^xG0dI_%VZ0`A^wORfqbf>0cfh5Kf@4$(hmEm`u>EZhfrd6SRongh@X z2_1QzOlQuu=9~B}U1dAA>udCb(lNi25i_*ylVBRYtQ#ooY#e<|pPTxE3LG^05i-c0 z;o(ZOqowgBvqIefMB)-zp@`8sYRDPzWA^NSRw>R2DpNQ_8#1XkBE8bmn1q$mgmZNS z-Lby^Be;L&w$y5`oa}|MJc*0#9FO_5?KzfR7aE_Kr6;E@%%c0s#MjI2TRf^Q*6UpE z%E90Q#g?a6y^x=2u$KSw#ME|p^Wrmt!efzteA&s$IMY|XKqcbh%o!jw!&GtFoGD*v z@*v%dW1E2Ms+nFS-gyL9J5n4PRz7RV{GVnC^M5rKyTguRDat8~(jvHo z-X$fFU5&1SUDr~ZB|BlVl(zB08D_ub=dh4|DNBXgh5{}CWik+qkR?NN<1}5OVG1om z_!V_Gucn%Qz3&C~^$Gp?iIej@hwe|AW+i@l24>@5pP8oz;d&nLTu0Wu^>3-aZcThu zbFk#xj|q}dMRBn!bvnrPrtRHi&312=-ZlP|?QMFlN;63BAp!=7rm)c3+~D(FQrN0m zazQx_hQ4IRWzlNHQ_qb4+OV9*Cxlm;srQ^0=~Wl(J7Te5roVOWe!ni}*F~|3J6gLM z{D`{{8s%)Op+bPhe&K`*N1Iy8Gxo zqkQBBQ>Y5<%*bu9Qb>C|kc^69x$?Na=Up-F84I~5(}IC&8kv&os-*V!pJ!blVBzuBNM|GPFnwFT8y-7`ye~Z@G#fabNoO-&C|m zHg5gzlK0i;TK#`kNE%;%8F-kSjU}4bA73llqFMx%5bQ6um`vuuE7TUwv(qYySOZ@C zX8X%M(RhN^epGD!gJGQXowS?lVp``zutaDcBI={5k$HTiT9~}Vux(>7KEpcZ?zJ>u zvg8wbdnA$^b{6ZUaFozLV%$6^R47OnQaqp@B6 z*{*4pc}$?0>S|~qfzmmN25_i)HHjKr(X;L z9o7R|CM1%nyRJKyi?x=iN`Ut{CYPX&p77Y(G`E^D)ZODvZ< zGC0~nGreC??&#Rq2BmqjzgP#4PRHhHA4qGxl+!hy^djsx5%W*Q}$qPdRzRo8Zr96^;ke6%raB%3Z-VNYQ~ z#pLeZ+?SX}K?`!f{ho5m2f^8aQ7MW}ZcTw>mMaTjBLG`lcz(c9lv^=BMMm6#`qh5^ z*l|Umpa@~qZH(-j(=I(Sx(-#6Ft>?l30+3xuL`$FGOvx}!U^tve(AGca z+Nf%6`J<6zp@cTMK=3C;fO;bZ?TuE4#uw*HaZ!~&;-uD-B&7CJ3zfBpDGMcnnHJ(#Z>S_g`#tWR7IZ?K5!FKaz~yG=)H(zO3!!7zS&PN@`!E=) z=I|^rX_=Xa7kV|t+yVn@$32h={chhrv|{G0OgV&$ZW87xkJcg`5Z5TanK@g?cv+`r;qK@fY z*vby_ zX(L}9b{NEpG*THsvVCx&hgy9Ch%4@00H}Wp+0!E0Cn@g*AXma@k;9@HkI|gMus62$SlXGdJvI`uKoBNLem9}61+V~uDK7*rT($Xh~Q zm^ZGKjz(FL$psdz5r+KL>{~0Qk2Xv#+|4*gsOZa_`<)mf@0lzL1F*Uj>y9sQ8eH)C zF=@%rg;ao)ZYp*pbnMBA@MH+V?ESYg`=RdSYb_W3>0Ti50{V zwPt2AElyjt(d^+m?rI0jKysjx^qi)N)E)hO$Gxx3_sf(=$VGIQE1rk*{la7K&Op(2 zoICxZbj)GbWj=6TjO(B0X1!ynmRI1e@a9d430Q~D;PBA!jLp8pry9B!0j>+Tc+(sF zJ3T!3GsM|b6+P|$rQP*%5GkWrx1m2cQHUS@e?-MB2EP<|Jhqi=~jWRildS3M@^^Rp$?~>&8IG*P#s2J9^n~(ZdEg;ir>Y&r(t! znUc`nCW3oLnawzdtysgoyOfGF>JiC|$Lz8;?wiQ2D4oiqd}aAGlA#aJR+n+;ta$&- z;9yvDb}wkH&lhZ(Se5n7QU$G3RidbN%*jUC(HD{AHYDe2P?aOQp6wh4sj|Xm6^{;w z_};YJKPedQn=4oZBZ-L`C}4MpqKi*>*z@ zhm-Nc%8MLQ9*VCjOf>}RXg4Fv^P;woT)5A8fof4IBBKNGccqRTI(}ve&}eh;TzY$^ zn2c5W_0nkrO;BybQCFLsg0U@ao&MUG%KnIFwpQCM3&ndXl73S9v1!hC-$XQ`>+b?A zBax5hslEKG8KFJ0*RSPc-;*6CVc`G)(~BN(*G$2C(B^S-I|KF{C^ydSKgD~#f}fSh zO2U0QU~gX7ogTxPkghEE-(1oVY!p5`V$ieg5zK3rJ{SV-{53s|9wO>-ru!k4QtK+) z%fvI?5a1JYbIu=&p4LvDwQL2GEqfIf@%5fFX%R?aYj0l&^~XhT?N%i7`o&aEu`goV zQutQoaC@!m7w4? z9|I2BvqB-hr&pfZwrzI60^q`=z`Q)mtbH+u2Gblf6En zpzcd~p|tn@(yl+u9gZctdomo#^za38Vj`^yN);n=4R%`uK~yHZkH+!HDswH3bgk>$ zc6fOc`L|bEe>#jEbrH4ugQpT?Mm&^ThVQ>bWmWQh@tqe=PYjQ@D~lKmGp8?PH*9WG z`%oz?B;uZlluZ&ARLPSgDTR}mG107 z;jV{IpNE;zv_8h!4evB^s&Gq$lT5kijM``)UI9LG^RK0R92R0u@7jo8p?a`8%;c6J z)T-MXnvU0dIvxl)xRgJVp>y1med~W}f`z|g z=*2f&*jy+r7pf6c#h)0^b@#w`>6UusbNM1}-^v4Xdb^KVN&gV%&#UDUY4)f#n|DJ$U{UqMgVtjbChGyp^E6e=V<_?}U}9t_6MJ^3fc5A@NPb zk5GfWQcm4O9F}}n$@9d%Tr+1BGsajS zo+b*Sgd8!gE!4}Vp<7iBxl~$wx>vmA)XOk6#H{xT7!M&d;r17{I1W!f0!&_V(wb}Y zbB`xdNbz3crqr7ZLC|E)&Q$R%rSZq3AE|=-t%*2-rYWVYLdU>Iutk7jnZ~&^Kyvb? z$0h7IHkgsa_cELyK!AU`W4kkL>ekM_JFoAg!lNOE;)I@Ey=4Z&NW0(r?6`f39}A6r zfQac?fU?L5jG|-pgu0c+6$G@=8CX9+WgQ`clhIzp{|n;bVEKISBgXxpgi__v$Zcr# z5=eO7PAL*WQd_H^R5S$KK4HtLV(-L>-wy~hhv!46913C&|MkH_Oor&Jh{0!QJ z`m9=>;k&0Yy38W92wgdwf7)(pE={j9!6qxVVi^SCVq-=K^8AR#Q6uga9Bi5RXK4{z zx3vWpE-YGKjVr$|W!y)INc~p}P(UT)hNee(_I7|$F>G6`(yTZp9YOUtXZYCX(yOk5 zvWv}Ne3FAUQ7yb~bNd*uc>LT|EmWhGo|=@J5_$J4Yy*cUFhZ1Klag`ZFXbo0XSdTV z37_fk4Pjzj-}~CFv}S`HQCmz2;1R%cS5L7b7+pVj`AF$;edTzG1jgws7SniMJn(yB_BFJe5e$m;n6JHWK! zpMbnt>y{Er$Ww2Ai_>hoHlD(yC%T?;C1v*st>wAN$-~I7{64bjh8J_bmuKD|s%gjj z*3YG7h$?nfj>P=iBj6k~{Z`as%=)?pw~Zur)h+zaQQhW895RTsJ!wEe<2)jaACrFc zu#>^#uIzM!F!6LQ{6diWKH{a_?@aiWj3>s9dCn809sL!3W*l=#L}6TeDtZKUiY2VBNwW7E8h+Cm>mtS+_LK^GiL@$?w#;6aRZ@la1Z zC}a*i5GMiJn0V%L{bT86QtA{u6epJ)BMn8dSmX#Peg-Ti?eniZkkLe!c%{%OGYA9- z=6>@G?De1)iMMx7PjX2a*Qg#G&X*YN^3ACEu)-KFEUgu@n|V7UB(dCi_ft?fJN^adOqID9UQ4EsKhzp&3|&Q9RZ4w?hLl1?-R;geGZdf*ofAkc zFgD9*oV*)mgGZzzhyE2^EU}0wf1Gsw7DKJ}HAuO3{^4oC#$|p*x?|bt5XcLsjijJz zjKQW(t7chVL#i))#cZ#0^}Mk{?RY2~{I7-=jttg76V1{t{ob^E3g?{=(+G`cd#@ZI}Yuz`?T>$oA(PB96k*bFqb`zp=!fp%jwT&;D zDmA6!g(ir^NYf>AYe&47FbHQ#Pe|dk5~;3G{4;nbU_y{P_{=`iX4C&r@Ynq_QqVWp z?hq;rCASH?K_D))<3U90sQ}tdFt{7WlkCczaSVITj-Lc_9sc@8`pp){bKf|lMdWUC zq%IsbhMV1Pp0W`Fjv>(SaTSl*iBr=pGJO~gynpMB;n;F`mPAthp@ zpY7mq{Fc}s0nz4U%EkU?cq8S>x0o}Em0{fozv8}BbdNM1{ikEK`X79L7eBlt6X?P> zljrv2|NDswHRjzFK;0YA{SHr1XR##Gdo4c^6Z4bFiw|!#eZdTAm~is4RP_t|r`eD8 z2HM2s91QsqZY^wR{-~mYP|4!M$sX>JO{#7B!}JgmV>S5<(q+ zn7($t9SyKcfe%MsbMc*qok(`*C^M8K$sa;=EBSvHk-O4Q78hX14;IR(v9GMspVE*! zTPG-T0>#DbOh`-?%i)+HaT61bt@am=Cu0*Mjdd5T)y37QbN6l6AzeVB5z-`n@PJ#1 zX`wIiZL&pYbut_BBH2gQZiT_ficx_mpd8#zXIx{AKD>b@E#Jh52dc9#B*#Y&popaq zNb!XIsgE;b{g#%jxZ`rXSW3znIdvtJQ&lkzG>Oo=ISEqhw&Utt{E-rcEG8@Df*2LS z5AEJ;EOfO`#wn3lOaw2i)AyZzJHXB36(E$cX!n!cED$JvRjO_hiSuGGm*^O+qW8Tn zbpxmKJ*D?fVDL(|#)r?TB4`@unvv@k&9)0?{)r7ST4S^j#xNTW2k75BeeW%1Qf#(g z>%TwWc)E|(qWC`m_CN{0gg~bW?KIn3wC88Y(ikr+6IBK&RjqO{X*Xy$ zX3#q0eeeHst8zA)EKAX8ijV^32Pi*63S}**S|gN)Q~^64zMpoSkfxa z?gdW5sb< zf3TTv{`(xwI;hCz{_3VAtO&Mk*~@*r zmIe=!V2BV5IbHsb-RUY1;ix)+hoBFrASol=wIWzR!Yw5J=FsdXV;30@WGNFHGWtf~ zb1$66WRgs$2noV7WX2wqQl*KLlqgUvTI+G_i9RoX^&qb}ZH#WNY))t@EaBI{9+z`< zWP@wBOmhAa1K8tt9tF^LkIx&&^UTX!O_^ub_7?f%BxZhJ?>A1~R^Fhij4k&(M)oXc z=#rqlIh_J{fxABdK2EQKwoA0Cp6h(uJ>XMrfA+fP$WOB5$V-fVn%@iK9J(R>XF-0v z%iRNaV;kG2u_uGJ1IN)-%m3^sh|B^9qp*+{C{Un4fdbDk9O?(*Q%!2>ib3lCez{&8 zy(r>=i563>j6Jo4{;9V88Et_17^YgxjyJ63d9(yo-x8ON)HaUibB$EP{-(8<&$MB( z#mr2bO61`W29~(YuOrVsHq#)D6KDuaW`@Qt)6QTjW<_S;FP{yGf#DMLNAQLle&RkI zuD0?)GlE2-@Lcw!g+U{y4c?IN^d|w`k{{zt;s6rQO~Nu_Bo%x-lq>W}&Cna;Lnl{4OxHAlj zyffYARSNptT2t4{t!R;OB-f#?l8mvEn>d9Ryz*^$et-~?SC>56i6N*+XMwkBOYQ9A zw&Ocj|73WSQN##5jLQPG)BJqGnL0zh%~YFbv(t#$8lY0&2*zlP&JaSP{IEkJHtKae z)sxkUM4}O$TN*`#p^hR%lP8X5NJ2Co8pFgv^S zUi0rneIsN^n^t|6wwwbYP|C+>O}o{`WGR38{@+7-wn)fmOJW+G@h5-vIS>M^Q!obM zDWp;$G^^JgNtW4hlhU*66q0Y=IfL@oBV@+Z?(NhYDQ|h@3Bdi>5A`zOYP{17kHeQyc|Y;^>M6Vlx{nD3rki<=%Df=n=7=8ndKq<1`nQ0VO0Uh6c-tSi~?X6SSEnVbB$| z`J|LEEJ87aA}`m;$+i|-i53usJYOa!K=X^~x%PUNy#)9hx9=YIB+dyv>pR%ueFu*uIddG2_it}b z@eb_x^kK>2IV{0@4_0CN*vQhtT3+B_6bj4&1qu`>P@n+t)RCCWIfMGu`|(dHb71*T zufPQO(L0V|d_E=cBv+DO+E_w!vSrnm zQ!SWkGdUY01q=;_FcjEU^T7c6gN4dVXUFSU$>XeB29#*`x5mU7^X-hxz+l;9x|uOF z5W+wSM$7Qa*F0js9?y^UK{MiLIM3-Xy98$4v`||G-Wm@fJtQF>K7tTULWCqEK;i*y zQZ%+TJ0hZlPnno0_J40P;s{AFRstj$nR`Y-Mv8Dn3K=aF#^y&J@QLSuBO*#ffJd1{ zc=%+rIKW0AAs}Rcex^HW6st;v3|r^pVJCg|q8N1g$)tyjwLfuF+GHe@sj!?uybD)x zVf=Nfq2%3H*lkq!_$XIj6eEeyjsmcTKx_50bfiF%qNt$p$ncTG2h+ReIaF9*+$@WV1v zd3JQPCW)J5S>isEcB{0`_`wZbyW}lfAj=Foi!oVBrZcoQH0lk=+RlD86EvG0X8mR#%q$%{Wl*u=^UjblLCPlDv{;I04N@D|%pFLHV~wh2tU6vX ztTZj!Xkz*>3?W#7z@>5`bedM* z?crUN`vt?x1Z$7;m~U#@&5TPwv>tncASV!Qftvl?O@dR(|LEZfzVWp>DulCM7V)Ar z6(C}o8sEHSmLxR1^0a;iJ6W4KaVdNDDWFSa=E}!>9}?{A?$cFh_Np#(qBmckpj-Nr z7r*80>G?YHqNdF~&)KWO^bdNzT-Es(*t|_2TYPpZkFE}Gx!34+tV;Ze#3rm-xr{y5 zZo*pl0bayowUg&4NX!CI5SRrD6ev)jz%v?8wek{R8PBG1-6Z~TB@V3o*$7O4@4j_C zGi^;NkgOaC@QfjjGa8K)p*5$j8?e^#o6hc__CUg~`j&N!kcjH8IsUIAu%-B@ZNro zJbj$t)x(r1ImIM|^ds=uv~@Y7Yrli0NkoY%Rpt;b4bn&ABS@T;J8!MEDjATQ-LY>U1Fd;<}l2O50 z%>{y()a9eK*yRXSLqGlWoqHr{yNQsBsN7Fb>c{g#l=8SR{tEB8(s$#QtA9Yb+{%Co z0TE^T@#&+^6e&$SSKy-^X}piSJFjs@hD5o9P{FzH`fXZ`Inua|$=`N>Fvhl{M^%h5 z#O*ppr}$xoG;R?$<_H4`Qt{fieFQ(M&}!EB$N&2tq?9PnLkflG2l%B5MnlqSlC)bS zafA8UNu(Fx2a(Oc#E>O1MyE*WA*8h9;D-n)T_bywERE4wiq;uI2&D2DUOdJ--u+&b z@-PNWmXRefm=q%@ycifK;K_5bW z>=B>u0*4=F@-i4+Nw;148CznnB109pVR~cnpG!C zPJdZIIGV8G$Fns329=c=iz|v{D2DMEK{1R^1&^phV&=qJ;4Znsu!Xf2=f5qKyTC%) zAs@37*-4cv{&pG@`|Q~@&V3v2A}ATELvZ?8AuoAVnd64b?s?06>AGz^_vcHjE_qJ7 zo+}vh49g6w04(vv$p%08REv6=@|xf2gMcqq09?B};yUo4CXP%Xr z?<+mGbE>7QRPCxY1zp0lH+wTDKJx;g+&-QwF`4{rrk@!Ue_BbwN^@h$)jBIEQyhmn4Jq< zHD_WV)#zB$Of>WDj3q1jVC4X#7i>Zik@r$-XK}Vuq>x>I?%Qn~tuXwWyAe)T=r3rt zhUSJQUfDyg5(vM7Bt=qkKM30x%7hHzkulFca3tDX;{eJibR|RYO%cl^P$nQm(nPz- ztVZJ#V5pO!okcrg*N3YNFWCtZs5kZDQ$o=PC`U?4q)Xkz5tJ$8lqoX@;4(UMWvJ>X zf-La$wwfi1Y3g4(mse5W68#ou@nAHz-`z}wk25W%BvQZ{9J@peLV=<{tMQO!qhYjj{xTY5#0DER=_#ef>1(P+IWdXgA5__5U2dp zqaV-;92S_lFGAmOz!=@E(#^p04)ZfT-ZGRY7pFYySs0O_{ETHs34)Q7x~S8)QnL0; zpX1I7S?sj!qbNr37$!i_tHSJ6V&<2Ku6i&4W@$4|*tt&~VrvBU1i%aO5nG<=X}WBe=v4pk7Hw4mE_7pEc1A=9k?Di(>-4ctGaxV+s?bN zgzI7+Z*zG;Vm@^lqGB$cy@c~-rdHherwN%-1%Xu^-L6YrRg$$hhbCLl*zV1}=NmD(2c5fAoqL z;=B_6+N!f*+tf^J9WT*#D#yTC+na15z^8=|gdGwWT1b3nf6u3Ymhv+g+O%CVWu7nA zonZduh12}bmrF=T^9dp{Y~G~6xU5O5a`Xt0M5NR(4C1>22T941wi-nfL4}xknrvV2 zo>VAyv6U}hdlx%)Y-iv29;POzICI-)=_@OK<6rH_3b!=^<;?4;(*^mC5cW}6veUj2 z)>021Q#`o9Ixd~|a_tMx1VAbu?JVp9LAhK(c~)r@maBL{sWTb$!!kk$;#QqBX(5#l zMkBK((u=t8t?vhX;-tnEU-%?J7|?FiNm_NXETvwXanI>ll2lk*ye;RkR&psNLOMl~ z5w6(BxP(5(@he+l{9j-Fj2p?@vE>*fj}B2EKxJ3~>zY1SXm=xC-%0mp#ty zEbxOke`2hg_9%22(qJl z_mGrO?r58@=7g{4xjqf6CJca#Iw|`|*|cvz z8*aQG=9;wY8PYRU`r+Mg9>Jbukl15F8!h`LU(?V)6lD|xgglaz&8d=nyZxTOdvh#%E$1AxOxUw*ZZSVtg_#qfx$^QkZX7(|U)=M) z$gLwU2FkD*mn+=k-;O=@{XO)#Q)e9b(B67eUypXyC7@IMHLo3uQ*VCHaP(WOUVj`x^+{zH#@U0?gv zBdN7A8tsf~D5-doqnDI8dU*x654VJvrSQ50A!dwEgZDwcNgubHIN>NfUT=AgnTf(wKVmd;z*J>W?9^1LQt&Ke{ z2*J`nsw14m*=9yI5h$m|>%;cO`ZU;y&7$;Ofseny*x23_!*qr^J;ERyWfqV+Yc}-Z z(T8A;CX-YcWS+XyN&48H?*^uA@IoJt2s;6bv5FWwiPU)P`Dg|4fx9}-{V%_~nr5Q8 zXwiZI%A(9Ws3W$GJuD237ruVjiQ92!WM1>U>(nQQ%_46q_jzB zIW?w1Vvqdy45WXZN0aD-xd;FZr#;W_kLQ`&ldy5Y1+4w}wZ7Bd?9A-U?#w)&`4mYR zkGi#+o4iRu0ha}0jPkL;T>#{r<}MDqURUNPhhpA!!wf$=Fv+K0v*A}AvlTi6YO?9+`)h9Y8t{G1@rb{dJ~gbNKhqfw?nNNc0C6at;42w|*@ zN@Zkef)EbFW9#tz5Un+h>S1GEbY0VCoThjp#qkUL?(hEAEne0MGZnaAS6Hf>Ob4}_6y8ldmU}n&Nzm= z?8gj*m*&4MUKfaQ1aK%n(kFhph7QGdA=n1d^S0MB^O zuep?%dsdU}#Sl0}emQ>NHy`^rn=TA>wtzw+8N@>_l9%_S#9V5TmO#QRt$@CQ001BW zNkl4K?csY++GA zn|RLc=(z$jpiNTd%E=r{^FEg%S9Tt)R$WSt<~L#Td8fc}7~(G{$iECchxYNyvD>AH zDKG1{^Ehn(ej-Lyz6Gek%q`Hj4jKy(rO3U2?@Vs63hTR?yjRLeoVjg?w5SSfw&_M@}5cFRyhfUq)IzdD*p`oRqsm$2S z&0s2n8OL0=j4RkQ2)9mwR#0-xAgG{W-i6^_#Q%A4cH0gfyLhCOmJcPF+4Ip=c*liI zJ$w5@GQTZBKp0R%Bq-8$d&=>-;l^F%*TtqS-Gcg~LDvj$1R`lC>gpMICGu{4OU~S_| z9O}ZHCm!^@d$~jSprlp>V%vnxnU_y zQkrCFJN#69;H5Q`2Y>OoB6&$pMgc_wK?zAhN`@f9!$%R|;gjOyks^t$ax}5l_Yg^w z7}HQ*=k6oy+%7Kr-rU1gyBj3Eia68!-e>axe@=7N9hs2%kHFS|Ss zhQxWS;2E^ZOJ~U=Co=QT@lv8LS7f%>L!CNMr;9-p-8AW6ya|?YWbw_>S(Faud$*4F zeeVjkT;4!OEv61MiQ||wOUSa6IBoLcmu+HnWeedo*t4s_mp(hkSx*Rg?!_g#PY}d? znpr=k6iAlg(2d}9dTFadmo|_KAYz7yzD1>JPD(D#xy;`;OJ19knqtYclD1Vne<(Xo zA9Gxjm}A`lrYvk3?Tdo_v{jo07RgM#9YjtF2bjqBfVp8*!Vs8=eQys9I>*mr3%@;K9UXMg zK?jcj^!}&8^-Z|wLVotj&+w!X0m4Q6zuO<&{JwlHZ~uqw{M}gv@B+BA1+6BG6k)Xs zI)I@%R0Mo6f(u=^-G_l*SeSsB!yq$TZaN6lQ|8?Np5KG7d;|T#F>nGH6^Iw_d`P!N z2fv+oxKxtAY8m(S@B5rz43*&5Yo}a_jUU>|#t)p$hkkH?W~w+;OW1O-L02H@FSxAe z4G4Wny`C^tO*mXnm}_Pz1#+Ja0GOAHZJyEz)Q1ql} zEMH1^<_gTvfmF3uSYXJedTO4}`5K#-DavLrBQcqS2@SNhJiB;HG<=c@!&EtB3v2Wd zivW{TD7%*qq;m2rwDx49h!J>rlu6NK1UB0;R|kSlC3-=U-JKx2TgbA9BICAqNGhkS zK)ms)d)+_3^QF7!`{H_7Y)2QQfXU<3Kw@b1CN3wGMkuu&8D?fJNCV2b`B0-%YlpdGFf3-w=leDMd@<8a1e)8ioD8$s|)W0T+$NAtfWm z5Wq)U3Jv!88H1}GcFkwJ?z65XBlEwfR&8n4P+IkoAkP6cM5eUlfI%z#-H(F_utcg~cZC{r-UP$N$ zsIZH;RcC%`A6jJu#R_4m8^;Tfj>F){D!%kDe}2>_W+^EUV+Q8yF@s?jV@uot?1DxM z*5)?y2&0tz1!k~Z#gLGFb{;j%0KN+B#tiglFkir7J6*+oC;BjorlkcG({?|O*`Ei1 z@4)x|5mts!b|7$}E{w&z8Nt<$j{ylPkQ%5y!^)!c?l+)@o3}(ac&FG$+}#1m^W`btg$Nnh=^@OOi-kcCMOWV zqTVyX5MR(fdFH<#2Ie{AIR)nLR8;SVpx`lksKvy-Iy18|LIiy63w!Vjnl&2)8_#fg z>8mTu&u4u5@)~0sT?S8dSou_!(B zp?y)~(Y`VC&_Qe6Au*33bQG8!bkIQufd2Zk;pe*{@tJHn488dbxN0-WoeQ*-pz;Aj z4(dNW4#onIRXE`|@cW>)A8wd|*$kFBhMcHq*ggYq*a)B93kU0vw&2`BD0IQy2cW1x z2`Jc$n0^l?GKjSqbG0-`W$dJ`0O`P4ML2B)uG$MTEx2$seB}VF3Hk3UQZD-D7(zVw z48aZ_n|P=Q%?CqVJ`#lLufkU^S<6f_qZ~T;uB03|6g^2fkO-xjt0zoX6Pi&*=m|!9 z0>*j*Mtf}odBq1uv`NMs3Zs;4WiTJnT8KF`AJdE#t|J)k@#*Rf&G8_A1Xg|N2t!n+ zrnHAdnV-!J>WTSxZXXXE`hR~4ug9m%Fpw~J=K<1k0t2@Agm&?b0BRgU;^5&E5FDWh zZ0=|wS9pkmG0#Z^L@932kETUlOkOi#Ax7OUtQz1pLTKZQPu`$@+Zrd7wv>VeMd<-#a4CzLTB=9L%`?w~fg-eR0 z!~%Ql7B&0+t(Sd_Yp?kQhbIqGtIh)&>G+^ES(cEc2`WpGj*DL?;|E1s;3IH6AG9KB zRH-ja(yGsa20ttj6e@&Wy~Yx*GqNnjkq$!xJ!k~g`8l5a+*hFu1Im@(`7cw}lSali z?s$fvl(vaHO~{fKX&Rw2V_)}zB12>A`1)nY z8Kj$xz4o9yFM9GZBxiydWKYv3Ra^{N>0-!)7^5nxVourtrhWH4FfjvrXJEbwN*VQa zUkECLsd*Tyz?mz!?H_OCl-E81(fz&$@xD8_H?+?=xAM!)<2!-lKz$43snGf<+`1D& z50>@8;Tmjw%OktOk2zdQTcrp`SPB+NycW~6xQUn%T$Tg9n3nN20lHM-n14q#caieL zYg@2CWpq?9IxI-Dgza0a+Ec|NbaAn0gvZK=9+sU&VY!{WOv#X$ z-53k|GE4^XYK~M*?zPKaZ(q9)a}(!P7&ZJ9##&yn+osMh-B5T4(IGI89droH4m#-I zn1`PH9X@}_FL=e9Pk{?x$d4|)jNJ=$j_WU@(TpXBSyzadO9Z`V2Qb(JI}gEx3s3BW zyXr6%!#|wCu8Xc^-MRg6>mfrzRF*@10-n(a+YZ}n5Dgn7R5kb-LIDQ_cm;S`1+Hj8 zb-`S#qz)7_^Lt`f*p+ZX!6-5N6L{VRc+Z{ioH024g|Pga2yykJwmm!e?ZB@~D*n2v z%SRGFeeDKz%|wKOgChi?Cvk+J6=x`=NE1brC`z8BujI14Ct!JxPpQXR$mJ3ObLki? zQH%ERLvu0v=OP>lU7^d`!4T19?dQJJwvLBRyLCKXLS81yWO7ECZ8_JbG2Iaiyln(Jv8$j?H-tNl3_;$HOC}c*M}Dc~=WL>LdKNh1?9Ky76$V zO+2wfs{qBk?fI5yVp3X&M4~+pWgEf8frQD+`jGFsnfpTT_T}J#T;n6@!gPHrt2Q)) z)B-((1kAI5AfvYJFtVa?MmNs?D?ao4RbKY* z3Q35`s5Atki*L>84iOPPAu$ace0)Mng4W2$kOX#GA3@#fZbCFJRZIkeSn_`tm(1qx zwat~<>SKkaFC~%?g|b$8g+!omkk*(lEQxC>eoV?~mAlZ^P(Q_i#cf;zZoFw1H{EnI z`}XZ;er}$9`}fmowTPn_r7|2ZB#oP7X>4rX$`A}fm^N~)6^~ZyI=pz;yi_P43TaJnObFL0HPH_NQRcL8R)zAH8l)z zxffFg<6s8)0o?w57%do^_`!KYU{)iOIal)9#bAvlcmn1$^zJdLj>Fg%^k3J0va*&RN!zGW*hMAzkYaE_L#%#X%l)4ph=yC&)!+%g!LY$65^0j zA*8La_Gw$pV<1A4@Pz{rYv+9$QAC!eJnJl@j-F$lA{p1-S>vj!s!Z*VY1K30NRcI) zQdzQkgU|3`YDP9FN0V?x4_WUQi{ajKR)zx1rT^v2avH8~t< z!O#DmleW1XylCg$unyela;wTwaae1T#4rUpVYTbK0y=SA@DZ^7?f z03Z4x^maqCKzdsP_qYIdG~jJ#!iR1#>d8Mk0ls{@InoYFSnk4zGUVkx1q}^7o>5)O zA#>NX<-l9dh5viGy&-Z>GrLSQ2@T z3{4dW7flI;pvE@)E|+FtdIb1Hi*4|^hR9Htrq|aap+Rcjfv~Dlvo(ZWmZ6&kDGok0 z_F7xN&nN%y8s7iUJ8=c9SrPJ@mydAPX$7viVV?8e(%vtd_bzbb4L5Py<}FmK3skFB zrY0weW3x})paepbr7>yLByQD6;}&jEA_$APK>^402nrQEzkuTf#H|`pqe^$lp*lAU zNX~uk%Mo4?R0=BP%I|!cERIoGic$)tQe4+Zx-LQp21i!&)yv++FSj}0L|f6MF$BU| zj0!TxVf(rY?V^-%j2dVbGiuLmmSy{ZwvuTDZQFQ1#*XgU*G$k>V~(4>H?d&yEJX$@ z`@!pnZ{G;Zx{O-;?!(aILp_3O3+gSHZ4hfkjHavXgYQvqDvDhduHJEwn17ROd+B|2<(2vwwHP&D-n^BmsV4A_;_sdL5qew-4JoAM4o3Mf`AE zi^rW%;B-ptqsAN&8}RYzrG2v@w|Q5&oH@REX+)!yQcq)=Nz6&7xxD0+1$z1vm0rP^ z=h7f0A)}V1v>F*x2U4#4X_GrPM?|S&?WO`}KC{TP)^$->v{XAli~}DQTG#nK_Y~Pak5AZDq`HZHBgjJhx?cW5~fF7FD4K zwj1@g*5+qwm$_~Y=2%*Vg(kQ~^I3O`zyPF^;GT^kDr3w|pM!SZcVHBo3z+QRT#>$o zc6Mh2LuL-xbzNnbH)z-O=;QoDgARdt?4UzncF;iw$29bJ&xNZe;ILxW54e5C<4I4e zz~KXY@XCZYz3XfiK6yPQG|uZ+!<7fPhj^hT*$=p(y!jRdQ~9p2c8up`omy z;6c3sYdm8&?UAO0XHr5jg}4Gwabenrs)W0H;Q|dG-2s=ZhYxQv$_?K$7a&T&CT-6D z8ys_CGMT|CD`3kw+$CUR0g`TL`LME#_}zQTEb5?x_CPPc@cT_CAs;II@HHFQI~Soe zEVMG}k!dXl=qtMPl{}XB_>A@V3|D*#o+NYx!j*RXAr=*wNh@W#mM~pQn4FI(_>zIL z$C`lxPRTX4@ueiDdz5`V)ot};5HX9M z&QSdVg<$G~1Mt*QSl)+N_V4#=+gCOZ!*YSs=Ud`5vlfGZu!dW2zMETa+06LfeN<~T>a`lR+5*-2dD0{zD0Y)3 zEz+oI)RjV_wL-ccT5CK%#4nU_T%UB|00@DUF6W&83WOUXR0>(lcfbBwbe1iunS~Tw z_=4Z%9e;Qch9qp4`usAsW5~r@O%cv?%PJVFu%-vZahUV(AsD|Cioz%zBL%zX!Es?t zFN7xh6OnIY1yKuTtRk}Bgj)~5XaxrBv}GS=8s@v!SAyvXgbTM%7gFz3bV;Zv&w@kVOZp_;Cqx3!VbNA~z)WN;uh;!K155UQP z_5fae8yvb0?wT->J+5y)tD!v>E1S)D{9iuAYyChmfw2!i_VG2I!5Mh0q8~%xdE_M6 zArA1S*B)l}u9Pf=I7tysOiw=yE{D-Ik|&;5VC@ERXLo#i@*$s5ke*Hw19ar?Jk+672Gm}B-ji~@7?e(doF zhYoppY@t))(?JIv9JA2+4SeFsU*$RLO5AuTqL&6wJAa7g&ksyq%ZHb(gdb1AGY8;*b{PWW zjMXsRfS11xzJD3iXJK;z*aP3L7}DeF1U_^Y{QFM0Z5GM`=9IbV`8eQ!0;$cl(ND&~ z)$poyu;XqRoi%OdP67SuRZtL!f4%Eb+}a)dCgR?dlS?lKAB&{s(?7WbfdBm6HKe{K z^d$XV9*%&?g_uT?ak!qMfO@Lw@+C!25;_v!5%`Y46@n;LG@^`ZtZ1g1M1#mQQKpHN zrjROQ15dSiWcDURW`ED0%Pg6hX_8E%G-Rn_`MWa|DImx!5$EF?OY>NGq#`uRm}#91 z&5Yjht)Mg1i5VFw`QSsN(Qbb4+SuL9&?d9?=scIv)a4j8pksB60-pi=eg|a-FB{&J zu;a%ObhXg>tqAe=_qpvCHcc%4-mll-Ajwcxe_24`(4yWh$Ej=d_6*?*SmmG_5Pv^L zJ}V<8T2z=beFzkD`7Ad1?d3 zZ^h@tbw%)$DUKoI4KMci+4Y*9f&--@yyIMcJ`SI|X&=XF&G}`YQ(cFFpBe?J0&csj z%57V=viY{HRI63$^*W74lSZRK5~rph$Z=`a=Sky;xYaQBa+TqQC5nE^&#w3kLb^QZ zf>(l9;QWhUgU({E`rg;*=^x_KSG)fMx`x04fz@$KC%i zs3vg2qgB3iG-P>c7&iKZs zt2jOs%CKxyux5itxm$2xUrep0sMR!ulHjDX0!GGMD#MZ)Qua>7jI4BVT}h3M+i4=u ztiz+YsK|6VvZN_ji{}>erTLvpvoXOCjrp|D{;cMz%KWqJ*=di%5QKT2WD!$5HjT-2 zJ-Q8kKhO_r*21m{Lt<*cQIOPOq7H>A=zcutahN&;gC_$G=p8WgsL#WmL$Gn5U5}L* zQZmF4lh}3Lk5OFa5gSwX{mz^D(cz4{Im{N zd>hgj5GJsHbs0|e!STRp!O9W%@(y!7@JHQ7J$0xA8%~G+x*oo?-z;Zck0Cf#IuQ55 zp54$Vjk@zKC&A}#ho}p7E|}|zNE&PTf?#2yOy%jRxltNdVDB8fa|l*%LWujPl^V~y1O_zPCzI|5~$+rBID96{hpxPu-X=(S|g)=o2{$KQo`t;WO0UmP$&%Mz0=CA3{eMuJCZ^A|HT zEkgPh|0Qsc1h{A%LNc4lweve&uwfWRdJ(0MJm76Vpie;H;~@wr6A@e0VP6O~?=481eLfX(4R!f+hlML3fcvG$=7l zN^I4eEnG|!yHC>)#`t8G&Xg3$n8LN$mkL1!)U7h5oq{Iq5(E(;?N)egr%?!-Z)S>v z97|xfiDc6mqQsn=?xX^QI=@WY}h=&4Vd?I0vbmvb+?6oiAwQeN?rr}LIK zz6n1JDRor{3uZe=G900i0!}{ZB>v!)&pYZ9vllavZ_zH$7{!pB2Z6Kfbnk)N_p$f; zi1!+XsqBFP%N0t!@KKdmJ7BC*p=qH87rgC6qujBJr75z`MXk( zLEK8IC5pOIl)5~GBdFFjE06Di{(xxr0*)teM~dckC@NYD001BWNklHYJh4~5SE&(ODYY&SgRIzBveuRK}3Q-KJ zUiWLSe+LgePCt3mV(FODDMBcut8hJy>j{(=D5X&X23I+Zo#?Up43CjBT?#8CEuoN7 z5#Z2^WB`XE4j!6rB%_N>+wJ_^gcR?HEX_OvQqVrG=eF+vbKGLd^gdX}L))G%fv4DM z^BY@R?W2x49>%mu)!c@jD?TOgeAscwsKkY`4tQa1Xf3VE>J7kr!^2e@Pyel!bDE;IGRgu&BVkQAXe zh4TPkzz={Yg>WE*t7Eur4gv*3)*{(&Eh}Li8W|LdFxP-Uu>BVTH`AEHQt#{vc}Th8(x$?HF5NX*calmZ9e z6?jr0g|Uw3T|Sx8w&7V*Yo)YeLo{|5T!t%_z$_RN(`-9Si6W)+ggx>sTa39~3$YOr(LN?1JzVTcePd_dd0 zN3S4c2p`YZ)FgI|l(m%$G)3DpE>I}u*lVrf3rHM%g2g<{9Eu{^s#`w)8qLc-sqFeY zXd*NPOFbIny1*kw;Zh{w5FXuV<|*JJ=t2Mq8W$Ih#yIYUXkKzG-&Nv^Z4P?2iIsq{z=4Z)|YtM@nz^Pa^<#||GwieCpwa+mV6wgk@jouN`Wg4Rck)t zn$=G`kL#}dHfJAKgqak+bEjP|*u1B~)~(yvwrvN~ho`95Yt-vCT8%ocNNHAQK}dvj zIOqJABE5q7EGos7U;6}Z5aKv_POByiL;N5hEL3nkf#(Kzo`)*|t$D!ex~ERX>k@z_U32rR>;57+ALC1ZJH)FSaH zFr`qj{dXDj0f{kpN^%817?LqB{u#AD^TM7YM(Ma0qplT8UYB8RB~4+7!xrW!oEQ7# zyl9^$nMvR?7Ml`rzQSX#y_^n9snG zOfAF={>>@yo?Fc|gDauG0DUe@RE=6g2pBBF2hM?yZh`40R0^2voPj>8^Msxx=dO|b#==m`~ssI8Ntk}QUN^=o1`fSay_U> zv#i6`cKY}s#EDluvOBAT-&ouifqATumq%mZ^UKL}#>c;1B5)0PDVJO$Yi$V3BvaHQ z(_*faBFi)dPqJ*0z;x&-xbzlX!lG-LPi$qtWU(DL_&-vA|62Zsbx^^?+rLk$m~j08o7!lTBHBi@sF)>|YnO^J`T>y|?-YDSH{+(i)~ znkjBUpsZ>(Wp?ou3WbBq<(CX`>PUsY6PCgB1XN-(uC2x_%*2dWHRJV+tL|%M?XFTQVopYRD4!N+e2uhJ9in&BlO*3LNzA!1BT5B>DQ6uA&)kR~o zjs=umkeUlh=aVKa)}L@PA9?Q|v%e0zc2BZr_Z}|)(q|W&##NS~mC1~I+%sOx8Rt9; zM+$_7kG$_KB#kO6%Rp$-G(rf87Zh;Z0%5U2;CncpW1?YQf#>=N0a9pG+G6+ay-4YD z<`d54@BZRu3}Fz{&WEcTf*)as%lVceF&nA*LWB8U)?$;1*-VU)LbQ_~QZzUcHvq@g zxUO$gz)HSg8PFS@DmIf-i0BOG)Cd8F={h&TY{)za#Q=BfGIus zhPg&NI1MY`@F14m!EYk2=S&K?^x&e%^^WGYoGA{w@0ybfY$ee%-X{Y@C4{cSYhxy#an9pd_{(f}MWsQ0`d*C0gqk5>9 za$g1dW?*6p24YAD;f`rDcsXsD`b`Uz`XdM>$Pikwu?fv(WDS$!u9Zf_8oUht>wLKM z2PSW9(1n+;h0pFY1ZH;ux_l@Xp-aN*ZfG@ODus~}n?H01D8)%`hC3FR3kQIn9`mzb zn`@h~mMJ`)gF_`;)b4Yg%*l35wryjYn(Uf%vT?F)HzV$`$jIn`gzjl6U zMZS44Z{y#IGCkLZ$dM}{`gtQ*Mby7oex5`;d%t!`)%H6eHnjNG(uQ6-np#H4oUDwc zuOuKonsJLK;)9ItPwSL4a!bNxTszUMqlinsXZaz0)%u<}NN>=T)PiZlDU7^GmRBupkW*s$c_sY% zxX*8&8O_tYp|aGSZfW zqBKe>Dlyo9i3l+RRUt?^rBK~QiF~Q;Ci0(-PVEr{bDI@AtqogNSHDQFI8?@W+b?*& zbT&Sum)7!a2Akl@2QbC8j^mFjBpvb4-k}5lh9OxCsrhU zwM@`Xf0&!1`+ACd0d)8Udav6(NSW8t)7IoEW##5b;YZQkD5{*L_I0e`+grUCSJ-| zN513rF<{f+uS?kVDdbj|lP;|!JP^WOVpC^G$6^rPG7oT!|E#jyu#eyo@Evo?k4d&t zn`f<=i13$-9v?fDr+tY3mwptR>iUT^cat$+P0JDGuPJ2!#|%V&N^Pz0HyoudBL>W+ z_eXXR6H*=2;A}pYeJzfbR|u2_a=Bv#yAV00K?KePk!!rLkHI;KoL57KgK(AqRAWkp8m{>+gQe6WFPju8NpaQ5wNb~J&c?j zrQ7B5pzEXP7b>_fnjTJ0E|bG%2(rR+@Ln7G&t8h9_{B}P?241_1lU|+Ybdd_FT(`x z#RAq@5p6^^DJhRqEZ%uefd_m}2B@I6AjSv4S$jUL0V1Doy<_R<0eJ!Rk%St)@?`ez z_9MoG-j)0hDWm`8fWc0*x8>v*VnR@CtbO%n!&`ha^379rL@a~M)0LN{cHb93OD`8# z%bUTL=%**}PWZV#!Uo-8M|v{v&Xlb(y2c?q{+GpsBd6OOZriB=57VzeN4A#-_NJz| zMg>zTa^)|Sm@~}Vwjt_veW^i8i+y*m^`(|NKA%n?6(({cAAHEa3Eky`Z!=$l-{?r( zOxrM+Lr2$Lm?0BVUuRK&&3R{P*B3*(qrHN>1N8tplj2&$KW>QNnf-LxRA^2dO|l%X_QnVGy4y@(Gs{XX`(ulY zOPCEqlzJZ1G{=I_2e~HW0Ju?CtF?6^a+`jocw3w$IeX0 z&w)2?^IB%FJG2g{ioZr{rkix^q$Hc3QF|)JBcr;el~Qe)j*Lh^1&93vX?1CwBKetS zRt4-rOt_EEr7WkCc+>=TJCQ1ZM0KNtIGi`>TmgBK&oRR1g(Dxx)@X{OqSnz>xeqyN309 z^P)(AXlbka1Pl}TYj`}fj^#j2Z7SMz?}}ia|a`_d0h|Y!h20WDu?G6 zx5QB@cbv0@IA%JM5?(0v$Q9{MgLgPCXXcnYp*?uY=>$4l*-pw*CCXI2$3&$WHs}A>V?%kP=9cB zZpGC`+~3>MMk^5j&;i*RasI5{zQdAl;+NIaO0EPa_p>y6Qq69t+uRO;#=VLA)V)^( z!8e$6)W8qRY;Byq5RFh#+{__{cbWsUrX|q==6B@#tEYI8w^?wb4Nf|iL-oU~?$f&F znpZx~x|%Qf`&$3+UkS*9a0d+$=%AI4rv8hLWZI4Lgw$Fv@C^WpGvvxh^vw0PpTJa#`|F0%9(dVQ0<_5j37EkXW3 zis8`|8OVA?s?@BAc-+Sz^*bo$8S;ZN^r1k`mCxf6Y5NU3@xEll;OS|&O4GG+^|~8r zqBM~BVaz499Q@}m>P)t${{-zM_s1YmL;;+F>!&d5$>4*%#Y3Y}w>beIY4R2!Vtoy! zDKv@O^e(QfN8pl*%i0_G6d}rI2h=#`y>ppu!-@%|MNnyh> zr2+X|#q+Hd&IVi92a_h1uz1u|e{(l6aR-vTtgRZCV4#g5c)Do-QtlHc)Ip^hKs>(} z{X5Uh$UYF@+@G}e$Y@tIzCHG;60kfYT-q`sT}6)ih9T+a+AgXF`!>$a!M zD#9h4^Y&~D4kjZ2_Y0>cF51Vg2_u!wGTAbe3aZ=o>d+PLCGg5Q%EruQHkQeIG=lMR z^iReCkM~qok&t^;jgWfQE6c%Z zzu|RI=eb4AGlkWfvb0132B0_AGA9DLVVJEXZJqnZvv7Z9)fNUk;qN>)Up`pXk(jsZ z=;v2|fko%{DKSqddeQZ27xD_T)J&nEkVINYEKEx8V8U^BR?I40nTF49aVIOO+hy-8 zC0l~Z|0DHUurK`2P`sb#J^N_wAcq~MUlGdPrEo#tFszMx6W9Xi)m|TLhgSXlW2)bL zm=E)~kbc(n@|~PM4$|0d&N|pzN-=L!=YSi|g7QP9`-6kag6R`_TPG=>ciroMBk)c3 z4~|2e?t5=gE{od*eoQHOU5s9y6Qfo>>|qh)@-;VBS6h)WpKe^};lC|?e^?|jXqZ>t znou6!*J|G`XQ_~*ppL{Ams02}4ASjahp#gZN)W?)J79X~_zj#4SWW_y$`m74TGTK7 zZ8;t*x;UZ! ziye+Jusoo^bMYpZ5qzP3{UNA9$*vM^Ri=z?RmT0zPV%efEltn+U@W$ONt1m}^M`YE zDJwkuU7#>GA1(G;Dv9Nc;)-wU;DRJ7k*eWrSVvXN`I1wkr6}}=;G5~FXo4`}ygtoS zJ0|W`qVxpLOxyrHtt@qt^uPy_=f^~|P?NV|dH9burE5(;=npg2j{m)H;O)upRKi_W zXLn!n+!h2T^fmM$zv3$X#`0dUF30ireCLgG-(0np^I>x+(|_r0&9mU)zehA=(2Pl? zBwTPC@|>Jh!qFd$Pfjmk^4u>g*94eoIN&Tz%(2p^!_;kEsy`)Z@Im#j2nx?PO%KN6 z%_W70n->8SEVyaXFTa?WI-j~j_}s-TqmE=k6V4EA6R@lG? zy4!Q((7EfgqD*KSwnSajK|EutQTk@BT~t4jvo_@j&-^S8T5T=t7b-v$QN!w?W zxvpn&G$s+;sl;(|Gcp%IvOTBqIr-`)_x`*+T!23W2$Epw`7p?kdB zxVl4n5^e=@TA-)lIn8161tS~AhB zrr4VNp=EZ~i?#=vzuJB`e`!qNLWZbgilRaTNV2h{|8jGWP%5HqIOvYGBcfn_AF(Rr zO33u-zY#U6EsF^9XpR~7$PdX-389OyTr)c-_>;SwZE0SSbqa2qrZ8#F5wN9+-@vCo zBexnfNn%Az6J(|o*OcarrK2p2isW}U2v+co8ReD+N2l_3o4VmcYZYs1EGwp5wPKoh zV12H&c6F*xQuXM_TE|RkcJYWgWG7SLga!eNgtP7uMu`|@~%(Gw#N zFH_7jchzg7O_D@2+lq7q-wY>Q^%W{=5o^x5VhQJDK-nyN?ZaK5)QC{xgn$x0KLei9 zp0Is(z?l@al7t2L3iT0qfZ787sP7+sQfKr_F0a$)2Pzr4lh-*@=DX>fJPwzn333^? zoW$Hd#Nj$ZMCb{%YOQxt3?y%*esSlg$9i_5B+o6+dRZYzZ$~o%;sdaSC4s17<=Kh^K zr-AhYpDBfo~afI_u^r=^*=A?%rW%5PnHlEjR z)Xw|D_zH=T{*PSrac9u~{0kAc%?xB_m(MA4sBaRxtQLN^c#MTVP=K(^vB_*RXKH_F zJaEXO%Iy$B`_m>O4*S~O@xgL}c-j{9qT{uuaJfsH$Tve8l#Ol$Tcc7l-!O0br-hH} zqK{YKLF;S%D2QH)p9KTMseyb!?I@gw7=l=BpP+0GVIW_JYp#vpa|0hov;6D62P_|h zD;?A?O}_A;opW3^leIeMY>dYFv(NsPw2Z)jB`T9`-a1ex^)pwJ`vSElscUSx8`Qs$ zpc+wNA7p0HA1LaMCHyOTqDKrqV|r)df^B&G0eGf$c`=M__>bVtGr!O8*=t~pOhmW5 z2`p-6j1tk|UHszTA9#}po*Y^KzZeI zdP$I96QTf8BuzjEKZLR<1tKdr&dSj(*LcdS&&qTpm)eYmScaq z!LfNhDHR$fAZ&7i=VL}@G{faZpzAZ`XVJTtmuFw#c(8Sn{pcdA@TMJ+R8>|8KJPKv zk&Q{!qW7a)4dX@DU5NhN<)z`BHG>m5D7DAFFNMXU5C=%<5V*J~Bdp(WoU=F1^^$U& zcct25CY-S#1DwA}vS|s-pG!y*f)Xetv38RY#|SuWtyQ8_@8=WM&B}wSH06qdw7>J} zuI;Pd&IkNjTdA~vzv3yMw~jq)kWO|bL1qp8rlraqkGb%hjvBsbQCq9QWg@FGj)l#$ z6mmN*Ht}L^EQvd4g8HHUIO`|+nmx^z2`kXkWupsH)jm$l4_ghS*a4Z{hwNR)L%w*0yMj zmtBm)wf*FjZ;!*whge~N(rmNMSsWl2bYnSh<97$KT2cXz+oivx@dRXbJ5Efy-gmqp z@XTy}aT~2vWtBR1cDC>sk4iU$t0^E-Q((Xuj&wt&`F_}bRm0jwdv-l}J5s=*iN|{7 zmv?HqSvr?$p0ux0ekt=))BsQn1HLWvL#A{eU>1T=J|0io`=$LogrPK06d!Iq~2NM0M$?5pLA z>#zD9z}t64@dGhqgjV1mw(X0)WPFuoBSZi-n6;Uq%txlrhlQc-}?sW$XVb3!Q!w*L#I?vmi`Kvim7z| zq%-pNFs{mk5ir?sQ3;e_S=6w~d-ZK>SgN>QXAoS3)j_`Y{-~u2rVP9GU`;zJ$3?{S z2?2Uc96w$E?16B4w2)?=nhA|EfM&9;7in1wdKQigc8=3d-^!`OFIW~zbP}nmGBOKd z0-SkRh^mA&V)CPFeL!+!nhTfzrl6@YM@G%_*3RT^6n#smlfK?HVtY8vi)0%sV$5Y` zFoU~$^4JF5M6E$2X<5OnGL;4=iOG*m&q9j7e0?2!!cIglPkC8tqVrWKfvr1+ulpa9 zuSF+n!skvQks)-Pj@7m|p`~CBxJSBQgS_Wm7p#5XvPz7KjYx}h$Y@4*u=a9l3bQA7 zEL~|#@ic6tOlF)T-GoCE;U29@+-zKGrMRlT&M3sX(Kzc$EPd=QqrwE+gUnp%S0qug z{J4zNDUg}%*XpC|b^2^nlxhoNigWR#?HAl<7P?(M3 zdvVPAhv9^zfozsyN;(AsCYk9I&th=?GI%QakYsmsqEhJL(xk@VkaoE+U1m8yYq(^b zyf@uviLxr_{R&o0y7%tvR9OD!#z*iWq{{-l|BF7m2{qNd#(` zvUuCijToPc)MJd{;4qUH*3upIY;;F!B-jHrFZnDer%Kgk2X*1fjIsJ?e_8I#5Ea~k zk~U3`X|uGCXhz~I)O@%zP3k*MJ%5RvplKXA#*j&~jig^^Ki($N=Y+c5T^+}ZES?_N z;fF)0wj&VCz_CCr!=o*oRHmc$m%;0{2|?KoBXceZbcb5&)Z))BV$bPG3Y?>|4GG^y zYGK91frntL4`A-jDd#F?c^hyi^ZzSfak&-_hl>bBon*kR&e-pDtx@W9EUei+wMBaT zedw)Vn+T1U~CM)(K~>fbXqz!*3L{ z+g`z6*5k>gp#5Qsw(hy~69`hF?A(vLfG)<;qzY{k;Y{IYk;CtNFD6Gk;t-yRQMJdI zOnTmu==Wt;C)AP^{ydi}Qz%3y5&>ThZ!xQmw;Dc@EYqSGnz zo@v?Tw|G#`wdqmShqT7EQAs_3!|3g@&>Q=ZE{yEX^peJBuTu6-}h%C%=GQ>`2)q8tT z>qB>Ge&ou;1?eP+>w1O@v7(m~HV0c*v*E`!5!$;TyrZ$*;Z&X;b7(r+x^CDVc5Eud zy%7@6GJ`9wy6krK2P+hy?C`s8Y|)Xw3+L_Lqtz`N?Oei?xT6K;ORG233&{%=T&<}l z*`^T2n>(Hb4)gbX5qQ~D7J+xj(W%$j#a}^d|q=!6y09gkc>{6;4E? zB9A5ktspKLsuZM@n{K*BmU4p6BN0d%POXlfD+=Jaf1Z9P=$L>XW3zXKtwwG;9N_7a4{2821KQit>p+m&IH-j zqA>uxaF85yr^#M2cmyDgzfAMhH3!qem~$)O zn#GbPBw`n1Z{8#YHouz3$&W)|NtO`4ZS!072gGV3nU|y31-uK=DI;YHGb+&?CXTk- z)Mn1khn;3gZWR+}u`{9=PNK4{O~h|%l%%4fhYb|{_?=j4q%>k7LZ-JEQH^J}^pzow zK=gjs($_uTIF?{OfrXlIS0NHV=Qh{aw#%RE#t<=^XygmiUK{W6v6F zf3Kzqf{;|?_g=Hp0j{Ap3HiAKDHGfsjZ5?^f5#aU@>xuF<4$h42?R7ElDk*~-j%X@ zri7o1Xyl?B+YxGns>kUyt2;Y%;V7HyaE@FC9joDY1~er;Xa=d(2KVH`S?9woy%23K!ROF~`qwWv#!dNT7yUu72m+BJ ze{%YbHhQ2I+Foxe6gUfwAqc!??{wnwYeh|Y|MY1Cx?G3y%G3}QW5J}Yo~oSQ;paq0 zRXq^)WRZTt<_iUBrVWKNq{$<54WI?v?Y-%5;H^hYVi>fwSXiabtjI4Wgt6I(X~YHE z15vK41){!f<3zqM0~4ohLJoI;SgZwc{znrpS{vzsV{l%9{4xa>ylYN*v7Q<@qI!PU zsOxPAROZhHpL%17p2_Cv+KyqP1HWKyLVc)zO~YlBL#L6L z)PP@FJI!AFxHiS4>Y?1*Sn6iXFyv8GMfn~n6I2z{NCe}&Eo9PhVAI!o+*Gr*=ze*A z2hPqNhS1h0f%}!*4Oko)@$1WQ!BsR}1BFbts=d6eCd+>m8oT-G)}4{-;NilVBV8J3 zR*c;(clgPp^dD?l zW|EJU!#Z~{K~_!v-C)*LLCQ2m^(Z`=-x_e;1MaX*s+YkebIzlC*_SXm-&si!^BCNI z0AUMg6znfl^K>=l#k)AAbqS07=TMD2_vvRfvQB#b$;9f|)M{aI_5Fn##;8b>OOm8A z#AmlDK5Y(qcI*Jv0&eg7A>#bJKC!q+M;r?sX)CirS0W0v$-oyqF7QpoPhv_gC+G#f z#`7YyP*X`Kr!*FQX52g|Of?|B%lS}%t+%uT-e2HMew5mCw_sRwcvU@=J$W}gXH zwDUcDqYx}nMrqRRWs8)FM#Rm3+IF*}pbSJsVV(N**21yrR=^zaZMWy0cX(kJgmMV0 z1)1cN_|jV)T`w>B8yyA4=7vHD^#@K_hRK`-5INB)ct_d<^B9FP1uO_6%H^t_I9u#u(P+pjCR~(? zg0UT>ne&#hVy#54FVRask`D|ETkVVIdSJ4l0wplmT&vxxuX!4`;z`M#SLME_|BdM53f(8@fbG-GHy3H8#@ks`&@7fGZuMA;{x?7d>^&f#G2+^a;mb zWFww{1}6i!iRop}@<)Zq1bA!Cl(cmx*Py_5B1W2T^bB~;ql8+ISMGUJBU z_82E)e=)AIJpgC&tV>)Q*P1-l5pl(?kov?k5(@!QT~RDW27l+jY}uoS8*rvf zFJs4NJ?PSiLd>8M*mARepvU(1bbr)45Q6Y%?TT;z4MXIs@UV|kJ=)5dP$EkXISwa} z&PeRC-ghJLn*^|kOyc0;ei%Z`&0okpFpkfM2Hp5k6Ge#J8_!Kje`VkOh5AyDE;qH0 znBcHI^@peX^%K76C6T>Y5elTt^0Ki2O#iVaOCF|7Xtajjk`960xGWCf_hs_?_*#a? z>pkztdsR{OgOG1AmW|TS2<;V1>e0uig};kss%aF$yTPj~*c*?<9QM5u*Dz}iu*>xx z2=bFA5{G5vA@u}e%5rx;5iI}O>=xS6h^Pq~4p&Gar1(_G-A|p(!lPoWa`UTl=x*zD zMBEyk?5OeQR$fSiETy$Q?OX+j`g(@7wz{!e-u4WsMHufoIZB|+$d%^D~!(7Ri5zp=LG*(dNg^j=-~?W}knnEi_%soB(b(c{Grxk^up>o2{z^x*RJ&pC04 zAbN;P+<=NqXP&fIV)!LH5p_6DXC*p|8)Qy~o@)i{^L+rWb%B7UBwRWL(*!B0RbH3| zCIprN)p_-GRx0+rQA2WEOsklICawL)&t&yD9*4)EDKqg*1}0PGAKW~ae-m(FP5UB# zj>n;7m`-$}+tRHG|e2cRivi=l!sJ-uy> z(tIY4T{fi9V1PP26@;E2m2N6xqhXqjC`! zXVulMX+P2|qWkQXMv=q81*g&acY}$M5HVkD{of)7Bf{Q>QAai7@Hz$?HIAY~1X{*FJj$?mWf*3J|nPK{u(-PoB z)RCFYL_@-zIbTBWl=1M`)bPM0`-ZI4j6Lw-zpQHgf3qt4c0X*bRT6pb2QpkVzbC5J zHwoPh#B${b1Nf=DzB7E$kw*ujYf)`HToIciP#KfKA3zR_{Bb>yy0dulZa8-V#IjNe z!@9nNqK{^z>F?9grGBV6jVp_^2hJtO7ZWP<|bD~W`nGBfWPN&JpAaO z6Y)S)YoU5hkP(0f(EwIaqM~ReL=M5U45j**Mk@S$-2@o6y#rpAuXEQ*53|KF zOUVP!Rt1?`h%Kt=@b@_OGW#?LNO&8O5feU>#@542rPBFy@YA%m^6xr}nuB;1Rx##O zV#f2_uCq!K80{5X2|Qnt5O)4*7dB1fFFS_bNwq7W3>ga7AZ3|gdchH3V;=_%(e|qM z(hezv$xEPTkgy_Te3C>BhNk-d@d*{@pKGNxaJz<>g`yFll8F+28%;T!Z44jbM{r)+ zW-~dD$_hh$XK&2;_QT7#+)nEF$!x4NQ*vlKUU7mr-ARgY?S>0T6OU zG!(dPI@|Obe>HHO{E9UvakAXb9u~6e<&{Mej~|3ZJAh&K9sC?v#Mu&uby?&1HAlG>qyKrPd1Evl?^ZL$U9m*S z>&K|o&v_n`otWDOxNP3-!;t?iN|FgqEhGce%=JX0Ah6n zicOehqn7>Ho}*FWx%UKIH%P+;vD}rFIUffb*nJ9<3TJHE=8`8&OOG0+ zVHmT)9aH@3g_{^;h8vHg&bd!kYy-6#-ZVIc+b8mM}Qw9UOaP@Zt;}) zx|}aTp%AG~!yhEEI}=)hzA&$0;XG0TEyS7(1C2-3J6t-zfJG@vb(V8fq!C+BR&TlM zEvO)`>n=-52`4~4kjJJBjRWaP$WtZx;9AZkG7#6y!^Z(Epz)30p*@BTq+gM-9foB7 zDw>gIX^NMituCkDCh>1CSHhPBb?9J-ow=vi5$-g8HJ-fN3mlI&}lhNG1HvziTezaAQ z%0Nshkp*InydJQN?>$`F7=;~jv3ds^UyQ}T38E=*cNQ5<1;B^S#>OrJs0Za~O})4! zGZ*j=`L$1m5O8UOowk}CG2~jnjaRq#y}lGjuq{D&hfwju;biB1;U^}mFpyG2i&(@2 z-v*GFs1W>E0|KV`)CAOtDk(TRAIeZ%|LIj%ZIXjh%QS2fSslTsrN{G!L`c_vS%0fD z#vRoE9dAy9*WEbRTVOgpE+sQ5#D@wa#Op%mRZYNm`?zGr{lDmCv#!!e{8S_wkPfZb z@3k?x{Jrj#)d7Casf%}T&9)B;NEyxI4)DUl$QytOvhV}dlM)&gv_LPe2~Sg77BVcbFp)e3v=T2&|mt*7d1UXkP;t%b~+-GeESdR@vPItM!2$C~ zZ;xF3y1^^mZm(w;9vBDSb^qQ-(9?G7Px$X>EY2qdi0zNc{YT+;#=q~5OFvOAoo;Xb zj@w8gAnB|LQcp2S>8!RNwniX?;fAKP#I?k(^4go%ykg=&zDx{?NqM3fehXXnOlQaA zf_7Uq)J#yy&{@!4#&(<3Wr#pKYLMA5CsRF{NJTP0#ne;_{KQb@#ovpWEl2?z+16A; zVM0r!SIQ#D5DuPQV96eoz}hYuJt(g9Voco2jFhAtzLPYON;T@`|5k+6Yz74-B}4oT zGj}7^)chOgW(vyC{y{D?;5Qv+axk+3YN(<)>gP3W%0qtTiPi3OIko8!Z0WH?cX-cQ zBEQv>o*Sux?S^48sY*;k(!Q%kuK;wp4?xgaq~N=5nGWI5KTfZJ{MlLT{qK3h_?xn} z7MVA1*PNKZ=bznT=LfiR;D20;XMhTtojc;5kuMojR8eReF!S{IQ9mNtW9_HESXQJ{ z!AzT)yNCLSl#$U5ASVw{#7fYHw<9ctv18d2E4IFZClUYJcL5*zoIFm3Ys2edHrz~@ z)Q1HTrR)j46-9GI-z3WkPqMjVyFxB3PM@LHju}!|$DzXv7jwe#Bt-0^+J?xc72D4u z8iEgO+BZx8n4&Y2Tan!b>i%+WukSWE zdg*!JyQKyq=G8~EQbI7Zgk?FVR_7J=^BjqKzvsLB@b)P(1&*WE)XZ%nP*7s2kBSR` z^t{rE>+9etqYe5aOBc3!{x^?QzI>~#iS0i~qAj|~)k6rdmvR4jMd$ckij32G230zN&63N68ba}AqbpESTz7GGCS1`Zrg_6kTvu1g|Dn4e#)n+Co#XN*GN)16G z7_2~=0|Uaal~cx0_*CHI!wqMN3P4bRi>ac3xh3K{o;11=)M=OC=Oj`FS*;gPL#C>A4mIJ{ zY1M=PK%C*7c0Y64xH$P0DPkduX|O@BuI*lB<5;9g$hoJ|xLYbOaKcgyQbcwQ}_L>hT?gU>&P@7)qZ!+u%NX2g<)xJBnf zN}qN&m|mIag_=Wh^)a~lhkcC$J~5w)%RAUm|Nh?A8+;>oF_=bt>V8NPg}3HcL&1mV z8{u&p)dO{P49hzeGLCFQ@hUoioJ3gjH*=UQ=gx3(3&Em6WW&>%fY~HItvKP|TinVD zS7UNOtr`3t5pbn@y$AsDq-@nCU}55k$oApwZtRQ%m|pV0f(*7O1`$>%Q~ zIO?(A_U+U;FH6ZD{-#`B99}*!2lh9V^MPUD50xYCS$DTVp*TWtowa!9YBfNC5^B%Az*B?vzY?-~h=;En${e=UMcN~N_auL7B}u@2nDO{`&t_yg z(C+;k38@0VHcT0`C(ck$U3&sPP)@?!{ID>*OiEJ?r1&DwFKLU5suq^GhneX79k8lK zP=THz2EL-5?pU|sFEx&>C5GZTFnK}gGn)W%!R*?L_7H`XY~8j>$*&s8O91eDH!Rua zRP*$v^nJ-^eq>hG%jMtwH3YF<{ew6U+YYb>9*Rkp)yxE_4t4!`w1~#YMxHKYS8C%J zJAa&Qt|W1W?q~y56UO{!x2{*3uO#`MQXI3Cmp@?_I4X^hc4`kbS!Q+!a^a*%AuruE zezv6|+&*x%uu&b9lu{;?N&N(hu+{Voib;?tRaNMaVOEU3opQ~$Wxo5rEP$w{;tOiznsF=4!H!nhm9~x7t2DrY zaG6A6@%L+fmo+~7{Xl4MKUVO^vtLs3)3xUpy`-nmN_ZfuCQ1{Coujo5 z5>H>N)d(Ye{UA#g=m%)od?IGrkH+Kbf)Y!St0XYzo^!@B{kZmCB7KvXt-(2gPa>hI z>#jF}u8(aS17n!7;omDN7thl2Zr};G()+i5wR#qiZy^LuAog7OcVABN2@ijhTE--| zZrS&QIXusBCT-Ual4}UIgcsV*jb*{h=%{HSVYXKd3_ptnq|`3o+xfaej-bW=-CBEi z+bd7R*2DZIe75*W#J!vs?zK`#X~O%#Vbu@6I1+vKEW};;@Hj%L2luWL`5iP~E-aab zZU4fk+mBG|CX$EvE9u=X&{m6K(03dn%tU$tJ0v+Gz4Ews-urd>f8 zO<=^uz6BjeUz<#nsf%z+zyyoL;9*NlxYyuk3{{8VS%T)U8T>0<8Q{9|u%IMb{YKc* zbZCc;WJ=H%Jw+ZBjwnK;YkR^9;6x}vY$z|e9~$xwWrPZ?ijq-M;*3Bg>D!ict2gPX zP55*kjMFm(l?-V>}o+ zWHW~mL2R{ea#j_nV+7dd8B3|M#QltoIY3mJF{6xl6h5{K@~wkk4qwQ8Z=K1!A2i7P z_c-kLTZiaj;H(X9WkYwbx?6f;$JLGoJmE}XK!|#3?7AGc88~F?wIyBPx5Hh&b?Lep zY5jX#RWVCCxr;xIpvfr@=0GMlxTG>3Bz%hy8z!j6&@Sv3ss-mCFb^T@e^ouS^KG4GGO8)KiPRiB8gR$9@$C48fr4ktr&sEyw z+P0#{&kFq&Ts;+bu>o&ajrj<)x5pVygLTiF0?^{(l28_H_1-NwaEk<0lGzjeE*OjP zMnb8#f|~lQyHv&~Nwb}iL-DcGkx&*zr273J-RbUnY?spn=G;KX%q3;KvlvBP#iU8K z20mXA(hslusqyTIXoKt9>AGusPz!4iDfUg#U}UlI!(Y96GZbdgrcmk*k<1_4DfqpC zBE8wZV-x6*O02L62~lR^lDC zxPs)_dc4IUD3oQpnQ#|djI=oAiQ|tKsO_Iaayzp_Widqvn3__eRD{#ejVU*~sgo4W zf#4&}`!zrSCknmh)o$l!ee6X{JpEImMo&kJBh#PwaI#<4WQz5_DkyfedKK@J>~Io5=P-?vaF zLlakSJGaii$9>)$PZpL}Fl=jHgiWm#eBf;7(S_27E(}Ag%PEa`m(ye;)&7Hi0ylj> zdGsxy)_`Kn3t|68*cAl#JmUh{F5X{#L1Yj8UoVr9kRanC%5Ux?XYU&Oc%+2M^1G}I zL4@IqhV1+>LOSA@eRwhz3c4gx3H7D>4Z&u;Rqj|fZ)H#kUwShVIe5eTn$XYCbN|5P z$((MSV?89HM8W<%55}WrZ$SS8Qxj+NEwRC$e<{stUwJenhld`wS~(}zaxoTW;z|PG zb8*zq5q{T3s7u!WN#Y(b4~d$*{N>2BvqD_y@)K}^0WH)W8p-L z5*zz6YfYb*)Sx9TPK>qm{TnCn_vI^BX6%g;6?=MvI&_Szymzuvx~3>M_V~>Fb8SNZ zTr7;-2*|fR#{}{Y`dPOoE*eT*7f6ng_g;|8u~Oca32oeP8lCm|;e0j3J&gntosRY*tQ}KQ}2mFl?qzz}BlS~fZvAJy(bFQH;1&i0H=Yt^-N?@Y2w&#`Y zs+*M*T2zkcL7B{kGZXjNEp;`x-Kj=M6H@NaI;_~|Kqyd2A&}1O_?q2pvw;8~=P<88 zo`4lv8G&OT-zR2EEue@-6y!Au)iexY>$SuOi(29;+VGAp( zyFtTQ2q(?adCqV3`fye5aCrQ4v$yMhV|-`pHPrKEeyPnnYMU*=+q7W39~8xP$o?E^ zJAv;($9HG??>>i`>~(+oagWqfeMFv4`NZt{#oX&X$GGG96Z&N&25tUH@he_UsoiwC0w!adwz`e@>=Vf^R zJ?EqO?Lvb)y2ViH{IM6Az23ETn@FQ^Ah-YwN5pCIl0w#^r3ke=L}O!slJ9npD(HeO zLdh56o6x6U4!*-|*KdedhhIYP%Mqf?2@&!TZvn9YB2i!3r_=M45WkUTa)VYyUM=Vq z|BiwyQy_dF%f<@8B`YsOXw19*RdU%=AzzkXVu6naUiYuSS?$(+M*cEVozx;Olnc>M zbtn=nVFTsuWdgJV|bvcegXf^|Y~bpJoMs=3+Z2O6YxGTp;`;p*66B z=QuO3c-@W9clSKL*h~c%-K2_3{h1~#p@k;dS`j~D2EfDCOQ9|@;SD?g2kbx-ziqM0 zBV#c;q~+Nz4vH8J2wVgXV!XShl@4u5xRZ*Jc1;+YgzE7wm}5t7tdFKlr>YtcaM6Sq zVn{o1lD>vaU)PGL3V|jeKoO;->6vtFwiI2Y4p2Ak$vMKhJx+*SeEP%|7N6L|$*mqF zh9}Aia|;1cV#v4-73Y;g9#G0)L}HiXcr+Q2!pu$;JfQ*7BY;) zivO8Ekyp*gTVZuDv0`RN4n&Oj#ma*{%m&YcJ0e4eXJ>3~&6?3_Jjr-Spf{V>J`hYAhhvca>_5HK4wXz+rV@X0R71#nx2h1afOc}X)f09}unn0Gnq%_qVGD_Fm=Le`gb&1#03 zBhbHF!|M){^Z>IinR`HVv*_20J2~RNm%7oItMw z`3Qy$obJHfcDO#VJvK85Y!0F7LR5okE`(_kYBz938+^GJrZ&No12CfrvJ$Eare~n& z!*K=7C!RvoH8eY*9hld~9e>!)c{2h=`)f3{`mEg+Q;7|(ClENyzxHBS_5j@O@x2E& z^8YTH0LORm-=AN_hM|~3v&RL~d?so^=Nl(;?=@>VfN$r$+p}(#$X#vF^14Pp(d1s&`BYbgh1%YM-mbs1Og<~glc*qG*e79HtseqvSrKa zUE01gbH6`kS1uUhDy_sk`i->Oot-&%W_EYx-S?cstnv(Uvn|Ec*pl0$w`1LQzog4d=uQ~7-Iz%%ya}l?@m!R| zWT$=WxN+mhB#wcR=nrl;;SmWJrA&yI0xjX-G?CpGs>w8Pkq|3Mq>?ALB{Jc|B;gIU z6T<~c;(xoLPqIyry^Qq4k^_mTwL~(x9gXeYw4Iwl>bpm_`S<3=JZ0ym^fsEuNFnZ(d>s|hjq!?nE~A^_{B z4`Fr4;D}LO7+ojoLKz16m zciH2q>9lKWW_jW4tH62#zWtL7$O`Tu}Sk?)r4TX2t!x6>M z-ULfK5VL@w2F*G&$6;9qhi7@9)gYtX11flG1(vQ-an>lPYlAyq1ziQdn{%%yf_+AC z)7kHF)0u@__D~%v8V{`w;ZX&Dm>)p%=-lv13#KJG{n|Ke%%lQ-nusE4&$3&Ot05%Jm7A{=q*g{_z0241@ zA`W<&x(00kGIBe5_OH7@O*=LQ0U5G~tmh0Q7KRw8vg*_|Eiw|CnZBylMM zlKV`EexE{~p#YW%Q3-L2cEdtZ!IjhWtVqR6og@I-d7GO&-}OE<;R$kO>o!;Q&iNc$aWX2N}Lh%7*2$Zut^w*REi|$VrSn^msD!OR4#(!C@}oV;~AGtz347 z*RE4p>*A8(X>@q=m|IiLkppya8?e*|8!I8l2OA97SAmfOVetlAg!G$W28q4hiR;NT zSupcS%5pUFCSjKr8f1duv%8qT-eI3#Wg4JKnB;?~0qqtPYA_%M5BwR{gu$i37%#L& zA?%0oar=C&$buzNsFqNuQ~5=V$USQqQwA(=2Q36^-Ei1osH}qKDBOKKv2$L-B?OGH zAh!g%Hc&iNWk~}BW`BiOvru&v3IvSO`SkGys{h`?p}B5QRPK9p49otwfydTcXcA~P zSZ_$i7HAwZIE%Hnv=Nsz#7s%c!|lwh@Y2>Aq%kCrSB!>^b|~;5{@B0kV}=i9q>z~=Gm%)hy1SHvnh-J#+$1}OgOcb(Zgi)OZ%*+8 zyGEvpfyrj2%j#~t14)Oay#}j0>0C=ZTO_Jeg4ONRNhY5sT{%fdj@|S}OQee1KF@e} zb^YjCJ!aYEU9w!z7PpTT!CtM^>9G5(uWzEfFb{wwM;y-EbKb%~X)^WeR&o7# zXL8vqFXGa4ety%h`Pcn-;x8J=%pd(6Gpe%aows>^{=X<1l#g9!+@W`<29^Uy?&fl~ zZ3?ubsC=`F^P4cRMNTVmJ7*Wy?XWvI;-$mRkV4;^Iyg8u>_N^Pj-6T};OsZyvbXrz z6dhJIV4vXn;q@xJ)?_S3>*`#1pbqZ+f;lIA&gDmKf)RtE%79Xsa&{gA(ha_UQV|&y z8swNzEa9$0;NpDnnXtr!cdDULffgOs#i7l@b#f7${XA6>LEgzaoHr2S8Y~LK$a1hs zAVY(5#zC_MYof3=45yVrrwUyPe5J$1AHk8?a8V)bp9X1u5H0Y2JESYH(gKeTLsjTB z7@95^lWDfZ9V3z2ofIn-6f_jviH15} zz=t3Wg)9`ZfV4!1a5pAuB4N;8p1n-FHIV3T3SlL>oh#ij7(^45H33ZGG!p+7@iN&B zT}h;)Z(Cu>k`e?M65>*Vl&FeGsHv%cJnjy`mA}&lymV0nao*p&y=WhfkIP0uIcCjccJu zha(5WYt`^t3~B|W=@9OOSEj+2A#l5)G6eg2VM7cC<-*)Xs1UF|3Z68`jYBvJXO%!! z6AUSZs~@$`!TvBGhGxS@7G%d^te5uReMOeXf~VF&vkGpD&OdyCHzY~(O3*aEtctOZ zuGrV=T_)t{SQ4UiPp2Cuab&SZ>>5M2mQWYcW%cMc5xI$qHi7@KEF>re$ z0VT%NX$91L)dZ!5KuvERF}+ICvDX*encE6uJ6qFnSB16R-5%c-XHV3nOfG*{YJhHU z-tEP^t10Z;BOp3RlbHaxw@TfU=!5}59Ct!YB;m-k6UA-pG;j+8Ni2~bZo4#1lIh}G zrj17v&)xj|WMX*IRbyA*G!pk)SeS{rni}R-!lRj(+a%syv0bL71WRHGfgiDpU2 z&g|{*9KMB>E5D+sVC$~fUCmA1w+D|d2jGO$&g7N1=CE$@G8Vr5U(9GH730b&C@n`y zqbEal*e*I>uR*DAak~pUrMndv-BUsBB1uQ5BaAyZq!Nw;)4{=^-y#1{3|Y-^#j%hs zh^>!7Ll~xbS<)bxeMcRvFsND*W%=p|mwhme_DGztaFZ7I^6=$ePAGzUsWUuF2UCNw zg^*JYQ%c|`li-ms!FN|M`QTiXSeWvY#(^}M@x5$@&&Y)I9C)-HZe3vqbww%sCjf7B zKs*;*=}@4%?Sfq`C#t%uu>0$pdpn^F4<v8xWo zZ(7#3J=Pm3@OxrxyX)5cHUgpplQ>bLeBEUz(TJcEM<))6+Le+R7O_OPaT5g#6$@b+ z5RYQT!pLYCD-y(v1~CX?5W*ykNiFjy4{sW-*m zmX=2$u4?#I1+sl$NP?EM&v*6w)?wFi9GDIc z4*dpsZ#iUGu)hyJ55dF#fdWZqgTe!=Oti3>yH6;UL4RB~S z{IePcXf&@2lQ$&`ZkPZ!E`kLb@4qTIWQ2g)S{R?2o=nBH~@50I;jB-P3 z%)VOB$bkPg!b~^RRKfZ%7!Sc|gJEeL>O$c6!zf^C2HaT-Gtyw<0dPhQJh0MsW^Q;1 za@?`zjZqp!k#Z^f@#@lEQg#M4{>KDHt7PYWq7I_6(T=2WUFs34#w_bjm^t=I_I%7N+p7|Yk zLG~Ncf%(9`y&Z^ygF_#}abP+)IP?qTKL*)ZDp3_a>40n#Ty{g8fMGIgph6r-*90vV zoOQ{33j7LBycEK)B*keOE$tfP4k_Z&v2I>|ZaDcqh5y^f%RzrEf>DP+!wO(B3{8i! z62?4t8SeyaS4zt>O>F$s89s2Ec4zSn3ltLqA-Lo~Xjb4LpIws26mUls4D&!$Ahbfnp!y~Ow>;tmkx+zeS4z&^1g(M74W9HNW z%zEK$^mEe4@aY`vgOe{9gk?c6DycN0eDX{k9tAGEbv&(ADjji2O+@l}rOD@)zr%GU zDzhpwxcb*aF%-eQ3)Lzt{#4&`TM>AB zw^NlZ)6REiyX2b=4WHIuBhmJ}qDF3V&mbBRPZ((yKC;r~2~PSHk}XroiK z(J5N#5G}NeZ99^G9n-XB&v?SnXV=2yJK?}Y2v8N0eUxHSY;KN|La2(}1FxmifM$c3 zAsJlYvmeZK1k6-sKtU;{5R5)(77t#39f~CwJbV}{t2T1&9e?KWH$K4S%|nwq6J{L9 ztkk)gM&k#M?Ss}Y!EOw7qWH8 z@WSjU%rzjUP(D&;>PflWaCSDUB(&&)6NY;D*(^8d9*si=Yh?eqgxujiICmdLK5`Mf z(Z&;B?!(M~mO#m5m^&99=>%%w)Et;`G@#Ktz~45)1s~JVE}*86cN-1ZXz}sdE^@pU zyj9O73nHw2y9LIZEWfxOa>2Z3ErppHv2`7Ah=<1yehfY{D9rOP{hj0B)S+B3Etj|j z=lpsE(?{q$dhQr_a}zm55em|Ep1P|5O#uR3WRJ`sJ8UxV#U`#fV;~Vrthh4!#Xp=wB$*7gka?b=@v+1H-h}BmgDxT9e6@_hbGwwgg>C*exySl7eWW9%!oN zkSmr&feJ;s3Sp22cHK@1;@bOrJ3NPPLDe*b+rx8z_#KL+P*^;GQ3veLj5E)pbo4|b zaR_$=IP~mu`0348F%-M!wW7H>YFsG*mi6r}YKK(BsW16mrZ0Sv?2vjm0;Yq5L!UQJbch1 zm?2=Y60ieXxZ0mmbQ# z#a>vK4r4N5WDM$RV5|=sENBS98*Q+v69yU(i@@SA1Wfp270hY3uh-jj@F?)~5;%1* z%oH%d1zrKOJaF+iJD1U=!qg$O7?RA5QE2?!wg=6N@XUIXYU$z950{bVRk-Ah^{jKd ziCOUdx7&ysl3PCtLd?gQQ!OYfK>hVdj(q(i)-_3Jj4?dh!*g#1h#MwQ%&TY4#gZ|8 zII)Dak8Nb>S7A_EVWJK<&S1j7t3U|Gk5<`#S{{s6@aO96_rR6h^L#yboLWMfu5fZW|U`T{$;kM`C!5P+HJ zFK%HGCx$^B;~Rg>?rB@LbZ~yX-}jD_>~@}%P(5ohNMD*mlV<~s-YV+F8tTd`shwWA zi)+}70w4vdObD2OD>;CEjHZA~74~P1B?&7E?a9|{id{vx1(drbq$?my+{w6QKi^6H zfa0Qj!tHHjrROq!|Eb*Y*wdVJ#@UP*P)J986D@1jLo`6?@KLycDxj`8z|_1gORJ>! z-T)kS5f%GODu@1oQ_s|4@8i_KbZ~I!v&hR!U{Vf@$$}--;EvF_GETsdw09b4QsUJ> zYm{)w0LTOedN_Z84o%G*RiLpp65;zlngCVHAhQ6M6T$kq-L3Vu3A}ykCmg<_9v*)hetibK=LR(bGczEq z6IO)mlsqL4hvmS(8tmq|x`3;5;E66c$OGveB~er%-l4!)o}^S#Z+FwESol z5mSOk!2C|g_JTi+__}t+UQs~JMG@Lt;|%a>9FUpG%C;7MFd>a67Ityd^mMMcW*H|= z@N(GD3@C9Etva5OBgetOPResTnL5~jQwGD0&vV>$1L3ncD?VG#=;w}wo94plgAgUJ z0SoP&vkdfX0WCpZd9j^Ir9Ms{e>=~dIeNa7FbQ`2$+3A?^IP6heJ2iK2G*EQt`#1uogM&k#L%x0tbX0-M z3&rU$VgNi{2~9yVvIN04$?$y84ErKxbps5~(_p?2Hdb-uZz^Dr&bbQUkHeBKm^Ko! z1)#wx`v9N8en$dJpt2K26u{kw0RkcJ+#JiYS#ZXgaP{xl(4tWG&nv-W!kPca;de}j zrWjoGeVCaAqhe5z17C%pJ`Tcy{dH(G;BPgse>!Y1;HoS;H7^dVmXOm0Q_Df^faVs+ zlRy>}PJxbf@cVV-mI`t^y$~@VZb6oW#}|EN10fd0Up7d>r5v8bTGfYdmRIO@MW{)r^jXR z_x3?t^v1>>ID+~HJL{m_QSoj^=G_}7l|3mgZaKzpx}EBz+DW|{Q2~L5Mw}QD3xU!t zM#9!^O1;L7GSEl;-}52M1%3@Y8X2=bPl%ZcRziqON}B4ooR*rH-SZ{axxH@Tdkwpn z5MH3glvtKT*HUXA?F}@MFj^*3u{TBHj7Updq$;U1{^#~7r!rt-3d{ZyFlgG{>@5|P z6tjvtY{i2={Q-Y`VIdxmo3RHSz?c~`dHA2taLom$1MrWh9{}Lp<+Vtly%Q#9`?p#~ zUwL15*ph1OPmPk^4#dI1p%38*m<|pOeG2*9G_cmgDW&jA2%cL7|5=ONWFXQ!ENX~g zNEqM&G6i@AMeTyl%hvI?dJorKKM1Dg0WNrGDO`9WRKEa+PJwl+;AI1G&a>ND^M~7w zM~r<3cxQ8b)}1gwhaoS;of?rT?!9mV^aLvu&BaZd}Jox|EmlbI+;bleFCCV(LRgoSdP zj?B_g!Uke~3{e0A9m0u*YQnCe*!k9e;8DS)kUsSz02EXN0*T$_ddrb*mMpgvp(HJ5 z4MfmDPhm<4LL?leb{e^oVj}b2KoxcxIi}q<-ecK9rfN5dPZ=_?&;_7MdonEorX*bx zDOao0VKefAlNj>cN91P>#GBjW1%tJ|>-OOy+NjljV|l6sQeBF(!2# zD#79my24Sedvzp2yuS59f3np6d+zexi|x`fI4}+BP3Qu-tP|mm!buru1zuPfgF9aV zmjXczE*S{55qPr=rl&#B4fl^>;)V0Tn+}6Qu<}z_)dB4RC=f6h80dpf>)?ukfCXg3 zmofNWCM}Cwc)Zc%pmIMofiOpnck#gTFj*TlW(|t+m$d=Xb@C)S5#!MD&9$Z1Rnlt6D_V5uAOrtSzo-! z_)?7*R>ZjZuPaeig$t)0?cTrEM+ly+6b z)CtpJ8!E>Q!}IPsbY0-pVD1aEX{m1_-Q(fb8*bxSko>zcC^Zm_s<1)VgMsYLRAY4%H)NAHgNKfvtfP| zjx0b-et);O&sk%9`11{h2{#f+s5XKgvtagzoHE%>x~VbqvHdVFnunU_1trcM?{v@< zmaI9wka+g$&#Bc=h%B*B+Z*gUTz+pflf9oS&rN7!w84*4IQ)9 z{Oe5^vIomHB!$dvafD5W-lGZ_#CJ`+bX=GYJ3|U3e>gZeID9j5_B8mQgLp#(e&;%8^DkFz`X!GfO5LHM^SHS1tl9^c$2_p{ObvNPH;`#e9c(xsa?O6Tbnt;dtWIK<{7;K8bsikn?WYDr;hzsgt5LIEZ0DlbPDh$`* zm31IHVA4pK8-aBZy90RuSP`|IP4ns@7H85dKSIFIE?dY0D^DTMt8)HmjVzbo&ZDy# zKTzSv-zx$m2*D`4v=Tm84Ic+!Z5PKDO4dHv0+ZABhcX9h}YTd#gY(dGCx8W- z^G)L2uBM9jv>3P}>)UoLsg_dS*G}34S)JXjd6MFyuIms@8r@VZ%|codS!dV@*V%5! zb3=g#@;y-Kg#kVo;D=#Zkm-UfH+WS#8;+uL?P0X9KAeyDanp9Fm#P_FOhsT|fAgNM z>`w3UT_YqV2n$P*SV+DDmb5G{-HD%S#+*rY$yyldo^L z`&*yu&^s*BeJH|(+vP?{%c3(JrfkG$W*mP!*FXO%SDklK_q;(Mwg+DF-y~XYJI}V0 zgG0|C*_+Mi931)sj)3Xl;E?jjdk4Xy2FMjq7=w+#uOA1m0u>b?B@vfE(=6sx#yRLu zV;GsQvmlhtrhrNyA|SlyuC(M+BcN1+Q>TOK17QGBD9nbzUa&%N&w99FUj~lPgxju# z32$+^6Zdk}f=CqRB1S#Y~+$%_F?`ccgbwB~j zvg?7Sl7QJ^g3GN!rrU00r$RirZ?bZ}{mBkJ&hvk}mwinimZ^|cG=Tk2IFfe08NonrYc(*5NI>M&Io@X#n)Z0Py3aNOm=8&2=0;Yq5 zLrNp>F0)hD3W00|S|yATkgkHB4sWf3@!7Pvvj}QlW=>CoXRBCQZ&6(z#P8S0{>^Yi z&VP45mMcdgA07^+E@+O!xLQ^L^yo9p0cKe-H6|neo*w6$o z)kDyPL-V012hPlb*H^==0th$RuF9Yer+c9hV#hoM0SjUZ9GT7fbKhpgN`qpb0zR-Vmme<+1BMngpK$~|2yZx!5f!7#uND=j#3FdLWq$p7nl?w#L= zIAQK?Z=daNv^Y%3Mk=uIy$1Lsz_G_?@ZUwPsKSDAX$aNe?hltjUM@VeAH_c_TOc_Bsf*J(eARjt&WoD zLoSjf676O?jTU$W6slN_Cb$#n;$F?3d@2YHTaMH~(-XH{iBxh042!rWAqtfNNmIFI#Aj)FxOEQ~-}6tdz2NBX$CG~9r{1x@P#v~IOYNOYT1V7$ zaBy(wSsVe=!NDPAk@r_Xnh9;fz9=yyGYY}zgrPpz6o-L+csmMjwy{PLL`-QrmcHy_ z@VS{(jB?}8(BLP(Bvd2eATRv9gsfAB!2Ff4APiwVwrxh^D6X)swR6%(@;*wPe z&&!luzi79&%l|^$u@Q6+;&(%sbly5w$lM+FmXNlkn3?KgT~EfB z>f2)H*xbTrOBqX=7NFQAGrR)DquZq_Jt}w;lSjptA(N8|xDu0YyDwb|#4RidK|@j< zvIWezWk18!!<*6s!WM)q@G1hAB5V;)q5q#rD@wxbDhQeoGbNTtR3Pm^5&3_SuK|_` zaT6jYgyW3MaU~wi@735Gwk8DZbM*22?tzE!xV)&EAh^vu^}w04rU9_1t8cx3I&Mt| zhg~C;zkqf~9s2uemxF^tU&a%Hkg%N|b#B-MG_-;{1C(aS48nc0DLH=<6+WoQQpxZu zOdgU(QH}~}0<_%S4nw|qF#LTr?BfQ-4N456ak!@io@%h;^O<19(SAP;KB|H@n!t>c z|JM=lVi+!}gq!POo(Z#xAsmO&0;sBoHy6XB_3%~%>-lyl%Z10A?K*KXlQCt2k3$kB zX>f=a+EiRaJaFw0_{Y6uK6MBbh2SO^9RO z-tFzNvxuWVhKF0=gGLyWK_F&QZzyobrxd110*1ju&z{I3B^H0XWC0hxb~78}CPmHd ze9>;f%2zq(fd+`D!5WiU87d=UF(zlItUY5O?Y}Iy_tPK7A@7>pJ<|lZu+zzPWpl$GZ&I+-wwd(JlS{FmV^~-~iz#Wh z>@;Q-TN~8{wllwnFo1{zT@m%pOw8bO@ z;}EnU3T8~&$}>Rz?w^T;G_%<5=#S(Zue&)UOB%W>NNhZ;50w!hjkJp$ZYC1UV z0CGE%gTod$UC13A98wbb|bZX z^`qe3zFj$!q5?=80u7p1pVFZtjIW zhq&6l(3KYqCU*jS`f&sQ{UC&a2K)ck%CZ=YLEXH5r9h6nlg$uO=MG5ytE9<{@^Y$@jT z#y9Of-66d{k{p%3)hVR39r7Y^yGTJ;(oQp%f`Z1+Xe>AsyYo#_z*I@p*RY?10+{v} zLU9WWi=ZW`krrL1#3jHKcKu6tQakM-BmxwHM-$)@h@gp?Od;=|ySW=nN3aN86ou6ENq6 zH+nR_p2q2f?%=RB64{;OvBjO+C)GZP9C`%Df$8Ajkeaj!(4_6^8KXc*1-AjgCfe(} z7?h*I6K}&kUoz?dKdLmLD4!Jz+A&tN!lX3B=#O_R1bJmSv`aAZpfb+d(-*)+6XC8+ zu(%nbfFG=Ygd4wv`);ybl@~t(udSzYsllr1809$%49kRLM!+#HI6ed3`V{6if*FMO zg0RkD(W4s?GhJ}*5W<>(KnxI2l8^uXQMN!Z{ClL`whv4h4(%qsndy+?cF>(%QapDn!u{jFo-+vHevL)eP%t2A%krgd`|M6O0st$3_ z(l#~(BaF&TqbVSn?AIu>JlwFno~UJV^%Rv=H!Wh|ct5j-NLI9I4E=E#o4yLc(t6}g zJ61W%p?66ohvuGON5|3^$DF<-lcZ|*wd;xQoN9?E65z2fL4;Hgeg%StJrUo|6irMK z2pRTdSOhG|rnvprCj@DV-Mh^zButyyL!-9QRe@Uv1n5H9+{C88pGjMQ5X9`9@$S1) z?ZQz=>{`>71PcO&beuaWNcFp~Gj*ihj8BmYnR(f~v3LW2`uk%hCucKk;GRqW z?@NwH$F1q$umfz*t?9h)_j?=%rh|h+${}wXXjgH!6iAcskqPGwh3BfkRLJrQ(9-Nw zu`CsG6pBV@u(pxW`=#3#F{ry2!(Agl3cD$Qs}sHmV1{7Xk3ME#He}}uXtI!Pahk#= zc|#1i;#Y9O2)=qW#>iqpoe2jXGMM=Mjp$ch2p8XFciR0y8ysE;q6qG3gy}_Wc&(0@ zDPfHP7cQng3LH@gYdXPl!!@hn>cJ3M1`FGu(*yNUC^VtYO}Ht}#DA~f16zOZBhLF0 z0D0RuczF>E@2g`WaMq3B1D^e=W%JB`9L@J0SjFRKRdCjmYdO5a{@AKDV!XUcV@`wQ z?qe({%wcM47c2==kgY*e04lu58;8TqMx*@egb;l)?wvu))Uf?{ z(49J-^h#LCxe|3S)9gEh5a3sAQPL%B7p5mUpPBd@O)S-fuwhU6UILnnaLmN3O0tBc z%amkirZeK4li=c;;Aj8nk#Sqt?oXlEjy^4!HZH{Oe$=Eq$*KURw1+AbVQaQ2CfsTQ z&{Z%k5Q);A7KnbnfBF*V-0&x!T-3tjAKXP}Z8f^CvuX7bG6$D&)r51mns;txD~)Sb zFzuXEdMVn}!*Odmd{@}63v=fd@Xe&ymv0U`Pl}y>I5;?b*OC960O3UE&}NR9%P@L4%ZEY91W2Pqb|;cHidXo4E|h$9OUDzPC>e^LS+Mbu^%3M2p$**cMXC` z)95<>D;CfEfQ{`Y)gL$VXoqQ+>pCHmCzl88vT83jLUn-Ix31xuc|oo`VF~i<{}Qkm9A#LKNX`aC%35-wPO7enqlgZ;9$GtVzq@aEb!3bQqYfa_*tapcf6 zOiS`cb%?vK$%4thW$EipSc<_(cUAKCS0U&GjC2@35Ejfs{(DLf56)pv&==g9sUF{+ z#PpbKnKv!Ayu|2k=wbpY!lfp}P6eSUwkR1iAP|RG(s>!Pr)U(6C1!$6z7b^ zCopW%L5@KLVX{S~zB$TuMi(3e=M0di! zz`jii9rI657-S!ZF4ZnSAi+SSq*L^}%J;6km3UenMkGuu6vpfJFzT=wldob7_CNp3iQt;heKexa*l(9$aZMpkX5il)4!a^|IO!@S8GF z3@Dh65P#bJ?cED>yVM?i6o9ukz0Q=Or^8dTVa7pFvYnK%pMT0NwIexub{+pZESKXp z1$p3SWt?{725#K{M$$bVl<(#9;$3%e=gcz+b_U5>-^mdZ-B3ROnu5rW59Z6eE2$Wf zMdq!`dTziDdxTVUXKqiplu~}}{(d8HZlf8>ghVL-e91AIh%MW5TM2XpzMu`eJ@x!Hjk0St=+@4Ok-R%2FeV9{5rVe0Xl*T0=@y*IFsw8teiLCHiF zqL#!br9F;*EMQ(fWB|GZq#y(6l9GsJrQDE(l(u&iI!ZgsmUZm8pat86%OE2_x=zW&$iI}P5*4*sn zcW_7v9M@)_!4WVW92`;xd1E>FO~_E7A`Ko3K&J*%RIoJ2vTLJ-f^mxd8H@k`AOJ~3 zK~#zd)&1fV_+Z3almgmZGi9brkW#rPTN;11id z%?ZGDBboig8VpUvCn8)rp%8%g%?QJC1#hkkqRo1Z34?O@WRuPnN9Sjv_KIj{l{hfR--bGR;4LyuqG|0iB58yNrN+}!x z)4{)^PaYdolZX0L*r`!s#mt6DBx36&^7q=AcWYxZk6(n zlOPnOZe=SWAt?2N%N2)_9@rEFb07tU8nj2*P%j8djgstiGCmD4xy+B%6u|A);lM%Q zYG!6@8nm|Z6QRPDSHY_1ncOrGhU9Z=yGh-KC>z6)itCE`+jX0Wn-(XnEMw5rP7pEM zvGl`{kf!f;H}zCwF)$(LxUWA@lFs7aw6U1GupZFxpZ^d!iBGDt%U%3qRg7D%TEntN z14V%{ugZcJi$L7qPe;ZeGJ=&&HE3(w8UEn&H2z{3`NbxSS13%lY%HBW`;7N0TRCw; z0rIyK5H~OG(Q!NM8Mbxa^^~aCZ=967h>XfD&f~YdEf5I-lQ0M`B$YjB2)lMtOZ-jb89Y)#6c39B@!!n7#QjI6>Lh*YkD9eMY zb{G(cV7uMC;^t{E|0Ou(OqlZzm{SjiLgv71_V>8C`RZ!gI>QW0(^+1#i3QInoODG6 ztf*wuZEGm~zy6o*ydD@n1iZX}{Yifk9DEQ+c&Dp{sS5|=C!hBo+5DUXFBr^$#X3*l zQN_Hv5JJL|Hj^18=}2iob`CGSSINX&N%@gw@Zbgt?pnhOCl!#13!YrW4Rh=4g+0|f zPA-Sde47}!I}LI6hC6ddh0FdfaCQypAXDaS&wmN-gi^FY!bkwsmN;V)ygwVg*Zq&! zyI&UU47w2L3bq4NLQN=&OV}Cy6yyV|dO5=XXYan_Q%t*+^F z?>)ai?npLZx~x%o-n_<=N9{QpA+)-f{M~X*ui!y4S5H8jg_Ix}Hp80F_D; zvqJ3LypC8nLcqyTw%>kKFFA}zQw25ZD#%V``|x+4>M!%!CC$w znd>&f=3Y4I0J!HyIQAr1_yW!^x3YCZAG2EO_{J$EtiRV`YhQ}_L5tRp)wAWQb<8@d zlI-IdzWKJ9R7EU4ck9+MS?fe_3h+P~9De_5I3ftV7w)+i4m^-$xg0-!===2M9oS>n z*yX?6K~JB@yDOnOV$)o%85(j4g%qdFi?R99K~8CQP(Nvh%eRky+^IM29QXB!iQ}zw zXHJL7;%}6}0}Ku>cHwTM0#vxLg*;^duQ2Mx!&si*!dMydw~X6r_jYmRLe@ZK7{Zo6 z?mM8t$@y)5rQxEjb5BtX0Rsuwu*>lXYlEc<=U>*<0qcuh;y&RSa1>x%v;~f{`}lx~ z#KREL6n>@@6-v=$754Vm)fKfi0l|0~O-omRamlp3KuI`+j?_`V>~QiCKU9-bCXur?T_eP3&BoVYp`}UqAEMVlP4LVPc=HDZ~UPU7K&21eijIi6OoaP8o*# zwnJ|Y&iN69HGFvieC=7t7|3~i`l>~AU9gdZnj`RoW$>q4#^&os4IEny!xsEw3$$yn z0#H8_u37I7novRbP(6Am0gpQ@IwS@r3?FV}zyEv&&bta`gkWVgY)e4zFf_%02t4{c zl)CWGzky?8Z*8M4 zD#YnGZhy_?Oa@)fE^fVV9xH;IsbAFxRC09Q0U$Y$CX){W@E^c6z`dJu9MceD=`xEC z3}?8$-Eh^Xnoyrw!&m=av}K5WWM6dGz25H3soqKXR+v|MEvEcedi`@S4GtOwRmz`2 zJ~Ivx%MU1RwR@mXP(du{2bjh{!1B8_!vGhL^Xm34rWH}8@Qk6y^{BwlWLdr#KL2_6 z;St3yai4IF!Bu|HoL7eY$ZbBsIxsCDs8yjw)DQ+@+7C1R4op!@r8DQTea&j}*))~{ zT~GxawO(D(i^uw~!+j%qVvG;&pgq-I_f>^**dd zh)GC-&DTu=Od&+kncpr3y#q2CSQ3VZJWz$R&#v193xm*SK_CNv$x%Ne1aXaujZt_B zu(%R>EI48=tZ9cOnumXp=ir)WAY1}l`e0EM28O}1;j>x9(3McMR0B^9K#R+a+6?qTs?BA^ zf(pnCLqy@`4aZi8F<)ItM`u4xS8p7<^%p^VOB?y&yP0=&6|Cw2DzVBmk>L_fzWX4E z!O184&A9+udpw?YGJJZo;@$hjxcc!;T>UB83O?P8Wmn`&yEETNa5-H=&S5n`x$z%- zs?k3U#5E@C`5l;p9;VC#G^)~|A~wv3L(KM{mM&gsl?nK!C;rjwF}Q zQMddkj#(i=*JQT$ZcVvOg?Qa$JNnDW(bhtU;&T-oUk`2^LN**3htJl+zf{2SRX_#U z2J8l&zo!kpwh;CCO=DWZ!?z8A8j(*OO$rIm*y8>+%}Ycf{sy z{?4-}ruYIb$SHK@rgvl1VJ;(~Pj`4s(JAe9!^hj-Si~ARkFOTx>>WvA*ORpV!>d!7 zNrKwc#yDx6vI?Z0X6^EP&c4RDKP|V{pSZEIz`qoa9sXSlPH`q*Tr^SU za1jto{j+M(w_3derh>3cKl)`T;7qQ`n0;-EAy2I-5ZiTmQ5i2Ki)l}&8S^6@s|}^9;_*5F)354%Ac4ZJkL`?lZNOVGgZqPg8Wd7*6{h zqCZK>w~M%v)rg}3n2&Y%GE%Ojw@Ry1`Xh*w5R`{2F1( z`~#<}o^qL4WjUVxo5YPBad`gIw)DiS@y3qOwA!^q&hfm4n_=ukITke|WeumU+YcFD zz=`yVnbxZ|4`^Hun*EOz>37`$Zj$aKSbJu+IR?I8u@E0nV89(YAQBqElo#&_g)JK0 z{mAwWd`P}~(;;5J2qX+hIMZN?L(wx85gU=|K$w)o;XQoHO+>lJ5P0NV>OR23c_OJe zF!@8aI~w;?W84*zcg^H^9D1bczWnEJoezkp$VISUc`(5c=dFLz39W7C%#b9U)>pJ? z_=4%9JQ*C7iSu&On^OXLufJtujCl$g8X_oE%q7@#r#~Vhe6N1l_5>nDm@4(l)-~UmfMqf=C_CRoRr>E;WceCAsAwR&yW0SM9;n zYAaRFBON#!R-0XqJ+nCodBP}Dj;_ZD!@-?rl|H#$E`QI*B|7zM*|ggMJ#rcbt;Hi^fI6_^?N_*UKGzJRwbzRauvwz*< zO>)f{S{m=qFHWto6Gwj_Jr$~HkUT{0-hYj-!>EZ;Is?4;*qOhPJV+r)K_XAW#ymip z_;(yM%dw)K23% z&YH2h#L7DqEGtvenKRcKF8dmhoM1 zUt|_KKG#schD%?Ed^qNp@TVmD;CV|aI}?_Tk-$ASX~wyX_)d3L&Tiv__SBeMmY6Qr z+fvak(_le{l>9IC$uS?_um94N!Bfd^j+Pr>z)yU%7_m?KGpLp5>447N&!ADo3|ER< z*f>P#%K>5(NBxQuVnoKo>ABDMehQn#mMKIJ^;{i!Iy;|b^{fsBS=h!5%1I@Wa#a`6 z=;siz;xzivOFSWyZ1YT>C_FJI_K0ccxZU+vh1I(f*Kd~*jEYNYJDJL~H_X>t~Rlk1-X z#Ivujw!ZT^zwVA&l;Fl`_m^aU*P*@{)2sbLdUK9RaC%qfs)S>yb{cN+xF*g)d+E4Q z8*&BD)%d~p^P5mb-@bsp7X~oaZcd6CM1phg>?r5)#6{IfSs%qz_&$D4g-C8-(#=3lf|ay9!5kbdf;d7B;tOfboUG^w^Ii*X zYpP)S=GNSiTAXu}yoUz!3=Rgmy&2#=DwWPZyZFyJgS9xH6Du2$Q;2I+COU z)>gckVy(bb`dLy-JmX_($x5_G*DrnSM(?Ohji1TvuL2!1`zFJ%`@GK`kp0kLVLy=jMn{zWo_(_DJv-l)l2un#e^KQx&RB3$1kXw@y3gmQ(!t#Q*;q5@u}o{evvf?QRhSKhTIgU+qiwv?JV2g3{+8w_jj1~WgC16x`3 zGfcx^D_WPTy8ci!B246|BNSf0qAD(?@5b3_v4wUb*G`yTP9??la2AnFv9h$-D#uVI zw3E|_rjc(>uPD)FS}}=Ya4X9>z30u*lbu!QE|clKoD{*#;iT`j1C$E*&@Q&B>QI`g zg!17ks6t2iB>mZ<58i+KGC_IXC+v7Vue&56+xHYi5fWLs_0-xCT6yme#h@AC6-CYw zmaU7RsZ?{{XkuRq_W9V-fHje~w{w}tY5lXZSt{c!q~T{-C4H~YW4%+Q*Jm9Z3uhCg z**y3Q0ZM&z!B?wBR<7z8+3BIff?-48yN*?C*?44lS7lbQ8Z>LHo4jxRAstuUk^82v zNh@|CWE_SM!q=m9<3!+;6!i)Cw6LlmRDnL)Gt&DzmT%H1UxtNlc?G59&VTyM^i*>% zIPXed?f8!TqMWlmhn2p3^GA?-G@1gVAzN=OC+uXS#j?AR)C51NO@gSD9P+wozU_g6 zj~E#T(tjL;K@6|lz(qJ2cCXYBr{%kMRv6Hddn!AUB$liJ+}B|-hcrP=3hBBQ{=x6| z7#wYnN`ds+45+12gx##?)J%>ayX6s!Uaf9+dYr}uYbJI}N)=K^y-`G4kS52@mi_#v z=AbLYPD2i&xII&()fd?tEb`LL^5G>+OR6m11JK(n% zY;=_~*cU8m)CiH+knf{k&12R>RP#74-{Wlp+W`xp7>c`T$I^_qjj$8;8%v$rWS4$k=n-rnwCUElfagtcSb3!0QD(O|(hfuj4V*mQTgmu>3 zZ3+$BbJufzPlJ;XW*`yM~lFTlfFp}&$@RxQ%0(r~zrCW@Ky82@6OgW_?#7pHxx zYjVtat>GB0Xf)XTuTr2!+nL>;{n*4d>*)RRNG?ID%{)jZa_-@2*o+*e1n|&+v!z8@ z>5R96(JzGuIyZp_f0X`nXsx~E^=t9$C(J_=bRr-*gl%$k6xlj`Y*+d8H$~x7ySeE* z;r$1-j@^UGv4D}!vE9+UZXAB;W0ZPBv&R(OESw=CKRYjqvvbLpoUPw^<|Jr(8o)9p84#0+cx z0G`i@5GIn>FY@J9BRk{3+$7{Dt*L-3VbDe?#rkml{Xtqb7r5YiESO7M%V=}IRIr4< z;4PZ2kRlg$E`~Tl(q1Ij2_%izuH2phx2jycJOMIw8d>|;iL}xItqj^b1iFr1roEX! z3u|^mMYVT~2f8Z*_wyd=&S2lx7(XSPO_YuYGTz^vJ0DNnKlvhbl|JvzxD_QB$KMPn zzQvZ2KvbYmEe|p9AFOz%okgoe&L8>4=v($$&~dhOa}ddjQ^U=uQI=0|p+iGr`|Y0S zrF72mX_%_Vw7czi)n}5AqH8F~p%KCu{8K2*@#L<=JS|7uLQP~JYLO&rkoMuLjHPqp zeP-VO6~qD3B#jhVkB3MvS@1sC#Ov_FVb;2~wMsU*V^@KAwx5oCeX(qSj&!Y?=9`U& zjN5Vs#r4UR2vmoxm{Tx>p$na^wAft>3sTD&Rf!1jHY}d zC)AVrqu*14eHB-ln5FcaAsoKQbKGimmySBpVM0!`4HpU06U>tSJjDcSnLlIHd%LoC zJpp1`zMWse$ihn1(6i4k74^dv?NNKXeoC)cXSDx3XgpZDB0!VZP(07LtJnZ8fkmk| zjV#owp5Xo}&5#ruB;U+$qHq6>B%b~I510A3g*J@F)MuHPSu+x&4s}LvO__}?IsXT` z#bfKZ+e1U^>eOpnULiE<3C#&#Mql*G-i^gB%et_Z$3rtMFkqlL$Xyg(XtnxJ*7 z*-V#F7Dtps**jdzS=r8r0m}0DOq3;G z{5G3q)#-Dz_G;#z?-F3{zT&ORas?g&8ZEJJT6pd+ZhluA*W=2>vGArrd?$`O*+zV* z`SDFd$%2;uZfT?uzcA?IA3Cm4Ml==LIi|rPES1|4gEb~y&^pSV&p}Amf8OaSiQ8eO zhZxU}7Zb9Y(*<)aBkp&OP~1z)R>+QP3i%}#vG#lb3m1K!+fs3mr7{@A{HxjVWTkfc198+cOZdaq9K{3ckmX-)}u9V_doYx{=e zF}1#IW))c`^__N#8iT^iNR6THdicLD3tnBa(6ox{F<~Qr@g#4X&c@_zBIM$&-|?zDGYg zYRoz$V6#dWUvp~Pu7*!0%*q6g;uyX z7<)<0(N*un;d}4x4;GM?NNH^ zTFd<7`$?RV5TRKRRi(? zeUWb0^6q|kDZO07xVCQNd$fk_uK4Ty=O*ivVF=C>s5uzT<^gSdN)A&657KOERINlJ zqwMxL;#xOQU$Hznz})I|B}Ee~l~_Sew!L98dGj4g^WML|!xCL0DU8?|~}51(z}-I)^}xBG0zO1@M?do33HKyG*It~M2GZWfJB(@Am3?t3-6+@)XE z(FPcjd0uAB@~10fA3>Uq-N^gPj`qQntKT73Vn5DY4N>CES0QD-0mEkB;L^|0$08L- zN_~l*>+k-!CRb)tQ>9NfJa&4YyLi3@F~Mqhvi31@nZ2V461a~eo>Y0Scd`Ac_pLP` zh5Y8I?Pb{Kv(BG<$c}{meBJd-Z(zrE?R!C;i0x~5`lxT%q}$91!M#h6^fPRG*||i8 zxrIuIe0@FH-vxI2Rf_{XR!1we1YvBSW2cozgTl_cCqgE2iAL z{WJui_EtJmHx<68qF|AGu0EvieC>R;`{_;vfbD*uaXG=PQ=^zFaTVC)3~81ttBuIP zvCxB1okm`zY6})32hgQ-4l$4#b|mCwyE4R2Pb2<_-)O|d!NFacRtQ{+X}F$l0STk% zC`+W&8F<_jhRs)c;l0WB#>Bt@ev4M(4AdnBe*03+M2&pb%TD*h{S+c5LQv-SPCkDakl*_Z!gS zwc!pyk4g{InU!1Fc(Pob_a-OiV8l)MH9x7;JCoYK(TjpS=<;6e=ThIjy%)vP2UwPh z^SVVdFv&@r}}E4XVF?uV`|NETi#rXhRpS zCGS1(%ZL_(uc)lY^!saM6UokrqCUR?Hs*T`N~ex5uNTkdzgqBc+pvcQh^*ECH}+RT zP!`SdQNE!U66MR=CEC^~dqI8#+=)mFRlgcU)*@Ip-zXcNV?O zFm7O%ZcpM)-9m&B7vcPT8B+CJ0aK(;Mw3TJ>|4SJZ|dV_YkCh(>U}6<`T68ZD-%86 z2qN4N{yL~c8j3Yqhz&b^Zmt!=GZ(sWR zUH(F;hT%n}P0UTn@!_wH@MgH5biHXkw4h(ZRh>y9KeActp67fzn}9GI%K*THliF+z;K zgEkzxZX9&iNcRR;9y?xKB+SrEI#co%$sH`HUTP||OEYg?9WFP0*5P3XZ7T=!N$i^79;ijln zkIpz6)x=>XO1?I65zWf0w{v#Nx3lJbL+L@tnC-i6EV-R7`gmE`(Q&v!47i)pTcB^n z-GCWZf!alA+Rt!f6~zRcu*Rn{UwsQ1;&PY`Xw;!|_Wh9&g~TuYbH-b!wk|iFV8ihC z?g;p5hsw=<_*PY~6_J#mzv3JC+Ye{% z@8#cdSv(=kH928q79h6xduwVLs2D6xPEAd>n}eBqDPB>qh2xrML(em$tfIOmk02Fd z;YF#)bb`B5@ew*IY@)SkM7)!mX+K{vrtz4XdaZ!i<0C4KXZme2(uo7eWTNcMi|=@( zOgUX9A-r5Fz~_W`X#{D*PG3Km^gumPlFtMCrano;S(3+ty2m@~>~}AJr|z=pJsz3A zJLRbep_?rcJ?Kip$nE9_mlPD#&uvA+kCA?)GMIB8j(2Q6_eb_|lv)(XRQ?nwF+7dq zjIg>Fc|5>`ffBC~)4Eer8$=tcJXd2-rb$-(>AAd|HrM=>FMObm%IDB z)=%=RZ>`+_UR|`^(3cb#A4>nTca-gOkNfk@mYTn0NW%`aDJ9z^Dyg~e5q4;XUpy@# z9VfUQ)WW^Dh&W!!SPzJNmxRUCUela-{J~0MA7zX_|VV!Pjuy{unhTfBcSF3kE^?Xo*khdDZ8v{r(6 zY=Upuu=TxPW*E9|QLvU@KWzdxay|nwH!$L-l#lM)h>^fnRxs1qN!z5yd=*?CYfyQ( zRqykdrZXVu{xmSNfmw1h@@@yW-_@Yu=Y2CNO&(Q9oWWrUDqU#^&`QL`ZTjsMA%}Gn z7OKRXZC-tZhi~+iLbhU_Qf|RDB!>kgx!!Y(#9_QINVq+?W>-`eCP%eJg;RKAW|)}j za1ZjBmhR(FBh(h;OWF4gsra7ddXC-ib$aH<^BGb0L3FVAW6|;5^>Tw*hAv*YZ70ij zdL9pnrvQ3I2?GA2^}JKd(Wi#rOu>#4!|L=(t!^AdKhHmB@+Yz{ z`fv%&jpe!A^O{H=mwCbkH|^2kl=whPX)=-un(l|k*Ksy;bD|?v8*cYDB>57qF4Y+? z!l4YWMYw!iXjYa_i>uLa`{}~ED3;|axP67@sIVCvcbjb_wEbJg+DH68kXV}#dre5j zRfJz!yjF)u5}}7( z)i`aE$Aa)`Fp1Wcw1f~QANTD57 zh0tuY%{sAOehkN*9D-d_Ke>gz+pYb}MM^&>H*PED?hA1sLeF4BC(%M@DJ|ecpi;0^ zlVQPGwu8Ql{*s2xdOFjWT2MS**Rbq1pXO1}O1b~ll42dP_VN)ZwEMY{Q?1s7{C>;` zCCD=5uz33cTMOQ&gW7Siu%p|rTfUpB z?S#s@^E;Qvin(EY8RZvSrRb)K6-qt1f3VTx<5hAAjn|yM;F`!_$4B7r-s*psEVp?B z|06WV4wY%@BSn9Jf_Y4ggS_lGeW_U|_n|9RYFgLc3cI(RIj8Q5H}7X52-+%ERsGUyv;-MJwJW$cL1Rz0YF(}gmqvCXEt9L{AH~V0 zB9A$TVtS|ezEBdWk~p&E&UDo9`T{wM z92J>1D}+oM#x#c{=gw72u8d1Owi)ViyyLL*bF<>>!i|Cf84Yo@Ce+*CbTaW3Y#AS4}b}2~3W3iiEZ+Y9IOD7_% z7{l2}4$V898Qw2i+*Ag4}?5~PzMi|#OgFY5kVlz0xQ{kpYd9gP6^&&F8 z2sk8S*Gt_Z?<);kaN1=7C)giS(J{+vjOX{CNTQcQg5wjwBP1q6c00}IYGqVIu0q8v z+!%m>v~EbeX7=eT-nNoe65^_atDn?$f5jsx(B-~-*-9wWs)O&SYJBO?5sNFMY`9&J zc9KC|{>~Jx0*gK2Y1OYY%wq*2EQ$4%CITA=9{djJz~^K$T};Hb`Uf-YI8VW?A8Yw> zr}dJFR8iK41``RaJ9kMqg4Jy&2^k)Xs3UHDfm}u{b#!orcYmoMMPvAbSXDT@|H$ip zHx)(rDuo|&c|v7dBDTaVE2q9orHO9}A{=A}78R*+JiLMlMf9-B1fE ze&EZ$MCH6{C6=<_A~j@lG!zq~#C#mgq{>K_HM|Q8aOa?$;2LGcwOA`z%j34zL<&v$ ztV;*f=nj61!+EI5>K^V%*nskiErEg^UVsvpA$W(&Xpk*L3Vd6GNjVGunF9uIMr$Wa z_GmQ@HxQAc2G_j0k7BBUHU-Il1(I7ERK0d0w2`9wc}?f!6g4%lcwRB~~xHeu#4cmWO$KOP}VI1CK=Dux}O-p~X-)TGP9p`n0C+dx3~?XL{JACG_Q z5OnCmp|&j4j=iFMVg20$+6o~!3>VtjPm2=TR8G~`75isBH7{TG8#63 zD?VDd?Z2;{{gytN%Oh|Qh*ME^@>J)j+ciy9wFKCn`E;X&TI8$AW-v;{osMO>9y~8s zJ#nRaMrIxCO_Y2-)FS26WC;?aqSoD0OWk^Pwv>_d2HB9E4u>2FQ za5pzsH&9g--Cn2-t*x|EV-zc%3@TuaTFKAqDj?~wnp|Zd zaah_97wfGr(D?$wT%s8r!UOG~36G>vD7Q^_fs{#H=MvBLsF&qB@v&%WxWSW%)J@+Q zaSPBmFrhchhY5R|wKSTKp-$qkd4T(Sx>ncC;q=AMcE5Ei39XVcp%qH7%LV`*`=`mA zg!Z}7e2elNV|f~ABK*W+Z~JrwDu43c1>eJoZm;W#S>?0AqJxiE+|y)$@IZvaCsQj^ z1mlgy5lWxf-*3v*=u1jSjgB&TP&g4&;V=Y8V%;0tLQ02jd3Wtun?HvH^dofh z62_GO%=6{>-;VR^lEhl`^vK)8Pb6(BIYy-I9#(JgSO|bae_tODFk2g?r{_4y=Xhnz zxO|yHNiiRj_XN;MI5T@3-8IGg)G|JgXo zm+puKrhS4d5-)Zcrjpm3=C>cwHf4ZU8W#s*pZB+(3ECB&(WoRLQIR#B|5;0xCh1lL zrSarHR44@>`GO!wdzhsI@(})I!I|!uPley4pG{asS@IdK=YJ4O}bC~W#+>W`@6r0}U16i7t8zt}P7eDmLIg8!S1kcRUU{Brl3G(^gY zTZliC1m~D}8mbR`XA-Ri$98pD*7$}Y@3S>ON+4W>h{o1q|Kr#^>CZ;rE7?F`eL#DS zL!w#gF-JoWZGF+C(jsIZzHbh}Q8je(`Z{s^2FHFuRs5gP z$NX!90pOUwomDV!q4U3!rGm0^%%NjY#CH%4`MsAO2MLg?yJ0}2?I=p5#xQ>kp2{0V zKJzM94ZA#DPXV@RpVwt^&@9iFNkeF(F77niit{$ve#{=gY=R=8#|LYW62i4|pzzC1 zHvKV8ZEkEl02XZ1`=xt`4oDq`@_cCjS@`m2;d5W7fxG%VDU`E+eck|B!%XR^P2rGT zI=h%4-7-j69k=$Vbt^704gbJL<^H4aym19|0`i#;=sU(NIR01+TU|V1I*l06`P4{g z<~uW&8MNgCIn{)hUJ*ZM5|6@Np=71vqbpe05 zCM{~O6CW`-1g-}07wO+PTy!LToJ$0VOc_zm8hfA7KUIh0B29$+$9iA6=2l*i{?{&E z+y>XT__V7&#^&QiF9IBGhl_w|E5V;zHiez(dV5P!yGgYUd4LuS>`0R*^z4ZM3{V-C zNA*OOX{O5oErOfhUR;FUx&-p96Xe(Yv?{4T9|1G-QYtEeD~gDX@~A3v`8oq9DeWn3Jf)7B-;j@cJet* zKTp(>>#Mualg4mFK%ma$Nph{OntxE2jEfBGmc{E|EfApiR;98N_q~tR_}?<{$pFm% zZ?1fF@S8=YfFwRBc1ECBJjc=&uU?~2d2u8I`euQ6WP-g2MLkiq>$8UdD`#f^4=H)3 z60US*GKT%;|j5FRdXka|FK4pv1CB>4;pxuiqCJzxZIwK zm9(5)cPzalGYt40PsbA=k}hJA3+raged(`we*AM~^KbxE-~R&@K2CrXlfi)&o{zQj zd2@4Fc8kCCn`>lXS!_K&)p*PaBG*Nf^)QD!UKq`Vt-q8X$K7JDEq7 z!l_urV7~DU^DQW5% zxpt<^4xzVY|16@2<&V-V5YWCoy2NCuRF{=f4?`OI_2c`( z`z3P-?mGLwc&?x(^HWecH}pS$+>C<@HN}2wVP;XFp|7rQswW-)`cHU8$zrV0muEP_ z=O~1=&UF-k%=!$@OWo5IFJJOhWQYnFG;g5Eq*gFNu2rc13Z2!Ss73pkvnVu&JV%<~ zufToBjFmnQ_B3cZVuUu`&)8*A)*hSLY8s^ge4T);7|Kx4|e7Xx* zhdcUnRVZigEM$>=bPd{67+_%CvHe@a>$Soy+CZ2#P7K2J~4$DO(p_gwR{ia)eorNY@;15`SOSOt9h zA@TSBWLHqOJ2?S`$(YrkYn5tv@afi-zF=M)_!obT2UC|M9(93ZgFF8hnKJDlv9e&= zrWG67V$=H9{O{-Vvb_&FP%9gJn$+7;w67de` zeLlHY>OM`m#Oc39otsPG5ru<4;Ob=1AG}@$3&>E| zfd;DUcm_G%zbK+TALOj5zC?&Z?S32mF^*8QJ~HkH1tB~9MuT39Mz_IRN>^*fL(_i0 zzG$~~G-!3p*oWPUqvozh|p+-=_e5QI{fl|R>G!Q7M6~bmk zM^8atlX@H-CHC;(hl2*fjZ^xu6mayBS-BH#cwkbl6A=V@yJYSV(6431Jmv&^-#uea zE;Hf2GJ^xXHebMht2|jH)W(PUPvY*;FUIY+2|EIo8$U`=Sz&Or3UW%cX4|Qo^|yS6_&YXq$KGj*YYl4L zIDF1+b#6yM0R2GccAEEE23Zr+OYoF5h5koVr>1%1aIaEKWyVtFQ8OW0tnal1Xu_xK z^shvlz?uHgf^P3OVtUSW8hpR~`OHLY&=AkS*`I2> zNlIQi!YJCmgr%{{KH`j~@F393!@WMqLH+6BEk8e1f#ABudv-6Q8Ts6s$8Q73pjYFr zqYAT8^IqSSJ?L#xIB6Pw;&D4=D%;`zv!|=6^+kI6vzmRPn$!~QO2eTJv4=R+N?ABs zA*`+md6oe*Q)Dz%yV2zkz{GIJJAjk;={2c+lHUf8pH704^YoX*uIS)8nY5hNWlt7+ z2^rk^4iHO|-v?>AX3RsM?EnUo^_(n6mTR92R4mz00ou{KUwX;vx)D_(*Pv3 zI0IdopN=yv=;<|e%HHbaaOhm@X99K=L1(NQc}E`g?QeyMsbY%FD}Y_)paV$>4vI10 z-X`l`KNsaUBTK$~a2)M{2Qgk^ZzA%8=9$IKXD$#`9*F?W!<2P$>MwTQY(~HPAS)0o z`$&i9=XvmySIrU7tUVpOBdiVrzn8NpPT1Or{)(iMn+(jUspX)bje_AQ=(On?-=)pQ zz&c`J=k#Ypc*1n_^g4Bf$r-UQGEJSGG0$(H@%SWUS_3{^n|r|WK}pG9Zl&@33Zlg5 zv+npGi^S@W$1KkUH(g?3NHuzaJ_i$JF|bcjj!`f&UP^Y56z@7W7aV;lfj1q>vr5fR zD**row|lp)0_d=&G z>F3ky2P(W9GJUp39f9DjJ0JS9VEIkQ&tKlTu+sz^%e6Do3j)-Y7j@u4=>3EYTyXvl zoWP%eur+`9wp$F9ALFP4SJ3+>)szZ^z|qm`&Dcb2pWVI)pJQ-ZsG9sGy2x&n{ZG-;{~jW3rc;NFhrhy!fg)V zH4}(0Ede(`v)}ym?-FoOCXC82@WnyA<*j+~wud1;51eucIP)XvMNSkD;z3f$7zr8N z-h?dg?W41R>u#+hd>%zdQ!Vn=Bwu?EI^PIsL0M6u%ux^ESLT54fTTPthI+`rtiSV<6#dfvzQo3Kg;Sr~PCxcx?mt9|$CaUdJcq^Dk(=ptU3h zM=5k>$6umQKjQ!(@vELd_!quMZAMBgE>E%``O%bSOGEU(pD|1{AlzibX)R8;-uW83 z81&3`B3e^=!}t`@GW9uWDwV!7Bgu7U%j{pdN{<0X0|IUH`gH!CUpDATEfM}*Z$VaL z;CEOV3nt5>;#G=*$|ET!|D~9eLL7m*H``zYNIXyBYHJ5G^GKLuNBh$|o4M?x4croz z9?x3SsF`45LBPT}nlcPQ(7y+vP=6tV)^RUhS(TD0QTeMuX16iyuJU$?= zdAa>3Ke_L*sPQUQJU(mAAQl^aH8#vo5xY97_b-X3#gLIUVmhD}ebJJ<{vcH`< zPDy>i0Oz4Z*A@ewhXnLvjgdVQc>UhMz`(D?A=8lsPOHa{Cg}L9HiGruVUn<13|$Ji zsU*oet-tnhiiLR_4j1w2ImUvejGun)1dN@Q(P3Wxa*umMy%Ocl)~jTs+<$Z<)+u$dH%w`pg+Gn2jW;`&6fH-D%k3pzG#X+{hJE$o znQ%1j=6#d0#lmp^pRG-=0f}?ZkHZN{+%GLl1t8HisbpN4^>LARgwI1!0&Z(u_I&Ms zsF;zr4-d6)D8Z(F3R;%pa_dX{rax~f35so4!ksDAQn-{90w#cxLkzB1 z+79AbU7l`_gRDwl{94PY6z=gW$^#sVK|@4`%w;;~G^762aiyxH3{Xpgz}OayTy?6# z3z~XI#vL?&wl>;VGKA@^#r3?I#jTqol)vMppp8&xdRK`dSbs3lSnzdzR`Gb3oHG3O z{o$R5axY;t4Np+vvu6gwrii(tGZJ_X&Ha!@0^2{{pHLzIqx0pD;Iv+TkFpc<|2?X| z)1RF;^~y3KKG`Cbl1D2Ril~f}$zSsq!Fu713309sFag9zO28#Q5d~#NR!(-qJ1_Dv z!oPJbWaYNLlvjqgF623|+Cv`UOC%SYeI8v-XS&b-(zKM6<3JHJ(}+(_d3_5+R#*E2 z-df~M42Rgx^PoBRu2cKJnpRkFlM*JIdKT#p1LKzuet%oFbbpW187_QyNRNECa=JkB z(}NZrmx~}>K}qR_>As}Q^|~LB(13Cg4NC9!!Wt$-)WT(Ct-QIY47}YrtO0}T9@P_7u%?*Wv$^UIyTRA88h!vmPFRJ9Egw1+ z$>QkjO}kGU_wJum+J%?fq(LF)b)4^`p<2BTz@u_#^(|a*yj`4>Xlpm<00Ee$K_{Vt zpm{`Y>tRf8g&D85?f!ymRMg%Zt4`0qdjqO4(XUv-)=sa9FyMF#d*Ar-mvo=iACe~{~b3BM;oV?A5Uv7_9lenbGhUxdesdQMnU#0&7&QD}g!%eeF_axx4V zxr3%R7zm&Q3dL7mC?j(1sDu$aT);?LzaYQ?M|sYAVjruTI>>{aJK7h?TC#ZYc!L*u zwo_X^J|%Ws?7o7Y*al~Ih7`FzmnI-uJ0m5SmIzL%5-!yjR%|@3Vb{LziQihq zb-0wVLOhBQMOIZil~+wei2fU{UyV=-3mk_1DW50GZuTZUHV5$Tb<8?^5wmXStW1OW6E4-K3!=S%gSRUU19||^M=hDoB@-thHQRdm{0i6&kQ#oGQAM&zGnnts zT!~K;3f9rti>Mo-qCsH@ctG0(dK;qzD23O&UVc~|?=!O|1XEj1d3k}}I*5QWK=1@= zrgcDAicx4Czb^B(Q%>SP%j^&)iL`jWL!VJAanYyO5z_E8f@UVpfGizqzuxDX|AS!Q0{Q8au+l(OA2k><*?i;AB6-myHeE0p;Mk zUPAqNxr@7NAZPGgtkKrggXiC9t+H`Dj#Bg5R6MT|{k#eoo{jit$F=UX7$*WhqB0&8 zo|c>%OzbkVOupD}fj3aa6CMy0}VMX*|1{7N1LlgZ?>x z^2`u(w)A3WU4WU_iMc%tUK`Ol_{tR`p8I8yd!gIoN~{ers_ zd`96RE1S~GQPGrvwC2F#&8@&}vAF=_!2qPpX07J|0v;3FF7YlH`FG4m@wy>)wz(js z_oglGD;fnn{{xL>_B@9u1bq`kdZRGd#Ksbme^)3zuqS?VJIVs z>@r=1@M4OnJ&K~o7lAcRy_i`y0E3^US4MgsIHKxmTr5(6bliiL7=Ax4jxgD(Ll_k( ztq3mZLHal;nmfL(jR(QuuA~ zBVAv$)6T4X{C%^l#lNas6U&0jcb;_XuX=&CIH&p)a0p(9X||&v7#?j2b?J|3qIYMc zJ)Sj2r`?0%W<{{(;(N$Vt}1FWS>}OXC2?@Nq!AesV!^1ZBcfEFF5d)sA{ozZeLi4S z4-?}FuoE3(XYm+je}Dhlux)mufL59qZa*V-?RdfE`1Jw1>Xc4px37tMIiyArkO2E* z!qMJHL!&X*8)v$uRjsHF&d#C`_D}i@2GE3`!s$>$a)tt3$jHGwB{$FlwVuOIG@XYs zj^6GIo_h9wA;%u>LWjHIKDuC!l;ObQ_dR433>-Y1jzZz)70`2&foKy2$VX|U_sK74 zh#oll29fxqfM+yZ*mYf}gj8K(KIRC{x>gX5~}K6Ox1A*63*skhR_f>b@K%F zYEAjmqbf34NNU}E{k}c^1;z*MhfJwuUM|VBiezX+QXfS|}HqoWv(%+9E z1Mpf2R%lVLvr_1Z(*i(YkxY^udqm#YV!1y8oAV2j9?2iIYyJ&%rT`I|EEffJw$#H~ zS0p-|m}Tk}e-Kki=tJF}g<13}e~8o4aQg97TGb?GpVj7a7<*5uDi7@0F(}8IsvZ+Q zXtWP~BLQW*EP@?g^>@5Ab#lTAl@KR(<>axwO68s`Lo!g+`@4Wc0rjxUl4ilU>5s6N!ukMDuw9y;iM4u#XDuwis<))8AgY{ ziD-CRt=qiWe7m##SPEH?Oz@}DnZ!O3MZAU?&ai>^$u2gy$SUkbXZ;|OKy2OVEm4>D z=CrxL2_5?3X?k7jcW4@JcCIG{8bjHGb&Nm9Ks)rOXPDk-=@tRna28#a`;r4!g?4+$ zR<`tPMVAD+1S(5yE@0?ryTeO6z2tmBl>&jg#f$HyHSzQHb?@YxBkeJ--pmX*)<~<) zd{UWGW46Q|18Yj!T~mu6AF-0sNzgKD5cwvI^2SfLOA3=8A}(8Xe+}~3*N#flng}}o zYVa-My2i9N+x`7{pb)8CyUszjP1!{pXX9R{GukfWr1asDdm9Ajl`V_WSWZe;KizB@$U(h-(nIBA6_R@*M#D5?R8@)6A!;hd0 zKZU(?_(^K}g_2TBh8j7Bg92nz4ih_j_9T^7C5gf6xn!=#PsI^Y1@J6E)aOMC0vAuv zZ;I*&Ih!bERS@^o`-LfIs)G2=5uiZkcJbVd3_p6eIBI6muZYitD)4$?Cs7Jva{nLn z$3inYr2uI&UC$T!OY#3)in|vYkWAcAn28Q*ac5fjs%q#sbU<>^fPH(KkFa2qvkQwN zC}Gc%m+totEG82{78bY5gkKqs-*_P@9Z&Fh|6(ZT@#})fpHXqd1^c^0J$acM#W&!SDa8CQv`1z(ZT_Lw zIh)8Aw^?F0#mfY2XG0beBl%AhzZnKqC$QqkX{=WqYOzZrutmgE-x+%fI4V2Cn)2@v zSK^4lMP`wH(rM!u8LIRp_v!I(U=kx*Pb2wX84uUb08zx&K?Wh9;SJ-M zS}gis3Q+QF3^|@y(&(O(k?J{`Z%*N6n8U-)FaPV2rk1QHa+%f`d)$SG^mTDT8w|(3 z(sHRJsd}-jZyt&#_!lQtFOlmMuZ{1yF2N6rCL8sapN~ah#Wz zn$O=c)nHGcCjyi=eUh$MYr=jdKc48yk`@n>z&l|2X6iR;;$|faVj9|lQIMQf5x=%D zGj5l1i(TQwFKO%b@DS=7=ZOEF^&N4-G+Cy74?1&|UhdO#OObK%dKGKRk>JJNZn`7A z!Wv|)-<=Y=PH12?NQqX<5clM{>VfaVOP<-@JK$pwGNiCX+fxia$Es*{|3Kfa0c#!S za5s@#^ZfKG1(=Grkt^2OD;|Vf9+`AC2Ep~AyWXMxPo=b^9^GT(xFC>UU4a`P@6@O<9g6Y8-lBKe+X**h#KLsyAn#5Wv3TkFw!GGcu!nLkJYruL zb&i6whH0E|v4$XK$O)ukXxSajrMk%Appqxs-#_Lv^wpx!Y4gq3of}q?2&PkUeH9La zQH@t+>Qq?1AEnbTrVs;aBy~<+?^!KFFhz6UrLoC&< z9$)LbzulkZ*A`be5=N4JJu;yF&?mOCVKPri4zcwiE^uzMQ)MiIkiki(f@$fvxQI&Y&u>>GG>K-RX z5>T_UNKVQ$(pW{EGoeusj-HQ6R#02pnm0Ip0+cL1=izxr=Y#uCyXHRk7CW-u#9+Cr zE=1S}K%B^{)!k&~ueZu)n}|QWZkW#B{*AjCfI`_CwTO@=bzl4AnrW5y>;t#UI_DCI zw${!@h4K{`SS@a;Q zra1C%?u6kX@B0xCRwFlJntN&+f8}fHo!FO>`($P<`}dYs@wX+yS}t5xw%&idZ*ILJ z=TTY89go%R>tP#8s`5^lQ=oG6mX82-u^}PkKlG|YW=U-*bYSwg*TBiJ{e+)ef7XU$ zo6uRbOYD-xr5l?D^83~w=jMSBd18bFjft~X(`pEI2yoEN- z8e%HJ_L}!IFO7+i@n|OdFoH1P)2T($(!jE)mRa!x!the;z{2L%oX=d1G$CkO;-9&o zzQ9c=8Uh~>RDkT^7XJE>a}Helj0h>N--%LRCI^!S30glsKhCeY5%BPi1&X2R^rI8+ z*-V3LIxRm7Tg_e@5Et6(jQ?x#F6ejBosFRFGp=x%edIhec>%P{=v&}r=;n!*8W4L?LL4zlk#D(F+gJO@c@iqukbNSLMC;;Nrx zus0gKv;jc-HSofa@{K2f#7O?$bYkTMM*en(lq#Zn;&I&dfcAW)2H zd!AI}%TE~*Ixw@y`QM|EG@sRQCTz1NW3{l8HGpqs9MR4i&A;RJb~x~?A|J6q^8bgT zl=-4Jb=m&5gXvHpn5O2!YmI;o$1{_K`{~{hMg4=REdf90UR!pwuP^J-q9wI&L1`27 z@7^Jf{vaf0-SgDPIrC0ffd;8uE4yTHWW}B7pJ??w?|cm-|#&leE@UHs_c>nMhh=8o(ts|56)5#$PvE-mv{BGMz&34ohaBFR+xv_W7M{;Kj&s z5X1%hT;tDqEw{D3?;JpkmYBESdp`+=$!zY*hT6LMt1SO~+@3#CKS?>)0U-30Ozn&i zq`77NTQ%Hso9I&`S@s~svc~K2o3ll|(UNiTK^!ZOWcEK8jH1B`sUU06jJnh@u?Z;9ecw#VwLx&0W+w*gBU($lT1E3_OvdC9ba*Kl-Q7K{;T%kAox zRIN_556S7r>cbu6k=`(@{=McerzhWJXW|EnQOm%22~j+kO@5~0%&P86su>TjoV098 z)8T;$@{9-pA*A2e_2-wgaLs7KGz~Rb+8rWIhtBeadbn=&G0|tTRo#C0)FZHmey%W= zZtUD!inn|e6fXo&sw9rU#V?FC<>HcTKW}`_4p{DMEmxRjb9G;JTCJS!uG zAcF9Qxg`jyS{gO*hC$!}&QeoLbW)o|R6VS<@P(dY8@;YtHP;SluTKa9KJg?Yv7qjO zjouYF!4iYL3BC@0c$8ybf=Lf zo~&C=e|@HPpQU2lK!b)CzkO?^0a8FTrokGDE~SD?1j&y(=jloSS*9)xEyMxY4V6$Z zA-CiLkR_?`O(DCFQ%>O(8E9wbF@%Z6*bDyT=Z119RcBuGGydJZK6NRsJ?v6tT^$@G zkZ>|h@RLnwVK}08`uRDXR|O~BsA_Sf;1Pqv-2T+vO2OM+25=Rpa73!41j_ZUIF22Q z=-*NOK)V|rv}vPsc+l5(DeF)9bVA~DpMvR1%une?R~}*H|E+(&&e7X9tfh_gbOGxs zO$_@klKw~>P*fGRma2FESb@F8-KgxQ`}|K*HhM{61Q=iY}N)+eKCtO-!`j?OF zOblg1RhcXKQqpsR)76P#QiYgvBMF@p!Uc&9ddZ5t5xqP*fn@aP{aU1_ zpwPEye)N+hj(u;q3ukLOVoB|c273y2Ca;{efS=O zvukwW5qAH!5y~lFrSN~jPC6DWuN7G=LFx6(XyS4A#ZZaHSv6dMYLtSJh-mMlO>*70bc}93QCv5MlaJo;df1R&D)Ay9GXMc{o&v zk$nJ1aR6^cE~zhl3Fas=*Aa}Bd-Bg<-IzhyTf@P~0om*OZHfNZI|=rOUzf}eP~;Ia zv*sX|9zZu1BQ_X^uWTRU)WgulMMXOYtkASWOd~?FYBWXhi}|!-bSpj8mdNqioEOKL zkF88}OYl{c1i~~S>7I0z)YoaEyQYxJ+fzudq@lI&B)@Wyis}Hxv8t#t2T%(uW$W!53JqDhb6v`(`E8vH~PNj7<|&i8PoHUNmMwOMvgbSp7Rm|`CdRotIhI$3a{XAP zHp5zoz7}~Ow2SP)DB692q%CM|b-p%*D2DuX zakOJh0SepC{`8rOe!JN9LK?Z?|H*zIY>gqZJ zYaNubvX;H>QcLUVhJyQ86MlgC$HfItTOAHY$oZ7s>Xe2+v_e*<+BPewXt|0>VI4Oi z02zFo`V{iISH#A ze4E7<*gmXiJ2No54+Pwp@L70nZs90q)*K`NB2UmOmV*>C8z)#S)-zMjOmVb(y^4GOpH9IO{@$8UnE#+%QD`QyWYvq>O$FvaC7jOm~mwY3hv z8Bkk4SG7QylrAi?_};0F5-x!tQOaaEa7%Jic?-S!8_82qOA zPMuS5FHju}+L2lMpi|h)Iw7vbIc#gsP~MCK{;_(O8MDBQK98L0nl~4pD|eqU~L!2tL|qP(!w1ptP$SPAn!v}vPe*`L z%{}3iFy(-O%c9*4jg75In_Q`X&DQ+68v!EtJZ z0)y`^2Y0i7XLL;FPbO6ts0we^uAZ7yJ{+)z;22*LcE%N(A)h3QLp>q_6)B7+Gs}B$QNpF&R|(u$b%CxkW`q%HygQXhSfU^*nk-fE3SGMKn)#b|tKX|*`i0Y6M`a<5b^<$O za*>rUukor#(Vvk*rH4U~-;(c<^c~q5^hX@KJgxwj=o?4kwLmpu%uTUMmfRi~>zn06 zRnl@3hk0bCo~MJ)#g9J1ZiN+C_0&r&tFG@$xdXTb%6rj8N#{>Rj)dy>Y1*~LE@~^$ zvfgznA-!($*UHbY%~)CT9lnDUN(#)|_QR%A#Whl+*9+fe8Hff~8#lM`>lNL4ms7cq z2TF{z08{=K{U@~3FKuhZogU=bn7_SVRrgWLowwq%dryqMBV>8H6Yt?J?zg-kBQA+D z*$PnTRKQea!=Fi`>bH8H&W2uIeyk+CUp*R~mNN!*BLgpJRh4Ulr9)$`zV*Nj~tEMEuFTRugXa5K}=#2Kx@=w%ivDs<1`}M!u*}+V7N~_l;eG!%ih95oPBY#7sHP zxN{rr9}G^(%5JjldLBcQpte!O!d62?r$*7}Jj%+Vu!OV$fQPeb&k;}5>;4`t^ud8z z28PiwfsNnDo-E16Trc;QE%UilHlrU7u>7;sGr6+vLG~8mHT^!5h{K2%Pk!mXZ;cjK z9+2Eo$U(%ZnSCD2^HIm}l!*W&eK6T_=2`+s$qErRA5Yh{Hjt6GGBOBtHG@o*=SAKL z-vbLbZVWADI4&H}Izs9?LDp)X7|FYS-_*jJL5%rvk|~SEg6?bj;9}X6ec=`bpF0IW zezh-Elq&B0D|TE5-xsKN(%L1NR3}0T;9(4nH=lHou9+B_tItvxK!lAPsD`hvOg7D- z?=p1br~Sfdl^)aDNffrt>pqxfg(;Y7>|{XO;J!%n`#ZX>e7SoHF7q33>Z1uC(assz z?RlK|aDBk)VtdNztQWIg<#LqH?tCf4rkAxzatblFJ_OydGZ>pqR%&-A^O5u=mU|b! zC6n}T`W44{#u{3I4{smEV1v*uO!Ll8MAI*MoYR&hH&-MH`GBGbs5HZ0Jx5-(vIOA! zVi(qs*|zz_+QrFtM($DI37-VQTClaj-!BODaHqKQ^v}+EFqyDUr+4|IC9>E=sV|$O zucY+UvyE(RTi(z%Hi9j9>Dg1;!O@6tMgL#708F714~AXoV?6cF>MF;-nPFwZ4KCBO zWnB{9n9@rYFBxBLn9Zuvt+{qL4|edUZlZ$KM4wT1r*7EMCd^u)x0qxS-tznA!`TO$HbHn@>e6C& zh1Jc3s3fAM^Cqr?upUo@IYxL`U&U2S;z)2lVjdsHfGXwO4UnjNN%DJDgoFlo?S5ed6doaQQ z<1yeHKH6Va$qwIkzctJHD5V)OF&{C%ecf?BrI(v=OHQWeUJ< zaPv=2#IKc&tL(*TaG~O=Owi}G&G49$@CD`g`N)tJR%-tGD9ztmmbIzuqC=8hz5V5CVtQSSqn9 z$#$UPg_h^@!ZljvqTd5{+E;eVW~|vkUV8whQeo}duV#ZSrDjJKO3=P6Hwul{{HXA~xcw>0bOrB!-*dL;IY9Sqd3n8D|LTzfO*K5^X<^G6F*57y3hs%Pmd5CH`S9}CghVijFx*clY!-T-|8D1M$jT7_3J?r+!Z4+rVzzQKNTz;z9E5S^9-Dt536E~68R;mvUZ7m@ z^MmVHzH$InQe34SK8BJ4mJy(Qa(J`#-N6JR$ATB0xVPF8t<;+7*<=-dBF=)n_(&Vy zd6g)%C=P-g6>*G%-jy{xJvZ@<8J#sy;IyeZ!p+Dsy8?u_KD104HIR|S{{0;h zP`7=Jkzwog>*aZ%D!)YQPb}!IG!OOYoWS&Fu~z!PT-EO~UG+`xWyk(VRrnW6cQF5A zIoJAX`D5ha@P}Vx@`6FV@Mg<_^KTK!_`m<4dw!Nx>qm54xSd>&xKK5#Catp*bBMUw z9%=}OY91O|dN1juq!V~N@FqyTg#o<#m-dd;H}~Oi#43^DAHG~4K6DzL@K^bq!O~7o zE2p41p+TRN0Xz3lX&V-k{8I1O?Hx_ffWP-=ijBY*n?nwNmVtki6u@76z43+o7|IP_ zjr824R@|xxe{(a9vL7Wk0-g3er#*DsV)R1VkJ_a#bwA~}43tkW@jdmtWA?FST{wUVhpVCIty9MD% zU7#aBf~s47v6WE2>e4mdr2d)!LhrhWg5Pk`Hv=hww z*f3KHfHW*uA+K1@&8yuQzSU=0~MRY8@I; zaYna6HKYN2JiDM3O(}Mynp}}1AKnZj;0D2Oex?-6yZVHu*UT}8Nm~I%RyUJPsM%Kw zIb%h@Sna$$sdCZ)6}Vb;zzmws(`OJmuA5`U0N-H4Z*C=?zKeGYRm~Nu1p@5(NzA!x zzRP9K>>KKnFHT^7Khtsp?vCU&ItIc8M7R)AG#3PXr>=WS{7vM)f1Rv3mlQdx0O*`a zKrBsSKCEaR(510_8ZWcgk?IP5E>;q-tK&Vmpc1W3_l~z44M*5-7yUMq*`3Ef+}fP& zVgJ}D#hI8WUp$gk?z1DOGCTa@M)!_((oEW;(p$4rKAV z%E{XjS){Z7q1+Nynn7c`aL%x0l;OuHEOW7S8FaL@JjuAG8HJyx!C-d%(6ZA`WIyL# ziPcvkh<-i=3=aRE~ac^Njvz4Wtp7z@d~+Z`DChfKtULHPEGb_BEw3 zk92&ldb{{wXdFSOM;%=2bRBiip)D;6UJCX)j#mIJo#f}sn^CE81oMNOoXc4$aHrB3 zSMvs3sQjF7p500-l*OJ}qbNDARnFAH4|^2oVd1Y7b!VnFbB~vo%8aydciMtx@jES# zjq@CD;9e?lv5e74lhtojxp4{i>_v4j918s@FEprRFn3h9{M%MpkBBOM%zb|f6vIZ8P|+XWRDALs~b5z!Y4L&IIO_&EW4`l^Nb5j-9|3-MrmaX#O^xSUg$p)+MCH zDBZ9L7A6`;sytc!&r~63hllI94%+4S4-sTi#p{&yf6&XmR_QOTSOGG57H=Fo5Zdb! zeyi#>K@qw9#Ld@9Kc;CHE*<=NiXn-@WzLnC|N0Uk_7{JMGFk$1E=W>wkf;8TXeQsq zaP-GF2-m|S^VJ<0)eG7>e^+@<78Tvz?6hm+BOZV{Wjqt&IlR>D3ho`9O##Q9dvOJ#i z&S6_})LjrN$6O`kKxIdzP$q7n`}}6HK2F9hQOZqr*l_OjLYkkT4_Ejh5XB#p_&c>0 zf2UI@?I)y6zx`H(Zhp`P=z(~BL*FTo(_*l2LAot9E|L(jpw39x( z-BC>I)k)T@mBNWGi4anIDoki0zjy_PBldts#F~2uGgiu#6iT{V2VKcnsYY3~lzgbJWx!eJ5x6EKCp)>KcC^o z>GmXr@saM8TvHO-PplC{Sc<1uoHfYR;pV#VII=LS?|t)-dsxeoZ(7dTBihzakHNi* zA;}Gm(3Y!r zv8%3qP*4Sx(Gl5tV6Jp3l$R%XlmafLsq+y%RiMk=ci7l21+|7Ov&g-?es8I`(BlAIpb#@HSJ$XG3x%dwFS1zveCf3HqhAt2P2f}*aGynhq literal 0 HcmV?d00001 diff --git a/3dworld/src/assets/down-arrow.png b/3dworld/src/assets/down-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fba6cb1619fe99f32bbe8b9b19517995525ccd57 GIT binary patch literal 838 zcmV-M1G)T(P)~nx z_`-!fvpe52yJu#1E&zfc2!bF8g8Vr!4~pZ zH6vX72y31&`8|)z(p2{wSt#nWFylehyO zk#c`ss{4&B6mFTnkuVXXTuy|Mj&;k$2CxOf<%MKx0O8_1*aG3AecG5?)27_x=i;lT z%}hW$*q8w4&)rtHLdnDcdo<~RRgSdjyb#>mTlC>Mp0kwp9@l*zup%-%D~nHWrL{{4_5`y0$>{;9s3 zAfwrFl29h@%p{>sIqwGIm>*PRU%ffqJpk_IffW>cF6Huekc3^QmGh>5#{ApoitMQ~ z=lS~(t)gHR#hy!;ycHy2=PBikKbtbYyVe}}yY`u%CgSH3E_=-+Xc+~sSI2h2&2f*=TjAh5{z4dbV$0lE^k QivR!s07*qoM6N<$f}p{DdH?_b literal 0 HcmV?d00001 diff --git a/3dworld/src/assets/up-arrow.png b/3dworld/src/assets/up-arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..776dbf83789cde07aeb274ac153162200a290663 GIT binary patch literal 845 zcmV-T1G4;yP)IJDs5Uk~}At(*G zT&jn0^Hz`jA40H}bD;(nO|!$zG1(A=8t`ujGL*xm8not*G;8PmEA4z3*6i3N8v+yf z0)iLv!B+&rxm@5AYx3wt?aT~m_&ps{EQI4Ni6Ol7PY8ifd0gVNxcST4nH^bXJ|4oTW~bT`R)QLa^0S4Ikp#j;OyGz$ z6Kd7Y>}XQ+HiXYn%}%!`u7ruAs-|MdIP+4CE}C%9v}Y*q6%gm2^8Jr_v`LA@!I zxCJtTVC`lm)R;A29nsF0sAuz5-^aCE*O|C6zAZRVvlY^rqN=81Ce*k!UlY;JSMR_4 z@(?DLgrMH#2f`(gj^qczC0yc^Eo!RH>#Xixoz-`DLAUPdP0_(sO`A5Rt?k#{8yhR3 zVw_6L5V%mcS151))}clX^OMN~n4gTbS#=z#`XJrlQnju=an#OS^8LVk=Vc6YEJ#Q4 zDjK)3{q?(+iVN&XIRJq@D~)B20htDq>UydHm_Fba7zLnc1#tQcAngI1HbJDbfJ3Lj zDAfT#h0rurfkVTh{FZzrdyHNPQ2$2>69Of!n#jJ51nxFEUS=GV=aEk%XM` z2FWD;^j-$5A3364fM4K3wg1B&&<4IC7<*~rrg^ICMNHxi^OnhaPn#eJf*=Tj03Y)Q X!?366mZnq!00000NkvXXu0mjf-FJ}C literal 0 HcmV?d00001 diff --git a/3dworld/src/environments/environment.development.ts b/3dworld/src/environments/environment.development.ts new file mode 100644 index 00000000..4384ca48 --- /dev/null +++ b/3dworld/src/environments/environment.development.ts @@ -0,0 +1,11 @@ +const backendBaseUrl = 'backend url with no protocal'; + +export const environment = { + production: false, + auth: { + domain: 'your domain', + clientId: 'client', + }, + apiEndpoint: 'http://' + backendBaseUrl, + wsEndpoint: 'ws://' + backendBaseUrl, +}; diff --git a/3dworld/src/environments/environment.ts b/3dworld/src/environments/environment.ts new file mode 100644 index 00000000..064ba6ae --- /dev/null +++ b/3dworld/src/environments/environment.ts @@ -0,0 +1,11 @@ +const backendBaseUrl = 'url to the backend with no protocol'; + +export const environment = { + production: false, + auth: { + domain: 'auth0 domain', + clientId: 'auth0 clientId', + }, + apiEndpoint: 'http://' + backendBaseUrl, + wsEndpoint: 'ws://' + backendBaseUrl, +}; diff --git a/3dworld/src/favicon.ico b/3dworld/src/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..997406ad22c29aae95893fb3d666c30258a09537 GIT binary patch literal 948 zcmV;l155mgP)CBYU7IjCFmI-B}4sMJt3^s9NVg!P0 z6hDQy(L`XWMkB@zOLgN$4KYz;j0zZxq9KKdpZE#5@k0crP^5f9KO};h)ZDQ%ybhht z%t9#h|nu0K(bJ ztIkhEr!*UyrZWQ1k2+YkGqDi8Z<|mIN&$kzpKl{cNP=OQzXHz>vn+c)F)zO|Bou>E z2|-d_=qY#Y+yOu1a}XI?cU}%04)zz%anD(XZC{#~WreV!a$7k2Ug`?&CUEc0EtrkZ zL49MB)h!_K{H(*l_93D5tO0;BUnvYlo+;yss%n^&qjt6fZOa+}+FDO(~2>G z2dx@=JZ?DHP^;b7*Y1as5^uphBsh*s*z&MBd?e@I>-9kU>63PjP&^#5YTOb&x^6Cf z?674rmSHB5Fk!{Gv7rv!?qX#ei_L(XtwVqLX3L}$MI|kJ*w(rhx~tc&L&xP#?cQow zX_|gx$wMr3pRZIIr_;;O|8fAjd;1`nOeu5K(pCu7>^3E&D2OBBq?sYa(%S?GwG&_0-s%_v$L@R!5H_fc)lOb9ZoOO#p`Nn`KU z3LTTBtjwo`7(HA6 z7gmO$yTR!5L>Bsg!X8616{JUngg_@&85%>W=mChTR;x4`P=?PJ~oPuy5 zU-L`C@_!34D21{fD~Y8NVnR3t;aqZI3fIhmgmx}$oc-dKDC6Ap$Gy>a!`A*x2L1v0 WcZ@i?LyX}70000 + + + + 3dworld + + + + + + + + diff --git a/3dworld/src/main.ts b/3dworld/src/main.ts new file mode 100644 index 00000000..17a5cd4e --- /dev/null +++ b/3dworld/src/main.ts @@ -0,0 +1,7 @@ +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/3dworld/src/styles.scss b/3dworld/src/styles.scss new file mode 100644 index 00000000..a191a991 --- /dev/null +++ b/3dworld/src/styles.scss @@ -0,0 +1,170 @@ +/* You can add global styles to this file, and also import other style files */ +/* You can add global styles to this file, and also import other style files */ +html { + overflow: -moz-scrollbars-vertical; +} + +body { + background: #1c1d20; + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + color: white; + text-align: left; + margin: auto; +} + +::after, +::before { + /* https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing */ + box-sizing: border-box; +} + +.row { + margin: 0 auto; + display: flex; + flex-wrap: wrap; +} + +/* 12 grid bootstrap layout */ +.col-1 { + flex-basis: calc(1 / 12 * 100%); +} +.col-2 { + flex-basis: calc(2 / 12 * 100%); +} +.col-3 { + flex-basis: calc(3 / 12 * 100%); +} +.col-4 { + flex-basis: calc(4 / 12 * 100%); +} +.col-5 { + flex-basis: calc(5 / 12 * 100%); +} +.col-6 { + flex-basis: calc(6 / 12 * 100%); +} +.col-7 { + flex-basis: calc(7 / 12 * 100%); +} +.col-8 { + flex-basis: calc(8 / 12 * 100%); +} +.col-9 { + flex-basis: calc(9 / 12 * 100%); +} +.col-10 { + flex-basis: calc(10 / 12 * 100%); +} +.col-11 { + flex-basis: calc(11 / 12 * 100%); +} +.col-12 { + flex-basis: calc(12 / 12 * 100%); +} +.col-auto { + flex: 1; +} + +/* for mobile */ +@media (max-width: 576px) { + .col-sm-1 { + flex-basis: calc(1 / 12 * 100%); + } + .col-sm-2 { + flex-basis: calc(2 / 12 * 100%); + } + .col-sm-3 { + flex-basis: calc(3 / 12 * 100%); + } + .col-sm-4 { + flex-basis: calc(4 / 12 * 100%); + } + .col-sm-5 { + flex-basis: calc(5 / 12 * 100%); + } + .col-sm-6 { + flex-basis: calc(6 / 12 * 100%); + } + .col-sm-7 { + flex-basis: calc(7 / 12 * 100%); + } + .col-sm-8 { + flex-basis: calc(8 / 12 * 100%); + } + .col-sm-9 { + flex-basis: calc(9 / 12 * 100%); + } + .col-sm-10 { + flex-basis: calc(10 / 12 * 100%); + } + .col-sm-11 { + flex-basis: calc(11 / 12 * 100%); + } + .col-sm-12 { + flex-basis: calc(12 / 12 * 100%); + } + .col-sm-auto { + flex: 1; + } +} + +.align-items-center { + align-items: center; + text-align: center; + justify-content: center; +} + +.complex-form { + margin-top: 20px; + margin-left: 20px; + margin-right: 20px; + margin-bottom: 20px; + border-radius: 10px; + background-color: #444; + padding: 20px 10px 10px 10px; + display: flex; + flex-direction: column; +} + +.complex-form .form-title { + font-size: 24px; + font-weight: bold; + margin: -20px -10px 20px -10px; + padding: 10px 0px 10px 25px; + color: white; + background-color: #333; + border-radius: 7px 7px 0px 0px; +} + +.complex-form .form-radio { + display: flex; + justify-content: flex-start; + align-items: center; +} + +.complex-form .form-element { + margin-bottom: 20px; + font-size: 20px; + border-radius: 10px; + padding: 5px 5px 5px 5px; + border: 2px solid rgba(239, 45, 94, 1); +} + +.btn { + padding: 9px 25px; + color: white; + background: rgba(239, 45, 94, 1); + border-radius: 50px; + border: none; + font-size: 15px; +} + +.btn:hover { + background: rgba(239, 45, 94, 0.8); +} + +.hidden { + visibility: hidden !important; + height: 0px !important; +} diff --git a/3dworld/src/three.js b/3dworld/src/three.js new file mode 100644 index 00000000..f99165ef --- /dev/null +++ b/3dworld/src/three.js @@ -0,0 +1,32 @@ +import * as THREE from "three"; + +const scene = new THREE.Scene(); +const camera = new THREE.PerspectiveCamera( + 75, + window.innerWidth / window.innerHeight, + 0.1, + 1000 +); + +const renderer = new THREE.WebGLRenderer(); +renderer.setSize(window.innerWidth, window.innerHeight); +document.body.appendChild(renderer.domElement); + +const geometry = new THREE.BoxGeometry(1, 1, 1); +const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); + +const gridSize = 10; +const cubeSize = 1; + +for (let x = 0; x < gridSize; x++) { + for (let z = 0; z < gridSize; z++) { + const cube = new THREE.Mesh(geometry, material); + cube.position.set(x * cubeSize, 0, z * cubeSize); + scene.add(cube); + } +} + +camera.position.y = 5; +camera.position.z = 10; + +renderer.render(scene, camera); diff --git a/3dworld/tsconfig.app.json b/3dworld/tsconfig.app.json new file mode 100644 index 00000000..9c8ca9a6 --- /dev/null +++ b/3dworld/tsconfig.app.json @@ -0,0 +1,11 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": ["node"], + "typeRoots": ["node_modules/@types"] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/3dworld/tsconfig.json b/3dworld/tsconfig.json new file mode 100644 index 00000000..51481450 --- /dev/null +++ b/3dworld/tsconfig.json @@ -0,0 +1,31 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "useDefineForClassFields": false, + "lib": ["ES2022", "dom"], + "resolveJsonModule": true + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/3dworld/tsconfig.spec.json b/3dworld/tsconfig.spec.json new file mode 100644 index 00000000..47e3dd75 --- /dev/null +++ b/3dworld/tsconfig.spec.json @@ -0,0 +1,9 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": ["jasmine"] + }, + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/README.md b/README.md new file mode 100644 index 00000000..5e3aa11c --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +## Domain: buildverse.live + +# BuildVerse + +BuildVerse is a 3D sandbox platform that allows players to add their creations into a shared virtual world. Players can claim a plot of land and make changes to it using a 3D modeling software of their choice, then submit this plot to be displayed among other players' creations. + +## Features + +- Users can create a BuildVerse account to participate in 3D public worlds. +- Users can select a plot of land from a public world to add their creations. +- Users can modify the land plot by adding their own 3D models and environments. +- Users can view individual plots of land or view a subsection of the public 3D world +- Users can add reactions and comments to other users’ land plots. +- Users will be notified when their creation is rated by other users + +## Complexity points: + +Three.js - 2 points \ +Auth0 - 1 point \ +Push API - 3 points \ +SharedDB - 2 points \ +SendGrid - 2 points + +**Total**: 10 complexity points + +## Our team + +**Team name**: 3D World \ +**Team members**: + +- Juefei Lu, 1006878602 +- Youngjae Heo, 1007002743 +- Tuan Ky Pham, 1007310081 + +## Our Milestones + +**Alpha**: + +- Account creation and Authentication. +- Users can select a land plot from a pool of predefined plots in a public 3D world. +- Users can make edits to their chosen land plot and submit their changes. + +**Beta**: + +- Users can view their and others' land plots individually or in a subsection of the 3D world. +- Ratings and comments implementation. + +**Final**: + +- Push notification and email notification + +## Our choice of reactive frontend framework + +Angular diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 00000000..600e365e --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1 @@ +**/node_modules \ No newline at end of file diff --git a/backend/.env.bak b/backend/.env.bak new file mode 100644 index 00000000..6d924a97 --- /dev/null +++ b/backend/.env.bak @@ -0,0 +1,7 @@ +MONGO_URI= +MONGO_DB_NAME= +ADMIN_SUB- +REDIS_URI=localhost +FRONTEND_BASE_URL=http://localhost:4200 +SESSION_SECRET= +SEND_GRID_API_KEY= \ No newline at end of file diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 00000000..012d3213 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,9 @@ +# OS Files +Thumbs.db +.DS_Store + +# node.js +node_modules + +.env +uploads/ \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 00000000..88c1e77c --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,13 @@ +FROM node:16 + +WORKDIR /usr/src/app + +COPY package*.json ./ + +RUN npm install + +COPY . . + +EXPOSE 3000 + +CMD [ "node", "app.js" ] \ No newline at end of file diff --git a/backend/adminInit.js b/backend/adminInit.js new file mode 100644 index 00000000..ec8cf873 --- /dev/null +++ b/backend/adminInit.js @@ -0,0 +1,25 @@ +import { User } from "./models/users.js"; +import { config } from "./config.js"; + +const adminSub = config.adminSub; + +export const initAdmin = async function () { + const existingAdmin = await User.findOne({ sub: adminSub }); + if (!existingAdmin) { + const admin = new User({ + sub: adminSub, + displayName: "admin", + email: "admin@localhost.loc", + claims: [], + isAdmin: true, + }); + await admin.save(); + } else { + existingAdmin.sub = adminSub; + existingAdmin.displayName = "admin"; + existingAdmin.email = "admin@localhost.loc"; + existingAdmin.claims = []; + existingAdmin.isAdmin = true; + await existingAdmin.save(); + } +}; diff --git a/backend/app.js b/backend/app.js new file mode 100644 index 00000000..6d80e950 --- /dev/null +++ b/backend/app.js @@ -0,0 +1,137 @@ +import express from "express"; +import expressWs from "express-ws"; +import { createServer } from "http"; +import bodyParser from "body-parser"; +import morgan from "morgan"; +import session from "express-session"; +import cors from "cors"; +import cron from "node-cron"; +import { openMongoSession, closeMongoSession } from "./datasource.js"; +import { + closeNotification, + initSocketIOFromServer, +} from "./socketio/notifications.js"; +import { config } from "./config.js"; +import sgMail from "@sendgrid/mail"; + +import { usersRouter } from "./routers/users_router.js"; +import { worldsRouter } from "./routers/worlds_router.js"; +import { commentsRouter } from "./routers/comments_router.js"; +import { notificationsRouter } from "./routers/notifications_router.js"; +import { initAdmin } from "./adminInit.js"; + +const port = 3000; // fix port number and expose it in docker +const app = express(); +const server = createServer(app); +const wsInstance = expressWs(app, server); + +app.use(bodyParser.json()); +app.use(morgan("dev")); // add request logger + +//create session +const sessionMiddleware = session({ + secret: config.sessionSecret, + resave: false, + saveUninitialized: true, +}); +app.use(sessionMiddleware); + +//cors +const corsOptions = { + origin: config.frontendBaseUrl, + credentials: true, +}; +app.use(cors(corsOptions)); + +// open MongoDB session +try { + await openMongoSession(); +} catch (err) { + console.error(err); +} + +// TODO: add other routers +app.use("/api/users", usersRouter); +app.use("/api/worlds", worldsRouter); +app.use("/api/comments", commentsRouter); +app.use("/api/notifications", notificationsRouter); + +//cronjob +cron.schedule("0 0 * * SUN", () => { + console.log("running a task every Sunday"); + /* + sgMail.setApiKey(config.sendGrid_Api_key); +const msg = { + to: 'youngjaeheo2002@gmail.com', // Change to your recipient + from: 'buildverse242@gmail.com', // Change to your verified sender + subject: 'Sending with SendGrid is Fun', + text: 'and easy to do anywhere, even with Node.js', + html: 'and easy to do anywhere, even with Node.js', +} +sgMail + .send(msg) + .then(() => { + console.log('Email sent') + }) + .catch((error) => { + console.error(error) + }) + */ + sgMail.setApiKey(config.sendGrid_Api_key); + fetch(`http://localhost:${port}/api/users/allusers/ratings`, { + method: "GET", + }) + .then((res) => res.json()) + .then((res) => { + res.forEach((item) => { + const msg = { + to: `${item.email}`, // Change to your recipient + from: "buildverse242@gmail.com", // Change to your verified sender + subject: "Upvotes and Downvotes", + text: `Hi ${item.name}! You have accumulated ${item.avgRating} average rating on your chunks`, + }; + sgMail + .send(msg) + .then(() => { + console.log("Email sent"); + }) + .catch((error) => { + console.error(error); + }); + }); + }); +}); + +// 500 error handler +app.use((err, req, res, next) => { + console.error(err.stack); + res.status(500).send("Internal Server Error"); +}); + +// Create an admin account +try { + await initAdmin(); +} catch (err) { + console.error(err); +} + +// start server +initSocketIOFromServer(server, sessionMiddleware, corsOptions); +server.listen(port, () => { + console.log(`Server started at http://localhost:${port}`); +}); + +// close mongo session and server +const cleanup = async () => { + wsInstance.getWss().clients.forEach((client) => { + client.close(); + }); + closeNotification(); + await closeMongoSession(); + server.close((err) => { + console.log("Server closed"); + process.exit(err ? 1 : 0); + }); +}; +process.on("SIGINT", cleanup); +process.on("SIGTERM", cleanup); diff --git a/backend/config.js b/backend/config.js new file mode 100644 index 00000000..22fded01 --- /dev/null +++ b/backend/config.js @@ -0,0 +1,14 @@ +"use strict"; + +import * as dotenv from "dotenv"; +dotenv.config(); + +export const config = { + mongoURI: process.env.MONGO_URI, + mongoDbName: process.env.MONGO_DB_NAME, + adminSub: process.env.ADMIN_SUB, + redisURI: process.env.REDIS_URI, + frontendBaseUrl: process.env.FRONTEND_BASE_URL, + sessionSecret: process.env.SESSION_SECRET, + sendGrid_Api_key: process.env.SENDGRID_API_KEY, +}; diff --git a/backend/datasource.js b/backend/datasource.js new file mode 100644 index 00000000..a92ae18f --- /dev/null +++ b/backend/datasource.js @@ -0,0 +1,46 @@ +import mongoose from "mongoose"; +import ShareDB from "sharedb"; +import ShareDbMongo from "sharedb-mongo"; + +import { config } from "./config.js"; + +const mongoURI = config.mongoURI; +const mongoDbName = config.mongoDbName; + +let mongo_client = null; +let shareBackend = null; + +export const openMongoSession = async function () { + if (mongo_client === null) { + console.log("Connecting to MongoDB..."); + await mongoose.connect(mongoURI, { + dbName: mongoDbName, + useNewUrlParser: true, + useUnifiedTopology: true, + }); + mongo_client = mongoose.connection.getClient(); + console.log("Connected to MongoDB"); + const db = new ShareDbMongo({ + mongo: (callback) => { + callback(null, mongo_client); + }, + }); + shareBackend = new ShareDB({ db }); + } +}; + +export const closeMongoSession = async function () { + if (mongo_client) { + await mongoose.disconnect(); + await shareBackend.close(); + mongo_client = null; + shareBackend = null; + } +}; + +export const getShareBackend = async function () { + if (mongo_client === null) { + await openMongoSession(); + } + return shareBackend; +}; diff --git a/backend/middleware/auth.js b/backend/middleware/auth.js new file mode 100644 index 00000000..a6b943c6 --- /dev/null +++ b/backend/middleware/auth.js @@ -0,0 +1,21 @@ +export const isAuthenticated = function (req, res, next) { + if (!req.session.userId) { + return res.status(401).json({ error: "Not authenticated" }); + } + next(); +}; + +export const isWsAuthenticated = function (ws, req, next) { + if (!req.session.sub) { + return ws.close(4011, "Not authenticated"); + } + next(); +}; + +export const isSocketAuthenticated = function (socket, next) { + if (!socket.request.session || !socket.request.session.sub) { + next(new Error("Not authenticated")); + } else { + next(); + } +}; diff --git a/backend/models/comments.js b/backend/models/comments.js new file mode 100644 index 00000000..0f6cc8be --- /dev/null +++ b/backend/models/comments.js @@ -0,0 +1,31 @@ +import mongoose from "mongoose"; +const commentSchema = new mongoose.Schema( + { + author: { + type: mongoose.SchemaTypes.ObjectId, + required: true, + ref: "User", + }, + worldId: { + type: mongoose.SchemaTypes.ObjectId, + required: true, + }, + chunk: { + x: Number, + z: Number, + }, + content: { + type: String, + required: true, + }, + rating: { + type: Number, + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + required: true, + }, + }, + { + timestamps: true, + } +); +export const Comments = mongoose.model("Comments", commentSchema); diff --git a/backend/models/gridfiles.js b/backend/models/gridfiles.js new file mode 100644 index 00000000..411d11b3 --- /dev/null +++ b/backend/models/gridfiles.js @@ -0,0 +1,4 @@ +import mongoose from "mongoose"; +import schema from "gridfile"; + +export const GridFile = mongoose.model("GridFile", schema); diff --git a/backend/models/notifications.js b/backend/models/notifications.js new file mode 100644 index 00000000..f60c2c82 --- /dev/null +++ b/backend/models/notifications.js @@ -0,0 +1,45 @@ +import mongoose from "mongoose"; + +const notificationSchema = new mongoose.Schema( + { + sender: { + type: String, + required: true, + }, + rating: { + type: Number, + enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + required: true, + }, + worldId: { + type: mongoose.SchemaTypes.ObjectId, + required: true, + }, + worldName: { + type: String, + required: true, + }, + chunk: { + x: Number, + z: Number, + }, + }, + { timestamps: true } +); + +const userNotificationsSchema = new mongoose.Schema({ + user: { + type: mongoose.SchemaTypes.ObjectId, + required: true, + ref: "User", + }, + notifications: { + type: [notificationSchema], + default: [], + }, +}); + +export const UserNotifications = mongoose.model( + "UserNotifications", + userNotificationsSchema +); diff --git a/backend/models/users.js b/backend/models/users.js new file mode 100644 index 00000000..dd7a86d7 --- /dev/null +++ b/backend/models/users.js @@ -0,0 +1,48 @@ +import mongoose from "mongoose"; + +const validateEmail = function (email) { + var re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/; + return re.test(email); +}; + +const claimsSchema = new mongoose.Schema({ + world: { type: mongoose.SchemaTypes.ObjectId, ref: "World" }, + chunk: mongoose.SchemaTypes.ObjectId, +}); +const userSchema = new mongoose.Schema({ + sub: { + type: String, + required: true, + unique: true, + }, + displayName: { + required: true, + type: String, + unique: true, + }, + claims: { + type: [claimsSchema], + required: true, + }, + ratings: { + type: [{ type: mongoose.SchemaTypes.ObjectId, ref: "Comments" }], + default: [], + }, + email: { + type: String, + trim: true, + lowercase: true, + required: "Email address is required", + validate: [validateEmail, "Please fill a valid email address"], + match: [ + /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, + "Please fill a valid email address", + ], + }, + isAdmin: { + type: Boolean, + default: false, + }, +}); + +export const User = mongoose.model("User", userSchema); diff --git a/backend/models/worlds.js b/backend/models/worlds.js new file mode 100644 index 00000000..97f416cc --- /dev/null +++ b/backend/models/worlds.js @@ -0,0 +1,44 @@ +import mongoose from "mongoose"; + +const chunkSchema = new mongoose.Schema({ + location: { + x: { type: Number, required: true }, + z: { type: Number, required: true }, + }, + chunkFile: { type: mongoose.ObjectId, default: null }, + claimedBy: { type: mongoose.ObjectId, default: null }, +}); + +const worldSchema = new mongoose.Schema({ + name: { type: String, required: true }, + chunkSize: { + x: { type: Number, required: true }, + }, + description: String, + rules: String, + chunks: { + type: [chunkSchema], + }, +}); + +worldSchema.pre("validate", function (next) { + // chunks must not overlap + const chunkSize = this.chunkSize.x; + const chunks = this.chunks; + for (let i = 0; i < chunks.length; i++) { + const c1 = chunks[i]; + for (let j = i + 1; j < chunks.length; j++) { + const c2 = chunks[j]; + if ( + Math.abs(c1.location.x - c2.location.x) < chunkSize && + Math.abs(c1.location.z - c2.location.z) < chunkSize + ) { + next(new Error("Chunks overlap")); + return; + } + } + } + next(); +}); + +export const World = mongoose.model("World", worldSchema); diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 00000000..82f871ba --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,3558 @@ +{ + "name": "buildverse-backend", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "buildverse-backend", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@sendgrid/mail": "^7.7.0", + "@teamwork/websocket-json-stream": "^2.0.0", + "adm-zip": "^0.5.10", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "express-session": "^1.17.3", + "express-ws": "^5.0.2", + "gltf-validator": "^2.0.0-dev.3.9", + "gridfile": "^1.1.4", + "ioredis": "^5.3.1", + "mongodb": "^5.2.0", + "mongoose": "^7.0.3", + "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", + "node-cron": "^3.0.2", + "sharedb": "^3.3.1", + "sharedb-mongo": "^3.0.1", + "socket.io": "^4.6.1" + }, + "devDependencies": { + "nodemon": "^2.0.20", + "prettier": "^2.8.4" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" + }, + "node_modules/@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "dependencies": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "dependencies": { + "deepmerge": "^4.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "dependencies": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "node_modules/@teamwork/websocket-json-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teamwork/websocket-json-stream/-/websocket-json-stream-2.0.0.tgz", + "integrity": "sha512-SCEM44hjNyxYwrtyJrjlHmeTd9RJlZr04BAMbHSBhdW0M2IXv0SC+4XeuRXPiY7U7pJ0W8TSUwVP/28MV/ds0w==" + }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "node_modules/@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", + "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha512-t0OgO06uolEcMUvV8+yHc9Pc9pazh8wi/Dtyok/sQwvcr8iFV+P86IfAzK7upUDhI4oavhVREMY7iSWtm38LeA==" + }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bson": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.2.0.tgz", + "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==", + "engines": { + "node": ">=14.20.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-session": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "dependencies": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express-ws": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", + "integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==", + "dependencies": { + "ws": "^7.4.6" + }, + "engines": { + "node": ">=4.5.0" + }, + "peerDependencies": { + "express": "^4.0.0 || ^5.0.0-alpha.1" + } + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gltf-validator": { + "version": "2.0.0-dev.3.9", + "resolved": "https://registry.npmjs.org/gltf-validator/-/gltf-validator-2.0.0-dev.3.9.tgz", + "integrity": "sha512-9nPcAgYJwT6sbml7S3/tC+N/BkqTUSL1u8GcmUQLuwToLR0ZH8CF3i/BhVqDwlg7OmKS2GGjjEcnU/oMMeIQUQ==" + }, + "node_modules/gridfile": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gridfile/-/gridfile-1.1.4.tgz", + "integrity": "sha512-gpGzUvstM0mXyUFPkdQ8Wa9reDodQu3fEwZszqbWXk6zIScHVg61jSbA4O797SjZTM/zkqxF2YI0gJZEySEiUw==", + "peerDependencies": { + "mongoose": "*" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==", + "engines": { + "node": "*" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ioredis": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.1.tgz", + "integrity": "sha512-C+IBcMysM6v52pTLItYMeV4Hz7uriGtoJdz7SSBDX6u+zwSYGirLdQh3L7t/OItWITcw3gTFMjJReYUwS4zihg==", + "dependencies": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ioredis/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/ioredis/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mongodb": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.2.0.tgz", + "integrity": "sha512-nLgo95eP1acvjBcOdrUV3aqpWwHZCZwhYA2opB8StybbtQL/WoE5pk92qUUfjbKOWcGLYJczTqQbfOQhYtrkKg==", + "dependencies": { + "bson": "^5.2.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": "^2.3.0", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongoose": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.0.3.tgz", + "integrity": "sha512-3n8vc1/mssuxKa6vfghSocp3MeiCFYzhX36Ok+PsDNNYzHC9tw3rNkAMLemIwZ2jgXqkZ7CfKOxkzjp/d/SWfg==", + "dependencies": { + "bson": "^5.0.1", + "kareem": "2.5.1", + "mongodb": "5.1.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", + "dependencies": { + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": "^2.3.0", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-cron": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", + "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/sharedb": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-3.3.1.tgz", + "integrity": "sha512-gPLKUFZX7FsrZ4AonyWtoslYbT9d+82yttH4dvsFTwwh4tNx8L7hXW9oKTWfqx3APhk0VApAN64ObT969cvCTA==", + "dependencies": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "node_modules/sharedb-mongo": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sharedb-mongo/-/sharedb-mongo-3.0.1.tgz", + "integrity": "sha512-IXoSjPgZ+pCgybUHcUXPwSX597W2qGi/DKfN9MRABw6GKS+EALLkvG5PgFdpxHXNXoDJpEjDXAY0D78rdhrGMg==", + "dependencies": { + "mongodb": "^3.1.13 || ^4.0.0 || ^5.0.0", + "sharedb": "^1.9.1 || ^2.0.0 || ^3.0.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + }, + "dependencies": { + "@ioredis/commands": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", + "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==" + }, + "@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "requires": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + } + }, + "@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "requires": { + "deepmerge": "^4.2.2" + } + }, + "@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "requires": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + } + }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "@teamwork/websocket-json-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teamwork/websocket-json-stream/-/websocket-json-stream-2.0.0.tgz", + "integrity": "sha512-SCEM44hjNyxYwrtyJrjlHmeTd9RJlZr04BAMbHSBhdW0M2IXv0SC+4XeuRXPiY7U7pJ0W8TSUwVP/28MV/ds0w==" + }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, + "@types/cors": { + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", + "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==" + }, + "@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==" + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha512-t0OgO06uolEcMUvV8+yHc9Pc9pazh8wi/Dtyok/sQwvcr8iFV+P86IfAzK7upUDhI4oavhVREMY7iSWtm38LeA==" + }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "requires": { + "lodash": "^4.17.14" + } + }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "bson": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.2.0.tgz", + "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "requires": { + "streamsearch": "^1.1.0" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "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" + } + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, + "denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" + }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, + "engine.io": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.1.tgz", + "integrity": "sha512-JFYQurD/nbsA5BSPmbaOSLa3tSVj8L6o4srSwXXY3NqE+gGUNmmPTbhn8tjzcCtSqhFgIeqef81ngny8JM25hw==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} + } + } + }, + "engine.io-parser": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" + }, + "express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + } + }, + "raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + } + } + }, + "express-session": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", + "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==", + "requires": { + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + } + } + }, + "express-ws": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", + "integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==", + "requires": { + "ws": "^7.4.6" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "gltf-validator": { + "version": "2.0.0-dev.3.9", + "resolved": "https://registry.npmjs.org/gltf-validator/-/gltf-validator-2.0.0-dev.3.9.tgz", + "integrity": "sha512-9nPcAgYJwT6sbml7S3/tC+N/BkqTUSL1u8GcmUQLuwToLR0ZH8CF3i/BhVqDwlg7OmKS2GGjjEcnU/oMMeIQUQ==" + }, + "gridfile": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/gridfile/-/gridfile-1.1.4.tgz", + "integrity": "sha512-gpGzUvstM0mXyUFPkdQ8Wa9reDodQu3fEwZszqbWXk6zIScHVg61jSbA4O797SjZTM/zkqxF2YI0gJZEySEiUw==", + "requires": {} + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==" + }, + "http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ioredis": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.3.1.tgz", + "integrity": "sha512-C+IBcMysM6v52pTLItYMeV4Hz7uriGtoJdz7SSBDX6u+zwSYGirLdQh3L7t/OItWITcw3gTFMjJReYUwS4zihg==", + "requires": { + "@ioredis/commands": "^1.1.1", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.4", + "denque": "^2.1.0", + "lodash.defaults": "^4.2.0", + "lodash.isarguments": "^3.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==" + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "mongodb": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.2.0.tgz", + "integrity": "sha512-nLgo95eP1acvjBcOdrUV3aqpWwHZCZwhYA2opB8StybbtQL/WoE5pk92qUUfjbKOWcGLYJczTqQbfOQhYtrkKg==", + "requires": { + "bson": "^5.2.0", + "mongodb-connection-string-url": "^2.6.0", + "saslprep": "^1.0.3", + "socks": "^2.7.1" + } + }, + "mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "mongoose": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.0.3.tgz", + "integrity": "sha512-3n8vc1/mssuxKa6vfghSocp3MeiCFYzhX36Ok+PsDNNYzHC9tw3rNkAMLemIwZ2jgXqkZ7CfKOxkzjp/d/SWfg==", + "requires": { + "bson": "^5.0.1", + "kareem": "2.5.1", + "mongodb": "5.1.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "dependencies": { + "mongodb": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.1.0.tgz", + "integrity": "sha512-qgKb7y+EI90y4weY3z5+lIgm8wmexbonz0GalHkSElQXVKtRuwqXuhXKccyvIjXCJVy9qPV82zsinY0W1FBnJw==", + "requires": { + "bson": "^5.0.1", + "mongodb-connection-string-url": "^2.6.0", + "saslprep": "^1.0.3", + "socks": "^2.7.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "requires": { + "ee-first": "1.1.1" + } + } + } + }, + "mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "requires": { + "debug": "4.x" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "multer": { + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "requires": { + "append-field": "^1.0.0", + "busboy": "^1.0.0", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + } + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "node-cron": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", + "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "requires": { + "uuid": "8.3.2" + } + }, + "nodemon": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz", + "integrity": "sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" + }, + "on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prettier": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" + }, + "qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==" + }, + "redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "requires": { + "redis-errors": "^1.0.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "requires": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "sharedb": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-3.3.1.tgz", + "integrity": "sha512-gPLKUFZX7FsrZ4AonyWtoslYbT9d+82yttH4dvsFTwwh4tNx8L7hXW9oKTWfqx3APhk0VApAN64ObT969cvCTA==", + "requires": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "sharedb-mongo": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sharedb-mongo/-/sharedb-mongo-3.0.1.tgz", + "integrity": "sha512-IXoSjPgZ+pCgybUHcUXPwSX597W2qGi/DKfN9MRABw6GKS+EALLkvG5PgFdpxHXNXoDJpEjDXAY0D78rdhrGMg==", + "requires": { + "mongodb": "^3.1.13 || ^4.0.0 || ^5.0.0", + "sharedb": "^1.9.1 || ^2.0.0 || ^3.0.0" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socket.io": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", + "requires": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.2", + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socket.io-adapter": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "requires": { + "ws": "~8.11.0" + }, + "dependencies": { + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "requires": {} + } + } + }, + "socket.io-parser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.2.tgz", + "integrity": "sha512-DJtziuKypFkMMHCm2uIshOYC7QaylbtzQwiMYDuCKy3OPkjLzu4B2vAhTlqipRHHzrI0NJeBAizTK7X+6m1jVw==", + "requires": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "requires": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + } + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==" + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" + }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, + "requires": { + "nopt": "~1.0.10" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, + "undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/backend/package.json b/backend/package.json new file mode 100644 index 00000000..c0fb1dc2 --- /dev/null +++ b/backend/package.json @@ -0,0 +1,41 @@ +{ + "name": "buildverse-backend", + "version": "1.0.0", + "description": "", + "main": "app.js", + "type": "module", + "scripts": { + "format": "prettier --write \"**/*.{js,jsx,json,css,md}\"", + "start": "node app.js", + "dev": "nodemon -L app.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@sendgrid/mail": "^7.7.0", + "@teamwork/websocket-json-stream": "^2.0.0", + "adm-zip": "^0.5.10", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "dotenv": "^16.0.3", + "express": "^4.18.2", + "express-session": "^1.17.3", + "express-ws": "^5.0.2", + "gltf-validator": "^2.0.0-dev.3.9", + "gridfile": "^1.1.4", + "ioredis": "^5.3.1", + "mongodb": "^5.2.0", + "mongoose": "^7.0.3", + "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", + "node-cron": "^3.0.2", + "sharedb": "^3.3.1", + "sharedb-mongo": "^3.0.1", + "socket.io": "^4.6.1" + }, + "devDependencies": { + "nodemon": "^2.0.20", + "prettier": "^2.8.4" + } +} diff --git a/backend/routers/comments_router.js b/backend/routers/comments_router.js new file mode 100644 index 00000000..75648aa3 --- /dev/null +++ b/backend/routers/comments_router.js @@ -0,0 +1,152 @@ +import { Router } from "express"; +import { Comments } from "../models/comments.js"; +import { User } from "../models/users.js"; +import { World } from "../models/worlds.js"; +import { UserNotifications } from "../models/notifications.js"; +import { isAuthenticated } from "../middleware/auth.js"; +import mongoose from "mongoose"; +import { usersRouter } from "./users_router.js"; +import { sendNotification } from "../socketio/notifications.js"; + +export const commentsRouter = Router(); + +//post +commentsRouter.post("/", isAuthenticated, async (req, res) => { + const author = req.body.author; + const x = req.body.x; + const z = req.body.z; + const worldId = req.body.worldId; + const content = req.body.content; + const rating = req.body.rating; + if (!mongoose.Types.ObjectId.isValid(author)) { + return res.status(422).json({ error: "Invalid id" }); + } + if (!mongoose.Types.ObjectId.isValid(worldId)) { + return res.status(422).json({ error: "Invalid id" }); + } + const world = await World.findById(worldId).lean(); + if (!world) { + return res.status(404).json({ error: "World not found" }); + } + + const chunks = world.chunks; + const wantedChunk = chunks.find( + (chunk) => (chunk.location.x === x) & (chunk.location.z === z) + ); + if (!wantedChunk) { + return res.status(404).json({ error: "Chunk not found" }); + } + const claimedBy = await User.findById(wantedChunk.claimedBy); + if (!claimedBy) { + return res.status(404).json({ error: "Chunk owner not found" }); + } + + if (!wantedChunk.chunkFile) { + return res.status(404).json({ error: "Chunk file not found" }); + } + const user = await User.findById(author); + if (!user) { + return res.status(404).json({ error: "Author not found" }); + } + const ogComment = await Comments.findOne({ + author: author, + "chunk.x": x, + "chunk.z": z, + worldId: worldId, + }); + if (ogComment) { + return res.status(422).json({ error: "You already rated this chunk" }); + } + const comment = new Comments({ + author: author, + worldId: worldId, + chunk: { + x: x, + z: z, + }, + content: content, + rating: rating, + }); + claimedBy.ratings.push(comment._id); + + if (wantedChunk.claimedBy.toString() !== author.toString()) { + const newNotification = { + sender: user.displayName, + rating: rating, + chunk: { + x, + z, + }, + worldName: world.name, + worldId: worldId, + }; + let userNotifications; + try { + userNotifications = await UserNotifications.findOne({ + user: wantedChunk.claimedBy, + }); + userNotifications.notifications.unshift(newNotification); + await userNotifications.save(); + const receiver = wantedChunk.claimedBy.toString(); + sendNotification(receiver, newNotification); + } catch (err) { + next(err); + } + } + + try { + await comment.save(); + await claimedBy.save(); + } catch { + return res.status(422).json({ error: "Comment creation failed" }); + } + + return res.json(comment); +}); + +//get for world +commentsRouter.get( + "/worldId=:worldId&x=:x&z=:z&page=:page&limit=:limit", + isAuthenticated, + async (req, res) => { + console.log(req.params.worldId); + const page = parseInt(req.params.page); + const limit = parseInt(req.params.limit); + const worldId = req.params.worldId; + const x = parseInt(req.params.x); + const z = parseInt(req.params.z); + const world = await World.findById(worldId).lean(); + if (!world) { + return res.status(404).json({ error: "World not found" }); + } + const comments = await Comments.find({ + worldId: worldId, + "chunk.x": x, + "chunk.z": z, + }) + .populate("author") + .sort({ createdAt: "desc" }) + .skip(page * limit) + .limit(limit + 1); + return res.json(comments); + } +); + +commentsRouter.delete("/:id", isAuthenticated, async (req, res) => { + const id = req.params.id; + + const comment = await Comments.findById(id); + if (!comment) { + return res.status(404).json({ error: "Comment not found" }); + } + if (comment.author.toString() !== req.session.userId) { + return res.status(401).json({ error: "Unauthorized to delete comment" }); + } + try { + await Comments.findByIdAndDelete(id); + } catch { + return res.status(422).json({ error: "Comment deletion failed" }); + } + + return res.json(comment); +}); diff --git a/backend/routers/notifications_router.js b/backend/routers/notifications_router.js new file mode 100644 index 00000000..01010af6 --- /dev/null +++ b/backend/routers/notifications_router.js @@ -0,0 +1,28 @@ +import { Router } from "express"; +import { UserNotifications } from "../models/notifications.js"; +import { isAuthenticated } from "../middleware/auth.js"; + +export const notificationsRouter = Router(); + +// GET /api/notifications +notificationsRouter.get( + "/page=:page&limit=:limit", + isAuthenticated, + async (req, res) => { + const userId = req.session.userId; + const limit = req.query.limit ? +req.query.limit : 10; + const page = req.query.page ? +req.query.page : 0; + const userNotifications = await UserNotifications.findOne({ + user: userId, + }); + if (!userNotifications) { + return res.status(404).json({ error: `user ${userId} not found` }); + } + const notifications = userNotifications.notifications; + const notificationsPostSlice = notifications.slice( + page * limit, + page * limit + limit + 1 + ); + return res.json(notificationsPostSlice); + } +); diff --git a/backend/routers/users_router.js b/backend/routers/users_router.js new file mode 100644 index 00000000..4b1a6742 --- /dev/null +++ b/backend/routers/users_router.js @@ -0,0 +1,165 @@ +import { Router } from "express"; +import { User } from "../models/users.js"; +import { isAuthenticated } from "../middleware/auth.js"; +import { Db } from "mongodb"; +import { World } from "../models/worlds.js"; +import { Comments } from "../models/comments.js"; +import { UserNotifications } from "../models/notifications.js"; +// TODO: Create a mongoose model for users and import it here + +export const usersRouter = Router(); + +// TODO: add users routes + +//signup +usersRouter.post("/signup", async (req, res) => { + //displayName:req.body.displayName + //sub = req.body.sub + //claims = [] + const user1 = await User.findOne({ + displayName: req.body.displayName, + }); + if (user1 !== null) { + return res.status(422).json({ error: "displayName already taken" }); + } + const user = new User({ + sub: req.body.sub, + displayName: req.body.displayName, + email: req.body.email, + claims: [], + }); + + const userNotifications = new UserNotifications({ + user: user._id, + notifications: [], + }); + + try { + await user.save(); + await userNotifications.save(); + } catch { + return res.status(422).json({ error: "user creation failed" }); + } + res.json(user); +}); +//signin +usersRouter.post("/signin", async (req, res) => { + //sub = req.body.sub + + const user = await User.findOne({ + sub: req.body.sub, + }); + + if (user === null) { + return res + .status(404) + .json({ error: `User with sub : ${req.body.sub} not found` }); + } + + let userNotifications = await UserNotifications.findOne({ + user: user._id, + }); + if (userNotifications === null) { + userNotifications = new UserNotifications({ + user: user._id, + notifications: [], + }); + await userNotifications.save(); + } + + req.session.sub = user.sub; + req.session.displayName = user.displayName; + const userId = user._id.toString(); + req.session.userId = userId; + console.log("Session started"); + console.log("-----------------------------------------------"); + console.log(`Req.session.sub is set to ${req.session.sub}`); + console.log(`Req.session.displayName is set to ${req.session.displayName}`); + console.log(`Req.session.userId is set to ${req.session.userId}`); + return res.json({ userId: user._id, sub: user.sub }); +}); + +usersRouter.get("/signout", isAuthenticated, function (req, res, next) { + console.log("started"); + req.session.destroy(); + console.log("Session ended"); + console.log("-----------------------------------------------"); + res.json({ message: "Signed out" }); +}); + +usersRouter.get("/me", isAuthenticated, async (req, res) => { + return res.json({ + userId: req.session.userId, + sub: req.session.sub, + displayName: req.session.displayName, + }); +}); +//getting all +usersRouter.get("/", async (req, res) => { + const users = await User.find(); + return res.json(users); +}); + +//getting claims +usersRouter.get( + "/myClaims/page=:page&limit=:limit", + isAuthenticated, + async (req, res) => { + const page = parseInt(req.params.page); + const limit = parseInt(req.params.limit); + const user = await User.findById(req.session.userId).populate( + "claims.world" + ); + const claims = [ + ...new Map(user.claims.map((m) => [m.world._id, m])).values(), + ]; + const claimsPostSlice = claims.slice( + page * limit, + page * limit + limit + 1 + ); + return res.json(claimsPostSlice); + } +); + +//getSumofUpvotesandDownvotes +usersRouter.get("/allusers/ratings", async (req, res) => { + const items = await User.find().populate("ratings"); + let returnItems = []; + items.forEach((item) => { + let sum = 0; + for (let i = 0; i < item.ratings.length; i++) { + sum += item.ratings[i].rating; + } + const avg = sum / item.ratings.length; + returnItems.push({ + email: item.email, + name: item.displayName, + avgRating: avg, + }); + }); + return res.json(returnItems); +}); + +//change displayName +usersRouter.patch("/displayName", isAuthenticated, async (req, res) => { + const userId = req.session.userId; + const newName = req.body.displayName; + + const user = await User.findById(userId); + if (!user) { + return res.status(404).json({ error: "User not found" }); + } + + user.displayName = newName; + try { + await user.save(); + req.session.displayName = newName; + return res.json({ + displayName: user.displayName, + }); + } catch { + return res + .status(422) + .json({ error: `Changing displayName for user ${user._id} failed` }); + } +}); diff --git a/backend/routers/utils.js b/backend/routers/utils.js new file mode 100644 index 00000000..6cefe419 --- /dev/null +++ b/backend/routers/utils.js @@ -0,0 +1,60 @@ +import AdmZip from "adm-zip"; +import gltfValidator from "gltf-validator"; +import fs from "fs"; +import mongoose from "mongoose"; + +// TODO: reformat the errors + +// util method to validate multi-file gltf in a zip +export const validateGltfZip = async (zipFile) => { + let zip; + try { + zip = new AdmZip(zipFile); + } catch (err) { + throw new Error("Invalid zip file"); + } + + const zipEntries = zip.getEntries(); + const gltfEntry = zipEntries.find((entry) => + entry.entryName.endsWith(".gltf") + ); + if (!gltfEntry) { + throw new Error("No .gltf file found in zip"); + } + + const gltfBuffer = zip.readFile(gltfEntry); + // Validate the loaded glTF file and its associated assets + const result = await gltfValidator.validateBytes(gltfBuffer, { + externalResourceFunction: (uri) => { + const externEntry = zipEntries.find((entry) => + entry.entryName.endsWith(uri) + ); + if (!externEntry) { + throw new Error(`External resource ${uri} not found in zip file`); + } + return Promise.resolve(zip.readFile(externEntry)); + }, + }); + if (result.issues.numErrors > 0) { + throw new Error( + `GLTF validation failed with ${result.issues.numErrors} errors` + ); + } +}; + +export const deleteFile = (path) => { + fs.unlink(path, (err) => { + if (err) { + console.error(err); + } + }); +}; + +export const validateIds = (ids) => { + for (const id of ids) { + if (!mongoose.Types.ObjectId.isValid(id)) { + return false; + } + } + return true; +}; diff --git a/backend/routers/worlds_router.js b/backend/routers/worlds_router.js new file mode 100644 index 00000000..ac4bdec4 --- /dev/null +++ b/backend/routers/worlds_router.js @@ -0,0 +1,365 @@ +import { Router } from "express"; +import multer from "multer"; +import fs from "fs"; +import patch from "express-ws/lib/add-ws-method.js"; +import WebSocketJSONStream from "@teamwork/websocket-json-stream"; + +import { getShareBackend } from "../datasource.js"; + +import { isAuthenticated, isWsAuthenticated } from "../middleware/auth.js"; +import { GridFile } from "../models/gridfiles.js"; +import { World } from "../models/worlds.js"; +import { User } from "../models/users.js"; + +import { validateGltfZip, deleteFile, validateIds } from "./utils.js"; + +// Create a temp folder for storing uploaded files +const upload = multer({ dest: "./uploads" }); + +// Get the shareDB backend +const shareBackend = await getShareBackend(); + +export const worldsRouter = Router(); +patch.default(worldsRouter); + +/* GET /api/worlds */ +worldsRouter.get("/", isAuthenticated, async (req, res) => { + const worlds = await World.find().lean(); + res.json({ worlds }); +}); + +/* GET /api/worlds/:id */ +worldsRouter.get("/:id", isAuthenticated, async (req, res) => { + if (!validateIds([req.params.id])) { + res.status(400).json({ error: "Invalid ID" }); + return; + } + const world = await World.findById(req.params.id).lean(); + if (!world) { + res.status(404).json({ error: "World not found" }); + return; + } + res.json({ world }); +}); + +/* GET /api/worlds/:worldId/chunks/:chunkId/file */ +worldsRouter.get( + "/:worldId/chunks/:chunkId/file", + isAuthenticated, + async (req, res) => { + const { worldId, chunkId } = req.params; + if (!validateIds([worldId, chunkId])) { + res.status(400).json({ error: "Invalid ID" }); + return; + } + + const world = await World.findById(worldId); + if (!world) { + res.status(404).json({ error: "World not found" }); + return; + } + const chunk = world.chunks.id(chunkId); + if (!chunk) { + res.status(404).json({ error: "Chunk not found" }); + return; + } + if (chunk.fileId === null) { + res.status(404).json({ error: "Chunk is currently empty" }); + return; + } + const chunkFile = await GridFile.findById(chunk.chunkFile); + if (!chunkFile) { + res.status(404).json({ error: "Chunk file not found" }); + return; + } + + res.header("Content-Type", chunkFile.contentType); + chunkFile.downloadStream(res); + } +); + +/* POST /api/worlds */ +worldsRouter.post("/", isAuthenticated, async (req, res) => { + /* req.body should be: + { + name: string, + chunkSize: { x: number, y: number, z: number }, + description: string, + rules: string, + chunks: [{ x: number, z: number }] + } + */ + // Check for admin permissions + const user = await User.findById(req.session.userId); + if (!user.isAdmin) { + res + .status(403) + .json({ error: "You do not have permission to add a world" }); + return; + } + if ( + !req.body.name || + !req.body.chunkSize || + !req.body.description || + !req.body.rules || + !req.body.chunks + ) { + res.status(400).json({ error: "Missing required fields" }); + return; + } + const chunkSize = req.body.chunkSize; + if (chunkSize.x <= 0 || chunkSize.y <= 0 || chunkSize.z <= 0) { + res.status(400).json({ error: "Invalid chunk size" }); + return; + } + if (req.body.chunks === 0) { + res.status(400).json({ error: "No chunks provided" }); + return; + } + const chunks = req.body.chunks.map((c) => { + return { location: { x: c.x, z: c.z } }; + }); + + const world = new World({ + name: req.body.name, + chunkSize: req.body.chunkSize, + description: req.body.description, + rules: req.body.rules, + chunks, + }); + + try { + await world.save(); + } catch (err) { + if (err.message === "Chunks overlap") { + res.status(400).json({ error: err.message }); + return; + } + } + res.json(world); +}); + +/* PATCH /api/worlds/:worldId/chunks/:chunkId */ +worldsRouter.patch( + "/:worldId/chunks/:chunkId", + isAuthenticated, + async (req, res) => { + /* an endpoint for a user to claim a chunk */ + + const { worldId, chunkId } = req.params; + const userId = req.session.userId; + if (!validateIds([worldId, chunkId])) { + res.status(400).json({ error: "Invalid ID" }); + return; + } + + const user = await User.findById(userId); + if (!user) { + res.status(404).json({ error: "User not found" }); + return; + } + const world = await World.findById(worldId); + if (!world) { + res.status(404).json({ error: "World not found" }); + return; + } + const chunk = world.chunks.id(chunkId); + if (!chunk) { + res.status(404).json({ error: "Chunk not found" }); + return; + } + if (chunk.claimedBy !== null) { + res.status(400).json({ error: "Chunk already claimed" }); + return; + } + + user.claims.push({ world: worldId, chunk: chunkId }); + chunk.claimedBy = userId; + + await world.save(); + await user.save(); + + // Update the live world if it exists + const liveWorld = shareBackend.connect().get("live_worlds", worldId); + liveWorld.fetch((err) => { + if (err) { + return; + } + if (liveWorld.type) { + const chunkIndex = liveWorld.data.chunks.findIndex( + (c) => + c.location.x === chunk.location.x && + c.location.z === chunk.location.z + ); + liveWorld.submitOp([ + { + p: ["chunks", chunkIndex, "claimedBy"], + oi: userId, + }, + ]); + } + }); + + res.json({ + message: "Chunk claimed", + }); + } +); + +/* POST /api/worlds/:worldId/chunks/:chunkId/file */ +worldsRouter.post( + "/:worldId/chunks/:chunkId/file", + isAuthenticated, + upload.single("chunkFile"), + async (req, res) => { + /* an endpoint for user to upload a chunk file */ + const { worldId, chunkId } = req.params; + const userId = req.session.userId; + const chunkFile = req.file; + if (!chunkFile) { + res.status(400).json({ error: "No file provided" }); + return; + } + try { + await validateGltfZip(chunkFile.path); + } catch (err) { + deleteFile(chunkFile.path); + res.status(400).json({ error: err.message }); + return; + } + + if (!validateIds([worldId, chunkId])) { + res.status(400).json({ error: "Invalid ID" }); + deleteFile(chunkFile.path); + return; + } + + const user = await User.findById(userId); + if (!user) { + res.status(404).json({ error: "User not found" }); + deleteFile(chunkFile.path); + return; + } + const world = await World.findById(worldId); + if (!world) { + res.status(404).json({ error: "World not found" }); + deleteFile(chunkFile.path); + return; + } + const chunk = world.chunks.id(chunkId); + if (!chunk) { + res.status(404).json({ error: "Chunk not found" }); + deleteFile(chunkFile.path); + return; + } + if (!chunk.claimedBy || chunk.claimedBy.toString() !== userId) { + res + .status(403) + .json({ error: `This chunk is not claimed by the user ${userId}` }); + deleteFile(chunkFile.path); + return; + } + + // Upload the file to MongoDB and delete from /uploads + const fileStream = fs.createReadStream(chunkFile.path); + const gridFile = new GridFile({ + filename: chunkFile.originalname, + contentType: chunkFile.mimetype, + metadata: { + world: worldId, + chunk: chunkId, + }, + }); + const uploadedChunk = await gridFile.upload(fileStream); + deleteFile(chunkFile.path); + + // If there is already a file, delete it + if (chunk.file !== null) { + const oldFile = await GridFile.findById(chunk.chunkFile); + if (oldFile) { + await GridFile.deleteOne({ _id: oldFile._id }); + } + } + chunk.chunkFile = uploadedChunk.id; + await world.save(); + + // Update the live world if it exists + const liveWorld = shareBackend.connect().get("live_worlds", worldId); + liveWorld.fetch((err) => { + if (err) { + return; + } + if (liveWorld.type) { + const chunkIndex = liveWorld.data.chunks.findIndex( + (c) => + c.location.x === chunk.location.x && + c.location.z === chunk.location.z + ); + if (chunkIndex !== -1) { + liveWorld.submitOp([ + { + p: ["chunks", chunkIndex, "chunkFile"], + oi: uploadedChunk.id, + }, + ]); + } + } + }); + + res.json({ + message: "Chunk file uploaded", + chunk: chunk, + }); + } +); + +/* WS /api/worlds/:worldId/live */ +worldsRouter.ws("/:worldId/live", isWsAuthenticated, async (ws, req) => { + if (!validateIds([req.params.worldId])) { + ws.close(4000, "Invalid world ID"); + return; + } + const world = await World.findById(req.params.worldId); + if (!world) { + ws.close(4004, "World not found"); + return; + } + const connection = shareBackend.connect(); + const liveWorld = connection.get("live_worlds", req.params.worldId); + + // Create live world if it doesn't exist + liveWorld.subscribe((err) => { + if (err) { + ws.close(1011, "Error fetching live world"); + return; + } + if (liveWorld.type === null) { + const data = { + chunks: world.chunks, + }; + liveWorld.create(data, "json0"); + } + }); + + const stream = new WebSocketJSONStream(ws); + stream.on("error", (err) => { + if (err.name !== "Error [ERR_CLOSED]") { + console.error(err); + } + }); + shareBackend.listen(stream); + + // listen to live world changes and update mongoDB + liveWorld.on("op", (ops, source) => { + if (source) { + return; + } + const chunkIndex = ops[0].p[1]; + if (ops[0].p[2] === "upvotes" || ops[0].p[2] === "downvotes") { + const chunkId = liveWorld.data.chunks[chunkIndex]._id; + const chunk = world.chunks.id(chunkId); + chunk[ops[0].p[2]] += ops[0].na ? ops[0].na : 0; + world.save(); + } + }); +}); diff --git a/backend/socketio/notifications.js b/backend/socketio/notifications.js new file mode 100644 index 00000000..fa268bcb --- /dev/null +++ b/backend/socketio/notifications.js @@ -0,0 +1,81 @@ +import { Server } from "socket.io"; +import { Redis } from "ioredis"; + +import { config } from "../config.js"; +import { isSocketAuthenticated } from "../middleware/auth.js"; + +let io; +let redisClient; +try { + redisClient = new Redis({ + port: 6379, + host: config.redisURI, + }); +} catch (err) { + console.log(err); +} + +const wrap = (middleware) => (socket, next) => + middleware(socket.request, {}, next); + +export const initSocketIOFromServer = ( + server, + sessionMiddleware, + corsOptions +) => { + io = new Server(server, { + cors: corsOptions, + }); + io.use(wrap(sessionMiddleware)); + io.use(isSocketAuthenticated); + + console.log("SocketIO initialized"); + + io.on("connection", (socket) => { + console.log("SocketIO connected"); + initializeUser(socket); + + socket.on("disconnect", () => onDisconnect(socket)); + }); +}; + +export const closeNotification = () => { + redisClient.quit(); + io.close(); +}; + +export const sendNotification = async (receiver, notification) => { + const receiverStatus = await redisClient.hget(`userId:${receiver}`, "online"); + if (receiverStatus === "false") { + redisClient.hincrby(`userId:${receiver}`, `unotifiedReviews`, 1); + } else { + io.to(receiver).emit("notification", notification); + } +}; + +const initializeUser = async (socket) => { + socket.user = { + sub: socket.request.session.sub, + displayName: socket.request.session.displayName, + userId: socket.request.session.userId, + }; + socket.join(socket.user.userId); + + const status = await redisClient.hgetall(`userId:${socket.user.userId}`); + + redisClient.hmset(`userId:${socket.user.userId}`, { + online: true, + unotifiedReviews: 0, + }); + + if (status) { + socket.emit("notification", { + unseen: +status.unotifiedReviews, + }); + } +}; + +const onDisconnect = (socket) => { + console.log("SocketIO disconnected"); + redisClient.hset(`userId:${socket.user.userId}`, "online", false); +}; diff --git a/config/proxy.conf b/config/proxy.conf new file mode 100644 index 00000000..2a497851 --- /dev/null +++ b/config/proxy.conf @@ -0,0 +1,5 @@ +client_max_body_size 100M; +proxy_read_timeout 600; +proxy_connect_timeout 600; +proxy_send_timeout 600; +send_timeout 600; diff --git a/docker-compose.yml.bak b/docker-compose.yml.bak new file mode 100644 index 00000000..ac415619 --- /dev/null +++ b/docker-compose.yml.bak @@ -0,0 +1,75 @@ +version: "3.8" +services: + nginx-proxy: + image: jwilder/nginx-proxy + container_name: nginx-proxy + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - ./config/proxy.conf:/etc/nginx/conf.d/proxy.conf:ro + - ./certs:/etc/nginx/certs + - ./vhost:/etc/nginx/vhost.d + - ./html:/usr/share/nginx/html + nginx-proxy-acme: + image: nginxproxy/acme-companion + container_name: nginx-proxy-acme + volumes_from: + - nginx-proxy + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - ./acme:/etc/acme.sh + environment: + - DEFAULT_EMAIL= + depends_on: + - nginx-proxy + frontend: + container_name: frontend + build: + context: ./3dworld + dockerfile: Dockerfile + expose: + - 80 + volumes: + - ./3dworld:/usr/src/app + environment: + - VIRTUAL_HOST=buildverse.live + - LETSENCRYPT_HOST=buildverse.live + depends_on: + - nginx-proxy-acme + backend: + container_name: backend + build: + context: ./backend + dockerfile: Dockerfile + expose: + - 3000 + volumes: + - ./backend:/usr/src/app + depends_on: + - nginx-proxy-acme + - mongodb + - redis + environment: + - VIRTUAL_HOST= + - LETSENCRYPT_HOST= + - MONGO_URI=mongodb://:@mongodb:27017 # same as mongodb env username and password + - MONGO_DB_NAME= + - REDIS_URI=redis + - ADMIN_SUB=admin| + - FRONTEND_BASE_URL= + - SESSION_SECRET= + - SEND_GRID_API_KEY= + mongodb: + container_name: mongodb + image: mongo + ports: + - 27017:27017 + environment: + - MONGO_INITDB_ROOT_USERNAME= + - MONGO_INITDB_ROOT_PASSWORD= + - MONGO_INITDB_DATABASE= + redis: + container_name: redis + image: redis