diff --git a/.github/workflows/deploy_api.yml b/.github/workflows/deploy_api.yml new file mode 100644 index 0000000..79c336e --- /dev/null +++ b/.github/workflows/deploy_api.yml @@ -0,0 +1,58 @@ +name: Deploy API + +on: + push: + branches: ['main'] + paths: ['api/**'] + +env: + REGISTRY: ghcr.io + +jobs: + build-and-push: + name: Build Docker image and push to GitHub Container Registry + runs-on: ubuntu-latest + + defaults: + run: + working-directory: api + + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v3 + - uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/metadata-action@v4 + id: meta + with: + images: ${{ env.REGISTRY }}/${{ github.repository }}/api + - uses: docker/build-push-action@v4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + deploy: + needs: [build-and-push] + name: Deploy to EC2 + runs-on: ubuntu-latest + + steps: + - uses: appleboy/ssh-action@master + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} + key: ${{ secrets.EC2_SSH_KEY }} + script: | + docker login ${{ env.REGISTRY }} -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + docker pull ${{ env.REGISTRY }}/${{ github.repository }}/api:latest + docker stop crabfit-api + docker rm crabfit-api + docker run -d -p 3000:3000 --name crabfit-api --env-file ./.env ${{ env.REGISTRY }}/${{ github.repository }}/api:latest diff --git a/.github/workflows/deploy_backend.yml b/.github/workflows/deploy_backend.yml deleted file mode 100644 index 951c2e2..0000000 --- a/.github/workflows/deploy_backend.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Deploy Backend - -on: - push: - branches: ['main'] - paths: ['crabfit-backend/**'] - -jobs: - deploy: - runs-on: ubuntu-latest - - defaults: - run: - working-directory: crabfit-backend - - permissions: - contents: read - id-token: write - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 17 - cache: yarn - cache-dependency-path: '**/yarn.lock' - - run: yarn install --immutable - - run: yarn build - - id: auth - uses: google-github-actions/auth@v0 - with: - credentials_json: '${{ secrets.GCP_SA_KEY }}' - - id: deploy - uses: google-github-actions/deploy-appengine@v0 - with: - working_directory: crabfit-backend - version: v1 diff --git a/.github/workflows/deploy_frontend.yml b/.github/workflows/deploy_frontend.yml index 6ba43c7..e495b49 100644 --- a/.github/workflows/deploy_frontend.yml +++ b/.github/workflows/deploy_frontend.yml @@ -3,7 +3,7 @@ name: Deploy Frontend on: push: branches: ['main'] - paths: ['crabfit-frontend/**'] + paths: ['frontend/**'] jobs: deploy: @@ -11,7 +11,7 @@ jobs: defaults: run: - working-directory: crabfit-frontend + working-directory: frontend permissions: contents: read @@ -33,5 +33,5 @@ jobs: - id: deploy uses: google-github-actions/deploy-appengine@v0 with: - working_directory: crabfit-frontend + working_directory: frontend version: v1 diff --git a/.gitignore b/.gitignore index 6e56161..cfc9619 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /graphics .DS_Store -/crabfit-browser-extension/*.zip diff --git a/README.md b/README.md index 1b44745..8ba0b35 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ Align your schedules to find the perfect time that works for everyone. Licensed under the GNU GPLv3. -Crab Fit - Use your availability to find a time that works for everyone | Product Hunt - ## Contributing ### ⭐️ Bugs or feature requests @@ -15,16 +13,19 @@ If you find any bugs or have a feature request, please create an issue by **Note** +> `memory-adaptor` is the default if no features are specified. Ensure you specify a different adaptor when deploying. + +### Adding an adaptor + +See [adding an adaptor](adaptors/README.md#adding-an-adaptor) in the adaptors readme. + +## Environment + +### CORS + +In release mode, a `FRONTEND_URL` environment variable is required to correctly restrict cross-origin requests to the frontend. + +### Cleanup task + +By default, anyone can run the cleanup task at `/tasks/cleanup`. This is usually not an issue, as it's based on when the events were last visited, and not when it's run, but if you'd prefer to restrict runs of the cleanup task (as it can be intensive), set a `CRON_KEY` environment variable in `.env`. This will require sending an `X-Cron-Key` header to the route with a value that matches `CRON_KEY`, or the route will return a 401 Unauthorized error. diff --git a/api/adaptors/README.md b/api/adaptors/README.md new file mode 100644 index 0000000..f8e7f1b --- /dev/null +++ b/api/adaptors/README.md @@ -0,0 +1,22 @@ +# Crab Fit Storage Adaptors + +This directory contains sub-crates that connect Crab Fit to a database of some sort. For a list of available adaptors, see the [api readme](../README.md). + +## Adding an adaptor + +The suggested flow is copying an existing adaptor, such as `memory`, and altering the code to work with your chosen database. + +Note, you will need to have the following crates as dependencies in your adaptor: + +- `common`
Includes a trait for implementing your adaptor, as well as structs your adaptor needs to return. +- `async-trait`
Required because the trait from `common` uses async functions, make sure you include `#[async_trait]` above your trait implementation. +- `chrono`
Required to deal with dates in the common structs and trait function signatures. + +Once you've created the adaptor, you'll need to make sure it's included as a dependency in the root [`Cargo.toml`](../Cargo.toml), and add a feature flag with the same name. Make sure you also document the new adaptor in the [api readme](../README.md). + +Finally, add a new version of the `create_adaptor` function in the [`adaptors.rs`](../src/adaptors.rs) file that will only compile if the specific feature flag you added is set. Don't forget to add a `not` version of the feature to the default memory adaptor function at the bottom of the file. + +## FAQ + +Why is it spelt "adaptor" and not "adapter"? +> The maintainer lives in Australia, where it's usually spelt "adaptor" 😎 diff --git a/api/adaptors/datastore/Cargo.toml b/api/adaptors/datastore/Cargo.toml new file mode 100644 index 0000000..da37e8c --- /dev/null +++ b/api/adaptors/datastore/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "datastore-adaptor" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = "0.1.68" +chrono = "0.4.24" +common = { path = "../../common" } +# Uses custom version of google-cloud that has support for NULL values +google-cloud = { git = "https://github.com/GRA0007/google-cloud-rs.git", features = ["datastore", "derive"] } +serde = "1.0.163" +serde_json = "1.0.96" +tokio = { version = "1.28.1", features = ["rt-multi-thread"] } diff --git a/api/adaptors/datastore/README.md b/api/adaptors/datastore/README.md new file mode 100644 index 0000000..ca3a3d6 --- /dev/null +++ b/api/adaptors/datastore/README.md @@ -0,0 +1,13 @@ +# Google Datastore Adaptor + +This adaptor works with [Google Cloud Datastore](https://cloud.google.com/datastore). Please note that it's compatible with Firestore in Datastore mode, but not with Firestore. + +## Environment + +To use this adaptor, make sure you have the `GCP_CREDENTIALS` environment variable set to your service account credentials in JSON format. See [this page](https://developers.google.com/workspace/guides/create-credentials#service-account) for info on setting up a service account and generating credentials. + +Example: + +```env +GCP_CREDENTIALS='{"type":"service_account","project_id":"my-project"}' +``` diff --git a/api/adaptors/datastore/src/lib.rs b/api/adaptors/datastore/src/lib.rs new file mode 100644 index 0000000..dc38e1b --- /dev/null +++ b/api/adaptors/datastore/src/lib.rs @@ -0,0 +1,328 @@ +use std::{env, error::Error, fmt::Display}; + +use async_trait::async_trait; +use chrono::{DateTime, NaiveDateTime, Utc}; +use common::{Adaptor, Event, Person, Stats}; +use google_cloud::{ + authorize::ApplicationCredentials, + datastore::{Client, Filter, FromValue, IntoValue, Key, KeyID, Query}, +}; +use tokio::sync::Mutex; + +pub struct DatastoreAdaptor { + client: Mutex, +} + +// Keys +const STATS_KIND: &str = "Stats"; +const EVENT_KIND: &str = "Event"; +const PERSON_KIND: &str = "Person"; +const STATS_EVENTS_ID: &str = "eventCount"; +const STATS_PEOPLE_ID: &str = "personCount"; + +#[async_trait] +impl Adaptor for DatastoreAdaptor { + type Error = DatastoreAdaptorError; + + async fn get_stats(&self) -> Result { + let mut client = self.client.lock().await; + + let event_key = Key::new(STATS_KIND).id(STATS_EVENTS_ID); + let event_stats: DatastoreStats = client.get(event_key).await?.unwrap_or_default(); + + let person_key = Key::new(STATS_KIND).id(STATS_PEOPLE_ID); + let person_stats: DatastoreStats = client.get(person_key).await?.unwrap_or_default(); + + Ok(Stats { + event_count: event_stats.value, + person_count: person_stats.value, + }) + } + + async fn increment_stat_event_count(&self) -> Result { + let mut client = self.client.lock().await; + + let key = Key::new(STATS_KIND).id(STATS_EVENTS_ID); + let mut event_stats: DatastoreStats = client.get(key.clone()).await?.unwrap_or_default(); + + event_stats.value += 1; + client.put((key, event_stats.clone())).await?; + Ok(event_stats.value) + } + + async fn increment_stat_person_count(&self) -> Result { + let mut client = self.client.lock().await; + + let key = Key::new(STATS_KIND).id(STATS_PEOPLE_ID); + let mut person_stats: DatastoreStats = client.get(key.clone()).await?.unwrap_or_default(); + + person_stats.value += 1; + client.put((key, person_stats.clone())).await?; + Ok(person_stats.value) + } + + async fn get_people(&self, event_id: String) -> Result>, Self::Error> { + let mut client = self.client.lock().await; + + // Check the event exists + if client + .get::(Key::new(EVENT_KIND).id(event_id.clone())) + .await? + .is_none() + { + return Ok(None); + } + + Ok(Some( + client + .query( + Query::new(PERSON_KIND) + .filter(Filter::Equal("eventId".into(), event_id.into_value())), + ) + .await? + .into_iter() + .filter_map(|entity| { + DatastorePerson::from_value(entity.properties().clone()) + .ok() + .map(|ds_person| ds_person.into()) + }) + .collect(), + )) + } + + async fn upsert_person( + &self, + event_id: String, + person: Person, + ) -> Result, Self::Error> { + let mut client = self.client.lock().await; + + // Check the event exists + if client + .get::(Key::new(EVENT_KIND).id(event_id.clone())) + .await? + .is_none() + { + return Ok(None); + } + + // Check if person exists + let existing_person = client + .query( + Query::new(PERSON_KIND) + .filter(Filter::Equal( + "eventId".into(), + event_id.clone().into_value(), + )) + .filter(Filter::Equal( + "name".into(), + person.name.clone().into_value(), + )), + ) + .await?; + + let mut key = Key::new(PERSON_KIND); + if let Some(entity) = existing_person.first() { + key = entity.key().clone(); + } + + client + .put((key, DatastorePerson::from_person(person.clone(), event_id))) + .await?; + + Ok(Some(person)) + } + + async fn get_event(&self, id: String) -> Result, Self::Error> { + let mut client = self.client.lock().await; + + let key = Key::new(EVENT_KIND).id(id.clone()); + let existing_event = client.get::(key.clone()).await?; + + // Mark as visited if it exists + if let Some(mut event) = existing_event.clone() { + event.visited = Utc::now().timestamp(); + client.put((key, event)).await?; + } + + Ok(existing_event.map(|e| e.to_event(id))) + } + + async fn create_event(&self, event: Event) -> Result { + let mut client = self.client.lock().await; + + let key = Key::new(EVENT_KIND).id(event.id.clone()); + + let ds_event: DatastoreEvent = event.clone().into(); + client.put((key, ds_event)).await?; + + Ok(event) + } + + async fn delete_events(&self, cutoff: DateTime) -> Result { + let mut client = self.client.lock().await; + + let mut keys_to_delete: Vec = client + .query(Query::new(EVENT_KIND).filter(Filter::LesserThan( + "visited".into(), + cutoff.timestamp().into_value(), + ))) + .await? + .iter() + .map(|entity| entity.key().clone()) + .collect(); + + let event_count = keys_to_delete.len() as i64; + + let events_to_delete = keys_to_delete.clone(); + for e in events_to_delete.iter() { + if let KeyID::StringID(id) = e.get_id() { + let mut event_people_to_delete: Vec = client + .query( + Query::new(PERSON_KIND) + .filter(Filter::Equal("eventId".into(), id.clone().into_value())), + ) + .await? + .iter() + .map(|entity| entity.key().clone()) + .collect(); + keys_to_delete.append(&mut event_people_to_delete); + } + } + + let person_count = keys_to_delete.len() as i64 - event_count; + + client.delete_all(keys_to_delete).await?; + + Ok(Stats { + event_count, + person_count, + }) + } +} + +impl DatastoreAdaptor { + pub async fn new() -> Self { + // Load credentials + let credentials: ApplicationCredentials = serde_json::from_str( + &env::var("GCP_CREDENTIALS").expect("Expected GCP_CREDENTIALS environment variable"), + ) + .expect("GCP_CREDENTIALS environment variable is not valid JSON"); + + // Connect to datastore + let client = Client::from_credentials(credentials.project_id.clone(), credentials.clone()) + .await + .expect("Failed to setup datastore client"); + let client = Mutex::new(client); + + println!( + "🎛️ Connected to datastore in project {}", + credentials.project_id + ); + + Self { client } + } +} + +#[derive(FromValue, IntoValue, Default, Clone)] +struct DatastoreStats { + value: i64, +} + +#[derive(FromValue, IntoValue, Clone)] +struct DatastoreEvent { + name: String, + created: i64, + visited: i64, + times: Vec, + timezone: String, +} + +#[derive(FromValue, IntoValue)] +#[allow(non_snake_case)] +struct DatastorePerson { + name: String, + password: Option, + created: i64, + eventId: String, + availability: Vec, +} + +impl From for Person { + fn from(value: DatastorePerson) -> Self { + Self { + name: value.name, + password_hash: value.password, + created_at: unix_to_date(value.created), + availability: value.availability, + } + } +} + +impl DatastorePerson { + fn from_person(person: Person, event_id: String) -> Self { + Self { + name: person.name, + password: person.password_hash, + created: person.created_at.timestamp(), + eventId: event_id, + availability: person.availability, + } + } +} + +impl From for DatastoreEvent { + fn from(value: Event) -> Self { + Self { + name: value.name, + created: value.created_at.timestamp(), + visited: value.visited_at.timestamp(), + times: value.times, + timezone: value.timezone, + } + } +} + +impl DatastoreEvent { + fn to_event(&self, event_id: String) -> Event { + Event { + id: event_id, + name: self.name.clone(), + created_at: unix_to_date(self.created), + visited_at: unix_to_date(self.visited), + times: self.times.clone(), + timezone: self.timezone.clone(), + } + } +} + +fn unix_to_date(unix: i64) -> DateTime { + DateTime::from_utc(NaiveDateTime::from_timestamp_opt(unix, 0).unwrap(), Utc) +} + +#[derive(Debug)] +pub enum DatastoreAdaptorError { + DatastoreError(google_cloud::error::Error), +} + +impl Display for DatastoreAdaptorError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + DatastoreAdaptorError::DatastoreError(e) => write!(f, "Datastore Error: {}", e), + } + } +} + +impl Error for DatastoreAdaptorError {} + +impl From for DatastoreAdaptorError { + fn from(value: google_cloud::error::Error) -> Self { + Self::DatastoreError(value) + } +} + +impl From for DatastoreAdaptorError { + fn from(value: google_cloud::error::ConvertError) -> Self { + Self::DatastoreError(google_cloud::error::Error::Convert(value)) + } +} diff --git a/api/adaptors/memory/Cargo.toml b/api/adaptors/memory/Cargo.toml new file mode 100644 index 0000000..b5280ca --- /dev/null +++ b/api/adaptors/memory/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "memory-adaptor" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = "0.1.68" +chrono = "0.4.24" +common = { path = "../../common" } +tokio = { version = "1.28.1", features = ["rt-multi-thread"] } diff --git a/api/adaptors/memory/README.md b/api/adaptors/memory/README.md new file mode 100644 index 0000000..c7a43e4 --- /dev/null +++ b/api/adaptors/memory/README.md @@ -0,0 +1,6 @@ +# Memory Adaptor + +This adaptor stores everything in memory, and all data is lost when the API is stopped. Useful for testing. + +> **Warning** +> Do not use this adaptor in production! diff --git a/api/adaptors/memory/src/lib.rs b/api/adaptors/memory/src/lib.rs new file mode 100644 index 0000000..2881696 --- /dev/null +++ b/api/adaptors/memory/src/lib.rs @@ -0,0 +1,167 @@ +use std::{collections::HashMap, error::Error, fmt::Display}; + +use async_trait::async_trait; +use chrono::{DateTime, Utc}; +use common::{Adaptor, Event, Person, Stats}; +use tokio::sync::Mutex; + +struct State { + stats: Stats, + events: HashMap, + people: HashMap<(String, String), Person>, +} + +pub struct MemoryAdaptor { + state: Mutex, +} + +#[async_trait] +impl Adaptor for MemoryAdaptor { + type Error = MemoryAdaptorError; + + async fn get_stats(&self) -> Result { + let state = self.state.lock().await; + + Ok(state.stats.clone()) + } + + async fn increment_stat_event_count(&self) -> Result { + let mut state = self.state.lock().await; + + state.stats.event_count += 1; + Ok(state.stats.event_count) + } + + async fn increment_stat_person_count(&self) -> Result { + let mut state = self.state.lock().await; + + state.stats.person_count += 1; + Ok(state.stats.person_count) + } + + async fn get_people(&self, event_id: String) -> Result>, Self::Error> { + let state = self.state.lock().await; + + // Event doesn't exist + if state.events.get(&event_id).is_none() { + return Ok(None); + } + + Ok(Some( + state + .people + .clone() + .into_iter() + .filter_map(|((p_event_id, _), p)| { + if p_event_id == event_id { + Some(p) + } else { + None + } + }) + .collect(), + )) + } + + async fn upsert_person( + &self, + event_id: String, + person: Person, + ) -> Result, Self::Error> { + let mut state = self.state.lock().await; + + // Check event exists + if state.events.get(&event_id).is_none() { + return Ok(None); + } + + state + .people + .insert((event_id, person.name.clone()), person.clone()); + + Ok(Some(person)) + } + + async fn get_event(&self, id: String) -> Result, Self::Error> { + let mut state = self.state.lock().await; + + let event = state.events.get(&id).cloned(); + if let Some(mut event) = event.clone() { + event.visited_at = Utc::now(); + state.events.insert(id, event); + } + + Ok(event) + } + + async fn create_event(&self, event: Event) -> Result { + let mut state = self.state.lock().await; + + state.events.insert(event.id.clone(), event.clone()); + + Ok(event) + } + + async fn delete_events(&self, cutoff: DateTime) -> Result { + let mut state = self.state.lock().await; + + // Delete events older than cutoff date + let mut deleted_event_ids: Vec = Vec::new(); + state.events = state + .events + .clone() + .into_iter() + .filter(|(id, event)| { + if event.visited_at >= cutoff { + true + } else { + deleted_event_ids.push(id.into()); + false + } + }) + .collect(); + + let mut person_count = state.people.len() as i64; + state.people = state + .people + .clone() + .into_iter() + .filter(|((event_id, _), _)| deleted_event_ids.contains(event_id)) + .collect(); + person_count -= state.people.len() as i64; + + Ok(Stats { + event_count: deleted_event_ids.len() as i64, + person_count, + }) + } +} + +impl MemoryAdaptor { + pub async fn new() -> Self { + println!("🧠 Using in-memory storage"); + println!("🚨 WARNING: All data will be lost when the process ends. Make sure you choose a database adaptor before deploying."); + + let state = Mutex::new(State { + stats: Stats { + event_count: 0, + person_count: 0, + }, + events: HashMap::new(), + people: HashMap::new(), + }); + + Self { state } + } +} + +#[derive(Debug)] +pub enum MemoryAdaptorError {} + +impl Display for MemoryAdaptorError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Memory adaptor error") + } +} + +impl Error for MemoryAdaptorError {} diff --git a/api/adaptors/sql/Cargo.toml b/api/adaptors/sql/Cargo.toml new file mode 100644 index 0000000..b56724a --- /dev/null +++ b/api/adaptors/sql/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sql-adaptor" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = "0.1.68" +common = { path = "../../common" } +sea-orm = { version = "0.11.3", features = [ "macros", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", "runtime-tokio-native-tls" ] } +serde = { version = "1.0.162", features = [ "derive" ] } +async-std = { version = "1", features = ["attributes", "tokio1"] } +sea-orm-migration = "0.11.0" +serde_json = "1.0.96" +chrono = "0.4.24" diff --git a/api/adaptors/sql/README.md b/api/adaptors/sql/README.md new file mode 100644 index 0000000..0fcb334 --- /dev/null +++ b/api/adaptors/sql/README.md @@ -0,0 +1,13 @@ +# SQL Adaptor + +This adaptor works with [Postgres](https://www.postgresql.org/), [MySQL](https://www.mysql.com/) or [SQLite](https://sqlite.org/index.html) databases. + +## Environment + +To use this adaptor, make sure you have the `DATABASE_URL` environment variable set to the database url for your chosen database. + +Example: + +```env +DATABASE_URL="postgresql://username:password@localhost:5432/crabfit" +``` diff --git a/api/adaptors/sql/src/entity/event.rs b/api/adaptors/sql/src/entity/event.rs new file mode 100644 index 0000000..72b03e9 --- /dev/null +++ b/api/adaptors/sql/src/entity/event.rs @@ -0,0 +1,29 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "event")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + pub name: String, + pub created_at: DateTime, + pub visited_at: DateTime, + pub times: Json, + pub timezone: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::person::Entity")] + Person, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Person.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/api/adaptors/sql/src/entity/mod.rs b/api/adaptors/sql/src/entity/mod.rs new file mode 100644 index 0000000..f5e4734 --- /dev/null +++ b/api/adaptors/sql/src/entity/mod.rs @@ -0,0 +1,7 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +pub mod prelude; + +pub mod event; +pub mod person; +pub mod stats; diff --git a/api/adaptors/sql/src/entity/person.rs b/api/adaptors/sql/src/entity/person.rs new file mode 100644 index 0000000..01f9a37 --- /dev/null +++ b/api/adaptors/sql/src/entity/person.rs @@ -0,0 +1,35 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "person")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub name: String, + pub password_hash: Option, + pub created_at: DateTime, + pub availability: Json, + #[sea_orm(primary_key, auto_increment = false)] + pub event_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::event::Entity", + from = "Column::EventId", + to = "super::event::Column::Id", + on_update = "Cascade", + on_delete = "Cascade" + )] + Event, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Event.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/api/adaptors/sql/src/entity/prelude.rs b/api/adaptors/sql/src/entity/prelude.rs new file mode 100644 index 0000000..5854e6b --- /dev/null +++ b/api/adaptors/sql/src/entity/prelude.rs @@ -0,0 +1,5 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +pub use super::event::Entity as Event; +pub use super::person::Entity as Person; +pub use super::stats::Entity as Stats; diff --git a/api/adaptors/sql/src/entity/stats.rs b/api/adaptors/sql/src/entity/stats.rs new file mode 100644 index 0000000..6485ff8 --- /dev/null +++ b/api/adaptors/sql/src/entity/stats.rs @@ -0,0 +1,17 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "stats")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub event_count: i32, + pub person_count: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/api/adaptors/sql/src/lib.rs b/api/adaptors/sql/src/lib.rs new file mode 100644 index 0000000..8a706f3 --- /dev/null +++ b/api/adaptors/sql/src/lib.rs @@ -0,0 +1,253 @@ +use std::{env, error::Error}; + +use async_trait::async_trait; +use chrono::{DateTime, Utc}; +use common::{Adaptor, Event, Person, Stats}; +use entity::{event, person, stats}; +use migration::{Migrator, MigratorTrait}; +use sea_orm::{ + strum::Display, + ActiveModelTrait, + ActiveValue::{NotSet, Set}, + ColumnTrait, Database, DatabaseConnection, DbErr, EntityTrait, ModelTrait, QueryFilter, + TransactionError, TransactionTrait, TryIntoModel, +}; +use serde_json::json; + +mod entity; +mod migration; + +pub struct SqlAdaptor { + db: DatabaseConnection, +} + +#[async_trait] +impl Adaptor for SqlAdaptor { + type Error = SqlAdaptorError; + + async fn get_stats(&self) -> Result { + let stats_row = get_stats_row(&self.db).await?; + Ok(Stats { + event_count: stats_row.event_count.unwrap() as i64, + person_count: stats_row.person_count.unwrap() as i64, + }) + } + + async fn increment_stat_event_count(&self) -> Result { + let mut current_stats = get_stats_row(&self.db).await?; + current_stats.event_count = Set(current_stats.event_count.unwrap() + 1); + + Ok(current_stats.save(&self.db).await?.event_count.unwrap() as i64) + } + + async fn increment_stat_person_count(&self) -> Result { + let mut current_stats = get_stats_row(&self.db).await?; + current_stats.person_count = Set(current_stats.person_count.unwrap() + 1); + + Ok(current_stats.save(&self.db).await?.person_count.unwrap() as i64) + } + + async fn get_people(&self, event_id: String) -> Result>, Self::Error> { + // TODO: optimize into one query + let event_row = event::Entity::find_by_id(event_id).one(&self.db).await?; + + Ok(match event_row { + Some(event) => Some( + event + .find_related(person::Entity) + .all(&self.db) + .await? + .into_iter() + .map(|model| model.into()) + .collect(), + ), + None => None, + }) + } + + async fn upsert_person( + &self, + event_id: String, + person: Person, + ) -> Result, Self::Error> { + let data = person::ActiveModel { + name: Set(person.name.clone()), + password_hash: Set(person.password_hash), + created_at: Set(person.created_at.naive_utc()), + availability: Set(serde_json::to_value(person.availability).unwrap_or(json!([]))), + event_id: Set(event_id.clone()), + }; + + // Check if the event exists + if event::Entity::find_by_id(event_id.clone()) + .one(&self.db) + .await? + .is_none() + { + return Ok(None); + } + + Ok(Some( + match person::Entity::find_by_id((person.name, event_id)) + .one(&self.db) + .await? + { + Some(_) => data.update(&self.db).await?.try_into_model()?.into(), + None => data.insert(&self.db).await?.try_into_model()?.into(), + }, + )) + } + + async fn get_event(&self, id: String) -> Result, Self::Error> { + let existing_event = event::Entity::find_by_id(id).one(&self.db).await?; + + // Mark as visited + if let Some(event) = existing_event.clone() { + let mut event: event::ActiveModel = event.into(); + event.visited_at = Set(Utc::now().naive_utc()); + event.save(&self.db).await?; + } + + Ok(existing_event.map(|model| model.into())) + } + + async fn create_event(&self, event: Event) -> Result { + Ok(event::ActiveModel { + id: Set(event.id), + name: Set(event.name), + created_at: Set(event.created_at.naive_utc()), + visited_at: Set(event.visited_at.naive_utc()), + times: Set(serde_json::to_value(event.times).unwrap_or(json!([]))), + timezone: Set(event.timezone), + } + .insert(&self.db) + .await? + .try_into_model()? + .into()) + } + + async fn delete_events(&self, cutoff: DateTime) -> Result { + let (event_count, person_count) = self + .db + .transaction::<_, (i64, i64), DbErr>(|t| { + Box::pin(async move { + // Get events older than the cutoff date + let old_events = event::Entity::find() + .filter(event::Column::VisitedAt.lt(cutoff.naive_utc())) + .all(t) + .await?; + + // Delete people + let mut people_deleted: i64 = 0; + // TODO: run concurrently + for e in old_events.iter() { + let people_delete_result = person::Entity::delete_many() + .filter(person::Column::EventId.eq(&e.id)) + .exec(t) + .await?; + people_deleted += people_delete_result.rows_affected as i64; + } + + // Delete events + let event_delete_result = event::Entity::delete_many() + .filter(event::Column::VisitedAt.lt(cutoff.naive_utc())) + .exec(t) + .await?; + + Ok((event_delete_result.rows_affected as i64, people_deleted)) + }) + }) + .await?; + + Ok(Stats { + event_count, + person_count, + }) + } +} + +// Get the current stats as an ActiveModel +async fn get_stats_row(db: &DatabaseConnection) -> Result { + let current_stats = stats::Entity::find().one(db).await?; + + Ok(match current_stats { + Some(model) => model.into(), + None => stats::ActiveModel { + id: NotSet, + event_count: Set(0), + person_count: Set(0), + }, + }) +} + +impl SqlAdaptor { + pub async fn new() -> Self { + let connection_string = + env::var("DATABASE_URL").expect("Expected DATABASE_URL environment variable"); + + // Connect to the database + let db = Database::connect(&connection_string) + .await + .expect("Failed to connect to SQL database"); + println!( + "{} Connected to database at {}", + match db { + DatabaseConnection::SqlxMySqlPoolConnection(_) => "🐬", + DatabaseConnection::SqlxPostgresPoolConnection(_) => "🐘", + DatabaseConnection::SqlxSqlitePoolConnection(_) => "🪶", + DatabaseConnection::Disconnected => panic!("Failed to connect to SQL database"), + }, + connection_string + ); + + // Setup tables + Migrator::up(&db, None) + .await + .expect("Failed to set up tables in the database"); + + Self { db } + } +} + +impl From for Event { + fn from(value: event::Model) -> Self { + Self { + id: value.id, + name: value.name, + created_at: DateTime::::from_utc(value.created_at, Utc), + visited_at: DateTime::::from_utc(value.visited_at, Utc), + times: serde_json::from_value(value.times).unwrap_or(vec![]), + timezone: value.timezone, + } + } +} + +impl From for Person { + fn from(value: person::Model) -> Self { + Self { + name: value.name, + password_hash: value.password_hash, + created_at: DateTime::::from_utc(value.created_at, Utc), + availability: serde_json::from_value(value.availability).unwrap_or(vec![]), + } + } +} + +#[derive(Display, Debug)] +pub enum SqlAdaptorError { + DbErr(DbErr), + TransactionError(TransactionError), +} + +impl Error for SqlAdaptorError {} + +impl From for SqlAdaptorError { + fn from(value: DbErr) -> Self { + Self::DbErr(value) + } +} +impl From> for SqlAdaptorError { + fn from(value: TransactionError) -> Self { + Self::TransactionError(value) + } +} diff --git a/api/adaptors/sql/src/migration/m01_setup_tables.rs b/api/adaptors/sql/src/migration/m01_setup_tables.rs new file mode 100644 index 0000000..1285b8c --- /dev/null +++ b/api/adaptors/sql/src/migration/m01_setup_tables.rs @@ -0,0 +1,122 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + print!("Setting up database..."); + + // Stats table + manager + .create_table( + Table::create() + .table(Stats::Table) + .if_not_exists() + .col( + ColumnDef::new(Stats::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Stats::EventCount).integer().not_null()) + .col(ColumnDef::new(Stats::PersonCount).integer().not_null()) + .to_owned(), + ) + .await?; + + // Events table + manager + .create_table( + Table::create() + .table(Event::Table) + .if_not_exists() + .col(ColumnDef::new(Event::Id).string().not_null().primary_key()) + .col(ColumnDef::new(Event::Name).string().not_null()) + .col(ColumnDef::new(Event::CreatedAt).timestamp().not_null()) + .col(ColumnDef::new(Event::VisitedAt).timestamp().not_null()) + .col(ColumnDef::new(Event::Times).json().not_null()) + .col(ColumnDef::new(Event::Timezone).string().not_null()) + .to_owned(), + ) + .await?; + + // People table + manager + .create_table( + Table::create() + .table(Person::Table) + .if_not_exists() + .col(ColumnDef::new(Person::Name).string().not_null()) + .col(ColumnDef::new(Person::PasswordHash).string()) + .col(ColumnDef::new(Person::CreatedAt).timestamp().not_null()) + .col(ColumnDef::new(Person::Availability).json().not_null()) + .col(ColumnDef::new(Person::EventId).string().not_null()) + .primary_key(Index::create().col(Person::EventId).col(Person::Name)) + .to_owned(), + ) + .await?; + + // Relation + manager + .create_foreign_key( + ForeignKey::create() + .name("FK_person_event") + .from(Person::Table, Person::EventId) + .to(Event::Table, Event::Id) + .on_delete(ForeignKeyAction::Cascade) + .on_update(ForeignKeyAction::Cascade) + .to_owned(), + ) + .await?; + + println!(" done"); + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Stats::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(Person::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(Event::Table).to_owned()) + .await?; + + Ok(()) + } +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum Stats { + Table, + Id, + EventCount, + PersonCount, +} + +#[derive(Iden)] +enum Event { + Table, + Id, + Name, + CreatedAt, + VisitedAt, + Times, + Timezone, +} + +#[derive(Iden)] +enum Person { + Table, + Name, + PasswordHash, + CreatedAt, + Availability, + EventId, +} diff --git a/api/adaptors/sql/src/migration/mod.rs b/api/adaptors/sql/src/migration/mod.rs new file mode 100644 index 0000000..08464e8 --- /dev/null +++ b/api/adaptors/sql/src/migration/mod.rs @@ -0,0 +1,12 @@ +pub use sea_orm_migration::prelude::*; + +mod m01_setup_tables; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![Box::new(m01_setup_tables::Migration)] + } +} diff --git a/api/common/Cargo.toml b/api/common/Cargo.toml new file mode 100644 index 0000000..5f96e36 --- /dev/null +++ b/api/common/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "common" +description = "Shared structs and traits for the data storage and transfer of Crab Fit" +version = "0.1.0" +edition = "2021" + +[dependencies] +async-trait = "0.1.68" +chrono = "0.4.24" diff --git a/api/common/README.md b/api/common/README.md new file mode 100644 index 0000000..864ea8b --- /dev/null +++ b/api/common/README.md @@ -0,0 +1,3 @@ +# Common + +This crate contains the adaptor trait, and structs that are used by it. These are separated into their own crate so that the root crate and the adaptors can import from it without causing a circular dependency. diff --git a/api/common/src/lib.rs b/api/common/src/lib.rs new file mode 100644 index 0000000..5c485a4 --- /dev/null +++ b/api/common/src/lib.rs @@ -0,0 +1,54 @@ +use std::error::Error; + +use async_trait::async_trait; +use chrono::{DateTime, Utc}; + +/// Data storage adaptor, all methods on an adaptor can return an error if +/// something goes wrong, or potentially None if the data requested was not found. +#[async_trait] +pub trait Adaptor: Send + Sync { + type Error: Error; + + async fn get_stats(&self) -> Result; + async fn increment_stat_event_count(&self) -> Result; + async fn increment_stat_person_count(&self) -> Result; + + async fn get_people(&self, event_id: String) -> Result>, Self::Error>; + async fn upsert_person( + &self, + event_id: String, + person: Person, + ) -> Result, Self::Error>; + + /// Get an event and update visited date to current time + async fn get_event(&self, id: String) -> Result, Self::Error>; + async fn create_event(&self, event: Event) -> Result; + + /// Delete events older than a cutoff date, as well as any associated people + /// Returns the amount of events and people deleted + async fn delete_events(&self, cutoff: DateTime) -> Result; +} + +#[derive(Clone)] +pub struct Stats { + pub event_count: i64, + pub person_count: i64, +} + +#[derive(Clone)] +pub struct Event { + pub id: String, + pub name: String, + pub created_at: DateTime, + pub visited_at: DateTime, + pub times: Vec, + pub timezone: String, +} + +#[derive(Clone)] +pub struct Person { + pub name: String, + pub password_hash: Option, + pub created_at: DateTime, + pub availability: Vec, +} diff --git a/api/src/adaptors.rs b/api/src/adaptors.rs new file mode 100644 index 0000000..2010922 --- /dev/null +++ b/api/src/adaptors.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "sql-adaptor")] +pub async fn create_adaptor() -> sql_adaptor::SqlAdaptor { + sql_adaptor::SqlAdaptor::new().await +} + +#[cfg(feature = "datastore-adaptor")] +pub async fn create_adaptor() -> datastore_adaptor::DatastoreAdaptor { + datastore_adaptor::DatastoreAdaptor::new().await +} + +#[cfg(not(feature = "sql-adaptor"))] +#[cfg(not(feature = "datastore-adaptor"))] +pub async fn create_adaptor() -> memory_adaptor::MemoryAdaptor { + memory_adaptor::MemoryAdaptor::new().await +} diff --git a/api/src/docs.rs b/api/src/docs.rs new file mode 100644 index 0000000..34710a0 --- /dev/null +++ b/api/src/docs.rs @@ -0,0 +1,60 @@ +use crate::payloads; +use crate::routes; + +use utoipa::openapi::security::ApiKey; +use utoipa::openapi::security::ApiKeyValue; +use utoipa::{ + openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme}, + Modify, OpenApi, +}; + +// OpenAPI documentation +#[derive(OpenApi)] +#[openapi( + info(title = "Crab Fit API"), + paths( + routes::stats::get_stats, + routes::event::create_event, + routes::event::get_event, + routes::person::get_people, + routes::person::get_person, + routes::person::update_person, + routes::tasks::cleanup, + ), + components(schemas( + payloads::StatsResponse, + payloads::EventResponse, + payloads::PersonResponse, + payloads::EventInput, + payloads::PersonInput, + )), + tags( + (name = "info"), + (name = "event"), + (name = "person"), + (name = "tasks"), + ), + modifiers(&SecurityAddon), +)] +pub struct ApiDoc; + +struct SecurityAddon; + +// Add password auth spec +impl Modify for SecurityAddon { + fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { + openapi.components.as_mut().unwrap().add_security_scheme( + "password", + SecurityScheme::Http( + HttpBuilder::new() + .scheme(HttpAuthScheme::Bearer) + .bearer_format("base64") + .build(), + ), + ); + openapi.components.as_mut().unwrap().add_security_scheme( + "cron-key", + SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-Cron-Key"))), + ); + } +} diff --git a/api/src/errors.rs b/api/src/errors.rs new file mode 100644 index 0000000..fe1a1dc --- /dev/null +++ b/api/src/errors.rs @@ -0,0 +1,22 @@ +use axum::{http::StatusCode, response::IntoResponse}; +use common::Adaptor; + +pub enum ApiError { + AdaptorError(A::Error), + NotFound, + NotAuthorized, +} + +// Define what the error types above should return +impl IntoResponse for ApiError
{ + fn into_response(self) -> axum::response::Response { + match self { + ApiError::AdaptorError(e) => { + tracing::error!(?e); + StatusCode::INTERNAL_SERVER_ERROR.into_response() + } + ApiError::NotFound => StatusCode::NOT_FOUND.into_response(), + ApiError::NotAuthorized => StatusCode::UNAUTHORIZED.into_response(), + } + } +} diff --git a/api/src/main.rs b/api/src/main.rs new file mode 100644 index 0000000..e2f46aa --- /dev/null +++ b/api/src/main.rs @@ -0,0 +1,116 @@ +use std::{env, net::SocketAddr, sync::Arc}; + +use axum::{ + error_handling::HandleErrorLayer, + extract, + http::{HeaderValue, Method}, + routing::{get, patch, post}, + BoxError, Router, Server, +}; +use routes::*; +use tokio::sync::Mutex; +use tower::ServiceBuilder; +use tower_governor::{errors::display_error, governor::GovernorConfigBuilder, GovernorLayer}; +use tower_http::{cors::CorsLayer, trace::TraceLayer}; +use tracing::Level; +use utoipa::OpenApi; +use utoipa_swagger_ui::SwaggerUi; + +use crate::adaptors::create_adaptor; +use crate::docs::ApiDoc; + +mod adaptors; +mod docs; +mod errors; +mod payloads; +mod routes; + +pub struct ApiState { + adaptor: A, +} + +pub type State = extract::State>>>; + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt().with_max_level(Level::INFO).init(); + + // Load env + dotenvy::dotenv().ok(); + + let shared_state = Arc::new(Mutex::new(ApiState { + adaptor: create_adaptor().await, + })); + + // CORS configuration + let cors = CorsLayer::new() + .allow_methods([Method::GET, Method::POST, Method::PATCH]) + .allow_origin( + if cfg!(debug_assertions) { + "http://localhost:1234".to_owned() + } else { + env::var("FRONTEND_URL").expect("Missing FRONTEND_URL environment variable") + } + .parse::() + .unwrap(), + ); + + // Rate limiting configuration (using tower_governor) + // From the docs: Allows bursts with up to eight requests and replenishes + // one element after 500ms, based on peer IP. + let governor_config = Box::new(GovernorConfigBuilder::default().finish().unwrap()); + let rate_limit = ServiceBuilder::new() + // Handle errors from governor and convert into HTTP responses + .layer(HandleErrorLayer::new(|e: BoxError| async move { + display_error(e) + })) + .layer(GovernorLayer { + config: Box::leak(governor_config), + }); + + let app = Router::new() + .merge(SwaggerUi::new("/docs").url("/docs/openapi.json", ApiDoc::openapi())) + .route("/", get(get_root)) + .route("/stats", get(stats::get_stats)) + .route("/event", post(event::create_event)) + .route("/event/:event_id", get(event::get_event)) + .route("/event/:event_id/people", get(person::get_people)) + .route( + "/event/:event_id/people/:person_name", + get(person::get_person), + ) + .route( + "/event/:event_id/people/:person_name", + patch(person::update_person), + ) + .route("/tasks/cleanup", get(tasks::cleanup)) + .with_state(shared_state) + .layer(cors) + .layer(rate_limit) + .layer(TraceLayer::new_for_http()); + + let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); + + println!( + "🦀 Crab Fit API listening at http://{} in {} mode", + addr, + if cfg!(debug_assertions) { + "debug" + } else { + "release" + } + ); + Server::bind(&addr) + .serve(app.into_make_service_with_connect_info::()) + .with_graceful_shutdown(async { + tokio::signal::ctrl_c() + .await + .expect("Failed to install Ctrl+C handler") + }) + .await + .unwrap(); +} + +async fn get_root() -> String { + format!("Crab Fit API v{}", env!("CARGO_PKG_VERSION")) +} diff --git a/api/src/payloads.rs b/api/src/payloads.rs new file mode 100644 index 0000000..6bf0176 --- /dev/null +++ b/api/src/payloads.rs @@ -0,0 +1,75 @@ +use axum::Json; +use common::{Event, Person, Stats}; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; + +use crate::errors::ApiError; + +pub type ApiResult = Result, ApiError>; + +#[derive(Deserialize, ToSchema)] +pub struct EventInput { + pub name: Option, + pub times: Vec, + pub timezone: String, +} + +#[derive(Serialize, ToSchema)] +pub struct EventResponse { + pub id: String, + pub name: String, + pub times: Vec, + pub timezone: String, + pub created_at: i64, +} + +impl From for EventResponse { + fn from(value: Event) -> Self { + Self { + id: value.id, + name: value.name, + times: value.times, + timezone: value.timezone, + created_at: value.created_at.timestamp(), + } + } +} + +#[derive(Serialize, ToSchema)] +pub struct StatsResponse { + pub event_count: i64, + pub person_count: i64, + pub version: String, +} + +impl From for StatsResponse { + fn from(value: Stats) -> Self { + Self { + event_count: value.event_count, + person_count: value.person_count, + version: env!("CARGO_PKG_VERSION").to_string(), + } + } +} + +#[derive(Serialize, ToSchema)] +pub struct PersonResponse { + pub name: String, + pub availability: Vec, + pub created_at: i64, +} + +impl From for PersonResponse { + fn from(value: Person) -> Self { + Self { + name: value.name, + availability: value.availability, + created_at: value.created_at.timestamp(), + } + } +} + +#[derive(Deserialize, ToSchema)] +pub struct PersonInput { + pub availability: Vec, +} diff --git a/api/src/res/adjectives.json b/api/src/res/adjectives.json new file mode 100644 index 0000000..48860c5 --- /dev/null +++ b/api/src/res/adjectives.json @@ -0,0 +1,201 @@ +[ + "Adorable", + "Adventurous", + "Aggressive", + "Agreeable", + "Alert", + "Alive", + "Amused", + "Angry", + "Annoyed", + "Annoying", + "Anxious", + "Arrogant", + "Ashamed", + "Attractive", + "Average", + "Beautiful", + "Better", + "Bewildered", + "Blue", + "Blushing", + "Bored", + "Brainy", + "Brave", + "Breakable", + "Bright", + "Busy", + "Calm", + "Careful", + "Cautious", + "Charming", + "Cheerful", + "Clean", + "Clear", + "Clever", + "Cloudy", + "Clumsy", + "Colorful", + "Comfortable", + "Concerned", + "Confused", + "Cooperative", + "Courageous", + "Crazy", + "Creepy", + "Crowded", + "Curious", + "Cute", + "Dangerous", + "Dark", + "Defiant", + "Delightful", + "Depressed", + "Determined", + "Different", + "Difficult", + "Disgusted", + "Distinct", + "Disturbed", + "Dizzy", + "Doubtful", + "Drab", + "Dull", + "Eager", + "Easy", + "Elated", + "Elegant", + "Embarrassed", + "Enchanting", + "Encouraging", + "Energetic", + "Enthusiastic", + "Envious", + "Evil", + "Excited", + "Expensive", + "Exuberant", + "Fair", + "Faithful", + "Famous", + "Fancy", + "Fantastic", + "Fierce", + "Fine", + "Foolish", + "Fragile", + "Frail", + "Frantic", + "Friendly", + "Frightened", + "Funny", + "Gentle", + "Gifted", + "Glamorous", + "Gleaming", + "Glorious", + "Good", + "Gorgeous", + "Graceful", + "Grumpy", + "Handsome", + "Happy", + "Healthy", + "Helpful", + "Hilarious", + "Homely", + "Hungry", + "Important", + "Impossible", + "Inexpensive", + "Innocent", + "Inquisitive", + "Itchy", + "Jealous", + "Jittery", + "Jolly", + "Joyous", + "Kind", + "Lazy", + "Light", + "Lively", + "Lonely", + "Long", + "Lovely", + "Lucky", + "Magnificent", + "Misty", + "Modern", + "Motionless", + "Muddy", + "Mushy", + "Mysterious", + "Naughty", + "Nervous", + "Nice", + "Nutty", + "Obedient", + "Obnoxious", + "Odd", + "Old-fashioned", + "Open", + "Outrageous", + "Outstanding", + "Panicky", + "Perfect", + "Plain", + "Pleasant", + "Poised", + "Powerful", + "Precious", + "Prickly", + "Proud", + "Puzzled", + "Quaint", + "Real", + "Relieved", + "Scary", + "Selfish", + "Shiny", + "Shy", + "Silly", + "Sleepy", + "Smiling", + "Smoggy", + "Sparkling", + "Splendid", + "Spotless", + "Stormy", + "Strange", + "Successful", + "Super", + "Talented", + "Tame", + "Tasty", + "Tender", + "Tense", + "Terrible", + "Thankful", + "Thoughtful", + "Thoughtless", + "Tired", + "Tough", + "Uninterested", + "Unsightly", + "Unusual", + "Upset", + "Uptight", + "Vast", + "Victorious", + "Vivacious", + "Wandering", + "Weary", + "Wicked", + "Wide-eyed", + "Wild", + "Witty", + "Worried", + "Worrisome", + "Zany", + "Zealous" +] diff --git a/api/src/res/crabs.json b/api/src/res/crabs.json new file mode 100644 index 0000000..62bbe15 --- /dev/null +++ b/api/src/res/crabs.json @@ -0,0 +1,47 @@ +[ + "American Horseshoe", + "Atlantic Ghost", + "Baja Elbow", + "Big Claw Purple Hermit", + "Coldwater Mole", + "Cuata Swim", + "Deepwater Frog", + "Dwarf Teardrop", + "Elegant Hermit", + "Flat Spider", + "Ghost", + "Globe Purse", + "Green", + "Halloween", + "Harbor Spider", + "Inflated Spider", + "Left Clawed Hermit", + "Lumpy Claw", + "Magnificent Hermit", + "Mexican Spider", + "Mouthless Land", + "Northern Lemon Rock", + "Pacific Arrow", + "Pacific Mole", + "Paco Box", + "Panamic Spider", + "Purple Shore", + "Red Rock", + "Red Swim", + "Red-leg Hermit", + "Robust Swim", + "Rough Swim", + "Sand Swim", + "Sally Lightfoot", + "Shamed-face Box", + "Shamed-face Heart Box", + "Shell", + "Small Arched Box", + "Southern Kelp", + "Spotted Box", + "Striated Mole", + "Striped Shore", + "Tropical Mole", + "Walking Rock", + "Yellow Shore" +] diff --git a/api/src/routes/event.rs b/api/src/routes/event.rs new file mode 100644 index 0000000..934b57c --- /dev/null +++ b/api/src/routes/event.rs @@ -0,0 +1,140 @@ +use axum::{ + extract::{self, Path}, + http::StatusCode, + Json, +}; +use common::{Adaptor, Event}; +use rand::{seq::SliceRandom, thread_rng, Rng}; +use regex::Regex; + +use crate::{ + errors::ApiError, + payloads::{ApiResult, EventInput, EventResponse}, + State, +}; + +#[utoipa::path( + get, + path = "/event/{event_id}", + params( + ("event_id", description = "The ID of the event"), + ), + responses( + (status = 200, description = "Ok", body = EventResponse), + (status = 404, description = "Not found"), + (status = 429, description = "Too many requests"), + ), + tag = "event", +)] +/// Get details about an event +pub async fn get_event( + extract::State(state): State, + Path(event_id): Path, +) -> ApiResult { + let adaptor = &state.lock().await.adaptor; + + let event = adaptor + .get_event(event_id) + .await + .map_err(ApiError::AdaptorError)?; + + match event { + Some(event) => Ok(Json(event.into())), + None => Err(ApiError::NotFound), + } +} + +#[utoipa::path( + post, + path = "/event", + request_body(content = EventInput, description = "New event details"), + responses( + (status = 201, description = "Created", body = EventResponse), + (status = 415, description = "Unsupported input format"), + (status = 422, description = "Invalid input provided"), + (status = 429, description = "Too many requests"), + ), + tag = "event", +)] +/// Create a new event +pub async fn create_event( + extract::State(state): State, + Json(input): Json, +) -> Result<(StatusCode, Json), ApiError> { + let adaptor = &state.lock().await.adaptor; + + // Get the current timestamp + let now = chrono::offset::Utc::now(); + + // Generate a name if none provided + let name = match input.name { + Some(x) if !x.is_empty() => x.trim().to_string(), + _ => generate_name(), + }; + + // Generate an ID + let mut id = generate_id(&name); + + // Check the ID doesn't already exist + while (adaptor + .get_event(id.clone()) + .await + .map_err(ApiError::AdaptorError)?) + .is_some() + { + id = generate_id(&name); + } + + let event = adaptor + .create_event(Event { + id, + name, + created_at: now, + visited_at: now, + times: input.times, + timezone: input.timezone, + }) + .await + .map_err(ApiError::AdaptorError)?; + + // Update stats + adaptor + .increment_stat_event_count() + .await + .map_err(ApiError::AdaptorError)?; + + Ok((StatusCode::CREATED, Json(event.into()))) +} + +// Generate a random name based on an adjective and a crab species +fn generate_name() -> String { + let adjectives: Vec = + serde_json::from_slice(include_bytes!("../res/adjectives.json")).unwrap(); + let crabs: Vec = serde_json::from_slice(include_bytes!("../res/crabs.json")).unwrap(); + + format!( + "{} {} Crab", + adjectives.choose(&mut thread_rng()).unwrap(), + crabs.choose(&mut thread_rng()).unwrap() + ) +} + +// Generate a slug for the crab fit +fn generate_id(name: &str) -> String { + let mut id = encode_name(name.to_string()); + if id.replace('-', "").is_empty() { + id = encode_name(generate_name()); + } + let number = thread_rng().gen_range(100000..=999999); + format!("{}-{}", id, number) +} + +// Use punycode to encode the name +fn encode_name(name: String) -> String { + let pc = punycode::encode(&name.trim().to_lowercase()) + .unwrap_or(String::from("")) + .trim() + .replace(|c: char| !c.is_ascii_alphanumeric() && c != ' ', ""); + let re = Regex::new(r"\s+").unwrap(); + re.replace_all(&pc, "-").to_string() +} diff --git a/api/src/routes/mod.rs b/api/src/routes/mod.rs new file mode 100644 index 0000000..7e1429b --- /dev/null +++ b/api/src/routes/mod.rs @@ -0,0 +1,4 @@ +pub mod event; +pub mod person; +pub mod stats; +pub mod tasks; diff --git a/api/src/routes/person.rs b/api/src/routes/person.rs new file mode 100644 index 0000000..974a519 --- /dev/null +++ b/api/src/routes/person.rs @@ -0,0 +1,216 @@ +use axum::{ + extract::{self, Path}, + headers::{authorization::Bearer, Authorization}, + Json, TypedHeader, +}; +use base64::{engine::general_purpose, Engine}; +use common::{Adaptor, Person}; + +use crate::{ + errors::ApiError, + payloads::{ApiResult, PersonInput, PersonResponse}, + State, +}; + +#[utoipa::path( + get, + path = "/event/{event_id}/people", + params( + ("event_id", description = "The ID of the event"), + ), + responses( + (status = 200, description = "Ok", body = [PersonResponse]), + (status = 404, description = "Event not found"), + (status = 429, description = "Too many requests"), + ), + tag = "person", +)] +/// Get availabilities for an event +pub async fn get_people( + extract::State(state): State, + Path(event_id): Path, +) -> ApiResult, A> { + let adaptor = &state.lock().await.adaptor; + + let people = adaptor + .get_people(event_id) + .await + .map_err(ApiError::AdaptorError)?; + + match people { + Some(people) => Ok(Json(people.into_iter().map(|p| p.into()).collect())), + None => Err(ApiError::NotFound), + } +} + +#[utoipa::path( + get, + path = "/event/{event_id}/people/{person_name}", + params( + ("event_id", description = "The ID of the event"), + ("person_name", description = "The name of the person"), + ), + security((), ("password" = [])), + responses( + (status = 200, description = "Ok", body = PersonResponse), + (status = 401, description = "Incorrect password"), + (status = 404, description = "Event not found"), + (status = 415, description = "Unsupported input format"), + (status = 422, description = "Invalid input provided"), + (status = 429, description = "Too many requests"), + ), + tag = "person", +)] +/// Login or create a person for an event +pub async fn get_person( + extract::State(state): State, + Path((event_id, person_name)): Path<(String, String)>, + bearer: Option>>, +) -> ApiResult { + let adaptor = &state.lock().await.adaptor; + + // Get inputted password + let password = parse_password(bearer); + + let existing_people = adaptor + .get_people(event_id.clone()) + .await + .map_err(ApiError::AdaptorError)?; + + // Event not found + if existing_people.is_none() { + return Err(ApiError::NotFound); + } + + // Check if the user already exists + let existing_person = existing_people + .unwrap() + .into_iter() + .find(|p| p.name.to_lowercase() == person_name.to_lowercase()); + + match existing_person { + // Login + Some(p) => { + // Verify password (if set) + if verify_password(&p, password) { + Ok(Json(p.into())) + } else { + Err(ApiError::NotAuthorized) + } + } + // Signup + None => { + // Update stats + adaptor + .increment_stat_person_count() + .await + .map_err(ApiError::AdaptorError)?; + + Ok(Json( + adaptor + .upsert_person( + event_id, + Person { + name: person_name, + password_hash: password + .map(|raw| bcrypt::hash(raw, 10).unwrap_or(String::from(""))), + created_at: chrono::offset::Utc::now(), + availability: vec![], + }, + ) + .await + .map_err(ApiError::AdaptorError)? + .unwrap() + .into(), + )) + } + } +} + +#[utoipa::path( + patch, + path = "/event/{event_id}/people/{person_name}", + params( + ("event_id", description = "The ID of the event"), + ("person_name", description = "The name of the person"), + ), + security((), ("password" = [])), + request_body(content = PersonInput, description = "Person details"), + responses( + (status = 200, description = "Ok", body = PersonResponse), + (status = 401, description = "Incorrect password"), + (status = 404, description = "Event or person not found"), + (status = 415, description = "Unsupported input format"), + (status = 422, description = "Invalid input provided"), + (status = 429, description = "Too many requests"), + ), + tag = "person", +)] +/// Update a person's availabilities +pub async fn update_person( + extract::State(state): State, + Path((event_id, person_name)): Path<(String, String)>, + bearer: Option>>, + Json(input): Json, +) -> ApiResult { + let adaptor = &state.lock().await.adaptor; + + let existing_people = adaptor + .get_people(event_id.clone()) + .await + .map_err(ApiError::AdaptorError)?; + + // Event not found + if existing_people.is_none() { + return Err(ApiError::NotFound); + } + + // Check if the user exists + let existing_person = existing_people + .unwrap() + .into_iter() + .find(|p| p.name.to_lowercase() == person_name.to_lowercase()) + .ok_or(ApiError::NotFound)?; + + // Verify password (if set) + if !verify_password(&existing_person, parse_password(bearer)) { + return Err(ApiError::NotAuthorized); + } + + Ok(Json( + adaptor + .upsert_person( + event_id, + Person { + name: existing_person.name, + password_hash: existing_person.password_hash, + created_at: existing_person.created_at, + availability: input.availability, + }, + ) + .await + .map_err(ApiError::AdaptorError)? + .unwrap() + .into(), + )) +} + +pub fn parse_password(bearer: Option>>) -> Option { + bearer.map(|TypedHeader(Authorization(b))| { + String::from_utf8( + general_purpose::STANDARD + .decode(b.token().trim()) + .unwrap_or(vec![]), + ) + .unwrap_or("".to_owned()) + }) +} + +pub fn verify_password(person: &Person, raw: Option) -> bool { + match &person.password_hash { + Some(hash) => bcrypt::verify(raw.unwrap_or("".to_owned()), hash).unwrap_or(false), + // Specifically allow a user who doesn't have a password + // set to log in with or without any password input + None => true, + } +} diff --git a/api/src/routes/stats.rs b/api/src/routes/stats.rs new file mode 100644 index 0000000..539fffa --- /dev/null +++ b/api/src/routes/stats.rs @@ -0,0 +1,26 @@ +use axum::{extract, Json}; +use common::Adaptor; + +use crate::{ + errors::ApiError, + payloads::{ApiResult, StatsResponse}, + State, +}; + +#[utoipa::path( + get, + path = "/stats", + responses( + (status = 200, description = "Ok", body = StatsResponse), + (status = 429, description = "Too many requests"), + ), + tag = "info", +)] +/// Get current stats +pub async fn get_stats(extract::State(state): State) -> ApiResult { + let adaptor = &state.lock().await.adaptor; + + let stats = adaptor.get_stats().await.map_err(ApiError::AdaptorError)?; + + Ok(Json(stats.into())) +} diff --git a/api/src/routes/tasks.rs b/api/src/routes/tasks.rs new file mode 100644 index 0000000..b8c60a8 --- /dev/null +++ b/api/src/routes/tasks.rs @@ -0,0 +1,51 @@ +use std::env; + +use axum::{extract, http::HeaderMap}; +use chrono::{Duration, Utc}; +use common::Adaptor; +use tracing::info; + +use crate::{errors::ApiError, State}; + +#[utoipa::path( + get, + path = "/tasks/cleanup", + responses( + (status = 200, description = "Cleanup complete"), + (status = 401, description = "Missing or incorrect X-Cron-Key header"), + (status = 429, description = "Too many requests"), + ), + security((), ("cron-key" = [])), + tag = "tasks", +)] +/// Delete events older than 3 months +pub async fn cleanup( + extract::State(state): State, + headers: HeaderMap, +) -> Result<(), ApiError> { + // Check cron key + let cron_key_header: String = headers + .get("X-Cron-Key") + .map(|k| k.to_str().unwrap_or_default().into()) + .unwrap_or_default(); + let env_key = env::var("CRON_KEY").unwrap_or_default(); + if !env_key.is_empty() && cron_key_header != env_key { + return Err(ApiError::NotAuthorized); + } + + info!("Running cleanup task"); + + let adaptor = &state.lock().await.adaptor; + + let result = adaptor + .delete_events(Utc::now() - Duration::days(90)) + .await + .map_err(ApiError::AdaptorError)?; + + info!( + "Cleanup successful: {} events and {} people removed", + result.event_count, result.person_count + ); + + Ok(()) +} diff --git a/browser-extension/.gitignore b/browser-extension/.gitignore new file mode 100644 index 0000000..c4c4ffc --- /dev/null +++ b/browser-extension/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/crabfit-browser-extension/manifest.json b/browser-extension/manifest.json similarity index 100% rename from crabfit-browser-extension/manifest.json rename to browser-extension/manifest.json diff --git a/crabfit-browser-extension/popup.html b/browser-extension/popup.html similarity index 100% rename from crabfit-browser-extension/popup.html rename to browser-extension/popup.html diff --git a/crabfit-browser-extension/res/icon128.png b/browser-extension/res/icon128.png similarity index 100% rename from crabfit-browser-extension/res/icon128.png rename to browser-extension/res/icon128.png diff --git a/crabfit-browser-extension/res/icon16.png b/browser-extension/res/icon16.png similarity index 100% rename from crabfit-browser-extension/res/icon16.png rename to browser-extension/res/icon16.png diff --git a/crabfit-browser-extension/res/icon32.png b/browser-extension/res/icon32.png similarity index 100% rename from crabfit-browser-extension/res/icon32.png rename to browser-extension/res/icon32.png diff --git a/crabfit-browser-extension/res/icon48.png b/browser-extension/res/icon48.png similarity index 100% rename from crabfit-browser-extension/res/icon48.png rename to browser-extension/res/icon48.png diff --git a/crabfit-backend/.eslintrc.js b/crabfit-backend/.eslintrc.js deleted file mode 100644 index 5a31f19..0000000 --- a/crabfit-backend/.eslintrc.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = { - 'env': { - 'es2021': true, - 'node': true - }, - 'extends': 'eslint:recommended', - 'overrides': [ - ], - 'parserOptions': { - 'ecmaVersion': 'latest', - 'sourceType': 'module' - }, - 'rules': { - 'indent': [ - 'error', - 2 - ], - 'linebreak-style': [ - 'error', - 'unix' - ], - 'quotes': [ - 'error', - 'single' - ], - 'semi': [ - 'error', - 'never' - ], - 'eqeqeq': 2, - 'no-return-await': 1, - 'no-var': 2, - 'prefer-const': 1, - 'yoda': 2, - 'no-trailing-spaces': 1, - 'eol-last': [1, 'always'], - 'no-unused-vars': [ - 1, - { - 'args': 'all', - 'argsIgnorePattern': '^_', - 'ignoreRestSiblings': true - }, - ], - 'arrow-parens': [ - 'error', - 'as-needed' - ], - } -} diff --git a/crabfit-backend/.gcloudignore b/crabfit-backend/.gcloudignore deleted file mode 100644 index 92f6f4d..0000000 --- a/crabfit-backend/.gcloudignore +++ /dev/null @@ -1,12 +0,0 @@ -.gcloudignore - -.git -.gitignore - -.env - -node_modules/ -.parcel-cache -res -routes -swagger.yaml diff --git a/crabfit-backend/.gitignore b/crabfit-backend/.gitignore deleted file mode 100644 index 7d68da3..0000000 --- a/crabfit-backend/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -dist -.parcel-cache -.env - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/crabfit-backend/app.yaml b/crabfit-backend/app.yaml deleted file mode 100644 index 885ea77..0000000 --- a/crabfit-backend/app.yaml +++ /dev/null @@ -1,7 +0,0 @@ -runtime: nodejs16 -service: api -handlers: - - url: /.* - secure: always - redirect_http_response_code: 301 - script: auto diff --git a/crabfit-backend/cron.yaml b/crabfit-backend/cron.yaml deleted file mode 100644 index 9dd6fcd..0000000 --- a/crabfit-backend/cron.yaml +++ /dev/null @@ -1,9 +0,0 @@ -cron: - - description: "clean up old events" - url: /tasks/cleanup - schedule: every monday 09:00 - target: api - - description: "remove people with an event id that no longer exists" - url: /tasks/removeOrphans - schedule: 1st wednesday of month 09:00 - target: api diff --git a/crabfit-backend/index.js b/crabfit-backend/index.js deleted file mode 100644 index 5dc5b39..0000000 --- a/crabfit-backend/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import { config } from 'dotenv' -import { Datastore } from '@google-cloud/datastore' -import express from 'express' -import cors from 'cors' - -import packageJson from './package.json' - -import { - stats, - getEvent, - createEvent, - getPeople, - createPerson, - login, - updatePerson, - taskCleanup, - taskRemoveOrphans, -} from './routes' - -config() - -const app = express() -const port = 8080 -const corsOptions = { - origin: process.env.NODE_ENV === 'production' ? 'https://crab.fit' : 'http://localhost:5173', -} - -const datastore = new Datastore({ - keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS, -}) - -app.use(express.json()) -app.use((req, _res, next) => { - req.datastore = datastore - req.types = { - event: process.env.NODE_ENV === 'production' ? 'Event' : 'DevEvent', - person: process.env.NODE_ENV === 'production' ? 'Person' : 'DevPerson', - stats: process.env.NODE_ENV === 'production' ? 'Stats' : 'DevStats', - } - next() -}) -app.options('*', cors(corsOptions)) -app.use(cors(corsOptions)) - -app.get('/', (_req, res) => res.send(`Crabfit API v${packageJson.version}`)) - -app.get('/stats', stats) -app.get('/event/:eventId', getEvent) -app.post('/event', createEvent) -app.get('/event/:eventId/people', getPeople) -app.post('/event/:eventId/people', createPerson) -app.post('/event/:eventId/people/:personName', login) -app.patch('/event/:eventId/people/:personName', updatePerson) - -// Tasks -app.get('/tasks/cleanup', taskCleanup) -app.get('/tasks/removeOrphans', taskRemoveOrphans) - -app.listen(port, () => { - console.log(`Crabfit API listening at http://localhost:${port} in ${process.env.NODE_ENV === 'production' ? 'prod' : 'dev'} mode`) -}) diff --git a/crabfit-backend/package.json b/crabfit-backend/package.json deleted file mode 100644 index cf3f3fd..0000000 --- a/crabfit-backend/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "crabfit-backend", - "version": "2.0.0", - "description": "API for Crabfit", - "author": "Ben Grant", - "license": "GPL-3.0-only", - "private": true, - "source": "index.js", - "main": "dist/index.js", - "engines": { - "node": ">=12.0.0" - }, - "scripts": { - "build:dev": "NODE_ENV=development parcel build --no-cache", - "dev": "rm -rf .parcel-cache dist && NODE_ENV=development nodemon --exec \"yarn build:dev && yarn start\" --watch routes --watch res --watch index.js", - "build": "parcel build", - "start": "node ./dist/index.js", - "lint": "eslint index.js ./routes" - }, - "dependencies": { - "@google-cloud/datastore": "^7.0.0", - "bcrypt": "^5.0.1", - "cors": "^2.8.5", - "dayjs": "^1.11.5", - "dotenv": "^16.0.1", - "express": "^4.18.1", - "punycode": "^2.1.1" - }, - "devDependencies": { - "eslint": "^8.22.0", - "nodemon": "^2.0.19", - "parcel": "^2.7.0" - } -} diff --git a/crabfit-backend/res/adjectives.json b/crabfit-backend/res/adjectives.json deleted file mode 100644 index 3edd6f5..0000000 --- a/crabfit-backend/res/adjectives.json +++ /dev/null @@ -1,201 +0,0 @@ -[ - "adorable", - "adventurous", - "aggressive", - "agreeable", - "alert", - "alive", - "amused", - "angry", - "annoyed", - "annoying", - "anxious", - "arrogant", - "ashamed", - "attractive", - "average", - "beautiful", - "better", - "bewildered", - "blue", - "blushing", - "bored", - "brainy", - "brave", - "breakable", - "bright", - "busy", - "calm", - "careful", - "cautious", - "charming", - "cheerful", - "clean", - "clear", - "clever", - "cloudy", - "clumsy", - "colorful", - "comfortable", - "concerned", - "confused", - "cooperative", - "courageous", - "crazy", - "creepy", - "crowded", - "curious", - "cute", - "dangerous", - "dark", - "defiant", - "delightful", - "depressed", - "determined", - "different", - "difficult", - "disgusted", - "distinct", - "disturbed", - "dizzy", - "doubtful", - "drab", - "dull", - "eager", - "easy", - "elated", - "elegant", - "embarrassed", - "enchanting", - "encouraging", - "energetic", - "enthusiastic", - "envious", - "evil", - "excited", - "expensive", - "exuberant", - "fair", - "faithful", - "famous", - "fancy", - "fantastic", - "fierce", - "fine", - "foolish", - "fragile", - "frail", - "frantic", - "friendly", - "frightened", - "funny", - "gentle", - "gifted", - "glamorous", - "gleaming", - "glorious", - "good", - "gorgeous", - "graceful", - "grumpy", - "handsome", - "happy", - "healthy", - "helpful", - "hilarious", - "homely", - "hungry", - "important", - "impossible", - "inexpensive", - "innocent", - "inquisitive", - "itchy", - "jealous", - "jittery", - "jolly", - "joyous", - "kind", - "lazy", - "light", - "lively", - "lonely", - "long", - "lovely", - "lucky", - "magnificent", - "misty", - "modern", - "motionless", - "muddy", - "mushy", - "mysterious", - "naughty", - "nervous", - "nice", - "nutty", - "obedient", - "obnoxious", - "odd", - "old-fashioned", - "open", - "outrageous", - "outstanding", - "panicky", - "perfect", - "plain", - "pleasant", - "poised", - "powerful", - "precious", - "prickly", - "proud", - "puzzled", - "quaint", - "real", - "relieved", - "scary", - "selfish", - "shiny", - "shy", - "silly", - "sleepy", - "smiling", - "smoggy", - "sparkling", - "splendid", - "spotless", - "stormy", - "strange", - "successful", - "super", - "talented", - "tame", - "tasty", - "tender", - "tense", - "terrible", - "thankful", - "thoughtful", - "thoughtless", - "tired", - "tough", - "uninterested", - "unsightly", - "unusual", - "upset", - "uptight", - "vast", - "victorious", - "vivacious", - "wandering", - "weary", - "wicked", - "wide-eyed", - "wild", - "witty", - "worried", - "worrisome", - "zany", - "zealous" -] diff --git a/crabfit-backend/res/crabs.json b/crabfit-backend/res/crabs.json deleted file mode 100644 index a0563b6..0000000 --- a/crabfit-backend/res/crabs.json +++ /dev/null @@ -1,47 +0,0 @@ -[ - "American Horseshoe", - "Atlantic Ghost", - "Baja Elbow", - "Big Claw Purple Hermit", - "Coldwater Mole", - "Cuata Swim", - "Deepwater Frog", - "Dwarf Teardrop", - "Elegant Hermit", - "Flat Spider", - "Ghost", - "Globe Purse", - "Green", - "Halloween", - "Harbor Spider", - "Inflated Spider", - "Left Clawed Hermit", - "Lumpy Claw", - "Magnificent Hermit", - "Mexican Spider", - "Mouthless Land", - "Northern Lemon Rock", - "Pacific Arrow", - "Pacific Mole", - "Paco Box", - "Panamic Spider", - "Purple Shore", - "Red Rock", - "Red Swim", - "Red-leg Hermit", - "Robust Swim", - "Rough Swim", - "Sand Swim", - "Sally Lightfoot", - "Shamed-face Box", - "Shamed-face Heart Box", - "Shell", - "Small Arched Box", - "Southern Kelp", - "Spotted Box", - "Striated Mole", - "Striped Shore", - "Tropical Mole", - "Walking Rock", - "Yellow Shore" -] diff --git a/crabfit-backend/routes/createEvent.js b/crabfit-backend/routes/createEvent.js deleted file mode 100644 index bf901f9..0000000 --- a/crabfit-backend/routes/createEvent.js +++ /dev/null @@ -1,84 +0,0 @@ -import dayjs from 'dayjs' -import punycode from 'punycode/' - -import adjectives from '../res/adjectives.json' -import crabs from '../res/crabs.json' - -const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1) - -// Generate a random name based on an adjective and a crab species -const generateName = () => - `${capitalize(adjectives[Math.floor(Math.random() * adjectives.length)])} ${crabs[Math.floor(Math.random() * crabs.length)]} Crab` - -// Generate a slug for the crab fit -const generateId = name => { - let id = punycode.encode(name.trim().toLowerCase()).trim().replace(/[^A-Za-z0-9 ]/g, '').replace(/\s+/g, '-') - if (id.replace(/-/g, '') === '') { - id = generateName().trim().toLowerCase().replace(/[^A-Za-z0-9 ]/g, '').replace(/\s+/g, '-') - } - const number = Math.floor(100000 + Math.random() * 900000) - return `${id}-${number}` -} - -const createEvent = async (req, res) => { - const { event } = req.body - - try { - const name = event.name.trim() === '' ? generateName() : event.name.trim() - let eventId = generateId(name) - const currentTime = dayjs().unix() - - // Check if the event ID already exists, and if so generate a new one - let eventResult - do { - const query = req.datastore.createQuery(req.types.event) - .select('__key__') - .filter('__key__', req.datastore.key([req.types.event, eventId])) - - eventResult = (await req.datastore.runQuery(query))[0][0] - - if (eventResult !== undefined) { - eventId = generateId(name) - } - } while (eventResult !== undefined) - - const entity = { - key: req.datastore.key([req.types.event, eventId]), - data: { - name: name, - created: currentTime, - times: event.times, - timezone: event.timezone, - }, - } - - await req.datastore.insert(entity) - - res.status(201).send({ - id: eventId, - name: name, - created: currentTime, - times: event.times, - timezone: event.timezone, - }) - - // Update stats - const eventCountResult = (await req.datastore.get(req.datastore.key([req.types.stats, 'eventCount'])))[0] || null - if (eventCountResult) { - await req.datastore.upsert({ - ...eventCountResult, - value: eventCountResult.value + 1, - }) - } else { - await req.datastore.insert({ - key: req.datastore.key([req.types.stats, 'eventCount']), - data: { value: 1 }, - }) - } - } catch (e) { - console.error(e) - res.status(400).send({ error: 'An error occurred while creating the event' }) - } -} - -export default createEvent diff --git a/crabfit-backend/routes/createPerson.js b/crabfit-backend/routes/createPerson.js deleted file mode 100644 index 5a437d2..0000000 --- a/crabfit-backend/routes/createPerson.js +++ /dev/null @@ -1,65 +0,0 @@ -import dayjs from 'dayjs' -import bcrypt from 'bcrypt' - -const createPerson = async (req, res) => { - const { eventId } = req.params - const { person } = req.body - - try { - const event = (await req.datastore.get(req.datastore.key([req.types.event, eventId])))[0] - const query = req.datastore.createQuery(req.types.person) - .filter('eventId', eventId) - .filter('name', person.name) - const personResult = (await req.datastore.runQuery(query))[0][0] - - if (event) { - if (person && personResult === undefined) { - const currentTime = dayjs().unix() - - // If password - let hash = null - if (person.password) { - hash = await bcrypt.hash(person.password, 10) - } - - const entity = { - key: req.datastore.key(req.types.person), - data: { - name: person.name.trim(), - password: hash, - eventId: eventId, - created: currentTime, - availability: [], - }, - } - - await req.datastore.insert(entity) - - res.status(201).send({ success: 'Created' }) - - // Update stats - const personCountResult = (await req.datastore.get(req.datastore.key([req.types.stats, 'personCount'])))[0] || null - if (personCountResult) { - await req.datastore.upsert({ - ...personCountResult, - value: personCountResult.value + 1, - }) - } else { - await req.datastore.insert({ - key: req.datastore.key([req.types.stats, 'personCount']), - data: { value: 1 }, - }) - } - } else { - res.status(400).send({ error: 'Unable to create person' }) - } - } else { - res.status(404).send({ error: 'Event does not exist' }) - } - } catch (e) { - console.error(e) - res.status(400).send({ error: 'An error occurred while creating the person' }) - } -} - -export default createPerson diff --git a/crabfit-backend/routes/getEvent.js b/crabfit-backend/routes/getEvent.js deleted file mode 100644 index 991a71a..0000000 --- a/crabfit-backend/routes/getEvent.js +++ /dev/null @@ -1,29 +0,0 @@ -import dayjs from 'dayjs' - -const getEvent = async (req, res) => { - const { eventId } = req.params - - try { - const event = (await req.datastore.get(req.datastore.key([req.types.event, eventId])))[0] - - if (event) { - res.send({ - id: eventId, - ...event, - }) - - // Update last visited time - await req.datastore.upsert({ - ...event, - visited: dayjs().unix() - }) - } else { - res.status(404).send({ error: 'Event not found' }) - } - } catch (e) { - console.error(e) - res.status(404).send({ error: 'Event not found' }) - } -} - -export default getEvent diff --git a/crabfit-backend/routes/getPeople.js b/crabfit-backend/routes/getPeople.js deleted file mode 100644 index 0a8c041..0000000 --- a/crabfit-backend/routes/getPeople.js +++ /dev/null @@ -1,20 +0,0 @@ -const getPeople = async (req, res) => { - const { eventId } = req.params - - try { - const query = req.datastore.createQuery(req.types.person).filter('eventId', eventId) - let people = (await req.datastore.runQuery(query))[0] - people = people.map(person => ({ - name: person.name, - availability: person.availability, - created: person.created, - })) - - res.send({ people }) - } catch (e) { - console.error(e) - res.status(404).send({ error: 'Person not found' }) - } -} - -export default getPeople diff --git a/crabfit-backend/routes/index.js b/crabfit-backend/routes/index.js deleted file mode 100644 index 3e65553..0000000 --- a/crabfit-backend/routes/index.js +++ /dev/null @@ -1,10 +0,0 @@ -export { default as stats } from './stats' -export { default as getEvent } from './getEvent' -export { default as createEvent } from './createEvent' -export { default as getPeople } from './getPeople' -export { default as createPerson } from './createPerson' -export { default as login } from './login' -export { default as updatePerson } from './updatePerson' - -export { default as taskCleanup } from './taskCleanup' -export { default as taskRemoveOrphans } from './taskRemoveOrphans' diff --git a/crabfit-backend/routes/login.js b/crabfit-backend/routes/login.js deleted file mode 100644 index 059b8de..0000000 --- a/crabfit-backend/routes/login.js +++ /dev/null @@ -1,35 +0,0 @@ -import bcrypt from 'bcrypt' - -const login = async (req, res) => { - const { eventId, personName } = req.params - const { person } = req.body - - try { - const query = req.datastore.createQuery(req.types.person) - .filter('eventId', eventId) - .filter('name', personName) - const personResult = (await req.datastore.runQuery(query))[0][0] - - if (personResult) { - if (personResult.password) { - const passwordsMatch = person && person.password && await bcrypt.compare(person.password, personResult.password) - if (!passwordsMatch) { - return res.status(401).send({ error: 'Incorrect password' }) - } - } - - res.send({ - name: personName, - availability: personResult.availability, - created: personResult.created, - }) - } else { - res.status(404).send({ error: 'Person does not exist' }) - } - } catch (e) { - console.error(e) - res.status(400).send({ error: 'An error occurred' }) - } -} - -export default login diff --git a/crabfit-backend/routes/stats.js b/crabfit-backend/routes/stats.js deleted file mode 100644 index f73d25b..0000000 --- a/crabfit-backend/routes/stats.js +++ /dev/null @@ -1,29 +0,0 @@ -import packageJson from '../package.json' - -const stats = async (req, res) => { - let eventCount = null - let personCount = null - - try { - const eventResult = (await req.datastore.get(req.datastore.key([req.types.stats, 'eventCount'])))[0] || null - const personResult = (await req.datastore.get(req.datastore.key([req.types.stats, 'personCount'])))[0] || null - - if (eventResult) { - eventCount = eventResult.value - } - if (personResult) { - personCount = personResult.value - } - - } catch (e) { - console.error(e) - } - - res.send({ - eventCount, - personCount, - version: packageJson.version, - }) -} - -export default stats diff --git a/crabfit-backend/routes/taskCleanup.js b/crabfit-backend/routes/taskCleanup.js deleted file mode 100644 index b4feac5..0000000 --- a/crabfit-backend/routes/taskCleanup.js +++ /dev/null @@ -1,48 +0,0 @@ -import dayjs from 'dayjs' - -const taskCleanup = async (req, res) => { - if (req.header('X-Appengine-Cron') === undefined) { - return res.status(400).send({ error: 'This task can only be run from a cron job' }) - } - - const threeMonthsAgo = dayjs().subtract(3, 'month').unix() - - console.log(`Running cleanup task at ${dayjs().format('h:mma D MMM YYYY')}`) - - try { - // Fetch events that haven't been visited in over 3 months - const eventQuery = req.datastore.createQuery(req.types.event).filter('visited', '<', threeMonthsAgo) - const oldEvents = (await req.datastore.runQuery(eventQuery))[0] - - if (oldEvents && oldEvents.length > 0) { - const oldEventIds = oldEvents.map(e => e[req.datastore.KEY].name) - console.log(`Found ${oldEventIds.length} events to remove`) - - // Fetch availabilities linked to the events discovered - let peopleDiscovered = 0 - await Promise.all(oldEventIds.map(async eventId => { - const peopleQuery = req.datastore.createQuery(req.types.person).filter('eventId', eventId) - const oldPeople = (await req.datastore.runQuery(peopleQuery))[0] - - if (oldPeople && oldPeople.length > 0) { - peopleDiscovered += oldPeople.length - await req.datastore.delete(oldPeople.map(person => person[req.datastore.KEY])) - } - })) - - await req.datastore.delete(oldEvents.map(event => event[req.datastore.KEY])) - - console.log(`Cleanup successful: ${oldEventIds.length} events and ${peopleDiscovered} people removed`) - - res.sendStatus(200) - } else { - console.log('Found 0 events to remove, ending cleanup') - res.sendStatus(404) - } - } catch (e) { - console.error(e) - res.sendStatus(404) - } -} - -export default taskCleanup diff --git a/crabfit-backend/routes/taskRemoveOrphans.js b/crabfit-backend/routes/taskRemoveOrphans.js deleted file mode 100644 index 95e4994..0000000 --- a/crabfit-backend/routes/taskRemoveOrphans.js +++ /dev/null @@ -1,48 +0,0 @@ -import dayjs from 'dayjs' - -const taskRemoveOrphans = async (req, res) => { - if (req.header('X-Appengine-Cron') === undefined) { - return res.status(400).send({ error: 'This task can only be run from a cron job' }) - } - - const threeMonthsAgo = dayjs().subtract(3, 'month').unix() - - console.log(`Running orphan removal task at ${dayjs().format('h:mma D MMM YYYY')}`) - - try { - // Fetch people that are older than 3 months - const peopleQuery = req.datastore.createQuery(req.types.person).filter('created', '<', threeMonthsAgo) - const oldPeople = (await req.datastore.runQuery(peopleQuery))[0] - - if (oldPeople && oldPeople.length > 0) { - console.log(`Found ${oldPeople.length} people older than 3 months, checking for events`) - - // Fetch events linked to the people discovered - let peopleWithoutEvents = 0 - await Promise.all(oldPeople.map(async person => { - const event = (await req.datastore.get(req.datastore.key([req.types.event, person.eventId])))[0] - - if (!event) { - peopleWithoutEvents++ - await req.datastore.delete(person[req.datastore.KEY]) - } - })) - - if (peopleWithoutEvents > 0) { - console.log(`Orphan removal successful: ${peopleWithoutEvents} people removed`) - res.sendStatus(200) - } else { - console.log('Found 0 people without events, ending orphan removal') - res.sendStatus(404) - } - } else { - console.log('Found 0 people older than 3 months, ending orphan removal') - res.sendStatus(404) - } - } catch (e) { - console.error(e) - res.sendStatus(404) - } -} - -export default taskRemoveOrphans diff --git a/crabfit-backend/routes/updatePerson.js b/crabfit-backend/routes/updatePerson.js deleted file mode 100644 index 921bb91..0000000 --- a/crabfit-backend/routes/updatePerson.js +++ /dev/null @@ -1,40 +0,0 @@ -import bcrypt from 'bcrypt' - -const updatePerson = async (req, res) => { - const { eventId, personName } = req.params - const { person } = req.body - - try { - const query = req.datastore.createQuery(req.types.person) - .filter('eventId', eventId) - .filter('name', personName) - const personResult = (await req.datastore.runQuery(query))[0][0] - - if (personResult) { - if (person && person.availability) { - if (personResult.password) { - const passwordsMatch = person.password && await bcrypt.compare(person.password, personResult.password) - if (!passwordsMatch) { - return res.status(401).send({ error: 'Incorrect password' }) - } - } - - await req.datastore.upsert({ - ...personResult, - availability: person.availability, - }) - - res.status(200).send({ success: 'Updated' }) - } else { - res.status(400).send({ error: 'Availability must be set' }) - } - } else { - res.status(404).send({ error: 'Person not found' }) - } - } catch (e) { - console.error(e) - res.status(400).send('An error occurred') - } -} - -export default updatePerson diff --git a/crabfit-backend/swagger.yaml b/crabfit-backend/swagger.yaml deleted file mode 100644 index 103e7e8..0000000 --- a/crabfit-backend/swagger.yaml +++ /dev/null @@ -1,245 +0,0 @@ -swagger: "2.0" -info: - title: "Crab Fit" - description: "Compare and align schedules to find a time that works for everyone" - version: "1.0.0" -host: "api-dot-crabfit.appspot.com" -x-google-endpoints: -- name: "api-dot-crabfit.appspot.com" - allowCors: true -schemes: - - "https" -produces: - - "application/json" -definitions: - Event: - type: "object" - properties: - id: - type: "string" - name: - type: "string" - timezone: - type: "string" - created: - type: "integer" - times: - type: "array" - items: - type: "string" - Person: - type: "object" - properties: - name: - type: "string" - availability: - type: "array" - items: - type: "string" - created: - type: "integer" -paths: - "/stats": - get: - summary: "Return stats for crabfit" - operationId: "getStats" - responses: - 200: - description: "OK" - schema: - type: "object" - properties: - eventCount: - type: "integer" - personCount: - type: "integer" - version: - type: "string" - "/event/{eventId}": - get: - summary: "Return an event details" - operationId: "getEvent" - parameters: - - in: "path" - name: "eventId" - required: true - type: "string" - description: "The ID of the event" - responses: - 200: - description: "OK" - schema: - $ref: '#/definitions/Event' - 404: - description: "Not found" - "/event": - post: - summary: "Create a new event" - operationId: "postEvent" - parameters: - - in: "body" - name: "event" - required: true - schema: - type: "object" - properties: - name: - type: "string" - timezone: - type: "string" - times: - type: "array" - items: - type: "string" - description: "New event details" - responses: - 201: - description: "Created" - schema: - $ref: '#/definitions/Event' - 400: - description: "Invalid data" - "/event/{eventId}/people": - get: - summary: "Get availabilities for an event" - operationId: "getPeople" - parameters: - - in: "path" - name: "eventId" - required: true - type: "string" - description: "The ID of the event" - responses: - 200: - description: "OK" - schema: - type: "object" - properties: - people: - type: "array" - items: - $ref: "#/definitions/Person" - 404: - description: "Not found" - post: - summary: "Add a new person to the event" - operationId: "postPeople" - parameters: - - in: "path" - name: "eventId" - required: true - type: "string" - description: "The ID of the event" - - in: "body" - name: "person" - required: true - schema: - type: "object" - properties: - name: - type: "string" - password: - type: "string" - description: "New person details" - responses: - 201: - description: "Created" - 404: - description: "Not found" - 400: - description: "Invalid data" - "/event/{eventId}/people/{personName}": - post: - summary: "Login as this person" - operationId: "getPerson" - parameters: - - in: "path" - name: "eventId" - required: true - type: "string" - description: "The ID of the event" - - in: "path" - name: "personName" - required: true - type: "string" - description: "The name of the person" - - in: "body" - name: "person" - required: false - schema: - type: "object" - properties: - password: - type: "string" - description: "Login details" - responses: - 200: - description: "OK" - schema: - $ref: "#/definitions/Person" - 401: - description: "Incorrect password" - 404: - description: "Not found" - patch: - summary: "Update this person's availabilities" - operationId: "patchPerson" - parameters: - - in: "path" - name: "eventId" - required: true - type: "string" - description: "The ID of the event" - - in: "path" - name: "personName" - required: true - type: "string" - description: "The name of the person" - - in: "body" - name: "person" - required: true - schema: - type: "object" - properties: - password: - type: "string" - availability: - type: "array" - items: - type: "string" - description: "Updated person details" - responses: - 200: - description: "OK" - 401: - description: "Incorrect password" - 404: - description: "Not found" - 400: - description: "Invalid data" - "/tasks/cleanup": - get: - summary: "Delete events inactive for more than 3 months" - operationId: "taskCleanup" - tags: - - tasks - responses: - 200: - description: "OK" - 404: - description: "Not found" - 400: - description: "Not called from a cron job" - "/tasks/removeOrphans": - get: - summary: "Deletes people if the event they were created under no longer exists" - operationId: "taskRemoveOrphans" - tags: - - tasks - responses: - 200: - description: "OK" - 404: - description: "Not found" - 400: - description: "Not called from a cron job" diff --git a/crabfit-backend/yarn.lock b/crabfit-backend/yarn.lock deleted file mode 100644 index 31fff37..0000000 --- a/crabfit-backend/yarn.lock +++ /dev/null @@ -1,3686 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/helper-validator-identifier@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" - integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.9.4": - version "7.18.11" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" - integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== - -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.3.2" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@google-cloud/datastore@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@google-cloud/datastore/-/datastore-7.0.0.tgz#e026db7d12c773230abf9e6b391a6196ef3fb81b" - integrity sha512-CbvqzqWFtwHqH3EWMWHqKzKiM9dV+/Ga0e1oSr7rO2KA6QBHGvUEBbLxRWirHnt6Xz2drjzIVjVE1tuOENHPlQ== - dependencies: - "@google-cloud/promisify" "^2.0.0" - arrify "^2.0.1" - concat-stream "^2.0.0" - extend "^3.0.2" - google-gax "^3.0.1" - is "^3.3.0" - split-array-stream "^2.0.0" - stream-events "^1.0.5" - -"@google-cloud/promisify@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-2.0.3.tgz#f934b5cdc939e3c7039ff62b9caaf59a9d89e3a8" - integrity sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw== - -"@grpc/grpc-js@~1.6.0": - version "1.6.10" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.6.10.tgz#b6584c59ef90aa76d878ac92c21785e602f247ff" - integrity sha512-XTX5z/P5kH802MDoVm/rqOil0UwYEOEjf9+NPgfmm5UINIxDzwYaXfVR6z8svCBG8Hlbu/FzkXqhP8J5xaWzSQ== - dependencies: - "@grpc/proto-loader" "^0.7.0" - "@types/node" ">=12.12.47" - -"@grpc/proto-loader@^0.7.0": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.7.2.tgz#fa63178853afe1473c50cff89fe572f7c8b20154" - integrity sha512-jCdyLIT/tdQ1zhrbTQnJNK5nbDf0GoBpy5jVNywBzzMDF+Vs6uEaHnfz46dMtDxkvwrF2hzk5Z67goliceH0sA== - dependencies: - "@types/long" "^4.0.1" - lodash.camelcase "^4.3.0" - long "^4.0.0" - protobufjs "^7.0.0" - yargs "^16.2.0" - -"@humanwhocodes/config-array@^0.10.4": - version "0.10.4" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" - integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/gitignore-to-minimatch@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" - integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.15" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" - integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@lezer/common@^0.15.0", "@lezer/common@^0.15.7": - version "0.15.12" - resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.15.12.tgz#2f21aec551dd5fd7d24eb069f90f54d5bc6ee5e9" - integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== - -"@lezer/lr@^0.15.4": - version "0.15.8" - resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.8.tgz#1564a911e62b0a0f75ca63794a6aa8c5dc63db21" - integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== - dependencies: - "@lezer/common" "^0.15.0" - -"@lmdb/lmdb-darwin-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz#bc66fa43286b5c082e8fee0eacc17995806b6fbe" - integrity sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A== - -"@lmdb/lmdb-darwin-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz#89d8390041bce6bab24a82a20392be22faf54ffc" - integrity sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA== - -"@lmdb/lmdb-linux-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz#14fe4c96c2bb1285f93797f45915fa35ee047268" - integrity sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ== - -"@lmdb/lmdb-linux-arm@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz#05bde4573ab10cf21827339fe687148f2590cfa1" - integrity sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw== - -"@lmdb/lmdb-linux-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz#d2f85afd857d2c33d2caa5b057944574edafcfee" - integrity sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q== - -"@lmdb/lmdb-win32-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz#28f643fbc0bec30b07fbe95b137879b6b4d1c9c5" - integrity sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA== - -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.0.tgz#2b809e701da0f6729b47fe78ad4b9dc187a7d2e5" - integrity sha512-mEaiD1CURETR/dBIiJAwz0M0Q0mH3gCW4pPMaIlNt97mdzYUVeqGcTJSamgJpS6Tg4tBHDrOJpjdh5fJTLnyNQ== - dependencies: - detect-libc "^1.0.3" - http-proxy-agent "^4.0.1" - mkdirp "^1.0.4" - node-fetch "^2.6.1" - nopt "^5.0.0" - npmlog "^4.1.2" - rimraf "^3.0.2" - semver "^7.3.4" - tar "^6.1.0" - -"@mischnic/json-sourcemap@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz#38af657be4108140a548638267d02a2ea3336507" - integrity sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA== - dependencies: - "@lezer/common" "^0.15.7" - "@lezer/lr" "^0.15.4" - json5 "^2.2.1" - -"@msgpackr-extract/msgpackr-extract-darwin-arm64@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-2.1.2.tgz#9571b87be3a3f2c46de05585470bc4f3af2f6f00" - integrity sha512-TyVLn3S/+ikMDsh0gbKv2YydKClN8HaJDDpONlaZR+LVJmsxLFUgA+O7zu59h9+f9gX1aj/ahw9wqa6rosmrYQ== - -"@msgpackr-extract/msgpackr-extract-darwin-x64@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-2.1.2.tgz#bfbc6936ede2955218f5621a675679a5fe8e6f4c" - integrity sha512-YPXtcVkhmVNoMGlqp81ZHW4dMxK09msWgnxtsDpSiZwTzUBG2N+No2bsr7WMtBKCVJMSD6mbAl7YhKUqkp/Few== - -"@msgpackr-extract/msgpackr-extract-linux-arm64@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-2.1.2.tgz#22555e28382af2922e7450634c8a2f240bb9eb82" - integrity sha512-vHZ2JiOWF2+DN9lzltGbhtQNzDo8fKFGrf37UJrgqxU0yvtERrzUugnfnX1wmVfFhSsF8OxrfqiNOUc5hko1Zg== - -"@msgpackr-extract/msgpackr-extract-linux-arm@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-2.1.2.tgz#ffb6ae1beea7ac572b6be6bf2a8e8162ebdd8be7" - integrity sha512-42R4MAFeIeNn+L98qwxAt360bwzX2Kf0ZQkBBucJ2Ircza3asoY4CDbgiu9VWklq8gWJVSJSJBwDI+c/THiWkA== - -"@msgpackr-extract/msgpackr-extract-linux-x64@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-2.1.2.tgz#7caf62eebbfb1345de40f75e89666b3d4194755f" - integrity sha512-RjRoRxg7Q3kPAdUSC5EUUPlwfMkIVhmaRTIe+cqHbKrGZ4M6TyCA/b5qMaukQ/1CHWrqYY2FbKOAU8Hg0pQFzg== - -"@msgpackr-extract/msgpackr-extract-win32-x64@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-2.1.2.tgz#f2d8b9ddd8d191205ed26ce54aba3dfc5ae3e7c9" - integrity sha512-rIZVR48zA8hGkHIK7ED6+ZiXsjRCcAVBJbm8o89OKAMTmEAQ2QvoOxoiu3w2isAaWwzgtQIOFIqHwvZDyLKCvw== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@parcel/bundler-default@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.7.0.tgz#17d94be7185f29773aa21454063cbba3cdc03d49" - integrity sha512-PU5MtWWhc+dYI9x8mguYnm9yiG6TkI7niRpxgJgtqAyGHuEyNXVBQQ0X+qyOF4D9LdankBf8uNN18g31IET2Zg== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/cache@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.7.0.tgz#cc4b99685c7ff0fc20fbc321f4b6850d6e0c6811" - integrity sha512-JlXNoZXcWzLKdDlfeF3dIj5Vtel5T9vtdBN72PJ+cjC4qNHk4Uwvc5sfOBELuibGN0bVu2bwY9nUgSwCiB1iIA== - dependencies: - "@parcel/fs" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/utils" "2.7.0" - lmdb "2.5.2" - -"@parcel/codeframe@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.7.0.tgz#b6e4ad6100938edbed1b6c72b37f609e1abaf931" - integrity sha512-UTKx0jejJmmO1dwTHSJuRgrO8N6PMlkxRT6sew8N6NC3Bgv6pu0EbO+RtlWt/jCvzcdLOPdIoTzj4MMZvgcMYg== - dependencies: - chalk "^4.1.0" - -"@parcel/compressor-raw@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.7.0.tgz#3f8677e6371ef099cd9e4bd2a899884dc8eb571b" - integrity sha512-SCXwnOOQT6EmpusBsYWNQ/RFri+2JnKuE0gMSf2dROl2xbererX45FYzeDplWALCKAdjMNDpFwU+FyMYoVZSCQ== - dependencies: - "@parcel/plugin" "2.7.0" - -"@parcel/config-default@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.7.0.tgz#2f6cec9c185b89e40f343549295cad21295621a8" - integrity sha512-ZzsLr97AYrz8c9k6qn3DlqPzifi3vbP7q3ynUrAFxmt0L4+K0H9N508ZkORYmCgaFjLIQ8Y3eWpwCJ0AewPNIg== - dependencies: - "@parcel/bundler-default" "2.7.0" - "@parcel/compressor-raw" "2.7.0" - "@parcel/namer-default" "2.7.0" - "@parcel/optimizer-css" "2.7.0" - "@parcel/optimizer-htmlnano" "2.7.0" - "@parcel/optimizer-image" "2.7.0" - "@parcel/optimizer-svgo" "2.7.0" - "@parcel/optimizer-terser" "2.7.0" - "@parcel/packager-css" "2.7.0" - "@parcel/packager-html" "2.7.0" - "@parcel/packager-js" "2.7.0" - "@parcel/packager-raw" "2.7.0" - "@parcel/packager-svg" "2.7.0" - "@parcel/reporter-dev-server" "2.7.0" - "@parcel/resolver-default" "2.7.0" - "@parcel/runtime-browser-hmr" "2.7.0" - "@parcel/runtime-js" "2.7.0" - "@parcel/runtime-react-refresh" "2.7.0" - "@parcel/runtime-service-worker" "2.7.0" - "@parcel/transformer-babel" "2.7.0" - "@parcel/transformer-css" "2.7.0" - "@parcel/transformer-html" "2.7.0" - "@parcel/transformer-image" "2.7.0" - "@parcel/transformer-js" "2.7.0" - "@parcel/transformer-json" "2.7.0" - "@parcel/transformer-postcss" "2.7.0" - "@parcel/transformer-posthtml" "2.7.0" - "@parcel/transformer-raw" "2.7.0" - "@parcel/transformer-react-refresh-wrap" "2.7.0" - "@parcel/transformer-svg" "2.7.0" - -"@parcel/core@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.7.0.tgz#3310f48230bd618735f199f159f37e6b45ed2710" - integrity sha512-7yKZUdh314Q/kU/9+27ZYTfcnXS6VYHuG+iiUlIohnvUUybxLqVJhdMU9Q+z2QcPka1IdJWz4K4Xx0y6/4goyg== - dependencies: - "@mischnic/json-sourcemap" "^0.1.0" - "@parcel/cache" "2.7.0" - "@parcel/diagnostic" "2.7.0" - "@parcel/events" "2.7.0" - "@parcel/fs" "2.7.0" - "@parcel/graph" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/package-manager" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - "@parcel/workers" "2.7.0" - abortcontroller-polyfill "^1.1.9" - base-x "^3.0.8" - browserslist "^4.6.6" - clone "^2.1.1" - dotenv "^7.0.0" - dotenv-expand "^5.1.0" - json5 "^2.2.0" - msgpackr "^1.5.4" - nullthrows "^1.1.1" - semver "^5.7.1" - -"@parcel/css-darwin-arm64@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-darwin-arm64/-/css-darwin-arm64-1.12.2.tgz#4215585dac699f0f75015f5b47254867ac1221d3" - integrity sha512-6VvsoYSltBiUh/uyfPzQ+I3DiTFN7tmRv6zm1LH98J7GGCDDhbYEtbQjjCs15ex6fVn1ORZK0JO+mMlsg1JwTA== - -"@parcel/css-darwin-x64@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-darwin-x64/-/css-darwin-x64-1.12.2.tgz#eeb4e04c512580bd531b5ffa9c34456e9799fdb9" - integrity sha512-3J0/LrDvt5vevOisnrE0q5mEcuiAY+K7OZwIv84SAnrbjlL5sshmIaaNzL869kb4thza+RClEj0mS5XTm1IUEw== - -"@parcel/css-linux-arm-gnueabihf@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm-gnueabihf/-/css-linux-arm-gnueabihf-1.12.2.tgz#ccd813bbc9b9d845fb8f6ed9c7c22c745cda007b" - integrity sha512-OsX7I3dhBvnxEbAH++08RFe7yhjRp33ulzrCvJTMOP9YkxEEJ8qId3sNzJBHIVQzHyTlPTnBRHbSDhU3TFe/eQ== - -"@parcel/css-linux-arm64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-gnu/-/css-linux-arm64-gnu-1.12.2.tgz#7959fbcbd38c9b9c2c24c6c2def4ec2df370b705" - integrity sha512-R1Kqw+1Rsru9Q4+qvUEC6B8P21bpqhuF9rv8GmBmmnF1i2hMZ1JiY+uh/ej8IaRV0O3fAHeQGIyGBWx6qWDpcw== - -"@parcel/css-linux-arm64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-musl/-/css-linux-arm64-musl-1.12.2.tgz#ffc3fc62db9b8a19f8be61028abbcb7c44d90fa6" - integrity sha512-nwixgM4SEgPUQata9aAiJW0A5Q9ms+xim1tXT1i+91kOei4Fu2Wr2OuofMk+mlhbgmGKCTcu4gzMPReGxUhuRA== - -"@parcel/css-linux-x64-gnu@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-gnu/-/css-linux-x64-gnu-1.12.2.tgz#15619756ba62558243ae996e257b1cca90f534eb" - integrity sha512-cJYVMHnQSGhDwQByyvjFZppjMBNlgxXl/R4cX5DwrQE0QZmK/42BYnMp92rvoprEG6LRyRoiGtCjyfYTPWajog== - -"@parcel/css-linux-x64-musl@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-musl/-/css-linux-x64-musl-1.12.2.tgz#de61e2bdec54609f7b681acfbd04e9fb57a5ef02" - integrity sha512-u9zdO/d831/74Tf+TdPUfaIuB9v6FD4Xz8UdWUDOXgQqaOlnJ9fAsAM39EkoWlMxPPljY3f4ay6irSe1a4XgSA== - -"@parcel/css-win32-x64-msvc@1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css-win32-x64-msvc/-/css-win32-x64-msvc-1.12.2.tgz#086586fce31d1e05340c2e31efc32d40aa9ee05a" - integrity sha512-kCAKr3vKqvPUv9oXBG3pGZQz5il3sEk35dpmTXFa/7eDNKR5XyLpiJs8JwWJTFfuUqroymDSXA1bCcjvNEYcAg== - -"@parcel/css@^1.12.2": - version "1.12.2" - resolved "https://registry.yarnpkg.com/@parcel/css/-/css-1.12.2.tgz#63eacc9fcdf58e4d9639db34271834394705b7b2" - integrity sha512-Sa0PvZu5u877CupQA8IjEATqjJFynBfA7LxbcyutFe2LDCRSqB5Bm08jKFScyaz56qjZNIxZxXk2SApNkOvoAA== - dependencies: - detect-libc "^1.0.3" - optionalDependencies: - "@parcel/css-darwin-arm64" "1.12.2" - "@parcel/css-darwin-x64" "1.12.2" - "@parcel/css-linux-arm-gnueabihf" "1.12.2" - "@parcel/css-linux-arm64-gnu" "1.12.2" - "@parcel/css-linux-arm64-musl" "1.12.2" - "@parcel/css-linux-x64-gnu" "1.12.2" - "@parcel/css-linux-x64-musl" "1.12.2" - "@parcel/css-win32-x64-msvc" "1.12.2" - -"@parcel/diagnostic@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.7.0.tgz#cf2596a20ce9277334616e12bbdac98490189e99" - integrity sha512-pdq/cTwVoL0n8yuDCRXFRSQHVWdmmIXPt3R3iT4KtYDYvOrMT2dLPT79IMqQkhYPANW8GuL15n/WxRngfRdkug== - dependencies: - "@mischnic/json-sourcemap" "^0.1.0" - nullthrows "^1.1.1" - -"@parcel/events@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.7.0.tgz#b6db8464d45626686134d412d3a36d024ffb1482" - integrity sha512-kQDwMKgZ1U4M/G17qeDYF6bW5kybluN6ajYPc7mZcrWg+trEI/oXi81GMFaMX0BSUhwhbiN5+/Vb2wiG/Sn6ig== - -"@parcel/fs-search@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/fs-search/-/fs-search-2.7.0.tgz#15e658006039ddc7b92528df5266ee2b9c47b6a4" - integrity sha512-K1Hv25bnRpwQVA15RvcRuB8ZhfclnCHA8N8L6w7Ul1ncSJDxCIkIAc5hAubYNNYW3kWjCC2SOaEgFKnbvMllEQ== - dependencies: - detect-libc "^1.0.3" - -"@parcel/fs@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.7.0.tgz#c9a0c60bdbef7101ff47f2db6b23814c3db06007" - integrity sha512-PU5fo4Hh8y03LZgemgVREttc0wyHQUNmsJCybxTB7EjJie2CqJRumo+DFppArlvdchLwJdc9em03yQV/GNWrEg== - dependencies: - "@parcel/fs-search" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - "@parcel/watcher" "^2.0.0" - "@parcel/workers" "2.7.0" - -"@parcel/graph@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-2.7.0.tgz#2ae326c62764aaa53324b89d9c83ec0bc6ad55bf" - integrity sha512-Q6E94GS6q45PtsZh+m+gvFRp/N1Qopxhu2sxjcWsGs5iBd6IWn2oYLWOH5iVzEjWuYpW2HkB08lH6J50O63uOA== - dependencies: - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/hash@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/hash/-/hash-2.7.0.tgz#8825cff69a0bc4816737415e6e2aa29e8671c0b1" - integrity sha512-k6bSKnIlPJMPU3yjQzfgfvF9zuJZGOAlJgzpL4BbWvdbE8BTdjzLcFn0Ujrtud94EgIkiXd22sC2HpCUWoHGdA== - dependencies: - detect-libc "^1.0.3" - xxhash-wasm "^0.4.2" - -"@parcel/logger@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.7.0.tgz#1aa1de0458bdd613714ce4031134d92135aec590" - integrity sha512-qjMY/bYo38+o+OiIrTRldU9CwL1E7J72t+xkTP8QIcUxLWz5LYR0YbynZUVulmBSfqsykjjxCy4a+8siVr+lPw== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/events" "2.7.0" - -"@parcel/markdown-ansi@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.7.0.tgz#4ba70e3661ce06cd8fd2eb3f7b84028853a586e4" - integrity sha512-ipOX0D6FVZFEXeb/z8MnTMq2RQEIuaILY90olVIuHEFLHHfOPEn+RK3u13HA1ChF5/9E3cMD79tu6x9JL9Kqag== - dependencies: - chalk "^4.1.0" - -"@parcel/namer-default@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.7.0.tgz#e008097586016f16509834db11985dcc772c314c" - integrity sha512-lIKMdsmi//7fepecNDYmJYzBlL91HifPsX03lJCdu1dC6q5fBs+gG0XjKKG7yPnSCw1qH/4m7drzt9+dRZYAHQ== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/node-resolver-core@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-2.7.0.tgz#468074aa58a2f0026a492607153079ebb16308e3" - integrity sha512-5UJQHalqMxdhJIs2hhqQzFfQpF7+NAowsRq064lYtiRvcD8wMr3OOQ9wd1iazGpFSl4JKdT7BwDU9/miDJmanQ== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - semver "^5.7.1" - -"@parcel/optimizer-css@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-css/-/optimizer-css-2.7.0.tgz#460cde19b9ee61efed577473cb0822796b6e8b1a" - integrity sha512-IfnOMACqhcAclKyOW9X9JpsknB6OShk9OVvb8EvbDTKHJhQHNNmzE88OkSI/pS3ZVZP9Zj+nWcVHguV+kvDeiQ== - dependencies: - "@parcel/css" "^1.12.2" - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - browserslist "^4.6.6" - nullthrows "^1.1.1" - -"@parcel/optimizer-htmlnano@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.7.0.tgz#d2e843b539a430fcca723f08efcee26f98b3d40b" - integrity sha512-5QrGdWS5Hi4VXE3nQNrGqugmSXt68YIsWwKRAdarOxzyULSJS3gbCiQOXqIPRJobfZjnSIcdtkyxSiCUe1inIA== - dependencies: - "@parcel/plugin" "2.7.0" - htmlnano "^2.0.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - svgo "^2.4.0" - -"@parcel/optimizer-image@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.7.0.tgz#180d7709e6268e0634967eb265bf901aba2471ce" - integrity sha512-EnaXz5UjR67FUu0BEcqZTT9LsbB/iFAkkghCotbnbOuC5QQsloq6tw54TKU3y+R3qsjgUoMtGxPcGfVoXxZXYw== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - "@parcel/workers" "2.7.0" - detect-libc "^1.0.3" - -"@parcel/optimizer-svgo@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.7.0.tgz#9b4ab38a9d3c99504cf399a5c7709e5d2a615e71" - integrity sha512-IO1JV4NpfP3V7FrhsqCcV8pDQIHraFi1/ZvEJyssITxjH49Im/txKlwMiQuZZryAPn8Xb8g395Muawuk6AK6sg== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - svgo "^2.4.0" - -"@parcel/optimizer-terser@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-terser/-/optimizer-terser-2.7.0.tgz#b9ef408f45714952d1502940b6a63e5ebd3f0940" - integrity sha512-07VZjIO8xsl2/WmS/qHI8lI/cpu47iS9eRpqwfZEEsdk1cfz50jhWkmFudHBxiHGMfcZ//1+DdaPg9RDBWZtZA== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - terser "^5.2.0" - -"@parcel/package-manager@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.7.0.tgz#5de1bf5c94d95330e98dffb2a66c22d1f20c4c8a" - integrity sha512-wmfSX1mRrTi8MeA4KrnPk/x7zGUsILCQmTo6lA4gygzAxDbM1pGuyFN8/Kt0y0SFO2lbljARtD/4an5qdotH+Q== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/fs" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - "@parcel/workers" "2.7.0" - semver "^5.7.1" - -"@parcel/packager-css@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.7.0.tgz#060af8b96e5ad53620b4021610364804e26d69b2" - integrity sha512-44nzZwu+ssGuiFmYM6cf/Y4iChiUZ4DUzzpegnGlhXtKJKe4NHntxThJynuRZWKN2AAf48avApDpimg2jW0KDw== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/packager-html@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.7.0.tgz#4f86698d05f5ec5c3ebc8b46102a6ae42c58a24a" - integrity sha512-Zgqd7sdcY/UnR370GR0q2ilmEohUDXsO8A1F28QCJzIsR1iCB6KRUT74+pawfQ1IhXZLaaFLLYe0UWcfm0JeXg== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - -"@parcel/packager-js@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.7.0.tgz#e694cc731d75697e63d3d4be0bdbbe4a2ae8f1fc" - integrity sha512-wTRdM81PgRVDzWGXdWmqLwguWnTYWzhEDdjXpW2n8uMOu/CjHhMtogk65aaYk3GOnq6OBL/NsrmBiV/zKPj1vA== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - globals "^13.2.0" - nullthrows "^1.1.1" - -"@parcel/packager-raw@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.7.0.tgz#5b68de05c19bbcf438f40b4ae9f45411ba9739bd" - integrity sha512-jg2Zp8dI5VpIQlaeahXDCfrPN9m/DKht1NkR9P2CylMAwqCcc1Xc1RRiF0wfwcPZpPMpq1265n+4qnB7rjGBlA== - dependencies: - "@parcel/plugin" "2.7.0" - -"@parcel/packager-svg@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.7.0.tgz#e7e96503c86815eca285b9cc8908105075d9ab38" - integrity sha512-EmJg3HpD6/xxKBjir/CdCKJZwI24iVfBuxRS9LUp3xHAIebOzVh1z6IN+i2Di5+NyRwfOFaLliL4uMa1zwbyCA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - posthtml "^0.16.4" - -"@parcel/plugin@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.7.0.tgz#0211281025d02afbc5a23fba237b7aae02e34e51" - integrity sha512-qqgx+nnMn6/0lRc4lKbLGmhNtBiT93S2gFNB4Eb4Pfz/SxVYoW+fmml+KdfOSiZffWOAH5L6NwhyD7N8aSikzw== - dependencies: - "@parcel/types" "2.7.0" - -"@parcel/reporter-cli@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.7.0.tgz#86499624e258034001b64c10b14e23ae4b92f44b" - integrity sha512-80gEODg8cnAmnxGVuaSVDo8JJ54P9AA2bHwSs1cIkHWlJ3BjDQb83H31bBHncJ5Kn5kQ/j+7WjlqHpTCiOR9PA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - chalk "^4.1.0" - term-size "^2.2.1" - -"@parcel/reporter-dev-server@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.7.0.tgz#9bd3d10f745e0cbc9ab983ec046953c2c564dcb2" - integrity sha512-ySuou5addK8fGue8aXzo536BaEjMujDrEc1xkp4TasInXHVcA98b+SYX5NAZTGob5CxKvZQ5ylhg77zW30B+iA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - -"@parcel/resolver-default@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.7.0.tgz#648a257b81abe2eda09700d8f36348a88ea0442e" - integrity sha512-v8TvWsbLK7/q7n4gv6OrYNbW18xUx4zKbVMGZb1u4yMhzEH4HFr1D9OeoTq3jk+ximAigds8B6triQbL5exF7A== - dependencies: - "@parcel/node-resolver-core" "2.7.0" - "@parcel/plugin" "2.7.0" - -"@parcel/runtime-browser-hmr@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.7.0.tgz#aed79b96c0d97021f56f2b7e35bc2d4f70869e26" - integrity sha512-PLbMLdclQeYsi2LkilZVGFV1n3y55G1jaBvby4ekedUZjMw3SWdMY2tDxgSDdFWfLCnYHJXdGUQSzGGi1kPzjA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - -"@parcel/runtime-js@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.7.0.tgz#63dd744e96c3554ac86778ffce1c8055e7653fce" - integrity sha512-9/YUZTBNrSN2H6rbz/o1EOM0O7I3ZR/x9IDzxjJBD6Mi+0uCgCD02aedare/SNr1qgnbZZWmhpOzC+YgREcfLA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/runtime-react-refresh@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.7.0.tgz#c56b847ef1144264e918339381e040ffe811efc5" - integrity sha512-vDKO0rWqRzEpmvoZ4kkYUiSsTxT5NnH904BFPFxKI0wJCl6yEmPuEifmATo73OuYhP6jIP3Qfl1R4TtiDFPJ1Q== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - react-error-overlay "6.0.9" - react-refresh "^0.9.0" - -"@parcel/runtime-service-worker@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.7.0.tgz#352c3722ec635eee2898d9698541e3c1f53e8906" - integrity sha512-uD2pAV0yV6+e7JaWH4KVPbG+zRCrxr/OACyS9tIh+Q/R1vRmh8zGM3yhdrcoiZ7tFOnM72vd6xY11eTrUsSVig== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/source-map@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@parcel/source-map/-/source-map-2.1.0.tgz#bd47aa0a93ae261436f7c5da40b09856e1a331d5" - integrity sha512-E7UOEIof2o89LrKk1agSLmwakjigmEdDp1ZaEdsLVEvq63R/bul4Ij5CT+0ZDcijGpl5tnTbQADY9EyYGtjYgQ== - dependencies: - detect-libc "^1.0.3" - -"@parcel/transformer-babel@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.7.0.tgz#eae98d50a99cd722c3146cd57c479bfb86f537b2" - integrity sha512-7iklDXXnKH1530+QbI+e4kIJ+Q1puA1ulRS10db3aUJMj5GnvXGDFwhSZ7+T1ps66QHO7cVO29VlbqiRDarH1Q== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - browserslist "^4.6.6" - json5 "^2.2.0" - nullthrows "^1.1.1" - semver "^5.7.0" - -"@parcel/transformer-css@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.7.0.tgz#d0879ec04191e5ba3eadb6fc06b7ec0db3f5c3f6" - integrity sha512-J4EpWK9spQpXyNCmKK8Xnane0xW/1B/EAmfp7Fiv7g+5yUjY4ODf4KUugvE+Eb2gekPkhOKNHermO2KrX0/PFA== - dependencies: - "@parcel/css" "^1.12.2" - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - browserslist "^4.6.6" - nullthrows "^1.1.1" - -"@parcel/transformer-html@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.7.0.tgz#5397a924fea683ef2c345f36f99f67f0181d6967" - integrity sha512-wYJl5rn81W+Rlk9oQwDJcjoVsWVDKyeri84FzmlGXOsg0EYgnqOiG+3MDM8GeZjfuGe5fuoum4eqZeS0WdUHXw== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/plugin" "2.7.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - -"@parcel/transformer-image@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.7.0.tgz#e569ffc426c6060bc4dcccc0347c526930abfba4" - integrity sha512-mhi9/R5/ULhCkL2COVIKhNFoLDiZwQgprdaTJr5fnODggVxEX5o7ebFV6KNLMTEkwZUJWoB1hL0ziI0++DtoFA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - "@parcel/workers" "2.7.0" - nullthrows "^1.1.1" - -"@parcel/transformer-js@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.7.0.tgz#1e69295a11bf70d880cdd3846cf89016a74aac50" - integrity sha512-mzerR+D4rDomUSIk5RSTa2w+DXBdXUeQrpDO74WCDdpDi1lIl8ppFpqtmU7O6y6p8QsgkmS9b0g/vhcry6CJTA== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/utils" "2.7.0" - "@parcel/workers" "2.7.0" - "@swc/helpers" "^0.4.2" - browserslist "^4.6.6" - detect-libc "^1.0.3" - nullthrows "^1.1.1" - regenerator-runtime "^0.13.7" - semver "^5.7.1" - -"@parcel/transformer-json@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.7.0.tgz#c203f74cd445ce93eb833dd88be8127d1eadc6c3" - integrity sha512-RQjuxBpYOch+kr4a0zi77KJtOLTPYRM7iq4NN80zKnA0r0dwDUCxZBtaj2l0O0o3R4MMJnm+ncP+cB7XR7dZYA== - dependencies: - "@parcel/plugin" "2.7.0" - json5 "^2.2.0" - -"@parcel/transformer-postcss@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.7.0.tgz#66be4469ae9186c89638ff67ec5808139caaeb8e" - integrity sha512-b6RskXBWf0MjpC9qjR2dQ1ZdRnlOiKYseG5CEovWCqM218RtdydFKz7jS+5Gxkb6qBtOG7zGPONXdPe+gTILcA== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - clone "^2.1.1" - nullthrows "^1.1.1" - postcss-value-parser "^4.2.0" - semver "^5.7.1" - -"@parcel/transformer-posthtml@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.7.0.tgz#67d5761b895574edb771f7ab1b24ec80775f58bd" - integrity sha512-cP8YOiSynWJ1ycmBlhnnHeuQb2cwmklZ+BNyLUktj5p78kDy2de7VjX+dRNRHoW4H9OgEcSF4UEfDVVz5RYIhw== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - -"@parcel/transformer-raw@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.7.0.tgz#d6d8b94d1b33efc3dbf748ec1954c8917a2e1566" - integrity sha512-sDnItWCFSDez0izK1i5cgv+kXzZTbcJh4rNpVIgmE1kBLvAz608sqgcCkavb2wVJIvLesxYM+5G4p1CwkDlZ1g== - dependencies: - "@parcel/plugin" "2.7.0" - -"@parcel/transformer-react-refresh-wrap@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.7.0.tgz#e206b529d4a3444e14ba329d3323c5be3ded25d2" - integrity sha512-1vRmIJzyBA1nIiXTAU6tZExq2FvJj/2F0ft6KDw8GYPv0KjmdiPo/PmaZ7JeSVOM6SdXQIQCbTmp1vkMP7DtkA== - dependencies: - "@parcel/plugin" "2.7.0" - "@parcel/utils" "2.7.0" - react-refresh "^0.9.0" - -"@parcel/transformer-svg@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.7.0.tgz#c2a7d10bdbc6aeb2ae7ef85db5b583574807071c" - integrity sha512-ioER37zceuuE+K6ZrnjCyMUWEnv+63hIAFResc1OXxRhyt+7kzMz9ZqK0Mt6QMLwl1dxhkLmrU41n9IxzKZuSQ== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/plugin" "2.7.0" - nullthrows "^1.1.1" - posthtml "^0.16.5" - posthtml-parser "^0.10.1" - posthtml-render "^3.0.0" - semver "^5.7.1" - -"@parcel/types@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.7.0.tgz#c89e95964339324c1931ef7a17906a72291d6b73" - integrity sha512-+dhXVUnseTCpJvBTGMp0V6X13z6O/A/+CUtwEpMGZ8XSmZ4Gk44GvaTiBOp0bJpWG4fvCKp+UmC8PYbrDiiziw== - dependencies: - "@parcel/cache" "2.7.0" - "@parcel/diagnostic" "2.7.0" - "@parcel/fs" "2.7.0" - "@parcel/package-manager" "2.7.0" - "@parcel/source-map" "^2.0.0" - "@parcel/workers" "2.7.0" - utility-types "^3.10.0" - -"@parcel/utils@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.7.0.tgz#f795d0f43efdd449ab0bbfac3632cd7f3ec0e4dd" - integrity sha512-jNZ5bIGg1r1RDRKi562o4kuVwnz+XJ2Ie3b0Zwrqwvgfj6AbRFIKzDd+h85dWWmcDYzKUbHp11u6VJl1u8Vapg== - dependencies: - "@parcel/codeframe" "2.7.0" - "@parcel/diagnostic" "2.7.0" - "@parcel/hash" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/markdown-ansi" "2.7.0" - "@parcel/source-map" "^2.0.0" - chalk "^4.1.0" - -"@parcel/watcher@^2.0.0": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.5.tgz#f913a54e1601b0aac972803829b0eece48de215b" - integrity sha512-x0hUbjv891omnkcHD7ZOhiyyUqUUR6MNjq89JhEI3BxppeKWAm6NPQsqqRrAkCJBogdT/o/My21sXtTI9rJIsw== - dependencies: - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@parcel/workers@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.7.0.tgz#d74955d361337127227912a5ab26cb3079ebfc78" - integrity sha512-99VfaOX+89+RaoTSyH9ZQtkMBFZBFMvJmVJ/GeJT6QCd2wtKBStTHlaSnQOkLD/iRjJCNwV2xpZmm8YkTwV+hg== - dependencies: - "@parcel/diagnostic" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/types" "2.7.0" - "@parcel/utils" "2.7.0" - chrome-trace-event "^1.0.2" - nullthrows "^1.1.1" - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= - -"@swc/helpers@^0.4.2": - version "0.4.7" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.7.tgz#25a32e462e799a5a102eb9c241f73bbc4cb806a7" - integrity sha512-jJKr/2JOivCQxb5Xpli3asedRLH34QgJ3G+7gm6CoCOwt/LDDX9g67OuxvjFOiYZfngWYB66ZbjU6cUNtQdavg== - dependencies: - tslib "^2.4.0" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - -"@types/linkify-it@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" - integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== - -"@types/long@^4.0.0", "@types/long@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" - integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== - -"@types/markdown-it@^12.2.3": - version "12.2.3" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" - integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== - dependencies: - "@types/linkify-it" "*" - "@types/mdurl" "*" - -"@types/mdurl@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== - -"@types/node@>=12.12.47": - version "14.14.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055" - integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g== - -"@types/node@>=13.7.0": - version "18.7.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.8.tgz#6bbf2be6fbf9c187a5040d4277d24a06a18957a1" - integrity sha512-/YP55EMK2341JkODUb8DM9O0x1SIz2aBvyF33Uf1c76St3VpsMXEIW0nxuKkq/5cxnbz0RD9cfwNZHEAZQD3ag== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abortcontroller-polyfill@^1.1.9: - version "1.7.3" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" - integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^8.5.0, acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -arrify@^2.0.0, arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base-x@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.0.1.tgz#f1a2c20f208e2ccdceea4433df0c8b2c54ecdf71" - integrity sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - node-addon-api "^3.1.0" - -bignumber.js@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== - 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.10.3" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.6.6: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== - dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" - -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -caniuse-lite@^1.0.30001370: - version "1.0.30001379" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001379.tgz#c42f61d3ee45152ad0fa5005a6b5b34c27797a07" - integrity sha512-zXf+qxuN8OJrK5Bl5HbJg8cc5/Zm01WNW4ooVWUh92YlKqQZW3fwN5lXLB+kI8wkP5vTWkIIN+rutZuJhf4ykw== - -catharsis@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" - integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== - dependencies: - lodash "^4.17.15" - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - 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" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^7.0.0, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cors@^2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cosmiconfig@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== - 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" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - -dayjs@^1.11.5: - version "1.11.5" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93" - integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - -dotenv@^16.0.1: - version "16.0.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" - integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== - -dotenv@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" - integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== - -duplexify@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.1.tgz#7027dc374f157b122a8ae08c2d3ea4d2d953aa61" - integrity sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA== - dependencies: - end-of-stream "^1.4.1" - inherits "^2.0.3" - readable-stream "^3.1.1" - stream-shift "^1.0.0" - -ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-to-chromium@^1.4.202: - version "1.4.225" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz#3e27bdd157cbaf19768141f2e0f0f45071e52338" - integrity sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== - -entities@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^1.13.0: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@^8.22.0: - version "8.22.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48" - integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA== - dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.10.4" - "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.3.3" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" - globby "^11.1.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^9.0.0, espree@^9.3.2, espree@^9.3.3: - version "9.3.3" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" - integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" - -esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -express@^4.18.1: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.0" - 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.10.3" - 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" - -extend@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - 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" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-text-encoding@^1.0.0, fast-text-encoding@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" - integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - 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" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gaxios@^5.0.0, gaxios@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-5.0.1.tgz#50fc76a2d04bc1700ed8c3ff1561e52255dfc6e0" - integrity sha512-keK47BGKHyyOVQxgcUaSaFvr3ehZYAlvhvpHXy0YB2itzZef+GqZR8TBsfVRWghdwlKrYsn+8L8i3eblF7Oviw== - dependencies: - extend "^3.0.2" - https-proxy-agent "^5.0.0" - is-stream "^2.0.0" - node-fetch "^2.6.7" - -gcp-metadata@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-5.0.0.tgz#a00f999f60a4461401e7c515f8a3267cfb401ee7" - integrity sha512-gfwuX3yA3nNsHSWUL4KG90UulNiq922Ukj3wLTrcnX33BB7PwB1o0ubR8KVvXu9nJH+P5w1j2SQSNNqto+H0DA== - dependencies: - gaxios "^5.0.0" - json-bigint "^1.0.0" - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" - integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-port@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" - integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^8.0.0: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -globals@^13.15.0, globals@^13.2.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -google-auth-library@^8.0.2: - version "8.3.0" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-8.3.0.tgz#9286a613ee089f1d1728c07b9a302a22acf2dc2a" - integrity sha512-rXasaUScggvyD5ELpQC7SIOUOdqyOIifCK9TRDOLFEcuw1JxuyewKAwDs2QiKzMf8uLa0L360W0bVlV+sJDc8g== - dependencies: - arrify "^2.0.0" - base64-js "^1.3.0" - ecdsa-sig-formatter "^1.0.11" - fast-text-encoding "^1.0.0" - gaxios "^5.0.0" - gcp-metadata "^5.0.0" - gtoken "^6.0.0" - jws "^4.0.0" - lru-cache "^6.0.0" - -google-gax@^3.0.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-3.2.1.tgz#1562ac3f7e0403daa114ee47f5f821eaa9498a78" - integrity sha512-vWUFzAd/WaEgTOIMuQjjsGC9awlHy5Kl83kO+mVibSTloQjWlfa1k5FklFpnFMCcusMJvGgg0PlzDZS8sl0w8w== - dependencies: - "@grpc/grpc-js" "~1.6.0" - "@grpc/proto-loader" "^0.7.0" - "@types/long" "^4.0.0" - abort-controller "^3.0.0" - duplexify "^4.0.0" - fast-text-encoding "^1.0.3" - google-auth-library "^8.0.2" - is-stream-ended "^0.1.4" - node-fetch "^2.6.1" - object-hash "^3.0.0" - proto3-json-serializer "^1.0.0" - protobufjs "7.0.0" - protobufjs-cli "1.0.0" - retry-request "^5.0.0" - -google-p12-pem@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-4.0.0.tgz#f46581add1dc6ea0b96160cda6ce37ee35ab8ca3" - integrity sha512-lRTMn5ElBdDixv4a86bixejPSRk1boRtUowNepeKEVvYiFlkLuAJUVpEz6PfObDHYEKnZWq/9a2zC98xu62A9w== - dependencies: - node-forge "^1.3.1" - -graceful-fs@^4.1.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -gtoken@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-6.1.1.tgz#29ebf3e6893719176d180f5694f1cad525ce3c04" - integrity sha512-HPM4VzzPEGxjQ7T2xLrdSYBs+h1c0yHAUiN+8RHPDoiZbndlpg9Sx3SjWcrTt9+N3FHsSABEpjvdQVan5AAuZQ== - dependencies: - gaxios "^5.0.1" - google-p12-pem "^4.0.0" - jws "^4.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -htmlnano@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.0.2.tgz#3e3170941e2446a86211196d740272ebca78f878" - integrity sha512-+ZrQFS4Ub+zd+/fWwfvoYCEGNEa0/zrpys6CyXxvZDwtL7Pl+pOtRkiujyvBQ7Lmfp7/iEPxtOFgxWA16Gkj3w== - dependencies: - cosmiconfig "^7.0.1" - posthtml "^0.16.5" - timsort "^0.3.0" - -htmlparser2@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5" - integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.2" - domutils "^2.8.0" - entities "^3.0.1" - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - 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" - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== - -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-json@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff" - integrity sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-stream-ended@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-stream-ended/-/is-stream-ended-0.1.4.tgz#f50224e95e06bce0e356d440a4827cd35b267eda" - integrity sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw== - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/is/-/is-3.3.0.tgz#61cff6dd3c4193db94a3d62582072b44e5645d79" - integrity sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js2xmlparser@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.2.tgz#2a1fdf01e90585ef2ae872a01bc169c6a8d5e60a" - integrity sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA== - dependencies: - xmlcreate "^2.0.4" - -jsdoc@^3.6.3: - version "3.6.11" - resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.11.tgz#8bbb5747e6f579f141a5238cbad4e95e004458ce" - integrity sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg== - dependencies: - "@babel/parser" "^7.9.4" - "@types/markdown-it" "^12.2.3" - bluebird "^3.7.2" - catharsis "^0.9.0" - escape-string-regexp "^2.0.0" - js2xmlparser "^4.0.2" - klaw "^3.0.0" - markdown-it "^12.3.2" - markdown-it-anchor "^8.4.1" - marked "^4.0.10" - mkdirp "^1.0.4" - requizzle "^0.2.3" - strip-json-comments "^3.1.0" - taffydb "2.6.2" - underscore "~1.13.2" - -json-bigint@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" - integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== - dependencies: - bignumber.js "^9.0.0" - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^2.2.0, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -jwa@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" - integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" - integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== - dependencies: - jwa "^2.0.0" - safe-buffer "^5.0.1" - -klaw@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" - integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== - dependencies: - graceful-fs "^4.1.9" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -linkify-it@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" - integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== - dependencies: - uc.micro "^1.0.1" - -lmdb@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.5.2.tgz#37e28a9fb43405f4dc48c44cec0e13a14c4a6ff1" - integrity sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA== - dependencies: - msgpackr "^1.5.4" - node-addon-api "^4.3.0" - node-gyp-build-optional-packages "5.0.3" - ordered-binary "^1.2.4" - weak-lru-cache "^1.2.2" - optionalDependencies: - "@lmdb/lmdb-darwin-arm64" "2.5.2" - "@lmdb/lmdb-darwin-x64" "2.5.2" - "@lmdb/lmdb-linux-arm" "2.5.2" - "@lmdb/lmdb-linux-arm64" "2.5.2" - "@lmdb/lmdb-linux-x64" "2.5.2" - "@lmdb/lmdb-win32-x64" "2.5.2" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.14, lodash@^4.17.15: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" - integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -markdown-it-anchor@^8.4.1: - version "8.6.4" - resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-8.6.4.tgz#affb8aa0910a504c114e9fcad53ac3a5b907b0e6" - integrity sha512-Ul4YVYZNxMJYALpKtu+ZRdrryYt/GlQ5CK+4l1bp/gWXOG2QWElt6AqF3Mih/wfUKdZbNAZVXGR73/n6U/8img== - -markdown-it@^12.3.2: - version "12.3.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" - integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== - dependencies: - argparse "^2.0.1" - entities "~2.1.0" - linkify-it "^3.0.1" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -marked@^4.0.10: - version "4.0.18" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" - integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.46.0: - version "1.46.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" - integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@~2.1.24: - version "2.1.29" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" - integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== - dependencies: - mime-db "1.46.0" - -mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== - -minipass@^3.0.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -msgpackr-extract@^2.0.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-2.1.2.tgz#56272030f3e163e1b51964ef8b1cd5e7240c03ed" - integrity sha512-cmrmERQFb19NX2JABOGtrKdHMyI6RUyceaPBQ2iRz9GnDkjBWFjNJC0jyyoOfZl2U/LZE3tQCCQc4dlRyA8mcA== - dependencies: - node-gyp-build-optional-packages "5.0.3" - optionalDependencies: - "@msgpackr-extract/msgpackr-extract-darwin-arm64" "2.1.2" - "@msgpackr-extract/msgpackr-extract-darwin-x64" "2.1.2" - "@msgpackr-extract/msgpackr-extract-linux-arm" "2.1.2" - "@msgpackr-extract/msgpackr-extract-linux-arm64" "2.1.2" - "@msgpackr-extract/msgpackr-extract-linux-x64" "2.1.2" - "@msgpackr-extract/msgpackr-extract-win32-x64" "2.1.2" - -msgpackr@^1.5.4: - version "1.6.2" - resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.6.2.tgz#176cd9f6b4437dad87a839b37f23c2dfee408d9a" - integrity sha512-bqSQ0DYJbXbrJcrZFmMygUZmqQiDfI2ewFVWcrZY12w5XHWtPuW4WppDT/e63Uu311ajwkRRXSoF0uILroBeTA== - optionalDependencies: - msgpackr-extract "^2.0.2" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -node-addon-api@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" - integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== - -node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - -node-gyp-build-optional-packages@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" - integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== - -node-gyp-build@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" - integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== - -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - -nodemon@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.19.tgz#cac175f74b9cb8b57e770d47841995eebe4488bd" - integrity sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A== - dependencies: - chokidar "^3.5.2" - debug "^3.2.7" - ignore-by-default "^1.0.1" - minimatch "^3.0.4" - 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" - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -nullthrows@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" - integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -object-assign@^4, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" - integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== - -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - 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" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ordered-binary@^1.2.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.3.0.tgz#a116d64c923278216e335602d279750b2ebd746e" - integrity sha512-knIeYepTI6BDAzGxqFEDGtI/iGqs57H32CInAIxEvAHG46vk1Di0CEpyc1A7iY39B1mfik3g3KLYwOTNnnMHLA== - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -parcel@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.7.0.tgz#41fdd3e5c7144d4cf7f1fa3ab8d0ea0d47d31f77" - integrity sha512-pRYwnivwtNP0tip8xYSo4zCB0XhLt7/gJzP1p8OovCqkmFjG9VG+GW9TcAKqMIo0ovEa9tT+/s6gY1Qy+BONGQ== - dependencies: - "@parcel/config-default" "2.7.0" - "@parcel/core" "2.7.0" - "@parcel/diagnostic" "2.7.0" - "@parcel/events" "2.7.0" - "@parcel/fs" "2.7.0" - "@parcel/logger" "2.7.0" - "@parcel/package-manager" "2.7.0" - "@parcel/reporter-cli" "2.7.0" - "@parcel/reporter-dev-server" "2.7.0" - "@parcel/utils" "2.7.0" - chalk "^4.1.0" - commander "^7.0.0" - get-port "^4.2.0" - v8-compile-cache "^2.0.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - 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" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -posthtml-parser@^0.10.1: - version "0.10.2" - resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573" - integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg== - dependencies: - htmlparser2 "^7.1.1" - -posthtml-parser@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.11.0.tgz#25d1c7bf811ea83559bc4c21c189a29747a24b7a" - integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw== - dependencies: - htmlparser2 "^7.1.1" - -posthtml-render@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-3.0.0.tgz#97be44931496f495b4f07b99e903cc70ad6a3205" - integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA== - dependencies: - is-json "^2.0.1" - -posthtml@^0.16.4, posthtml@^0.16.5: - version "0.16.6" - resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.16.6.tgz#e2fc407f67a64d2fa3567afe770409ffdadafe59" - integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ== - dependencies: - posthtml-parser "^0.11.0" - posthtml-render "^3.0.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proto3-json-serializer@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/proto3-json-serializer/-/proto3-json-serializer-1.0.3.tgz#c23a037eb7c3c7d963a0976fa8b09e942ac83fbe" - integrity sha512-4Xo7uzbTfc8ur9R8VgI0pJpI6aHix76cc7DHJEfZKrZ6vOUbOddxBrsMzAGG2s6b3iHknl4Gn50dA2Y3AoCdow== - dependencies: - protobufjs "^7.0.0" - -protobufjs-cli@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/protobufjs-cli/-/protobufjs-cli-1.0.0.tgz#62f99de142118f34c7b4ee53c2dc122612d2711c" - integrity sha512-7NZEBrFuuU2ZdzlhmAmvh8fdU7A4OFhzYX9AB7a5vXjopAeiks6ZgUSjOlOO7ItCDJQm3y9RWjk7spUbHc4X0w== - dependencies: - chalk "^4.0.0" - escodegen "^1.13.0" - espree "^9.0.0" - estraverse "^5.1.0" - glob "^8.0.0" - jsdoc "^3.6.3" - minimist "^1.2.0" - semver "^7.1.2" - tmp "^0.2.1" - uglify-js "^3.7.7" - -protobufjs@7.0.0, protobufjs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.0.0.tgz#8c678e1351fd926178fce5a4213913e8d990974f" - integrity sha512-ffNIEm+quOcYtQvHdW406v1NQmZSuqVklxsXk076BtuFnlYZfigLU+JOMrTD8TUOyqHYbRI/fSVNvgd25YeN3w== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^5.0.0" - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -pstree.remy@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - 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" - -react-error-overlay@6.0.9: - version "6.0.9" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" - integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== - -react-refresh@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" - integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== - -readable-stream@^2.0.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - 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" - -readable-stream@^3.0.2, readable-stream@^3.1.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.13.7: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -requizzle@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.3.tgz#4675c90aacafb2c036bd39ba2daa4a1cb777fded" - integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== - dependencies: - lodash "^4.17.14" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -retry-request@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-5.0.1.tgz#c6be2a4a36f1554ba3251fa8fd945af26ee0e9ec" - integrity sha512-lxFKrlBt0OZzCWh/V0uPEN0vlr3OhdeXnpeY5OES+ckslm791Cb1D5P7lJUSnY7J5hiCjcyaUGmzCnIGDCUBig== - dependencies: - debug "^4.1.1" - extend "^3.0.2" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^7.1.2: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -semver@^7.3.4: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== - dependencies: - lru-cache "^6.0.0" - -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - 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" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -simple-update-notifier@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz#7edf75c5bdd04f88828d632f762b2bc32996a9cc" - integrity sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew== - dependencies: - semver "~7.0.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -split-array-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-2.0.0.tgz#85a4f8bfe14421d7bca7f33a6d176d0c076a53b1" - integrity sha512-hmMswlVY91WvGMxs0k8MRgq8zb2mSen4FmDNc5AFiTWtrBpdZN6nwD6kROVe4vNL+ywrvbCKsWVCnEd4riELIg== - dependencies: - is-stream-ended "^0.1.4" - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stream-events@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" - integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== - dependencies: - stubs "^3.0.0" - -stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -stubs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" - integrity sha1-6NK6H6nJBXAwPAMLaQD31fiavls= - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -svgo@^2.4.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - -taffydb@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" - integrity sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA== - -tar@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -term-size@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" - integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== - -terser@^5.2.0: - version "5.14.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" - integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A== - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -uglify-js@^3.7.7: - version "3.17.0" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85" - integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg== - -undefsafe@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" - integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== - -underscore@~1.13.2: - version "1.13.4" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.4.tgz#7886b46bbdf07f768e0052f1828e1dcab40c0dee" - integrity sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -v8-compile-cache@^2.0.0, v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -weak-lru-cache@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19" - integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -xmlcreate@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" - integrity sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg== - -xxhash-wasm@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79" - integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - 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" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/crabfit-frontend/.eslintrc.js b/frontend/.eslintrc.js similarity index 100% rename from crabfit-frontend/.eslintrc.js rename to frontend/.eslintrc.js diff --git a/crabfit-frontend/.gcloudignore b/frontend/.gcloudignore similarity index 100% rename from crabfit-frontend/.gcloudignore rename to frontend/.gcloudignore diff --git a/crabfit-frontend/.gitignore b/frontend/.gitignore similarity index 100% rename from crabfit-frontend/.gitignore rename to frontend/.gitignore diff --git a/crabfit-frontend/app.yaml b/frontend/app.yaml similarity index 100% rename from crabfit-frontend/app.yaml rename to frontend/app.yaml diff --git a/crabfit-frontend/index.html b/frontend/index.html similarity index 100% rename from crabfit-frontend/index.html rename to frontend/index.html diff --git a/crabfit-frontend/jsconfig.json b/frontend/jsconfig.json similarity index 100% rename from crabfit-frontend/jsconfig.json rename to frontend/jsconfig.json diff --git a/crabfit-frontend/package.json b/frontend/package.json similarity index 100% rename from crabfit-frontend/package.json rename to frontend/package.json diff --git a/crabfit-frontend/public/.well-known/assetlinks.json b/frontend/public/.well-known/assetlinks.json similarity index 100% rename from crabfit-frontend/public/.well-known/assetlinks.json rename to frontend/public/.well-known/assetlinks.json diff --git a/crabfit-frontend/public/.well-known/microsoft-identity-association.json b/frontend/public/.well-known/microsoft-identity-association.json similarity index 100% rename from crabfit-frontend/public/.well-known/microsoft-identity-association.json rename to frontend/public/.well-known/microsoft-identity-association.json diff --git a/crabfit-frontend/public/favicon.ico b/frontend/public/favicon.ico similarity index 100% rename from crabfit-frontend/public/favicon.ico rename to frontend/public/favicon.ico diff --git a/crabfit-frontend/public/fonts/karla-italic-variable.ttf b/frontend/public/fonts/karla-italic-variable.ttf similarity index 100% rename from crabfit-frontend/public/fonts/karla-italic-variable.ttf rename to frontend/public/fonts/karla-italic-variable.ttf diff --git a/crabfit-frontend/public/fonts/karla-variable.ttf b/frontend/public/fonts/karla-variable.ttf similarity index 100% rename from crabfit-frontend/public/fonts/karla-variable.ttf rename to frontend/public/fonts/karla-variable.ttf diff --git a/crabfit-frontend/public/fonts/molot.woff b/frontend/public/fonts/molot.woff similarity index 100% rename from crabfit-frontend/public/fonts/molot.woff rename to frontend/public/fonts/molot.woff diff --git a/crabfit-frontend/public/fonts/molot.woff2 b/frontend/public/fonts/molot.woff2 similarity index 100% rename from crabfit-frontend/public/fonts/molot.woff2 rename to frontend/public/fonts/molot.woff2 diff --git a/crabfit-frontend/public/fonts/samuraibob.woff b/frontend/public/fonts/samuraibob.woff similarity index 100% rename from crabfit-frontend/public/fonts/samuraibob.woff rename to frontend/public/fonts/samuraibob.woff diff --git a/crabfit-frontend/public/fonts/samuraibob.woff2 b/frontend/public/fonts/samuraibob.woff2 similarity index 100% rename from crabfit-frontend/public/fonts/samuraibob.woff2 rename to frontend/public/fonts/samuraibob.woff2 diff --git a/crabfit-frontend/public/i18n/de/common.json b/frontend/public/i18n/de/common.json similarity index 100% rename from crabfit-frontend/public/i18n/de/common.json rename to frontend/public/i18n/de/common.json diff --git a/crabfit-frontend/public/i18n/de/event.json b/frontend/public/i18n/de/event.json similarity index 100% rename from crabfit-frontend/public/i18n/de/event.json rename to frontend/public/i18n/de/event.json diff --git a/crabfit-frontend/public/i18n/de/help.json b/frontend/public/i18n/de/help.json similarity index 100% rename from crabfit-frontend/public/i18n/de/help.json rename to frontend/public/i18n/de/help.json diff --git a/crabfit-frontend/public/i18n/de/home.json b/frontend/public/i18n/de/home.json similarity index 100% rename from crabfit-frontend/public/i18n/de/home.json rename to frontend/public/i18n/de/home.json diff --git a/crabfit-frontend/public/i18n/de/privacy.json b/frontend/public/i18n/de/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/de/privacy.json rename to frontend/public/i18n/de/privacy.json diff --git a/crabfit-frontend/public/i18n/en-GB/common.json b/frontend/public/i18n/en-GB/common.json similarity index 100% rename from crabfit-frontend/public/i18n/en-GB/common.json rename to frontend/public/i18n/en-GB/common.json diff --git a/crabfit-frontend/public/i18n/en-GB/event.json b/frontend/public/i18n/en-GB/event.json similarity index 100% rename from crabfit-frontend/public/i18n/en-GB/event.json rename to frontend/public/i18n/en-GB/event.json diff --git a/crabfit-frontend/public/i18n/en-GB/help.json b/frontend/public/i18n/en-GB/help.json similarity index 100% rename from crabfit-frontend/public/i18n/en-GB/help.json rename to frontend/public/i18n/en-GB/help.json diff --git a/crabfit-frontend/public/i18n/en-GB/home.json b/frontend/public/i18n/en-GB/home.json similarity index 100% rename from crabfit-frontend/public/i18n/en-GB/home.json rename to frontend/public/i18n/en-GB/home.json diff --git a/crabfit-frontend/public/i18n/en-GB/privacy.json b/frontend/public/i18n/en-GB/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/en-GB/privacy.json rename to frontend/public/i18n/en-GB/privacy.json diff --git a/crabfit-frontend/public/i18n/en/common.json b/frontend/public/i18n/en/common.json similarity index 100% rename from crabfit-frontend/public/i18n/en/common.json rename to frontend/public/i18n/en/common.json diff --git a/crabfit-frontend/public/i18n/en/event.json b/frontend/public/i18n/en/event.json similarity index 100% rename from crabfit-frontend/public/i18n/en/event.json rename to frontend/public/i18n/en/event.json diff --git a/crabfit-frontend/public/i18n/en/help.json b/frontend/public/i18n/en/help.json similarity index 100% rename from crabfit-frontend/public/i18n/en/help.json rename to frontend/public/i18n/en/help.json diff --git a/crabfit-frontend/public/i18n/en/home.json b/frontend/public/i18n/en/home.json similarity index 100% rename from crabfit-frontend/public/i18n/en/home.json rename to frontend/public/i18n/en/home.json diff --git a/crabfit-frontend/public/i18n/en/privacy.json b/frontend/public/i18n/en/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/en/privacy.json rename to frontend/public/i18n/en/privacy.json diff --git a/crabfit-frontend/public/i18n/es/common.json b/frontend/public/i18n/es/common.json similarity index 100% rename from crabfit-frontend/public/i18n/es/common.json rename to frontend/public/i18n/es/common.json diff --git a/crabfit-frontend/public/i18n/es/event.json b/frontend/public/i18n/es/event.json similarity index 100% rename from crabfit-frontend/public/i18n/es/event.json rename to frontend/public/i18n/es/event.json diff --git a/crabfit-frontend/public/i18n/es/help.json b/frontend/public/i18n/es/help.json similarity index 100% rename from crabfit-frontend/public/i18n/es/help.json rename to frontend/public/i18n/es/help.json diff --git a/crabfit-frontend/public/i18n/es/home.json b/frontend/public/i18n/es/home.json similarity index 100% rename from crabfit-frontend/public/i18n/es/home.json rename to frontend/public/i18n/es/home.json diff --git a/crabfit-frontend/public/i18n/es/privacy.json b/frontend/public/i18n/es/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/es/privacy.json rename to frontend/public/i18n/es/privacy.json diff --git a/crabfit-frontend/public/i18n/fr/common.json b/frontend/public/i18n/fr/common.json similarity index 100% rename from crabfit-frontend/public/i18n/fr/common.json rename to frontend/public/i18n/fr/common.json diff --git a/crabfit-frontend/public/i18n/fr/event.json b/frontend/public/i18n/fr/event.json similarity index 100% rename from crabfit-frontend/public/i18n/fr/event.json rename to frontend/public/i18n/fr/event.json diff --git a/crabfit-frontend/public/i18n/fr/help.json b/frontend/public/i18n/fr/help.json similarity index 100% rename from crabfit-frontend/public/i18n/fr/help.json rename to frontend/public/i18n/fr/help.json diff --git a/crabfit-frontend/public/i18n/fr/home.json b/frontend/public/i18n/fr/home.json similarity index 100% rename from crabfit-frontend/public/i18n/fr/home.json rename to frontend/public/i18n/fr/home.json diff --git a/crabfit-frontend/public/i18n/fr/privacy.json b/frontend/public/i18n/fr/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/fr/privacy.json rename to frontend/public/i18n/fr/privacy.json diff --git a/crabfit-frontend/public/i18n/hi/common.json b/frontend/public/i18n/hi/common.json similarity index 100% rename from crabfit-frontend/public/i18n/hi/common.json rename to frontend/public/i18n/hi/common.json diff --git a/crabfit-frontend/public/i18n/hi/event.json b/frontend/public/i18n/hi/event.json similarity index 100% rename from crabfit-frontend/public/i18n/hi/event.json rename to frontend/public/i18n/hi/event.json diff --git a/crabfit-frontend/public/i18n/hi/help.json b/frontend/public/i18n/hi/help.json similarity index 100% rename from crabfit-frontend/public/i18n/hi/help.json rename to frontend/public/i18n/hi/help.json diff --git a/crabfit-frontend/public/i18n/hi/home.json b/frontend/public/i18n/hi/home.json similarity index 100% rename from crabfit-frontend/public/i18n/hi/home.json rename to frontend/public/i18n/hi/home.json diff --git a/crabfit-frontend/public/i18n/hi/privacy.json b/frontend/public/i18n/hi/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/hi/privacy.json rename to frontend/public/i18n/hi/privacy.json diff --git a/crabfit-frontend/public/i18n/hu-HU/privacy.json b/frontend/public/i18n/hu-HU/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/hu-HU/privacy.json rename to frontend/public/i18n/hu-HU/privacy.json diff --git a/crabfit-frontend/public/i18n/id/common.json b/frontend/public/i18n/id/common.json similarity index 100% rename from crabfit-frontend/public/i18n/id/common.json rename to frontend/public/i18n/id/common.json diff --git a/crabfit-frontend/public/i18n/id/event.json b/frontend/public/i18n/id/event.json similarity index 100% rename from crabfit-frontend/public/i18n/id/event.json rename to frontend/public/i18n/id/event.json diff --git a/crabfit-frontend/public/i18n/id/help.json b/frontend/public/i18n/id/help.json similarity index 100% rename from crabfit-frontend/public/i18n/id/help.json rename to frontend/public/i18n/id/help.json diff --git a/crabfit-frontend/public/i18n/id/home.json b/frontend/public/i18n/id/home.json similarity index 100% rename from crabfit-frontend/public/i18n/id/home.json rename to frontend/public/i18n/id/home.json diff --git a/crabfit-frontend/public/i18n/id/privacy.json b/frontend/public/i18n/id/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/id/privacy.json rename to frontend/public/i18n/id/privacy.json diff --git a/crabfit-frontend/public/i18n/it/common.json b/frontend/public/i18n/it/common.json similarity index 100% rename from crabfit-frontend/public/i18n/it/common.json rename to frontend/public/i18n/it/common.json diff --git a/crabfit-frontend/public/i18n/it/event.json b/frontend/public/i18n/it/event.json similarity index 100% rename from crabfit-frontend/public/i18n/it/event.json rename to frontend/public/i18n/it/event.json diff --git a/crabfit-frontend/public/i18n/it/help.json b/frontend/public/i18n/it/help.json similarity index 100% rename from crabfit-frontend/public/i18n/it/help.json rename to frontend/public/i18n/it/help.json diff --git a/crabfit-frontend/public/i18n/it/home.json b/frontend/public/i18n/it/home.json similarity index 100% rename from crabfit-frontend/public/i18n/it/home.json rename to frontend/public/i18n/it/home.json diff --git a/crabfit-frontend/public/i18n/it/privacy.json b/frontend/public/i18n/it/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/it/privacy.json rename to frontend/public/i18n/it/privacy.json diff --git a/crabfit-frontend/public/i18n/ja/common.json b/frontend/public/i18n/ja/common.json similarity index 100% rename from crabfit-frontend/public/i18n/ja/common.json rename to frontend/public/i18n/ja/common.json diff --git a/crabfit-frontend/public/i18n/ja/event.json b/frontend/public/i18n/ja/event.json similarity index 100% rename from crabfit-frontend/public/i18n/ja/event.json rename to frontend/public/i18n/ja/event.json diff --git a/crabfit-frontend/public/i18n/ja/home.json b/frontend/public/i18n/ja/home.json similarity index 100% rename from crabfit-frontend/public/i18n/ja/home.json rename to frontend/public/i18n/ja/home.json diff --git a/crabfit-frontend/public/i18n/ja/privacy.json b/frontend/public/i18n/ja/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/ja/privacy.json rename to frontend/public/i18n/ja/privacy.json diff --git a/crabfit-frontend/public/i18n/ko/common.json b/frontend/public/i18n/ko/common.json similarity index 100% rename from crabfit-frontend/public/i18n/ko/common.json rename to frontend/public/i18n/ko/common.json diff --git a/crabfit-frontend/public/i18n/ko/event.json b/frontend/public/i18n/ko/event.json similarity index 100% rename from crabfit-frontend/public/i18n/ko/event.json rename to frontend/public/i18n/ko/event.json diff --git a/crabfit-frontend/public/i18n/ko/help.json b/frontend/public/i18n/ko/help.json similarity index 100% rename from crabfit-frontend/public/i18n/ko/help.json rename to frontend/public/i18n/ko/help.json diff --git a/crabfit-frontend/public/i18n/ko/home.json b/frontend/public/i18n/ko/home.json similarity index 100% rename from crabfit-frontend/public/i18n/ko/home.json rename to frontend/public/i18n/ko/home.json diff --git a/crabfit-frontend/public/i18n/ko/privacy.json b/frontend/public/i18n/ko/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/ko/privacy.json rename to frontend/public/i18n/ko/privacy.json diff --git a/crabfit-frontend/public/i18n/pl/common.json b/frontend/public/i18n/pl/common.json similarity index 100% rename from crabfit-frontend/public/i18n/pl/common.json rename to frontend/public/i18n/pl/common.json diff --git a/crabfit-frontend/public/i18n/pl/home.json b/frontend/public/i18n/pl/home.json similarity index 100% rename from crabfit-frontend/public/i18n/pl/home.json rename to frontend/public/i18n/pl/home.json diff --git a/crabfit-frontend/public/i18n/pl/privacy.json b/frontend/public/i18n/pl/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/pl/privacy.json rename to frontend/public/i18n/pl/privacy.json diff --git a/crabfit-frontend/public/i18n/pt-BR/common.json b/frontend/public/i18n/pt-BR/common.json similarity index 100% rename from crabfit-frontend/public/i18n/pt-BR/common.json rename to frontend/public/i18n/pt-BR/common.json diff --git a/crabfit-frontend/public/i18n/pt-BR/event.json b/frontend/public/i18n/pt-BR/event.json similarity index 100% rename from crabfit-frontend/public/i18n/pt-BR/event.json rename to frontend/public/i18n/pt-BR/event.json diff --git a/crabfit-frontend/public/i18n/pt-BR/help.json b/frontend/public/i18n/pt-BR/help.json similarity index 100% rename from crabfit-frontend/public/i18n/pt-BR/help.json rename to frontend/public/i18n/pt-BR/help.json diff --git a/crabfit-frontend/public/i18n/pt-BR/home.json b/frontend/public/i18n/pt-BR/home.json similarity index 100% rename from crabfit-frontend/public/i18n/pt-BR/home.json rename to frontend/public/i18n/pt-BR/home.json diff --git a/crabfit-frontend/public/i18n/pt-BR/privacy.json b/frontend/public/i18n/pt-BR/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/pt-BR/privacy.json rename to frontend/public/i18n/pt-BR/privacy.json diff --git a/crabfit-frontend/public/i18n/pt_PT/common.json b/frontend/public/i18n/pt_PT/common.json similarity index 100% rename from crabfit-frontend/public/i18n/pt_PT/common.json rename to frontend/public/i18n/pt_PT/common.json diff --git a/crabfit-frontend/public/i18n/pt_PT/event.json b/frontend/public/i18n/pt_PT/event.json similarity index 100% rename from crabfit-frontend/public/i18n/pt_PT/event.json rename to frontend/public/i18n/pt_PT/event.json diff --git a/crabfit-frontend/public/i18n/pt_PT/help.json b/frontend/public/i18n/pt_PT/help.json similarity index 100% rename from crabfit-frontend/public/i18n/pt_PT/help.json rename to frontend/public/i18n/pt_PT/help.json diff --git a/crabfit-frontend/public/i18n/pt_PT/home.json b/frontend/public/i18n/pt_PT/home.json similarity index 100% rename from crabfit-frontend/public/i18n/pt_PT/home.json rename to frontend/public/i18n/pt_PT/home.json diff --git a/crabfit-frontend/public/i18n/pt_PT/privacy.json b/frontend/public/i18n/pt_PT/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/pt_PT/privacy.json rename to frontend/public/i18n/pt_PT/privacy.json diff --git a/crabfit-frontend/public/i18n/ru/common.json b/frontend/public/i18n/ru/common.json similarity index 100% rename from crabfit-frontend/public/i18n/ru/common.json rename to frontend/public/i18n/ru/common.json diff --git a/crabfit-frontend/public/i18n/ru/event.json b/frontend/public/i18n/ru/event.json similarity index 100% rename from crabfit-frontend/public/i18n/ru/event.json rename to frontend/public/i18n/ru/event.json diff --git a/crabfit-frontend/public/i18n/ru/help.json b/frontend/public/i18n/ru/help.json similarity index 100% rename from crabfit-frontend/public/i18n/ru/help.json rename to frontend/public/i18n/ru/help.json diff --git a/crabfit-frontend/public/i18n/ru/home.json b/frontend/public/i18n/ru/home.json similarity index 100% rename from crabfit-frontend/public/i18n/ru/home.json rename to frontend/public/i18n/ru/home.json diff --git a/crabfit-frontend/public/i18n/ru/privacy.json b/frontend/public/i18n/ru/privacy.json similarity index 100% rename from crabfit-frontend/public/i18n/ru/privacy.json rename to frontend/public/i18n/ru/privacy.json diff --git a/crabfit-frontend/public/index.css b/frontend/public/index.css similarity index 100% rename from crabfit-frontend/public/index.css rename to frontend/public/index.css diff --git a/crabfit-frontend/public/logo-icon.png b/frontend/public/logo-icon.png similarity index 100% rename from crabfit-frontend/public/logo-icon.png rename to frontend/public/logo-icon.png diff --git a/crabfit-frontend/public/logo192.png b/frontend/public/logo192.png similarity index 100% rename from crabfit-frontend/public/logo192.png rename to frontend/public/logo192.png diff --git a/crabfit-frontend/public/logo512.png b/frontend/public/logo512.png similarity index 100% rename from crabfit-frontend/public/logo512.png rename to frontend/public/logo512.png diff --git a/crabfit-frontend/public/manifest.json b/frontend/public/manifest.json similarity index 100% rename from crabfit-frontend/public/manifest.json rename to frontend/public/manifest.json diff --git a/crabfit-frontend/public/robots.txt b/frontend/public/robots.txt similarity index 100% rename from crabfit-frontend/public/robots.txt rename to frontend/public/robots.txt diff --git a/crabfit-frontend/public/sitemap.xml b/frontend/public/sitemap.xml similarity index 100% rename from crabfit-frontend/public/sitemap.xml rename to frontend/public/sitemap.xml diff --git a/crabfit-frontend/public/sw.js b/frontend/public/sw.js similarity index 100% rename from crabfit-frontend/public/sw.js rename to frontend/public/sw.js diff --git a/crabfit-frontend/src/App.jsx b/frontend/src/App.jsx similarity index 100% rename from crabfit-frontend/src/App.jsx rename to frontend/src/App.jsx diff --git a/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.jsx b/frontend/src/components/AvailabilityEditor/AvailabilityEditor.jsx similarity index 100% rename from crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.jsx rename to frontend/src/components/AvailabilityEditor/AvailabilityEditor.jsx diff --git a/crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.styles.js b/frontend/src/components/AvailabilityEditor/AvailabilityEditor.styles.js similarity index 100% rename from crabfit-frontend/src/components/AvailabilityEditor/AvailabilityEditor.styles.js rename to frontend/src/components/AvailabilityEditor/AvailabilityEditor.styles.js diff --git a/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.jsx b/frontend/src/components/AvailabilityViewer/AvailabilityViewer.jsx similarity index 100% rename from crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.jsx rename to frontend/src/components/AvailabilityViewer/AvailabilityViewer.jsx diff --git a/crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.styles.js b/frontend/src/components/AvailabilityViewer/AvailabilityViewer.styles.js similarity index 100% rename from crabfit-frontend/src/components/AvailabilityViewer/AvailabilityViewer.styles.js rename to frontend/src/components/AvailabilityViewer/AvailabilityViewer.styles.js diff --git a/crabfit-frontend/src/components/Button/Button.jsx b/frontend/src/components/Button/Button.jsx similarity index 100% rename from crabfit-frontend/src/components/Button/Button.jsx rename to frontend/src/components/Button/Button.jsx diff --git a/crabfit-frontend/src/components/Button/Button.styles.js b/frontend/src/components/Button/Button.styles.js similarity index 100% rename from crabfit-frontend/src/components/Button/Button.styles.js rename to frontend/src/components/Button/Button.styles.js diff --git a/crabfit-frontend/src/components/CalendarField/CalendarField.jsx b/frontend/src/components/CalendarField/CalendarField.jsx similarity index 100% rename from crabfit-frontend/src/components/CalendarField/CalendarField.jsx rename to frontend/src/components/CalendarField/CalendarField.jsx diff --git a/crabfit-frontend/src/components/CalendarField/CalendarField.styles.js b/frontend/src/components/CalendarField/CalendarField.styles.js similarity index 100% rename from crabfit-frontend/src/components/CalendarField/CalendarField.styles.js rename to frontend/src/components/CalendarField/CalendarField.styles.js diff --git a/crabfit-frontend/src/components/Center/Center.js b/frontend/src/components/Center/Center.js similarity index 100% rename from crabfit-frontend/src/components/Center/Center.js rename to frontend/src/components/Center/Center.js diff --git a/crabfit-frontend/src/components/Donate/Donate.jsx b/frontend/src/components/Donate/Donate.jsx similarity index 100% rename from crabfit-frontend/src/components/Donate/Donate.jsx rename to frontend/src/components/Donate/Donate.jsx diff --git a/crabfit-frontend/src/components/Donate/Donate.styles.js b/frontend/src/components/Donate/Donate.styles.js similarity index 100% rename from crabfit-frontend/src/components/Donate/Donate.styles.js rename to frontend/src/components/Donate/Donate.styles.js diff --git a/crabfit-frontend/src/components/Egg/Egg.jsx b/frontend/src/components/Egg/Egg.jsx similarity index 100% rename from crabfit-frontend/src/components/Egg/Egg.jsx rename to frontend/src/components/Egg/Egg.jsx diff --git a/crabfit-frontend/src/components/Egg/Egg.styles.js b/frontend/src/components/Egg/Egg.styles.js similarity index 100% rename from crabfit-frontend/src/components/Egg/Egg.styles.js rename to frontend/src/components/Egg/Egg.styles.js diff --git a/crabfit-frontend/src/components/Error/Error.jsx b/frontend/src/components/Error/Error.jsx similarity index 100% rename from crabfit-frontend/src/components/Error/Error.jsx rename to frontend/src/components/Error/Error.jsx diff --git a/crabfit-frontend/src/components/Error/Error.styles.js b/frontend/src/components/Error/Error.styles.js similarity index 100% rename from crabfit-frontend/src/components/Error/Error.styles.js rename to frontend/src/components/Error/Error.styles.js diff --git a/crabfit-frontend/src/components/Footer/Footer.jsx b/frontend/src/components/Footer/Footer.jsx similarity index 100% rename from crabfit-frontend/src/components/Footer/Footer.jsx rename to frontend/src/components/Footer/Footer.jsx diff --git a/crabfit-frontend/src/components/Footer/Footer.styles.js b/frontend/src/components/Footer/Footer.styles.js similarity index 100% rename from crabfit-frontend/src/components/Footer/Footer.styles.js rename to frontend/src/components/Footer/Footer.styles.js diff --git a/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.jsx b/frontend/src/components/GoogleCalendar/GoogleCalendar.jsx similarity index 100% rename from crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.jsx rename to frontend/src/components/GoogleCalendar/GoogleCalendar.jsx diff --git a/crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.styles.js b/frontend/src/components/GoogleCalendar/GoogleCalendar.styles.js similarity index 100% rename from crabfit-frontend/src/components/GoogleCalendar/GoogleCalendar.styles.js rename to frontend/src/components/GoogleCalendar/GoogleCalendar.styles.js diff --git a/crabfit-frontend/src/components/Legend/Legend.jsx b/frontend/src/components/Legend/Legend.jsx similarity index 100% rename from crabfit-frontend/src/components/Legend/Legend.jsx rename to frontend/src/components/Legend/Legend.jsx diff --git a/crabfit-frontend/src/components/Legend/Legend.styles.js b/frontend/src/components/Legend/Legend.styles.js similarity index 100% rename from crabfit-frontend/src/components/Legend/Legend.styles.js rename to frontend/src/components/Legend/Legend.styles.js diff --git a/crabfit-frontend/src/components/Loading/Loading.jsx b/frontend/src/components/Loading/Loading.jsx similarity index 100% rename from crabfit-frontend/src/components/Loading/Loading.jsx rename to frontend/src/components/Loading/Loading.jsx diff --git a/crabfit-frontend/src/components/Loading/Loading.styles.js b/frontend/src/components/Loading/Loading.styles.js similarity index 100% rename from crabfit-frontend/src/components/Loading/Loading.styles.js rename to frontend/src/components/Loading/Loading.styles.js diff --git a/crabfit-frontend/src/components/Logo/Logo.jsx b/frontend/src/components/Logo/Logo.jsx similarity index 100% rename from crabfit-frontend/src/components/Logo/Logo.jsx rename to frontend/src/components/Logo/Logo.jsx diff --git a/crabfit-frontend/src/components/Logo/Logo.styles.js b/frontend/src/components/Logo/Logo.styles.js similarity index 100% rename from crabfit-frontend/src/components/Logo/Logo.styles.js rename to frontend/src/components/Logo/Logo.styles.js diff --git a/crabfit-frontend/src/components/OutlookCalendar/OutlookCalendar.jsx b/frontend/src/components/OutlookCalendar/OutlookCalendar.jsx similarity index 100% rename from crabfit-frontend/src/components/OutlookCalendar/OutlookCalendar.jsx rename to frontend/src/components/OutlookCalendar/OutlookCalendar.jsx diff --git a/crabfit-frontend/src/components/Recents/Recents.jsx b/frontend/src/components/Recents/Recents.jsx similarity index 100% rename from crabfit-frontend/src/components/Recents/Recents.jsx rename to frontend/src/components/Recents/Recents.jsx diff --git a/crabfit-frontend/src/components/Recents/Recents.styles.js b/frontend/src/components/Recents/Recents.styles.js similarity index 100% rename from crabfit-frontend/src/components/Recents/Recents.styles.js rename to frontend/src/components/Recents/Recents.styles.js diff --git a/crabfit-frontend/src/components/SelectField/SelectField.jsx b/frontend/src/components/SelectField/SelectField.jsx similarity index 100% rename from crabfit-frontend/src/components/SelectField/SelectField.jsx rename to frontend/src/components/SelectField/SelectField.jsx diff --git a/crabfit-frontend/src/components/SelectField/SelectField.styles.js b/frontend/src/components/SelectField/SelectField.styles.js similarity index 100% rename from crabfit-frontend/src/components/SelectField/SelectField.styles.js rename to frontend/src/components/SelectField/SelectField.styles.js diff --git a/crabfit-frontend/src/components/Settings/Settings.jsx b/frontend/src/components/Settings/Settings.jsx similarity index 100% rename from crabfit-frontend/src/components/Settings/Settings.jsx rename to frontend/src/components/Settings/Settings.jsx diff --git a/crabfit-frontend/src/components/Settings/Settings.styles.js b/frontend/src/components/Settings/Settings.styles.js similarity index 100% rename from crabfit-frontend/src/components/Settings/Settings.styles.js rename to frontend/src/components/Settings/Settings.styles.js diff --git a/crabfit-frontend/src/components/TextField/TextField.jsx b/frontend/src/components/TextField/TextField.jsx similarity index 100% rename from crabfit-frontend/src/components/TextField/TextField.jsx rename to frontend/src/components/TextField/TextField.jsx diff --git a/crabfit-frontend/src/components/TextField/TextField.styles.js b/frontend/src/components/TextField/TextField.styles.js similarity index 100% rename from crabfit-frontend/src/components/TextField/TextField.styles.js rename to frontend/src/components/TextField/TextField.styles.js diff --git a/crabfit-frontend/src/components/TimeRangeField/TimeRangeField.jsx b/frontend/src/components/TimeRangeField/TimeRangeField.jsx similarity index 100% rename from crabfit-frontend/src/components/TimeRangeField/TimeRangeField.jsx rename to frontend/src/components/TimeRangeField/TimeRangeField.jsx diff --git a/crabfit-frontend/src/components/TimeRangeField/TimeRangeField.styles.js b/frontend/src/components/TimeRangeField/TimeRangeField.styles.js similarity index 100% rename from crabfit-frontend/src/components/TimeRangeField/TimeRangeField.styles.js rename to frontend/src/components/TimeRangeField/TimeRangeField.styles.js diff --git a/crabfit-frontend/src/components/ToggleField/ToggleField.jsx b/frontend/src/components/ToggleField/ToggleField.jsx similarity index 100% rename from crabfit-frontend/src/components/ToggleField/ToggleField.jsx rename to frontend/src/components/ToggleField/ToggleField.jsx diff --git a/crabfit-frontend/src/components/ToggleField/ToggleField.styles.js b/frontend/src/components/ToggleField/ToggleField.styles.js similarity index 100% rename from crabfit-frontend/src/components/ToggleField/ToggleField.styles.js rename to frontend/src/components/ToggleField/ToggleField.styles.js diff --git a/crabfit-frontend/src/components/TranslateDialog/TranslateDialog.jsx b/frontend/src/components/TranslateDialog/TranslateDialog.jsx similarity index 100% rename from crabfit-frontend/src/components/TranslateDialog/TranslateDialog.jsx rename to frontend/src/components/TranslateDialog/TranslateDialog.jsx diff --git a/crabfit-frontend/src/components/TranslateDialog/TranslateDialog.styles.js b/frontend/src/components/TranslateDialog/TranslateDialog.styles.js similarity index 100% rename from crabfit-frontend/src/components/TranslateDialog/TranslateDialog.styles.js rename to frontend/src/components/TranslateDialog/TranslateDialog.styles.js diff --git a/crabfit-frontend/src/components/index.js b/frontend/src/components/index.js similarity index 100% rename from crabfit-frontend/src/components/index.js rename to frontend/src/components/index.js diff --git a/crabfit-frontend/src/i18n/index.js b/frontend/src/i18n/index.js similarity index 100% rename from crabfit-frontend/src/i18n/index.js rename to frontend/src/i18n/index.js diff --git a/crabfit-frontend/src/i18n/locales.js b/frontend/src/i18n/locales.js similarity index 100% rename from crabfit-frontend/src/i18n/locales.js rename to frontend/src/i18n/locales.js diff --git a/crabfit-frontend/src/index.jsx b/frontend/src/index.jsx similarity index 100% rename from crabfit-frontend/src/index.jsx rename to frontend/src/index.jsx diff --git a/crabfit-frontend/src/pages/Create/Create.jsx b/frontend/src/pages/Create/Create.jsx similarity index 100% rename from crabfit-frontend/src/pages/Create/Create.jsx rename to frontend/src/pages/Create/Create.jsx diff --git a/crabfit-frontend/src/pages/Create/Create.styles.js b/frontend/src/pages/Create/Create.styles.js similarity index 100% rename from crabfit-frontend/src/pages/Create/Create.styles.js rename to frontend/src/pages/Create/Create.styles.js diff --git a/crabfit-frontend/src/pages/Event/Event.jsx b/frontend/src/pages/Event/Event.jsx similarity index 100% rename from crabfit-frontend/src/pages/Event/Event.jsx rename to frontend/src/pages/Event/Event.jsx diff --git a/crabfit-frontend/src/pages/Event/Event.styles.js b/frontend/src/pages/Event/Event.styles.js similarity index 100% rename from crabfit-frontend/src/pages/Event/Event.styles.js rename to frontend/src/pages/Event/Event.styles.js diff --git a/crabfit-frontend/src/pages/Help/Help.jsx b/frontend/src/pages/Help/Help.jsx similarity index 100% rename from crabfit-frontend/src/pages/Help/Help.jsx rename to frontend/src/pages/Help/Help.jsx diff --git a/crabfit-frontend/src/pages/Help/Help.styles.js b/frontend/src/pages/Help/Help.styles.js similarity index 100% rename from crabfit-frontend/src/pages/Help/Help.styles.js rename to frontend/src/pages/Help/Help.styles.js diff --git a/crabfit-frontend/src/pages/Home/Home.jsx b/frontend/src/pages/Home/Home.jsx similarity index 100% rename from crabfit-frontend/src/pages/Home/Home.jsx rename to frontend/src/pages/Home/Home.jsx diff --git a/crabfit-frontend/src/pages/Home/Home.styles.js b/frontend/src/pages/Home/Home.styles.js similarity index 100% rename from crabfit-frontend/src/pages/Home/Home.styles.js rename to frontend/src/pages/Home/Home.styles.js diff --git a/crabfit-frontend/src/pages/Privacy/Privacy.jsx b/frontend/src/pages/Privacy/Privacy.jsx similarity index 100% rename from crabfit-frontend/src/pages/Privacy/Privacy.jsx rename to frontend/src/pages/Privacy/Privacy.jsx diff --git a/crabfit-frontend/src/pages/Privacy/Privacy.styles.js b/frontend/src/pages/Privacy/Privacy.styles.js similarity index 100% rename from crabfit-frontend/src/pages/Privacy/Privacy.styles.js rename to frontend/src/pages/Privacy/Privacy.styles.js diff --git a/crabfit-frontend/src/pages/index.js b/frontend/src/pages/index.js similarity index 100% rename from crabfit-frontend/src/pages/index.js rename to frontend/src/pages/index.js diff --git a/crabfit-frontend/src/res/google.svg b/frontend/src/res/google.svg similarity index 100% rename from crabfit-frontend/src/res/google.svg rename to frontend/src/res/google.svg diff --git a/crabfit-frontend/src/res/logo.svg b/frontend/src/res/logo.svg similarity index 100% rename from crabfit-frontend/src/res/logo.svg rename to frontend/src/res/logo.svg diff --git a/crabfit-frontend/src/res/outlook.svg b/frontend/src/res/outlook.svg similarity index 100% rename from crabfit-frontend/src/res/outlook.svg rename to frontend/src/res/outlook.svg diff --git a/crabfit-frontend/src/res/paypal.svg b/frontend/src/res/paypal.svg similarity index 100% rename from crabfit-frontend/src/res/paypal.svg rename to frontend/src/res/paypal.svg diff --git a/crabfit-frontend/src/res/timezones.json b/frontend/src/res/timezones.json similarity index 100% rename from crabfit-frontend/src/res/timezones.json rename to frontend/src/res/timezones.json diff --git a/crabfit-frontend/src/res/video_thumb.jpg b/frontend/src/res/video_thumb.jpg similarity index 100% rename from crabfit-frontend/src/res/video_thumb.jpg rename to frontend/src/res/video_thumb.jpg diff --git a/crabfit-frontend/src/services/index.js b/frontend/src/services/index.js similarity index 100% rename from crabfit-frontend/src/services/index.js rename to frontend/src/services/index.js diff --git a/crabfit-frontend/src/stores/index.js b/frontend/src/stores/index.js similarity index 100% rename from crabfit-frontend/src/stores/index.js rename to frontend/src/stores/index.js diff --git a/crabfit-frontend/src/stores/localeUpdateStore.js b/frontend/src/stores/localeUpdateStore.js similarity index 100% rename from crabfit-frontend/src/stores/localeUpdateStore.js rename to frontend/src/stores/localeUpdateStore.js diff --git a/crabfit-frontend/src/stores/recentsStore.js b/frontend/src/stores/recentsStore.js similarity index 100% rename from crabfit-frontend/src/stores/recentsStore.js rename to frontend/src/stores/recentsStore.js diff --git a/crabfit-frontend/src/stores/settingsStore.js b/frontend/src/stores/settingsStore.js similarity index 100% rename from crabfit-frontend/src/stores/settingsStore.js rename to frontend/src/stores/settingsStore.js diff --git a/crabfit-frontend/src/stores/translateStore.js b/frontend/src/stores/translateStore.js similarity index 100% rename from crabfit-frontend/src/stores/translateStore.js rename to frontend/src/stores/translateStore.js diff --git a/crabfit-frontend/src/stores/twaStore.js b/frontend/src/stores/twaStore.js similarity index 100% rename from crabfit-frontend/src/stores/twaStore.js rename to frontend/src/stores/twaStore.js diff --git a/crabfit-frontend/src/utils/index.js b/frontend/src/utils/index.js similarity index 100% rename from crabfit-frontend/src/utils/index.js rename to frontend/src/utils/index.js diff --git a/crabfit-frontend/vite.config.js b/frontend/vite.config.js similarity index 100% rename from crabfit-frontend/vite.config.js rename to frontend/vite.config.js diff --git a/crabfit-frontend/yarn.lock b/frontend/yarn.lock similarity index 100% rename from crabfit-frontend/yarn.lock rename to frontend/yarn.lock