diff --git a/.dockerignore b/.dockerignore
index 3754bfc1..181b30a8 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -54,6 +54,7 @@ db.sqlite3-journal
# React
.DS_*
*.log
+*.tsbuildinfo
logs
**/*.backup.*
**/*.back.*
diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index fe467311..714eaed4 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -9,35 +9,35 @@ defaults:
on:
push:
- branches: [ "main" ]
+ branches: ["main"]
paths:
- rsconcept/frontend/**
- .github/workflows/frontend.yml
pull_request:
- branches: [ "main" ]
+ branches: ["main"]
jobs:
build:
-
runs-on: ubuntu-22.04
strategy:
matrix:
- node-version: [18.x]
+ node-version: [22.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- - uses: actions/checkout@v4
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
- with:
- node-version: ${{ matrix.node-version }}
- cache-dependency-path: rsconcept/frontend/package-lock.json
- cache: 'npm'
- - name: Build
- run: |
- npm ci
- npm run build --if-present
- - name: Test
- run: |
- npm test
+ - uses: actions/checkout@v4
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache-dependency-path: rsconcept/frontend/package-lock.json
+ cache: "npm"
+ - name: Build
+ run: |
+ npm install -g typescript vite jest
+ npm ci
+ npm run build --if-present
+ - name: Test
+ run: |
+ npm test
diff --git a/.gitignore b/.gitignore
index fa0da0f3..291ef36e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,6 +47,7 @@ db.sqlite3-journal
# React
.DS_*
*.log
+*.tsbuildinfo
logs
**/*.backup.*
**/*.back.*
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 07c8043b..90b939b8 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -11,7 +11,9 @@
"--multi-line",
"3",
"--project",
- "apps"
+ "apps",
+ "--project",
+ "shared"
],
"autopep8.args": [
"--max-line-length",
@@ -38,6 +40,10 @@
{
"name": "django",
"depth": 5
+ },
+ {
+ "name": "djangorestframework",
+ "depth": 2
}
],
"colorize.include": [".tsx", ".jsx", ".ts", ".js"],
diff --git a/README.md b/README.md
index ea99477d..51d4dd10 100644
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@ This readme file is used mostly to document project dependencies
- Backticks
- Svg Preview
- TODO Highlight v2
+ - Prettier
@@ -114,8 +115,10 @@ This readme file is used mostly to document project dependencies
- Pylance
- Pylint
- - Django
- autopep8
+ - isort
+ - Django
+ - SQLite
diff --git a/TODO.txt b/TODO.txt
index d5bb5628..8c9ec45d 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -11,7 +11,7 @@ For more specific TODOs see comments in code
[Functionality - PENDING]
- Search functionality for manuals
- User notifications on edit - consider spam prevention and change aggregation
-- Static analyzer for RSForm
+- Static analyzer for RSForm as a whole: check term duplication and empty conventions
- Content based search in Library
- User profile: Settings + settings persistency
@@ -25,12 +25,18 @@ For more specific TODOs see comments in code
- Internationalization - at least english version. Consider react.intl
- Focus on codemirror editor when label is clicked (need React 19 ref for clean code solution)
+- Sitemap for better SEO and crawler optimization
+
[Tech]
-- add debounce to some search fields
- duplicate syntax parsing and type info calculations to client. Consider moving backend to Nodejs or embedding c++ lib
-
+- add debounce to some search fields
- DataTable: fixed percentage columns, especially for SubstituteTable. Rework column sizing mechanics
+- move autopep8 and isort settings from vscode settings to pyproject.toml
+- Test UI for #enable-force-dark Chrome setting
+
+- Testing: frontend react components, testplane / playwright?
+- Documentation: frontend base components at least
[Deployment]
@@ -39,7 +45,6 @@ For more specific TODOs see comments in code
[Security]
-- password-reset leaks info of email being used
- improve nginx config. Consider DDOS and other types of attacks on infrastructure
- recaptcha for create user and rest password
https://yandex.cloud/ru/docs/smartcaptcha
@@ -50,9 +55,17 @@ Research and consider integration
- django-allauth - consider supporting popular auth providers
- drf-messages
+- skeleton loading
+https://react.dev/reference/react/Suspense
+
- backend error message unification
https://drf-standardized-errors.readthedocs.io/en/latest/error_response.html
+- semantic json diff
+https://stackoverflow.com/questions/28838170/multilevel-json-diff-in-python
+
+- Documentation platform. Consider diplodoc
+
- radix-ui
- shadcn-ui
@@ -60,6 +73,4 @@ https://drf-standardized-errors.readthedocs.io/en/latest/error_response.html
- use-debounce
- react-query
-- react-hook-form
-
-- node-based UI
\ No newline at end of file
+- react-hook-form
\ No newline at end of file
diff --git a/rsconcept/backend/Dockerfile b/rsconcept/backend/Dockerfile
index bb2db3f4..4a5521d9 100644
--- a/rsconcept/backend/Dockerfile
+++ b/rsconcept/backend/Dockerfile
@@ -1,7 +1,7 @@
# ==========================================
# ============ Multi-stage build ===========
# ==========================================
-FROM ubuntu:jammy as python-base
+FROM ubuntu:jammy AS python-base
ENV DEBIAN_FRONTEND=noninteractive
@@ -25,7 +25,7 @@ RUN apt-get update -qq && \
rm -rf /var/lib/apt/lists/*
# ========= Builder ==============
-FROM python-base as builder
+FROM python-base AS builder
# Set env variables
ENV PYTHONDONTWRITEBYTECODE 1
@@ -65,9 +65,10 @@ RUN pip install --no-cache /wheels/* && \
rm -rf /wheels
# Copy application sources and setup permissions
-COPY apps/ ./apps
COPY project/ ./project
+COPY shared/ ./shared
COPY fixtures/ ./fixtures
+COPY apps/ ./apps
COPY manage.py entrypoint.sh ./
RUN sed -i 's/\r$//g' $APP_HOME/entrypoint.sh && \
chmod +x $APP_HOME/entrypoint.sh && \
diff --git a/rsconcept/backend/apps/oss/__init__.py b/rsconcept/backend/apps/oss/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/rsconcept/backend/apps/oss/admin.py b/rsconcept/backend/apps/oss/admin.py
new file mode 100644
index 00000000..3bf56a23
--- /dev/null
+++ b/rsconcept/backend/apps/oss/admin.py
@@ -0,0 +1,14 @@
+''' Admin view: OperationSchema. '''
+from django.contrib import admin
+
+from . import models
+
+
+class OperationAdmin(admin.ModelAdmin):
+ ''' Admin model: Operation. '''
+ ordering = ['oss']
+ list_display = ['oss', 'operation_type', 'result', 'alias', 'title', 'comment', 'position_x', 'position_y']
+ search_fields = ['operation_type', 'title', 'alias']
+
+
+admin.site.register(models.Operation, OperationAdmin)
diff --git a/rsconcept/backend/apps/oss/apps.py b/rsconcept/backend/apps/oss/apps.py
new file mode 100644
index 00000000..540eca26
--- /dev/null
+++ b/rsconcept/backend/apps/oss/apps.py
@@ -0,0 +1,8 @@
+''' Application: Operation Schema. '''
+from django.apps import AppConfig
+
+
+class RsformConfig(AppConfig):
+ ''' Application config. '''
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'apps.oss'
diff --git a/rsconcept/backend/apps/oss/migrations/0001_initial.py b/rsconcept/backend/apps/oss/migrations/0001_initial.py
new file mode 100644
index 00000000..e5fc31f8
--- /dev/null
+++ b/rsconcept/backend/apps/oss/migrations/0001_initial.py
@@ -0,0 +1,69 @@
+# Generated by Django 5.0.7 on 2024-07-17 09:51
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('rsform', '0008_alter_libraryitem_item_type'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Operation',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('operation_type', models.CharField(choices=[
+ ('input', 'Input'), ('synthesis', 'Synthesis')], default='input', max_length=10, verbose_name='Тип')),
+ ('alias', models.CharField(blank=True, max_length=255, verbose_name='Шифр')),
+ ('title', models.TextField(blank=True, verbose_name='Название')),
+ ('comment', models.TextField(blank=True, verbose_name='Комментарий')),
+ ('position_x', models.FloatField(default=0, verbose_name='Положение по горизонтали')),
+ ('position_y', models.FloatField(default=0, verbose_name='Положение по вертикали')),
+ ('oss', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='items', to='rsform.libraryitem', verbose_name='Схема синтеза')),
+ ('result', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL,
+ related_name='producer', to='rsform.libraryitem', verbose_name='Связанная КС')),
+ ],
+ options={
+ 'verbose_name': 'Операция',
+ 'verbose_name_plural': 'Операции',
+ },
+ ),
+ migrations.CreateModel(
+ name='SynthesisSubstitution',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('transfer_term', models.BooleanField(default=False, verbose_name='Перенос термина')),
+ ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ to='oss.operation', verbose_name='Операция')),
+ ('original', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='as_original', to='rsform.constituenta', verbose_name='Удаляемая конституента')),
+ ('substitution', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='as_substitute', to='rsform.constituenta', verbose_name='Замещающая конституента')),
+ ],
+ options={
+ 'verbose_name': 'Отождествление синтеза',
+ 'verbose_name_plural': 'Таблицы отождествлений',
+ },
+ ),
+ migrations.CreateModel(
+ name='Argument',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('argument', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='descendants', to='oss.operation', verbose_name='Аргумент')),
+ ('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
+ related_name='arguments', to='oss.operation', verbose_name='Операция')),
+ ],
+ options={
+ 'verbose_name': 'Аргумент',
+ 'verbose_name_plural': 'Аргументы операций',
+ 'unique_together': {('operation', 'argument')},
+ },
+ ),
+ ]
diff --git a/rsconcept/backend/apps/oss/migrations/__init__.py b/rsconcept/backend/apps/oss/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/rsconcept/backend/apps/oss/models/Argument.py b/rsconcept/backend/apps/oss/models/Argument.py
new file mode 100644
index 00000000..3282113d
--- /dev/null
+++ b/rsconcept/backend/apps/oss/models/Argument.py
@@ -0,0 +1,27 @@
+''' Models: Operation Argument in OSS. '''
+from django.db.models import CASCADE, ForeignKey, Model
+
+
+class Argument(Model):
+ ''' Operation Argument.'''
+ operation: ForeignKey = ForeignKey(
+ verbose_name='Операция',
+ to='oss.Operation',
+ on_delete=CASCADE,
+ related_name='arguments'
+ )
+ argument: ForeignKey = ForeignKey(
+ verbose_name='Аргумент',
+ to='oss.Operation',
+ on_delete=CASCADE,
+ related_name='descendants'
+ )
+
+ class Meta:
+ ''' Model metadata. '''
+ verbose_name = 'Аргумент'
+ verbose_name_plural = 'Аргументы операций'
+ unique_together = [['operation', 'argument']]
+
+ def __str__(self) -> str:
+ return f'{self.argument.pk} -> {self.operation.pk}'
diff --git a/rsconcept/backend/apps/oss/models/Operation.py b/rsconcept/backend/apps/oss/models/Operation.py
new file mode 100644
index 00000000..54b16740
--- /dev/null
+++ b/rsconcept/backend/apps/oss/models/Operation.py
@@ -0,0 +1,71 @@
+''' Models: Operation in OSS. '''
+from django.db.models import (
+ CASCADE,
+ SET_NULL,
+ CharField,
+ FloatField,
+ ForeignKey,
+ Model,
+ TextChoices,
+ TextField
+)
+
+
+class OperationType(TextChoices):
+ ''' Type of operation. '''
+ INPUT = 'input'
+ SYNTHESIS = 'synthesis'
+
+
+class Operation(Model):
+ ''' Operational schema Unit.'''
+ oss: ForeignKey = ForeignKey(
+ verbose_name='Схема синтеза',
+ to='rsform.LibraryItem',
+ on_delete=CASCADE,
+ related_name='items'
+ )
+ operation_type: CharField = CharField(
+ verbose_name='Тип',
+ max_length=10,
+ choices=OperationType.choices,
+ default=OperationType.INPUT
+ )
+ result: ForeignKey = ForeignKey(
+ verbose_name='Связанная КС',
+ to='rsform.LibraryItem',
+ null=True,
+ on_delete=SET_NULL,
+ related_name='producer'
+ )
+
+ alias: CharField = CharField(
+ verbose_name='Шифр',
+ max_length=255,
+ blank=True
+ )
+ title: TextField = TextField(
+ verbose_name='Название',
+ blank=True
+ )
+ comment: TextField = TextField(
+ verbose_name='Комментарий',
+ blank=True
+ )
+
+ position_x: FloatField = FloatField(
+ verbose_name='Положение по горизонтали',
+ default=0
+ )
+ position_y: FloatField = FloatField(
+ verbose_name='Положение по вертикали',
+ default=0
+ )
+
+ class Meta:
+ ''' Model metadata. '''
+ verbose_name = 'Операция'
+ verbose_name_plural = 'Операции'
+
+ def __str__(self) -> str:
+ return f'Операция {self.alias}'
diff --git a/rsconcept/backend/apps/oss/models/SynthesisSubstitution.py b/rsconcept/backend/apps/oss/models/SynthesisSubstitution.py
new file mode 100644
index 00000000..61c2da22
--- /dev/null
+++ b/rsconcept/backend/apps/oss/models/SynthesisSubstitution.py
@@ -0,0 +1,36 @@
+''' Models: SynthesisSubstitution. '''
+from django.db.models import CASCADE, BooleanField, ForeignKey, Model
+
+
+class SynthesisSubstitution(Model):
+ ''' Substitutions as part of Synthesis operation in OSS.'''
+ operation: ForeignKey = ForeignKey(
+ verbose_name='Операция',
+ to='oss.Operation',
+ on_delete=CASCADE
+ )
+
+ original: ForeignKey = ForeignKey(
+ verbose_name='Удаляемая конституента',
+ to='rsform.Constituenta',
+ on_delete=CASCADE,
+ related_name='as_original'
+ )
+ substitution: ForeignKey = ForeignKey(
+ verbose_name='Замещающая конституента',
+ to='rsform.Constituenta',
+ on_delete=CASCADE,
+ related_name='as_substitute'
+ )
+ transfer_term: BooleanField = BooleanField(
+ verbose_name='Перенос термина',
+ default=False
+ )
+
+ class Meta:
+ ''' Model metadata. '''
+ verbose_name = 'Отождествление синтеза'
+ verbose_name_plural = 'Таблицы отождествлений'
+
+ def __str__(self) -> str:
+ return f'{self.original.pk} -> {self.substitution.pk}'
diff --git a/rsconcept/backend/apps/oss/models/__init__.py b/rsconcept/backend/apps/oss/models/__init__.py
new file mode 100644
index 00000000..baa166e3
--- /dev/null
+++ b/rsconcept/backend/apps/oss/models/__init__.py
@@ -0,0 +1,8 @@
+''' Django: Models. '''
+
+from apps.rsform.models import LibraryItem, LibraryItemType
+
+from .api_OSS import OperationSchema
+from .Argument import Argument
+from .Operation import Operation, OperationType
+from .SynthesisSubstitution import SynthesisSubstitution
diff --git a/rsconcept/backend/apps/oss/models/api_OSS.py b/rsconcept/backend/apps/oss/models/api_OSS.py
new file mode 100644
index 00000000..c4a3db7c
--- /dev/null
+++ b/rsconcept/backend/apps/oss/models/api_OSS.py
@@ -0,0 +1,128 @@
+''' Models: OSS API. '''
+from typing import Optional
+
+from django.core.exceptions import ValidationError
+from django.db import transaction
+from django.db.models import QuerySet
+
+from apps.rsform.models import LibraryItem, LibraryItemType
+from shared import messages as msg
+
+from .Argument import Argument
+from .Operation import Operation
+from .SynthesisSubstitution import SynthesisSubstitution
+
+
+class OperationSchema:
+ ''' Operations schema API. '''
+
+ def __init__(self, item: LibraryItem):
+ if item.item_type != LibraryItemType.OPERATION_SCHEMA:
+ raise ValueError(msg.libraryTypeUnexpected())
+ self.item = item
+
+ @staticmethod
+ def create(**kwargs) -> 'OperationSchema':
+ item = LibraryItem.objects.create(item_type=LibraryItemType.OPERATION_SCHEMA, **kwargs)
+ return OperationSchema(item=item)
+
+ def operations(self) -> QuerySet[Operation]:
+ ''' Get QuerySet containing all operations of current OSS. '''
+ return Operation.objects.filter(oss=self.item)
+
+ def arguments(self) -> QuerySet[Argument]:
+ ''' Operation arguments. '''
+ return Argument.objects.filter(operation__oss=self.item)
+
+ def substitutions(self) -> QuerySet[SynthesisSubstitution]:
+ ''' Operation substitutions. '''
+ return SynthesisSubstitution.objects.filter(operation__oss=self.item)
+
+ def update_positions(self, data: list[dict]):
+ ''' Update positions. '''
+ lookup = {x['id']: x for x in data}
+ operations = self.operations()
+ for item in operations:
+ if item.pk in lookup:
+ item.position_x = lookup[item.pk]['position_x']
+ item.position_y = lookup[item.pk]['position_y']
+ Operation.objects.bulk_update(operations, ['position_x', 'position_y'])
+
+ @transaction.atomic
+ def create_operation(self, **kwargs) -> Operation:
+ ''' Insert new operation. '''
+ if kwargs['alias'] != '' and self.operations().filter(alias=kwargs['alias']).exists():
+ raise ValidationError(msg.aliasTaken(kwargs['alias']))
+ result = Operation.objects.create(
+ oss=self.item,
+ **kwargs
+ )
+ self.item.save()
+ result.refresh_from_db()
+ return result
+
+ @transaction.atomic
+ def delete_operation(self, operation: Operation):
+ ''' Delete operation. '''
+ operation.delete()
+
+ # deal with attached schema
+ # trigger on_change effects
+
+ self.item.save()
+
+ @transaction.atomic
+ def set_input(self, target: Operation, schema: Optional[LibraryItem]):
+ ''' Set input schema for operation. '''
+ if schema == target.result:
+ return
+ if schema:
+ target.result = schema
+ target.alias = schema.alias
+ target.title = schema.title
+ target.comment = schema.comment
+ else:
+ target.result = None
+ target.save()
+
+ # trigger on_change effects
+
+ self.item.save()
+
+ @transaction.atomic
+ def add_argument(self, operation: Operation, argument: Operation) -> Optional[Argument]:
+ ''' Add Argument to operation. '''
+ if Argument.objects.filter(operation=operation, argument=argument).exists():
+ return None
+ result = Argument.objects.create(operation=operation, argument=argument)
+ self.item.save()
+ return result
+
+ @transaction.atomic
+ def clear_arguments(self, target: Operation):
+ ''' Clear all arguments for operation. '''
+ if not Argument.objects.filter(operation=target).exists():
+ return
+
+ Argument.objects.filter(operation=target).delete()
+ SynthesisSubstitution.objects.filter(operation=target).delete()
+
+ # trigger on_change effects
+
+ self.item.save()
+
+ @transaction.atomic
+ def set_substitutions(self, target: Operation, substitutes: list[dict]):
+ ''' Clear all arguments for operation. '''
+ SynthesisSubstitution.objects.filter(operation=target).delete()
+ for sub in substitutes:
+ SynthesisSubstitution.objects.create(
+ operation=target,
+ original=sub['original'],
+ substitution=sub['substitution'],
+ transfer_term=sub['transfer_term']
+ )
+
+ # trigger on_change effects
+
+ self.item.save()
diff --git a/rsconcept/backend/apps/oss/serializers/__init__.py b/rsconcept/backend/apps/oss/serializers/__init__.py
new file mode 100644
index 00000000..fe010453
--- /dev/null
+++ b/rsconcept/backend/apps/oss/serializers/__init__.py
@@ -0,0 +1,13 @@
+''' REST API: Serializers. '''
+
+from apps.rsform.serializers import LibraryItemSerializer
+
+from .basics import OperationPositionSerializer, PositionsSerializer
+from .data_access import (
+ ArgumentSerializer,
+ OperationCreateSerializer,
+ OperationDeleteSerializer,
+ OperationSchemaSerializer,
+ OperationSerializer
+)
+from .schema_typing import NewOperationResponse
diff --git a/rsconcept/backend/apps/oss/serializers/basics.py b/rsconcept/backend/apps/oss/serializers/basics.py
new file mode 100644
index 00000000..d597ca5a
--- /dev/null
+++ b/rsconcept/backend/apps/oss/serializers/basics.py
@@ -0,0 +1,16 @@
+''' Basic serializers that do not interact with database. '''
+from rest_framework import serializers
+
+
+class OperationPositionSerializer(serializers.Serializer):
+ ''' Operation position. '''
+ id = serializers.IntegerField()
+ position_x = serializers.FloatField()
+ position_y = serializers.FloatField()
+
+
+class PositionsSerializer(serializers.Serializer):
+ ''' Operations position for OperationSchema. '''
+ positions = serializers.ListField(
+ child=OperationPositionSerializer()
+ )
diff --git a/rsconcept/backend/apps/oss/serializers/data_access.py b/rsconcept/backend/apps/oss/serializers/data_access.py
new file mode 100644
index 00000000..eb161ff6
--- /dev/null
+++ b/rsconcept/backend/apps/oss/serializers/data_access.py
@@ -0,0 +1,108 @@
+''' Serializers for persistent data manipulation. '''
+from typing import cast
+
+from django.db.models import F
+from rest_framework import serializers
+from rest_framework.serializers import PrimaryKeyRelatedField as PKField
+
+from apps.rsform.models import LibraryItem
+from apps.rsform.serializers import LibraryItemDetailsSerializer
+from shared import messages as msg
+
+from ..models import Argument, Operation, OperationSchema, OperationType
+from .basics import OperationPositionSerializer
+
+
+class OperationSerializer(serializers.ModelSerializer):
+ ''' Serializer: Operation data. '''
+ class Meta:
+ ''' serializer metadata. '''
+ model = Operation
+ fields = '__all__'
+ read_only_fields = ('id', 'oss')
+
+
+class ArgumentSerializer(serializers.ModelSerializer):
+ ''' Serializer: Operation data. '''
+ class Meta:
+ ''' serializer metadata. '''
+ model = Argument
+ fields = ('operation', 'argument')
+
+
+class OperationCreateSerializer(serializers.Serializer):
+ ''' Serializer: Operation creation. '''
+ class OperationData(serializers.ModelSerializer):
+ ''' Serializer: Operation creation data. '''
+ alias = serializers.CharField()
+ operation_type = serializers.ChoiceField(OperationType.choices)
+
+ class Meta:
+ ''' serializer metadata. '''
+ model = Operation
+ fields = \
+ 'alias', 'operation_type', 'title', \
+ 'comment', 'position_x', 'position_y'
+
+ item_data = OperationData()
+ positions = serializers.ListField(
+ child=OperationPositionSerializer(),
+ default=[]
+ )
+
+
+class OperationDeleteSerializer(serializers.Serializer):
+ ''' Serializer: Delete operation. '''
+ target = PKField(many=False, queryset=Operation.objects.all())
+ positions = serializers.ListField(
+ child=OperationPositionSerializer(),
+ default=[]
+ )
+
+ def validate(self, attrs):
+ oss = cast(LibraryItem, self.context['oss'])
+ operation = cast(Operation, attrs['target'])
+ if oss and operation.oss != oss:
+ raise serializers.ValidationError({
+ f'{operation.id}': msg.operationNotOwned(oss.title)
+ })
+ self.instance = operation
+ return attrs
+
+
+class OperationSchemaSerializer(serializers.ModelSerializer):
+ ''' Serializer: Detailed data for OSS. '''
+ items = serializers.ListField(
+ child=OperationSerializer()
+ )
+ graph = serializers.ListField(
+ child=ArgumentSerializer()
+ )
+
+ class Meta:
+ ''' serializer metadata. '''
+ model = LibraryItem
+ fields = '__all__'
+
+ def to_representation(self, instance: LibraryItem):
+ result = LibraryItemDetailsSerializer(instance).data
+ oss = OperationSchema(instance)
+ result['items'] = []
+ for operation in oss.operations():
+ result['items'].append(OperationSerializer(operation).data)
+ result['graph'] = []
+ for argument in oss.arguments():
+ result['graph'].append(ArgumentSerializer(argument).data)
+ result['substitutions'] = []
+ for substitution in oss.substitutions().values(
+ 'operation',
+ 'original',
+ 'transfer_term',
+ 'substitution',
+ original_alias=F('original__alias'),
+ original_term=F('original__term_resolved'),
+ substitution_alias=F('substitution__alias'),
+ substitution_term=F('substitution__term_resolved'),
+ ):
+ result['substitutions'].append(substitution)
+ return result
diff --git a/rsconcept/backend/apps/oss/serializers/schema_typing.py b/rsconcept/backend/apps/oss/serializers/schema_typing.py
new file mode 100644
index 00000000..c0cf5b31
--- /dev/null
+++ b/rsconcept/backend/apps/oss/serializers/schema_typing.py
@@ -0,0 +1,10 @@
+''' Utility serializers for REST API schema - SHOULD NOT BE ACCESSED DIRECTLY. '''
+from rest_framework import serializers
+
+from .data_access import OperationSchemaSerializer, OperationSerializer
+
+
+class NewOperationResponse(serializers.Serializer):
+ ''' Serializer: Create operation response. '''
+ new_operation = OperationSerializer()
+ oss = OperationSchemaSerializer()
diff --git a/rsconcept/backend/apps/oss/tests/__init__.py b/rsconcept/backend/apps/oss/tests/__init__.py
new file mode 100644
index 00000000..a27a6767
--- /dev/null
+++ b/rsconcept/backend/apps/oss/tests/__init__.py
@@ -0,0 +1,3 @@
+''' Tests. '''
+from .s_models import *
+from .s_views import *
diff --git a/rsconcept/backend/apps/oss/tests/s_models/__init__.py b/rsconcept/backend/apps/oss/tests/s_models/__init__.py
new file mode 100644
index 00000000..4458b11f
--- /dev/null
+++ b/rsconcept/backend/apps/oss/tests/s_models/__init__.py
@@ -0,0 +1 @@
+''' Tests for Django Models. '''
diff --git a/rsconcept/backend/apps/oss/tests/s_views/__init__.py b/rsconcept/backend/apps/oss/tests/s_views/__init__.py
new file mode 100644
index 00000000..10c776a8
--- /dev/null
+++ b/rsconcept/backend/apps/oss/tests/s_views/__init__.py
@@ -0,0 +1,2 @@
+''' Tests for REST API. '''
+from .t_oss import *
diff --git a/rsconcept/backend/apps/oss/tests/s_views/t_oss.py b/rsconcept/backend/apps/oss/tests/s_views/t_oss.py
new file mode 100644
index 00000000..1247148a
--- /dev/null
+++ b/rsconcept/backend/apps/oss/tests/s_views/t_oss.py
@@ -0,0 +1,189 @@
+''' Testing API: Operation Schema. '''
+
+from rest_framework import status
+
+from apps.oss.models import Operation, OperationSchema, OperationType
+from apps.rsform.models import AccessPolicy, LibraryItem, LibraryItemType, LocationHead, RSForm
+from shared.EndpointTester import EndpointTester, decl_endpoint
+
+
+class TestOssViewset(EndpointTester):
+ ''' Testing OSS view. '''
+
+ def setUp(self):
+ super().setUp()
+ self.owned = OperationSchema.create(title='Test', alias='T1', owner=self.user)
+ self.owned_id = self.owned.item.pk
+ self.unowned = OperationSchema.create(title='Test2', alias='T2')
+ self.unowned_id = self.unowned.item.pk
+ self.private = OperationSchema.create(title='Test2', alias='T2', access_policy=AccessPolicy.PRIVATE)
+ self.private_id = self.private.item.pk
+ self.invalid_id = self.private.item.pk + 1337
+
+
+ def populateData(self):
+ self.ks1 = RSForm.create(alias='KS1', title='Test1')
+ self.ks1x1 = self.ks1.insert_new('X1', term_resolved='X1_1')
+ self.ks2 = RSForm.create(alias='KS2', title='Test2')
+ self.ks2x1 = self.ks2.insert_new('X2', term_resolved='X1_2')
+ self.operation1 = self.owned.create_operation(
+ alias='1',
+ operation_type=OperationType.INPUT,
+ result=self.ks1.item
+ )
+ self.operation2 = self.owned.create_operation(
+ alias='2',
+ operation_type=OperationType.INPUT,
+ result=self.ks2.item
+ )
+ self.operation3 = self.owned.create_operation(
+ alias='3',
+ operation_type=OperationType.SYNTHESIS
+ )
+ self.owned.add_argument(self.operation3, self.operation1)
+ self.owned.add_argument(self.operation3, self.operation2)
+ self.owned.set_substitutions(self.operation3, [{
+ 'original': self.ks1x1,
+ 'substitution': self.ks2x1,
+ 'transfer_term': False
+ }])
+
+ @decl_endpoint('/api/oss/{item}/details', method='get')
+ def test_details(self):
+ self.populateData()
+
+ response = self.executeOK(item=self.owned_id)
+ self.assertEqual(response.data['owner'], self.owned.item.owner.pk)
+ self.assertEqual(response.data['title'], self.owned.item.title)
+ self.assertEqual(response.data['alias'], self.owned.item.alias)
+ self.assertEqual(response.data['location'], self.owned.item.location)
+ self.assertEqual(response.data['access_policy'], self.owned.item.access_policy)
+ self.assertEqual(response.data['visible'], self.owned.item.visible)
+
+ self.assertEqual(response.data['item_type'], LibraryItemType.OPERATION_SCHEMA)
+
+ self.assertEqual(len(response.data['items']), 3)
+ self.assertEqual(response.data['items'][0]['id'], self.operation1.pk)
+ self.assertEqual(response.data['items'][0]['operation_type'], self.operation1.operation_type)
+
+ self.assertEqual(len(response.data['substitutions']), 1)
+ sub = response.data['substitutions'][0]
+ self.assertEqual(sub['operation'], self.operation3.pk)
+ self.assertEqual(sub['original'], self.ks1x1.pk)
+ self.assertEqual(sub['substitution'], self.ks2x1.pk)
+ self.assertEqual(sub['transfer_term'], False)
+ self.assertEqual(sub['original_alias'], self.ks1x1.alias)
+ self.assertEqual(sub['original_term'], self.ks1x1.term_resolved)
+ self.assertEqual(sub['substitution_alias'], self.ks2x1.alias)
+ self.assertEqual(sub['substitution_term'], self.ks2x1.term_resolved)
+
+ graph = response.data['graph']
+ self.assertEqual(len(graph), 2)
+ self.assertEqual(graph[0]['operation'], self.operation3.pk)
+ self.assertEqual(graph[0]['argument'], self.operation1.pk)
+ self.assertEqual(graph[1]['operation'], self.operation3.pk)
+ self.assertEqual(graph[1]['argument'], self.operation2.pk)
+
+ self.executeOK(item=self.unowned_id)
+ self.executeForbidden(item=self.private_id)
+
+ self.logout()
+ self.executeOK(item=self.owned_id)
+ self.executeOK(item=self.unowned_id)
+ self.executeForbidden(item=self.private_id)
+
+ @decl_endpoint('/api/oss/{item}/update-positions', method='patch')
+ def test_update_positions(self):
+ self.populateData()
+ self.executeBadData(item=self.owned_id)
+
+ data = {'positions': []}
+ self.executeOK(data=data)
+
+ data = {'positions': [
+ {'id': self.operation1.pk, 'position_x': 42.1, 'position_y': 1337},
+ {'id': self.operation2.pk, 'position_x': 36.1, 'position_y': 1437},
+ {'id': self.invalid_id, 'position_x': 31, 'position_y': 12},
+ ]}
+ self.toggle_admin(True)
+ self.executeOK(data=data, item=self.unowned_id)
+ self.operation1.refresh_from_db()
+ self.assertNotEqual(self.operation1.position_x, data['positions'][0]['position_x'])
+ self.assertNotEqual(self.operation1.position_y, data['positions'][0]['position_y'])
+
+ self.toggle_admin(False)
+ self.executeOK(data=data, item=self.owned_id)
+ self.operation1.refresh_from_db()
+ self.operation2.refresh_from_db()
+ self.assertEqual(self.operation1.position_x, data['positions'][0]['position_x'])
+ self.assertEqual(self.operation1.position_y, data['positions'][0]['position_y'])
+ self.assertEqual(self.operation2.position_x, data['positions'][1]['position_x'])
+ self.assertEqual(self.operation2.position_y, data['positions'][1]['position_y'])
+
+ self.executeForbidden(data=data, item=self.unowned_id)
+ self.executeForbidden(item=self.private_id)
+
+
+ @decl_endpoint('/api/oss/{item}/create-operation', method='post')
+ def test_create_operation(self):
+ self.executeNotFound(item=self.invalid_id)
+
+ self.populateData()
+ self.executeBadData(item=self.owned_id)
+
+ data = {
+ 'item_data': {
+ 'alias': 'Test3',
+ 'title': 'Test title',
+ 'comment': 'Тест кириллицы',
+ 'position_x': 1,
+ 'position_y': 1,
+ },
+ 'positions': [
+ {'id': self.operation1.pk, 'position_x': 42.1, 'position_y': 1337}
+ ]
+ }
+ self.executeBadData(data=data)
+
+ data['item_data']['operation_type'] = 'invalid'
+ self.executeBadData(data=data)
+
+ data['item_data']['operation_type'] = OperationType.INPUT
+ response = self.executeCreated(data=data)
+ self.assertEqual(len(response.data['oss']['items']), 4)
+ new_operation = response.data['new_operation']
+ self.assertEqual(new_operation['alias'], data['item_data']['alias'])
+ self.assertEqual(new_operation['operation_type'], data['item_data']['operation_type'])
+ self.assertEqual(new_operation['title'], data['item_data']['title'])
+ self.assertEqual(new_operation['comment'], data['item_data']['comment'])
+ self.assertEqual(new_operation['position_x'], data['item_data']['position_x'])
+ self.assertEqual(new_operation['position_y'], data['item_data']['position_y'])
+ self.operation1.refresh_from_db()
+ self.assertEqual(self.operation1.position_x, data['positions'][0]['position_x'])
+ self.assertEqual(self.operation1.position_y, data['positions'][0]['position_y'])
+
+ self.executeForbidden(data=data, item=self.unowned_id)
+ self.toggle_admin(True)
+ self.executeCreated(data=data, item=self.unowned_id)
+
+ @decl_endpoint('/api/oss/{item}/delete-operation', method='patch')
+ def test_delete_operation(self):
+ self.executeNotFound(item=self.invalid_id)
+
+ self.populateData()
+ self.executeBadData(item=self.owned_id)
+
+ data = {
+ 'positions': []
+ }
+ self.executeBadData(data=data)
+
+ data['target'] = self.operation1.pk
+ self.toggle_admin(True)
+ self.executeBadData(data=data, item=self.unowned_id)
+ self.logout()
+ self.executeForbidden(data=data, item=self.owned_id)
+
+ self.login()
+ response = self.executeOK(data=data)
+ self.assertEqual(len(response.data['items']), 2)
diff --git a/rsconcept/backend/apps/oss/urls.py b/rsconcept/backend/apps/oss/urls.py
new file mode 100644
index 00000000..04f3a316
--- /dev/null
+++ b/rsconcept/backend/apps/oss/urls.py
@@ -0,0 +1,12 @@
+''' Routing: Operation Schema. '''
+from django.urls import include, path
+from rest_framework import routers
+
+from . import views
+
+library_router = routers.SimpleRouter(trailing_slash=False)
+library_router.register('oss', views.OssViewSet, 'OSS')
+
+urlpatterns = [
+ path('', include(library_router.urls)),
+]
diff --git a/rsconcept/backend/apps/oss/views/__init__.py b/rsconcept/backend/apps/oss/views/__init__.py
new file mode 100644
index 00000000..d9319816
--- /dev/null
+++ b/rsconcept/backend/apps/oss/views/__init__.py
@@ -0,0 +1,2 @@
+''' REST API: Endpoint processors. '''
+from .oss import OssViewSet
diff --git a/rsconcept/backend/apps/oss/views/oss.py b/rsconcept/backend/apps/oss/views/oss.py
new file mode 100644
index 00000000..b824f321
--- /dev/null
+++ b/rsconcept/backend/apps/oss/views/oss.py
@@ -0,0 +1,141 @@
+''' Endpoints for OSS. '''
+from typing import cast
+
+from django.db import transaction
+from drf_spectacular.utils import extend_schema, extend_schema_view
+from rest_framework import generics
+from rest_framework import status as c
+from rest_framework import viewsets
+from rest_framework.decorators import action
+from rest_framework.request import Request
+from rest_framework.response import Response
+
+from shared import permissions
+
+from .. import models as m
+from .. import serializers as s
+
+
+@extend_schema(tags=['OSS'])
+@extend_schema_view()
+class OssViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.RetrieveAPIView):
+ ''' Endpoint: OperationSchema. '''
+ queryset = m.LibraryItem.objects.filter(item_type=m.LibraryItemType.OPERATION_SCHEMA)
+ serializer_class = s.LibraryItemSerializer
+
+ def _get_schema(self) -> m.OperationSchema:
+ return m.OperationSchema(cast(m.LibraryItem, self.get_object()))
+
+ def get_permissions(self):
+ ''' Determine permission class. '''
+ if self.action in [
+ 'create_operation',
+ 'delete_operation',
+ 'update_positions'
+ ]:
+ permission_list = [permissions.ItemEditor]
+ elif self.action in ['details']:
+ permission_list = [permissions.ItemAnyone]
+ else:
+ permission_list = [permissions.Anyone]
+ return [permission() for permission in permission_list]
+
+ @extend_schema(
+ summary='get operations data',
+ tags=['OSS'],
+ request=None,
+ responses={
+ c.HTTP_200_OK: s.OperationSchemaSerializer,
+ c.HTTP_404_NOT_FOUND: None
+ }
+ )
+ @action(detail=True, methods=['get'], url_path='details')
+ def details(self, request: Request, pk):
+ ''' Endpoint: Detailed OSS data. '''
+ serializer = s.OperationSchemaSerializer(cast(m.LibraryItem, self.get_object()))
+ return Response(
+ status=c.HTTP_200_OK,
+ data=serializer.data
+ )
+
+ @extend_schema(
+ summary='update positions',
+ tags=['OSS'],
+ request=s.PositionsSerializer,
+ responses={
+ c.HTTP_200_OK: None,
+ c.HTTP_403_FORBIDDEN: None,
+ c.HTTP_404_NOT_FOUND: None
+ }
+ )
+ @action(detail=True, methods=['patch'], url_path='update-positions')
+ def update_positions(self, request: Request, pk):
+ ''' Endpoint: Update operations positions. '''
+ schema = self._get_schema()
+ serializer = s.PositionsSerializer(data=request.data)
+ serializer.is_valid(raise_exception=True)
+ schema.update_positions(serializer.validated_data['positions'])
+ return Response(status=c.HTTP_200_OK)
+
+ @extend_schema(
+ summary='create operation',
+ tags=['OSS'],
+ request=s.OperationCreateSerializer(),
+ responses={
+ c.HTTP_201_CREATED: s.NewOperationResponse,
+ c.HTTP_400_BAD_REQUEST: None,
+ c.HTTP_403_FORBIDDEN: None,
+ c.HTTP_404_NOT_FOUND: None
+ }
+ )
+ @action(detail=True, methods=['post'], url_path='create-operation')
+ def create_operation(self, request: Request, pk):
+ ''' Create new operation. '''
+ schema = self._get_schema()
+ serializer = s.OperationCreateSerializer(data=request.data)
+ serializer.is_valid(raise_exception=True)
+
+ with transaction.atomic():
+ schema.update_positions(serializer.validated_data['positions'])
+ new_operation = schema.create_operation(**serializer.validated_data['item_data'])
+ schema.item.refresh_from_db()
+
+ response = Response(
+ status=c.HTTP_201_CREATED,
+ data={
+ 'new_operation': s.OperationSerializer(new_operation).data,
+ 'oss': s.OperationSchemaSerializer(schema.item).data
+ }
+ )
+ return response
+
+ @extend_schema(
+ summary='delete operation',
+ tags=['OSS'],
+ request=s.OperationDeleteSerializer,
+ responses={
+ c.HTTP_200_OK: s.OperationSchemaSerializer,
+ c.HTTP_400_BAD_REQUEST: None,
+ c.HTTP_403_FORBIDDEN: None,
+ c.HTTP_404_NOT_FOUND: None
+ }
+ )
+ @action(detail=True, methods=['patch'], url_path='delete-operation')
+ def delete_operation(self, request: Request, pk):
+ ''' Endpoint: Delete operation. '''
+ schema = self._get_schema()
+ serializer = s.OperationDeleteSerializer(
+ data=request.data,
+ context={'oss': schema.item}
+ )
+ serializer.is_valid(raise_exception=True)
+
+ with transaction.atomic():
+ schema.update_positions(serializer.validated_data['positions'])
+ schema.delete_operation(serializer.validated_data['target'])
+ schema.item.refresh_from_db()
+
+ return Response(
+ status=c.HTTP_200_OK,
+ data=s.OperationSchemaSerializer(schema.item).data
+ )
diff --git a/rsconcept/backend/apps/rsform/graph.py b/rsconcept/backend/apps/rsform/graph.py
index 4177840d..b6a749ad 100644
--- a/rsconcept/backend/apps/rsform/graph.py
+++ b/rsconcept/backend/apps/rsform/graph.py
@@ -91,7 +91,7 @@ class Graph(Generic[ItemType]):
if len(self.inputs[node_id]) == 0:
continue
for parent in self.inputs[node_id]:
- result[parent] = result[parent] + [id for id in result[node_id] if not id in result[parent]]
+ result[parent] = result[parent] + [id for id in result[node_id] if id not in result[parent]]
return result
def topological_order(self) -> list[ItemType]:
diff --git a/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py b/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py
new file mode 100644
index 00000000..ef7f844d
--- /dev/null
+++ b/rsconcept/backend/apps/rsform/migrations/0008_alter_libraryitem_item_type.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.0.7 on 2024-07-17 09:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('rsform', '0007_location_and_flags'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='libraryitem',
+ name='item_type',
+ field=models.CharField(choices=[('rsform', 'Rsform'), ('oss', 'Operation Schema')], max_length=50, verbose_name='Тип'),
+ ),
+ ]
diff --git a/rsconcept/backend/apps/rsform/models/Editor.py b/rsconcept/backend/apps/rsform/models/Editor.py
index 2f9ce6a0..d43ae17c 100644
--- a/rsconcept/backend/apps/rsform/models/Editor.py
+++ b/rsconcept/backend/apps/rsform/models/Editor.py
@@ -60,12 +60,12 @@ class Editor(Model):
''' Set editors for item. '''
processed: list[User] = []
for editor_item in Editor.objects.filter(item=item):
- if not editor_item.editor in users:
+ if editor_item.editor not in users:
editor_item.delete()
else:
processed.append(editor_item.editor)
for user in users:
- if not user in processed:
+ if user not in processed:
processed.append(user)
Editor.objects.create(item=item, editor=user)
diff --git a/rsconcept/backend/apps/rsform/models/LibraryItem.py b/rsconcept/backend/apps/rsform/models/LibraryItem.py
index 56813796..d4daf365 100644
--- a/rsconcept/backend/apps/rsform/models/LibraryItem.py
+++ b/rsconcept/backend/apps/rsform/models/LibraryItem.py
@@ -9,6 +9,7 @@ from django.db.models import (
DateTimeField,
ForeignKey,
Model,
+ QuerySet,
TextChoices,
TextField
)
@@ -23,7 +24,7 @@ from .Version import Version
class LibraryItemType(TextChoices):
''' Type of library items '''
RSFORM = 'rsform'
- OPERATIONS_SCHEMA = 'oss'
+ OPERATION_SCHEMA = 'oss'
class AccessPolicy(TextChoices):
@@ -113,17 +114,17 @@ class LibraryItem(Model):
def get_absolute_url(self):
return f'/api/library/{self.pk}'
- def subscribers(self) -> list[Subscription]:
+ def subscribers(self) -> list[User]:
''' Get all subscribers for this item. '''
- return [subscription.user for subscription in Subscription.objects.filter(item=self.pk)]
+ return [subscription.user for subscription in Subscription.objects.filter(item=self.pk).only('user')]
- def versions(self) -> list[Version]:
- ''' Get all Versions of this item. '''
- return list(Version.objects.filter(item=self.pk).order_by('-time_create'))
-
- def editors(self) -> list[Editor]:
+ def editors(self) -> list[User]:
''' Get all Editors of this item. '''
- return [item.editor for item in Editor.objects.filter(item=self.pk)]
+ return [item.editor for item in Editor.objects.filter(item=self.pk).only('editor')]
+
+ def versions(self) -> QuerySet[Version]:
+ ''' Get all Versions of this item. '''
+ return Version.objects.filter(item=self.pk).order_by('-time_create')
@transaction.atomic
def save(self, *args, **kwargs):
diff --git a/rsconcept/backend/apps/rsform/models/api_RSForm.py b/rsconcept/backend/apps/rsform/models/api_RSForm.py
index e0c03e12..9790f6b0 100644
--- a/rsconcept/backend/apps/rsform/models/api_RSForm.py
+++ b/rsconcept/backend/apps/rsform/models/api_RSForm.py
@@ -1,13 +1,14 @@
''' Models: RSForm API. '''
from copy import deepcopy
-from typing import Optional, Union, cast
+from typing import Optional, cast
from cctext import Entity, Resolver, TermForm, extract_entities, split_grams
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import QuerySet
-from .. import messages as msg
+from shared import messages as msg
+
from ..graph import Graph
from .api_RSLanguage import (
extract_globals,
@@ -39,7 +40,7 @@ class RSForm:
def create(**kwargs) -> 'RSForm':
return RSForm(LibraryItem.objects.create(item_type=LibraryItemType.RSFORM, **kwargs))
- def constituents(self) -> QuerySet['Constituenta']:
+ def constituents(self) -> QuerySet[Constituenta]:
''' Get QuerySet containing all constituents of current RSForm. '''
return Constituenta.objects.filter(schema=self.item)
@@ -104,11 +105,39 @@ class RSForm:
result = max(result, int(alias[1:]))
return result
+ @transaction.atomic
+ def create_cst(self, data: dict, insert_after: Optional[Constituenta] = None) -> Constituenta:
+ ''' Create new cst from data. '''
+ if insert_after is None:
+ position = _INSERT_LAST
+ else:
+ position = insert_after.order + 1
+ result = self.insert_new(data['alias'], data['cst_type'], position)
+ result.convention = data.get('convention', '')
+ result.definition_formal = data.get('definition_formal', '')
+ result.term_forms = data.get('term_forms', [])
+ result.term_raw = data.get('term_raw', '')
+ result.definition_raw = data.get('definition_raw', '')
+
+ if result.term_raw != '' or result.definition_raw != '':
+ resolver = self.resolver()
+ if result.term_raw != '':
+ resolved = resolver.resolve(result.term_raw)
+ result.term_resolved = resolved
+ resolver.context[result.alias] = Entity(result.alias, resolved)
+ if result.definition_raw != '':
+ result.definition_resolved = resolver.resolve(result.definition_raw)
+
+ result.save()
+ self.on_term_change([result.id])
+ result.refresh_from_db()
+ return result
+
@transaction.atomic
def insert_new(
self,
alias: str,
- cst_type: Union[CstType, None] = None,
+ cst_type: Optional[CstType] = None,
position: int = _INSERT_LAST,
**kwargs
) -> Constituenta:
@@ -195,27 +224,6 @@ class RSForm:
self.resolve_all_text()
self.item.save()
- @transaction.atomic
- def create_cst(self, data: dict, insert_after: Optional[str] = None) -> Constituenta:
- ''' Create new cst from data. '''
- resolver = self.resolver()
- cst = self._insert_new(data, insert_after)
- cst.convention = data.get('convention', '')
- cst.definition_formal = data.get('definition_formal', '')
- cst.term_forms = data.get('term_forms', [])
- cst.term_raw = data.get('term_raw', '')
- if cst.term_raw != '':
- resolved = resolver.resolve(cst.term_raw)
- cst.term_resolved = resolved
- resolver.context[cst.alias] = Entity(cst.alias, resolved)
- cst.definition_raw = data.get('definition_raw', '')
- if cst.definition_raw != '':
- cst.definition_resolved = resolver.resolve(cst.definition_raw)
- cst.save()
- self.on_term_change([cst.id])
- cst.refresh_from_db()
- return cst
-
@transaction.atomic
def substitute(
self,
@@ -363,13 +371,6 @@ class RSForm:
cst.save()
order += 1
- def _insert_new(self, data: dict, insert_after: Optional[str] = None) -> Constituenta:
- if insert_after is not None:
- cst_after = Constituenta.objects.get(pk=insert_after)
- return self.insert_new(data['alias'], data['cst_type'], cst_after.order + 1)
- else:
- return self.insert_new(data['alias'], data['cst_type'])
-
def _graph_formal(self) -> Graph[int]:
''' Graph based on formal definitions. '''
result: Graph[int] = Graph()
diff --git a/rsconcept/backend/apps/rsform/models/api_RSLanguage.py b/rsconcept/backend/apps/rsform/models/api_RSLanguage.py
index d32a8c4e..26daa1bb 100644
--- a/rsconcept/backend/apps/rsform/models/api_RSLanguage.py
+++ b/rsconcept/backend/apps/rsform/models/api_RSLanguage.py
@@ -6,7 +6,8 @@ from typing import Set, Tuple, cast
import pyconcept
-from .. import messages as msg
+from shared import messages as msg
+
from .Constituenta import CstType
_RE_GLOBALS = r'[XCSADFPT]\d+' # cspell:disable-line
diff --git a/rsconcept/backend/apps/rsform/serializers/__init__.py b/rsconcept/backend/apps/rsform/serializers/__init__.py
index 5c0aaca3..797fcaef 100644
--- a/rsconcept/backend/apps/rsform/serializers/__init__.py
+++ b/rsconcept/backend/apps/rsform/serializers/__init__.py
@@ -22,6 +22,7 @@ from .data_access import (
InlineSynthesisSerializer,
LibraryItemBaseSerializer,
LibraryItemCloneSerializer,
+ LibraryItemDetailsSerializer,
LibraryItemSerializer,
RSFormParseSerializer,
RSFormSerializer,
diff --git a/rsconcept/backend/apps/rsform/serializers/basics.py b/rsconcept/backend/apps/rsform/serializers/basics.py
index cc21c83f..a7a19c3b 100644
--- a/rsconcept/backend/apps/rsform/serializers/basics.py
+++ b/rsconcept/backend/apps/rsform/serializers/basics.py
@@ -4,7 +4,8 @@ from typing import cast
from cctext import EntityReference, Reference, ReferenceType, Resolver, SyntacticReference
from rest_framework import serializers
-from .. import messages as msg
+from shared import messages as msg
+
from ..models import AccessPolicy, validate_location
@@ -34,7 +35,7 @@ class LocationSerializer(serializers.Serializer):
class AccessPolicySerializer(serializers.Serializer):
''' Serializer: Constituenta renaming. '''
- access_policy = serializers.CharField(max_length=500)
+ access_policy = serializers.CharField()
def validate(self, attrs):
attrs = super().validate(attrs)
diff --git a/rsconcept/backend/apps/rsform/serializers/data_access.py b/rsconcept/backend/apps/rsform/serializers/data_access.py
index 2861eff7..b181fa74 100644
--- a/rsconcept/backend/apps/rsform/serializers/data_access.py
+++ b/rsconcept/backend/apps/rsform/serializers/data_access.py
@@ -7,7 +7,8 @@ from django.db import transaction
from rest_framework import serializers
from rest_framework.serializers import PrimaryKeyRelatedField as PKField
-from .. import messages as msg
+from shared import messages as msg
+
from ..models import Constituenta, CstType, LibraryItem, RSForm, Version
from .basics import CstParseSerializer
from .io_pyconcept import PyConceptAdapter
@@ -140,6 +141,8 @@ class CstDetailsSerializer(serializers.ModelSerializer):
class CstCreateSerializer(serializers.ModelSerializer):
''' Serializer: Constituenta creation. '''
insert_after = serializers.IntegerField(required=False, allow_null=True)
+ alias = serializers.CharField(max_length=8)
+ cst_type = serializers.ChoiceField(CstType.choices)
class Meta:
''' serializer metadata. '''
diff --git a/rsconcept/backend/apps/rsform/serializers/io_files.py b/rsconcept/backend/apps/rsform/serializers/io_files.py
index 00065236..afc59108 100644
--- a/rsconcept/backend/apps/rsform/serializers/io_files.py
+++ b/rsconcept/backend/apps/rsform/serializers/io_files.py
@@ -2,7 +2,8 @@
from django.db import transaction
from rest_framework import serializers
-from .. import messages as msg
+from shared import messages as msg
+
from ..models import Constituenta, LibraryItem, RSForm
from ..utils import fix_old_references
diff --git a/rsconcept/backend/apps/rsform/serializers/io_pyconcept.py b/rsconcept/backend/apps/rsform/serializers/io_pyconcept.py
index 1aa79820..0b767b62 100644
--- a/rsconcept/backend/apps/rsform/serializers/io_pyconcept.py
+++ b/rsconcept/backend/apps/rsform/serializers/io_pyconcept.py
@@ -4,7 +4,8 @@ from typing import Optional, Union, cast
import pyconcept
-from .. import messages as msg
+from shared import messages as msg
+
from ..models import RSForm
diff --git a/rsconcept/backend/apps/rsform/tests/__init__.py b/rsconcept/backend/apps/rsform/tests/__init__.py
index 66f814e6..039a907c 100644
--- a/rsconcept/backend/apps/rsform/tests/__init__.py
+++ b/rsconcept/backend/apps/rsform/tests/__init__.py
@@ -1,5 +1,5 @@
''' Tests. '''
-from .s_models.t_RSForm import *
+from .s_models import *
from .s_views import *
from .t_graph import *
from .t_imports import *
diff --git a/rsconcept/backend/apps/rsform/tests/s_models/__init__.py b/rsconcept/backend/apps/rsform/tests/s_models/__init__.py
index f2ec99ed..44295f0f 100644
--- a/rsconcept/backend/apps/rsform/tests/s_models/__init__.py
+++ b/rsconcept/backend/apps/rsform/tests/s_models/__init__.py
@@ -1,4 +1,4 @@
-''' Tests for REST API. '''
+''' Tests for Django Models. '''
from .t_Constituenta import *
from .t_Editor import *
from .t_LibraryItem import *
diff --git a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py
index 7881f2b9..195bb080 100644
--- a/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py
+++ b/rsconcept/backend/apps/rsform/tests/s_models/t_RSForm.py
@@ -101,6 +101,26 @@ class TestRSForm(TestCase):
self.assertEqual(x2.schema, self.schema.item)
self.assertEqual(x1.order, 1)
+ def test_create_cst(self):
+ data = {
+ 'alias': 'X3',
+ 'cst_type': CstType.BASE,
+ 'term_raw': 'слон',
+ 'definition_raw': 'test',
+ 'convention': 'convention'
+ }
+
+ x1 = self.schema.insert_new('X1')
+ x2 = self.schema.insert_new('X2')
+ x3 = self.schema.create_cst(data=data, insert_after=x1)
+ x2.refresh_from_db()
+
+ self.assertEqual(x3.alias, data['alias'])
+ self.assertEqual(x3.term_raw, data['term_raw'])
+ self.assertEqual(x3.definition_raw, data['definition_raw'])
+ self.assertEqual(x2.order, 3)
+ self.assertEqual(x3.order, 2)
+
def test_create_cst_resolve(self):
x1 = self.schema.insert_new(
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py b/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py
index 33c91811..01e2adc3 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_cctext.py
@@ -1,7 +1,7 @@
''' Testing views '''
from cctext import split_grams
-from ..EndpointTester import EndpointTester, decl_endpoint
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestNaturalLanguageViews(EndpointTester):
@@ -14,20 +14,20 @@ class TestNaturalLanguageViews(EndpointTester):
@decl_endpoint(endpoint='/api/cctext/parse', method='post')
def test_parse_text(self):
data = {'text': 'синим слонам'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self._assert_tags(response.data['result'], 'datv,NOUN,plur,anim,masc')
@decl_endpoint(endpoint='/api/cctext/inflect', method='post')
def test_inflect(self):
data = {'text': 'синий слон', 'grams': 'plur,datv'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.assertEqual(response.data['result'], 'синим слонам')
@decl_endpoint(endpoint='/api/cctext/generate-lexeme', method='post')
def test_generate_lexeme(self):
data = {'text': 'синий слон'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.assertEqual(len(response.data['items']), 12)
self.assertEqual(response.data['items'][0]['text'], 'синий слон')
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py
index a19cfc49..b11d950e 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_constituents.py
@@ -1,7 +1,6 @@
''' Testing API: Constituents. '''
from apps.rsform.models import Constituenta, CstType, RSForm
-
-from ..EndpointTester import EndpointTester, decl_endpoint
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestConstituentaAPI(EndpointTester):
@@ -52,18 +51,18 @@ class TestConstituentaAPI(EndpointTester):
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_partial_update(self):
data = {'convention': 'tt'}
- self.executeForbidden(data, item=self.cst2.pk)
+ self.executeForbidden(data=data, item=self.cst2.pk)
self.logout()
- self.executeForbidden(data, item=self.cst1.pk)
+ self.executeForbidden(data=data, item=self.cst1.pk)
self.login()
- response = self.executeOK(data, item=self.cst1.pk)
+ response = self.executeOK(data=data, item=self.cst1.pk)
self.cst1.refresh_from_db()
self.assertEqual(response.data['convention'], 'tt')
self.assertEqual(self.cst1.convention, 'tt')
- self.executeOK(data, item=self.cst1.pk)
+ self.executeOK(data=data, item=self.cst1.pk)
@decl_endpoint('/api/constituents/{item}', method='patch')
@@ -72,7 +71,7 @@ class TestConstituentaAPI(EndpointTester):
'term_raw': 'New term',
'definition_raw': 'New def'
}
- response = self.executeOK(data, item=self.cst3.pk)
+ response = self.executeOK(data=data, item=self.cst3.pk)
self.cst3.refresh_from_db()
self.assertEqual(response.data['term_resolved'], 'New term')
self.assertEqual(self.cst3.term_resolved, 'New term')
@@ -86,7 +85,7 @@ class TestConstituentaAPI(EndpointTester):
'term_raw': '@{X1|nomn,sing}',
'definition_raw': '@{X1|nomn,sing} @{X1|sing,datv}'
}
- response = self.executeOK(data, item=self.cst3.pk)
+ response = self.executeOK(data=data, item=self.cst3.pk)
self.cst3.refresh_from_db()
self.assertEqual(self.cst3.term_resolved, self.cst1.term_resolved)
self.assertEqual(response.data['term_resolved'], self.cst1.term_resolved)
@@ -97,7 +96,7 @@ class TestConstituentaAPI(EndpointTester):
@decl_endpoint('/api/constituents/{item}', method='patch')
def test_readonly_cst_fields(self):
data = {'alias': 'X33', 'order': 10}
- response = self.executeOK(data, item=self.cst1.pk)
+ response = self.executeOK(data=data, item=self.cst1.pk)
self.assertEqual(response.data['alias'], 'X1')
self.assertEqual(response.data['alias'], self.cst1.alias)
self.assertEqual(response.data['order'], self.cst1.order)
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py
index 3c53d80e..d83700fc 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_library.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_library.py
@@ -11,9 +11,8 @@ from apps.rsform.models import (
RSForm,
Subscription
)
-
-from ..EndpointTester import EndpointTester, decl_endpoint
-from ..testing_utils import response_contains
+from shared.EndpointTester import EndpointTester, decl_endpoint
+from shared.testing_utils import response_contains
class TestLibraryViewset(EndpointTester):
@@ -49,17 +48,17 @@ class TestLibraryViewset(EndpointTester):
'title': 'Title',
'alias': 'alias',
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {
- 'item_type': LibraryItemType.OPERATIONS_SCHEMA,
+ 'item_type': LibraryItemType.OPERATION_SCHEMA,
'title': 'Title',
'alias': 'alias',
'access_policy': AccessPolicy.PROTECTED,
'visible': False,
'read_only': True
}
- response = self.executeCreated(data)
+ response = self.executeCreated(data=data)
self.assertEqual(response.data['owner'], self.user.pk)
self.assertEqual(response.data['item_type'], data['item_type'])
self.assertEqual(response.data['title'], data['title'])
@@ -70,25 +69,25 @@ class TestLibraryViewset(EndpointTester):
self.logout()
data = {'title': 'Title2'}
- self.executeForbidden(data)
+ self.executeForbidden(data=data)
@decl_endpoint('/api/library/{item}', method='patch')
def test_update(self):
data = {'id': self.unowned.pk, 'title': 'New Title'}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
self.toggle_editor(self.unowned, True)
- response = self.executeOK(data, item=self.unowned.pk)
+ response = self.executeOK(data=data, item=self.unowned.pk)
self.assertEqual(response.data['title'], data['title'])
self.unowned.access_policy = AccessPolicy.PRIVATE
self.unowned.save()
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeForbidden(data=data, item=self.unowned.pk)
data = {'id': self.owned.pk, 'title': 'New Title'}
- response = self.executeOK(data, item=self.owned.pk)
+ response = self.executeOK(data=data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['title'])
self.assertEqual(response.data['alias'], self.owned.alias)
@@ -99,7 +98,7 @@ class TestLibraryViewset(EndpointTester):
'access_policy': AccessPolicy.PROTECTED,
'location': LocationHead.LIBRARY
}
- response = self.executeOK(data, item=self.owned.pk)
+ response = self.executeOK(data=data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['title'])
self.assertEqual(response.data['owner'], self.owned.owner.pk)
self.assertEqual(response.data['access_policy'], self.owned.access_policy)
@@ -112,22 +111,22 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'user': self.user.pk}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.owner, self.user)
data = {'user': self.user2.pk}
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.owner, self.user2)
self.assertEqual(self.owned.time_update, time_update)
- self.executeForbidden(data, item=self.owned.pk)
+ self.executeForbidden(data=data, item=self.owned.pk)
self.toggle_admin(True)
data = {'user': self.user.pk}
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.owner, self.user)
@@ -136,20 +135,20 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'access_policy': 'invalid'}
- self.executeBadData(data, item=self.owned.pk)
+ self.executeBadData(data=data, item=self.owned.pk)
data = {'access_policy': AccessPolicy.PRIVATE}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.access_policy, data['access_policy'])
self.toggle_editor(self.unowned, True)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeForbidden(data=data, item=self.unowned.pk)
self.toggle_admin(True)
- self.executeOK(data, item=self.unowned.pk)
+ self.executeOK(data=data, item=self.unowned.pk)
self.unowned.refresh_from_db()
self.assertEqual(self.unowned.access_policy, data['access_policy'])
@@ -158,29 +157,29 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'location': 'invalid'}
- self.executeBadData(data, item=self.owned.pk)
+ self.executeBadData(data=data, item=self.owned.pk)
data = {'location': '/U/temp'}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.location, data['location'])
data = {'location': LocationHead.LIBRARY}
- self.executeForbidden(data, item=self.owned.pk)
+ self.executeForbidden(data=data, item=self.owned.pk)
data = {'location': '/U/temp'}
self.toggle_editor(self.unowned, True)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeForbidden(data=data, item=self.unowned.pk)
self.toggle_admin(True)
data = {'location': LocationHead.LIBRARY}
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.location, data['location'])
- self.executeOK(data, item=self.unowned.pk)
+ self.executeOK(data=data, item=self.unowned.pk)
self.unowned.refresh_from_db()
self.assertEqual(self.unowned.location, data['location'])
@@ -189,22 +188,22 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'user': self.invalid_user}
- self.executeBadData(data, item=self.owned.pk)
+ self.executeBadData(data=data, item=self.owned.pk)
data = {'user': self.user.pk}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.time_update, time_update)
self.assertEqual(self.owned.editors(), [self.user])
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [self.user])
data = {'user': self.user2.pk}
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(set(self.owned.editors()), set([self.user, self.user2]))
@@ -213,25 +212,25 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'user': self.invalid_user}
- self.executeBadData(data, item=self.owned.pk)
+ self.executeBadData(data=data, item=self.owned.pk)
data = {'user': self.user.pk}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.time_update, time_update)
self.assertEqual(self.owned.editors(), [])
Editor.add(item=self.owned, user=self.user)
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [])
Editor.add(item=self.owned, user=self.user)
Editor.add(item=self.owned, user=self.user2)
data = {'user': self.user2.pk}
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [self.user])
@@ -240,30 +239,30 @@ class TestLibraryViewset(EndpointTester):
time_update = self.owned.time_update
data = {'users': [self.invalid_user]}
- self.executeBadData(data, item=self.owned.pk)
+ self.executeBadData(data=data, item=self.owned.pk)
data = {'users': [self.user.pk]}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeForbidden(data, item=self.unowned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeForbidden(data=data, item=self.unowned.pk)
- self.executeOK(data, item=self.owned.pk)
+ self.executeOK(data=data, item=self.owned.pk)
self.owned.refresh_from_db()
self.assertEqual(self.owned.time_update, time_update)
self.assertEqual(self.owned.editors(), [self.user])
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [self.user])
data = {'users': [self.user2.pk]}
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [self.user2])
data = {'users': []}
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(self.owned.editors(), [])
data = {'users': [self.user2.pk, self.user.pk]}
- self.executeOK(data)
+ self.executeOK(data=data)
self.assertEqual(set(self.owned.editors()), set([self.user2, self.user]))
@@ -294,7 +293,7 @@ class TestLibraryViewset(EndpointTester):
@decl_endpoint('/api/library', method='get')
def test_library_get(self):
non_schema = LibraryItem.objects.create(
- item_type=LibraryItemType.OPERATIONS_SCHEMA,
+ item_type=LibraryItemType.OPERATION_SCHEMA,
title='Test4'
)
response = self.executeOK()
@@ -376,11 +375,11 @@ class TestLibraryViewset(EndpointTester):
)
data = {'title': 'Title1337'}
- self.executeNotFound(data, item=self.invalid_item)
- self.executeCreated(data, item=self.unowned.pk)
+ self.executeNotFound(data=data, item=self.invalid_item)
+ self.executeCreated(data=data, item=self.unowned.pk)
data = {'title': 'Title1338'}
- response = self.executeCreated(data, item=self.owned.pk)
+ response = self.executeCreated(data=data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['title'])
self.assertEqual(len(response.data['items']), 2)
self.assertEqual(response.data['items'][0]['alias'], x12.alias)
@@ -390,12 +389,12 @@ class TestLibraryViewset(EndpointTester):
self.assertEqual(response.data['items'][1]['term_resolved'], d2.term_resolved)
data = {'title': 'Title1340', 'items': []}
- response = self.executeCreated(data, item=self.owned.pk)
+ response = self.executeCreated(data=data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['title'])
self.assertEqual(len(response.data['items']), 0)
data = {'title': 'Title1341', 'items': [x12.pk]}
- response = self.executeCreated(data, item=self.owned.pk)
+ response = self.executeCreated(data=data, item=self.owned.pk)
self.assertEqual(response.data['title'], data['title'])
self.assertEqual(len(response.data['items']), 1)
self.assertEqual(response.data['items'][0]['alias'], x12.alias)
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py
index 0cd9867f..e74d9422 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_operations.py
@@ -1,7 +1,6 @@
''' Testing API: Operations. '''
from apps.rsform.models import Constituenta, CstType, RSForm
-
-from ..EndpointTester import EndpointTester, decl_endpoint
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestInlineSynthesis(EndpointTester):
@@ -24,20 +23,20 @@ class TestInlineSynthesis(EndpointTester):
'items': [],
'substitutions': []
}
- self.executeForbidden(data)
+ self.executeForbidden(data=data)
data['receiver'] = invalid_id
- self.executeBadData(data)
+ self.executeBadData(data=data)
data['receiver'] = self.schema1.item.pk
data['source'] = invalid_id
- self.executeBadData(data)
+ self.executeBadData(data=data)
data['source'] = self.schema1.item.pk
- self.executeOK(data)
+ self.executeOK(data=data)
data['items'] = [invalid_id]
- self.executeBadData(data)
+ self.executeBadData(data=data)
def test_inline_synthesis(self):
@@ -68,7 +67,7 @@ class TestInlineSynthesis(EndpointTester):
}
]
}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
result = {item['alias']: item for item in response.data['items']}
self.assertEqual(len(result), 6)
self.assertEqual(result['X2']['term_raw'], ks1_x2.term_raw)
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py
index dc735490..aa4ee1bc 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rsforms.py
@@ -15,9 +15,8 @@ from apps.rsform.models import (
LocationHead,
RSForm
)
-
-from ..EndpointTester import EndpointTester, decl_endpoint
-from ..testing_utils import response_contains
+from shared.EndpointTester import EndpointTester, decl_endpoint
+from shared.testing_utils import response_contains
class TestRSFormViewset(EndpointTester):
@@ -44,7 +43,7 @@ class TestRSFormViewset(EndpointTester):
'access_policy': AccessPolicy.PROTECTED,
'visible': False
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
with open(f'{work_dir}/data/sample-rsform.trs', 'rb') as file:
data['file'] = file
@@ -59,7 +58,7 @@ class TestRSFormViewset(EndpointTester):
@decl_endpoint('/api/rsforms', method='get')
def test_list_rsforms(self):
non_schema = LibraryItem.objects.create(
- item_type=LibraryItemType.OPERATIONS_SCHEMA,
+ item_type=LibraryItemType.OPERATION_SCHEMA,
title='Test3'
)
response = self.executeOK()
@@ -124,14 +123,14 @@ class TestRSFormViewset(EndpointTester):
def test_check(self):
self.owned.insert_new('X1')
data = {'expression': 'X1=X1'}
- response = self.executeOK(data, item=self.owned_id)
+ response = self.executeOK(data=data, item=self.owned_id)
self.assertEqual(response.data['parseResult'], True)
self.assertEqual(response.data['syntax'], 'math')
self.assertEqual(response.data['astText'], '[=[X1][X1]]')
self.assertEqual(response.data['typification'], 'LOGIC')
self.assertEqual(response.data['valueClass'], 'value')
- self.executeOK(data, item=self.unowned_id)
+ self.executeOK(data=data, item=self.unowned_id)
@decl_endpoint('/api/rsforms/{item}/resolve', method='post')
@@ -142,7 +141,7 @@ class TestRSFormViewset(EndpointTester):
)
data = {'text': '@{1|редкий} @{X1|plur,datv}'}
- response = self.executeOK(data, item=self.owned_id)
+ response = self.executeOK(data=data, item=self.owned_id)
self.assertEqual(response.data['input'], '@{1|редкий} @{X1|plur,datv}')
self.assertEqual(response.data['output'], 'редким синим слонам')
self.assertEqual(len(response.data['refs']), 2)
@@ -189,13 +188,19 @@ class TestRSFormViewset(EndpointTester):
@decl_endpoint('/api/rsforms/{item}/cst-create', method='post')
def test_create_constituenta(self):
- data = {'alias': 'X3', 'cst_type': CstType.BASE}
- self.executeForbidden(data, item=self.unowned_id)
+ data = {'alias': 'X3'}
+ self.executeForbidden(data=data, item=self.unowned_id)
self.owned.insert_new('X1')
x2 = self.owned.insert_new('X2')
+ self.executeBadData(item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
- response = self.executeCreated(data, item=self.owned_id)
+ data['cst_type'] = 'invalid'
+ self.executeBadData(data=data, item=self.owned_id)
+
+ data['cst_type'] = CstType.BASE
+ response = self.executeCreated(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], 'X3')
x3 = Constituenta.objects.get(alias=response.data['new_cst']['alias'])
self.assertEqual(x3.order, 3)
@@ -207,7 +212,7 @@ class TestRSFormViewset(EndpointTester):
'term_raw': 'test',
'term_forms': [{'text': 'form1', 'tags': 'sing,datv'}]
}
- response = self.executeCreated(data, item=self.owned_id)
+ response = self.executeCreated(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], data['alias'])
x4 = Constituenta.objects.get(alias=response.data['new_cst']['alias'])
self.assertEqual(x4.order, 3)
@@ -234,14 +239,14 @@ class TestRSFormViewset(EndpointTester):
)
data = {'target': x2_2.pk, 'alias': 'D2', 'cst_type': CstType.TERM}
- self.executeForbidden(data, item=self.unowned_id)
- self.executeBadData(data, item=self.owned_id)
+ self.executeForbidden(data=data, item=self.unowned_id)
+ self.executeBadData(data=data, item=self.owned_id)
data = {'target': x1.pk, 'alias': x1.alias, 'cst_type': CstType.TERM}
- self.executeBadData(data, item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
data = {'target': x1.pk, 'alias': x3.alias}
- self.executeBadData(data, item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
d1 = self.owned.insert_new(
alias='D1',
@@ -253,7 +258,7 @@ class TestRSFormViewset(EndpointTester):
self.assertEqual(x1.cst_type, CstType.BASE)
data = {'target': x1.pk, 'alias': 'D2', 'cst_type': CstType.TERM}
- response = self.executeOK(data, item=self.owned_id)
+ response = self.executeOK(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], 'D2')
self.assertEqual(response.data['new_cst']['cst_type'], CstType.TERM)
d1.refresh_from_db()
@@ -280,14 +285,14 @@ class TestRSFormViewset(EndpointTester):
unowned = self.unowned.insert_new('X2')
data = {'substitutions': [{'original': x1.pk, 'substitution': unowned.pk, 'transfer_term': True}]}
- self.executeForbidden(data, item=self.unowned_id)
- self.executeBadData(data, item=self.owned_id)
+ self.executeForbidden(data=data, item=self.unowned_id)
+ self.executeBadData(data=data, item=self.owned_id)
data = {'substitutions': [{'original': unowned.pk, 'substitution': x1.pk, 'transfer_term': True}]}
- self.executeBadData(data, item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
data = {'substitutions': [{'original': x1.pk, 'substitution': x1.pk, 'transfer_term': True}]}
- self.executeBadData(data, item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
d1 = self.owned.insert_new(
alias='D1',
@@ -295,7 +300,7 @@ class TestRSFormViewset(EndpointTester):
definition_formal='X1'
)
data = {'substitutions': [{'original': x1.pk, 'substitution': x2.pk, 'transfer_term': True}]}
- response = self.executeOK(data, item=self.owned_id)
+ response = self.executeOK(data=data, item=self.owned_id)
d1.refresh_from_db()
x2.refresh_from_db()
self.assertEqual(x2.term_raw, 'Test1')
@@ -315,7 +320,7 @@ class TestRSFormViewset(EndpointTester):
)
data = {'substitutions': []}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'substitutions': [
{
@@ -329,7 +334,7 @@ class TestRSFormViewset(EndpointTester):
'transfer_term': True
}
]}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'substitutions': [
{
@@ -343,7 +348,7 @@ class TestRSFormViewset(EndpointTester):
'transfer_term': True
}
]}
- response = self.executeOK(data, item=self.owned_id)
+ response = self.executeOK(data=data, item=self.owned_id)
d3.refresh_from_db()
self.assertEqual(d3.definition_formal, r'D1 \ D2')
@@ -358,7 +363,7 @@ class TestRSFormViewset(EndpointTester):
'definition_formal': '3',
'definition_raw': '4'
}
- response = self.executeCreated(data, item=self.owned_id)
+ response = self.executeCreated(data=data, item=self.owned_id)
self.assertEqual(response.data['new_cst']['alias'], 'X3')
self.assertEqual(response.data['new_cst']['cst_type'], CstType.BASE)
self.assertEqual(response.data['new_cst']['convention'], '1')
@@ -374,13 +379,13 @@ class TestRSFormViewset(EndpointTester):
self.set_params(item=self.owned_id)
data = {'items': [1337]}
- self.executeBadData(data)
+ self.executeBadData(data=data)
x1 = self.owned.insert_new('X1')
x2 = self.owned.insert_new('X2')
data = {'items': [x1.pk]}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
x2.refresh_from_db()
self.owned.item.refresh_from_db()
self.assertEqual(len(response.data['items']), 1)
@@ -390,7 +395,7 @@ class TestRSFormViewset(EndpointTester):
x3 = self.unowned.insert_new('X1')
data = {'items': [x3.pk]}
- self.executeBadData(data, item=self.owned_id)
+ self.executeBadData(data=data, item=self.owned_id)
@decl_endpoint('/api/rsforms/{item}/cst-moveto', method='patch')
@@ -398,13 +403,13 @@ class TestRSFormViewset(EndpointTester):
self.set_params(item=self.owned_id)
data = {'items': [1337], 'move_to': 1}
- self.executeBadData(data)
+ self.executeBadData(data=data)
x1 = self.owned.insert_new('X1')
x2 = self.owned.insert_new('X2')
data = {'items': [x2.pk], 'move_to': 1}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
x1.refresh_from_db()
x2.refresh_from_db()
self.assertEqual(response.data['id'], self.owned_id)
@@ -413,7 +418,7 @@ class TestRSFormViewset(EndpointTester):
x3 = self.unowned.insert_new('X1')
data = {'items': [x3.pk], 'move_to': 1}
- self.executeBadData(data)
+ self.executeBadData(data=data)
@decl_endpoint('/api/rsforms/{item}/reset-aliases', method='patch')
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py b/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py
index 910e852e..c35cf491 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_rslang.py
@@ -1,5 +1,5 @@
''' Testing views '''
-from ..EndpointTester import EndpointTester, decl_endpoint
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestRSLanguageViews(EndpointTester):
@@ -8,30 +8,30 @@ class TestRSLanguageViews(EndpointTester):
@decl_endpoint('/api/rslang/to-ascii', method='post')
def test_convert_to_ascii(self):
data = {'data': '1=1'}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'expression': '1=1'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.assertEqual(response.data['result'], r'1 \eq 1')
@decl_endpoint('/api/rslang/to-math', method='post')
def test_convert_to_math(self):
data = {'data': r'1 \eq 1'}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'expression': r'1 \eq 1'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.assertEqual(response.data['result'], r'1=1')
@decl_endpoint('/api/rslang/parse-expression', method='post')
def test_parse_expression(self):
data = {'data': r'1=1'}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'expression': r'1=1'}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.assertEqual(response.data['parseResult'], True)
self.assertEqual(response.data['syntax'], 'math')
self.assertEqual(response.data['astText'], '[=[1][1]]')
diff --git a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py b/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py
index d2b273a7..cc8433cd 100644
--- a/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py
+++ b/rsconcept/backend/apps/rsform/tests/s_views/t_versions.py
@@ -7,8 +7,7 @@ from zipfile import ZipFile
from rest_framework import status
from apps.rsform.models import Constituenta, RSForm
-
-from ..EndpointTester import EndpointTester, decl_endpoint
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestVersionViews(EndpointTester):
@@ -31,11 +30,11 @@ class TestVersionViews(EndpointTester):
invalid_id = 1338
data = {'version': '1.0.0', 'description': 'test'}
- self.executeNotFound(data, schema=invalid_id)
- self.executeForbidden(data, schema=self.unowned.pk)
- self.executeBadData(invalid_data, schema=self.owned.pk)
+ self.executeNotFound(data=data, schema=invalid_id)
+ self.executeForbidden(data=data, schema=self.unowned.pk)
+ self.executeBadData(data=invalid_data, schema=self.owned.pk)
- response = self.executeCreated(data, schema=self.owned.pk)
+ response = self.executeCreated(data=data, schema=self.owned.pk)
self.assertTrue('version' in response.data)
self.assertTrue('schema' in response.data)
self.assertTrue(response.data['version'] in [v['id'] for v in response.data['schema']['versions']])
@@ -65,7 +64,7 @@ class TestVersionViews(EndpointTester):
@decl_endpoint('/api/versions/{version}', method='get')
def test_access_version(self):
data = {'version': '1.0.0', 'description': 'test'}
- version_id = self._create_version(data)
+ version_id = self._create_version(data=data)
invalid_id = version_id + 1337
self.executeNotFound(version=invalid_id)
@@ -79,14 +78,14 @@ class TestVersionViews(EndpointTester):
data = {'version': '1.2.0', 'description': 'test1'}
self.method = 'patch'
- self.executeForbidden(data)
+ self.executeForbidden(data=data)
self.method = 'delete'
self.executeForbidden()
self.client.force_authenticate(user=self.user)
self.method = 'patch'
- self.executeOK(data)
+ self.executeOK(data=data)
response = self.get()
self.assertEqual(response.data['version'], data['version'])
self.assertEqual(response.data['description'], data['description'])
@@ -139,7 +138,7 @@ class TestVersionViews(EndpointTester):
x2 = self.schema.insert_new('X2')
d1 = self.schema.insert_new('D1', term_raw='TestTerm')
data = {'version': '1.0.0', 'description': 'test'}
- version_id = self._create_version(data)
+ version_id = self._create_version(data=data)
invalid_id = version_id + 1337
d1.delete()
diff --git a/rsconcept/backend/apps/rsform/views/constituents.py b/rsconcept/backend/apps/rsform/views/constituents.py
index cd772f1c..195a099c 100644
--- a/rsconcept/backend/apps/rsform/views/constituents.py
+++ b/rsconcept/backend/apps/rsform/views/constituents.py
@@ -2,8 +2,9 @@
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import generics
+from shared import permissions
+
from .. import models as m
-from .. import permissions
from .. import serializers as s
diff --git a/rsconcept/backend/apps/rsform/views/library.py b/rsconcept/backend/apps/rsform/views/library.py
index 4ce592af..4748a7d8 100644
--- a/rsconcept/backend/apps/rsform/views/library.py
+++ b/rsconcept/backend/apps/rsform/views/library.py
@@ -13,8 +13,9 @@ from rest_framework.decorators import action
from rest_framework.request import Request
from rest_framework.response import Response
+from shared import permissions
+
from .. import models as m
-from .. import permissions
from .. import serializers as s
@@ -42,17 +43,27 @@ class LibraryViewSet(viewsets.ModelViewSet):
def get_permissions(self):
if self.action in ['update', 'partial_update']:
- permission_list = [permissions.ItemEditor]
+ access_level = permissions.ItemEditor
elif self.action in [
- 'destroy', 'set_owner', 'set_access_policy', 'set_location',
- 'editors_add', 'editors_remove', 'editors_set'
+ 'destroy',
+ 'set_owner',
+ 'set_access_policy',
+ 'set_location',
+ 'editors_add',
+ 'editors_remove',
+ 'editors_set'
]:
- permission_list = [permissions.ItemOwner]
- elif self.action in ['create', 'clone', 'subscribe', 'unsubscribe']:
- permission_list = [permissions.GlobalUser]
+ access_level = permissions.ItemOwner
+ elif self.action in [
+ 'create',
+ 'clone',
+ 'subscribe',
+ 'unsubscribe'
+ ]:
+ access_level = permissions.GlobalUser
else:
- permission_list = [permissions.ItemAnyone]
- return [permission() for permission in permission_list]
+ access_level = permissions.ItemAnyone
+ return [access_level()]
def _get_item(self) -> m.LibraryItem:
return cast(m.LibraryItem, self.get_object())
@@ -68,7 +79,6 @@ class LibraryViewSet(viewsets.ModelViewSet):
c.HTTP_404_NOT_FOUND: None
}
)
- @transaction.atomic
@action(detail=True, methods=['post'], url_path='clone')
def clone(self, request: Request, pk):
''' Endpoint: Create deep copy of library item. '''
@@ -85,19 +95,20 @@ class LibraryViewSet(viewsets.ModelViewSet):
clone.read_only = False
clone.access_policy = serializer.validated_data.get('access_policy', m.AccessPolicy.PUBLIC)
clone.location = serializer.validated_data.get('location', m.LocationHead.USER)
- clone.save()
- if clone.item_type == m.LibraryItemType.RSFORM:
- need_filter = 'items' in request.data
- for cst in m.RSForm(item).constituents():
- if not need_filter or cst.pk in request.data['items']:
- cst.pk = None
- cst.schema = clone
- cst.save()
- return Response(
- status=c.HTTP_201_CREATED,
- data=s.RSFormParseSerializer(clone).data
- )
+ with transaction.atomic():
+ clone.save()
+ if clone.item_type == m.LibraryItemType.RSFORM:
+ need_filter = 'items' in request.data
+ for cst in m.RSForm(item).constituents():
+ if not need_filter or cst.pk in request.data['items']:
+ cst.pk = None
+ cst.schema = clone
+ cst.save()
+ return Response(
+ status=c.HTTP_201_CREATED,
+ data=s.RSFormParseSerializer(clone).data
+ )
return Response(status=c.HTTP_400_BAD_REQUEST)
@extend_schema(
@@ -266,24 +277,17 @@ class LibraryActiveView(generics.ListAPIView):
serializer_class = s.LibraryItemSerializer
def get_queryset(self):
+ common_location = Q(location__startswith=m.LocationHead.COMMON) | Q(location__startswith=m.LocationHead.LIBRARY)
+ is_public = Q(access_policy=m.AccessPolicy.PUBLIC)
if self.request.user.is_anonymous:
- return m.LibraryItem.objects.filter(
- Q(access_policy=m.AccessPolicy.PUBLIC),
- ).filter(
- Q(location__startswith=m.LocationHead.COMMON) |
- Q(location__startswith=m.LocationHead.LIBRARY)
- ).order_by('-time_update')
+ return m.LibraryItem.objects \
+ .filter(is_public) \
+ .filter(common_location).order_by('-time_update')
else:
user = cast(m.User, self.request.user)
# pylint: disable=unsupported-binary-operation
return m.LibraryItem.objects.filter(
- (
- Q(access_policy=m.AccessPolicy.PUBLIC) &
- (
- Q(location__startswith=m.LocationHead.COMMON) |
- Q(location__startswith=m.LocationHead.LIBRARY)
- )
- ) |
+ (is_public & common_location) |
Q(owner=user) |
Q(editor__editor=user) |
Q(subscription__user=user)
diff --git a/rsconcept/backend/apps/rsform/views/operations.py b/rsconcept/backend/apps/rsform/views/operations.py
index 4520d29f..3dca6751 100644
--- a/rsconcept/backend/apps/rsform/views/operations.py
+++ b/rsconcept/backend/apps/rsform/views/operations.py
@@ -18,7 +18,6 @@ from .. import serializers as s
request=s.InlineSynthesisSerializer,
responses={c.HTTP_200_OK: s.RSFormParseSerializer}
)
-@transaction.atomic
@api_view(['PATCH'])
def inline_synthesis(request: Request):
''' Endpoint: Inline synthesis. '''
@@ -30,20 +29,21 @@ def inline_synthesis(request: Request):
schema = m.RSForm(serializer.validated_data['receiver'])
items = cast(list[m.Constituenta], serializer.validated_data['items'])
- new_items = schema.insert_copy(items)
- for substitution in serializer.validated_data['substitutions']:
- original = cast(m.Constituenta, substitution['original'])
- replacement = cast(m.Constituenta, substitution['substitution'])
- if original in items:
- index = next(i for (i, cst) in enumerate(items) if cst == original)
- original = new_items[index]
- else:
- index = next(i for (i, cst) in enumerate(items) if cst == replacement)
- replacement = new_items[index]
- schema.substitute(original, replacement, substitution['transfer_term'])
+ with transaction.atomic():
+ new_items = schema.insert_copy(items)
+ for substitution in serializer.validated_data['substitutions']:
+ original = cast(m.Constituenta, substitution['original'])
+ replacement = cast(m.Constituenta, substitution['substitution'])
+ if original in items:
+ index = next(i for (i, cst) in enumerate(items) if cst == original)
+ original = new_items[index]
+ else:
+ index = next(i for (i, cst) in enumerate(items) if cst == replacement)
+ replacement = new_items[index]
+ schema.substitute(original, replacement, substitution['transfer_term'])
+ schema.restore_order()
- schema.restore_order()
return Response(
status=c.HTTP_200_OK,
data=s.RSFormParseSerializer(schema.item).data
diff --git a/rsconcept/backend/apps/rsform/views/rsforms.py b/rsconcept/backend/apps/rsform/views/rsforms.py
index 1af946f1..5c3a4e9a 100644
--- a/rsconcept/backend/apps/rsform/views/rsforms.py
+++ b/rsconcept/backend/apps/rsform/views/rsforms.py
@@ -13,9 +13,10 @@ from rest_framework.decorators import action, api_view
from rest_framework.request import Request
from rest_framework.response import Response
-from .. import messages as msg
+from shared import messages as msg
+from shared import permissions
+
from .. import models as m
-from .. import permissions
from .. import serializers as s
from .. import utils
@@ -33,11 +34,21 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
def get_permissions(self):
''' Determine permission class. '''
if self.action in [
- 'load_trs', 'cst_create', 'cst_delete_multiple',
- 'reset_aliases', 'cst_rename', 'cst_substitute'
+ 'load_trs',
+ 'reset_aliases',
+ 'cst_create',
+ 'cst_delete_multiple',
+ 'cst_rename',
+ 'cst_substitute'
]:
permission_list = [permissions.ItemEditor]
- elif self.action in ['contents', 'details', 'export_trs', 'resolve', 'check']:
+ elif self.action in [
+ 'contents',
+ 'details',
+ 'export_trs',
+ 'resolve',
+ 'check'
+ ]:
permission_list = [permissions.ItemAnyone]
else:
permission_list = [permissions.Anyone]
@@ -49,6 +60,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstCreateSerializer,
responses={
c.HTTP_201_CREATED: s.NewCstResponse,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
@@ -60,10 +72,15 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
serializer = s.CstCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
- new_cst = schema.create_cst(
- data=data,
- insert_after=data['insert_after'] if 'insert_after' in data else None
- )
+ if 'insert_after' in data:
+ try:
+ insert_after = m.Constituenta.objects.get(pk=data['insert_after'])
+ except m.LibraryItem.DoesNotExist:
+ return Response(status=c.HTTP_404_NOT_FOUND)
+ else:
+ insert_after = None
+ new_cst = schema.create_cst(data, insert_after)
+
schema.item.refresh_from_db()
response = Response(
status=c.HTTP_201_CREATED,
@@ -81,6 +98,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstTargetSerializer,
responses={
c.HTTP_200_OK: s.NewMultiCstResponse,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
@@ -117,11 +135,11 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstRenameSerializer,
responses={
c.HTTP_200_OK: s.NewCstResponse,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
)
- @transaction.atomic
@action(detail=True, methods=['patch'], url_path='cst-rename')
def cst_rename(self, request: Request, pk):
''' Rename constituenta possibly changing type. '''
@@ -134,12 +152,12 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
cst.alias = serializer.validated_data['alias']
cst.cst_type = serializer.validated_data['cst_type']
- cst.save()
- mapping = {old_alias: cst.alias}
- schema.apply_mapping(mapping, change_aliases=False)
- schema.item.refresh_from_db()
- cst.refresh_from_db()
+ with transaction.atomic():
+ cst.save()
+ schema.apply_mapping(mapping={old_alias: cst.alias}, change_aliases=False)
+ schema.item.refresh_from_db()
+ cst.refresh_from_db()
return Response(
status=c.HTTP_200_OK,
@@ -155,11 +173,11 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstSubstituteSerializer,
responses={
c.HTTP_200_OK: s.RSFormParseSerializer,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
)
- @transaction.atomic
@action(detail=True, methods=['patch'], url_path='cst-substitute')
def cst_substitute(self, request: Request, pk):
''' Substitute occurrences of constituenta with another one. '''
@@ -169,11 +187,13 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
context={'schema': schema.item}
)
serializer.is_valid(raise_exception=True)
- for substitution in serializer.validated_data['substitutions']:
- original = cast(m.Constituenta, substitution['original'])
- replacement = cast(m.Constituenta, substitution['substitution'])
- schema.substitute(original, replacement, substitution['transfer_term'])
- schema.item.refresh_from_db()
+
+ with transaction.atomic():
+ for substitution in serializer.validated_data['substitutions']:
+ original = cast(m.Constituenta, substitution['original'])
+ replacement = cast(m.Constituenta, substitution['substitution'])
+ schema.substitute(original, replacement, substitution['transfer_term'])
+ schema.item.refresh_from_db()
return Response(
status=c.HTTP_200_OK,
data=s.RSFormParseSerializer(schema.item).data
@@ -185,6 +205,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstListSerializer,
responses={
c.HTTP_200_OK: s.RSFormParseSerializer,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
@@ -211,6 +232,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.CstMoveSerializer,
responses={
c.HTTP_200_OK: s.RSFormParseSerializer,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
@@ -279,6 +301,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
request=s.RSFormUploadSerializer,
responses={
c.HTTP_200_OK: s.RSFormParseSerializer,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
@@ -313,7 +336,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
c.HTTP_404_NOT_FOUND: None
}
)
- @action(detail=True, methods=['get'])
+ @action(detail=True, methods=['get'], url_path='contents')
def contents(self, request: Request, pk):
''' Endpoint: View schema db contents (including constituents). '''
schema = s.RSFormSerializer(self.get_object())
@@ -331,7 +354,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
c.HTTP_404_NOT_FOUND: None
}
)
- @action(detail=True, methods=['get'])
+ @action(detail=True, methods=['get'], url_path='details')
def details(self, request: Request, pk):
''' Endpoint: Detailed schema view including statuses and parse. '''
serializer = s.RSFormParseSerializer(cast(m.LibraryItem, self.get_object()))
@@ -349,7 +372,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
c.HTTP_404_NOT_FOUND: None
},
)
- @action(detail=True, methods=['post'])
+ @action(detail=True, methods=['post'], url_path='check')
def check(self, request: Request, pk):
''' Endpoint: Check RSLang expression against schema context. '''
serializer = s.ExpressionSerializer(data=request.data)
@@ -371,7 +394,7 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
c.HTTP_404_NOT_FOUND: None
}
)
- @action(detail=True, methods=['post'])
+ @action(detail=True, methods=['post'], url_path='resolve')
def resolve(self, request: Request, pk):
''' Endpoint: Resolve references in text against schema terms context. '''
serializer = s.TextSerializer(data=request.data)
diff --git a/rsconcept/backend/apps/rsform/views/versions.py b/rsconcept/backend/apps/rsform/views/versions.py
index a5e69c9a..318e4da5 100644
--- a/rsconcept/backend/apps/rsform/views/versions.py
+++ b/rsconcept/backend/apps/rsform/views/versions.py
@@ -10,8 +10,9 @@ from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.request import Request
from rest_framework.response import Response
+from shared import permissions
+
from .. import models as m
-from .. import permissions
from .. import serializers as s
from .. import utils
@@ -54,6 +55,7 @@ class VersionViewset(
request=s.VersionCreateSerializer,
responses={
c.HTTP_201_CREATED: s.NewVersionResponse,
+ c.HTTP_400_BAD_REQUEST: None,
c.HTTP_403_FORBIDDEN: None,
c.HTTP_404_NOT_FOUND: None
}
diff --git a/rsconcept/backend/apps/users/messages.py b/rsconcept/backend/apps/users/messages.py
deleted file mode 100644
index f142f37a..00000000
--- a/rsconcept/backend/apps/users/messages.py
+++ /dev/null
@@ -1,14 +0,0 @@
-''' Utility: Text messages. '''
-# pylint: skip-file
-
-
-def passwordAuthFailed():
- return 'Неизвестное сочетание имени пользователя (email) и пароля'
-
-
-def passwordsNotMatch():
- return 'Введенные пароли не совпадают'
-
-
-def emailAlreadyTaken():
- return 'Пользователь с данным email уже существует'
diff --git a/rsconcept/backend/apps/users/serializers.py b/rsconcept/backend/apps/users/serializers.py
index d7ed3dd6..31f9c2e0 100644
--- a/rsconcept/backend/apps/users/serializers.py
+++ b/rsconcept/backend/apps/users/serializers.py
@@ -4,8 +4,8 @@ from django.contrib.auth.password_validation import validate_password
from rest_framework import serializers
from apps.rsform.models import Editor, Subscription
+from shared import messages as msg
-from . import messages as msg
from . import models
diff --git a/rsconcept/backend/apps/users/tests/t_views.py b/rsconcept/backend/apps/users/tests/t_views.py
index 44551a5c..d289cc91 100644
--- a/rsconcept/backend/apps/users/tests/t_views.py
+++ b/rsconcept/backend/apps/users/tests/t_views.py
@@ -1,30 +1,30 @@
''' Testing API: users. '''
from rest_framework.test import APIClient, APITestCase
-from apps.rsform.tests.EndpointTester import EndpointTester, decl_endpoint
from apps.users.models import User
+from shared.EndpointTester import EndpointTester, decl_endpoint
class TestUserAPIViews(EndpointTester):
''' Testing Authentication views. '''
def setUp(self):
- super().setUp()
+ super().setUpFullUsers()
@decl_endpoint('/users/api/login', method='post')
def test_login(self):
self.logout()
data = {'username': self.user.username, 'password': 'invalid'}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {'username': self.user.username, 'password': 'password'}
- self.executeAccepted(data)
- self.executeAccepted(data)
+ self.executeAccepted(data=data)
+ self.executeAccepted(data=data)
self.logout()
data = {'username': self.user.email, 'password': 'password'}
- self.executeAccepted(data)
+ self.executeAccepted(data=data)
@decl_endpoint('/users/api/logout', method='post')
@@ -59,7 +59,7 @@ class TestUserUserProfileAPIView(EndpointTester):
''' Testing User profile views. '''
def setUp(self):
- super().setUp()
+ super().setUpFullUsers()
self.user.first_name = 'John'
self.user.second_name = 'Smith'
self.user.save()
@@ -84,7 +84,7 @@ class TestUserUserProfileAPIView(EndpointTester):
'first_name': 'firstName',
'last_name': 'lastName',
}
- response = self.executeOK(data)
+ response = self.executeOK(data=data)
self.user.refresh_from_db()
self.assertEqual(response.data['email'], '123@mail.ru')
self.assertEqual(self.user.email, '123@mail.ru')
@@ -98,10 +98,10 @@ class TestUserUserProfileAPIView(EndpointTester):
'first_name': 'new',
'last_name': 'new2',
}
- self.executeOK(data)
+ self.executeOK(data=data)
data = {'email': self.user2.email}
- self.executeBadData(data)
+ self.executeBadData(data=data)
self.logout()
self.executeForbidden()
@@ -113,14 +113,14 @@ class TestUserUserProfileAPIView(EndpointTester):
'old_password': 'invalid',
'new_password': 'password2'
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {
'old_password': 'password',
'new_password': 'password2'
}
oldHash = self.user.password
- response = self.executeNoContent(data)
+ response = self.executeNoContent(data=data)
self.user.refresh_from_db()
self.assertNotEqual(self.user.password, oldHash)
self.assertTrue(self.client.login(username=self.user.username, password='password2'))
@@ -154,7 +154,7 @@ class TestSignupAPIView(EndpointTester):
'first_name': 'firstName',
'last_name': 'lastName'
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {
'username': 'NewUser',
@@ -164,7 +164,7 @@ class TestSignupAPIView(EndpointTester):
'first_name': 'firstName',
'last_name': 'lastName'
}
- response = self.executeCreated(data)
+ response = self.executeCreated(data=data)
self.assertTrue('id' in response.data)
self.assertEqual(response.data['username'], data['username'])
self.assertEqual(response.data['email'], data['email'])
@@ -179,7 +179,7 @@ class TestSignupAPIView(EndpointTester):
'first_name': 'firstName',
'last_name': 'lastName'
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
data = {
'username': 'NewUser2',
@@ -189,4 +189,4 @@ class TestSignupAPIView(EndpointTester):
'first_name': 'firstName',
'last_name': 'lastName'
}
- self.executeBadData(data)
+ self.executeBadData(data=data)
diff --git a/rsconcept/backend/project/settings.py b/rsconcept/backend/project/settings.py
index 2d2f0de2..5357c542 100644
--- a/rsconcept/backend/project/settings.py
+++ b/rsconcept/backend/project/settings.py
@@ -74,6 +74,7 @@ INSTALLED_APPS = [
'apps.users',
'apps.rsform',
+ 'apps.oss',
'drf_spectacular',
'drf_spectacular_sidecar',
diff --git a/rsconcept/backend/project/urls.py b/rsconcept/backend/project/urls.py
index 550874ba..c6c2aa7e 100644
--- a/rsconcept/backend/project/urls.py
+++ b/rsconcept/backend/project/urls.py
@@ -9,6 +9,7 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, Spec
urlpatterns = [
path('admin', admin.site.urls),
path('api/', include('apps.rsform.urls')),
+ path('api/', include('apps.oss.urls')),
path('users/', include('apps.users.urls')),
path('schema', SpectacularAPIView.as_view(), name='schema'),
path('redoc', SpectacularRedocView.as_view()),
diff --git a/rsconcept/backend/requirements-dev.txt b/rsconcept/backend/requirements-dev.txt
index ab9d5484..a33d4026 100644
--- a/rsconcept/backend/requirements-dev.txt
+++ b/rsconcept/backend/requirements-dev.txt
@@ -14,7 +14,6 @@ psycopg2-binary
gunicorn
djangorestframework-stubs[compatible-mypy]
-
mypy
pylint
coverage
\ No newline at end of file
diff --git a/rsconcept/backend/requirements.txt b/rsconcept/backend/requirements.txt
index 8fdafb21..652b2571 100644
--- a/rsconcept/backend/requirements.txt
+++ b/rsconcept/backend/requirements.txt
@@ -1,13 +1,13 @@
tzdata==2024.1
-Django==5.0.6
-djangorestframework==3.15.1
-django-cors-headers==4.3.1
+Django==5.0.7
+djangorestframework==3.15.2
+django-cors-headers==4.4.0
django-filter==24.2
drf-spectacular==0.27.2
-drf-spectacular-sidecar==2024.6.1
+drf-spectacular-sidecar==2024.7.1
coreapi==2.3.3
django-rest-passwordreset==1.4.1
-cctext==0.1.3
+cctext==0.1.4
pyconcept==0.1.6
psycopg2-binary==2.9.9
diff --git a/rsconcept/backend/apps/rsform/tests/EndpointTester.py b/rsconcept/backend/shared/EndpointTester.py
similarity index 92%
rename from rsconcept/backend/apps/rsform/tests/EndpointTester.py
rename to rsconcept/backend/shared/EndpointTester.py
index e2436cc4..0f0a6b63 100644
--- a/rsconcept/backend/apps/rsform/tests/EndpointTester.py
+++ b/rsconcept/backend/shared/EndpointTester.py
@@ -26,6 +26,21 @@ class EndpointTester(APITestCase):
''' Abstract base class for Testing endpoints. '''
def setUp(self):
+ self.factory = APIRequestFactory()
+ self.user = User.objects.create(
+ username='UserTest',
+ email='blank@test.com',
+ password='password'
+ )
+ self.user2 = User.objects.create(
+ username='UserTest2',
+ email='another@test.com',
+ password='password'
+ )
+ self.client = APIClient()
+ self.client.force_authenticate(user=self.user)
+
+ def setUpFullUsers(self):
self.factory = APIRequestFactory()
self.user = User.objects.create_user(
username='UserTest',
diff --git a/rsconcept/backend/shared/__init__.py b/rsconcept/backend/shared/__init__.py
new file mode 100644
index 00000000..6246926d
--- /dev/null
+++ b/rsconcept/backend/shared/__init__.py
@@ -0,0 +1 @@
+''' Utilities shared between applications. '''
diff --git a/rsconcept/backend/apps/rsform/messages.py b/rsconcept/backend/shared/messages.py
similarity index 79%
rename from rsconcept/backend/apps/rsform/messages.py
rename to rsconcept/backend/shared/messages.py
index 9469bbdb..dae5328e 100644
--- a/rsconcept/backend/apps/rsform/messages.py
+++ b/rsconcept/backend/shared/messages.py
@@ -6,6 +6,10 @@ def constituentaNotOwned(title: str):
return f'Конституента не принадлежит схеме: {title}'
+def operationNotOwned(title: str):
+ return f'Операция не принадлежит схеме: {title}'
+
+
def substitutionNotInList():
return 'Отождествляемая конституента отсутствует в списке'
@@ -64,3 +68,15 @@ def constituentaNoStructure():
def missingFile():
return 'Отсутствует прикрепленный файл'
+
+
+def passwordAuthFailed():
+ return 'Неизвестное сочетание имени пользователя (email) и пароля'
+
+
+def passwordsNotMatch():
+ return 'Введенные пароли не совпадают'
+
+
+def emailAlreadyTaken():
+ return 'Пользователь с данным email уже существует'
diff --git a/rsconcept/backend/apps/rsform/permissions.py b/rsconcept/backend/shared/permissions.py
similarity index 78%
rename from rsconcept/backend/apps/rsform/permissions.py
rename to rsconcept/backend/shared/permissions.py
index 7a163dec..87726c4d 100644
--- a/rsconcept/backend/apps/rsform/permissions.py
+++ b/rsconcept/backend/shared/permissions.py
@@ -11,16 +11,27 @@ from rest_framework.permissions import \
from rest_framework.request import Request
from rest_framework.views import APIView
-from . import models as m
+from apps.oss.models import Operation
+from apps.rsform.models import (
+ AccessPolicy,
+ Constituenta,
+ Editor,
+ LibraryItem,
+ Subscription,
+ Version
+)
+from apps.users.models import User
-def _extract_item(obj: Any) -> m.LibraryItem:
- if isinstance(obj, m.LibraryItem):
+def _extract_item(obj: Any) -> LibraryItem:
+ if isinstance(obj, LibraryItem):
return obj
- elif isinstance(obj, m.Constituenta):
- return cast(m.LibraryItem, obj.schema)
- elif isinstance(obj, (m.Version, m.Subscription, m.Editor)):
- return cast(m.LibraryItem, obj.item)
+ elif isinstance(obj, Constituenta):
+ return cast(LibraryItem, obj.schema)
+ elif isinstance(obj, Operation):
+ return cast(LibraryItem, obj.oss)
+ elif isinstance(obj, (Version, Subscription, Editor)):
+ return cast(LibraryItem, obj.item)
raise PermissionDenied({
'message': 'Invalid type error. Please contact developers',
'object_id': obj.id
@@ -60,10 +71,10 @@ class ItemEditor(ItemOwner):
if request.user.is_anonymous:
return False
item = _extract_item(obj)
- if m.Editor.objects.filter(
+ if Editor.objects.filter(
item=item,
- editor=cast(m.User, request.user)
- ).exists() and item.access_policy != m.AccessPolicy.PRIVATE:
+ editor=cast(User, request.user)
+ ).exists() and item.access_policy != AccessPolicy.PRIVATE:
return True
return super().has_object_permission(request, view, obj)
@@ -76,7 +87,7 @@ class ItemAnyone(ItemEditor):
def has_object_permission(self, request: Request, view: APIView, obj: Any) -> bool:
item = _extract_item(obj)
- if item.access_policy == m.AccessPolicy.PUBLIC:
+ if item.access_policy == AccessPolicy.PUBLIC:
return True
return super().has_object_permission(request, view, obj)
diff --git a/rsconcept/backend/apps/rsform/tests/testing_utils.py b/rsconcept/backend/shared/testing_utils.py
similarity index 100%
rename from rsconcept/backend/apps/rsform/tests/testing_utils.py
rename to rsconcept/backend/shared/testing_utils.py
diff --git a/rsconcept/frontend/.env.local b/rsconcept/frontend/.env.local
index e406b9c7..114223fa 100644
--- a/rsconcept/frontend/.env.local
+++ b/rsconcept/frontend/.env.local
@@ -1,5 +1,4 @@
# Local build config
VITE_PORTAL_BACKEND=http://localhost:8000
-VITE_PORTAL_FRONT_PORT=3000
-VITE_PORTAL_FRONT_HTTPS=false
+VITE_PORTAL_FRONT_PORT=3000
\ No newline at end of file
diff --git a/rsconcept/frontend/Dockerfile b/rsconcept/frontend/Dockerfile
index fdff3fce..6cba1d87 100644
--- a/rsconcept/frontend/Dockerfile
+++ b/rsconcept/frontend/Dockerfile
@@ -1,26 +1,30 @@
# ======== Multi-stage base ==========
-FROM node:bullseye-slim as node-base
+FROM node:22-bookworm-slim AS node-base
RUN apt-get update -qq && \
apt-get upgrade -y && \
rm -rf /var/lib/apt/lists/*
# ======= Build =======
ARG BUILD_TYPE=production
-FROM node-base as builder
+FROM node-base AS builder
WORKDIR /result
+RUN npm install -g typescript vite
+
COPY ./ ./
COPY ./env/.env.$BUILD_TYPE ./
RUN rm -rf ./env
+
RUN npm ci
-ENV NODE_ENV production
+
+ENV NODE_ENV=production
RUN npm run build
# ========= Server =======
-FROM node-base as product-server
+FROM node-base AS product-server
-ENV NODE_ENV production
+ENV NODE_ENV=production
# Install serve util
RUN npm install -g serve
diff --git a/rsconcept/frontend/Dockerfile.dev b/rsconcept/frontend/Dockerfile.dev
index be4e8c9f..00e36bab 100644
--- a/rsconcept/frontend/Dockerfile.dev
+++ b/rsconcept/frontend/Dockerfile.dev
@@ -1,14 +1,17 @@
# ======== Multi-stage base ==========
-FROM node:bullseye-slim as node-base
+FROM node:22-bookworm-slim AS node-base
RUN apt-get update -qq && \
apt-get upgrade -y && \
rm -rf /var/lib/apt/lists/*
# ========= Server =======
-FROM node-base as product-server
-ARG BUILD_TYPE=production
+FROM node-base AS product-server
+ARG BUILD_TYPE=development
+
+ENV NODE_ENV=development
WORKDIR /home
+RUN npm install -g vite
COPY ./ ./
COPY ./env/.env.$BUILD_TYPE ./
diff --git a/rsconcept/frontend/env/.env.development b/rsconcept/frontend/env/.env.development
index b662d21b..9e83a3a4 100644
--- a/rsconcept/frontend/env/.env.development
+++ b/rsconcept/frontend/env/.env.development
@@ -2,4 +2,3 @@
VITE_PORTAL_BACKEND=http://localhost:8002
VITE_PORTAL_FRONT_PORT=3002
-VITE_PORTAL_FRONT_HTTPS=false
diff --git a/rsconcept/frontend/env/.env.production b/rsconcept/frontend/env/.env.production
index 7d450ce8..2f98a22f 100644
--- a/rsconcept/frontend/env/.env.production
+++ b/rsconcept/frontend/env/.env.production
@@ -2,4 +2,3 @@
VITE_PORTAL_BACKEND=https://api.portal.acconcept.ru
VITE_PORTAL_FRONT_PORT=443
-VITE_PORTAL_FRONT_HTTPS=true
diff --git a/rsconcept/frontend/env/.env.production.local b/rsconcept/frontend/env/.env.production.local
index afc1a660..c373d02c 100644
--- a/rsconcept/frontend/env/.env.production.local
+++ b/rsconcept/frontend/env/.env.production.local
@@ -2,5 +2,4 @@
VITE_PORTAL_BACKEND=https://localhost:8001
VITE_PORTAL_FRONT_PORT=3001
-VITE_PORTAL_FRONT_HTTPS=true
diff --git a/rsconcept/frontend/package-lock.json b/rsconcept/frontend/package-lock.json
index 0aefa717..d3fff291 100644
--- a/rsconcept/frontend/package-lock.json
+++ b/rsconcept/frontend/package-lock.json
@@ -9,50 +9,50 @@
"version": "1.0.0",
"dependencies": {
"@lezer/lr": "^1.4.1",
- "@reactflow/core": "^11.11.4",
- "@tanstack/react-table": "^8.17.3",
- "@uiw/codemirror-themes": "^4.22.2",
- "@uiw/react-codemirror": "^4.22.2",
+ "@tanstack/react-table": "^8.19.3",
+ "@uiw/codemirror-themes": "^4.23.0",
+ "@uiw/react-codemirror": "^4.23.0",
"axios": "^1.7.2",
"clsx": "^2.1.1",
- "framer-motion": "^10.18.0",
+ "framer-motion": "^11.3.8",
"js-file-download": "^0.4.12",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
- "react-icons": "^4.12.0",
+ "react-icons": "^5.2.1",
"react-intl": "^6.6.8",
- "react-loader-spinner": "^5.4.5",
- "react-pdf": "^9.0.0",
- "react-router-dom": "^6.23.1",
+ "react-loader-spinner": "^6.1.6",
+ "react-pdf": "^9.1.0",
+ "react-router-dom": "^6.25.1",
"react-select": "^5.8.0",
"react-tabs": "^6.0.2",
- "react-toastify": "^9.1.3",
- "react-tooltip": "^5.27.0",
- "reagraph": "^4.19.1",
+ "react-toastify": "^10.0.5",
+ "react-tooltip": "^5.27.1",
+ "reactflow": "^11.11.4",
+ "reagraph": "^4.19.2",
"use-debounce": "^10.0.1"
},
"devDependencies": {
"@lezer/generator": "^1.7.1",
"@types/jest": "^29.5.12",
- "@types/node": "^20.14.7",
+ "@types/node": "^20.14.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
- "@typescript-eslint/eslint-plugin": "^6.21.0",
- "@typescript-eslint/parser": "^6.21.0",
+ "@typescript-eslint/eslint-plugin": "^7.16.1",
+ "@typescript-eslint/parser": "^7.16.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
- "eslint-plugin-react-refresh": "^0.4.7",
- "eslint-plugin-simple-import-sort": "^10.0.0",
- "eslint-plugin-tsdoc": "^0.2.17",
+ "eslint-plugin-react-refresh": "^0.4.8",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
+ "eslint-plugin-tsdoc": "^0.3.0",
"jest": "^29.7.0",
- "postcss": "^8.4.38",
- "tailwindcss": "^3.4.4",
- "ts-jest": "^29.1.5",
- "typescript": "^5.5.2",
- "vite": "^4.5.3"
+ "postcss": "^8.4.39",
+ "tailwindcss": "^3.4.6",
+ "ts-jest": "^29.2.3",
+ "typescript": "^5.5.3",
+ "vite": "^5.3.4"
}
},
"node_modules/@alloc/quick-lru": {
@@ -72,6 +72,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -95,30 +96,32 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz",
- "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==",
+ "version": "7.24.9",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz",
+ "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz",
- "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==",
+ "version": "7.24.9",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz",
+ "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.7",
- "@babel/helper-compilation-targets": "^7.24.7",
- "@babel/helper-module-transforms": "^7.24.7",
- "@babel/helpers": "^7.24.7",
- "@babel/parser": "^7.24.7",
+ "@babel/generator": "^7.24.9",
+ "@babel/helper-compilation-targets": "^7.24.8",
+ "@babel/helper-module-transforms": "^7.24.9",
+ "@babel/helpers": "^7.24.8",
+ "@babel/parser": "^7.24.8",
"@babel/template": "^7.24.7",
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7",
+ "@babel/traverse": "^7.24.8",
+ "@babel/types": "^7.24.9",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -137,18 +140,19 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz",
- "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==",
+ "version": "7.24.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz",
+ "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.24.7",
+ "@babel/types": "^7.24.9",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@@ -157,27 +161,16 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
- "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz",
- "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz",
+ "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.24.7",
- "@babel/helper-validator-option": "^7.24.7",
- "browserslist": "^4.22.2",
+ "@babel/compat-data": "^7.24.8",
+ "@babel/helper-validator-option": "^7.24.8",
+ "browserslist": "^4.23.1",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -189,6 +182,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -245,9 +239,10 @@
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz",
- "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==",
+ "version": "7.24.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz",
+ "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-environment-visitor": "^7.24.7",
@@ -264,9 +259,10 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz",
- "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
+ "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -276,6 +272,7 @@
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
"integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.24.7",
@@ -298,9 +295,9 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
- "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
+ "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -316,22 +313,24 @@
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz",
- "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
+ "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz",
- "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz",
+ "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.24.8"
},
"engines": {
"node": ">=6.9.0"
@@ -353,9 +352,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
- "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz",
+ "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==",
"license": "MIT",
"bin": {
"parser": "bin/babel-parser.js"
@@ -433,6 +432,7 @@
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
"integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.7"
@@ -587,9 +587,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
- "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
+ "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -613,19 +613,19 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz",
- "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz",
+ "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.7",
+ "@babel/generator": "^7.24.8",
"@babel/helper-environment-visitor": "^7.24.7",
"@babel/helper-function-name": "^7.24.7",
"@babel/helper-hoist-variables": "^7.24.7",
"@babel/helper-split-export-declaration": "^7.24.7",
- "@babel/parser": "^7.24.7",
- "@babel/types": "^7.24.7",
+ "@babel/parser": "^7.24.8",
+ "@babel/types": "^7.24.8",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -634,12 +634,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
- "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
+ "version": "7.24.9",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz",
+ "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.7",
+ "@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
},
@@ -655,9 +655,9 @@
"license": "MIT"
},
"node_modules/@codemirror/autocomplete": {
- "version": "6.16.3",
- "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.16.3.tgz",
- "integrity": "sha512-Vl/tIeRVVUCRDuOG48lttBasNQu8usGgXQawBXI7WJAiUDSFOfzflmEsZFZo48mAvAaa4FZ/4/yLLxFtdJaKYA==",
+ "version": "6.17.0",
+ "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.17.0.tgz",
+ "integrity": "sha512-fdfj6e6ZxZf8yrkMHUSJJir7OJkHkZKaOZGzLWIYp2PZ3jd+d+UjG8zVPqJF6d3bKxkhvXTPan/UZ1t7Bqm0gA==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
@@ -739,9 +739,9 @@
}
},
"node_modules/@codemirror/view": {
- "version": "6.28.2",
- "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.2.tgz",
- "integrity": "sha512-A3DmyVfjgPsGIjiJqM/zvODUAPQdQl3ci0ghehYNnbt5x+o76xq+dL5+mMBuysDXnI3kapgOkoeJ0sbtL/3qPw==",
+ "version": "6.28.6",
+ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.6.tgz",
+ "integrity": "sha512-bhwB1AZ6zU4M3dNKm8Aa2BXwj5mWDqE9IWpqxYKJoLCnx+AcwcMuLO01tLWgc1mx4vT1IVYVqx86YoqUsATrqQ==",
"license": "MIT",
"dependencies": {
"@codemirror/state": "^6.4.0",
@@ -750,16 +750,16 @@
}
},
"node_modules/@emotion/babel-plugin": {
- "version": "11.11.0",
- "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
- "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
+ "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==",
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
- "@emotion/hash": "^0.9.1",
- "@emotion/memoize": "^0.8.1",
- "@emotion/serialize": "^1.1.2",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.2.0",
"babel-plugin-macros": "^3.1.0",
"convert-source-map": "^1.5.0",
"escape-string-regexp": "^4.0.0",
@@ -768,12 +768,6 @@
"stylis": "4.2.0"
}
},
- "node_modules/@emotion/babel-plugin/node_modules/@emotion/memoize": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
- "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
- "license": "MIT"
- },
"node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
@@ -802,60 +796,58 @@
}
},
"node_modules/@emotion/cache": {
- "version": "11.11.0",
- "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
- "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.12.0.tgz",
+ "integrity": "sha512-VFo/F1PthkxHwWDCcXkidyXw70eAkdiNiCzthMI2rRQjFiTvmXt8UDlv/VE1DTsd4CIEY2wQf5AnL2QiPgphlw==",
"license": "MIT",
"dependencies": {
- "@emotion/memoize": "^0.8.1",
- "@emotion/sheet": "^1.2.2",
- "@emotion/utils": "^1.2.1",
- "@emotion/weak-memoize": "^0.3.1",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/sheet": "^1.3.0",
+ "@emotion/utils": "^1.3.0",
+ "@emotion/weak-memoize": "^0.4.0",
"stylis": "4.2.0"
}
},
- "node_modules/@emotion/cache/node_modules/@emotion/memoize": {
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+ "license": "MIT"
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+ "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
+ "node_modules/@emotion/is-prop-valid/node_modules/@emotion/memoize": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
"license": "MIT"
},
- "node_modules/@emotion/hash": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
- "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==",
+ "node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
"license": "MIT"
},
- "node_modules/@emotion/is-prop-valid": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
- "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emotion/memoize": "0.7.4"
- }
- },
- "node_modules/@emotion/memoize": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
- "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
- "license": "MIT",
- "optional": true
- },
"node_modules/@emotion/react": {
- "version": "11.11.4",
- "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz",
- "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==",
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.12.0.tgz",
+ "integrity": "sha512-kTktYMpG8mHjLi8u6XOTMfDmQvUve/un2ZVj4khcU2KTn17ElMV8BK6QFzT8V/v2QW8013rf07Yc0ayQL3tp3w==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.3",
- "@emotion/babel-plugin": "^11.11.0",
- "@emotion/cache": "^11.11.0",
- "@emotion/serialize": "^1.1.3",
+ "@emotion/babel-plugin": "^11.12.0",
+ "@emotion/cache": "^11.12.0",
+ "@emotion/serialize": "^1.2.0",
"@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
- "@emotion/utils": "^1.2.1",
- "@emotion/weak-memoize": "^0.3.1",
+ "@emotion/utils": "^1.3.0",
+ "@emotion/weak-memoize": "^0.4.0",
"hoist-non-react-statics": "^3.3.1"
},
"peerDependencies": {
@@ -868,40 +860,28 @@
}
},
"node_modules/@emotion/serialize": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz",
- "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.2.0.tgz",
+ "integrity": "sha512-X5UWpZAhGGp5LOn7OAI9k9JjRtz7nSFhZypatADcuEd/0bECZ0DzVjPdL8hljTrAku8+TjFvWIYHMOCO/0v/Ng==",
"license": "MIT",
"dependencies": {
- "@emotion/hash": "^0.9.1",
- "@emotion/memoize": "^0.8.1",
- "@emotion/unitless": "^0.8.1",
- "@emotion/utils": "^1.2.1",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/unitless": "^0.9.0",
+ "@emotion/utils": "^1.3.0",
"csstype": "^3.0.2"
}
},
- "node_modules/@emotion/serialize/node_modules/@emotion/memoize": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
- "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
- "license": "MIT"
- },
"node_modules/@emotion/sheet": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
- "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==",
- "license": "MIT"
- },
- "node_modules/@emotion/stylis": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
- "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.3.0.tgz",
+ "integrity": "sha512-vOPwbKw8fj/oSEa7CWqiKCvLZ1AeLIAApmboGP34xUyUjXalFyf+tMtgMDqP7VMevLPhUa+YWJS46cQUA+tr9A==",
"license": "MIT"
},
"node_modules/@emotion/unitless": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
- "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.9.0.tgz",
+ "integrity": "sha512-TP6GgNZtmtFaFcsOgExdnfxLLpRDla4Q66tnenA9CktvVSdNKDvMVuUah4QvWPIpNjrWsGg3qeGo9a43QooGZQ==",
"license": "MIT"
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
@@ -914,21 +894,38 @@
}
},
"node_modules/@emotion/utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
- "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.3.0.tgz",
+ "integrity": "sha512-+M7u4EaX5t4bCunKTltAdGis3NFHQniikLVEQ+rPQccsX/xV4v5Etwg12paioZ9DsO+CTvimtmnjZbW85kbF8Q==",
"license": "MIT"
},
"node_modules/@emotion/weak-memoize": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
- "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
+ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@esbuild/android-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
- "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
"cpu": [
"arm"
],
@@ -943,9 +940,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
- "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
"cpu": [
"arm64"
],
@@ -960,9 +957,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
- "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
"cpu": [
"x64"
],
@@ -977,9 +974,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
- "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
"cpu": [
"arm64"
],
@@ -994,9 +991,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
- "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
"cpu": [
"x64"
],
@@ -1011,9 +1008,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
- "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
"cpu": [
"arm64"
],
@@ -1028,9 +1025,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
- "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
"cpu": [
"x64"
],
@@ -1045,9 +1042,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
- "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
"cpu": [
"arm"
],
@@ -1062,9 +1059,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
- "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
"cpu": [
"arm64"
],
@@ -1079,9 +1076,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
- "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
"cpu": [
"ia32"
],
@@ -1096,9 +1093,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
- "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
"cpu": [
"loong64"
],
@@ -1113,9 +1110,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
- "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
"cpu": [
"mips64el"
],
@@ -1130,9 +1127,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
- "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
"cpu": [
"ppc64"
],
@@ -1147,9 +1144,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
- "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
"cpu": [
"riscv64"
],
@@ -1164,9 +1161,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
- "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
"cpu": [
"s390x"
],
@@ -1181,9 +1178,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
- "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
"cpu": [
"x64"
],
@@ -1198,9 +1195,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
- "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
"cpu": [
"x64"
],
@@ -1215,9 +1212,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
- "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
"cpu": [
"x64"
],
@@ -1232,9 +1229,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
- "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
"cpu": [
"x64"
],
@@ -1249,9 +1246,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
- "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
"cpu": [
"arm64"
],
@@ -1266,9 +1263,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
- "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
"cpu": [
"ia32"
],
@@ -1283,9 +1280,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
- "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
"cpu": [
"x64"
],
@@ -1316,9 +1313,9 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.10.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz",
- "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==",
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
+ "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1413,28 +1410,28 @@
}
},
"node_modules/@floating-ui/core": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz",
- "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==",
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz",
+ "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==",
"license": "MIT",
"dependencies": {
- "@floating-ui/utils": "^0.2.0"
+ "@floating-ui/utils": "^0.2.4"
}
},
"node_modules/@floating-ui/dom": {
- "version": "1.6.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz",
- "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz",
+ "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==",
"license": "MIT",
"dependencies": {
- "@floating-ui/core": "^1.0.0",
- "@floating-ui/utils": "^0.2.0"
+ "@floating-ui/core": "^1.6.0",
+ "@floating-ui/utils": "^0.2.4"
}
},
"node_modules/@floating-ui/utils": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
- "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz",
+ "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==",
"license": "MIT"
},
"node_modules/@formatjs/ecma402-abstract": {
@@ -2518,9 +2515,9 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
@@ -2625,25 +2622,49 @@
"license": "Apache-2.0"
},
"node_modules/@microsoft/tsdoc": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
- "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==",
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz",
+ "integrity": "sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==",
"dev": true,
"license": "MIT"
},
"node_modules/@microsoft/tsdoc-config": {
- "version": "0.16.2",
- "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz",
- "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==",
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz",
+ "integrity": "sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@microsoft/tsdoc": "0.14.2",
- "ajv": "~6.12.6",
+ "@microsoft/tsdoc": "0.15.0",
+ "ajv": "~8.12.0",
"jju": "~1.4.0",
- "resolve": "~1.19.0"
+ "resolve": "~1.22.2"
}
},
+ "node_modules/@microsoft/tsdoc-config/node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2835,6 +2856,36 @@
}
}
},
+ "node_modules/@reactflow/background": {
+ "version": "11.3.14",
+ "resolved": "https://registry.npmjs.org/@reactflow/background/-/background-11.3.14.tgz",
+ "integrity": "sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/core": "11.11.4",
+ "classcat": "^5.0.3",
+ "zustand": "^4.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
+ "node_modules/@reactflow/controls": {
+ "version": "11.2.14",
+ "resolved": "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.14.tgz",
+ "integrity": "sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/core": "11.11.4",
+ "classcat": "^5.0.3",
+ "zustand": "^4.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
"node_modules/@reactflow/core": {
"version": "11.11.4",
"resolved": "https://registry.npmjs.org/@reactflow/core/-/core-11.11.4.tgz",
@@ -2856,15 +2907,290 @@
"react-dom": ">=17"
}
},
+ "node_modules/@reactflow/minimap": {
+ "version": "11.7.14",
+ "resolved": "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.14.tgz",
+ "integrity": "sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/core": "11.11.4",
+ "@types/d3-selection": "^3.0.3",
+ "@types/d3-zoom": "^3.0.1",
+ "classcat": "^5.0.3",
+ "d3-selection": "^3.0.0",
+ "d3-zoom": "^3.0.0",
+ "zustand": "^4.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
+ "node_modules/@reactflow/node-resizer": {
+ "version": "2.2.14",
+ "resolved": "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz",
+ "integrity": "sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/core": "11.11.4",
+ "classcat": "^5.0.4",
+ "d3-drag": "^3.0.0",
+ "d3-selection": "^3.0.0",
+ "zustand": "^4.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
+ "node_modules/@reactflow/node-toolbar": {
+ "version": "1.3.14",
+ "resolved": "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz",
+ "integrity": "sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/core": "11.11.4",
+ "classcat": "^5.0.3",
+ "zustand": "^4.4.1"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
"node_modules/@remix-run/router": {
- "version": "1.16.1",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.1.tgz",
- "integrity": "sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==",
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz",
+ "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz",
+ "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz",
+ "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz",
+ "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz",
+ "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz",
+ "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz",
+ "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz",
+ "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz",
+ "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz",
+ "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz",
+ "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz",
+ "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz",
+ "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz",
+ "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz",
+ "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz",
+ "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz",
+ "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
@@ -2893,12 +3219,12 @@
}
},
"node_modules/@tanstack/react-table": {
- "version": "8.17.3",
- "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.17.3.tgz",
- "integrity": "sha512-5gwg5SvPD3lNAXPuJJz1fOCEZYk9/GeBFH3w/hCgnfyszOIzwkwgp5I7Q4MJtn0WECp84b5STQUDdmvGi8m3nA==",
+ "version": "8.19.3",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.19.3.tgz",
+ "integrity": "sha512-MtgPZc4y+cCRtU16y1vh1myuyZ2OdkWgMEBzyjYsoMWMicKZGZvcDnub3Zwb6XF2pj9iRMvm1SO1n57lS0vXLw==",
"license": "MIT",
"dependencies": {
- "@tanstack/table-core": "8.17.3"
+ "@tanstack/table-core": "8.19.3"
},
"engines": {
"node": ">=12"
@@ -2913,9 +3239,9 @@
}
},
"node_modules/@tanstack/table-core": {
- "version": "8.17.3",
- "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.17.3.tgz",
- "integrity": "sha512-mPBodDGVL+fl6d90wUREepHa/7lhsghg2A3vFpakEhrhtbIlgNAZiMr7ccTgak5qbHqF14Fwy+W1yFWQt+WmYQ==",
+ "version": "8.19.3",
+ "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.19.3.tgz",
+ "integrity": "sha512-IqREj9ADoml9zCAouIG/5kCGoyIxPFdqdyoxis9FisXFi5vT+iYfEfLosq4xkU/iDbMcEuAj+X8dWRLvKYDNoQ==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -3235,6 +3561,13 @@
"integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==",
"license": "MIT"
},
+ "node_modules/@types/estree": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/geojson": {
"version": "7946.0.14",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
@@ -3299,17 +3632,10 @@
"pretty-format": "^29.0.0"
}
},
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/node": {
- "version": "20.14.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz",
- "integrity": "sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==",
+ "version": "20.14.11",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
+ "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3372,13 +3698,6 @@
"@types/react": "*"
}
},
- "node_modules/@types/semver": {
- "version": "7.5.8",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
- "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -3392,14 +3711,20 @@
"integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==",
"license": "MIT"
},
+ "node_modules/@types/stylis": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
+ "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
+ "license": "MIT"
+ },
"node_modules/@types/three": {
- "version": "0.165.0",
- "resolved": "https://registry.npmjs.org/@types/three/-/three-0.165.0.tgz",
- "integrity": "sha512-AJK8JZAFNBF0kBXiAIl5pggYlzAGGA8geVYQXAcPCEDRbyA+oEjkpUBcJJrtNz6IiALwzGexFJGZG2yV3WsYBw==",
+ "version": "0.166.0",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.166.0.tgz",
+ "integrity": "sha512-FHMnpcdhdbdOOIYbfkTkUVpYMW53odxbTRwd0/xJpYnTzEsjnVnondGAvHZb4z06UW0vo6WPVuvH0/9qrxKx7g==",
"license": "MIT",
"peer": true,
"dependencies": {
- "@tweenjs/tween.js": "~23.1.1",
+ "@tweenjs/tween.js": "~23.1.2",
"@types/stats.js": "*",
"@types/webxr": "*",
"fflate": "~0.8.2",
@@ -3407,9 +3732,9 @@
}
},
"node_modules/@types/webxr": {
- "version": "0.5.17",
- "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.17.tgz",
- "integrity": "sha512-JYcclaQIlisHRXM9dMF7SeVvQ54kcYc7QK1eKCExCTLKWnZDxP4cp/rXH4Uoa1j5+5oQJ0Cc2sZC/PWiiG4q2g==",
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.19.tgz",
+ "integrity": "sha512-4hxA+NwohSgImdTSlPXEqDqqFktNgmTXQ05ff1uWam05tNGroCMp4G+4XVl6qWm1p7GQ/9oD41kAYsSssF6Mzw==",
"license": "MIT"
},
"node_modules/@types/yargs": {
@@ -3430,34 +3755,32 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
- "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz",
+ "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/type-utils": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
- "debug": "^4.3.4",
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.16.1",
+ "@typescript-eslint/type-utils": "7.16.1",
+ "@typescript-eslint/utils": "7.16.1",
+ "@typescript-eslint/visitor-keys": "7.16.1",
"graphemer": "^1.4.0",
- "ignore": "^5.2.4",
+ "ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
- "eslint": "^7.0.0 || ^8.0.0"
+ "@typescript-eslint/parser": "^7.0.0",
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3466,27 +3789,27 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
- "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz",
+ "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/scope-manager": "7.16.1",
+ "@typescript-eslint/types": "7.16.1",
+ "@typescript-eslint/typescript-estree": "7.16.1",
+ "@typescript-eslint/visitor-keys": "7.16.1",
"debug": "^4.3.4"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3495,17 +3818,17 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
- "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz",
+ "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0"
+ "@typescript-eslint/types": "7.16.1",
+ "@typescript-eslint/visitor-keys": "7.16.1"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3513,26 +3836,26 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
- "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz",
+ "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "6.21.0",
- "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/typescript-estree": "7.16.1",
+ "@typescript-eslint/utils": "7.16.1",
"debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -3541,13 +3864,13 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
- "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz",
+ "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3555,23 +3878,23 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
- "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz",
+ "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/visitor-keys": "6.21.0",
+ "@typescript-eslint/types": "7.16.1",
+ "@typescript-eslint/visitor-keys": "7.16.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3584,43 +3907,40 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
- "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz",
+ "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "6.21.0",
- "@typescript-eslint/types": "6.21.0",
- "@typescript-eslint/typescript-estree": "6.21.0",
- "semver": "^7.5.4"
+ "@typescript-eslint/scope-manager": "7.16.1",
+ "@typescript-eslint/types": "7.16.1",
+ "@typescript-eslint/typescript-estree": "7.16.1"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^7.0.0 || ^8.0.0"
+ "eslint": "^8.56.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
- "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "version": "7.16.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz",
+ "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "6.21.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.16.1",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -3628,9 +3948,9 @@
}
},
"node_modules/@uiw/codemirror-extensions-basic-setup": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.22.2.tgz",
- "integrity": "sha512-zcHGkldLFN3cGoI5XdOGAkeW24yaAgrDEYoyPyWHODmPiNwybQQoZGnH3qUdzZwUaXtAcLWoAeOPzfNRW2yGww==",
+ "version": "4.23.0",
+ "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.23.0.tgz",
+ "integrity": "sha512-+k5nkRpUWGaHr1JWT8jcKsVewlXw5qBgSopm9LW8fZ6KnSNZBycz8kHxh0+WSvckmXEESGptkIsb7dlkmJT/hQ==",
"license": "MIT",
"dependencies": {
"@codemirror/autocomplete": "^6.0.0",
@@ -3655,9 +3975,9 @@
}
},
"node_modules/@uiw/codemirror-themes": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.22.2.tgz",
- "integrity": "sha512-gsLHn6SUuV5iboBvGrM7YimzLFHQmsNlkGIYs3UaVUJTo/A/ZrKoSJNyPziShLRjBXA2UwKdBTIU6VhHyyaChw==",
+ "version": "4.23.0",
+ "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.23.0.tgz",
+ "integrity": "sha512-9fiji9xooZyBQozR1i6iTr56YP7j/Dr/VgsNWbqf5Szv+g+4WM1iZuiDGwNXmFMWX8gbkDzp6ASE21VCPSofWw==",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.0.0",
@@ -3674,16 +3994,16 @@
}
},
"node_modules/@uiw/react-codemirror": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.22.2.tgz",
- "integrity": "sha512-okCSl+WJG63gRx8Fdz7v0C6RakBQnbb3pHhuzIgDB+fwhipgFodSnu2n9oOsQesJ5YQ7mSOcKMgX0JEsu4nnfQ==",
+ "version": "4.23.0",
+ "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.23.0.tgz",
+ "integrity": "sha512-MnqTXfgeLA3fsUUQjqjJgemEuNyoGALgsExVm0NQAllAAi1wfj+IoKFeK+h3XXMlTFRCFYOUh4AHDv0YXJLsOg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.6",
"@codemirror/commands": "^6.1.0",
"@codemirror/state": "^6.1.1",
"@codemirror/theme-one-dark": "^6.0.0",
- "@uiw/codemirror-extensions-basic-setup": "4.22.2",
+ "@uiw/codemirror-extensions-basic-setup": "4.23.0",
"codemirror": "^6.0.0"
},
"funding": {
@@ -3758,9 +4078,9 @@
"optional": true
},
"node_modules/acorn": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
- "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"license": "MIT",
"bin": {
@@ -3915,6 +4235,13 @@
"node": ">=8"
}
},
+ "node_modules/async": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
+ "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -4143,22 +4470,6 @@
"npm": ">=6"
}
},
- "node_modules/babel-plugin-styled-components": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz",
- "integrity": "sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-module-imports": "^7.22.5",
- "@babel/plugin-syntax-jsx": "^7.22.5",
- "lodash": "^4.17.21",
- "picomatch": "^2.3.1"
- },
- "peerDependencies": {
- "styled-components": ">= 2"
- }
- },
"node_modules/babel-preset-current-node-syntax": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
@@ -4253,9 +4564,10 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
- "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+ "version": "4.23.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
+ "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4272,10 +4584,10 @@
],
"license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001629",
- "electron-to-chromium": "^1.4.796",
+ "caniuse-lite": "^1.0.30001640",
+ "electron-to-chromium": "^1.4.820",
"node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.16"
+ "update-browserslist-db": "^1.1.0"
},
"bin": {
"browserslist": "cli.js"
@@ -4362,9 +4674,10 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001636",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz",
- "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==",
+ "version": "1.0.30001642",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz",
+ "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -4626,6 +4939,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/cosmiconfig": {
@@ -4820,9 +5134,9 @@
"license": "MIT"
},
"node_modules/ctrl-keys": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/ctrl-keys/-/ctrl-keys-1.0.2.tgz",
- "integrity": "sha512-MBVjzR+RlUqbgmDRbnrGsXdFo0xB5/OxO4o54tyhBvPtbZ/f5hPl/De4i5yEGPyKPKyyEbLCxR5qmY+NEbXnCA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/ctrl-keys/-/ctrl-keys-1.0.3.tgz",
+ "integrity": "sha512-Kcb05/xUNra57fxpsLOflECWYbjQEQ9ZuQEthB3cgESN5zMLJ364twA9h2kqz8n06RnTY/+rKWM3UbkOWKeEJg==",
"license": "MIT",
"engines": {
"node": ">=10"
@@ -5134,9 +5448,9 @@
}
},
"node_modules/detect-gpu": {
- "version": "5.0.38",
- "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.38.tgz",
- "integrity": "sha512-36QeGHSXYcJ/RfrnPEScR8GDprbXFG4ZhXsfVNVHztZr38+fRxgHnJl3CjYXXjbeRUhu3ZZBJh6Lg0A9v0Qd8A==",
+ "version": "5.0.39",
+ "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.39.tgz",
+ "integrity": "sha512-qs+7gnNNxsH4RN1IPpQieU2XNO+RhgemuaRhcawiUug6oXb0Glup90H1YGSjslPO30Sw0E4yfjRoGtSEURwVPQ==",
"license": "MIT",
"dependencies": {
"webgl-constants": "^1.1.1"
@@ -5235,10 +5549,27 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/electron-to-chromium": {
- "version": "1.4.808",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.808.tgz",
- "integrity": "sha512-0ItWyhPYnww2VOuCGF4s1LTfbrdAV2ajy/TN+ZTuhR23AHI6rWHCrBXJ/uxoXOvRRqw8qjYVrG81HFI7x/2wdQ==",
+ "version": "1.4.830",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.830.tgz",
+ "integrity": "sha512-TrPKKH20HeN0J1LHzsYLs2qwXrp8TF4nHdu4sq61ozGbzMpWhI7iIOPYPPkxeq1azMT9PZ8enPFcftbs/Npcjg==",
+ "dev": true,
"license": "ISC"
},
"node_modules/ellipsize": {
@@ -5277,9 +5608,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.18.20",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
- "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+ "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -5290,34 +5621,36 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/android-arm": "0.18.20",
- "@esbuild/android-arm64": "0.18.20",
- "@esbuild/android-x64": "0.18.20",
- "@esbuild/darwin-arm64": "0.18.20",
- "@esbuild/darwin-x64": "0.18.20",
- "@esbuild/freebsd-arm64": "0.18.20",
- "@esbuild/freebsd-x64": "0.18.20",
- "@esbuild/linux-arm": "0.18.20",
- "@esbuild/linux-arm64": "0.18.20",
- "@esbuild/linux-ia32": "0.18.20",
- "@esbuild/linux-loong64": "0.18.20",
- "@esbuild/linux-mips64el": "0.18.20",
- "@esbuild/linux-ppc64": "0.18.20",
- "@esbuild/linux-riscv64": "0.18.20",
- "@esbuild/linux-s390x": "0.18.20",
- "@esbuild/linux-x64": "0.18.20",
- "@esbuild/netbsd-x64": "0.18.20",
- "@esbuild/openbsd-x64": "0.18.20",
- "@esbuild/sunos-x64": "0.18.20",
- "@esbuild/win32-arm64": "0.18.20",
- "@esbuild/win32-ia32": "0.18.20",
- "@esbuild/win32-x64": "0.18.20"
+ "@esbuild/aix-ppc64": "0.21.5",
+ "@esbuild/android-arm": "0.21.5",
+ "@esbuild/android-arm64": "0.21.5",
+ "@esbuild/android-x64": "0.21.5",
+ "@esbuild/darwin-arm64": "0.21.5",
+ "@esbuild/darwin-x64": "0.21.5",
+ "@esbuild/freebsd-arm64": "0.21.5",
+ "@esbuild/freebsd-x64": "0.21.5",
+ "@esbuild/linux-arm": "0.21.5",
+ "@esbuild/linux-arm64": "0.21.5",
+ "@esbuild/linux-ia32": "0.21.5",
+ "@esbuild/linux-loong64": "0.21.5",
+ "@esbuild/linux-mips64el": "0.21.5",
+ "@esbuild/linux-ppc64": "0.21.5",
+ "@esbuild/linux-riscv64": "0.21.5",
+ "@esbuild/linux-s390x": "0.21.5",
+ "@esbuild/linux-x64": "0.21.5",
+ "@esbuild/netbsd-x64": "0.21.5",
+ "@esbuild/openbsd-x64": "0.21.5",
+ "@esbuild/sunos-x64": "0.21.5",
+ "@esbuild/win32-arm64": "0.21.5",
+ "@esbuild/win32-ia32": "0.21.5",
+ "@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5402,9 +5735,9 @@
}
},
"node_modules/eslint-plugin-react-refresh": {
- "version": "0.4.7",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.7.tgz",
- "integrity": "sha512-yrj+KInFmwuQS2UQcg1SF83ha1tuHC1jMQbRNyuWtlEzzKRDgAl7L4Yp4NlDUZTZNlWvHEzOtJhMi40R7JxcSw==",
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.8.tgz",
+ "integrity": "sha512-MIKAclwaDFIiYtVBLzDdm16E+Ty4GwhB6wZlCAG1R3Ur+F9Qbo6PRxpA5DK7XtDgm+WlCoAY2WxAwqhmIDHg6Q==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -5412,9 +5745,9 @@
}
},
"node_modules/eslint-plugin-simple-import-sort": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz",
- "integrity": "sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==",
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz",
+ "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -5422,14 +5755,14 @@
}
},
"node_modules/eslint-plugin-tsdoc": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz",
- "integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==",
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.3.0.tgz",
+ "integrity": "sha512-0MuFdBrrJVBjT/gyhkP2BqpD0np1NxNLfQ38xXDlSs/KVVpKI2A6vN7jx2Rve/CyUsvOsMGwp9KKrinv7q9g3A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@microsoft/tsdoc": "0.14.2",
- "@microsoft/tsdoc-config": "0.16.2"
+ "@microsoft/tsdoc": "0.15.0",
+ "@microsoft/tsdoc-config": "0.17.0"
}
},
"node_modules/eslint-scope": {
@@ -5637,9 +5970,9 @@
}
},
"node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -5831,6 +6164,29 @@
"node": "^10.12.0 || >=12.0.0"
}
},
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -5968,21 +6324,22 @@
}
},
"node_modules/framer-motion": {
- "version": "10.18.0",
- "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-10.18.0.tgz",
- "integrity": "sha512-oGlDh1Q1XqYPksuTD/usb0I70hq95OUzmL9+6Zd+Hs4XV0oaISBa/UUMSjYiq6m8EUF32132mOJ8xVZS+I0S6w==",
+ "version": "11.3.8",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.8.tgz",
+ "integrity": "sha512-1D+RDTsIp4Rz2dq/oToqSEc9idEQwgBRQyBq4rGpFba+0Z+GCbj9z1s0+ikFbanWe3YJ0SqkNlDe08GcpFGj5A==",
"license": "MIT",
"dependencies": {
"tslib": "^2.4.0"
},
- "optionalDependencies": {
- "@emotion/is-prop-valid": "^0.8.2"
- },
"peerDependencies": {
+ "@emotion/is-prop-valid": "*",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
"react": {
"optional": true
},
@@ -6081,6 +6438,7 @@
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -6590,9 +6948,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
- "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz",
+ "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==",
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
@@ -6697,9 +7055,9 @@
}
},
"node_modules/istanbul-lib-instrument": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz",
- "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==",
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6802,17 +7160,14 @@
}
},
"node_modules/jackspeak": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
- "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
- "engines": {
- "node": ">=14"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
@@ -6820,6 +7175,125 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jake/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jake/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/jake/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/jake/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jake/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jake/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jake/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/jake/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
@@ -7798,24 +8272,6 @@
"node": ">=8"
}
},
- "node_modules/jest-resolve/node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/jest-resolve/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -8580,6 +9036,7 @@
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -8664,12 +9121,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
- "license": "MIT"
- },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -8700,19 +9151,20 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
}
},
"node_modules/maath": {
- "version": "0.10.7",
- "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.7.tgz",
- "integrity": "sha512-zQ2xd7dNOIVTjAS+hj22fyj1EFYmOJX6tzKjZ92r6WDoq8hyFxjuGA2q950tmR4iC/EKXoMQdSipkaJVuUHDTg==",
+ "version": "0.10.8",
+ "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz",
+ "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==",
"license": "MIT",
"peerDependencies": {
- "@types/three": ">=0.144.0",
- "three": ">=0.144.0"
+ "@types/three": ">=0.134.0",
+ "three": ">=0.134.0"
}
},
"node_modules/make-cancellable-promise": {
@@ -8880,9 +9332,9 @@
}
},
"node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -8990,7 +9442,6 @@
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -9041,9 +9492,10 @@
"license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.17.tgz",
+ "integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==",
+ "dev": true,
"license": "MIT"
},
"node_modules/nopt": {
@@ -9319,14 +9771,11 @@
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
- "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
- "license": "ISC",
- "engines": {
- "node": "14 || >=16.14"
- }
+ "license": "ISC"
},
"node_modules/path-type": {
"version": "4.0.0",
@@ -9338,9 +9787,9 @@
}
},
"node_modules/path2d": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.0.tgz",
- "integrity": "sha512-KdPAykQX6kmLSOO6Jpu2KNcCED7CKjmaBNGGNuctOsG0hgYO1OdYQaan6cYXJiG0WmXOwZZPILPBimu5QAIw3A==",
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.1.tgz",
+ "integrity": "sha512-Fl2z/BHvkTNvkuBzYTpTuirHZg6wW9z8+4SND/3mDTEcYbbNKWAy21dz9D3ePNNwrrK8pqZO5vLPZ1hLF6T7XA==",
"license": "MIT",
"optional": true,
"engines": {
@@ -9348,9 +9797,9 @@
}
},
"node_modules/pdfjs-dist": {
- "version": "4.3.136",
- "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.3.136.tgz",
- "integrity": "sha512-gzfnt1qc4yA+U46golPGYtU4WM2ssqP2MvFjKga8GEKOrEnzRPrA/9jogLLPYHiA3sGBPJ+p7BdAq+ytmw3jEg==",
+ "version": "4.4.168",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.4.168.tgz",
+ "integrity": "sha512-MbkAjpwka/dMHaCfQ75RY1FXX3IewBVu6NGZOcxerRFlaBiIkZmUoR0jotX5VUzYZEXAGzSFtknWs5xRKliXPA==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
@@ -9370,6 +9819,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -9468,9 +9918,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "version": "8.4.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
+ "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
"dev": true,
"funding": [
{
@@ -9489,7 +9939,7 @@
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
+ "picocolors": "^1.0.1",
"source-map-js": "^1.2.0"
},
"engines": {
@@ -9617,9 +10067,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
- "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
+ "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9815,9 +10265,9 @@
}
},
"node_modules/react-icons": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
- "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz",
+ "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==",
"license": "MIT",
"peerDependencies": {
"react": "*"
@@ -9857,14 +10307,16 @@
"license": "MIT"
},
"node_modules/react-loader-spinner": {
- "version": "5.4.5",
- "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-5.4.5.tgz",
- "integrity": "sha512-32f+sb/v2tnNfyvnCCOS4fpyVHsGXjSyNo6QLniHcaj1XjKLxx14L2z0h6szRugOL8IEJ+53GPwNAdbkDqmy4g==",
+ "version": "6.1.6",
+ "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-6.1.6.tgz",
+ "integrity": "sha512-x5h1Jcit7Qn03MuKlrWcMG9o12cp9SNDVHVJTNRi9TgtGPKcjKiXkou4NRfLAtXaFB3+Z8yZsVzONmPzhv2ErA==",
"license": "MIT",
"dependencies": {
"react-is": "^18.2.0",
- "styled-components": "^5.3.5",
- "styled-tools": "^1.7.2"
+ "styled-components": "^6.1.2"
+ },
+ "engines": {
+ "node": ">= 12"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0 || ^18.0.0",
@@ -9882,9 +10334,9 @@
}
},
"node_modules/react-pdf": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-9.0.0.tgz",
- "integrity": "sha512-J+pza8R2p9oNEOJOHIQJI4o5rFK7ji7bBl2IvsHvz1OOyphvuzVDo5tOJwWAFAbxYauCH3Kt8jOvcMJUOpxYZQ==",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-9.1.0.tgz",
+ "integrity": "sha512-KhPDQE3QshkLdS3b48S5Bldv0N5flob6qwvsiADWdZOS5TMDaIrkRtEs+Dyl6ubRf2jTf9jWmFb6RjWu46lSSg==",
"license": "MIT",
"dependencies": {
"clsx": "^2.0.0",
@@ -9892,7 +10344,7 @@
"make-cancellable-promise": "^1.3.1",
"make-event-props": "^1.6.0",
"merge-refs": "^1.3.0",
- "pdfjs-dist": "4.3.136",
+ "pdfjs-dist": "4.4.168",
"tiny-invariant": "^1.0.0",
"warning": "^4.0.0"
},
@@ -9946,12 +10398,12 @@
}
},
"node_modules/react-router": {
- "version": "6.23.1",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.1.tgz",
- "integrity": "sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==",
+ "version": "6.25.1",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz",
+ "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==",
"license": "MIT",
"dependencies": {
- "@remix-run/router": "1.16.1"
+ "@remix-run/router": "1.18.0"
},
"engines": {
"node": ">=14.0.0"
@@ -9961,13 +10413,13 @@
}
},
"node_modules/react-router-dom": {
- "version": "6.23.1",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz",
- "integrity": "sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==",
+ "version": "6.25.1",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz",
+ "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==",
"license": "MIT",
"dependencies": {
- "@remix-run/router": "1.16.1",
- "react-router": "6.23.1"
+ "@remix-run/router": "1.18.0",
+ "react-router": "6.25.1"
},
"engines": {
"node": ">=14.0.0"
@@ -10012,31 +10464,22 @@
}
},
"node_modules/react-toastify": {
- "version": "9.1.3",
- "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
- "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==",
+ "version": "10.0.5",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
+ "integrity": "sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==",
"license": "MIT",
"dependencies": {
- "clsx": "^1.1.1"
+ "clsx": "^2.1.0"
},
"peerDependencies": {
- "react": ">=16",
- "react-dom": ">=16"
- }
- },
- "node_modules/react-toastify/node_modules/clsx": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
- "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
+ "react": ">=18",
+ "react-dom": ">=18"
}
},
"node_modules/react-tooltip": {
- "version": "5.27.0",
- "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.27.0.tgz",
- "integrity": "sha512-JXROcdfCEbCqkAkh8LyTSP3guQ0dG53iY2E2o4fw3D8clKzziMpE6QG6CclDaHELEKTzpMSeAOsdtg0ahoQosw==",
+ "version": "5.27.1",
+ "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.27.1.tgz",
+ "integrity": "sha512-a+micPXcMOMt11CYlwJD4XShcqGziasHco4NPe1OFw298WBTILMyzUgNC1LAFViAe791JdHNVSJIpzhZm2MvDA==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.1",
@@ -10086,6 +10529,24 @@
"react-dom": ">=16.13"
}
},
+ "node_modules/reactflow": {
+ "version": "11.11.4",
+ "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.4.tgz",
+ "integrity": "sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og==",
+ "license": "MIT",
+ "dependencies": {
+ "@reactflow/background": "11.3.14",
+ "@reactflow/controls": "11.2.14",
+ "@reactflow/core": "11.11.4",
+ "@reactflow/minimap": "11.7.14",
+ "@reactflow/node-resizer": "2.2.14",
+ "@reactflow/node-toolbar": "1.3.14"
+ },
+ "peerDependencies": {
+ "react": ">=17",
+ "react-dom": ">=17"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -10125,9 +10586,9 @@
}
},
"node_modules/reagraph": {
- "version": "4.19.1",
- "resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.19.1.tgz",
- "integrity": "sha512-BMSfZ2CoLSWsxe+vowHbCZSqeJJlH2UcbQA6hM1JHI0PmZ/3UHIXCQUHXrsROtYIIH5AnFEj9pUAZh2FGnfGhw==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/reagraph/-/reagraph-4.19.2.tgz",
+ "integrity": "sha512-SfEaXGRR/kWwG6Hq8Q6WropdhMAFgszWG174/j4rsZQNMYTEiwwK+47iQLW9qxwVO1YJAloktfihN7QsWZmLaw==",
"license": "Apache-2.0",
"dependencies": {
"@react-spring/three": "9.6.1",
@@ -10148,7 +10609,7 @@
"graphology-shortest-path": "^2.0.2",
"hold-event": "^0.2.0",
"react-use-gesture": "^9.1.3",
- "reakeys": "^2.0.1",
+ "reakeys": "^2.0.3",
"three": "^0.154.0",
"three-stdlib": "^2.23.13",
"zustand": "4.3.9"
@@ -10183,12 +10644,12 @@
}
},
"node_modules/reakeys": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/reakeys/-/reakeys-2.0.2.tgz",
- "integrity": "sha512-xY6OvVxuSC3iH55wvfPDyZ5xxMXIzEp6tNdipNXkaP6eznC9NdH+S3OqX3gktY731oIX31zH7u0QBV4lRXo1iQ==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/reakeys/-/reakeys-2.0.3.tgz",
+ "integrity": "sha512-5qeGH9xtvFITi+9AyPeTmPhzjDTEBRZICxAg6RJFuEgWFKMHqr6mnMIaL9fgOKJMBzLWCBorpUhyiB824f0EyA==",
"license": "Apache-2.0",
"dependencies": {
- "ctrl-keys": "^1.0.2"
+ "ctrl-keys": "^1.0.3"
},
"peerDependencies": {
"react": ">=16",
@@ -10221,13 +10682,17 @@
}
},
"node_modules/resolve": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
- "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
"license": "MIT",
"dependencies": {
- "is-core-module": "^2.1.0",
- "path-parse": "^1.0.6"
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -10304,19 +10769,38 @@
}
},
"node_modules/rollup": {
- "version": "3.29.4",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
- "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz",
+ "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.5"
+ },
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
- "node": ">=14.18.0",
+ "node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.18.1",
+ "@rollup/rollup-android-arm64": "4.18.1",
+ "@rollup/rollup-darwin-arm64": "4.18.1",
+ "@rollup/rollup-darwin-x64": "4.18.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.18.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.18.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.18.1",
+ "@rollup/rollup-linux-arm64-musl": "4.18.1",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.18.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.18.1",
+ "@rollup/rollup-linux-x64-gnu": "4.18.1",
+ "@rollup/rollup-linux-x64-musl": "4.18.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.18.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.18.1",
+ "@rollup/rollup-win32-x64-msvc": "4.18.1",
"fsevents": "~2.3.2"
}
},
@@ -10375,9 +10859,9 @@
}
},
"node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"devOptional": true,
"license": "ISC",
"bin": {
@@ -10492,7 +10976,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
- "dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -10689,24 +11172,23 @@
"license": "MIT"
},
"node_modules/styled-components": {
- "version": "5.3.11",
- "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz",
- "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==",
+ "version": "6.1.12",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz",
+ "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==",
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.0.0",
- "@babel/traverse": "^7.4.5",
- "@emotion/is-prop-valid": "^1.1.0",
- "@emotion/stylis": "^0.8.4",
- "@emotion/unitless": "^0.7.4",
- "babel-plugin-styled-components": ">= 1.12.0",
- "css-to-react-native": "^3.0.0",
- "hoist-non-react-statics": "^3.0.0",
- "shallowequal": "^1.1.0",
- "supports-color": "^5.5.0"
+ "@emotion/is-prop-valid": "1.2.2",
+ "@emotion/unitless": "0.8.1",
+ "@types/stylis": "4.2.5",
+ "css-to-react-native": "3.2.0",
+ "csstype": "3.1.3",
+ "postcss": "8.4.38",
+ "shallowequal": "1.1.0",
+ "stylis": "4.3.2",
+ "tslib": "2.6.2"
},
"engines": {
- "node": ">=10"
+ "node": ">= 16"
},
"funding": {
"type": "opencollective",
@@ -10714,37 +11196,55 @@
},
"peerDependencies": {
"react": ">= 16.8.0",
- "react-dom": ">= 16.8.0",
- "react-is": ">= 16.8.0"
+ "react-dom": ">= 16.8.0"
}
},
- "node_modules/styled-components/node_modules/@emotion/is-prop-valid": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
- "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
- "license": "MIT",
- "dependencies": {
- "@emotion/memoize": "^0.8.1"
- }
- },
- "node_modules/styled-components/node_modules/@emotion/memoize": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
- "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
- "license": "MIT"
- },
"node_modules/styled-components/node_modules/@emotion/unitless": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
- "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
"license": "MIT"
},
- "node_modules/styled-tools": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/styled-tools/-/styled-tools-1.7.2.tgz",
- "integrity": "sha512-IjLxzM20RMwAsx8M1QoRlCG/Kmq8lKzCGyospjtSXt/BTIIcvgTonaxQAsKnBrsZNwhpHzO9ADx5te0h76ILVg==",
+ "node_modules/styled-components/node_modules/postcss": {
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/styled-components/node_modules/stylis": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+ "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
"license": "MIT"
},
+ "node_modules/styled-components/node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "license": "0BSD"
+ },
"node_modules/stylis": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
@@ -10775,9 +11275,9 @@
}
},
"node_modules/sucrase/node_modules/glob": {
- "version": "10.4.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
- "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -10791,25 +11291,6 @@
"bin": {
"glob": "dist/esm/bin.mjs"
},
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/sucrase/node_modules/minimatch": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
- "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
@@ -10840,7 +11321,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.4"
@@ -10859,9 +11339,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
- "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "version": "3.4.6",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
+ "integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10896,24 +11376,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/tailwindcss/node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/tar": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
@@ -11015,18 +11477,18 @@
"license": "MIT"
},
"node_modules/three-mesh-bvh": {
- "version": "0.7.5",
- "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.5.tgz",
- "integrity": "sha512-WDd77RklE52pZSKZx8sDXzrd2JCF/gL/hugFvsIBylpMRlJxxwesKn2rW7TcQZ809NocDVkQx1UJo9pJtVAPYg==",
+ "version": "0.7.6",
+ "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.6.tgz",
+ "integrity": "sha512-rCjsnxEqR9r1/C/lCqzGLS67NDty/S/eT6rAJfDvsanrIctTWdNoR4ZOGWewCB13h1QkVo2BpmC0wakj1+0m8A==",
"license": "MIT",
"peerDependencies": {
"three": ">= 0.151.0"
}
},
"node_modules/three-stdlib": {
- "version": "2.30.3",
- "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.30.3.tgz",
- "integrity": "sha512-rYr8PqMljMza+Ct8kQk90Y7y+YcWoPu1thfYv5YGCp0hytNRbxSQWXY4GpdTGymCj3bDggEBpxso53C3pPwhIw==",
+ "version": "2.30.4",
+ "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.30.4.tgz",
+ "integrity": "sha512-E7sN8UkaorSq2uRZU14AE7wXkdCBa2oFwPkPt92zaecuzrgd98BXkTt+2tFQVF1tPJRvfs7aMZV5dSOq4/vNVg==",
"license": "MIT",
"dependencies": {
"@types/draco3d": "^1.4.0",
@@ -11139,13 +11601,14 @@
"license": "Apache-2.0"
},
"node_modules/ts-jest": {
- "version": "29.1.5",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.5.tgz",
- "integrity": "sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==",
+ "version": "29.2.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.3.tgz",
+ "integrity": "sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"bs-logger": "0.x",
+ "ejs": "^3.1.10",
"fast-json-stable-stringify": "2.x",
"jest-util": "^29.0.0",
"json5": "^2.2.3",
@@ -11238,9 +11701,9 @@
}
},
"node_modules/typescript": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
- "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
+ "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
"devOptional": true,
"license": "Apache-2.0",
"bin": {
@@ -11259,9 +11722,10 @@
"license": "MIT"
},
"node_modules/update-browserslist-db": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
- "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
+ "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -11363,9 +11827,9 @@
}
},
"node_modules/v8-to-istanbul": {
- "version": "9.2.0",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
- "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==",
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -11378,30 +11842,30 @@
}
},
"node_modules/vite": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
- "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz",
+ "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "esbuild": "^0.18.10",
- "postcss": "^8.4.27",
- "rollup": "^3.27.1"
+ "esbuild": "^0.21.3",
+ "postcss": "^8.4.39",
+ "rollup": "^4.13.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^14.18.0 || >=16.0.0"
+ "node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
- "fsevents": "~2.3.2"
+ "fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": ">= 14",
+ "@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
@@ -11666,6 +12130,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
"license": "ISC"
},
"node_modules/yaml": {
@@ -11720,9 +12185,9 @@
}
},
"node_modules/zustand": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz",
- "integrity": "sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==",
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz",
+ "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==",
"license": "MIT",
"dependencies": {
"use-sync-external-store": "1.2.0"
diff --git a/rsconcept/frontend/package.json b/rsconcept/frontend/package.json
index 5f4033ce..7433fa66 100644
--- a/rsconcept/frontend/package.json
+++ b/rsconcept/frontend/package.json
@@ -13,50 +13,50 @@
},
"dependencies": {
"@lezer/lr": "^1.4.1",
- "@reactflow/core": "^11.11.4",
- "@tanstack/react-table": "^8.17.3",
- "@uiw/codemirror-themes": "^4.22.2",
- "@uiw/react-codemirror": "^4.22.2",
+ "@tanstack/react-table": "^8.19.3",
+ "@uiw/codemirror-themes": "^4.23.0",
+ "@uiw/react-codemirror": "^4.23.0",
"axios": "^1.7.2",
"clsx": "^2.1.1",
- "framer-motion": "^10.18.0",
+ "framer-motion": "^11.3.8",
"js-file-download": "^0.4.12",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
- "react-icons": "^4.12.0",
+ "react-icons": "^5.2.1",
"react-intl": "^6.6.8",
- "react-loader-spinner": "^5.4.5",
- "react-pdf": "^9.0.0",
- "react-router-dom": "^6.23.1",
+ "react-loader-spinner": "^6.1.6",
+ "react-pdf": "^9.1.0",
+ "react-router-dom": "^6.25.1",
"react-select": "^5.8.0",
"react-tabs": "^6.0.2",
- "react-toastify": "^9.1.3",
- "react-tooltip": "^5.27.0",
- "reagraph": "^4.19.1",
+ "react-toastify": "^10.0.5",
+ "react-tooltip": "^5.27.1",
+ "reactflow": "^11.11.4",
+ "reagraph": "^4.19.2",
"use-debounce": "^10.0.1"
},
"devDependencies": {
"@lezer/generator": "^1.7.1",
"@types/jest": "^29.5.12",
- "@types/node": "^20.14.7",
+ "@types/node": "^20.14.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
- "@typescript-eslint/eslint-plugin": "^6.21.0",
- "@typescript-eslint/parser": "^6.21.0",
+ "@typescript-eslint/eslint-plugin": "^7.16.1",
+ "@typescript-eslint/parser": "^7.16.1",
"@vitejs/plugin-react": "^4.3.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.2",
- "eslint-plugin-react-refresh": "^0.4.7",
- "eslint-plugin-simple-import-sort": "^10.0.0",
- "eslint-plugin-tsdoc": "^0.2.17",
+ "eslint-plugin-react-refresh": "^0.4.8",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
+ "eslint-plugin-tsdoc": "^0.3.0",
"jest": "^29.7.0",
- "postcss": "^8.4.38",
- "tailwindcss": "^3.4.4",
- "ts-jest": "^29.1.5",
- "typescript": "^5.5.2",
- "vite": "^4.5.3"
+ "postcss": "^8.4.39",
+ "tailwindcss": "^3.4.6",
+ "ts-jest": "^29.2.3",
+ "typescript": "^5.5.3",
+ "vite": "^5.3.4"
},
"jest": {
"preset": "ts-jest",
diff --git a/rsconcept/frontend/public/robots.txt b/rsconcept/frontend/public/robots.txt
index a7022980..65568494 100644
--- a/rsconcept/frontend/public/robots.txt
+++ b/rsconcept/frontend/public/robots.txt
@@ -1,2 +1,5 @@
User-agent: *
-Disallow: /library
\ No newline at end of file
+Disallow: /library
+Disallow: /restore-password
+Disallow: /signup
+Disallow: /profile
\ No newline at end of file
diff --git a/rsconcept/frontend/src/app/ApplicationLayout.tsx b/rsconcept/frontend/src/app/ApplicationLayout.tsx
index 84b95b75..f592d4a2 100644
--- a/rsconcept/frontend/src/app/ApplicationLayout.tsx
+++ b/rsconcept/frontend/src/app/ApplicationLayout.tsx
@@ -3,8 +3,8 @@ import { Outlet } from 'react-router-dom';
import ConceptToaster from '@/app/ConceptToaster';
import Footer from '@/app/Footer';
import Navigation from '@/app/Navigation';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { NavigationState } from '@/context/NavigationContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { globals } from '@/utils/constants';
function ApplicationLayout() {
diff --git a/rsconcept/frontend/src/app/ConceptToaster.tsx b/rsconcept/frontend/src/app/ConceptToaster.tsx
index 09e361f2..262759e8 100644
--- a/rsconcept/frontend/src/app/ConceptToaster.tsx
+++ b/rsconcept/frontend/src/app/ConceptToaster.tsx
@@ -1,6 +1,6 @@
import { ToastContainer, type ToastContainerProps } from 'react-toastify';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
interface ToasterThemedProps extends Omit {}
diff --git a/rsconcept/frontend/src/app/Footer.tsx b/rsconcept/frontend/src/app/Footer.tsx
index bae26d81..c4f98a8f 100644
--- a/rsconcept/frontend/src/app/Footer.tsx
+++ b/rsconcept/frontend/src/app/Footer.tsx
@@ -1,6 +1,6 @@
import clsx from 'clsx';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { external_urls } from '@/utils/constants';
import TextURL from '../components/ui/TextURL';
diff --git a/rsconcept/frontend/src/app/GlobalProviders.tsx b/rsconcept/frontend/src/app/GlobalProviders.tsx
index d62c99d5..db0369e9 100644
--- a/rsconcept/frontend/src/app/GlobalProviders.tsx
+++ b/rsconcept/frontend/src/app/GlobalProviders.tsx
@@ -5,8 +5,8 @@ import { IntlProvider } from 'react-intl';
import { pdfjs } from 'react-pdf';
import { AuthState } from '@/context/AuthContext';
+import { OptionsState } from '@/context/ConceptOptionsContext';
import { LibraryState } from '@/context/LibraryContext';
-import { OptionsState } from '@/context/OptionsContext';
import { UsersState } from '@/context/UsersContext';
import ErrorFallback from './ErrorFallback';
diff --git a/rsconcept/frontend/src/app/Navigation/Logo.tsx b/rsconcept/frontend/src/app/Navigation/Logo.tsx
index a4d16662..e4097fbb 100644
--- a/rsconcept/frontend/src/app/Navigation/Logo.tsx
+++ b/rsconcept/frontend/src/app/Navigation/Logo.tsx
@@ -1,6 +1,6 @@
import clsx from 'clsx';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize';
function Logo() {
diff --git a/rsconcept/frontend/src/app/Navigation/Navigation.tsx b/rsconcept/frontend/src/app/Navigation/Navigation.tsx
index 207dccae..c694a2ba 100644
--- a/rsconcept/frontend/src/app/Navigation/Navigation.tsx
+++ b/rsconcept/frontend/src/app/Navigation/Navigation.tsx
@@ -3,14 +3,14 @@ import { motion } from 'framer-motion';
import { IconLibrary2, IconManuals, IconNewItem2 } from '@/components/Icons';
import { CProps } from '@/components/props';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useConceptNavigation } from '@/context/NavigationContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { animateNavigation } from '@/styling/animations';
import { urls } from '../urls';
import Logo from './Logo';
import NavigationButton from './NavigationButton';
-import ToggleNavigationButton from './ToggleNavigationButton';
+import ToggleNavigation from './ToggleNavigation';
import UserMenu from './UserMenu';
function Navigation() {
@@ -33,7 +33,7 @@ function Navigation() {
'select-none'
)}
>
-
+
- }
- onClick={navigateCreateNew}
- />
- }
- onClick={navigateLibrary}
- />
- } onClick={navigateHelp} />
+ } onClick={navigateCreateNew} />
+ } onClick={navigateLibrary} />
+ } onClick={navigateHelp} />
diff --git a/rsconcept/frontend/src/app/Navigation/ToggleNavigationButton.tsx b/rsconcept/frontend/src/app/Navigation/ToggleNavigation.tsx
similarity index 88%
rename from rsconcept/frontend/src/app/Navigation/ToggleNavigationButton.tsx
rename to rsconcept/frontend/src/app/Navigation/ToggleNavigation.tsx
index ce564c40..ed4e4307 100644
--- a/rsconcept/frontend/src/app/Navigation/ToggleNavigationButton.tsx
+++ b/rsconcept/frontend/src/app/Navigation/ToggleNavigation.tsx
@@ -2,11 +2,11 @@ import clsx from 'clsx';
import { motion } from 'framer-motion';
import { IconPin, IconUnpin } from '@/components/Icons';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { animateNavigationToggle } from '@/styling/animations';
import { globals } from '@/utils/constants';
-function ToggleNavigationButton() {
+function ToggleNavigation() {
const { noNavigationAnimation, toggleNoNavigation } = useConceptOptions();
return (
{
export interface FrontPush extends IFrontRequest {
data: DataType;
}
-
export interface FrontPull extends IFrontRequest {
onSuccess: DataCallback;
}
@@ -228,10 +234,27 @@ export function postCloneLibraryItem(target: string, request: FrontExchange) {
- AxiosGet({
- endpoint: `/api/synthesis/${target}`,
- request: request
+ request.setLoading!(false);
+ request.onSuccess({
+ id: Number(target),
+ comment: '123',
+ alias: 'oss1',
+ access_policy: AccessPolicy.PUBLIC,
+ editors: [],
+ owner: 1,
+ item_type: LibraryItemType.OSS,
+ location: '/U',
+ read_only: false,
+ subscribers: [],
+ time_create: '0',
+ time_update: '0',
+ title: 'TestOss',
+ visible: false
});
+ // AxiosGet({
+ // endpoint: `/api/oss/${target}`, // TODO: endpoint to access OSS
+ // request: request
+ // });
}
export function getRSFormDetails(target: string, version: string, request: FrontPull) {
@@ -415,35 +438,13 @@ export function patchUploadTRS(target: string, request: FrontExchange) {
+export function patchInlineSynthesis(request: FrontExchange) {
AxiosPatch({
endpoint: `/api/operations/inline-synthesis`,
request: request
});
}
-export function runSingleSynthesis(request: FrontExchange) {
- AxiosPost({
- endpoint: `/api/synthesis/run_single`,
- request: request
- });
-}
-
-export function postSynthesisGraph(request: FrontExchange) {
- AxiosPost({
- endpoint: `/api/synthesis/save`,
- request: request
- });
-}
-
-export function postResolveText(schema: string, request: FrontExchange) {
- AxiosPost({
- endpoint: `/api/rsforms/${schema}/resolve`,
- request: request
- });
-}
-
export function postInflectText(request: FrontExchange) {
AxiosPost({
endpoint: `/api/cctext/inflect`,
diff --git a/rsconcept/frontend/src/components/RSInput/RSInput.tsx b/rsconcept/frontend/src/components/RSInput/RSInput.tsx
index 19ba811b..ebc673f0 100644
--- a/rsconcept/frontend/src/components/RSInput/RSInput.tsx
+++ b/rsconcept/frontend/src/components/RSInput/RSInput.tsx
@@ -9,7 +9,7 @@ import { EditorView } from 'codemirror';
import { forwardRef, useCallback, useMemo, useRef } from 'react';
import Label from '@/components/ui/Label';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { getFontClassName } from '@/models/miscellaneousAPI';
import { ConstituentaID, IRSForm } from '@/models/rsform';
import { generateAlias, getCstTypePrefix, guessCstType } from '@/models/rsformAPI';
diff --git a/rsconcept/frontend/src/components/RefsInput/RefsInput.tsx b/rsconcept/frontend/src/components/RefsInput/RefsInput.tsx
index bdfe33fe..2c28313e 100644
--- a/rsconcept/frontend/src/components/RefsInput/RefsInput.tsx
+++ b/rsconcept/frontend/src/components/RefsInput/RefsInput.tsx
@@ -10,7 +10,7 @@ import { AnimatePresence } from 'framer-motion';
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
import Label from '@/components/ui/Label';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import DlgEditReference from '@/dialogs/DlgEditReference';
import { ReferenceType } from '@/models/language';
import { ConstituentaID, IRSForm } from '@/models/rsform';
diff --git a/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx b/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx
index 06427b59..207868f6 100644
--- a/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx
+++ b/rsconcept/frontend/src/components/info/BadgeConstituenta.tsx
@@ -1,10 +1,11 @@
import clsx from 'clsx';
-import ConstituentaTooltip from '@/components/info/ConstituentaTooltip';
import { IConstituenta } from '@/models/rsform';
import { isMockCst } from '@/models/rsformAPI';
import { colorFgCstStatus, IColorTheme } from '@/styling/color';
+import TooltipConstituenta from './TooltipConstituenta';
+
interface BadgeConstituentaProps {
prefixID?: string;
value: IConstituenta;
@@ -28,7 +29,7 @@ function BadgeConstituenta({ value, prefixID, theme }: BadgeConstituentaProps) {
}}
>
{value.alias}
-
+
);
}
diff --git a/rsconcept/frontend/src/components/info/BadgeGrammeme.tsx b/rsconcept/frontend/src/components/info/BadgeGrammeme.tsx
index cf431f1a..55965d89 100644
--- a/rsconcept/frontend/src/components/info/BadgeGrammeme.tsx
+++ b/rsconcept/frontend/src/components/info/BadgeGrammeme.tsx
@@ -1,6 +1,6 @@
import clsx from 'clsx';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { GramData } from '@/models/language';
import { colorFgGrammeme } from '@/styling/color';
import { labelGrammeme } from '@/utils/labels';
diff --git a/rsconcept/frontend/src/components/info/BadgeHelp.tsx b/rsconcept/frontend/src/components/info/BadgeHelp.tsx
index 77a68cde..e57be9da 100644
--- a/rsconcept/frontend/src/components/info/BadgeHelp.tsx
+++ b/rsconcept/frontend/src/components/info/BadgeHelp.tsx
@@ -2,7 +2,7 @@ import clsx from 'clsx';
import TextURL from '@/components/ui/TextURL';
import Tooltip, { PlacesType } from '@/components/ui/Tooltip';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import TopicPage from '../../pages/ManualsPage/TopicPage';
diff --git a/rsconcept/frontend/src/components/info/InfoCstClass.tsx b/rsconcept/frontend/src/components/info/InfoCstClass.tsx
index 6580bc6e..02605505 100644
--- a/rsconcept/frontend/src/components/info/InfoCstClass.tsx
+++ b/rsconcept/frontend/src/components/info/InfoCstClass.tsx
@@ -1,6 +1,6 @@
import clsx from 'clsx';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstClass } from '@/models/rsform';
import { colorBgCstClass } from '@/styling/color';
import { prefixes } from '@/utils/constants';
diff --git a/rsconcept/frontend/src/components/info/InfoCstStatus.tsx b/rsconcept/frontend/src/components/info/InfoCstStatus.tsx
index f3c8002c..ba95a5b9 100644
--- a/rsconcept/frontend/src/components/info/InfoCstStatus.tsx
+++ b/rsconcept/frontend/src/components/info/InfoCstStatus.tsx
@@ -1,6 +1,6 @@
import clsx from 'clsx';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ExpressionStatus } from '@/models/rsform';
import { colorBgCstStatus } from '@/styling/color';
import { prefixes } from '@/utils/constants';
diff --git a/rsconcept/frontend/src/components/info/ConstituentaTooltip.tsx b/rsconcept/frontend/src/components/info/TooltipConstituenta.tsx
similarity index 73%
rename from rsconcept/frontend/src/components/info/ConstituentaTooltip.tsx
rename to rsconcept/frontend/src/components/info/TooltipConstituenta.tsx
index fc4f2601..42bab46d 100644
--- a/rsconcept/frontend/src/components/info/ConstituentaTooltip.tsx
+++ b/rsconcept/frontend/src/components/info/TooltipConstituenta.tsx
@@ -2,12 +2,12 @@ import InfoConstituenta from '@/components/info/InfoConstituenta';
import Tooltip from '@/components/ui/Tooltip';
import { IConstituenta } from '@/models/rsform';
-interface ConstituentaTooltipProps {
+interface TooltipConstituentaProps {
data: IConstituenta;
anchor: string;
}
-function ConstituentaTooltip({ data, anchor }: ConstituentaTooltipProps) {
+function TooltipConstituenta({ data, anchor }: TooltipConstituentaProps) {
return (
event.stopPropagation()} />
@@ -15,4 +15,4 @@ function ConstituentaTooltip({ data, anchor }: ConstituentaTooltipProps) {
);
}
-export default ConstituentaTooltip;
+export default TooltipConstituenta;
diff --git a/rsconcept/frontend/src/components/select/PickConstituenta.tsx b/rsconcept/frontend/src/components/select/PickConstituenta.tsx
index 5f656280..976c2f3b 100644
--- a/rsconcept/frontend/src/components/select/PickConstituenta.tsx
+++ b/rsconcept/frontend/src/components/select/PickConstituenta.tsx
@@ -4,7 +4,7 @@ import { useEffect, useMemo, useState } from 'react';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { CstMatchMode } from '@/models/miscellaneous';
import { IConstituenta } from '@/models/rsform';
import { matchConstituenta } from '@/models/rsformAPI';
diff --git a/rsconcept/frontend/src/components/select/PickMultiConstituenta.tsx b/rsconcept/frontend/src/components/select/PickMultiConstituenta.tsx
index ab1e216f..ee7f0eb8 100644
--- a/rsconcept/frontend/src/components/select/PickMultiConstituenta.tsx
+++ b/rsconcept/frontend/src/components/select/PickMultiConstituenta.tsx
@@ -4,14 +4,14 @@ import clsx from 'clsx';
import { useLayoutEffect, useMemo, useState } from 'react';
import DataTable, { createColumnHelper, RowSelectionState } from '@/components/ui/DataTable';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { isBasicConcept } from '@/models/rsformAPI';
import { describeConstituenta } from '@/utils/labels';
import BadgeConstituenta from '../info/BadgeConstituenta';
import NoData from '../ui/NoData';
-import GraphSelectionToolbar from './GraphSelectionToolbar';
+import ToolbarGraphSelection from './ToolbarGraphSelection';
interface PickMultiConstituentaProps {
id?: string;
@@ -80,7 +80,7 @@ function PickMultiConstituenta({ id, schema, prefixID, rows, selected, setSelect
Выбраны {selected.length} из {schema?.items.length ?? 0}
{schema ? (
- isBasicConcept(cst.cst_type)).map(cst => cst.id)}
setSelected={setSelected}
diff --git a/rsconcept/frontend/src/components/select/PickSchema.tsx b/rsconcept/frontend/src/components/select/PickSchema.tsx
index a7f8b897..24b2e521 100644
--- a/rsconcept/frontend/src/components/select/PickSchema.tsx
+++ b/rsconcept/frontend/src/components/select/PickSchema.tsx
@@ -3,8 +3,8 @@ import { useIntl } from 'react-intl';
import DataTable, { createColumnHelper, IConditionalStyle } from '@/components/ui/DataTable';
import SearchBar from '@/components/ui/SearchBar';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
import { ILibraryFilter } from '@/models/miscellaneous';
diff --git a/rsconcept/frontend/src/components/select/PickSubstitutions.tsx b/rsconcept/frontend/src/components/select/PickSubstitutions.tsx
index c66a73af..ada311e1 100644
--- a/rsconcept/frontend/src/components/select/PickSubstitutions.tsx
+++ b/rsconcept/frontend/src/components/select/PickSubstitutions.tsx
@@ -7,7 +7,7 @@ import SelectConstituenta from '@/components/select/SelectConstituenta';
import DataTable, { createColumnHelper } from '@/components/ui/DataTable';
import Label from '@/components/ui/Label';
import MiniButton from '@/components/ui/MiniButton';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta, IRSForm, ISubstitution } from '@/models/rsform';
import { describeConstituenta } from '@/utils/labels';
diff --git a/rsconcept/frontend/src/components/select/SelectLocation.tsx b/rsconcept/frontend/src/components/select/SelectLocation.tsx
index 43cbcd66..cded1871 100644
--- a/rsconcept/frontend/src/components/select/SelectLocation.tsx
+++ b/rsconcept/frontend/src/components/select/SelectLocation.tsx
@@ -1,40 +1,109 @@
'use client';
-import { useCallback } from 'react';
+import clsx from 'clsx';
+import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
-import useDropdown from '@/hooks/useDropdown';
-import { FolderTree } from '@/models/FolderTree';
+import { FolderNode, FolderTree } from '@/models/FolderTree';
+import { labelFolderNode } from '@/utils/labels';
-import { IconFolderTree } from '../Icons';
+import { IconFolder, IconFolderClosed, IconFolderEmpty, IconFolderOpened } from '../Icons';
+import { CProps } from '../props';
import MiniButton from '../ui/MiniButton';
-interface SelectLocationProps {
+interface SelectLocationProps extends CProps.Styling {
value: string;
- onChange: (newValue: string) => void;
-
folderTree: FolderTree;
+ prefix: string;
+ dense?: boolean;
+ onClick: (event: CProps.EventMouse, target: FolderNode) => void;
}
-function SelectLocation({ value, onChange, folderTree }: SelectLocationProps) {
- const menu = useDropdown();
+function SelectLocation({ value, folderTree, dense, prefix, onClick, className, style }: SelectLocationProps) {
+ const activeNode = useMemo(() => folderTree.at(value), [folderTree, value]);
- const handleChange = useCallback(
- (newValue: string) => {
- console.log(folderTree.roots.size);
- console.log(value);
- menu.hide();
- onChange(newValue);
+ const items = useMemo(() => folderTree.getTree(), [folderTree]);
+ const [folded, setFolded] = useState(items);
+
+ useLayoutEffect(() => {
+ setFolded(items.filter(item => item !== activeNode && (!activeNode || !activeNode.hasPredecessor(item))));
+ }, [items, activeNode]);
+
+ const onFoldItem = useCallback(
+ (target: FolderNode, showChildren: boolean) => {
+ setFolded(prev =>
+ items.filter(item => {
+ if (item === target) {
+ return !showChildren;
+ }
+ if (!showChildren && item.hasPredecessor(target)) {
+ return true;
+ } else {
+ return prev.includes(item);
+ }
+ })
+ );
},
- [menu, onChange, value, folderTree]
+ [items]
+ );
+
+ const handleClickFold = useCallback(
+ (event: CProps.EventMouse, target: FolderNode, showChildren: boolean) => {
+ event.preventDefault();
+ event.stopPropagation();
+ onFoldItem(target, showChildren);
+ },
+ [onFoldItem]
);
return (
-
-
}
- onClick={() => handleChange('/U/test')}
- />
+
+ {items.map((item, index) =>
+ !item.parent || !folded.includes(item.parent) ? (
+
5 ? 5 : item.rank) * 0.5 + 0.5}rem` }}
+ onClick={event => onClick(event, item)}
+ >
+ {item.children.size > 0 ? (
+
+ ) : (
+
+ )
+ ) : (
+
+ )
+ }
+ onClick={event => handleClickFold(event, item, folded.includes(item))}
+ />
+ ) : (
+
+ {item.filesInside ? (
+
+ ) : (
+
+ )}
+
+ )}
+
{labelFolderNode(item)}
+
+ ) : null
+ )}
);
}
diff --git a/rsconcept/frontend/src/components/select/SelectLocationContext.tsx b/rsconcept/frontend/src/components/select/SelectLocationContext.tsx
new file mode 100644
index 00000000..91e260a8
--- /dev/null
+++ b/rsconcept/frontend/src/components/select/SelectLocationContext.tsx
@@ -0,0 +1,62 @@
+'use client';
+
+import clsx from 'clsx';
+import { useCallback } from 'react';
+
+import useDropdown from '@/hooks/useDropdown';
+import { FolderTree } from '@/models/FolderTree';
+import { prefixes } from '@/utils/constants';
+
+import { IconFolderTree } from '../Icons';
+import { CProps } from '../props';
+import Dropdown from '../ui/Dropdown';
+import MiniButton from '../ui/MiniButton';
+import SelectLocation from './SelectLocation';
+
+interface SelectLocationContextProps extends CProps.Styling {
+ value: string;
+ folderTree: FolderTree;
+ stretchTop?: boolean;
+
+ onChange: (newValue: string) => void;
+}
+
+function SelectLocationContext({ value, folderTree, onChange, className, style }: SelectLocationContextProps) {
+ const menu = useDropdown();
+
+ const handleClick = useCallback(
+ (event: CProps.EventMouse, newValue: string) => {
+ event.preventDefault();
+ event.stopPropagation();
+ menu.hide();
+ onChange(newValue);
+ },
+ [menu, onChange]
+ );
+
+ return (
+
+ }
+ onClick={() => menu.toggle()}
+ />
+
+ handleClick(event, target.getPath())}
+ />
+
+
+ );
+}
+
+export default SelectLocationContext;
diff --git a/rsconcept/frontend/src/dialogs/DlgEditReference/SelectWordForm.tsx b/rsconcept/frontend/src/components/select/SelectWordForm.tsx
similarity index 93%
rename from rsconcept/frontend/src/dialogs/DlgEditReference/SelectWordForm.tsx
rename to rsconcept/frontend/src/components/select/SelectWordForm.tsx
index 1db8c129..7f385da0 100644
--- a/rsconcept/frontend/src/dialogs/DlgEditReference/SelectWordForm.tsx
+++ b/rsconcept/frontend/src/components/select/SelectWordForm.tsx
@@ -6,7 +6,7 @@ import { Grammeme } from '@/models/language';
import { prefixes } from '@/utils/constants';
import { DefaultWordForms, IGrammemeOption, SelectorGrammemes } from '@/utils/selectors';
-import WordformButton from './WordformButton';
+import WordformButton from '../../dialogs/DlgEditReference/WordformButton';
interface SelectWordFormProps {
selected: IGrammemeOption[];
diff --git a/rsconcept/frontend/src/components/select/GraphSelectionToolbar.tsx b/rsconcept/frontend/src/components/select/ToolbarGraphSelection.tsx
similarity index 93%
rename from rsconcept/frontend/src/components/select/GraphSelectionToolbar.tsx
rename to rsconcept/frontend/src/components/select/ToolbarGraphSelection.tsx
index ec06db95..3a074964 100644
--- a/rsconcept/frontend/src/components/select/GraphSelectionToolbar.tsx
+++ b/rsconcept/frontend/src/components/select/ToolbarGraphSelection.tsx
@@ -14,21 +14,21 @@ import {
import { CProps } from '../props';
import MiniButton from '../ui/MiniButton';
-interface GraphSelectionToolbarProps extends CProps.Styling {
+interface ToolbarGraphSelectionProps extends CProps.Styling {
graph: Graph;
core: number[];
setSelected: React.Dispatch
>;
emptySelection?: boolean;
}
-function GraphSelectionToolbar({
+function ToolbarGraphSelection({
className,
graph,
core,
setSelected,
emptySelection,
...restProps
-}: GraphSelectionToolbarProps) {
+}: ToolbarGraphSelectionProps) {
return (
{!isLoading && !error && !hasNoData ? (
-
+
{children}
) : null}
{!isLoading && !error && hasNoData ? (
-
+
Данные не загружены
) : null}
diff --git a/rsconcept/frontend/src/context/OptionsContext.tsx b/rsconcept/frontend/src/context/ConceptOptionsContext.tsx
similarity index 100%
rename from rsconcept/frontend/src/context/OptionsContext.tsx
rename to rsconcept/frontend/src/context/ConceptOptionsContext.tsx
diff --git a/rsconcept/frontend/src/context/LibraryContext.tsx b/rsconcept/frontend/src/context/LibraryContext.tsx
index 16e2c11d..3561ecd0 100644
--- a/rsconcept/frontend/src/context/LibraryContext.tsx
+++ b/rsconcept/frontend/src/context/LibraryContext.tsx
@@ -24,7 +24,7 @@ import { RSFormLoader } from '@/models/RSFormLoader';
import { contextOutsideScope } from '@/utils/labels';
import { useAuth } from './AuthContext';
-import { useConceptOptions } from './OptionsContext';
+import { useConceptOptions } from './ConceptOptionsContext';
interface ILibraryContext {
items: ILibraryItem[];
@@ -65,12 +65,12 @@ interface LibraryStateProps {
}
export const LibraryState = ({ children }: LibraryStateProps) => {
- const { user } = useAuth();
+ const { user, loading: userLoading } = useAuth();
const { adminMode } = useConceptOptions();
const [items, setItems] = useState([]);
const [templates, setTemplates] = useState([]);
- const [loading, setLoading] = useState(false);
+ const [loading, setLoading] = useState(true);
const [processing, setProcessing] = useState(false);
const [loadingError, setLoadingError] = useState(undefined);
const [processingError, setProcessingError] = useState(undefined);
@@ -92,8 +92,8 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
if (!filter.folderMode && filter.head) {
result = result.filter(item => item.location.startsWith(filter.head!));
}
- if (filter.folderMode && filter.folder) {
- result = result.filter(item => item.location == filter.folder);
+ if (filter.folderMode && filter.location) {
+ result = result.filter(item => item.location == filter.location);
}
if (filter.type) {
result = result.filter(item => item.item_type === filter.type);
@@ -175,16 +175,18 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
const reloadTemplates = useCallback(() => {
setTemplates([]);
getTemplates({
- setLoading: setLoading,
- onError: setLoadingError,
+ setLoading: setProcessing,
+ onError: setProcessingError,
showError: true,
onSuccess: newData => setTemplates(newData)
});
}, []);
useEffect(() => {
- reloadItems();
- }, [reloadItems]);
+ if (!userLoading) {
+ reloadItems();
+ }
+ }, [reloadItems, userLoading]);
useEffect(() => {
reloadTemplates();
diff --git a/rsconcept/frontend/src/context/UserProfileContext.tsx b/rsconcept/frontend/src/context/UserProfileContext.tsx
index 7185a553..7c39352e 100644
--- a/rsconcept/frontend/src/context/UserProfileContext.tsx
+++ b/rsconcept/frontend/src/context/UserProfileContext.tsx
@@ -36,7 +36,7 @@ interface UserProfileStateProps {
export const UserProfileState = ({ children }: UserProfileStateProps) => {
const { users } = useUsers();
const [user, setUser] = useState(undefined);
- const [loading, setLoading] = useState(false);
+ const [loading, setLoading] = useState(true);
const [processing, setProcessing] = useState(false);
const [error, setError] = useState(undefined);
const [errorProcessing, setErrorProcessing] = useState(undefined);
diff --git a/rsconcept/frontend/src/dialogs/DlgChangeLocation.tsx b/rsconcept/frontend/src/dialogs/DlgChangeLocation.tsx
index f6768572..82ef4bf3 100644
--- a/rsconcept/frontend/src/dialogs/DlgChangeLocation.tsx
+++ b/rsconcept/frontend/src/dialogs/DlgChangeLocation.tsx
@@ -1,13 +1,15 @@
'use client';
import clsx from 'clsx';
-import { useMemo, useState } from 'react';
+import { useCallback, useMemo, useState } from 'react';
+import SelectLocationContext from '@/components/select/SelectLocationContext';
import SelectLocationHead from '@/components/select/SelectLocationHead';
import Label from '@/components/ui/Label';
import Modal, { ModalProps } from '@/components/ui/Modal';
import TextArea from '@/components/ui/TextArea';
import { useAuth } from '@/context/AuthContext';
+import { useLibrary } from '@/context/LibraryContext';
import { LocationHead } from '@/models/library';
import { combineLocation, validateLocation } from '@/models/libraryAPI';
import { limits } from '@/utils/constants';
@@ -22,9 +24,16 @@ function DlgChangeLocation({ hideWindow, initial, onChangeLocation }: DlgChangeL
const [head, setHead] = useState(initial.substring(0, 2) as LocationHead);
const [body, setBody] = useState(initial.substring(3));
+ const { folders } = useLibrary();
+
const location = useMemo(() => combineLocation(head, body), [head, body]);
const isValid = useMemo(() => initial !== location && validateLocation(location), [initial, location]);
+ const handleSelectLocation = useCallback((newValue: string) => {
+ setHead(newValue.substring(0, 2) as LocationHead);
+ setBody(newValue.length > 3 ? newValue.substring(3) : '');
+ }, []);
+
function handleSubmit() {
onChangeLocation(location);
}
@@ -41,13 +50,19 @@ function DlgChangeLocation({ hideWindow, initial, onChangeLocation }: DlgChangeL
className={clsx('w-[35rem]', 'pb-3 px-6 flex gap-3')}
>
-
+
+
+
@@ -210,13 +210,13 @@ function DlgEditWordForms({ hideWindow, target, onSave }: DlgEditWordFormsProps)
title='Сбросить все словоформы'
className='py-0'
icon={ }
- disabled={textProcessor.loading || forms.length === 0}
+ disabled={textProcessor.processing || forms.length === 0}
onClick={handleResetAll}
/>
-
+
);
}
diff --git a/rsconcept/frontend/src/dialogs/DlgEditWordForms/WordFormsTable.tsx b/rsconcept/frontend/src/dialogs/DlgEditWordForms/TableWordForms.tsx
similarity index 94%
rename from rsconcept/frontend/src/dialogs/DlgEditWordForms/WordFormsTable.tsx
rename to rsconcept/frontend/src/dialogs/DlgEditWordForms/TableWordForms.tsx
index 8bc65c0b..7935748c 100644
--- a/rsconcept/frontend/src/dialogs/DlgEditWordForms/WordFormsTable.tsx
+++ b/rsconcept/frontend/src/dialogs/DlgEditWordForms/TableWordForms.tsx
@@ -10,7 +10,7 @@ import MiniButton from '@/components/ui/MiniButton';
import NoData from '@/components/ui/NoData';
import { IWordForm } from '@/models/language';
-interface WordFormsTableProps {
+interface TableWordFormsProps {
forms: IWordForm[];
setForms: React.Dispatch>;
onFormSelect?: (form: IWordForm) => void;
@@ -18,7 +18,7 @@ interface WordFormsTableProps {
const columnHelper = createColumnHelper();
-function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps) {
+function TableWordForms({ forms, setForms, onFormSelect }: TableWordFormsProps) {
const handleDeleteRow = useCallback(
(row: number) => {
setForms(prev => {
@@ -89,4 +89,4 @@ function WordFormsTable({ forms, setForms, onFormSelect }: WordFormsTableProps)
);
}
-export default WordFormsTable;
+export default TableWordForms;
diff --git a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/DlgInlineSynthesis.tsx b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/DlgInlineSynthesis.tsx
index f15a4e7c..d0a0a300 100644
--- a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/DlgInlineSynthesis.tsx
+++ b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/DlgInlineSynthesis.tsx
@@ -10,9 +10,9 @@ import useRSFormDetails from '@/hooks/useRSFormDetails';
import { LibraryItemID } from '@/models/library';
import { IInlineSynthesisData, IRSForm, ISubstitution } from '@/models/rsform';
-import ConstituentsTab from './ConstituentsTab';
-import SchemaTab from './SchemaTab';
-import SubstitutionsTab from './SubstitutionsTab';
+import TabConstituents from './TabConstituents';
+import TabSchema from './TabSchema';
+import TabSubstitutions from './TabSubstitutions';
interface DlgInlineSynthesisProps extends Pick {
receiver: IRSForm;
@@ -61,7 +61,7 @@ function DlgInlineSynthesis({ hideWindow, receiver, onInlineSynthesis }: DlgInli
const schemaPanel = useMemo(
() => (
-
+
),
[donorID]
@@ -69,7 +69,7 @@ function DlgInlineSynthesis({ hideWindow, receiver, onInlineSynthesis }: DlgInli
const itemsPanel = useMemo(
() => (
- (
- >;
}
-function ConstituentsTab({ schema, error, loading, selected, setSelected }: ConstituentsTabProps) {
+function TabConstituents({ schema, error, loading, selected, setSelected }: TabConstituentsProps) {
return (
void;
}
-function SchemaTab({ selected, setSelected }: SchemaTabProps) {
+function TabSchema({ selected, setSelected }: TabSchemaProps) {
const library = useLibrary();
const selectedInfo = useMemo(() => library.items.find(item => item.id === selected), [selected, library.items]);
@@ -41,4 +41,4 @@ function SchemaTab({ selected, setSelected }: SchemaTabProps) {
);
}
-export default SchemaTab;
+export default TabSchema;
diff --git a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/SubstitutionsTab.tsx b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx
similarity index 90%
rename from rsconcept/frontend/src/dialogs/DlgInlineSynthesis/SubstitutionsTab.tsx
rename to rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx
index 568fb105..f67f3771 100644
--- a/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/SubstitutionsTab.tsx
+++ b/rsconcept/frontend/src/dialogs/DlgInlineSynthesis/TabSubstitutions.tsx
@@ -8,7 +8,7 @@ import { prefixes } from '@/utils/constants';
import PickSubstitutions from '../../components/select/PickSubstitutions';
import { ISynthesisSubstitution } from '@/models/oss.ts';
-interface SubstitutionsTabProps {
+interface TabSubstitutionsProps {
receiver?: IRSForm;
source?: IRSForm;
selected: ConstituentaID[];
@@ -20,7 +20,7 @@ interface SubstitutionsTabProps {
setSubstitutions: React.Dispatch>;
}
-function SubstitutionsTab({
+function TabSubstitutions({
source,
receiver,
selected,
@@ -30,7 +30,7 @@ function SubstitutionsTab({
substitutions,
setSubstitutions
-}: SubstitutionsTabProps) {
+}: TabSubstitutionsProps) {
return (
(undefined);
const [parseData, setParseData] = useState(undefined);
@@ -22,7 +22,7 @@ function useCheckExpression({ schema }: { schema?: IRSForm }) {
postCheckExpression(String(schema!.id), {
data: { expression: expression },
showError: true,
- setLoading,
+ setLoading: setProcessing,
onError: setError,
onSuccess: parse => {
if (activeCst) {
@@ -34,7 +34,7 @@ function useCheckExpression({ schema }: { schema?: IRSForm }) {
});
}
- return { parseData, checkExpression, resetParse, error, setError, loading };
+ return { parseData, checkExpression, resetParse, error, setError, processing };
}
export default useCheckExpression;
diff --git a/rsconcept/frontend/src/hooks/useConceptText.ts b/rsconcept/frontend/src/hooks/useConceptText.ts
index 5ea48753..661d6ee7 100644
--- a/rsconcept/frontend/src/hooks/useConceptText.ts
+++ b/rsconcept/frontend/src/hooks/useConceptText.ts
@@ -7,7 +7,7 @@ import { ErrorData } from '@/components/info/InfoError';
import { ILexemeData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
function useConceptText() {
- const [loading, setLoading] = useState(false);
+ const [processing, setProcessing] = useState(false);
const [error, setError] = useState(undefined);
const inflect = useCallback((data: IWordFormPlain, onSuccess: DataCallback) => {
@@ -15,7 +15,7 @@ function useConceptText() {
postInflectText({
data: data,
showError: true,
- setLoading,
+ setLoading: setProcessing,
onError: setError,
onSuccess: data => {
if (onSuccess) onSuccess(data);
@@ -28,7 +28,7 @@ function useConceptText() {
postParseText({
data: data,
showError: true,
- setLoading,
+ setLoading: setProcessing,
onError: setError,
onSuccess: data => {
if (onSuccess) onSuccess(data);
@@ -41,7 +41,7 @@ function useConceptText() {
postGenerateLexeme({
data: data,
showError: true,
- setLoading,
+ setLoading: setProcessing,
onError: setError,
onSuccess: data => {
if (onSuccess) onSuccess(data);
@@ -49,7 +49,7 @@ function useConceptText() {
});
}, []);
- return { inflect, parse, generateLexeme, error, setError, loading };
+ return { inflect, parse, generateLexeme, error, setError, processing };
}
export default useConceptText;
diff --git a/rsconcept/frontend/src/hooks/useOssDetails.ts b/rsconcept/frontend/src/hooks/useOssDetails.ts
index ee807ca4..7fd14aeb 100644
--- a/rsconcept/frontend/src/hooks/useOssDetails.ts
+++ b/rsconcept/frontend/src/hooks/useOssDetails.ts
@@ -4,13 +4,14 @@ import { useCallback, useEffect, useState } from 'react';
import { getOssDetails } from '@/app/backendAPI';
import { type ErrorData } from '@/components/info/InfoError';
-import { AccessPolicy, LibraryItemType } from '@/models/library.ts';
+import { useAuth } from '@/context/AuthContext';
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
import { OssLoader } from '@/models/OssLoader';
function useOssDetails({ target }: { target?: string }) {
+ const { loading: userLoading } = useAuth();
const [schema, setInner] = useState(undefined);
- const [loading, setLoading] = useState(false);
+ const [loading, setLoading] = useState(target != undefined);
const [error, setError] = useState(undefined);
function setSchema(data?: IOperationSchemaData) {
@@ -28,24 +29,6 @@ function useOssDetails({ target }: { target?: string }) {
if (!target) {
return;
}
-
- const staticData = {
- id: Number(target),
- comment: '123',
- alias: 'oss1',
- access_policy: AccessPolicy.PUBLIC,
- editors: [],
- owner: 1,
- item_type: LibraryItemType.OSS,
- location: '/U',
- read_only: false,
- subscribers: [],
- time_create: '0',
- time_update: '0',
- title: 'TestOss',
- visible: false
- };
-
getOssDetails(target, {
showError: true,
setLoading: setCustomLoading ?? setLoading,
@@ -54,11 +37,7 @@ function useOssDetails({ target }: { target?: string }) {
setError(error);
},
onSuccess: schema => {
- const combinedData = {
- ...staticData,
- ...schema
- };
- setSchema(combinedData);
+ setSchema(schema);
if (callback) callback();
}
});
@@ -67,8 +46,10 @@ function useOssDetails({ target }: { target?: string }) {
);
useEffect(() => {
- reload();
- }, [reload]);
+ if (!userLoading) {
+ reload();
+ }
+ }, [reload, userLoading]);
return { schema, setSchema, reload, error, setError, loading };
}
diff --git a/rsconcept/frontend/src/hooks/useRSFormDetails.ts b/rsconcept/frontend/src/hooks/useRSFormDetails.ts
index dd2c532b..ce6025a9 100644
--- a/rsconcept/frontend/src/hooks/useRSFormDetails.ts
+++ b/rsconcept/frontend/src/hooks/useRSFormDetails.ts
@@ -4,12 +4,14 @@ import { useCallback, useEffect, useState } from 'react';
import { getRSFormDetails } from '@/app/backendAPI';
import { type ErrorData } from '@/components/info/InfoError';
+import { useAuth } from '@/context/AuthContext';
import { IRSForm, IRSFormData } from '@/models/rsform';
import { RSFormLoader } from '@/models/RSFormLoader';
function useRSFormDetails({ target, version }: { target?: string; version?: string }) {
+ const { loading: userLoading } = useAuth();
const [schema, setInnerSchema] = useState(undefined);
- const [loading, setLoading] = useState(false);
+ const [loading, setLoading] = useState(target != undefined);
const [error, setError] = useState(undefined);
function setSchema(data?: IRSFormData) {
@@ -44,8 +46,10 @@ function useRSFormDetails({ target, version }: { target?: string; version?: stri
);
useEffect(() => {
- reload();
- }, [reload]);
+ if (!userLoading) {
+ reload();
+ }
+ }, [reload, userLoading]);
return { schema, setSchema, reload, error, setError, loading };
}
diff --git a/rsconcept/frontend/src/hooks/useResolveText.ts b/rsconcept/frontend/src/hooks/useResolveText.ts
deleted file mode 100644
index 2926d330..00000000
--- a/rsconcept/frontend/src/hooks/useResolveText.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client';
-
-import { useCallback, useState } from 'react';
-
-import { DataCallback, postResolveText } from '@/app/backendAPI';
-import { ErrorData } from '@/components/info/InfoError';
-import { IResolutionData } from '@/models/language';
-import { IRSForm } from '@/models/rsform';
-
-function useResolveText({ schema }: { schema?: IRSForm }) {
- const [loading, setLoading] = useState(false);
- const [error, setError] = useState(undefined);
- const [refsData, setRefsData] = useState(undefined);
-
- const resetData = useCallback(() => setRefsData(undefined), []);
-
- function resolveText(text: string, onSuccess?: DataCallback) {
- setError(undefined);
- postResolveText(String(schema!.id), {
- data: { text: text },
- showError: true,
- setLoading,
- onError: setError,
- onSuccess: data => {
- setRefsData(data);
- if (onSuccess) onSuccess(data);
- }
- });
- }
-
- return { refsData, resolveText, resetData, error, setError, loading };
-}
-
-export default useResolveText;
diff --git a/rsconcept/frontend/src/models/language.ts b/rsconcept/frontend/src/models/language.ts
index d58063ea..f872aa86 100644
--- a/rsconcept/frontend/src/models/language.ts
+++ b/rsconcept/frontend/src/models/language.ts
@@ -291,12 +291,3 @@ export interface IResolvedReference extends IReference {
pos_input: ITextPosition;
pos_output: ITextPosition;
}
-
-/**
- * Represents resolved references data for the whole text.
- */
-export interface IResolutionData {
- input: string;
- output: string;
- refs: IResolvedReference[];
-}
diff --git a/rsconcept/frontend/src/models/miscellaneous.ts b/rsconcept/frontend/src/models/miscellaneous.ts
index 4ea90958..7cda6856 100644
--- a/rsconcept/frontend/src/models/miscellaneous.ts
+++ b/rsconcept/frontend/src/models/miscellaneous.ts
@@ -144,11 +144,10 @@ export interface ILibraryFilter {
type?: LibraryItemType;
query?: string;
+ folderMode?: boolean;
path?: string;
head?: LocationHead;
-
- folderMode?: boolean;
- folder?: string;
+ location?: string;
isVisible?: boolean;
isOwned?: boolean;
diff --git a/rsconcept/frontend/src/pages/CreateItemPage/FormCreateItem.tsx b/rsconcept/frontend/src/pages/CreateItemPage/FormCreateItem.tsx
index b5ab8e23..b5f909a8 100644
--- a/rsconcept/frontend/src/pages/CreateItemPage/FormCreateItem.tsx
+++ b/rsconcept/frontend/src/pages/CreateItemPage/FormCreateItem.tsx
@@ -10,7 +10,7 @@ import { IconDownload } from '@/components/Icons';
import InfoError from '@/components/info/InfoError';
import SelectAccessPolicy from '@/components/select/SelectAccessPolicy';
import SelectItemType from '@/components/select/SelectItemType';
-import SelectLocation from '@/components/select/SelectLocation';
+import SelectLocationContext from '@/components/select/SelectLocationContext';
import SelectLocationHead from '@/components/select/SelectLocationHead';
import Button from '@/components/ui/Button';
import Label from '@/components/ui/Label';
@@ -185,11 +185,7 @@ function FormCreateItem() {
excluded={!user?.is_staff ? [LocationHead.LIBRARY] : []}
/>
- {user?.is_staff ? (
-
-
-
- ) : null}
+
-
Разделы Портала
@@ -35,7 +34,6 @@ function HelpPortal() {
– данные
пользователя и смена пароля
-
Разделы Справки
{[
@@ -50,7 +48,6 @@ function HelpPortal() {
].map(topic => (
))}
-
Лицензирование и раскрытие информации
Пользователи Портала сохраняют авторские права на создаваемый ими контент
@@ -65,12 +62,15 @@ function HelpPortal() {
Данный сайт использует доменное имя и серверные мощности{' '}
-
Поддержка
Портал разрабатывается
+
+ Портал поддерживает актуальные версии браузеров Chrome, Firefox, Safari. Убедитесь, что используете последнюю
+ версию браузера в случае возникновения визуальных ошибок или проблем с производительностью.
+
Ваши пожелания по доработке, найденные ошибки и иные предложения можно направлять по email:{' '}
diff --git a/rsconcept/frontend/src/pages/ManualsPage/items/HelpTermGraph.tsx b/rsconcept/frontend/src/pages/ManualsPage/items/HelpTermGraph.tsx
index 3589d547..614f1e14 100644
--- a/rsconcept/frontend/src/pages/ManualsPage/items/HelpTermGraph.tsx
+++ b/rsconcept/frontend/src/pages/ManualsPage/items/HelpTermGraph.tsx
@@ -1,6 +1,6 @@
import Divider from '@/components/ui/Divider';
import LinkTopic from '@/components/ui/LinkTopic';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { HelpTopic } from '@/models/miscellaneous';
import {
@@ -68,7 +68,7 @@ function HelpTermGraph() {
-
+
Общие
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/EditorOssCard.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssCard/EditorOssCard.tsx
index 6933f56f..1df15a76 100644
--- a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/EditorOssCard.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssCard/EditorOssCard.tsx
@@ -7,11 +7,11 @@ import AnimateFade from '@/components/wrap/AnimateFade';
import { useAuth } from '@/context/AuthContext';
import { useOSS } from '@/context/OssContext';
import EditorLibraryItem from '@/pages/RSFormPage/EditorRSFormCard/EditorLibraryItem';
+import ToolbarRSFormCard from '@/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard';
import { globals } from '@/utils/constants';
import { useOssEdit } from '../OssEditContext';
import FormOSS from './FormOSS';
-import RSFormToolbar from './OssFormToolbar';
interface EditorOssCardProps {
isModified: boolean;
@@ -42,12 +42,13 @@ function EditorOssCard({ isModified, onDestroy, setIsModified }: EditorOssCardPr
return (
<>
-
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/FormOSS.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssCard/FormOSS.tsx
index babd8c69..591ebece 100644
--- a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/FormOSS.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssCard/FormOSS.tsx
@@ -10,7 +10,7 @@ import TextArea from '@/components/ui/TextArea';
import TextInput from '@/components/ui/TextInput';
import { useOSS } from '@/context/OssContext';
import { ILibraryUpdateData, LibraryItemType } from '@/models/library';
-import AccessToolbar from '@/pages/RSFormPage/EditorRSFormCard/AccessToolbar';
+import ToolbarItemAccess from '@/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess';
import { limits, patterns } from '@/utils/constants';
import { information } from '@/utils/labels';
@@ -108,7 +108,7 @@ function FormOSS({ id, isModified, setIsModified }: FormOSSProps) {
value={alias}
onChange={event => setAlias(event.target.value)}
/>
- setVisible(prev => !prev)}
readOnly={readOnly}
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/OssFormToolbar.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssCard/OssFormToolbar.tsx
deleted file mode 100644
index a076cffa..00000000
--- a/rsconcept/frontend/src/pages/OssPage/EditorOssCard/OssFormToolbar.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-'use client';
-
-import { useMemo } from 'react';
-
-import { SubscribeIcon } from '@/components/DomainIcons';
-import { IconDestroy, IconSave, IconShare } from '@/components/Icons';
-import BadgeHelp from '@/components/info/BadgeHelp';
-import MiniButton from '@/components/ui/MiniButton';
-import Overlay from '@/components/ui/Overlay';
-import { useAccessMode } from '@/context/AccessModeContext';
-import { HelpTopic } from '@/models/miscellaneous';
-import { UserLevel } from '@/models/user';
-import { PARAMETER } from '@/utils/constants';
-import { prepareTooltip } from '@/utils/labels';
-
-import { useOssEdit } from '../OssEditContext';
-
-interface RSFormToolbarProps {
- modified: boolean;
- subscribed: boolean;
- anonymous: boolean;
- onSubmit: () => void;
- onDestroy: () => void;
-}
-
-function RSFormToolbar({ modified, anonymous, subscribed, onSubmit, onDestroy }: RSFormToolbarProps) {
- const controller = useOssEdit();
- const { accessLevel } = useAccessMode();
- const canSave = useMemo(() => modified && !controller.isProcessing, [modified, controller.isProcessing]);
- return (
-
- {controller.isMutable || modified ? (
- }
- onClick={onSubmit}
- />
- ) : null}
- }
- onClick={controller.share}
- />
- {!anonymous ? (
- ${subscribed ? 'включено' : 'выключено'}`}
- icon={ }
- disabled={controller.isProcessing}
- onClick={controller.toggleSubscribe}
- />
- ) : null}
- {controller.isMutable ? (
- }
- disabled={!controller.isMutable || controller.isProcessing || accessLevel < UserLevel.OWNER}
- onClick={onDestroy}
- />
- ) : null}
-
-
- );
-}
-
-export default RSFormToolbar;
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/EditorOssGraph.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/EditorOssGraph.tsx
index eef62e28..8d17b729 100644
--- a/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/EditorOssGraph.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/EditorOssGraph.tsx
@@ -1,24 +1,21 @@
'use client';
-import { ReactFlowProvider } from '@reactflow/core';
+import { ReactFlowProvider } from 'reactflow';
-import SynthesisFlow from '@/components/ui/Synthesis/SynthesisFlow.tsx';
import AnimateFade from '@/components/wrap/AnimateFade';
-import { SynthesisState } from '@/pages/OssPage/SynthesisContext.tsx';
-import SynthesisToolbar from '@/pages/OssPage/SynthesisToolbar.tsx';
+
+import { useOssEdit } from '../OssEditContext';
+import OssFlow from './OssFlow';
function EditorOssGraph() {
- // TODO: Implement OSS editing UI here
+ const controller = useOssEdit();
return (
-
-
-
-
-
-
-
-
+
+
+
+
+
);
}
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/InputNode.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/InputNode.tsx
new file mode 100644
index 00000000..c0ea650a
--- /dev/null
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/InputNode.tsx
@@ -0,0 +1,58 @@
+import { CiSquareRemove } from 'react-icons/ci';
+import { PiPlugsConnected } from 'react-icons/pi';
+import { Handle, Position } from 'reactflow';
+
+import MiniButton from '@/components/ui/MiniButton.tsx';
+
+import { useOssEdit } from '../OssEditContext';
+
+interface InputNodeProps {
+ id: string;
+}
+
+function InputNode({ id }: InputNodeProps) {
+ const controller = useOssEdit();
+ console.log(controller.isMutable);
+
+ const handleDelete = () => {
+ console.log('delete node ' + id);
+ };
+
+ const handleClick = () => {
+ // controller.selectNode(id);
+ // controller.showSelectInput();
+ };
+
+ return (
+ <>
+
+
+
}
+ title='Удалить'
+ onClick={handleDelete}
+ color={'red'}
+ />
+
+ Тип: Ввод
+
+
+ {/* Схема:{controller.getBind(id) === undefined ? '' : controller.getBind(id)} */}
+
+ }
+ title='Привязать схему'
+ onClick={() => {
+ handleClick();
+ }}
+ />
+
+
+
+ >
+ );
+}
+
+export default InputNode;
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OperationNode.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OperationNode.tsx
new file mode 100644
index 00000000..34ff84fb
--- /dev/null
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OperationNode.tsx
@@ -0,0 +1,70 @@
+import { CiSquareRemove } from 'react-icons/ci';
+import { IoGitNetworkSharp } from 'react-icons/io5';
+import { VscDebugStart } from 'react-icons/vsc';
+import { Handle, Position } from 'reactflow';
+
+import MiniButton from '@/components/ui/MiniButton.tsx';
+
+import { useOssEdit } from '../OssEditContext';
+interface OperationNodeProps {
+ id: string;
+}
+
+function OperationNode({ id }: OperationNodeProps) {
+ const controller = useOssEdit();
+ console.log(controller.isMutable);
+
+ const handleDelete = () => {
+ console.log('delete node ' + id);
+ // onDelete(id);
+ };
+
+ const handleEditOperation = () => {
+ console.log('edit operation ' + id);
+ //controller.selectNode(id);
+ //controller.showSynthesis();
+ };
+
+ const handleRunOperation = () => {
+ console.log('run operation');
+ // controller.singleSynthesis(id);
+ };
+
+ return (
+ <>
+
+
+
}
+ title='Удалить'
+ onClick={handleDelete}
+ color={'red'}
+ />
+
+ Тип: Отождествление
+
+
+ Схема:
+ }
+ title='Синтез'
+ onClick={() => handleRunOperation()}
+ />
+ }
+ title='Отождествления'
+ onClick={() => handleEditOperation()}
+ />
+
+
+
+
+
+ >
+ );
+}
+
+export default OperationNode;
diff --git a/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OssFlow.tsx b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OssFlow.tsx
new file mode 100644
index 00000000..a3f7fe3f
--- /dev/null
+++ b/rsconcept/frontend/src/pages/OssPage/EditorOssGraph/OssFlow.tsx
@@ -0,0 +1,50 @@
+'use client';
+
+import { useMemo } from 'react';
+import { NodeTypes, ProOptions, ReactFlow } from 'reactflow';
+
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
+import { useOSS } from '@/context/OssContext';
+
+import { IOssEditContext } from '../OssEditContext';
+import InputNode from './InputNode';
+import OperationNode from './OperationNode';
+
+const OssNodeTypes: NodeTypes = {
+ synthesis: OperationNode,
+ input: InputNode
+};
+
+interface OssFlowProps {
+ controller: IOssEditContext;
+}
+
+function OssFlow({ controller }: OssFlowProps) {
+ const { calculateHeight } = useConceptOptions();
+ const model = useOSS();
+
+ console.log(model.loading);
+ console.log(controller.isMutable);
+
+ const initialNodes = [
+ { id: '1', position: { x: 0, y: 0 }, data: { label: '1' }, type: 'input' },
+ { id: '2', position: { x: 0, y: 100 }, data: { label: '2' }, type: 'synthesis' }
+ ];
+ const initialEdges = [{ id: 'e1-2', source: '1', target: '2' }];
+
+ const proOptions: ProOptions = { hideAttribution: true };
+
+ const canvasWidth = useMemo(() => {
+ return 'calc(100vw - 1rem)';
+ }, []);
+
+ const canvasHeight = useMemo(() => calculateHeight('1.75rem + 4px'), [calculateHeight]);
+
+ return (
+
+
+
+ );
+}
+
+export default OssFlow;
diff --git a/rsconcept/frontend/src/pages/OssPage/OssTabsMenu.tsx b/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
similarity index 98%
rename from rsconcept/frontend/src/pages/OssPage/OssTabsMenu.tsx
rename to rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
index ee385eb2..201dabef 100644
--- a/rsconcept/frontend/src/pages/OssPage/OssTabsMenu.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/MenuOssTabs.tsx
@@ -27,11 +27,11 @@ import { describeAccessMode, labelAccessMode } from '@/utils/labels';
import { useOssEdit } from './OssEditContext';
-interface OssTabsMenuProps {
+interface MenuOssTabsProps {
onDestroy: () => void;
}
-function OssTabsMenu({ onDestroy }: OssTabsMenuProps) {
+function MenuOssTabs({ onDestroy }: MenuOssTabsProps) {
const controller = useOssEdit();
const router = useConceptNavigation();
const { user } = useAuth();
@@ -200,4 +200,4 @@ function OssTabsMenu({ onDestroy }: OssTabsMenuProps) {
);
}
-export default OssTabsMenu;
+export default MenuOssTabs;
diff --git a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
index 2c13cafe..1b3317a3 100644
--- a/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/OssEditContext.tsx
@@ -6,7 +6,7 @@ import { toast } from 'react-toastify';
import { useAccessMode } from '@/context/AccessModeContext';
import { useAuth } from '@/context/AuthContext';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useOSS } from '@/context/OssContext';
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
import DlgEditEditors from '@/dialogs/DlgEditEditors';
@@ -15,7 +15,7 @@ import { IOperationSchema } from '@/models/oss';
import { UserID, UserLevel } from '@/models/user';
import { information } from '@/utils/labels';
-interface IOssEditContext {
+export interface IOssEditContext {
schema?: IOperationSchema;
isMutable: boolean;
diff --git a/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx b/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx
index 12cbc9da..fe920fb5 100644
--- a/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx
+++ b/rsconcept/frontend/src/pages/OssPage/OssTabs.tsx
@@ -12,17 +12,17 @@ import Loader from '@/components/ui/Loader';
import TabLabel from '@/components/ui/TabLabel';
import TextURL from '@/components/ui/TextURL';
import AnimateFade from '@/components/wrap/AnimateFade';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import { useBlockNavigation, useConceptNavigation } from '@/context/NavigationContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { useOSS } from '@/context/OssContext';
import useQueryStrings from '@/hooks/useQueryStrings';
import { information, prompts } from '@/utils/labels';
import EditorRSForm from './EditorOssCard';
import EditorTermGraph from './EditorOssGraph';
+import MenuOssTabs from './MenuOssTabs';
import { OssEditState } from './OssEditContext';
-import OssTabsMenu from './OssTabsMenu';
export enum OssTabID {
CARD = 0,
@@ -131,7 +131,7 @@ function OssTabs() {
className='flex flex-col mx-auto min-w-fit'
>
-
+
${schema.title ?? ''}`} />
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx
index 285ea3e8..45e83f7b 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta/EditorConstituenta.tsx
@@ -4,7 +4,7 @@ import clsx from 'clsx';
import { AnimatePresence } from 'framer-motion';
import { useMemo, useState } from 'react';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
import { ConstituentaID, IConstituenta } from '@/models/rsform';
@@ -12,8 +12,8 @@ import { globals, storage } from '@/utils/constants';
import { useRSEdit } from '../RSEditContext';
import ViewConstituents from '../ViewConstituents';
-import ConstituentaToolbar from './ConstituentaToolbar';
import FormConstituenta from './FormConstituenta';
+import ToolbarConstituenta from './ToolbarConstituenta';
// Threshold window width to switch layout.
const SIDELIST_LAYOUT_THRESHOLD = 1000; // px
@@ -81,7 +81,7 @@ function EditorConstituenta({ activeCst, isModified, setIsModified, onOpenEdit }
return (
{controller.isContentEditable ? (
-
void;
}
-function ConstituentaToolbar({
+function ToolbarConstituenta({
disabled,
modified,
showList,
@@ -45,7 +45,7 @@ function ConstituentaToolbar({
onClone,
onCreate,
onToggleList
-}: ConstituentaToolbarProps) {
+}: ToolbarConstituentaProps) {
return (
-
void;
}
-function ExpressionToolbar({ disabled, showControls, toggleControls, showAST }: ExpressionToolbarProps) {
+function ToolbarRSExpression({ disabled, showControls, toggleControls, showAST }: ToolbarRSExpressionProps) {
const model = useRSForm();
const { mathFont, setMathFont } = useConceptOptions();
@@ -45,4 +45,4 @@ function ExpressionToolbar({ disabled, showControls, toggleControls, showAST }:
);
}
-export default ExpressionToolbar;
+export default ToolbarRSExpression;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/EditorRSFormCard.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/EditorRSFormCard.tsx
index 479ec0d6..fb2f290b 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/EditorRSFormCard.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/EditorRSFormCard.tsx
@@ -12,7 +12,7 @@ import { useRSEdit } from '../RSEditContext';
import EditorLibraryItem from './EditorLibraryItem';
import FormRSForm from './FormRSForm';
import RSFormStats from './RSFormStats';
-import RSFormToolbar from './RSFormToolbar';
+import ToolbarRSFormCard from './ToolbarRSFormCard';
interface EditorRSFormCardProps {
isModified: boolean;
@@ -43,12 +43,13 @@ function EditorRSFormCard({ isModified, onDestroy, setIsModified }: EditorRSForm
return (
<>
-
setAlias(event.target.value)}
/>
-
-
+
setVisible(prev => !prev)}
readOnly={readOnly}
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/AccessToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess.tsx
similarity index 92%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/AccessToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess.tsx
index 79ab54a6..14f5c1bc 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/AccessToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarItemAccess.tsx
@@ -13,7 +13,7 @@ import { HelpTopic } from '@/models/miscellaneous';
import { UserLevel } from '@/models/user';
import { PARAMETER } from '@/utils/constants';
-interface AccessToolbarProps {
+interface ToolbarItemAccessProps {
visible: boolean;
toggleVisible: () => void;
readOnly: boolean;
@@ -21,7 +21,7 @@ interface AccessToolbarProps {
controller: ILibraryItemEditor;
}
-function AccessToolbar({ visible, toggleVisible, readOnly, toggleReadOnly, controller }: AccessToolbarProps) {
+function ToolbarItemAccess({ visible, toggleVisible, readOnly, toggleReadOnly, controller }: ToolbarItemAccessProps) {
const { accessLevel } = useAccessMode();
const policy = useMemo(
() => controller.schema?.access_policy ?? AccessPolicy.PRIVATE,
@@ -64,4 +64,4 @@ function AccessToolbar({ visible, toggleVisible, readOnly, toggleReadOnly, contr
);
}
-export default AccessToolbar;
+export default ToolbarItemAccess;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/RSFormToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard.tsx
similarity index 82%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/RSFormToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard.tsx
index 5dfb3147..7743cecd 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/RSFormToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard.tsx
@@ -8,29 +8,34 @@ import BadgeHelp from '@/components/info/BadgeHelp';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
import { useAccessMode } from '@/context/AccessModeContext';
-import { AccessPolicy } from '@/models/library';
+import { AccessPolicy, ILibraryItemEditor } from '@/models/library';
import { HelpTopic } from '@/models/miscellaneous';
import { UserLevel } from '@/models/user';
import { PARAMETER } from '@/utils/constants';
import { prepareTooltip, tooltips } from '@/utils/labels';
-import { useRSEdit } from '../RSEditContext';
-
-interface RSFormToolbarProps {
+interface ToolbarRSFormCardProps {
modified: boolean;
subscribed: boolean;
anonymous: boolean;
onSubmit: () => void;
onDestroy: () => void;
+ controller: ILibraryItemEditor;
}
-function RSFormToolbar({ modified, anonymous, subscribed, onSubmit, onDestroy }: RSFormToolbarProps) {
- const controller = useRSEdit();
+function ToolbarRSFormCard({
+ modified,
+ anonymous,
+ controller,
+ subscribed,
+ onSubmit,
+ onDestroy
+}: ToolbarRSFormCardProps) {
const { accessLevel } = useAccessMode();
const canSave = useMemo(() => modified && !controller.isProcessing, [modified, controller.isProcessing]);
return (
- {controller.isContentEditable || modified ? (
+ {controller.isMutable || modified ? (
}
- disabled={!controller.isContentEditable || controller.isProcessing || accessLevel < UserLevel.OWNER}
+ disabled={!controller.isMutable || controller.isProcessing || accessLevel < UserLevel.OWNER}
onClick={onDestroy}
/>
) : null}
@@ -65,4 +70,4 @@ function RSFormToolbar({ modified, anonymous, subscribed, onSubmit, onDestroy }:
);
}
-export default RSFormToolbar;
+export default ToolbarRSFormCard;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/VersionsToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx
similarity index 92%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/VersionsToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx
index 7f273de2..a0b23277 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/VersionsToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSFormCard/ToolbarVersioning.tsx
@@ -7,10 +7,10 @@ import { PARAMETER } from '@/utils/constants';
import { useRSEdit } from '../RSEditContext';
-function VersionsToolbar() {
+function ToolbarVersioning() {
const controller = useRSEdit();
return (
-
+
{controller.isMutable ? (
<>
void;
@@ -104,7 +104,7 @@ function EditorRSList({ onOpenEdit }: EditorRSListProps) {
return (
<>
- {controller.isContentEditable ? : null}
+ {controller.isContentEditable ? : null}
{controller.isContentEditable ? (
- ();
-function RSTable({ items, maxHeight, enableSelection, selected, setSelected, onEdit, onCreateNew }: RSTableProps) {
+function TableRSList({
+ items,
+ maxHeight,
+ enableSelection,
+ selected,
+ setSelected,
+ onEdit,
+ onCreateNew
+}: TableRSListProps) {
const { colors } = useConceptOptions();
const windowSize = useWindowSize();
@@ -147,4 +155,4 @@ function RSTable({ items, maxHeight, enableSelection, selected, setSelected, onE
);
}
-export default RSTable;
+export default TableRSList;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx
similarity index 98%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx
index c297995f..ecd6e787 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/RSListToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorRSList/ToolbarRSList.tsx
@@ -21,7 +21,7 @@ import { getCstTypeShortcut, labelCstType, prepareTooltip } from '@/utils/labels
import { useRSEdit } from '../RSEditContext';
-function RSListToolbar() {
+function ToolbarRSList() {
const controller = useRSEdit();
const insertMenu = useDropdown();
@@ -87,4 +87,4 @@ function RSListToolbar() {
);
}
-export default RSListToolbar;
+export default ToolbarRSList;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
index 92c339af..c6cfbf8b 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/EditorTermGraph.tsx
@@ -8,11 +8,11 @@ import { useDebounce } from 'use-debounce';
import InfoConstituenta from '@/components/info/InfoConstituenta';
import SelectedCounter from '@/components/info/SelectedCounter';
-import GraphSelectionToolbar from '@/components/select/GraphSelectionToolbar';
+import ToolbarGraphSelection from '@/components/select/ToolbarGraphSelection';
import { GraphCanvasRef, GraphEdge, GraphLayout, GraphNode } from '@/components/ui/GraphUI';
import Overlay from '@/components/ui/Overlay';
import AnimateFade from '@/components/wrap/AnimateFade';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import DlgGraphParams from '@/dialogs/DlgGraphParams';
import useLocalStorage from '@/hooks/useLocalStorage';
import { GraphColoring, GraphFilterParams, GraphSizing } from '@/models/miscellaneous';
@@ -24,10 +24,10 @@ import { PARAMETER, storage } from '@/utils/constants';
import { convertBase64ToBlob } from '@/utils/utils';
import { useRSEdit } from '../RSEditContext';
-import FocusToolbar from './FocusToolbar';
import GraphSelectors from './GraphSelectors';
-import GraphToolbar from './GraphToolbar';
import TermGraph from './TermGraph';
+import ToolbarFocusedCst from './ToolbarFocusedCst';
+import ToolbarTermGraph from './ToolbarTermGraph';
import useGraphFilter from './useGraphFilter';
import ViewHidden from './ViewHidden';
@@ -303,7 +303,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
position='top-0 pt-1 right-1/2 translate-x-1/2'
className='flex flex-col items-center rounded-b-2xl cc-blur'
>
-
{!focusCst ? (
- isBasicConcept(cst.cst_type)).map(cst => cst.id)}
setSelected={controller.setSelected}
@@ -331,7 +331,7 @@ function EditorTermGraph({ onOpenEdit }: EditorTermGraphProps) {
/>
) : null}
{focusCst ? (
- handleSetFocus(undefined)}
showInputs={filterParams.focusShowInputs}
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
index d8334c0a..e68b8dca 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/TermGraph.tsx
@@ -12,7 +12,7 @@ import GraphUI, {
GraphPointerEvent,
useSelection
} from '@/components/ui/GraphUI';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { ConstituentaID } from '@/models/rsform';
import { graphDarkT, graphLightT } from '@/styling/color';
import { PARAMETER, resources } from '@/utils/constants';
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/FocusToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarFocusedCst.tsx
similarity index 89%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/FocusToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarFocusedCst.tsx
index 38e017ba..ffd7642d 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/FocusToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarFocusedCst.tsx
@@ -4,12 +4,12 @@ import { useCallback } from 'react';
import { IconGraphInputs, IconGraphOutputs, IconReset } from '@/components/Icons';
import MiniButton from '@/components/ui/MiniButton';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { IConstituenta } from '@/models/rsform';
import { useRSEdit } from '../RSEditContext';
-interface FocusToolbarProps {
+interface ToolbarFocusedCstProps {
center: IConstituenta;
showInputs: boolean;
showOutputs: boolean;
@@ -19,14 +19,14 @@ interface FocusToolbarProps {
toggleShowOutputs: () => void;
}
-function FocusToolbar({
+function ToolbarFocusedCst({
center,
reset,
showInputs,
showOutputs,
toggleShowInputs,
toggleShowOutputs
-}: FocusToolbarProps) {
+}: ToolbarFocusedCstProps) {
const { colors } = useConceptOptions();
const controller = useRSEdit();
@@ -60,4 +60,4 @@ function FocusToolbar({
);
}
-export default FocusToolbar;
+export default ToolbarFocusedCst;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarTermGraph.tsx
similarity index 96%
rename from rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarTermGraph.tsx
index d3bbc7ac..b923d4d2 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/GraphToolbar.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ToolbarTermGraph.tsx
@@ -19,7 +19,7 @@ import { PARAMETER } from '@/utils/constants';
import { useRSEdit } from '../RSEditContext';
-interface GraphToolbarProps {
+interface ToolbarTermGraphProps {
is3D: boolean;
orbit: boolean;
@@ -37,7 +37,7 @@ interface GraphToolbarProps {
toggleOrbit: () => void;
}
-function GraphToolbar({
+function ToolbarTermGraph({
is3D,
noText,
foldDerived,
@@ -50,7 +50,7 @@ function GraphToolbar({
onDelete,
onResetViewpoint,
onSaveImage
-}: GraphToolbarProps) {
+}: ToolbarTermGraphProps) {
const controller = useRSEdit();
return (
@@ -123,4 +123,4 @@ function GraphToolbar({
);
}
-export default GraphToolbar;
+export default ToolbarTermGraph;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ViewHidden.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ViewHidden.tsx
index c3dd5cd0..e2d20b20 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ViewHidden.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorTermGraph/ViewHidden.tsx
@@ -5,11 +5,11 @@ import { motion } from 'framer-motion';
import { useCallback, useMemo } from 'react';
import { IconDropArrow, IconDropArrowUp } from '@/components/Icons';
-import ConstituentaTooltip from '@/components/info/ConstituentaTooltip';
+import TooltipConstituenta from '@/components/info/TooltipConstituenta';
import { CProps } from '@/components/props';
import MiniButton from '@/components/ui/MiniButton';
import Overlay from '@/components/ui/Overlay';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useLocalStorage from '@/hooks/useLocalStorage';
import useWindowSize from '@/hooks/useWindowSize';
import { GraphColoring } from '@/models/miscellaneous';
@@ -112,7 +112,7 @@ function ViewHidden({ items, selected, toggleSelection, setFocus, schema, colori
>
{cst.alias}
-
+
);
})}
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx b/rsconcept/frontend/src/pages/RSFormPage/MenuRSTabs.tsx
similarity index 99%
rename from rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx
rename to rsconcept/frontend/src/pages/RSFormPage/MenuRSTabs.tsx
index c6f02a65..1c349e62 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/RSTabsMenu.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/MenuRSTabs.tsx
@@ -38,11 +38,11 @@ import { describeAccessMode, labelAccessMode, tooltips } from '@/utils/labels';
import { useRSEdit } from './RSEditContext';
-interface RSTabsMenuProps {
+interface MenuRSTabsProps {
onDestroy: () => void;
}
-function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
+function MenuRSTabs({ onDestroy }: MenuRSTabsProps) {
const controller = useRSEdit();
const router = useConceptNavigation();
const { user } = useAuth();
@@ -334,4 +334,4 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
);
}
-export default RSTabsMenu;
+export default MenuRSTabs;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx
index f2671926..52c94614 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/RSEditContext.tsx
@@ -8,8 +8,8 @@ import { toast } from 'react-toastify';
import { urls } from '@/app/urls';
import { useAccessMode } from '@/context/AccessModeContext';
import { useAuth } from '@/context/AuthContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useConceptNavigation } from '@/context/NavigationContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { useRSForm } from '@/context/RSFormContext';
import DlgChangeLocation from '@/dialogs/DlgChangeLocation';
import DlgCloneLibraryItem from '@/dialogs/DlgCloneLibraryItem';
@@ -46,7 +46,7 @@ import { EXTEOR_TRS_FILE } from '@/utils/constants';
import { information, prompts } from '@/utils/labels';
import { promptUnsaved } from '@/utils/utils';
-interface IRSEditContext {
+export interface IRSEditContext {
schema?: IRSForm;
selected: ConstituentaID[];
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
index ee299aa0..0a04c0cb 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
@@ -13,9 +13,9 @@ import Loader from '@/components/ui/Loader';
import TabLabel from '@/components/ui/TabLabel';
import TextURL from '@/components/ui/TextURL';
import AnimateFade from '@/components/wrap/AnimateFade';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import { useLibrary } from '@/context/LibraryContext';
import { useBlockNavigation, useConceptNavigation } from '@/context/NavigationContext';
-import { useConceptOptions } from '@/context/OptionsContext';
import { useRSForm } from '@/context/RSFormContext';
import useQueryStrings from '@/hooks/useQueryStrings';
import { ConstituentaID, IConstituenta, IConstituentaMeta } from '@/models/rsform';
@@ -26,8 +26,8 @@ import EditorConstituenta from './EditorConstituenta';
import EditorRSForm from './EditorRSFormCard';
import EditorRSList from './EditorRSList';
import EditorTermGraph from './EditorTermGraph';
+import MenuRSTabs from './MenuRSTabs';
import { RSEditState } from './RSEditContext';
-import RSTabsMenu from './RSTabsMenu';
export enum RSTabID {
CARD = 0,
@@ -249,7 +249,7 @@ function RSTabs() {
className='flex flex-col mx-auto min-w-fit'
>
-
+
void;
@@ -22,7 +22,13 @@ interface ConstituentsTableProps {
const columnHelper = createColumnHelper();
-function ConstituentsTable({ items, activeCst, onOpenEdit, maxHeight, denseThreshold = 9999 }: ConstituentsTableProps) {
+function TableSideConstituents({
+ items,
+ activeCst,
+ onOpenEdit,
+ maxHeight,
+ denseThreshold = 9999
+}: TableSideConstituentsProps) {
const { colors } = useConceptOptions();
const windowSize = useWindowSize();
@@ -165,4 +171,4 @@ function ConstituentsTable({ items, activeCst, onOpenEdit, maxHeight, denseThres
);
}
-export default ConstituentsTable;
+export default TableSideConstituents;
diff --git a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx
index d844dd10..e5aca018 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/ViewConstituents/ViewConstituents.tsx
@@ -5,14 +5,14 @@ import { motion } from 'framer-motion';
import { useMemo, useState } from 'react';
import { useAccessMode } from '@/context/AccessModeContext';
-import { useConceptOptions } from '@/context/OptionsContext';
+import { useConceptOptions } from '@/context/ConceptOptionsContext';
import useWindowSize from '@/hooks/useWindowSize';
import { ConstituentaID, IConstituenta, IRSForm } from '@/models/rsform';
import { UserLevel } from '@/models/user';
import { animateSideView } from '@/styling/animations';
import ConstituentsSearch from './ConstituentsSearch';
-import ConstituentsTable from './ConstituentsTable';
+import TableSideConstituents from './TableSideConstituents';
// Window width cutoff for expression show
const COLUMN_EXPRESSION_HIDE_THRESHOLD = 1500;
@@ -37,7 +37,7 @@ function ViewConstituents({ expression, schema, activeCst, isBottom, onOpenEdit
const table = useMemo(
() => (
- ();
-function ViewSubscriptions({ items }: ViewSubscriptionsProps) {
+function TableSubscriptions({ items }: TableSubscriptionsProps) {
const router = useConceptNavigation();
const intl = useIntl();
@@ -82,4 +82,4 @@ function ViewSubscriptions({ items }: ViewSubscriptionsProps) {
);
}
-export default ViewSubscriptions;
+export default TableSubscriptions;
diff --git a/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx b/rsconcept/frontend/src/pages/UserProfilePage/UserContents.tsx
similarity index 89%
rename from rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx
rename to rsconcept/frontend/src/pages/UserProfilePage/UserContents.tsx
index f5357dea..a9185e09 100644
--- a/rsconcept/frontend/src/pages/UserProfilePage/UserTabs.tsx
+++ b/rsconcept/frontend/src/pages/UserProfilePage/UserContents.tsx
@@ -14,9 +14,9 @@ import { useUserProfile } from '@/context/UserProfileContext';
import EditorPassword from './EditorPassword';
import EditorProfile from './EditorProfile';
-import ViewSubscriptions from './ViewSubscriptions';
+import TableSubscriptions from './TableSubscriptions';
-function UserTabs() {
+function UserContents() {
const { user, error, loading } = useUserProfile();
const { user: auth } = useAuth();
const { items } = useLibrary();
@@ -50,11 +50,11 @@ function UserTabs() {
- {subscriptions.length > 0 && showSubs ? : null}
+ {subscriptions.length > 0 && showSubs ? : null}
);
}
-export default UserTabs;
+export default UserContents;
diff --git a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx
index 207e4e91..6f8f608e 100644
--- a/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx
+++ b/rsconcept/frontend/src/pages/UserProfilePage/UserProfilePage.tsx
@@ -1,13 +1,13 @@
import RequireAuth from '@/components/wrap/RequireAuth';
import { UserProfileState } from '@/context/UserProfileContext';
-import UserTabs from './UserTabs';
+import UserContents from './UserContents';
function UserProfilePage() {
return (
-
+
);
diff --git a/rsconcept/frontend/src/styling/imports.css b/rsconcept/frontend/src/styling/imports.css
index 89dda133..9bb8cf27 100644
--- a/rsconcept/frontend/src/styling/imports.css
+++ b/rsconcept/frontend/src/styling/imports.css
@@ -3,3 +3,4 @@
*/
@import 'react-toastify/dist/ReactToastify.css';
+@import 'reactflow/dist/style.css';
diff --git a/rsconcept/frontend/src/styling/overrides.css b/rsconcept/frontend/src/styling/overrides.css
index d4f24f21..8cc27759 100644
--- a/rsconcept/frontend/src/styling/overrides.css
+++ b/rsconcept/frontend/src/styling/overrides.css
@@ -33,3 +33,22 @@
color: var(--cd-fg-60);
}
}
+
+.Flow {
+ flex-grow: 1;
+ font-size: 12px;
+}
+
+.react-flow__node-input {
+ border: 1px solid #555;
+ padding: 10px;
+ width: 150px;
+ border-radius: 5px;
+}
+
+.react-flow__node-synthesis {
+ border: 1px solid #555;
+ padding: 10px;
+ width: 250px;
+ border-radius: 5px;
+}
diff --git a/rsconcept/frontend/src/utils/constants.ts b/rsconcept/frontend/src/utils/constants.ts
index 038531ca..f1c6870e 100644
--- a/rsconcept/frontend/src/utils/constants.ts
+++ b/rsconcept/frontend/src/utils/constants.ts
@@ -95,7 +95,7 @@ export const storage = {
librarySearchHead: 'library.search.head',
librarySearchFolderMode: 'library.search.folder_mode',
- librarySearchFolder: 'library.search.folder',
+ librarySearchLocation: 'library.search.location',
librarySearchVisible: 'library.search.visible',
librarySearchOwned: 'library.search.owned',
librarySearchSubscribed: 'library.search.subscribed',
diff --git a/rsconcept/frontend/tsconfig.json b/rsconcept/frontend/tsconfig.json
index a5ca6eb6..3ace1996 100644
--- a/rsconcept/frontend/tsconfig.json
+++ b/rsconcept/frontend/tsconfig.json
@@ -1,9 +1,9 @@
{
"compilerOptions": {
- "target": "es6",
+ "target": "ES2022",
"useDefineForClassFields": true,
- "lib": ["ES2020", "dom", "dom.iterable"],
- "module": "esnext",
+ "lib": ["ES2022", "dom", "dom.iterable"],
+ "module": "ES2022",
"skipLibCheck": true,
"esModuleInterop": true,
diff --git a/rsconcept/frontend/vite.config.ts b/rsconcept/frontend/vite.config.ts
index d75d350c..ef079cff 100644
--- a/rsconcept/frontend/vite.config.ts
+++ b/rsconcept/frontend/vite.config.ts
@@ -16,13 +16,11 @@ export default ({ mode }: { mode: string }) => {
...process.env,
...loadEnv(mode, process.cwd())
};
- const enableHttps = process.env.VITE_PORTAL_FRONT_HTTPS === 'true';
return defineConfig({
appType: 'spa',
plugins: [react(), muteWarningsPlugin(warningsToIgnore)],
server: {
- port: Number(process.env.VITE_PORTAL_FRONT_PORT),
- https: enableHttps
+ port: Number(process.env.VITE_PORTAL_FRONT_PORT)
},
publicDir: 'public',
build: {
diff --git a/scripts/dev/PopulateDevData.ps1 b/scripts/dev/PopulateDevData.ps1
index 6db22c8d..d217ad07 100644
--- a/scripts/dev/PopulateDevData.ps1
+++ b/scripts/dev/PopulateDevData.ps1
@@ -2,25 +2,14 @@
# FOR DEVELOPEMENT BUILDS ONLY!
$container= Read-Host -Prompt "Enter backend container name: "
-$backend = Resolve-Path -Path "$PSScriptRoot\..\..\rsconcept\backend"
-
function PopulateDevData() {
ImportInitialData
- CreateAdmin
}
function ImportInitialData() {
docker exec `
-it $container `
- python3.12 manage.py loaddata $backend\fixtures\InitialData.json
-}
-
-function CreateAdmin() {
- docker exec `
- -e DJANGO_SUPERUSER_USERNAME=admin `
- -e DJANGO_SUPERUSER_PASSWORD=1234 `
- -e DJANGO_SUPERUSER_EMAIL=admin@admin.com `
- -it $container python3.12 manage.py createsuperuser --noinput
+ python3.12 manage.py loaddata ./fixtures/InitialData.json
}
PopulateDevData
diff --git a/scripts/dev/RunServer.ps1 b/scripts/dev/RunServer.ps1
index 0484bb43..5b6559a4 100644
--- a/scripts/dev/RunServer.ps1
+++ b/scripts/dev/RunServer.ps1
@@ -25,7 +25,6 @@ function BackendRun() {
DoMigrations
PrepareStatic -clearPrevious
AddInitialData
- AddAdmin
} else {
DoMigrations
PrepareStatic
@@ -48,13 +47,15 @@ function FlushData {
}
function AddInitialData {
- & $pyExec manage.py loaddata $initialData
-}
-function AddAdmin {
- $env:DJANGO_SUPERUSER_USERNAME = 'admin'
- $env:DJANGO_SUPERUSER_PASSWORD = '1234'
- $env:DJANGO_SUPERUSER_EMAIL = 'admin@admin.com'
- & $pyExec $djangoSrc createsuperuser --noinput
+ if (Test-Path -Path $initialData -PathType Leaf) {
+ & $pyExec $djangoSrc flush --noinput
+ & $pyExec $djangoSrc loaddata $initialData
+ } else {
+ $env:DJANGO_SUPERUSER_USERNAME = 'admin'
+ $env:DJANGO_SUPERUSER_PASSWORD = '1234'
+ $env:DJANGO_SUPERUSER_EMAIL = 'admin@admin.com'
+ & $pyExec $djangoSrc createsuperuser --noinput
+ }
}
function DoMigrations {