This commit is contained in:
Alex Shevchuk
2025-08-18 17:12:04 +03:00
commit d84487d238
157 changed files with 160686 additions and 0 deletions

34
Dockerfile Normal file
View File

@@ -0,0 +1,34 @@
FROM golang:1.24-alpine AS builder
ARG BUILD_LDFLAGS
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download -x
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="${BUILD_LDFLAGS}" -trimpath -o main ./cmd/main.go
FROM alpine:3.18 AS certs
RUN wget -q "https://storage.yandexcloud.net/cloud-certs/CA.pem" -O /YandexInternalRootCA.crt \
&& chmod 0655 /YandexInternalRootCA.crt
FROM alpine:3.18
WORKDIR /
ARG CONFIG_FILE_PATH
RUN apk add --no-cache ca-certificates tzdata
COPY --from=certs /YandexInternalRootCA.crt /root/.redis/YandexInternalRootCA.crt
COPY --from=certs /YandexInternalRootCA.crt /root/.postgres/YandexInternalRootCA.crt
COPY ${CONFIG_FILE_PATH} /config.yaml
COPY --from=builder /app/main /main
RUN adduser -D -u 10001 appuser && chown appuser /main
USER appuser
ENTRYPOINT ["/main"]
CMD ["--config_path", "/config.yaml"]

82
Makefile Normal file
View File

@@ -0,0 +1,82 @@
BIN_DIR := $(CURDIR)/bin
APP_NAME ?= molva-app-backend
VERSION ?= $(shell git describe --tags 2>/dev/null || echo "v0.0.0")
BUILD_DATE := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ')
GIT_COMMIT := $(shell git rev-parse HEAD 2>/dev/null)
LDFLAGS := "-s -w -X main.version=$(VERSION) -X main.commit=$(GIT_COMMIT) -X main.date=$(BUILD_DATE)"
GOLANGCI_LINT_VERSION := v1.62.2
ENV := "local"
UNAME_S := $(shell uname -s)
CONFIG_PATH := .build/config/
ifeq ($(OS),Windows_NT)
CONFIG_PATH := $(subst /,\,$(CONFIG_PATH))
endif
.PHONY: all
all: lint build
## -- Dependency Management --
.PHONY: install-tools
install-tools: $(BIN_DIR)/golangci-lint
.PHONY: $(BIN_DIR)/golangci-lint
$(BIN_DIR)/golangci-lint:
@mkdir -p $(@D)
@echo "Installing golangci-lint $(GOLANGCI_LINT_VERSION)..."
@GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
## -- Linting --
.PHONY: lint
lint: $(BIN_DIR)/golangci-lint
@echo "Running linter..."
@$(BIN_DIR)/golangci-lint run --config .golangci-lint.yaml --fix=false --color=always
## -- Run --
## To change env use: make run CONFIG_PATH={config file dir path} ENV={env}
.PHONY: run
run:
@echo "Starting $(APP_NAME)..."
@echo CGO_ENABLED=0 go run -ldflags=$(LDFLAGS) ./cmd/main.go --config_path=$(CONFIG_PATH) --env=$(ENV)
@CGO_ENABLED=0 go run -ldflags=$(LDFLAGS) ./cmd/main.go --config_path=$(CONFIG_PATH) --env=$(ENV)
## -- Building --
.PHONY: build
build: build-linux build-darwin build-windows
# Build for Linux
.PHONY: build-linux
build-linux:
@echo "Building for Linux..."
@GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_linux_amd64 ./cmd/main.go
@GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_linux_arm64 ./cmd/main.go
# Build for macOS (Darwin)
.PHONY: build-darwin
build-darwin:
@echo "Building for macOS..."
@GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_darwin_amd64 ./cmd/main.go
@GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_darwin_arm64 ./cmd/main.go
# Build for Windows
.PHONY: build-windows
build-windows:
@echo "Building for Windows..."
@GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_windows_amd64.exe ./cmd/main.go
@GOOS=windows GOARCH=arm64 CGO_ENABLED=0 go build -ldflags=$(LDFLAGS) -o $(BIN_DIR)/$(APP_NAME)_windows_arm64.exe ./cmd/main.go
## -- Docker --
.PHONY: docker-build
docker-build:
@echo "Building Docker image..."
@docker build \
--build-arg BUILD_LDFLAGS=$(LDFLAGS) \
--build-arg CONFIG_FILE_PATH="$(CONFIG_PATH)$(ENV).yaml" \
-t $(APP_NAME):$(VERSION) \
.
## -- Cleanup --
.PHONY: clean
clean:
@echo "Cleaning..."
@rm -rf $(BIN_DIR)

169
README.md Normal file
View File

@@ -0,0 +1,169 @@
# Molva Backend
Backend сервис для платформы Molva, написанный на Go.
## Требования
- Go 1.24+
- Docker (опционально)
- Git
## Установка и настройка
### 1. Клонирование репозитория
```bash
git clone <repository-url>
cd molva-backend
```
### 2. Установка зависимостей
```bash
go mod download
```
### 3. Установка инструментов разработки
```bash
make install-tools
```
## Запуск проекта
### Локальная разработка
Для запуска в режиме разработки:
```bash
make run
```
По умолчанию проект запускается с конфигурацией:
- **Конфигурация**: `.build/config/`
- **Окружение**: `local`
### Изменение параметров запуска
Вы можете изменить параметры запуска:
```bash
# Изменение пути к конфигурации
make run CONFIG_PATH=...
# Изменение окружения
make run ENV=...
# Изменение обоих параметров
make run CONFIG_PATH=... ENV=...
```
### Сборка проекта
#### Сборка для всех платформ
```bash
make build
```
Эта команда создаст исполняемые файлы для:
- Linux (amd64, arm64)
- macOS (amd64, arm64)
- Windows (amd64, arm64)
Файлы будут сохранены в директории `bin/` с именами:
- `molva-app-backend_linux_amd64`
- `molva-app-backend_linux_arm64`
- `molva-app-backend_darwin_amd64`
- `molva-app-backend_darwin_arm64`
- `molva-app-backend_windows_amd64.exe`
- `molva-app-backend_windows_arm64.exe`
#### Сборка для конкретной платформы
```bash
# Только для Linux
make build-linux
# Только для macOS
make build-darwin
# Только для Windows
make build-windows
```
### Docker
Для сборки Docker образа:
```bash
make docker-build
```
Образ будет создан с тегом `molva-app-backend:$(VERSION)`, где `VERSION` - это git tag или "v0.0.0" по умолчанию.
## Разработка
### Проверка кода
Перед коммитом рекомендуется запустить линтер:
```bash
make lint
```
### Очистка
Для удаления скомпилированных файлов:
```bash
make clean
```
## Структура проекта
```
molva-backend/
├── bin/ # Скомпилированные файлы
├── cmd/
│ └── main.go # Точка входа приложения
├── internal/ # Внутренние пакеты
│ ├── auth/ # Аутентификация
│ ├── broker/ # Message broker
│ ├── cache/ # Кэширование
│ ├── config/ # Конфигурация
│ ├── database/ # Работа с БД
│ ├── feed/ # Лента
│ ├── file_manager/ # Управление файлами
│ ├── form_generator/ # Генератор форм
│ ├── http/ # HTTP handlers
│ ├── integration/ # Интеграции
│ ├── logger/ # Логирование
│ ├── notifications/ # Уведомления
│ ├── object_storage/ # Объектное хранилище
│ ├── request_model/ # Модели запросов
│ ├── services/ # Сервисы
│ ├── types/ # Типы данных
│ └── url_shortener/ # Сокращение URL
├── Dockerfile
├── go.mod
├── Makefile
└── README.md
```
## Конфигурация
Проект использует конфигурационные файлы в формате YAML. По умолчанию они находятся в директории `.build/config/`.
Структура конфигурации:
- `local.yaml` - для локальной разработки
- `staging.yaml` - для dev окружения
- `production.yaml` - для production окружения
## Переменные сборки
Приложение включает следующие переменные сборки:
- `version` - версия приложения (git tag)
- `commit` - хеш коммита
- `date` - дата сборки

5
build_push.sh Executable file
View File

@@ -0,0 +1,5 @@
echo "714dadb9-e8ad-468c-a77f-e98d86cd7393" | docker login -u "molvaapp" --password-stdin
IMAGE_NAME="molvaapp/api_gateway"
TAG="latest"
docker build -t $IMAGE_NAME:$TAG .
docker push $IMAGE_NAME:$TAG

126
cmd/main.go Normal file
View File

@@ -0,0 +1,126 @@
package main
import (
"context"
"fmt"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/logger"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/broker"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/config"
httprouter "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/http"
)
var (
version string
commit string
date string
)
func main() {
cfg := config.MustLoad(version, commit, date)
log, err := logger.New(cfg.Env)
if err != nil {
panic(err)
}
log.Info("Starting App", slog.String("version", version), slog.String("commit", commit), slog.String("build_date", date))
brok := setupBroker(log, &cfg.Broker)
defer func(brok *broker.RabbitMQBroker) {
if err := brok.Disconnect(); err != nil {
log.Error("Error disconnecting from broker")
}
}(brok)
server, err := setupServer(log, cfg)
if err != nil {
panic(fmt.Sprintf("can not start http server: %v", err))
}
serverErrors := make(chan error, 1)
go func() {
log.Info("starting server", slog.Int("port", cfg.Port))
serverErrors <- server.ListenAndServe()
}()
shutdownSignal := make(chan os.Signal, 1)
signal.Notify(shutdownSignal, os.Interrupt, syscall.SIGTERM)
select {
case err := <-serverErrors:
log.Error("Error starting server: %v\n", slog.Any("err", err))
case sig := <-shutdownSignal:
log.Info("received signal. shutting down server", slog.String("signal", sig.String()))
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
log.Info("shutting down server...")
if err := server.Shutdown(ctx); err != nil {
log.Error(fmt.Sprintf("Error shutting down server: %v\n", err))
}
log.Info("server gracefully stopped")
}
func setupServer(logger *slog.Logger, cfg *config.Config) (*http.Server, error) {
router, err := httprouter.New(logger, cfg)
if err != nil {
return nil, err
}
httprouter.SetupRouter(router, cfg.Build)
return &http.Server{
Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
Handler: router.Mux,
ReadHeaderTimeout: 15 * time.Second,
}, nil
}
func doWithRetry(function func() error, serviceName string, logger *slog.Logger) {
if err := function(); err != nil {
logger.Error(fmt.Sprintf("Error connecting to %s: %v", serviceName, err),
slog.String("error", err.Error()))
go func() {
ticker := time.NewTicker(constants.DefaultRetryTimeout)
defer ticker.Stop()
for range ticker.C {
if err := function(); err != nil {
logger.Error(fmt.Sprintf("Error connecting to %s: %v", serviceName, err),
slog.String("error", err.Error()))
} else {
logger.Info(fmt.Sprintf("Successfully connected to %s service", serviceName))
break
}
}
}()
} else {
logger.Info(fmt.Sprintf("Successfully connected to %s service", serviceName))
}
}
func setupBroker(logger *slog.Logger, cfg *config.Broker) *broker.RabbitMQBroker {
brok := broker.NewRabbitMQBroker(cfg)
doWithRetry(func() error {
return brok.Connect()
}, "Broker", logger)
return brok
}

View File

@@ -0,0 +1,53 @@
version: "3.9"
services:
molva-api-gateway:
image: molvaapp/api_gateway:${VERSION:-latest}
container_name: molva-api-gateway
restart: unless-stopped
ports:
- "8001:8000"
volumes:
- /opt/molva:/opt/molva
- /opt/molva/object_storage/credentials:/root/.aws/credentials:ro
- /opt/molva/object_storage/config:/root/.aws/config:ro
networks:
- molva
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/healthcheck"]
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 20s
window: 120s
update_config:
parallelism: 1
failure_action: rollback
monitor: 60s
max_failure_ratio: 0.3
order: start-first
rollback_config:
parallelism: 0
failure_action: continue
order: start-first
placement:
constraints:
- node.labels.env == stg
- node.labels.app == true
preferences:
- spread: node.labels.TZ
molva-notifications:
image: molvaapp/notification:latest
container_name: molva-notifications
restart: unless-stopped
volumes:
- /opt/molva:/opt/molva
networks:
- molva
networks:
molva:
external: true

62
go.mod Normal file
View File

@@ -0,0 +1,62 @@
module git-molva.ru/Molva/molva-backend/services/api_gateway
go 1.24
require (
github.com/AlexOreL-272/ProtoMolva v1.32.5
github.com/Masterminds/squirrel v1.5.4
github.com/Nerzal/gocloak/v13 v13.9.0
github.com/aws/aws-sdk-go-v2 v1.36.3
github.com/aws/aws-sdk-go-v2/config v1.29.14
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.4
github.com/aws/smithy-go v1.22.3
github.com/go-redis/redis/v7 v7.4.1
github.com/golang-jwt/jwt/v5 v5.2.3
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/ilyakaznacheev/cleanenv v1.5.0
github.com/jackc/pgx/v5 v5.7.5
github.com/jmoiron/sqlx v1.4.0
github.com/lib/pq v1.10.9
github.com/rabbitmq/amqp091-go v1.10.0
google.golang.org/protobuf v1.36.6
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/BurntSushi/toml v1.4.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/net v0.37.0 // indirect
golang.org/x/sync v0.13.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/text v0.24.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/grpc v1.71.0 // indirect
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
)

186
go.sum Normal file
View File

@@ -0,0 +1,186 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/AlexOreL-272/ProtoMolva v1.32.5 h1:mQybFqLmwlW7DpSppiRsID11m6t8GGOOkiuzWtsjyT0=
github.com/AlexOreL-272/ProtoMolva v1.32.5/go.mod h1:0lY7t+z3fhKs2ZxsdVvAePxAC4UdIRQT7LOejnJmb00=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Nerzal/gocloak/v13 v13.9.0 h1:YWsJsdM5b0yhM2Ba3MLydiOlujkBry4TtdzfIzSVZhw=
github.com/Nerzal/gocloak/v13 v13.9.0/go.mod h1:YYuDcXZ7K2zKECyVP7pPqjKxx2AzYSpKDj8d6GuyM10=
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14=
github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=
github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34 h1:ZNTqv4nIdE/DiBfUUfXcLZ/Spcuz+RjeziUtNJackkM=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2 h1:BCG7DCXEXpNCcpwCxg1oi9pkJWH2+eZzTn9MY56MbVw=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.2/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15 h1:moLQUoVq91LiqT1nbvzDukyqAlCv89ZmwaHw/ZFlFZg=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.4 h1:4yxno6bNHkekkfqG/a1nz/gC2gBwhJSojV1+oTE7K+4=
github.com/aws/aws-sdk-go-v2/service/s3 v1.79.4/go.mod h1:qbn305Je/IofWBJ4bJz/Q7pDEtnnoInw/dGt71v6rHE=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=
github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
github.com/aws/smithy-go v1.22.3 h1:Z//5NuZCSW6R4PhQ93hShNbyBbn8BWCmCVCt+Q8Io5k=
github.com/aws/smithy-go v1.22.3/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ=
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=

27
internal/auth/client.go Normal file
View File

@@ -0,0 +1,27 @@
package auth
import (
"context"
)
type Manager interface {
RegisterUser(ctx context.Context, request RegisterUserRequest) (*RegisterUserResponse, error)
LoginUser(ctx context.Context, request LoginUserRequest) (*LoginUserResponse, error)
LogoutUser(ctx context.Context, request LogoutUserRequest) error
GetNewAccessToken(ctx context.Context, request GetNewAccessTokenRequest) (*GetNewAccessTokenResponse, error)
GetUserEmailVerificationToken(ctx context.Context, uid string) (*GetUserTokenResponse, error)
CheckTokenIsValid(ctx context.Context, token string) (bool, error)
GetPermissionsByUsersId(ctx context.Context, id string) (*GetPermissionsByUsersIdResponse, error)
CheckPermissions(ctx context.Context, required CheckPermissionsRequest) (bool, error)
GetUserInfo(ctx context.Context, id string) (*UserInfo, error)
VerifyEmail(ctx context.Context, userID string, token string) error
GetEmailVerificationStatus(ctx context.Context, userID string) (*GetEmailVerificationResponse, error)
ResetPassword(ctx context.Context, request ResetPasswordRequest) error
}
type Config struct {
AuthServerAddr string
Realm string
ClientId string
ClientSecret string
}

104
internal/auth/domain.go Normal file
View File

@@ -0,0 +1,104 @@
package auth
type (
User struct {
Email string
Password string
FirstName string
SecondName string
Patronymic *string
Number string
Permissions map[string]string
}
RegisterUserRequest struct {
User User
UserType int32
}
RegisterUserResponse struct {
UserId string
}
)
type (
LoginUserRequest struct {
Email string
Password string
}
LoginUserResponse struct {
UserId string `json:"user_id"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
}
)
type (
GetUserTokenResponse struct {
AccessToken string `json:"access_token"`
}
)
type (
LogoutUserRequest struct {
RefreshToken string
}
)
type (
GetNewAccessTokenRequest struct {
RefreshToken string
}
GetNewAccessTokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
}
)
type (
UserInfoFromToken struct {
UserId string
}
)
type (
GetPermissionsByUsersIdResponse struct {
Balance string
Company string
Employees string
Profile string
Submissions string
Vacancies string
}
)
type (
CheckPermissionsRequest struct {
UserId string
RequiredPermission string
RequiredPermissionLevel string
}
)
type (
ResetPasswordRequest struct {
Email string
NewPassword string
}
)
type (
UserInfo struct {
Email string
FirstName string
SecondName string
Patronymic *string
Permissions map[string]string
UserType int32
}
)
type GetEmailVerificationResponse struct {
EmailVerified bool `json:"email_verified"`
}

View File

@@ -0,0 +1,390 @@
package keycloak
import (
"context"
"errors"
"time"
"github.com/golang-jwt/jwt/v5"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/auth"
"github.com/Nerzal/gocloak/v13"
)
func (k *Client) RegisterUser(ctx context.Context, request auth.RegisterUserRequest) (*auth.RegisterUserResponse, error) {
attrs := make(map[string][]string)
if request.User.Patronymic != nil {
attrs[PatronymicAttr] = []string{*request.User.Patronymic}
}
for key, value := range request.User.Permissions {
attrs[key] = []string{value}
}
for _, perm := range permissionsSlice {
if _, ok := attrs[perm]; !ok {
return nil, errors.Join(ErrBadRequest, ErrMissingPermission)
}
}
client, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return nil, k.handleError(err)
}
userGroup, err := k.getUserGroupByType(request.UserType)
if err != nil {
return nil, err
}
emailVerified := false
if k.env != "production" {
emailVerified = true
}
userId, err := k.client.CreateUser(
ctx,
client.AccessToken,
k.realm,
gocloak.User{
Email: gocloak.StringP(request.User.Email),
EmailVerified: &emailVerified,
FirstName: gocloak.StringP(request.User.FirstName),
LastName: gocloak.StringP(request.User.SecondName),
Groups: &[]string{userGroup},
Enabled: gocloak.BoolP(true),
Attributes: &attrs,
})
if err != nil {
return nil, k.handleError(err)
}
if err = k.client.SetPassword(
ctx, client.AccessToken,
userId, k.realm,
request.User.Password, false,
); err != nil {
return nil, k.handleError(err)
}
return &auth.RegisterUserResponse{
UserId: userId,
}, nil
}
func (k *Client) getUserGroupByType(userType int32) (string, error) {
switch userType {
case UserAgentType:
return UserGroupAgents, nil
case UserDistributorType:
return UserGroupDistributor, nil
default:
return "", ErrUnknownUserType
}
}
func (k *Client) LoginUser(ctx context.Context, request auth.LoginUserRequest) (*auth.LoginUserResponse, error) {
token, err := k.client.Login(ctx, k.clientId, k.clientSecret, k.realm, request.Email, request.Password)
if err != nil {
return nil, k.handleError(err)
}
userInfo, err := k.jwtManager.GetUserInfoFromToken(token.AccessToken)
if err != nil {
return nil, k.handleError(err)
}
return &auth.LoginUserResponse{
UserId: userInfo.UserId,
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
}, nil
}
func (k *Client) GetNewAccessToken(ctx context.Context, request auth.GetNewAccessTokenRequest) (*auth.GetNewAccessTokenResponse, error) {
token, err := k.client.RefreshToken(ctx, request.RefreshToken, k.clientId, k.clientSecret, k.realm)
if err != nil {
return nil, k.handleError(err)
}
return &auth.GetNewAccessTokenResponse{
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
}, nil
}
func (k *Client) CheckTokenIsValid(ctx context.Context, token string) (bool, error) {
resp, err := k.client.RetrospectToken(ctx, token, k.clientId, k.clientSecret, k.realm)
if err != nil {
return false, k.handleError(err)
}
if resp.Active == nil {
return false, nil
}
return *resp.Active, nil
}
func (k *Client) LogoutUser(ctx context.Context, request auth.LogoutUserRequest) error {
if err := k.client.Logout(ctx, k.clientId, k.clientSecret, k.realm, request.RefreshToken); err != nil {
return k.handleError(err)
}
if err := k.client.RevokeToken(ctx, k.realm, k.clientId, k.clientSecret, request.RefreshToken); err != nil {
return k.handleError(err)
}
return nil
}
func (k *Client) GetUserInfo(ctx context.Context, id string) (*auth.UserInfo, error) {
client, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return nil, k.handleError(err)
}
user, err := k.client.GetUserByID(ctx, client.AccessToken, k.realm, id)
if err != nil {
return nil, k.handleError(err)
}
if user.Attributes == nil {
return nil, ErrNoAttributes
}
groups, err := k.client.GetUserGroups(ctx, client.AccessToken, k.realm, id, gocloak.GetGroupsParams{})
if err != nil {
return nil, k.handleError(err)
}
if len(groups) == 0 {
return nil, ErrUnknownUserType
}
if groups[0].Name == nil {
return nil, ErrUnknownUserType
}
userType, err := k.getUserTypeByUserGroup(*groups[0].Name)
if err != nil {
return nil, err
}
return &auth.UserInfo{
Email: *user.Email,
FirstName: *user.FirstName,
SecondName: *user.LastName,
Patronymic: k.getUserPatronymicFromAttributes(*user.Attributes),
Permissions: k.getUserPermissionsFromAttributes(*user.Attributes),
UserType: userType,
}, nil
}
func (k *Client) getUserPatronymicFromAttributes(attr attributes) *string {
item, ok := attr[PatronymicAttr]
if !ok || len(item) == 0 {
return nil
}
return &item[0]
}
func (k *Client) getUserPermissionsFromAttributes(attr attributes) permissions {
resp := make(map[string]string)
for _, permission := range permissionsSlice {
if item, ok := attr[permission]; ok {
if len(item) != 0 {
resp[permission] = item[0]
} else {
resp[permission] = "" // todo: подумать над тем как правильно делать в таких ситуациях
}
} else {
resp[permission] = "" // todo: подумать над тем как правильно делать в таких ситуациях
}
}
return resp
}
func (k *Client) getUserTypeByUserGroup(attr string) (int32, error) {
switch attr {
case UserGroupAgents:
return UserAgentType, nil
case UserGroupDistributor:
return UserDistributorType, nil
default:
return -1, ErrUnknownUserType
}
}
func (k *Client) GetPermissionsByUsersId(ctx context.Context, id string) (*auth.GetPermissionsByUsersIdResponse, error) {
userInfo, err := k.GetUserInfo(ctx, id)
if err != nil {
return nil, err
}
return &auth.GetPermissionsByUsersIdResponse{
Balance: userInfo.Permissions[PermissionBalance],
Company: userInfo.Permissions[PermissionCompany],
Employees: userInfo.Permissions[PermissionEmployees],
Profile: userInfo.Permissions[PermissionProfile],
Submissions: userInfo.Permissions[PermissionSubmissions],
Vacancies: userInfo.Permissions[PermissionVacancies],
}, nil
}
func (k *Client) CheckPermissions(ctx context.Context, request auth.CheckPermissionsRequest) (bool, error) {
userInfo, err := k.GetUserInfo(ctx, request.UserId)
if err != nil {
return false, err
}
if userInfo.Permissions == nil {
return false, ErrInternal
}
if val, ok := userInfo.Permissions[request.RequiredPermission]; ok {
return k.getPermissionLevel(val) >= k.getPermissionLevel(request.RequiredPermissionLevel), nil
}
return false, ErrInternal
}
func (k *Client) getPermissionLevel(permission string) int8 {
switch permission {
case PermissionLevelCanEdit:
return 2
case PermissionLevelCanView:
return 1
case PermissionLevelNoPermission:
return 0
default:
return -1
}
}
func (k *Client) VerifyEmail(ctx context.Context, userID string, token string) error {
if err := k.jwtManager.VerifyEmailToken(token, userID); err != nil {
return err
}
// Get admin token
adminToken, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return k.handleError(err)
}
// Get user
user, err := k.client.GetUserByID(ctx, adminToken.AccessToken, k.realm, userID)
if err != nil {
return k.handleError(err)
}
// Set email as verified
user.EmailVerified = gocloak.BoolP(true)
// Update user
if err := k.client.UpdateUser(ctx, adminToken.AccessToken, k.realm, *user); err != nil {
return k.handleError(err)
}
return nil
}
func (k *Client) GetEmailVerificationStatus(ctx context.Context, userID string) (*auth.GetEmailVerificationResponse, error) {
// Get admin token
adminToken, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return nil, k.handleError(err)
}
// Get user
user, err := k.client.GetUserByID(ctx, adminToken.AccessToken, k.realm, userID)
if err != nil {
return nil, k.handleError(err)
}
// Check if email is verified
verified := false
if user.EmailVerified != nil {
verified = *user.EmailVerified
}
return &auth.GetEmailVerificationResponse{
EmailVerified: verified,
}, nil
}
func (k *Client) GetUserEmailVerificationToken(ctx context.Context, uid string) (*auth.GetUserTokenResponse, error) {
// Получение токена администратора
adminToken, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return nil, k.handleError(err)
}
// Получаем пользователя, чтобы убедиться в его существовании
_, err = k.client.GetUserByID(ctx, adminToken.AccessToken, k.realm, uid)
if err != nil {
return nil, k.handleError(err)
}
// Создаём кастомный JWT-токен для верификации email сроком на 24 часа
claims := jwt.MapClaims{
"sub": uid, // Subject (user ID)
"iat": time.Now().Unix(), // Issued at
"exp": time.Now().Add(24 * time.Hour).Unix(), // Expires in 24 hours
"purpose": "email_verification", // Custom claim to identify purpose
"iss": "molva-api-gateway", // Issuer
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Используем клиентский секрет как ключ подписи
signedToken, err := token.SignedString([]byte(k.clientSecret))
if err != nil {
return nil, ErrInternal
}
return &auth.GetUserTokenResponse{
AccessToken: signedToken,
}, nil
}
func (k *Client) ResetPassword(ctx context.Context, request auth.ResetPasswordRequest) error {
token, err := k.client.LoginClient(ctx, k.clientId, k.clientSecret, k.realm)
if err != nil {
return k.handleError(err)
}
user, err := k.client.GetUsers(
ctx,
token.AccessToken,
k.realm,
gocloak.GetUsersParams{
Username: gocloak.StringP(request.Email),
},
)
if err != nil {
return k.handleError(err)
}
if len(user) == 0 {
return ErrNotFound
}
if err := k.client.SetPassword(
ctx,
token.AccessToken,
*user[0].ID,
k.realm,
request.NewPassword,
false,
); err != nil {
return k.handleError(err)
}
return nil
}

View File

@@ -0,0 +1,15 @@
package keycloak
import (
"github.com/Nerzal/gocloak/v13"
)
type Client struct {
client *gocloak.GoCloak
jwtManager TokenManager
env string
realm string
clientId string
clientSecret string
}

View File

@@ -0,0 +1,38 @@
package keycloak
const (
PatronymicAttr = "patronymic"
PermissionLevelCanEdit = "can_edit"
PermissionLevelCanView = "can_view"
PermissionLevelNoPermission = "no_permission"
UserGroupAgents = "agents"
UserGroupDistributor = "distributors"
UserAgentType = 0
UserDistributorType = 1
PermissionBalance = "balance"
PermissionCompany = "company"
PermissionEmployees = "employees"
PermissionProfile = "profile"
PermissionSubmissions = "submissions"
PermissionVacancies = "vacancies"
)
var (
permissionsSlice = []string{
PermissionBalance,
PermissionCompany,
PermissionEmployees,
PermissionProfile,
PermissionSubmissions,
PermissionVacancies,
}
)
type (
attributes map[string][]string
permissions map[string]string
)

View File

@@ -0,0 +1,16 @@
package keycloak
import "errors"
var (
ErrInvalidToken = errors.New("invalid token")
ErrInternal = errors.New("internal error")
ErrRealmClientNotFound = errors.New("realm client not found")
ErrRealmClientUnauthorized = errors.New("realm client unauthorized")
ErrUnknownUserType = errors.New("unknown user type")
ErrNoAttributes = errors.New("no attributes")
ErrAlreadyExists = errors.New("user already exists")
ErrBadRequest = errors.New("bad request")
ErrNotFound = errors.New("user not found")
ErrMissingPermission = errors.New("missing one or more permissions")
)

View File

@@ -0,0 +1,51 @@
package keycloak
import (
"errors"
"net/http"
"github.com/Nerzal/gocloak/v13"
)
type Config struct {
Env string
AuthServerAddr string
Realm string
ClientId string
ClientSecret string
}
func New(c *Config) (*Client, error) {
cli := &Client{
client: gocloak.NewClient(c.AuthServerAddr),
jwtManager: NewJWTManager(),
env: c.Env,
realm: c.Realm,
clientId: c.ClientId,
clientSecret: c.ClientSecret,
}
return cli, nil
}
func (k *Client) handleError(err error) error {
var apiErr *gocloak.APIError
if !errors.As(err, &apiErr) {
return ErrInternal
}
switch apiErr.Code {
case http.StatusNotFound:
return ErrRealmClientNotFound
case http.StatusUnauthorized:
return ErrRealmClientUnauthorized
case http.StatusConflict:
return ErrAlreadyExists
case http.StatusBadRequest:
return ErrBadRequest
default:
return ErrInternal
}
}

View File

@@ -0,0 +1,76 @@
package keycloak
import (
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/auth"
"github.com/golang-jwt/jwt/v5"
"time"
)
type TokenManager interface {
GetUserInfoFromToken(token string) (*auth.UserInfoFromToken, error)
VerifyEmailToken(token string, expectedUserID string) error
}
type tokenManager struct {
parser *jwt.Parser
}
func NewJWTManager() TokenManager {
return &tokenManager{
parser: jwt.NewParser(),
}
}
func (t *tokenManager) GetUserInfoFromToken(token string) (*auth.UserInfoFromToken, error) {
userToken, _, err := t.parser.ParseUnverified(token, jwt.MapClaims{})
if err != nil {
return nil, ErrInvalidToken
}
if claims, ok := userToken.Claims.(jwt.MapClaims); ok {
resp := auth.UserInfoFromToken{}
resp.UserId, ok = claims["sub"].(string)
if !ok {
return nil, ErrInvalidToken
}
return &resp, nil
}
return nil, ErrInvalidToken
}
func (t *tokenManager) VerifyEmailToken(token string, expectedUserID string) error {
// Parse token without verification (we'll verify signature manually)
parsedToken, _, err := t.parser.ParseUnverified(token, jwt.MapClaims{})
if err != nil {
return ErrInvalidToken
}
// Extract claims
claims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok {
return ErrInvalidToken
}
// Check if token is for email verification
purpose, ok := claims["purpose"].(string)
if !ok || purpose != "email_verification" {
return ErrInvalidToken
}
// Check if subject matches expected user ID
sub, ok := claims["sub"].(string)
if !ok || sub != expectedUserID {
return ErrInvalidToken
}
// Check expiration
exp, ok := claims["exp"].(float64)
if !ok || float64(time.Now().Unix()) > exp {
return ErrInvalidToken
}
return nil
}

257
internal/broker/rmq.go Normal file
View File

@@ -0,0 +1,257 @@
package broker
import (
"context"
"errors"
"fmt"
"log/slog"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/config"
requestmodel "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/request_model"
"github.com/google/uuid"
amqp "github.com/rabbitmq/amqp091-go"
)
var conn *amqp.Connection
var (
NotificationQueue string
)
type Broker interface {
Connect() error
Disconnect() error
}
type RabbitMQBroker struct {
cfg *config.Broker
}
func NewRabbitMQBroker(cfg *config.Broker) *RabbitMQBroker {
NotificationQueue = cfg.NotificationsQueueName
return &RabbitMQBroker{
cfg: cfg,
}
}
func (r *RabbitMQBroker) Connect() error {
var err error
rabbitConn := fmt.Sprintf(
"amqp://%s:%s@%s:%d",
r.cfg.UserName,
r.cfg.Password,
r.cfg.Host,
r.cfg.Port,
)
conn, err = amqp.Dial(rabbitConn)
return err
}
func (r *RabbitMQBroker) Disconnect() error {
return conn.Close()
}
func produceMessage(qName, replyToQName, corrId string, message []byte, headers amqp.Table) (err error) {
ch, err := conn.Channel()
if err != nil {
return err
}
defer func(ch *amqp.Channel) {
if errClose := ch.Close(); errClose != nil {
err = errors.Join(err, errClose)
}
}(ch)
q, err := ch.QueueDeclare(
qName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), constants.DefaultContextTimeout)
defer cancel()
err = ch.PublishWithContext(ctx,
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
DeliveryMode: amqp.Persistent,
Type: headers["command"].(string),
ReplyTo: replyToQName,
CorrelationId: corrId,
Body: message,
Headers: headers,
},
)
if err != nil {
return err
}
return nil
}
func consumeMessage(qName string, corrId string) (resp []byte, err error) {
ch, err := conn.Channel()
if err != nil {
return nil, err
}
defer func(ch *amqp.Channel) {
if errClose := ch.Close(); errClose != nil {
err = errors.Join(err, errClose)
}
}(ch)
if _, err = ch.QueueDeclare(
qName, // name
true, // durable
true, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
); err != nil {
return nil, err
}
messages, err := ch.Consume(
qName, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
return nil, err
}
response := <-messages
//todo: Поправить на проверку correlationId
// if d.CorrelationId == corrId {
// return nil, fmt.Errorf("invalid correlation ID %s", d.CorrelationId)
// }
if err = response.Ack(false); err != nil {
return nil, err
}
return response.Body, nil
}
func ProcessRequest(qName, replyToQName, corrId string, headers amqp.Table, message []byte, log *slog.Logger) ([]byte, error) {
log.Info("produce request to: ",
slog.String("qName", qName),
slog.String("replyToQName", replyToQName),
slog.String("command", headers["command"].(string)),
slog.String("corrId", corrId),
)
if err := produceMessage(qName, replyToQName, corrId, message, headers); err != nil {
log.Error("got some error while producing message: ",
slog.String("error", err.Error()),
slog.String("corrId", corrId))
return nil, err
}
log.Info("consume response from: ",
slog.String("qName", qName),
slog.String("replyToQName", replyToQName),
slog.String("command", headers["command"].(string)),
slog.String("corrId", corrId),
)
body, err := consumeMessage(replyToQName, corrId)
if err != nil {
log.Error("got some error while consuming message: ",
slog.String("error", err.Error()),
slog.String("corrId", corrId))
return body, err
}
return body, nil
}
func BuildAndProcessRequest(qName string, headers requestmodel.Header, message []byte, log *slog.Logger) ([]byte, error) {
queueUuid := uuid.New().String()
resp, err := ProcessRequest(
qName,
queueUuid,
"0",
headers.ToTable(),
message,
log,
)
return resp, err
}
func SendNotification(qName, messageType string, message []byte, log *slog.Logger) error {
ch, err := conn.Channel()
if err != nil {
return err
}
defer func(ch *amqp.Channel) {
if errClose := ch.Close(); errClose != nil {
err = errors.Join(err, errClose)
}
}(ch)
q, err := ch.QueueDeclare(
qName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
log.Error("error while sending notification message",
slog.String("error", err.Error()),
slog.String("qName", qName))
return err
}
ctx, cancel := context.WithTimeout(context.Background(), constants.DefaultContextTimeout)
defer cancel()
err = ch.PublishWithContext(ctx,
"", // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
Type: messageType,
Body: message,
},
)
if err != nil {
log.Error("error while sending notification message",
slog.String("error", err.Error()),
slog.String("qName", qName))
return err
}
return nil
}

16
internal/cache/client.go vendored Normal file
View File

@@ -0,0 +1,16 @@
package cache
import "fmt"
func New(c Config, t Type) (Client, error) {
switch t {
case ValkeyCacheType:
return newValKeyCache(c)
default:
return nil, ErrUnknownCacheType
}
}
func getKey(k string, t ValueType) string {
return fmt.Sprintf("%s:%s", t, k)
}

16
internal/cache/errors.go vendored Normal file
View File

@@ -0,0 +1,16 @@
package cache
import "errors"
var (
ErrUnknownCacheType = errors.New("unknown cache type")
ErrInvalidConfig = errors.New("invalid config")
ErrConnect = errors.New("connecting to server")
ErrTlsConfig = errors.New("tls config")
ErrInvalidInstance = errors.New("check instance failed")
ErrKeyNotFound = errors.New("key not found")
ErrKeyExists = errors.New("key already exists")
ErrGet = errors.New("failed to get value")
ErrSet = errors.New("failed to set value")
ErrDel = errors.New("failed to delete value")
)

53
internal/cache/types.go vendored Normal file
View File

@@ -0,0 +1,53 @@
package cache
import (
"context"
"time"
)
type Client interface {
// Set добавляет в кеш под ключем key значение value
//
// Если такого ключа с таким типом значения нет,
// то возвращает ошибку ErrKeyExists
Set(ctx context.Context, key string, valueType ValueType, value any, expiration time.Duration) error
// Del удаляет значение по ключу key и указанному valueType
//
// Если такого ключа с таким типом значения нет,
// то возвращает ошибку ErrKeyNotFound
Del(ctx context.Context, key string, valueType ValueType) error
// Get возвращает значение по ключу key и valueType
//
// Если такого ключа с таким типом значения нет,
// то возвращает ошибку ErrKeyNotFound
//
// В случае, если получаемое значение не является строкой,
// необходимо воспользоваться соответсвующим методом под
// этот тип данных
Get(ctx context.Context, key string, valueType ValueType) (string, error)
// TODO: По необходимости расширить необходимыми методами
}
type (
Type uint
ValueType string
Config any
)
const (
ValkeyCacheType Type = iota
)
const (
LogoValueType ValueType = "value_logo_type"
DocumentsValueType ValueType = "value_documents_type"
PswResetOTPValueType ValueType = "value_otp_type"
PswResetTokenValueType ValueType = "value_token_type"
IntegrationCompanyValueType ValueType = "integration:company"
IntegrationVacancyValueType ValueType = "integration:vacancy"
)

143
internal/cache/valkey.go vendored Normal file
View File

@@ -0,0 +1,143 @@
package cache
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"os"
"time"
"github.com/go-redis/redis/v7"
)
type ValKeyCacheConfig struct {
Addrs []string
Password string
ReadOnly bool
DialTimeout time.Duration
PoolSize int
DefaultTTL time.Duration
RootCaFilePath string
}
type valkeyClient interface {
Set(key string, value any, expiration time.Duration) *redis.StatusCmd
Get(key string) *redis.StringCmd
Del(keys ...string) *redis.IntCmd
Exists(keys ...string) *redis.IntCmd
Ping() *redis.StatusCmd
}
type valKeyCache struct {
config ValKeyCacheConfig
client valkeyClient
}
func newValKeyCache(c Config) (*valKeyCache, error) {
cfg, ok := c.(ValKeyCacheConfig)
if !ok {
return nil, ErrInvalidConfig
}
caCert, err := os.ReadFile(cfg.RootCaFilePath)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrTlsConfig, err.Error())
}
caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
return nil, fmt.Errorf("%w: %s", ErrTlsConfig, "failed to append CA cert to pool")
}
tlsConfig := &tls.Config{
RootCAs: caCertPool,
MinVersion: tls.VersionTLS12,
}
client := redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: cfg.Addrs,
Password: cfg.Password,
ReadOnly: cfg.ReadOnly,
DialTimeout: cfg.DialTimeout,
PoolSize: cfg.PoolSize,
TLSConfig: tlsConfig,
})
if err := client.Ping().Err(); err != nil {
return nil, fmt.Errorf("%w: %v", ErrConnect, err)
}
return &valKeyCache{
config: cfg,
client: client,
}, nil
}
func (c *valKeyCache) Get(ctx context.Context, key string, valueType ValueType) (string, error) {
if err := c.checkInstance(); err != nil {
return "", fmt.Errorf("%w: %v", ErrGet, err)
}
val, err := c.client.Get(getKey(key, valueType)).Result()
if err == redis.Nil {
return "", ErrKeyNotFound
}
if err != nil {
return "", fmt.Errorf("%w: %v", ErrGet, err)
}
return val, nil
}
func (c *valKeyCache) Set(ctx context.Context, key string, valueType ValueType, value any, expiration time.Duration) error {
if err := c.checkInstance(); err != nil {
return fmt.Errorf("%w: %v", ErrSet, err)
}
key = getKey(key, valueType)
if exists, err := c.client.Exists(key).Result(); err != nil || exists == 1 {
if exists == 1 {
return ErrKeyExists
}
return fmt.Errorf("%w: %v", ErrSet, err)
}
if err := c.client.Set(key, value, expiration).Err(); err != nil {
return fmt.Errorf("%w: %v", ErrSet, err)
}
return nil
}
func (c *valKeyCache) Del(ctx context.Context, key string, valueType ValueType) error {
if err := c.checkInstance(); err != nil {
return fmt.Errorf("%w: %v", ErrDel, err.Error())
}
if res, err := c.client.Del(getKey(key, valueType)).Result(); err != nil || res == 0 {
if res == 0 {
return ErrKeyNotFound
}
return fmt.Errorf("%w: %s", ErrDel, err.Error())
}
return nil
}
func (c *valKeyCache) checkInstance() error {
if c == nil {
return ErrInvalidInstance
}
if s := c.client.Ping(); s.Err() != nil {
return fmt.Errorf("%w: %v", ErrInvalidInstance, s.Err().Error())
}
return nil
}

53
internal/config/config.go Normal file
View File

@@ -0,0 +1,53 @@
package config
import (
"errors"
"fmt"
"os"
"github.com/ilyakaznacheev/cleanenv"
)
var (
ErrInternal = errors.New("can not load config")
ErrMarshaling = errors.New("can not marshal config path")
)
func MustLoad(version, commit, date string) *Config {
cfg, err := loadConfig()
if err != nil {
panic(err)
}
cfg.Build.Version = version
cfg.Build.Commit = commit
cfg.Build.Date = date
return cfg
}
func loadConfig() (*Config, error) {
if _, err := os.Stat(ConfigBasePath); os.IsNotExist(err) {
return nil, fmt.Errorf("no config file found")
}
var localConfig LocalDeploy
if err := cleanenv.ReadConfig(ConfigBasePath, &localConfig); err != nil {
return nil, fmt.Errorf("error reading local config: %w", err)
}
for _, env := range localConfig.Deploy.Env {
if err := os.Setenv(env.Name, env.Value); err != nil {
return nil, fmt.Errorf("error setting env %s: %w", env.Name, err)
}
}
var cfg Config
if err := cleanenv.ReadConfig(ConfigBasePath, &cfg); err != nil {
return nil, err
}
return &cfg, nil
}

View File

@@ -0,0 +1,5 @@
package config
const (
ConfigBasePath = "/home/alexorel/work/Molva/molva-backend/.build/config/local.example.yaml"
)

View File

@@ -0,0 +1,99 @@
package config
import "time"
type (
Config struct {
Env string `yaml:"env" env-default:"production"`
Host string `yaml:"host" env-default:"localhost"`
Port int `yaml:"port" env-default:"8000"`
Keycloak Keycloak
Broker Broker `yaml:"broker"`
Secret SecretConfig
EmailVerificationService EmailVerificationService `yaml:"emailVerificationService"`
ValkeyCache ValkeyCacheConfig `yaml:"cache"`
S3Storage S3StorageConfig `yaml:"s3Storage"`
Database Database `yaml:"database"`
Integration Integration
Build BuildInfo
}
BuildInfo struct {
Version string
Commit string
Date string
}
ValkeyCacheConfig struct {
Addrs string `yaml:"-" env:"CACHE_ADDRS" env-default:"localhost:6379"`
Password string `yaml:"-" env:"CACHE_PASSWORD" env-default:""`
ReadOnly bool `yaml:"readOnly" env-default:"false"`
DialTimeout time.Duration `yaml:"dialTimeout" env-default:"5s"`
PoolSize int `yaml:"poolSize" env-default:"10"`
DefaultTTL time.Duration `yaml:"defaultTtl" env-default:"1h"`
RootCaFilePath string `yaml:"rootCaFilePath" env-default:""`
}
S3StorageConfig struct {
Bucket string `yaml:"bucket" env-default:""`
DefaultLinkTTL time.Duration `yaml:"defaultLinkTtl" env-default:"1h"`
}
SecretConfig struct {
Key string `env:"SHORTENER_SECRET_KEY"` // 32-byte key
}
Keycloak struct {
BaseURL string `env:"KEYCLOAK_BASE_URL" env-default:"http://localhost"`
Realm string `env:"KEYCLOAK_REALM" env-default:""`
ClientId string `env:"KEYCLOAK_CLIENT_ID" env-default:""`
ClientSecret string `env:"KEYCLOAK_CLIENT_SECRET" env-default:""`
}
Broker struct {
Host string `yaml:"-" env:"BROKER_HOST" env-default:"amqp://user:password@localhost"`
Port int `yaml:"-" env:"BROKER_PORT" env-default:"5672"`
UserName string `yaml:"-" env:"BROKER_USERNAME" env-default:"user"`
Password string `yaml:"-" env:"BROKER_PASSWORD" env-default:"password"`
NotificationsQueueName string `yaml:"notificationsQueueName" env-default:"notifications"`
}
// TODO: че с этим делать? Его нигде нет (ни на дев, ни на прод)
EmailVerificationService struct {
APIKey string `yaml:"-" env-default:""`
}
Database struct {
Host string `yaml:"-" env:"DB_HOSTS"`
Port uint16 `yaml:"-" env:"DB_PORT"`
Username string `yaml:"-" env:"DB_USERNAME"`
Password string `yaml:"-" env:"DB_PASSWORD"`
DBName string `yaml:"-" env:"DB_DBNAME"`
Schema string `yaml:"schema"`
SSLMode string `yaml:"sslmode" env-default:"verify-full"`
RootCaFilePath string `yaml:"rootCaFilePath" env-default:"/root/YandexInternalRootCA.crt"`
}
Integration struct {
Vkusvill VkusvillIntegration `yaml:"vkusvill"`
}
VkusvillIntegration struct {
ApiToken string `yaml:"-" env:"INTEGRATION_VKUSVILL_API_TOKEN"`
}
)
type (
LocalDeploy struct {
Deploy LocalDeployConfig `yaml:"deploy"`
}
LocalDeployConfig struct {
Env []LocalDeployConfigElement `yaml:"env"`
}
LocalDeployConfigElement struct {
Name string `yaml:"name"`
Value string `yaml:"value"`
}
)

View File

@@ -0,0 +1,17 @@
package constants
import "errors"
var (
ErrInternalServerError = errors.New("internal server error")
ErrBadRequest = errors.New("bad request")
ErrForbidden = errors.New("forbidden")
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrConflict = errors.New("conflict")
ErrRequestTimeout = errors.New("request timeout")
ErrNotImplemented = errors.New("not implemented")
ErrBadGateway = errors.New("bad gateway")
ErrServiceUnavailable = errors.New("service unavailable")
ErrIntOutOfRange = errors.New("value is out of range for int32")
)

View File

@@ -0,0 +1,11 @@
package constants
const (
FeedEventsTableName = "feed_events"
ClientTableName = "client"
SubmissionTableName = "submission"
)
const (
DefaultFeedFilterLimit = 20
)

View File

@@ -0,0 +1,182 @@
package constants
const (
EmailNotificationMessageType = "email"
RegistrationNotificationMessageSubject = "Регистрация пользователя в системе приложения Molva"
RegistrationNewUserAdmin = "Зарегистрирован новый пользователь приложения"
EmailVerificationMessageSubject = "Подтверждение адреса электронной почты"
TextNotificationContentType = "text/plain"
HTMLNotificationContentType = "text/html"
RegistrationNotificationText = `
Добро пожаловать в Molva!
Здравствуйте, %s!
Спасибо за регистрацию в Molva. Мы рады видеть вас в нашем сообществе.
Теперь вы можете:
- Получать персонализированные уведомления.
- Настраивать свои предпочтения.
- Использовать все возможности платформы.
Если у вас есть вопросы, не стесняйтесь обращаться в нашу службу поддержки!
После проверки аккаунта наш администратор с вами свяжется
С уважением, команда Molva.
Это письмо отправлено автоматически, пожалуйста, не отвечайте на него.
`
//nolint:gosec // there are no [potentially hardcoded] credentials in this message
ForgotPasswordNotificationMessageSubject = "Восстановление пароля в системе приложения Molva"
//nolint:gosec // there are no [potentially hardcoded] credentials in this message
ForgotPasswordNotificationText = `
Ваш код восстановления пароля: %s. Его можно использовать, чтобы сбросить пароль и зайти в свой аккаунт в Molva.
Если Вы не запрашивали восстановление доступа к аккаунту, пожалуйста, проигнорируйте это письмо.
С уважением, команда Molva.
`
)
const EmailVerificationTemplate = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin: 0; padding: 20px; font-family: Arial, sans-serif; background-color: #f5f5f5;">
<div style="max-width: 600px; margin: 0 auto; background-color: #ffffff; padding: 40px; border-radius: 8px;">
<h1 style="color: #333; font-size: 24px; margin: 0 0 30px 0;">MOLVA</h1>
<h2 style="color: #333; font-size: 20px; margin: 0 0 20px 0;">Подтвердите email</h2>
<p style="color: #555; font-size: 16px; line-height: 24px; margin: 0 0 10px 0;">
Здравствуйте, %s!
</p>
<p style="color: #555; font-size: 16px; line-height: 24px; margin: 0 0 30px 0;">
Для завершения регистрации подтвердите ваш email адрес.
</p>
<a href="%s" style="display: inline-block; padding: 12px 30px; background-color: #4A90E2; color: #ffffff; text-decoration: none; border-radius: 4px; font-size: 16px;">
Подтвердить email
</a>
<p style="color: #999; font-size: 14px; line-height: 20px; margin: 30px 0 10px 0;">
Или скопируйте ссылку:
</p>
<p style="color: #4A90E2; font-size: 14px; line-height: 20px; word-break: break-all; margin: 0 0 30px 0;">
%s
</p>
<p style="color: #999; font-size: 13px; line-height: 18px; margin: 0;">
Ссылка действительна 24 часа.
</p>
</div>
</body>
</html>`
const EmailConfirmationPage = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Подтверждение Email</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
background: #ffffff;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
text-align: center;
max-width: 400px;
width: 100%;
}
.title {
color: #333;
margin-bottom: 20px;
font-size: 22px;
}
.message {
color: #555;
font-size: 16px;
margin-bottom: 30px;
}
.close-note {
color: #777;
font-size: 14px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="title" id="status-title">Идёт подтверждение...</div>
<div class="message" id="status-message">Пожалуйста, подождите.</div>
<div class="close-note" id="close-note" style="display:none;">
Вы можете закрыть это окно.
</div>
</div>
<script>
(function() {
fetch("{{.VerificationURL}}", {
method: "PATCH",
headers: {
"Content-Type": "application/json"
}
})
.then(response => {
const titleEl = document.getElementById("status-title");
const msgEl = document.getElementById("status-message");
const closeEl = document.getElementById("close-note");
if (response.ok) {
titleEl.innerText = "Email успешно подтверждён!";
msgEl.innerText = "Спасибо за подтверждение. Теперь вы можете вернуться на сайт MOLVA!";
msgEl.style.color = "green";
} else if (response.status === 400 || response.status === 404) {
titleEl.innerText = "Неверная ссылка или токен";
msgEl.innerText = "Проверьте правильность ссылки или запросите новую.";
msgEl.style.color = "red";
} else {
titleEl.innerText = "Ошибка сервера";
msgEl.innerText = "Попробуйте повторить позднее.";
msgEl.style.color = "red";
}
closeEl.style.display = "block";
})
.catch(() => {
const titleEl = document.getElementById("status-title");
const msgEl = document.getElementById("status-message");
const closeEl = document.getElementById("close-note");
titleEl.innerText = "Не удалось подключиться";
msgEl.innerText = "Проверьте интернет-соединение и попробуйте снова.";
msgEl.style.color = "red";
closeEl.style.display = "block";
});
})();
</script>
</body>
</html>`
const EmailNewUserRegistrationAdminMessage = `
Зарегистрирован новый пользователь. Email подтверждён
Email: %s
Name: %s
Type: %s
`

View File

@@ -0,0 +1,38 @@
package constants
type PermissionType string
const (
Balance PermissionType = "balance"
Vacancies PermissionType = "vacancies"
Employees PermissionType = "employees"
Profile PermissionType = "profile"
Company PermissionType = "company"
Submissions PermissionType = "submissions"
)
func (p PermissionType) String() string {
return string(p)
}
type PermissionValue string
const (
NoPermission PermissionValue = "no_permission"
CanView PermissionValue = "can_view"
CanEdit PermissionValue = "can_edit"
)
func (p PermissionValue) String() string {
return string(p)
}
var PermissionLevels = map[PermissionValue]int{
NoPermission: 1,
CanView: 2,
CanEdit: 3,
}
var AllPermissions = []PermissionType{
Vacancies, Balance, Company, Submissions, Profile, Employees, Submissions,
}

27
internal/constants/s3.go Normal file
View File

@@ -0,0 +1,27 @@
package constants
import "time"
const (
LogoLinkTTL = 55 * time.Minute
LogoMaxSize = 10 << 20 // 10 MB
BytesToDetectContentType = 512
ParseMultipartFormAllFile = 0
TempDirPermission = 0750
TempLogoFilePattern = "logo-*.tmp"
)
const (
DefaultFileTTL = 30 * 24 * time.Hour //30 days
)
var ValidImageTypes = map[string]bool{
"image/png": true,
"image/jpeg": true,
"image/jpg": true,
"image/webp": true,
}
const (
RefreshLogoCacheAsyncTimeout = 10 * time.Second
)

View File

@@ -0,0 +1,31 @@
package constants
import "time"
const (
EmailVerificationServiceURL = "https://emailvalidation.abstractapi.com/v1/"
DocumentsPath = "/opt/molva/docs"
UserFilesBasePath = "/opt/molva/user_files"
DefaultRetryTimeout = time.Second * 10
DefaultContextTimeout = 30 * time.Second
DefaultPaginationPageSize = 20
DefaultPaginationPage = 1
)
const (
AdminNotificationEmail = "information@molva.io"
AdminNotificationId = 0
)
var AdminNotificationEmails = []string{AdminNotificationEmail}
const (
UserTypeAgentName = "Агент"
UserTypeDistributorName = "Дистрибьютор"
)
const (
DistributorClientType = 1
AgentClientType = 0
)

View File

@@ -0,0 +1,62 @@
package database
import (
"context"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
pgdb "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/postgres"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
)
type Client interface {
CreateUser(ctx context.Context, request *dbtypes.UserSaveRequest) (*dbtypes.UserSaveResponse, error)
GetClientValidation(ctx context.Context, request *dbtypes.ClientValidationGetRequest) (*dbtypes.ClientValidationGetResponse, error)
GetVacancyIntegrationInfoById(ctx context.Context, vacancyId string) (string, *dbtypes.VacancyExtraFieldsTemplate, error)
GetCompanyMetadataById(ctx context.Context, companyId string) (*dbtypes.CompanyMetadata, *dbtypes.CompanyExtraFieldsTemplate, error)
GetVacancyList(ctx context.Context, request *dbtypes.VacancyListGetRequest) (*dbtypes.VacancyListGetResponse, error)
CreateVacancy(ctx context.Context, request *dbtypes.VacancyCreateRequest) (*dbtypes.VacancyCreateResponse, error)
UpdateVacancy(ctx context.Context, request *dbtypes.VacancyUpdateRequest) (*dbtypes.VacancyUpdateResponse, error)
DeleteVacancy(ctx context.Context, request *dbtypes.VacancyDeleteRequest) (*dbtypes.VacancyDeleteResponse, error)
SendVacancyToModeration(ctx context.Context, request *dbtypes.SendVacancyToModerationRequest) (*dbtypes.SendVacancyToModerationResponse, error)
GetSubmissionList(ctx context.Context, request *dbtypes.SubmissionListGetRequest) (*dbtypes.SubmissionListGetResponse, error)
CreateSubmission(ctx context.Context, request *dbtypes.SubmissionCreateRequest) (*dbtypes.SubmissionCreateResponse, error)
UpdateSubmissionStatus(ctx context.Context, request *dbtypes.SubmissionStatusUpdateRequest) (*dbtypes.SubmissionStatusUpdateResponse, error)
DeleteSubmission(ctx context.Context, request *dbtypes.SubmissionDeleteRequest) (*dbtypes.SubmissionDeleteResponse, error)
GetCompanyList(ctx context.Context, request *dbtypes.CompanyListGetRequest) (*dbtypes.CompanyListGetResponse, error)
GetCompanyById(ctx context.Context, request *dbtypes.CompanyByIdGetRequest) (*dbtypes.CompanyByIdGetResponse, error)
CreateCompany(ctx context.Context, request *dbtypes.CompanyCreateRequest) (*dbtypes.CompanyCreateResponse, error)
UpdateCompany(ctx context.Context, request *dbtypes.CompanyUpdateRequest) (*dbtypes.CompanyUpdateResponse, error)
// DeleteDistributorCompany(ctx context.Context, request *dbtypes.DistributorCompanyDeleteRequest) (*dbtypes.DistributorCompanyDeleteResponse, error)
GetProfileById(ctx context.Context, request *dbtypes.ProfileGetRequest) (*dbtypes.ProfileGetResponse, error)
UpdateProfile(ctx context.Context, request *dbtypes.ProfileUpdateRequest) (*dbtypes.ProfileUpdateResponse, error)
GetBalance(ctx context.Context, request *dbtypes.BalanceGetRequest) (*dbtypes.BalanceGetResponse, error)
GetTransactionList(ctx context.Context, request *dbtypes.TransactionListGetRequest) (*dbtypes.TransactionListGetResponse, error)
CreateTransaction(ctx context.Context, request *dbtypes.TransactionCreateRequest) (*dbtypes.TransactionCreateResponse, error)
GetBankAccountList(ctx context.Context, request *dbtypes.BankAccountListGetRequest) (*dbtypes.BankAccountListGetResponse, error)
CreateBankAccount(ctx context.Context, request *dbtypes.BankAccountCreateRequest) (*dbtypes.BankAccountCreateResponse, error)
UpdateBankAccount(ctx context.Context, request *dbtypes.BankAccountUpdateRequest) (*dbtypes.BankAccountUpdateResponse, error)
DeleteBankAccount(ctx context.Context, request *dbtypes.BankAccountDeleteRequest) (*dbtypes.BankAccountDeleteResponse, error)
}
func New(cType ClientType, c Config) (Client, error) {
switch cType {
case PostgresClientType:
cfg, ok := c.(pgdb.PostgresConfig)
if !ok {
return nil, dberrors.ErrInvalidConfig
}
return pgdb.NewClient(cfg)
default:
return nil, dberrors.ErrClientType
}
}

View File

@@ -0,0 +1,10 @@
package database
type (
ClientType int
Config any
)
const (
PostgresClientType ClientType = iota
)

View File

@@ -0,0 +1,16 @@
package dberrors
import "errors"
var (
ErrClientType = errors.New("invalid client type")
ErrInvalidConfig = errors.New("invalid config")
ErrUnimplemented = errors.New("unimplemented")
ErrBadRequest = errors.New("bad request")
ErrForbidden = errors.New("forbidden")
ErrNotFound = errors.New("not found")
ErrConflict = errors.New("conflict")
ErrInternal = errors.New("internal")
)

View File

@@ -0,0 +1,100 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
)
func (c *client) GetBalance(
ctx context.Context,
request *dbtypes.BalanceGetRequest,
) (*dbtypes.BalanceGetResponse, error) {
if request == nil {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
balancesTable = fmt.Sprintf("%s.%s", c.config.Schema, BalancesTableName)
)
getBalance := psql.Select(
"raw_balance", "clean_balance",
).From(balancesTable).
Where(squirrel.Eq{"owner_id": request.OwnerId})
query, args, err := getBalance.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get balance query: %v", dberrors.ErrInternal, err)
}
row := c.db.QueryRowContext(ctx, query, args...)
var (
balance dbtypes.Balance
)
if err := row.Scan(&balance.RawBalance, &balance.CleanBalance); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
return &dbtypes.BalanceGetResponse{
Balance: &balance,
}, nil
}
func (c *client) createBalance(
ctx context.Context,
driver Driver,
request *dbtypes.BalanceCreateRequest,
) error {
if request == nil {
return fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
balancesTable = fmt.Sprintf("%s.%s", c.config.Schema, BalancesTableName)
)
createBalance := psql.Insert(balancesTable).
Columns(
"id", "owner_id", "raw_balance", "clean_balance",
).
Values(
request.Id, request.OwnerId, request.RawBalance, request.CleanBalance,
)
query, args, err := createBalance.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'create balance' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'create balance' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'create balance' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}

View File

@@ -0,0 +1,313 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
)
// ALERT: intergrate safety checks
func (c *client) GetBankAccountList(
ctx context.Context,
request *dbtypes.BankAccountListGetRequest,
) (*dbtypes.BankAccountListGetResponse, error) {
if request == nil {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
bankAccountsTable = fmt.Sprintf("%s.%s", c.config.Schema, BankAccountsTableName)
)
getAccounts := psql.Select(
"id", "owner_id", "account_number", "bank_name", "bik",
"correspondent_account", "is_primary", "created_at", "updated_at",
).From(bankAccountsTable).
Where(squirrel.Eq{"owner_id": request.OwnerId})
query, args, err := getAccounts.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get bank accounts query: %v", dberrors.ErrInternal, err)
}
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing get bank accounts query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
var accounts []dbtypes.BankAccount
for rows.Next() {
var (
accountNumber, bankName, bik, correspondentAccount sql.NullString
bankAccount dbtypes.BankAccount
)
if err := rows.Scan(
&bankAccount.Id, &bankAccount.OwnerId, &accountNumber, &bankName, &bik,
&correspondentAccount, &bankAccount.IsPrimary, &bankAccount.CreatedAt, &bankAccount.UpdatedAt,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if accountNumber.Valid {
bankAccount.AccountName = accountNumber.String
}
if bankName.Valid {
bankAccount.BankName = bankName.String
}
if bik.Valid {
bankAccount.Bik = bik.String
}
if correspondentAccount.Valid {
bankAccount.CorrespondentAccount = correspondentAccount.String
}
accounts = append(accounts, bankAccount)
}
return &dbtypes.BankAccountListGetResponse{
BankAccounts: accounts,
}, nil
}
func (c *client) CreateBankAccount(
ctx context.Context,
request *dbtypes.BankAccountCreateRequest,
) (*dbtypes.BankAccountCreateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
bankAccountsTable = fmt.Sprintf("%s.%s", c.config.Schema, BankAccountsTableName)
)
// TODO: use normal uuid after DB reengineering
bankAccountId := fmt.Sprintf("%sBNK", strings.ReplaceAll(uuid.NewString(), "-", ""))
createBankAccount := psql.Insert(bankAccountsTable).
Columns(
"id", "owner_id", "account_number", "bank_name", "bik", "correspondent_account", "is_primary",
).
Values(
bankAccountId, request.OwnerId, request.AccountNumber, request.BankName,
request.Bik, request.CorrespondentAccount, request.IsPrimary,
)
query, args, err := createBankAccount.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building create bank account query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing create bank account query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for create bank account query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.BankAccountCreateResponse{
Id: bankAccountId,
}, nil
}
func (c *client) UpdateBankAccount(
ctx context.Context,
request *dbtypes.BankAccountUpdateRequest,
) (*dbtypes.BankAccountUpdateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
result, err := c.updateBankAccount(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error updating bank account: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err)
}
return result, nil
}
func (c *client) updateBankAccount(
ctx context.Context,
driver Driver,
request *dbtypes.BankAccountUpdateRequest,
) (*dbtypes.BankAccountUpdateResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
bankAccountsTable = fmt.Sprintf("%s.%s", c.config.Schema, BankAccountsTableName)
)
updateAccount := psql.Update(bankAccountsTable).
Where(squirrel.Eq{"id": request.Id})
if request.AccountNumber != nil {
updateAccount = updateAccount.Set("account_number", *request.AccountNumber)
}
// TODO: uncomment when DB supports it
// if request.AccountName != nil {
// updateAccount = updateAccount.Set("account_name", *request.AccountName)
// }
if request.BankName != nil {
updateAccount = updateAccount.Set("bank_name", *request.BankName)
}
if request.Bik != nil {
updateAccount = updateAccount.Set("bik", *request.Bik)
}
if request.CorrespondentAccount != nil {
updateAccount = updateAccount.Set("correspondent_account", *request.CorrespondentAccount)
}
if request.IsPrimary != nil {
if *request.IsPrimary {
if err := c.unmarkPrimaryBankAccount(ctx, driver, request.Id); err != nil {
return nil, fmt.Errorf("error unmarking currently primary bank account: %w", err)
}
}
// QnA: what if the update makes all BAs non-primary?
updateAccount = updateAccount.Set("is_primary", *request.IsPrimary)
}
query, args, err := updateAccount.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'update bank account' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'update bank account' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'update bank account' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.BankAccountUpdateResponse{}, nil
}
func (c *client) unmarkPrimaryBankAccount(
ctx context.Context,
driver Driver,
bankAccountId string,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
bankAccountsTable = fmt.Sprintf("%s.%s", c.config.Schema, BankAccountsTableName)
)
getOwnerId := psql.Select(
"owner_id", "is_primary",
).From(bankAccountsTable).
Where(squirrel.Eq{"id": bankAccountId}).
Suffix("FOR UPDATE")
query, args, err := getOwnerId.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'get owner id of bank account' query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var (
ownerId string
isPrimary bool
)
if err := row.Scan(&ownerId, &isPrimary); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return dberrors.ErrNotFound
}
return fmt.Errorf("%w: error scanning row for 'get owner id of bank account' query: %v", dberrors.ErrInternal, err)
}
if isPrimary {
return nil
}
unmarkPrimaryBA := psql.Update(bankAccountsTable).
Set("is_primary", false).
Where(squirrel.Eq{
"owner_id": ownerId,
"is_primary": true,
})
query, args, err = unmarkPrimaryBA.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'unmark primary bank account' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'unmark primary bank account' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'unmark primary bank account' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return fmt.Errorf("%w: error unmarking primary bank account: no rows affected", dberrors.ErrInternal)
}
return nil
}
func (c *client) DeleteBankAccount(
ctx context.Context,
request *dbtypes.BankAccountDeleteRequest,
) (*dbtypes.BankAccountDeleteResponse, error) {
return nil, dberrors.ErrUnimplemented
}

View File

@@ -0,0 +1,107 @@
package pgdb
import (
"context"
"crypto/tls"
"crypto/x509"
"database/sql"
"fmt"
"os"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/stdlib"
"github.com/jmoiron/sqlx"
)
// Интерфейс передается в неэкспортируемые функции
// нужен для того, чтобы не зависило от того, что передаём
// транзацию или обычное соединение
type Driver interface {
// QueryContext executes a query that returns rows, typically a SELECT.
// The args are for any placeholder parameters in the query.
QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
// QueryRowContext executes a query that is expected to return at most one row.
// QueryRowContext always returns a non-nil value. Errors are deferred until
// [Row]'s Scan method is called.
// If the query selects no rows, the [*Row.Scan] will return [ErrNoRows].
// Otherwise, [*Row.Scan] scans the first selected row and discards
// the rest.
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
// ExecContext executes a query without returning any rows.
// The args are for any placeholder parameters in the query.
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}
type PostgresConfig struct {
Host string
Port uint16
Username string
Password string
Database string
Schema string
SSLMode string
SSLRootCert string
}
type client struct {
config PostgresConfig
db *sqlx.DB
}
func NewClient(cfg PostgresConfig) (*client, error) {
rootCertPool := x509.NewCertPool()
caCert, err := os.ReadFile(cfg.SSLRootCert)
if err != nil {
return nil, fmt.Errorf("failed to read CA cert: %w", err)
}
if ok := rootCertPool.AppendCertsFromPEM(caCert); !ok {
return nil, fmt.Errorf("failed to append CA cert to pool")
}
tlsConfig := &tls.Config{
RootCAs: rootCertPool,
MinVersion: tls.VersionTLS12,
//nolint:gosec // TODO: set server name
InsecureSkipVerify: true,
}
config, err := pgx.ParseConfig("")
if err != nil {
return nil, fmt.Errorf("failed to parse [empty] config: %w", err)
}
config.Host = cfg.Host
config.Port = cfg.Port
config.Database = cfg.Database
config.User = cfg.Username
config.Password = cfg.Password
config.TLSConfig = tlsConfig
config.RuntimeParams = map[string]string{"sslmode": cfg.SSLMode}
db := sqlx.NewDb(stdlib.OpenDB(*config), "pgx")
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("failed to ping postgres: %w", err)
}
return &client{
config: cfg,
db: db,
}, nil
}
func countOffset(page, pageSize uint64) uint64 {
if page == 0 {
page = 1
}
if pageSize == 0 {
pageSize = DefaultPaginationPageSize
}
return (page - 1) * pageSize
}

View File

@@ -0,0 +1,506 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
"github.com/lib/pq"
)
func CompanyModerationStatusIdToString(status int32) dbtypes.CompanyModerationStatus {
switch status {
case 0:
return dbtypes.CompanyModerationStatusPending
case 1:
return dbtypes.CompanyModerationStatusApproved
case 2:
return dbtypes.CompanyModerationStatusRejected
case 3:
return dbtypes.CompanyModerationStatusNew
default:
return dbtypes.CompanyModerationStatusNew
}
}
func CompanyModerationStatusStringToId(status dbtypes.CompanyModerationStatus) int32 {
switch status {
case dbtypes.CompanyModerationStatusPending:
return 0
case dbtypes.CompanyModerationStatusApproved:
return 1
case dbtypes.CompanyModerationStatusRejected:
return 2
case dbtypes.CompanyModerationStatusNew:
return 3
default:
return 3
}
}
//nolint:gocognit // TODO: refactor
func (c *client) GetCompanyList(
ctx context.Context,
request *dbtypes.CompanyListGetRequest,
) (*dbtypes.CompanyListGetResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
companiesTable = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
getComList := psql.Select(
"id", "uid", "name", "legal_person", "description", "website",
"physical_address", "legal_address", "inn", "is_active", // TODO: add KPP when DB supports it
"has_moderation_ticket", "staff", "metadata", "additional_fields_tmpl",
).
From(companiesTable).
Where(squirrel.Eq{"uid": request.Id})
query, args, err := getComList.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get distributor company list query: %v", dberrors.ErrInternal, err)
}
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing get distributor company list query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
var res dbtypes.CompanyListGetResponse
for rows.Next() {
var (
name, legalPerson, description, website, physicalAddress sql.NullString
legalAddress, inn, metadata, additionalFieldsTmpl sql.NullString
staff pq.StringArray
company dbtypes.Company
)
if err := rows.Scan(
&company.Id, &company.OwnerId, &name, &legalPerson, &description, &website,
&physicalAddress, &legalAddress, &inn, &company.IsActive,
&company.HasModerationTicket, &staff, &metadata, &additionalFieldsTmpl,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if name.Valid {
company.Name = &name.String
}
if legalPerson.Valid {
company.LegalPerson = &legalPerson.String
}
if description.Valid {
company.Description = &description.String
}
if website.Valid {
company.Website = &website.String
}
if physicalAddress.Valid {
company.PhysicalAddress = &physicalAddress.String
}
if legalAddress.Valid {
company.LegalAddress = &legalAddress.String
}
if inn.Valid {
company.Inn = &inn.String
}
company.Staff = staff
if metadata.Valid {
company.Metadata = &metadata.String
}
if additionalFieldsTmpl.Valid {
company.ExtraFieldsTemplate = &additionalFieldsTmpl.String
}
res.Companies = append(res.Companies, company)
}
return &res, nil
}
func (c *client) GetCompanyById(
ctx context.Context,
request *dbtypes.CompanyByIdGetRequest,
) (*dbtypes.CompanyByIdGetResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
companiesTable = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
getComList := psql.Select(
"id", "uid", "name", "legal_person", "description", "website",
"physical_address", "legal_address", "inn", "is_active", // TODO: add KPP when DB supports it
"has_moderation_ticket", "staff", "metadata", "additional_fields_tmpl",
).
From(companiesTable).
Where(squirrel.And{
squirrel.Eq{"id": request.CompanyId},
squirrel.Eq{"uid": request.Id},
})
query, args, err := getComList.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get distributor company list query: %v", dberrors.ErrInternal, err)
}
row := c.db.QueryRowContext(ctx, query, args...)
var (
name, legalPerson, description, website, physicalAddress sql.NullString
legalAddress, inn, metadata, additionalFieldsTmpl sql.NullString
staff pq.StringArray
company dbtypes.Company
)
if err := row.Scan(
&company.Id, &company.OwnerId, &name, &legalPerson, &description, &website,
&physicalAddress, &legalAddress, &inn, &company.IsActive,
&company.HasModerationTicket, &staff, &metadata, &additionalFieldsTmpl,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if name.Valid {
company.Name = &name.String
}
if legalPerson.Valid {
company.LegalPerson = &legalPerson.String
}
if description.Valid {
company.Description = &description.String
}
if website.Valid {
company.Website = &website.String
}
if physicalAddress.Valid {
company.PhysicalAddress = &physicalAddress.String
}
if legalAddress.Valid {
company.LegalAddress = &legalAddress.String
}
if inn.Valid {
company.Inn = &inn.String
}
company.Staff = staff
if metadata.Valid {
company.Metadata = &metadata.String
}
if additionalFieldsTmpl.Valid {
company.ExtraFieldsTemplate = &additionalFieldsTmpl.String
}
return &dbtypes.CompanyByIdGetResponse{Company: company}, nil
}
func (c *client) CreateCompany(
ctx context.Context,
request *dbtypes.CompanyCreateRequest,
) (*dbtypes.CompanyCreateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
res, err := c.createCompany(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error creating company: %w", err)
}
if err := c.createCompanyValidationTicket(ctx, tx, res.Id, request); err != nil {
return nil, fmt.Errorf("error creating company validation ticket: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("error committing transaction: %w", err)
}
return res, nil
}
func (c *client) createCompany(
ctx context.Context,
driver Driver,
request *dbtypes.CompanyCreateRequest,
) (*dbtypes.CompanyCreateResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
companyTable = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
// TODO: use normal uuid after DB reengineering
comId := fmt.Sprintf("%sCOM", strings.ReplaceAll(uuid.NewString(), "-", ""))
createCompany := psql.Insert(companyTable).
Columns(
"id", "uid", "is_active", "has_moderation_ticket", "metadata", "additional_fields_tmpl",
).
Values(
comId, request.OwnerId, false, true, request.Metadata, request.ExtraFieldsTemplate,
)
query, args, err := createCompany.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building create company query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing create company query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for create company query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.CompanyCreateResponse{Id: comId}, nil
}
func (c *client) createCompanyValidationTicket(
ctx context.Context,
driver Driver,
companyId string,
request *dbtypes.CompanyCreateRequest,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
comValTable = fmt.Sprintf("%s.%s", c.config.Schema, CompanyValidationTicketsTableName)
)
var (
ticketId = fmt.Sprintf("%sTCK", strings.ReplaceAll(uuid.NewString(), "-", ""))
)
createCompany := psql.Insert(comValTable).
Columns(
"id", "company_id", "name", "legal_person", "description", "website",
"physical_address", "legal_address", "inn", // TODO: add KPP when DB supports it
"staff", "status",
).
Values(
ticketId, companyId, request.Name, request.LegalPerson, request.Description, request.Website,
request.PhysicalAddress, request.LegalAddress, request.Inn,
request.Staff, CompanyModerationStatusStringToId(dbtypes.CompanyModerationStatusPending), // TODO: switch to status "NEW"
)
query, args, err := createCompany.ToSql()
if err != nil {
return fmt.Errorf("%w: error building create company moderation ticket query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing create company moderation ticket query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for create company moderation ticket query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}
func (c *client) UpdateCompany(
ctx context.Context,
request *dbtypes.CompanyUpdateRequest,
) (*dbtypes.CompanyUpdateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
res, err := c.updateCompany(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error updating company: %w", err)
}
if err := c.updateCompanyValidationTicket(ctx, tx, request.Id, request); err != nil {
return nil, fmt.Errorf("error updating company validation ticket: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("error committing transaction: %w", err)
}
return res, nil
}
func (c *client) updateCompany(
ctx context.Context,
driver Driver,
request *dbtypes.CompanyUpdateRequest,
) (*dbtypes.CompanyUpdateResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
companyTable = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
updateCompany := psql.Update(companyTable).
SetMap(map[string]any{
"is_active": false,
"has_moderation_ticket": true,
"metadata": request.Metadata,
"additional_fields_tmpl": request.ExtraFields,
}).
Where(squirrel.Eq{"id": request.Id})
query, args, err := updateCompany.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building update company query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing update company query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for update company query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.CompanyUpdateResponse{}, nil
}
// NOTE: do we believe that every company has a moderation ticket?
func (c *client) updateCompanyValidationTicket(
ctx context.Context,
driver Driver,
companyId string,
request *dbtypes.CompanyUpdateRequest,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
comValTable = fmt.Sprintf("%s.%s", c.config.Schema, CompanyValidationTicketsTableName)
)
updateCompany := psql.Update(comValTable).
Where(squirrel.Eq{"company_id": companyId})
if request.Name != nil {
updateCompany = updateCompany.Set("name", *request.Name)
}
if request.LegalPerson != nil {
updateCompany = updateCompany.Set("legal_person", *request.LegalPerson)
}
if request.Description != nil {
updateCompany = updateCompany.Set("description", *request.Description)
}
if request.Website != nil {
updateCompany = updateCompany.Set("website", *request.Website)
}
if request.PhysicalAddress != nil {
updateCompany = updateCompany.Set("physical_address", *request.PhysicalAddress)
}
if request.LegalAddress != nil {
updateCompany = updateCompany.Set("legal_address", *request.LegalAddress)
}
if request.Inn != nil {
updateCompany = updateCompany.Set("inn", *request.Inn)
}
if len(request.Staff) > 0 {
updateCompany = updateCompany.Set("staff", request.Staff)
}
query, args, err := updateCompany.ToSql()
if err != nil {
return fmt.Errorf("%w: error building update company moderation ticket query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing update company moderation ticket query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for update company moderation ticket query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}

View File

@@ -0,0 +1,23 @@
package pgdb
const (
BalancesTableName = "balances"
BankAccountsTableName = "company_bank_accounts"
CompaniesTableName = "company"
CompanyValidationTicketsTableName = "company_validation"
SubmissionsTableName = "submission"
TransactionsTableName = "transactions"
VacanciesTableName = "vacancy"
VacancyCandidatesTableName = "vacancy_candidates"
VacancyDescriptionHistoryTableName = "vacancy_moderation_descriptions"
UsersTableName = "client"
UserValidationTableName = "client_validation"
)
const (
DefaultPaginationPageSize = 20
)
const (
PGErrUniqueViolation = "23505"
)

View File

@@ -0,0 +1,128 @@
package pgdb
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
)
func (c *client) GetVacancyIntegrationInfoById(
ctx context.Context,
vacancyId string,
) (string, *dbtypes.VacancyExtraFieldsTemplate, error) {
return c.getVacancyIntegrationInfoById(ctx, c.db, vacancyId)
}
func (c *client) getVacancyIntegrationInfoById(
ctx context.Context,
driver Driver,
vacancyId string,
) (string, *dbtypes.VacancyExtraFieldsTemplate, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
getCompanyIdQuery := psql.Select("company_id", "additional_fields").
From(vacancyTable).
Where(squirrel.Eq{"id": vacancyId})
query, args, err := getCompanyIdQuery.ToSql()
if err != nil {
return "", nil, fmt.Errorf("%w: error building query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var (
companyId string
fieldsString sql.NullString
fields dbtypes.VacancyExtraFieldsTemplate
)
if err := row.Scan(&companyId, &fieldsString); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return "", nil, dberrors.ErrNotFound
}
return "", nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if fieldsString.Valid {
if err := json.Unmarshal([]byte(fieldsString.String), &fields); err != nil {
return "", nil, fmt.Errorf("%w: error unmarshalling fields: %v", dberrors.ErrInternal, err)
}
}
return companyId, &fields, nil
}
func (c *client) GetCompanyMetadataById(
ctx context.Context,
companyId string,
) (*dbtypes.CompanyMetadata, *dbtypes.CompanyExtraFieldsTemplate, error) {
return c.getCompanyMetadataById(ctx, c.db, companyId)
}
func (c *client) getCompanyMetadataById(
ctx context.Context,
driver Driver,
companyId string,
) (*dbtypes.CompanyMetadata, *dbtypes.CompanyExtraFieldsTemplate, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
companyTable = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
getCompanyMetadataQuery := psql.Select(
"metadata",
"additional_fields_tmpl",
).
From(companyTable).
Where(squirrel.Eq{"id": companyId})
query, args, err := getCompanyMetadataQuery.ToSql()
if err != nil {
return nil, nil, fmt.Errorf("%w: error building query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var (
metadataString sql.NullString
metadata dbtypes.CompanyMetadata
fieldsTemplateString sql.NullString
fieldsTemplate dbtypes.CompanyExtraFieldsTemplate
)
if err := row.Scan(&metadataString, &fieldsTemplateString); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, nil, dberrors.ErrNotFound
}
return nil, nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if metadataString.Valid {
if err := json.Unmarshal([]byte(metadataString.String), &metadata); err != nil {
return nil, nil, fmt.Errorf("%w: error unmarshalling metadata: %v", dberrors.ErrInternal, err)
}
}
if fieldsTemplateString.Valid {
if err := json.Unmarshal([]byte(fieldsTemplateString.String), &fieldsTemplate); err != nil {
return nil, nil, fmt.Errorf("%w: error unmarshalling fields template: %v", dberrors.ErrInternal, err)
}
}
return &metadata, &fieldsTemplate, nil
}

View File

@@ -0,0 +1,130 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/lib/pq"
)
func (c *client) GetProfileById(
ctx context.Context,
request *dbtypes.ProfileGetRequest,
) (*dbtypes.ProfileGetResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
usersTable = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName)
)
getProfile := psql.Select(
"uid", "name", "phone", "email",
).From(usersTable).
Where(squirrel.Eq{"uid": request.Id})
query, args, err := getProfile.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get profile query: %v", dberrors.ErrInternal, err)
}
row := c.db.QueryRowContext(ctx, query, args...)
var (
name, phoneNumber, email sql.NullString
profile dbtypes.Profile
)
if err := row.Scan(&profile.Id, &name, &phoneNumber, &email); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if name.Valid {
profile.Name = name.String
}
if phoneNumber.Valid {
profile.PhoneNumber = phoneNumber.String
}
if email.Valid {
profile.Email = email.String
}
return &dbtypes.ProfileGetResponse{
Profile: &profile,
}, nil
}
func (c *client) UpdateProfile(
ctx context.Context,
request *dbtypes.ProfileUpdateRequest,
) (*dbtypes.ProfileUpdateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
if request.Name == nil && request.PhoneNumber == nil && request.Email == nil {
return nil, fmt.Errorf("%w: nothing to update", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
usersTable = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName)
)
updateProfile := psql.Update(usersTable).
Where(squirrel.Eq{"uid": request.Id})
if request.Name != nil {
updateProfile = updateProfile.Set("name", *request.Name)
}
if request.PhoneNumber != nil {
updateProfile = updateProfile.Set("phone", *request.PhoneNumber)
}
if request.Email != nil {
updateProfile = updateProfile.Set("email", *request.Email)
}
query, args, err := updateProfile.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building update profile query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
if pqErr, ok := err.(*pq.Error); ok {
if pqErr.Code == PGErrUniqueViolation {
return nil, dberrors.ErrConflict
}
}
return nil, fmt.Errorf("%w: error executing update profile query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for update profile query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.ProfileUpdateResponse{}, nil
}

View File

@@ -0,0 +1,494 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
)
func SubmissionStatusIdToString(status int32) dbtypes.SubmissionStatus {
switch status {
case 0:
return dbtypes.SubStatusUnspecified
case 1:
return dbtypes.SubStatusNew
case 2:
return dbtypes.SubStatusPending
case 3:
return dbtypes.SubStatusOnInterview
case 4:
return dbtypes.SubStatusRejected
case 5:
return dbtypes.SubStatusCancelled
case 6:
return dbtypes.SubStatusApproved
default:
return dbtypes.SubStatusUnspecified
}
}
func SubmissionStatusStringToId(status dbtypes.SubmissionStatus) int32 {
switch status {
case dbtypes.SubStatusUnspecified:
return 0
case dbtypes.SubStatusNew:
return 1
case dbtypes.SubStatusPending:
return 2
case dbtypes.SubStatusOnInterview:
return 3
case dbtypes.SubStatusRejected:
return 4
case dbtypes.SubStatusCancelled:
return 5
case dbtypes.SubStatusApproved:
return 6
default:
return 0
}
}
//nolint:gocognit // not so hard
func (c *client) GetSubmissionList(
ctx context.Context,
request *dbtypes.SubmissionListGetRequest,
) (*dbtypes.SubmissionListGetResponse, error) {
if request == nil {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
submissionsTable = fmt.Sprintf("%s.%s", c.config.Schema, SubmissionsTableName)
)
getSubmissions := psql.Select(
"id", "uid", "vacancy_id", "submission_status_id",
"cv", "name", "phone", "email", "birthday", "info",
).From(submissionsTable).
Limit(request.PageSize).
Offset(countOffset(request.Page, request.PageSize))
if request.Filters != nil {
if request.Filters.AgentId != nil {
getSubmissions = getSubmissions.Where(squirrel.Eq{"uid": *request.Filters.AgentId})
}
if request.Filters.VacancyId != nil {
getSubmissions = getSubmissions.Where(squirrel.Eq{"vacancy_id": *request.Filters.VacancyId})
}
if request.Filters.Status != nil && *request.Filters.Status != dbtypes.SubStatusUnspecified {
getSubmissions = getSubmissions.Where(squirrel.Eq{"submission_status_id": SubmissionStatusStringToId(*request.Filters.Status)})
}
}
query, args, err := getSubmissions.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get submissions query: %v", dberrors.ErrInternal, err)
}
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing get submissions query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
submissionsList := &dbtypes.SubmissionListGetResponse{
Submissions: make([]dbtypes.Submission, 0, request.PageSize),
}
for rows.Next() {
var (
cvLink, info sql.NullString
statusId int32
candidateName string
sub = dbtypes.Submission{
AgentInfo: new(dbtypes.AgentInfo),
VacancyInfo: new(dbtypes.VacancyInfo),
CandidateInfo: new(dbtypes.CandidateInfo),
}
)
if err := rows.Scan(
&sub.Id, &sub.AgentInfo.Id, &sub.VacancyInfo.Id, &statusId,
&cvLink, &candidateName, &sub.CandidateInfo.PhoneNumber, &sub.CandidateInfo.Email,
&sub.CandidateInfo.Birthday, &info,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
sub.CandidateInfo.LastName, sub.CandidateInfo.FirstName, sub.CandidateInfo.MiddleName = splitName(candidateName)
if cvLink.Valid {
sub.CandidateInfo.CvLink = &cvLink.String
}
if info.Valid {
sub.CandidateInfo.Resume = &info.String
}
sub.Status = SubmissionStatusIdToString(statusId)
submissionsList.Submissions = append(submissionsList.Submissions, sub)
}
return submissionsList, nil
}
func splitName(name string) (string, string, string) {
var (
parts = strings.SplitN(name, " ", 3)
lastName, firstName, middleName string
)
if len(parts) > 0 {
lastName = parts[0]
}
if len(parts) > 1 {
firstName = parts[1]
}
if len(parts) > 2 {
middleName = parts[2]
}
return lastName, firstName, middleName
}
func (c *client) CreateSubmission(
ctx context.Context,
request *dbtypes.SubmissionCreateRequest,
) (*dbtypes.SubmissionCreateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
if request.CandidateInfo == nil {
return nil, fmt.Errorf("%w: request.CandidateInfo is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
submissionsTable = fmt.Sprintf("%s.%s", c.config.Schema, SubmissionsTableName)
)
var (
// TODO: use normal uuid after DB reengineering
subId = fmt.Sprintf("%sSUB", strings.ReplaceAll(uuid.NewString(), "-", ""))
fullName = formatName(request.CandidateInfo.LastName, request.CandidateInfo.FirstName, request.CandidateInfo.MiddleName)
)
createSubmission := psql.Insert(submissionsTable).
Columns(
"id", "uid", "vacancy_id", "submission_status_id",
"cv", "name", "phone", "email", "birthday", "info",
).
Values(
subId, request.AgentId, request.VacancyId, SubmissionStatusStringToId(dbtypes.SubStatusNew),
request.CandidateInfo.CvLink, fullName, request.CandidateInfo.PhoneNumber,
request.CandidateInfo.Email, request.CandidateInfo.Birthday, request.CandidateInfo.Resume,
)
query, args, err := createSubmission.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building create submission query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing create submission query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for create submission query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.SubmissionCreateResponse{
Id: subId,
}, nil
}
// NOTE: lastName and firstName are required to be non-empty
func formatName(lastName, firstName, middleName string) string {
name := fmt.Sprintf("%s %s", lastName, firstName)
if middleName != "" {
name = fmt.Sprintf("%s %s", name, middleName)
}
return name
}
//nolint:funlen,gocognit // TODO: refactor
func (c *client) UpdateSubmissionStatus(
ctx context.Context,
request *dbtypes.SubmissionStatusUpdateRequest,
) (*dbtypes.SubmissionStatusUpdateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
submissionsTable = fmt.Sprintf("%s.%s", c.config.Schema, SubmissionsTableName)
)
updateSubmissionStatus := psql.Update(submissionsTable).
Set("submission_status_id", SubmissionStatusStringToId(request.Status)).
Where(squirrel.Eq{"id": request.Id})
query, args, err := updateSubmissionStatus.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'update submission status' query: %v", dberrors.ErrInternal, err)
}
if request.Status != dbtypes.SubStatusApproved {
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'update submission status' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'update submission status' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.SubmissionStatusUpdateResponse{}, nil
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
vacancy, agentId, err := c.getSubmissionMetadata(ctx, tx, request.Id)
if err != nil {
return nil, fmt.Errorf("error getting vacancy info: %w", err)
}
if vacancy.AgentReward == nil {
return nil, fmt.Errorf("%w: agent reward is unknown", dberrors.ErrForbidden)
}
if vacancy.IsArchived {
return nil, fmt.Errorf("%w: vacancy is closed", dberrors.ErrForbidden)
}
if vacancy.CurrentCandidates+1 > vacancy.RequiredCandidates {
return nil, fmt.Errorf("%w: vacancy quota exceeded", dberrors.ErrForbidden)
}
if err := c.addSubmissionCandidate(ctx, tx, vacancy.Id); err != nil {
return nil, fmt.Errorf("%w: error adding submission candidate: %v", dberrors.ErrInternal, err)
}
payload := dbtypes.TransactionPayload{
Origin: "submission",
CompanyId: vacancy.Company.Id,
CompanyName: vacancy.Company.Name,
VacancyId: vacancy.Id,
VacancyName: vacancy.Name,
}
molvaAgentTransId := uuid.NewString()
if _, err := c.createTransactionWithDriver(ctx, tx, &dbtypes.TransactionCreateRequest{
OwnerId: agentId,
Amount: int64(*vacancy.AgentReward),
Currency: "RUB",
RequestId: molvaAgentTransId,
Payload: &payload,
}); err != nil {
return nil, fmt.Errorf("error creating molva -> agent transaction: %w", err)
}
distMolvaTransId := uuid.NewString()
if _, err := c.createTransactionWithDriver(ctx, tx, &dbtypes.TransactionCreateRequest{
OwnerId: vacancy.Company.Id,
Amount: -int64(*vacancy.AgentReward),
Currency: "RUB",
RequestId: distMolvaTransId,
Payload: &payload,
}); err != nil {
return nil, fmt.Errorf("error creating dist -> molva transaction: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err)
}
res, err := tx.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'update submission status' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'update submission status' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.SubmissionStatusUpdateResponse{}, nil
}
func (c *client) getSubmissionMetadata(
ctx context.Context,
driver Driver,
submissionId string,
) (*dbtypes.Vacancy, string, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
submissionsTable = fmt.Sprintf("%s.%s s", c.config.Schema, SubmissionsTableName)
companiesTable = fmt.Sprintf("%s.%s c", c.config.Schema, CompaniesTableName)
vacanciesTable = fmt.Sprintf("%s.%s v", c.config.Schema, VacanciesTableName)
vacancyCandidatesTable = fmt.Sprintf("%s.%s vc", c.config.Schema, VacancyCandidatesTableName)
)
getMetadata := psql.Select(
"s.uid", "v.id", "v.name", "v.company_id", "c.name", "v.agent_reward", "v.is_archived",
"vc.current_candidates_amt", "vc.required_candidates_amt",
).From(submissionsTable).
InnerJoin(fmt.Sprintf("%s on s.vacancy_id = v.id", vacanciesTable)).
InnerJoin(fmt.Sprintf("%s on v.id = vc.vacancy_id", vacancyCandidatesTable)).
InnerJoin(fmt.Sprintf("%s on v.company_id = c.id", companiesTable)).
Where(squirrel.Eq{"s.id": submissionId}).
Suffix("FOR UPDATE OF vc")
query, args, err := getMetadata.ToSql()
if err != nil {
return nil, "", fmt.Errorf("%w: error building 'get submission metadata' query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var (
agentId string
vacancy dbtypes.Vacancy
)
if err := row.Scan(
&agentId,
&vacancy.Id, &vacancy.Name, &vacancy.Company.Id, &vacancy.Company.Name,
&vacancy.AgentReward, &vacancy.IsArchived,
&vacancy.CurrentCandidates, &vacancy.RequiredCandidates,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, "", dberrors.ErrNotFound
}
return nil, "", fmt.Errorf("%w: error scanning row for 'get submission metadata' query: %v", dberrors.ErrInternal, err)
}
return &vacancy, agentId, nil
}
func (c *client) addSubmissionCandidate(
ctx context.Context,
driver Driver,
vacancyId string,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyCandisTable = fmt.Sprintf("%s.%s", c.config.Schema, VacancyCandidatesTableName)
)
addSubmissionCandidate := psql.Update(vacancyCandisTable).
Set("current_candidates_amt", squirrel.Expr("current_candidates_amt + 1")).
Where(squirrel.Eq{"vacancy_id": vacancyId})
query, args, err := addSubmissionCandidate.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'add submission candidate' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'add submission candidate' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'add submission candidate' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}
func (c *client) DeleteSubmission(
ctx context.Context,
request *dbtypes.SubmissionDeleteRequest,
) (*dbtypes.SubmissionDeleteResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
submissionsTable = fmt.Sprintf("%s.%s", c.config.Schema, SubmissionsTableName)
)
deleteSubmission := psql.Update(submissionsTable).
Set("submission_status_id", SubmissionStatusStringToId(dbtypes.SubStatusCancelled)).
Where(squirrel.Eq{"id": request.Id})
query, args, err := deleteSubmission.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building delete submission query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing delete submission query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for delete submission query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.SubmissionDeleteResponse{}, nil
}

View File

@@ -0,0 +1,485 @@
package pgdb
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
)
func getTransactionTypeByAmount(amount int64) dbtypes.TransactionType {
if amount > 0 {
return dbtypes.TransactionTypeDeposit
}
return dbtypes.TransactionTypeWithdrawal
}
// TODO: add migration to rebind statuses
func TransactionStatusIdToString(status int32) dbtypes.TransactionStatus {
switch status {
case 0:
return dbtypes.TransactionStatusPending
case 1:
return dbtypes.TransactionStatusApproved
case 2:
return dbtypes.TransactionStatusRejected
case 3:
return dbtypes.TransactionStatusNew
default:
return dbtypes.TransactionStatusPending
}
}
func TransactionStatusStringToId(status dbtypes.TransactionStatus) int32 {
switch status {
case dbtypes.TransactionStatusNew:
return 3
case dbtypes.TransactionStatusPending:
return 0
case dbtypes.TransactionStatusApproved:
return 1
case dbtypes.TransactionStatusRejected:
return 2
default:
return 3
}
}
//nolint:gocognit // not so hard
func (c *client) GetTransactionList(
ctx context.Context,
request *dbtypes.TransactionListGetRequest,
) (*dbtypes.TransactionListGetResponse, error) {
if request == nil {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
transactionsTable = fmt.Sprintf("%s.%s", c.config.Schema, TransactionsTableName)
)
getTransactions := psql.Select(
"id", "owner_id", "bank_account_id", "amount", "currency", "status", "created_at", "payload",
).From(transactionsTable).
Where(squirrel.Eq{"owner_id": request.OwnerId}).
Limit(request.PageSize).
Offset(countOffset(request.Page, request.PageSize))
getTransactions, err := c.setGetTransactionsQueryFilters(getTransactions, request.Filters)
if err != nil {
return nil, fmt.Errorf("%w: error setting get transactions query filters: %v", dberrors.ErrBadRequest, err)
}
query, args, err := getTransactions.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get transactions query: %v", dberrors.ErrInternal, err)
}
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing get transactions query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
transList := &dbtypes.TransactionListGetResponse{
Transactions: make([]dbtypes.Transaction, 0, request.PageSize),
}
for rows.Next() {
var (
transStatus int32
ownerId string
payload, bankAccountId sql.NullString
transaction dbtypes.Transaction
)
if err := rows.Scan(
&transaction.Id, &ownerId, &bankAccountId, &transaction.Amount, &transaction.Currency,
&transStatus, &transaction.CreatedAt, &payload,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if bankAccountId.Valid {
bankAccountInfo, err := c.getBankAccountInfoById(ctx, c.db, bankAccountId.String)
if err != nil {
return nil, fmt.Errorf("%w: error getting bank account info: %v", dberrors.ErrInternal, err)
}
transaction.BankAccountInfo = bankAccountInfo
ownerInfo, err := c.getOwnerInfoById(ctx, c.db, ownerId, bankAccountInfo.OwnerType)
if err != nil {
return nil, fmt.Errorf("%w: error getting owner info: %v", dberrors.ErrInternal, err)
}
transaction.OwnerInfo = ownerInfo
}
transaction.Type = getTransactionTypeByAmount(transaction.Amount)
transaction.Status = TransactionStatusIdToString(transStatus)
if payload.Valid {
var payloadData dbtypes.TransactionPayload
if err := json.Unmarshal([]byte(payload.String), &payloadData); err != nil {
return nil, fmt.Errorf("%w: error unmarshaling transaction payload: %v", dberrors.ErrInternal, err)
}
transaction.Payload = &payloadData
}
transList.Transactions = append(transList.Transactions, transaction)
}
return transList, nil
}
func (c *client) setGetTransactionsQueryFilters(
query squirrel.SelectBuilder,
filters *dbtypes.TransactionListFilters,
) (squirrel.SelectBuilder, error) {
if filters == nil {
return query, nil
}
if filters.Type != nil {
switch *filters.Type {
case dbtypes.TransactionTypeDeposit:
query = query.Where(squirrel.Gt{
"amount": 0,
})
case dbtypes.TransactionTypeWithdrawal:
query = query.Where(squirrel.Lt{
"amount": 0,
})
default:
return query, fmt.Errorf("%w: invalid transaction type: %v", dberrors.ErrBadRequest, *filters.Type)
}
}
if filters.Status != nil {
query = query.Where(squirrel.Eq{"status": TransactionStatusStringToId(*filters.Status)})
}
if filters.BankAccountId != nil {
query = query.Where(squirrel.Eq{"bank_account_id": *filters.BankAccountId})
}
return query, nil
}
func (c *client) getOwnerInfoById(
ctx context.Context,
driver Driver,
ownerId string,
ownerType string,
) (*dbtypes.TransactionOwnerInfo, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
clientTableName = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName)
companyTableName = fmt.Sprintf("%s.%s", c.config.Schema, CompaniesTableName)
)
var getOwnerInfoById squirrel.SelectBuilder
// TODO: reingeneer the DB
switch ownerType {
case "agent":
getOwnerInfoById = psql.Select(
"uid",
"name",
).
From(clientTableName).
Where(squirrel.Eq{"uid": ownerId})
case "company":
getOwnerInfoById = psql.Select(
"id",
"name",
).
From(companyTableName).
Where(squirrel.Eq{"id": ownerId})
default:
return nil, fmt.Errorf("%w: invalid owner type", dberrors.ErrBadRequest)
}
query, args, err := getOwnerInfoById.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get owner info by id query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var ownerInfo dbtypes.TransactionOwnerInfo
if err := row.Scan(
&ownerInfo.Id,
&ownerInfo.Name,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row for get owner info by id query: %v", dberrors.ErrInternal, err)
}
return &ownerInfo, nil
}
func (c *client) getBankAccountInfoById(
ctx context.Context,
driver Driver,
bankAccountId string,
) (*dbtypes.BankAccountInfo, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
bankAccountsTableName = fmt.Sprintf("%s.%s", c.config.Schema, BankAccountsTableName)
)
getBankAccountInfoById := psql.Select(
"id",
"account_number",
"bank_name",
"bik",
"correspondent_account",
"owner_type",
).
From(bankAccountsTableName).
Where(squirrel.Eq{"id": bankAccountId})
query, args, err := getBankAccountInfoById.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get bank account info by id query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var accountInfo dbtypes.BankAccountInfo
if err := row.Scan(
&accountInfo.Id,
&accountInfo.AccountNumber,
&accountInfo.BankName,
&accountInfo.Bik,
&accountInfo.CorrespondentAccount,
&accountInfo.OwnerType,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row for get bank account info by id query: %v", dberrors.ErrInternal, err)
}
return &accountInfo, nil
}
func (c *client) CreateTransaction(
ctx context.Context,
request *dbtypes.TransactionCreateRequest,
) (*dbtypes.TransactionCreateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
result, err := c.createTransactionWithDriver(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error creating transaction: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err)
}
return result, nil
}
func (c *client) createTransactionWithDriver(
ctx context.Context,
driver Driver,
request *dbtypes.TransactionCreateRequest,
) (*dbtypes.TransactionCreateResponse, error) {
if _, err := c.getRawBalanceForUpdate(ctx, driver, request.OwnerId); err != nil {
return nil, fmt.Errorf("error getting raw balance for update: %w", err)
}
result, err := c.createTransaction(ctx, driver, request)
if err != nil {
if errors.Is(err, dberrors.ErrConflict) {
return result, nil
}
return nil, fmt.Errorf("error creating transaction: %w", err)
}
if err := c.updateBalance(ctx, driver, request.Amount, request.OwnerId); err != nil {
return nil, fmt.Errorf("error updating balance: %w", err)
}
return result, nil
}
func (c *client) getRawBalanceForUpdate(
ctx context.Context,
driver Driver,
ownerId string,
) (int64, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
balancesTable = fmt.Sprintf("%s.%s", c.config.Schema, BalancesTableName)
)
getBalance := psql.Select(
"raw_balance",
).From(balancesTable).
Where(squirrel.Eq{"owner_id": ownerId}).
Suffix("FOR UPDATE")
query, args, err := getBalance.ToSql()
if err != nil {
return 0, fmt.Errorf("%w: error building 'get balance' query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var rawBalance int64
if err := row.Scan(&rawBalance); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return 0, dberrors.ErrNotFound
}
return 0, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
return rawBalance, nil
}
func (c *client) updateBalance(
ctx context.Context,
driver Driver,
amountDelta int64,
ownerId string,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
balancesTable = fmt.Sprintf("%s.%s", c.config.Schema, BalancesTableName)
)
updateBalance := psql.Update(balancesTable).
SetMap(map[string]any{
"raw_balance": squirrel.Expr("raw_balance + ?", amountDelta),
"updated_at": squirrel.Expr("NOW()"),
}).
Where(squirrel.Eq{"owner_id": ownerId})
query, args, err := updateBalance.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'update balance' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'update balance' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'update balance' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}
func (c *client) createTransaction(
ctx context.Context,
driver Driver,
request *dbtypes.TransactionCreateRequest,
) (*dbtypes.TransactionCreateResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
transactionsTable = fmt.Sprintf("%s.%s", c.config.Schema, TransactionsTableName)
)
var payload []byte
if request.Payload == nil {
payload = []byte("{}")
} else {
payloadBytes, err := json.Marshal(request.Payload)
if err != nil {
return nil, fmt.Errorf("%w: error marshaling transaction payload: %v", dberrors.ErrInternal, err)
}
payload = payloadBytes
}
createTransaction := psql.Insert(transactionsTable).
Columns(
"id", "owner_id", "bank_account_id", "amount", "currency", "status", "created_at", "payload",
).
Values(
request.RequestId, request.OwnerId, request.BankAccountId, request.Amount, request.Currency,
dbtypes.TransactionStatusNew, squirrel.Expr("CURRENT_TIMESTAMP"), payload,
).
Suffix("ON CONFLICT (id, owner_id) DO NOTHING")
query, args, err := createTransaction.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'create transaction' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'create transaction' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'create transaction' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return &dbtypes.TransactionCreateResponse{
Id: request.RequestId,
}, dberrors.ErrConflict
}
return &dbtypes.TransactionCreateResponse{
Id: request.RequestId,
}, nil
}

View File

@@ -0,0 +1,203 @@
package pgdb
import (
"context"
"database/sql"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
)
func (c *client) GetClientValidation(
ctx context.Context,
request *dbtypes.ClientValidationGetRequest,
) (*dbtypes.ClientValidationGetResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName)
)
getUserValidation := psql.Select(
"status", "description",
).
From(userValidationTable).
Where(squirrel.Eq{"uid": request.UserId})
query, args, err := getUserValidation.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'get user validation' query: %v", dberrors.ErrInternal, err)
}
row := c.db.QueryRowContext(ctx, query, args...)
var result dbtypes.ClientValidation
if err := row.Scan(&result.Status, &result.Description); err != nil {
if err == sql.ErrNoRows {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row for 'get user validation' query: %v", dberrors.ErrInternal, err)
}
return &dbtypes.ClientValidationGetResponse{
ClientValidation: &result,
}, nil
}
func (c *client) CreateUser(
ctx context.Context,
request *dbtypes.UserSaveRequest,
) (*dbtypes.UserSaveResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
result, err := c.createUser(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error creating user: %w", err)
}
if err := c.createUserValidationTicket(ctx, tx, request); err != nil {
return nil, fmt.Errorf("error creating user validation ticket: %w", err)
}
resp, err := c.createCompany(ctx, tx, &dbtypes.CompanyCreateRequest{
OwnerId: request.Id,
Staff: []string{
request.Id,
},
})
if err != nil {
return nil, fmt.Errorf("error creating company: %w", err)
}
var ownerId string
switch request.Type {
case dbtypes.UserTypeAgent:
ownerId = request.Id
case dbtypes.UserTypeDistributor:
ownerId = resp.Id
default:
return nil, fmt.Errorf("%w: unknown user type: %v", dberrors.ErrBadRequest, request.Type)
}
balanceId := fmt.Sprintf("%sBAL", strings.ReplaceAll(uuid.NewString(), "-", ""))
if err := c.createBalance(ctx, tx, &dbtypes.BalanceCreateRequest{
Id: balanceId,
OwnerId: ownerId,
RawBalance: 0,
CleanBalance: 0,
}); err != nil {
return nil, fmt.Errorf("error creating balance: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err)
}
return result, nil
}
func (c *client) createUser(
ctx context.Context,
driver Driver,
request *dbtypes.UserSaveRequest,
) (*dbtypes.UserSaveResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userTable = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName)
)
saveUser := psql.Insert(userTable).
Columns(
"uid", "name", "phone", "email", "client_type_id",
).
Values(
request.Id, request.FullName, request.Phone, request.Email, request.Type,
)
query, args, err := saveUser.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'save user' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'save user' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'save user' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.UserSaveResponse{}, nil
}
func (c *client) createUserValidationTicket(
ctx context.Context,
driver Driver,
request *dbtypes.UserSaveRequest,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName)
)
// TODO: use normal uuid after DB reengineering
ticketId := fmt.Sprintf("%sVAL", strings.ReplaceAll(uuid.NewString(), "-", ""))
createUserValidation := psql.Insert(userValidationTable).
Columns(
"id", "uid", "status", "description", "last_update",
).
Values(
ticketId, request.Id, dbtypes.ClientValStatusNew, request.FullName, squirrel.Expr("CURRENT_TIMESTAMP"),
)
query, args, err := createUserValidation.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'create user validation' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'create user validation' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'create user validation' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}

View File

@@ -0,0 +1,573 @@
package pgdb
import (
"context"
"database/sql"
"errors"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
)
func VacancyStatusIdToString(status int32) dbtypes.VacancyStatus {
switch status {
case 0:
return dbtypes.VacUnspecified
case 1:
return dbtypes.VacNew
case 2:
return dbtypes.VacPending
case 3:
return dbtypes.VacApproved
case 4:
return dbtypes.VacRejected
default:
return dbtypes.VacUnspecified
}
}
func VacancyStatusStringToId(status dbtypes.VacancyStatus) int32 {
switch status {
case dbtypes.VacUnspecified:
return 0
case dbtypes.VacNew:
return 1
case dbtypes.VacPending:
return 2
case dbtypes.VacApproved:
return 3
case dbtypes.VacRejected:
return 4
default:
return 0
}
}
//nolint:funlen,gocognit // maybe refactor later
func (c *client) GetVacancyList(
ctx context.Context,
request *dbtypes.VacancyListGetRequest,
) (*dbtypes.VacancyListGetResponse, error) {
if request == nil {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s v", c.config.Schema, VacanciesTableName)
companyTable = fmt.Sprintf("%s.%s c", c.config.Schema, CompaniesTableName)
)
getVacList := psql.Select(
"v.id", "v.company_id", "c.name", "v.name", "v.address", "v.work_format",
"v.agent_reward", "v.region", "v.salary_top", "v.salary_bottom", "v.requirements",
"v.responsibilities", "v.additional_info", "v.is_archived",
"v.target_action", "v.target_action_amount", "v.publish_date",
"v.moderation_status_id", "v.required_candidates", "v.current_candidates",
"v.additional_fields",
).
From(vacancyTable).
LeftJoin(fmt.Sprintf("%s on v.company_id = c.id", companyTable)).
Limit(request.PageSize).
Offset(countOffset(request.Page, request.PageSize))
getVacList = c.setVacancyListFilters(getVacList, request.Filters)
query, args, err := getVacList.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building get vacancy list query: %v", dberrors.ErrInternal, err)
}
rows, err := c.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing get vacancy list query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
var (
res dbtypes.VacancyListGetResponse
vacancyIds = make([]string, 0, request.PageSize)
)
for rows.Next() {
var (
status int32
agentReward sql.NullInt32
comName, reqs, resps, extraInfo, extraFields sql.NullString
vacancy dbtypes.Vacancy
)
if err := rows.Scan(
&vacancy.Id, &vacancy.Company.Id, &comName, &vacancy.Name, &vacancy.Address,
&vacancy.WorkFormat, &agentReward, &vacancy.Region, &vacancy.SalaryTop, &vacancy.SalaryBottom,
&reqs, &resps, &extraInfo, &vacancy.IsArchived, &vacancy.TargetAction.Action, &vacancy.TargetAction.Duration,
&vacancy.CreatedAt, &status, &vacancy.RequiredCandidates, &vacancy.CurrentCandidates,
&extraFields,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row: %v", dberrors.ErrInternal, err)
}
if agentReward.Valid {
vacancy.AgentReward = &agentReward.Int32
}
if comName.Valid {
vacancy.Company.Name = comName.String
}
if reqs.Valid {
vacancy.Requirements = &reqs.String
}
if resps.Valid {
vacancy.Responsibilities = &resps.String
}
if extraInfo.Valid {
vacancy.ExtraInfo = &extraInfo.String
}
if extraFields.Valid {
vacancy.ExtraFields = &extraFields.String
}
vacancy.Moderation.Status = VacancyStatusIdToString(status)
res.Vacancies = append(res.Vacancies, vacancy)
vacancyIds = append(vacancyIds, vacancy.Id)
}
descriptions, err := c.getVacancyModerationDescriptionHistory(ctx, c.db, vacancyIds)
if err != nil {
if errors.Is(err, dberrors.ErrNotFound) {
return &res, nil
}
return nil, fmt.Errorf("error getting descriptions for vacancies: %w", err)
}
for i, vacancy := range res.Vacancies {
res.Vacancies[i].Moderation.DescriptionHistory = descriptions[vacancy.Id]
}
return &res, nil
}
func (c *client) setVacancyListFilters(
query squirrel.SelectBuilder,
filters *dbtypes.VacancyListFilters,
) squirrel.SelectBuilder {
if filters.DistributorId != nil {
query = query.Where(squirrel.Eq{"c.uid": *filters.DistributorId})
}
if filters.CompanyId != nil {
query = query.Where(squirrel.Eq{"v.company_id": *filters.CompanyId})
}
if filters.VacancyId != nil {
query = query.Where(squirrel.Eq{"v.id": *filters.VacancyId})
}
if filters.Region != nil {
query = query.Where(squirrel.Eq{"v.region": *filters.Region})
}
if filters.SalaryBottom != nil {
query = query.Where(squirrel.Or{
squirrel.GtOrEq{"v.salary_bottom": *filters.SalaryBottom},
squirrel.Eq{"v.salary_bottom": nil},
})
}
if filters.SalaryTop != nil {
query = query.Where(squirrel.Or{
squirrel.LtOrEq{"v.salary_top": *filters.SalaryTop},
squirrel.Eq{"v.salary_top": nil},
})
}
if filters.IsArchived != nil {
query = query.Where(squirrel.Eq{"v.is_archived": *filters.IsArchived})
}
if filters.Status != nil {
query = query.Where(squirrel.Eq{"v.moderation_status_id": VacancyStatusStringToId(*filters.Status)})
}
return query
}
func (c *client) getVacancyModerationDescriptionHistory(
ctx context.Context,
driver Driver,
vacancyIds []string,
) (map[string][]dbtypes.VacancyModerationDescription, error) {
if len(vacancyIds) == 0 {
return nil, nil
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyModerDescriptionsTable = fmt.Sprintf("%s.%s", c.config.Schema, VacancyDescriptionHistoryTableName)
)
getVacancyModerationDescriptionHistory := psql.Select(
"vacancy_id",
"description",
"created_at",
).
From(vacancyModerDescriptionsTable).
Where(squirrel.Eq{"vacancy_id": vacancyIds}).
OrderBy("vacancy_id", "created_at ASC")
query, args, err := getVacancyModerationDescriptionHistory.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building getVacancyModerationDescriptionHistory query: %v", dberrors.ErrInternal, err)
}
rows, err := driver.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing getVacancyModerationDescriptionHistory query: %v", dberrors.ErrInternal, err)
}
defer rows.Close()
descriptionsMap := make(map[string][]dbtypes.VacancyModerationDescription)
for rows.Next() {
var (
vacancyId string
description dbtypes.VacancyModerationDescription
)
if err := rows.Scan(
&vacancyId,
&description.Description,
&description.CreatedAt,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row for getVacancyModerationDescriptionHistory: %v", dberrors.ErrInternal, err)
}
descriptionsMap[vacancyId] = append(descriptionsMap[vacancyId], description)
}
return descriptionsMap, nil
}
func (c *client) CreateVacancy(
ctx context.Context,
request *dbtypes.VacancyCreateRequest,
) (*dbtypes.VacancyCreateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
// TODO: use normal uuid after DB reengineering
vacancyId := fmt.Sprintf("%sVAC", strings.ReplaceAll(uuid.NewString(), "-", ""))
createVacancy := psql.Insert(vacancyTable).
Columns(
"id", "company_id", "name", "address", "work_format", "agent_reward",
"salary_top", "salary_bottom", "requirements", "responsibilities", "additional_info",
"region", "is_archived", "target_action", "target_action_amount", "moderation_status_id",
"required_candidates", "publish_date", "current_candidates", "additional_fields",
).
Values(
vacancyId, request.CompanyId, request.Name, request.Address, request.WorkFormat, request.AgentReward,
request.SalaryTop, request.SalaryBottom, request.Requirements, request.Responsibilities, request.ExtraInfo,
request.Region, false, request.TargetAction.Action, request.TargetAction.Duration, VacancyStatusStringToId(dbtypes.VacNew),
request.RequiredCandidates, squirrel.Expr("now()"), request.CurrentCandidates, request.ExtraFields,
)
query, args, err := createVacancy.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building create vacancy query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
// TODO: process conflict via err.(*pq.Error).Code
return nil, fmt.Errorf("%w: error executing create vacancy query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for create vacancy query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.VacancyCreateResponse{Id: vacancyId}, nil
}
func (c *client) UpdateVacancy(
ctx context.Context,
request *dbtypes.VacancyUpdateRequest,
) (*dbtypes.VacancyUpdateResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
status, err := c.getVacancyModerStatusForUpdate(ctx, tx, request.Id)
if err != nil {
return nil, fmt.Errorf("error getting vacancy moder status: %w", err)
}
if status == dbtypes.VacApproved {
return nil, dberrors.ErrForbidden
}
res, err := c.updateVacancy(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error updating vacancy: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("error committing transaction: %w", err)
}
return res, nil
}
func (c *client) getVacancyModerStatusForUpdate(
ctx context.Context,
driver Driver,
vacancyId string,
) (dbtypes.VacancyStatus, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
getVacancyModerStatus := psql.Select(
"moderation_status_id",
).
From(vacancyTable).
Where(squirrel.Eq{"id": vacancyId}).
Suffix("FOR UPDATE")
query, args, err := getVacancyModerStatus.ToSql()
if err != nil {
return "", fmt.Errorf("%w: error building get vacancy moder status query: %v", dberrors.ErrInternal, err)
}
row := driver.QueryRowContext(ctx, query, args...)
var (
statusId int32
)
if err := row.Scan(&statusId); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return "", dberrors.ErrNotFound
}
return "", fmt.Errorf("%w: error scanning row for get vacancy moder status query: %v", dberrors.ErrInternal, err)
}
return VacancyStatusIdToString(statusId), nil
}
func (c *client) updateVacancy(
ctx context.Context,
driver Driver,
request *dbtypes.VacancyUpdateRequest,
) (*dbtypes.VacancyUpdateResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
updateVacancy := psql.Update(vacancyTable).
Where(squirrel.Eq{"id": request.Id})
if request.Name != nil {
updateVacancy = updateVacancy.Set("name", *request.Name)
}
if request.Address != nil {
updateVacancy = updateVacancy.Set("address", *request.Address)
}
if request.WorkFormat != nil {
updateVacancy = updateVacancy.Set("work_format", *request.WorkFormat)
}
if request.AgentReward != nil {
updateVacancy = updateVacancy.Set("agent_reward", *request.AgentReward)
}
if request.SalaryTop != nil {
updateVacancy = updateVacancy.Set("salary_top", *request.SalaryTop)
}
if request.SalaryBottom != nil {
updateVacancy = updateVacancy.Set("salary_bottom", *request.SalaryBottom)
}
if request.Requirements != nil {
updateVacancy = updateVacancy.Set("requirements", *request.Requirements)
}
if request.Responsibilities != nil {
updateVacancy = updateVacancy.Set("responsibilities", *request.Responsibilities)
}
if request.ExtraInfo != nil {
updateVacancy = updateVacancy.Set("extra_info", *request.ExtraInfo)
}
if request.Region != nil {
updateVacancy = updateVacancy.Set("region", *request.Region)
}
if request.TargetAction.Action != nil {
updateVacancy = updateVacancy.Set("target_action", *request.TargetAction.Action)
}
if request.TargetAction.Duration != nil {
updateVacancy = updateVacancy.Set("target_action_amount", *request.TargetAction.Duration)
}
if request.RequiredCandidates != nil {
updateVacancy = updateVacancy.Set("required_candidates", *request.RequiredCandidates)
}
if request.ExtraFields != nil {
updateVacancy = updateVacancy.Set("additional_fields", *request.ExtraFields)
}
query, args, err := updateVacancy.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building update vacancy query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing update vacancy query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for update vacancy query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.VacancyUpdateResponse{}, nil
}
func (c *client) DeleteVacancy(
ctx context.Context,
request *dbtypes.VacancyDeleteRequest,
) (*dbtypes.VacancyDeleteResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
deleteVacancy := psql.Update(vacancyTable).
Set("is_archived", true).
Where(squirrel.Eq{"id": request.Id})
query, args, err := deleteVacancy.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building delete vacancy query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing delete vacancy query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for delete vacancy query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.VacancyDeleteResponse{}, nil
}
func (c *client) SendVacancyToModeration(
ctx context.Context,
request *dbtypes.SendVacancyToModerationRequest,
) (*dbtypes.SendVacancyToModerationResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
vacancyTable = fmt.Sprintf("%s.%s", c.config.Schema, VacanciesTableName)
)
sendVacancyToModeration := psql.Update(vacancyTable).
Set("moderation_status_id", VacancyStatusStringToId(dbtypes.VacPending)).
Where(squirrel.Eq{"id": request.Id})
query, args, err := sendVacancyToModeration.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building send vacancy to moderation query: %v", dberrors.ErrInternal, err)
}
res, err := c.db.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing send vacancy to moderation query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for send vacancy to moderation query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrNotFound
}
return &dbtypes.SendVacancyToModerationResponse{}, nil
}

View File

@@ -0,0 +1,217 @@
package dbtypes
import "time"
type (
Balance struct {
RawBalance int64
CleanBalance int64
}
)
type (
BalanceGetRequest struct {
OwnerId string
}
BalanceGetResponse struct {
Balance *Balance
}
)
type (
BalanceCreateRequest struct {
Id string
OwnerId string
RawBalance int64
CleanBalance int64
}
)
type TransactionStatus string
const (
TransactionStatusNew TransactionStatus = "new"
TransactionStatusPending TransactionStatus = "pending"
TransactionStatusApproved TransactionStatus = "approved"
TransactionStatusRejected TransactionStatus = "rejected"
)
func NewTransactionStatus(status *string) *TransactionStatus {
if status == nil {
return nil
}
res := TransactionStatus(*status)
return &res
}
type TransactionType string
const (
TransactionTypeDeposit TransactionType = "deposit"
TransactionTypeWithdrawal TransactionType = "withdrawal"
)
func NewTransactionType(typ *string) *TransactionType {
if typ == nil {
return nil
}
res := TransactionType(*typ)
return &res
}
type (
Transaction struct {
Id string
OwnerInfo *TransactionOwnerInfo
BankAccountInfo *BankAccountInfo
Type TransactionType
Status TransactionStatus
Amount int64
Currency string
CreatedAt time.Time
Payload *TransactionPayload
}
BankAccountInfo struct {
Id string
AccountNumber string
AccountName string
BankName string
Bik string
CorrespondentAccount string
OwnerType string
}
TransactionOwnerInfo struct {
Id string
Name string
}
// TODO: make DB migration to use this
// TransactionPayload struct {
// Origin string `json:"origin"`
// CompanyInfo *PayloadCompanyInfo `json:"company_info"`
// VacancyInfo *PayloadVacancyInfo `json:"vacancy_info"`
// }
// PayloadCompanyInfo struct {
// Id string `json:"id"`
// Name string `json:"name"`
// }
// PayloadVacancyInfo struct {
// Id string `json:"id"`
// Name string `json:"name"`
// }
TransactionPayload struct {
Origin string `json:"origin"`
CompanyId string `json:"company_id"`
CompanyName string `json:"company_name"`
VacancyId string `json:"vacancy_id"`
VacancyName string `json:"vacancy_name"`
}
)
type (
TransactionListGetRequest struct {
OwnerId string
Filters *TransactionListFilters
Page uint64
PageSize uint64
}
TransactionListFilters struct {
Type *TransactionType
Status *TransactionStatus
BankAccountId *string
}
TransactionListGetResponse struct {
Transactions []Transaction
}
)
type (
TransactionCreateRequest struct {
OwnerId string
Amount int64
Currency string
BankAccountId *string
RequestId string
Payload *TransactionPayload
}
TransactionCreateResponse struct {
Id string
}
)
type (
BankAccount struct {
Id string
OwnerId string
AccountNumber string
AccountName string
BankName string
Bik string
CorrespondentAccount string
IsPrimary bool
CreatedAt time.Time
UpdatedAt time.Time
}
)
type (
BankAccountListGetRequest struct {
OwnerId string
}
BankAccountListGetResponse struct {
BankAccounts []BankAccount
}
)
type (
BankAccountCreateRequest struct {
OwnerId string
AccountNumber *string
AccountName *string
BankName *string
Bik *string
CorrespondentAccount *string
IsPrimary *bool
}
BankAccountCreateResponse struct {
Id string
}
)
type (
BankAccountUpdateRequest struct {
Id string
AccountNumber *string
AccountName *string
BankName *string
Bik *string
CorrespondentAccount *string
IsPrimary *bool
}
BankAccountUpdateResponse struct{}
)
type (
BankAccountDeleteRequest struct {
Id string
OwnerId string
}
BankAccountDeleteResponse struct{}
)

View File

@@ -0,0 +1,101 @@
package dbtypes
type CompanyModerationStatus string
const (
CompanyModerationStatusNew CompanyModerationStatus = "new"
CompanyModerationStatusPending CompanyModerationStatus = "pending"
CompanyModerationStatusApproved CompanyModerationStatus = "approved"
CompanyModerationStatusRejected CompanyModerationStatus = "rejected"
)
type (
Company struct {
Id string
OwnerId string
Name *string
LegalPerson *string
Description *string
Website *string
PhysicalAddress *string
LegalAddress *string
Inn *string
Kpp *string
IsActive bool
HasModerationTicket bool
Staff []string
Metadata *string
ExtraFieldsTemplate *string
}
)
type (
CompanyListGetRequest struct {
Id string
}
CompanyListGetResponse struct {
Companies []Company
}
)
type (
CompanyByIdGetRequest struct {
Id string
CompanyId string
}
CompanyByIdGetResponse struct {
Company Company
}
)
type (
CompanyCreateRequest struct {
OwnerId string
Name *string
LegalPerson *string
Description *string
Website *string
PhysicalAddress *string
LegalAddress *string
Inn *string
Kpp *string
Staff []string
Metadata *string
ExtraFieldsTemplate *string
}
CompanyCreateResponse struct {
Id string
}
)
type (
CompanyUpdateRequest struct {
Id string
Name *string
LegalPerson *string
Description *string
Website *string
PhysicalAddress *string
LegalAddress *string
Inn *string // can be updated in several rare cases
Kpp *string // can be updated in several rare cases
Staff []string
Metadata *string
ExtraFields *string
}
CompanyUpdateResponse struct {
}
)
type (
CompanyDeleteRequest struct {
Id string
}
CompanyDeleteResponse struct {
}
)

View File

@@ -0,0 +1,53 @@
package dbtypes
type Fieldtype string
type (
CompanyMetadata map[string]string
ValidValue struct {
DisplayName string `json:"display_name"`
Value string `json:"value"`
}
/*
CompanyExtraFieldTemplate describes single
additional field of company additional fields template
*/
CompanyExtraFieldTemplate struct {
SystemName string `json:"system_name"`
DisplayName string `json:"display_name"`
Type Fieldtype `json:"type"`
Required bool `json:"required"`
MultipleChoice bool `json:"multiple_choice"`
ValidValues []ValidValue `json:"valid_values"`
}
/*
CompanyExtraFieldsTemplate describes additional fields
needed to integrate company
*/
CompanyExtraFieldsTemplate struct {
Fields []CompanyExtraFieldTemplate `json:"fields"`
}
/*
VacancyExtraFieldTemplate describes single filled
additional field of vacancy additional fields template
*/
VacancyExtraFieldTemplate struct {
SystemName string `json:"system_name"`
Type Fieldtype `json:"type"`
IsValidValue bool `json:"is_valid_values"`
MultipleChoice bool `json:"multiple_choice"`
Value []string `json:"value"`
}
/*
VacancyExtraFieldsTemplate describes additional fields
filled during vacancy creation
*/
VacancyExtraFieldsTemplate struct {
Fields []VacancyExtraFieldTemplate `json:"fields"`
}
)

View File

@@ -0,0 +1,31 @@
package dbtypes
type (
Profile struct {
Id string
Name string
PhoneNumber string
Email string
}
)
type (
ProfileGetRequest struct {
Id string
}
ProfileGetResponse struct {
Profile *Profile
}
)
type (
ProfileUpdateRequest struct {
Id string
Name *string
PhoneNumber *string
Email *string
}
ProfileUpdateResponse struct{}
)

View File

@@ -0,0 +1,100 @@
package dbtypes
type SubmissionStatus string
const (
SubStatusUnspecified SubmissionStatus = "unspecified"
SubStatusNew SubmissionStatus = "new"
SubStatusPending SubmissionStatus = "pending"
SubStatusOnInterview SubmissionStatus = "on_interview"
SubStatusApproved SubmissionStatus = "approved"
SubStatusCancelled SubmissionStatus = "cancelled"
SubStatusRejected SubmissionStatus = "rejected"
)
func NewSubmissionStatus(status *string) *SubmissionStatus {
if status == nil {
return nil
}
res := SubmissionStatus(*status)
return &res
}
type (
Submission struct {
Id string
AgentInfo *AgentInfo
VacancyInfo *VacancyInfo
CandidateInfo *CandidateInfo
Status SubmissionStatus
}
AgentInfo struct {
Id string
}
VacancyInfo struct {
Id string
}
CandidateInfo struct {
Id string
FirstName string
LastName string
MiddleName string
PhoneNumber string
Email string
Birthday string
CvLink *string
Resume *string
}
)
type (
SubmissionListGetRequest struct {
Filters *SubmissionListGetFilters
Page uint64
PageSize uint64
}
SubmissionListGetFilters struct {
AgentId *string
VacancyId *string
Status *SubmissionStatus
}
SubmissionListGetResponse struct {
Submissions []Submission
}
)
type (
SubmissionCreateRequest struct {
AgentId string
VacancyId string
CandidateInfo *CandidateInfo
}
SubmissionCreateResponse struct {
Id string
}
)
type (
SubmissionStatusUpdateRequest struct {
Id string
Status SubmissionStatus
}
SubmissionStatusUpdateResponse struct{}
)
type (
SubmissionDeleteRequest struct {
Id string
}
SubmissionDeleteResponse struct{}
)

View File

@@ -0,0 +1,57 @@
package dbtypes
type ClientValidationStatus string
const (
ClientValStatusNew ClientValidationStatus = "new"
ClientValStatusPending ClientValidationStatus = "on review"
ClientValStatusApproved ClientValidationStatus = "confirmed"
ClientValStatusRejected ClientValidationStatus = "rejected"
)
type (
ClientValidation struct {
Status ClientValidationStatus `json:"status"`
Description string `json:"description"`
}
)
type (
ClientValidationGetRequest struct {
UserId string
}
ClientValidationGetResponse struct {
ClientValidation *ClientValidation `json:"moderation"`
}
)
type UserType int32
const (
UserTypeAgent UserType = 0 // NOTE: no iota here
UserTypeDistributor UserType = 1
)
type (
User struct {
Id string
FullName string
Phone string
Email string
Type UserType
}
)
type (
UserSaveRequest struct {
Id string
FullName string
Phone string
Email string
Type UserType
}
UserSaveResponse struct {
}
)

View File

@@ -0,0 +1,184 @@
package dbtypes
import "time"
type VacancyStatus string
const (
VacUnspecified VacancyStatus = "unspecified"
VacNew VacancyStatus = "new"
VacPending VacancyStatus = "pending"
VacApproved VacancyStatus = "approved"
VacRejected VacancyStatus = "rejected"
)
func NewVacancyStatus(status *string) *VacancyStatus {
if status == nil {
return nil
}
res := VacancyStatus(*status)
return &res
}
// <=============================>
// Common Vacancy types
// <=============================>
type (
Vacancy struct {
Id string
Company VacancyCompanyInfo
Name string
Address string
WorkFormat string
AgentReward *int32
SalaryTop int32
SalaryBottom int32
Requirements *string
Responsibilities *string
ExtraInfo *string
Region string
IsArchived bool
TargetAction VacancyTargetAction
Moderation VacancyModeration
RequiredCandidates int32
CurrentCandidates int32
ExtraFields *string
CreatedAt time.Time
}
VacancyCompanyInfo struct {
Id string
Name string
LogoLink *string
}
VacancyTargetAction struct {
Action string
Duration int32
}
VacancyModeration struct {
Status VacancyStatus
DescriptionHistory []VacancyModerationDescription
}
VacancyModerationDescription struct {
Description *string
CreatedAt time.Time
}
)
// <=============================>
// Get Vacancy List
// <=============================>
type (
VacancyListGetRequest struct {
Filters *VacancyListFilters
Page uint64
PageSize uint64
}
VacancyListFilters struct {
DistributorId *string
CompanyId *string
VacancyId *string
Region *string
SalaryBottom *int32
SalaryTop *int32
IsArchived *bool
Status *VacancyStatus
}
VacancyListGetResponse struct {
Vacancies []Vacancy
}
)
// <=============================>
// Create Vacancy
// <=============================>
type (
VacancyCreateRequest struct {
CompanyId string
Name string
Address string
WorkFormat string
AgentReward *int32
SalaryTop int32
SalaryBottom int32
Requirements *string
Responsibilities *string
ExtraInfo *string
Region string
TargetAction VacancyTargetAction
RequiredCandidates int32
CurrentCandidates int32
ExtraFields *string
}
VacancyCreateResponse struct {
Id string
}
)
// <=============================>
// Update Vacancy
// <=============================>
type (
VacancyUpdateRequest struct {
Id string
Name *string
Address *string
WorkFormat *string
AgentReward *int32
SalaryTop *int32
SalaryBottom *int32
Requirements *string
Responsibilities *string
ExtraInfo *string
Region *string
TargetAction VacancyTargetActionForUpdate
RequiredCandidates *int32
ExtraFields *string
}
VacancyTargetActionForUpdate struct {
Action *string
Duration *int32
}
VacancyUpdateResponse struct {
}
)
// <=============================>
// Delete Vacancy
// <=============================>
type (
VacancyDeleteRequest struct {
Id string
}
VacancyDeleteResponse struct {
}
)
// <=============================>
// Send Vacancy to Moderation
// <=============================>
type (
SendVacancyToModerationRequest struct {
Id string
}
SendVacancyToModerationResponse struct {
}
)

17
internal/feed/errors.go Normal file
View File

@@ -0,0 +1,17 @@
package feed
import "errors"
// Ошибки, связанные с валидацией входных данных
var (
// ErrCancellationReasonRequired Возвращается при попытке отмены события без указания причины
ErrCancellationReasonRequired = errors.New("cancellation reason is required for feed event cancellation")
// ErrAttachmentIDRequired Возвращается при попытке отмены события без указания Id вложения
ErrAttachmentIDRequired = errors.New("attachment Id is required for feed event cancellation")
// ErrUserIDRequired Возвращается при попытке отмены события без указания Id пользователя
ErrUserIDRequired = errors.New("user Id cancellation is required for feed event cancellation")
// ErrCreationInvalidData Возвращается при попытке создания события без указания Id пользователя, или типа события, или сообщения
ErrCreationInvalidData = errors.New("invalid event data provided for creation (missing owner, type, or message)")
ErrNotFound = errors.New("not found")
)

9
internal/feed/filters.go Normal file
View File

@@ -0,0 +1,9 @@
package feed
type Filter struct {
OwnerID string // Id пользователя
EventTypes []EventType // Фильтр по типам событий
Limit uint64 // Лимит записей
Offset uint64 // Смещение
ShowCancelled bool // Показывать отмененные
}

101
internal/feed/handlers.go Normal file
View File

@@ -0,0 +1,101 @@
package feed
import (
"context"
"fmt"
"log/slog"
)
type Handler struct {
Service *Service
logger *slog.Logger
}
func NewFeedHandler(logger *slog.Logger, service *Service) *Handler {
return &Handler{
Service: service,
logger: logger,
}
}
func (h *Handler) CreateEvent(ctx context.Context, event *Event) error {
if event == nil {
h.logger.Error("CreateEvent: empty event",
slog.String("error", ErrCreationInvalidData.Error()))
return ErrCreationInvalidData
}
h.logger.Debug("CreateEvent: Attempting to create event",
slog.String("type", event.EventType.String()),
slog.String("ownerID", event.OwnerId))
if event.OwnerId == "" || event.EventType == "" || event.Message == "" {
h.logger.Error("CreateEvent: Validation error",
slog.String("error", ErrCreationInvalidData.Error()),
slog.String("type", event.EventType.String()),
slog.String("ownerID", event.OwnerId),
slog.String("message", event.Message),
)
return ErrCreationInvalidData
}
if err := h.Service.AddUserEvent(ctx, event); err != nil {
h.logger.Error("CreateEvent: Service error",
slog.String("error", err.Error()),
slog.String("type", event.EventType.String()),
slog.String("ownerID", event.OwnerId))
return fmt.Errorf("Error creating event: %w", err)
}
h.logger.Debug("CreateEvent: Successfully created event",
slog.String("eventID", event.Id),
slog.String("type", event.EventType.String()),
slog.String("ownerID", event.OwnerId))
return nil
}
func (h *Handler) CancelEvent(ctx context.Context, attachmentId string, reason string) error {
h.logger.Debug("CancelEvent: Attempting to cancel event",
slog.String("attachmentID", attachmentId),
)
if attachmentId == "" {
h.logger.Error("CancelEvent: Validation error",
slog.String("error", "attachment Id is required"))
return ErrAttachmentIDRequired
}
if reason == "" {
h.logger.Error("CancelEvent: Validation error",
slog.String("error", "cancellation reason is required"),
slog.String("attachmentID", attachmentId))
return ErrCancellationReasonRequired
}
if err := h.Service.CancelEvents(ctx, attachmentId, reason); err != nil {
h.logger.Error("CancelEvent: Service error",
slog.String("error", err.Error()),
slog.String("attachmentID", attachmentId))
return fmt.Errorf("error cancelling event: %w", err)
}
h.logger.Debug("CancelEvent: Successfully cancelled event",
slog.String("attachmentID", attachmentId))
return nil
}
func (h *Handler) GetCompanyIdByUidTmp(ctx context.Context, ownerID string) ([]string, error) {
return h.Service.GetCompanyIdsByUid(ctx, ownerID)
}
func (h *Handler) GetAgentIdBySubmissionId(ctx context.Context, submissionId string) (string, error) {
return h.Service.GetAgentIdBySubmissionId(ctx, submissionId)
}

91
internal/feed/models.go Normal file
View File

@@ -0,0 +1,91 @@
package feed
import (
"database/sql"
"time"
)
type (
EventType string
UserRole string
Visibility string
)
const (
// User Roles
RoleAgent UserRole = "agent"
RoleDistributor UserRole = "distributor"
// Visibility Types
VisibilityPublic Visibility = "public" // Показывается всем агентам(инициатор может быть только дистр)
VisibilityPrivate Visibility = "private" // Показывается только инициатору события
VisibilityCompanyWide Visibility = "company_wide" // Показывается всем в компании
// Event Types (Common)
EventWelcome EventType = "welcome"
EventNewCompanyMember EventType = "new_company_member"
// Users Events
EventProfileChanged EventType = "profile_changed"
EventCompanyCreated EventType = "company_created"
EventCompanyChanged EventType = "company_changed"
EventVacancyCreated EventType = "vacancy_created"
EventVacancyChanged EventType = "vacancy_changed"
EventVacancyModerationSent EventType = "vacancy_moderation_sent"
EventSubmissionStatusChanged EventType = "submission_status_changed"
EventTransactionCreated EventType = "transaction_created"
EventBankAccountChanged EventType = "bank_details_changed"
EventBankAccountCreated EventType = "bank_account_created"
EventPostAnketa EventType = "post_anketa"
)
type Event struct {
Id string `json:"id" db:"id"`
OwnerId string `json:"owner_id" db:"owner_id"`
OwnerType UserRole `json:"owner_type" db:"owner_type"`
Message string `json:"message" db:"message"`
Visibility Visibility `json:"visibility" db:"visibility"`
CompanyID *string `json:"company_id,omitempty"`
EventType EventType `json:"event_type" db:"event_type"`
Payload EventPayload `json:"payload" db:"payload"`
IsCancelled bool `json:"is_cancelled" db:"is_cancelled"`
CancellationReason *string `json:"cancellation_reason" db:"cancellation_reason"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
func (e EventType) String() string {
return string(e)
}
func (u UserRole) String() string {
return string(u)
}
func (e *Event) processNullableFields(companyID, cancellationReason sql.NullString) {
if companyID.Valid {
e.CompanyID = &companyID.String
}
if cancellationReason.Valid {
e.CancellationReason = &cancellationReason.String
}
}
type EventPayload struct {
AttachmentId string `json:"attachment_id" db:"attachment_id"`
AttachmentType AttachmentType `json:"attachment_type" db:"attachment_type"`
AdditionalReceiver string `json:"additional_receiver,omitempty" db:"additional_receiver"` // may be uid or company id
CustomData string `json:"custom_data,omitempty"`
}
type AttachmentType string
const (
AttachmentTypeVacancy AttachmentType = "vacancy"
AttachmentTypeCV AttachmentType = "cv"
AttachmentTypeProfile AttachmentType = "profile"
AttachmentTypeCompany AttachmentType = "company"
AttachmentTypeBankAccount AttachmentType = "bank_account"
AttachmentTypeSubmission AttachmentType = "submission"
)

325
internal/feed/service.go Normal file
View File

@@ -0,0 +1,325 @@
package feed
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
"log/slog"
"time"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database"
sq "github.com/Masterminds/squirrel"
"github.com/google/uuid"
"github.com/lib/pq"
)
type Service struct {
db *sql.DB
schemaName string
logger *slog.Logger
dbClient database.Client //nolint:unused // TODO: переписать на этого клиента в рамках https://tracker.yandex.ru/MOLVARAZRABOTKA-363
}
func NewService(dbUrl, schemaName string, logger *slog.Logger, dbClient database.Client) (*Service, error) {
db, err := sql.Open("postgres", dbUrl)
if err != nil {
return nil, fmt.Errorf("error opening database connection: %w", err)
}
if err := db.Ping(); err != nil {
return nil, fmt.Errorf("error pinging database: %w", err)
}
return &Service{
db: db,
schemaName: schemaName,
logger: logger,
}, nil
}
func (s *Service) GetUserEvents(ctx context.Context, filter Filter, userType string) ([]Event, error) {
companyIDs, err := s.GetCompanyIdsByUid(ctx, filter.OwnerID)
if err != nil {
return nil, err
}
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
baseQuery := psql.Select(
"id", "owner_id", "owner_type", "message", "event_type", "visibility", "company_id",
"payload", "is_cancelled", "cancellation_reason", "created_at", "updated_at",
).From(fmt.Sprintf("%s.%s", pq.QuoteIdentifier(s.schemaName), constants.FeedEventsTableName))
conditions := []sq.Sqlizer{
sq.Eq{"owner_id": filter.OwnerID},
sq.And{
sq.Eq{"visibility": VisibilityCompanyWide},
sq.Expr("company_id = ANY(?)", pq.Array(companyIDs)),
},
sq.And{
sq.Expr("payload->>'additional_receiver' IS NOT NULL"),
sq.Or{
sq.Expr("(payload->>'additional_receiver')::uuid = ?::uuid", filter.OwnerID),
sq.Expr("(payload->>'additional_receiver')::text = ANY(?)", pq.Array(companyIDs)),
},
},
}
if userType == RoleAgent.String() {
conditions = append(conditions, sq.Eq{"visibility": VisibilityPublic})
}
query := baseQuery.Where(sq.Or(conditions))
if len(filter.EventTypes) > 0 {
query = query.Where(sq.Expr("event_type = ANY(?)", pq.Array(filter.EventTypes)))
}
if !filter.ShowCancelled {
query = query.Where(sq.Eq{"is_cancelled": false})
}
query = query.OrderBy("created_at DESC").
Limit(filter.Limit).
Offset(filter.Offset)
sqlQuery, args, err := query.ToSql()
if err != nil {
return nil, fmt.Errorf("failed to build query: %w", err)
}
s.logger.Debug("Executing GetUserEvents query", "query", sqlQuery, "args", args)
rows, err := s.db.QueryContext(ctx, sqlQuery, args...)
if err != nil {
return nil, fmt.Errorf("failed to query events: %w", err)
}
defer rows.Close()
var events []Event
for rows.Next() {
event, err := s.scanEventRow(rows)
if err != nil {
return nil, err
}
events = append(events, event)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("error iterating event rows: %w", err)
}
s.logger.Debug("GetUserEvents completed successfully",
slog.Int("count", len(events)),
slog.String("owner_id", filter.OwnerID),
slog.String("user_type", userType),
slog.String("company_ids", fmt.Sprintf("%v", companyIDs)),
slog.Any("filter", filter),
)
return events, nil
}
func (s *Service) GetCompanyIdsByUid(ctx context.Context, ownerID string) ([]string, error) {
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := psql.Select("company_id").
From(fmt.Sprintf("%s.%s", pq.QuoteIdentifier(s.schemaName), constants.ClientTableName)).
Where(sq.Eq{"uid": ownerID})
sqlQuery, args, err := query.ToSql()
if err != nil {
return nil, fmt.Errorf("failed to build query: %w", err)
}
var companyID sql.NullString
if err = s.db.QueryRowContext(ctx, sqlQuery, args...).Scan(&companyID); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return []string{}, nil
}
return nil, fmt.Errorf("failed to get company Id: %w", err)
}
if companyID.Valid {
return []string{companyID.String}, nil
}
return []string{}, nil
}
func (s *Service) scanEventRow(rows *sql.Rows) (Event, error) {
var (
event Event
payload []byte
companyIDScan sql.NullString
cancellationReasonScan sql.NullString
)
if err := rows.Scan(
&event.Id,
&event.OwnerId,
&event.OwnerType,
&event.Message,
&event.EventType,
&event.Visibility,
&companyIDScan,
&payload,
&event.IsCancelled,
&cancellationReasonScan,
&event.CreatedAt,
&event.UpdatedAt,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return Event{}, nil
}
return Event{}, fmt.Errorf("failed to scan event: %w", err)
}
event.processNullableFields(companyIDScan, cancellationReasonScan)
event.processPayload(payload)
return event, nil
}
func (e *Event) processPayload(payload []byte) {
if len(payload) == 0 {
e.Payload = EventPayload{}
return
}
if err := json.Unmarshal(payload, &e.Payload); err != nil {
e.Payload = EventPayload{}
}
}
func (s *Service) AddUserEvent(ctx context.Context, event *Event) error {
if event == nil {
return ErrCreationInvalidData
}
if event.Id == "" {
event.Id = "MSG_" + uuid.New().String()
}
now := time.Now()
event.CreatedAt = now
event.UpdatedAt = now
payloadBytes, err := json.Marshal(event.Payload)
if err != nil {
return fmt.Errorf("failed to marshal payload: %w", err)
}
var payloadArg interface{} = payloadBytes
if string(payloadBytes) == "null" || string(payloadBytes) == "{}" {
payloadArg = nil
}
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := psql.Insert(fmt.Sprintf("%s.%s", pq.QuoteIdentifier(s.schemaName), constants.FeedEventsTableName)).
Columns(
"id", "owner_id", "owner_type", "message", "event_type", "visibility", "company_id",
"payload", "is_cancelled", "cancellation_reason", "created_at", "updated_at",
).
Values(
event.Id,
event.OwnerId,
event.OwnerType,
event.Message,
event.EventType,
event.Visibility,
event.CompanyID,
payloadArg,
event.IsCancelled,
event.CancellationReason,
event.CreatedAt,
event.UpdatedAt,
)
sqlQuery, args, err := query.ToSql()
if err != nil {
return fmt.Errorf("failed to build query: %w", err)
}
_, err = s.db.ExecContext(ctx, sqlQuery, args...)
if err != nil {
return fmt.Errorf("failed to insert event: %w", err)
}
s.logger.Debug("Event added successfully", "event_id", event.Id)
return nil
}
func (s *Service) CancelEvents(ctx context.Context, attachmentID, cancellationReason string) error {
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := psql.Update(fmt.Sprintf("%s.%s", pq.QuoteIdentifier(s.schemaName), constants.FeedEventsTableName)).
Set("is_cancelled", true).
Set("cancellation_reason", cancellationReason).
Set("updated_at", sq.Expr("NOW()")).
Where(sq.Expr("payload ->> 'attachment_id' = ?", attachmentID)).
Where(sq.Eq{"is_cancelled": false})
sqlQuery, args, err := query.ToSql()
if err != nil {
return fmt.Errorf("failed to build query: %w", err)
}
result, err := s.db.ExecContext(ctx, sqlQuery, args...)
if err != nil {
return fmt.Errorf("failed to execute cancel events query for attachmentID %s: %w", attachmentID, err)
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return fmt.Errorf("failed to get affected rows for attachmentID %s: %w", attachmentID, err)
}
if rowsAffected == 0 {
s.logger.Debug("No active events found or updated for cancellation", "attachment_id", attachmentID)
} else {
s.logger.Debug("Events cancelled successfully", "attachment_id", attachmentID, "count", rowsAffected)
}
return nil
}
func (s *Service) GetAgentIdBySubmissionId(ctx context.Context, submissionId string) (string, error) {
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
query := psql.Select("uid").
From(fmt.Sprintf("%s.%s", pq.QuoteIdentifier(s.schemaName), constants.SubmissionTableName)).
Where(sq.Eq{"id": submissionId})
sqlQuery, args, err := query.ToSql()
if err != nil {
return "", fmt.Errorf("failed to build query: %w", err)
}
var agentId string
if err = s.db.QueryRowContext(ctx, sqlQuery, args...).Scan(&agentId); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return "", ErrNotFound
}
return "", fmt.Errorf("failed to get agent Id: %w", err)
}
if agentId == "" {
s.logger.Debug("Agent Id not found", "submission_id", submissionId)
return "", ErrNotFound
}
return agentId, nil
}

View File

@@ -0,0 +1,15 @@
package filemanager
import "errors"
var (
ErrInvalidFileType = errors.New("invalid file type")
ErrParameterNotFound = errors.New("parameter required, but not found")
ErrFileNotFound = errors.New("file not found")
ErrFileAlreadyExists = errors.New("file already exists")
ErrFailedUploadFile = errors.New("failed to upload file to S3")
ErrFailedToCacheUrl = errors.New("failed to cache URL")
ErrMsgReadFile = errors.New("failed to read file")
ErrMsgGetPresignedURL = errors.New("failed to get presigned URL")
)

View File

@@ -0,0 +1,127 @@
package storage
import (
"context"
"io"
"mime/multipart"
"os"
"path/filepath"
filemanager "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/file_manager"
)
type Storage struct {
basePath string
}
func New(basePath string) *Storage {
return &Storage{
basePath: basePath,
}
}
func (s *Storage) GetFilePaths(
ctx context.Context,
fileType filemanager.FileType,
parameters filemanager.ParameterTable,
) ([]string, error) {
var dirPath string
fileNames := make([]string, 0)
switch fileType {
case filemanager.AvatarFileType:
userId, ok := parameters[filemanager.UserIdParam]
if !ok {
return nil, filemanager.ErrParameterNotFound
}
dirPath = filepath.Join(s.basePath, userId.(string), "avatars")
case filemanager.CVFileType:
submId, ok := parameters[filemanager.SubmissionIdParam]
if !ok {
return nil, filemanager.ErrParameterNotFound
}
dirPath = filepath.Join(s.basePath, "CVs", submId.(string))
default:
return nil, filemanager.ErrInvalidFileType
}
if _, err := os.Stat(dirPath); os.IsNotExist(err) {
return nil, filemanager.ErrFileNotFound
}
if err := filepath.WalkDir(dirPath, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
return nil
}
fileNames = append(fileNames, path)
return nil
}); err != nil {
return nil, err
}
if len(fileNames) == 0 {
return nil, filemanager.ErrFileNotFound
}
return fileNames, nil
}
func (s *Storage) SaveFile(
ctx context.Context,
fileType filemanager.FileType,
file multipart.File,
fileHeader *multipart.FileHeader,
parameters filemanager.ParameterTable,
) error {
var dirPath string
switch fileType {
case filemanager.AvatarFileType:
userId, ok := parameters[filemanager.UserIdParam]
if !ok {
return filemanager.ErrParameterNotFound
}
dirPath = filepath.Join(s.basePath, userId.(string), "avatars")
case filemanager.CVFileType:
submId, ok := parameters[filemanager.SubmissionIdParam]
if !ok {
return filemanager.ErrParameterNotFound
}
dirPath = filepath.Join(s.basePath, "CVs", submId.(string))
default:
return filemanager.ErrInvalidFileType
}
if err := os.MkdirAll(dirPath, 0755); err != nil {
return err
}
filePath := filepath.Join(dirPath, fileHeader.Filename)
dstFile, err := os.Create(filePath)
if err != nil {
return err
}
defer dstFile.Close()
if _, err := io.Copy(dstFile, file); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,39 @@
package filemanager
import (
"context"
"mime/multipart"
)
type FileType string
const (
AvatarFileType FileType = "avatar"
CVFileType FileType = "cv"
)
type ParameterType string
const (
UserIdParam ParameterType = "user_id"
VacancyIdParam ParameterType = "vacancy_id"
SubmissionIdParam ParameterType = "submission_id"
)
type ParameterTable map[ParameterType]any
type UserFileManager interface {
GetFilePaths(
ctx context.Context,
fileType FileType,
parameters ParameterTable,
) ([]string, error)
SaveFile(
ctx context.Context,
fileType FileType,
file multipart.File,
fileHeader *multipart.FileHeader,
parameters ParameterTable,
) error
}

View File

@@ -0,0 +1,156 @@
package s3_storage
import (
"bytes"
"context"
"errors"
"fmt"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/cache"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/constants"
filemanager "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/file_manager"
"git-molva.ru/Molva/molva-backend/services/api_gateway/internal/object_storage"
"github.com/aws/smithy-go/ptr"
"mime"
"mime/multipart"
"path/filepath"
"strings"
"time"
)
type S3Storage struct {
objectStorage object_storage.Client
cacheClient cache.Client
}
func NewS3Storage(objectStorage object_storage.Client, cacheClient cache.Client) *S3Storage {
return &S3Storage{
objectStorage: objectStorage,
cacheClient: cacheClient,
}
}
func (s *S3Storage) GetFilePaths(
ctx context.Context,
fileType filemanager.FileType,
parameters filemanager.ParameterTable,
) ([]string, error) {
objectKey, category, err := s.buildObjectKey(fileType, parameters)
if err != nil {
return nil, err
}
// Сначала пытаемся получить URL из кэша
cachedURL, err := s.getCachedURL(ctx, objectKey, category)
if err == nil && cachedURL != "" {
return []string{cachedURL}, nil
}
// Получаем линк из s3
url, err := s.objectStorage.GetPresignedLink(ctx, objectKey, category,
object_storage.LinkOptions{
TTL: ptr.Duration(constants.DefaultFileTTL),
})
if err != nil {
if errors.Is(err, object_storage.ErrObjectNotFound) {
return nil, filemanager.ErrFileNotFound
}
return nil, fmt.Errorf("%s: %w", filemanager.ErrMsgGetPresignedURL, err)
}
// Кэшируем URL
if err := s.cacheURL(ctx, objectKey, category, url); err != nil {
return nil, fmt.Errorf("%s: %w", filemanager.ErrFailedToCacheUrl, err)
}
return []string{url}, nil
}
func (s *S3Storage) SaveFile(
ctx context.Context,
fileType filemanager.FileType,
file multipart.File,
fileHeader *multipart.FileHeader,
parameters filemanager.ParameterTable,
) error {
objectKey, category, err := s.buildObjectKey(fileType, parameters)
if err != nil {
return err
}
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(file); err != nil {
return fmt.Errorf("%s: %w", filemanager.ErrMsgReadFile, err)
}
// Определяем тип контента
contentType := s.getContentType(fileHeader.Filename)
// Загружаем файл в S3
err = s.objectStorage.PutNewObject(ctx, objectKey, category,
bytes.NewReader(buf.Bytes()),
object_storage.PutOptions{
ContentType: contentType,
})
if err != nil {
// Обрабатываем случай существующего файла
if errors.Is(err, object_storage.ErrObjectAlreadyExists) {
return filemanager.ErrFileAlreadyExists
}
return fmt.Errorf("%s: %w", filemanager.ErrFailedUploadFile, err)
}
return nil
}
// Создаем ключ объекта S3 на основе типа файла и параметров
func (s *S3Storage) buildObjectKey(fileType filemanager.FileType, parameters filemanager.ParameterTable) (string, object_storage.Category, error) {
switch fileType {
case filemanager.AvatarFileType:
userID, ok := parameters[filemanager.UserIdParam]
if !ok {
return "", "", filemanager.ErrParameterNotFound
}
return fmt.Sprintf(objectKeyAvatarTemplate, userID), object_storage.LogoCategory, nil
case filemanager.CVFileType:
submissionID, ok := parameters[filemanager.SubmissionIdParam]
if !ok {
return "", "", filemanager.ErrParameterNotFound
}
return fmt.Sprintf(objectKeyCVTemplate, submissionID), object_storage.DocumentCategory, nil
default:
return "", "", filemanager.ErrInvalidFileType
}
}
// getContentType определяет тип контента по расширению
func (s *S3Storage) getContentType(filename string) string {
ext := strings.ToLower(filepath.Ext(filename))
if ct, ok := ContentTypes[ext]; ok {
return ct
}
if ct := mime.TypeByExtension(ext); ct != "" {
return ct
}
return defaultContentType
}
func (s *S3Storage) getCachedURL(ctx context.Context, objectKey string, category object_storage.Category) (string, error) {
cacheKey := fmt.Sprintf(cacheKeyTemplate, category, objectKey)
return s.cacheClient.Get(ctx, cacheKey, cache.DocumentsValueType)
}
func (s *S3Storage) cacheURL(ctx context.Context, objectKey string, category object_storage.Category, url string) error {
cacheKey := fmt.Sprintf(cacheKeyTemplate, category, objectKey)
cacheDuration := constants.DefaultFileTTL - time.Hour
return s.cacheClient.Set(ctx, cacheKey, cache.DocumentsValueType, url, cacheDuration)
}

View File

@@ -0,0 +1,22 @@
package s3_storage
var ContentTypes = map[string]string{
".pdf": "application/pdf",
".txt": "text/plain",
".doc": "application/msword",
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
".rtf": "application/rtf",
".odt": "application/vnd.oasis.opendocument.text",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".webp": "image/webp",
}
// Константы для ключей
const (
objectKeyAvatarTemplate = "%s_avatar"
objectKeyCVTemplate = "%s_cv"
cacheKeyTemplate = "%s_%s"
defaultContentType = "application/octet-stream"
)

View File

@@ -0,0 +1,65 @@
package formgenerator
import (
"embed"
"errors"
"html/template"
"io/fs"
"strings"
)
//go:embed templates/index.html
var formTemplate string
//go:embed templates
var formFS embed.FS
var (
requiredFields []string = []string{
"VacancyName",
"Address",
"WorkFormat",
"SalaryTop",
"SalaryBottom",
"Requirements",
"Responsibilities",
"Description",
"VacancyId",
"AgentId",
}
)
var (
ErrNotFound = errors.New("One of the required fields is not set")
)
func GetFileSystem() (fs.FS, error) {
formFs, err := fs.Sub(formFS, "templates")
if err != nil {
return nil, err
}
return formFs, nil
}
func GenerateForm(formData map[string]string) (string, error) {
for _, field := range requiredFields {
if _, ok := formData[field]; !ok {
return "", ErrNotFound
}
}
tmpl, err := template.New("index.html").Parse(formTemplate)
if err != nil {
return "", err
}
var buf strings.Builder
if err = tmpl.Execute(&buf, formData); err != nil {
return "", err
}
return buf.String(), nil
}

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
"DQUHFmFzc2V0cy9pbWFnZXMvbG9nby5zdmcMAQ0BBwVhc3NldAcWYXNzZXRzL2ltYWdlcy9sb2dvLnN2ZwcdYXNzZXRzL2ltYWdlcy9yZXN1bWUtZmlsZS5zdmcMAQ0BBwVhc3NldAcdYXNzZXRzL2ltYWdlcy9yZXN1bWUtZmlsZS5zdmcHHWFzc2V0cy9pbWFnZXMvcmVzdW1lLWxpbmsuc3ZnDAENAQcFYXNzZXQHHWFzc2V0cy9pbWFnZXMvcmVzdW1lLWxpbmsuc3ZnBxZhc3NldHMvaW1hZ2VzL3NlbmQuc3ZnDAENAQcFYXNzZXQHFmFzc2V0cy9pbWFnZXMvc2VuZC5zdmcHMnBhY2thZ2VzL2N1cGVydGlub19pY29ucy9hc3NldHMvQ3VwZXJ0aW5vSWNvbnMudHRmDAENAQcFYXNzZXQHMnBhY2thZ2VzL2N1cGVydGlub19pY29ucy9hc3NldHMvQ3VwZXJ0aW5vSWNvbnMudHRm"

View File

@@ -0,0 +1 @@
{"assets/images/logo.svg":["assets/images/logo.svg"],"assets/images/resume-file.svg":["assets/images/resume-file.svg"],"assets/images/resume-link.svg":["assets/images/resume-link.svg"],"assets/images/send.svg":["assets/images/send.svg"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]}

View File

@@ -0,0 +1 @@
[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}]

View File

@@ -0,0 +1,8 @@
<svg width="138" height="28" viewBox="0 0 138 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.1226 15.512L6.39303 0.519165H0V26.4807H7.23678V16.0636L13.2404 26.4807H16.7776L22.8462 15.7067L22.9111 26.4807H30.1154V0.519165H23.6575L15.1226 15.512Z" fill="#1454B2"/>
<path d="M55.0384 1.7524C52.8641 0.584135 50.3978 0 47.6718 0C44.9459 0 42.4795 0.584135 40.3053 1.7524C38.131 2.92067 36.3786 4.54327 35.1454 6.58774C33.9122 8.63221 33.2632 10.9688 33.2632 13.5325C33.2632 16.0962 33.8798 18.4327 35.1454 20.4772C36.3786 22.5216 38.131 24.1442 40.3053 25.3125C42.4795 26.4808 44.9459 27.0649 47.6718 27.0649C50.3978 27.0649 52.8641 26.4808 55.0384 25.3125C57.2127 24.1442 58.9651 22.5216 60.1983 20.4772C61.4315 18.4327 62.0805 16.0962 62.0805 13.5325C62.0805 10.9688 61.4639 8.63221 60.1983 6.58774C58.9651 4.51082 57.2127 2.88822 55.0384 1.7524ZM50.9819 19.5685C50.0084 20.1526 48.8726 20.4447 47.6718 20.4447C46.4387 20.4447 45.3353 20.1526 44.3293 19.5685C43.3557 18.9844 42.5444 18.1731 41.9927 17.1346C41.4086 16.0962 41.1165 14.863 41.1165 13.5C41.1165 12.137 41.4086 10.9038 41.9927 9.86539C42.5769 8.82692 43.3557 8.01562 44.3293 7.43149C45.3028 6.84736 46.4387 6.55529 47.6718 6.55529C48.905 6.55529 50.0084 6.84736 50.9819 7.43149C51.9555 8.01562 52.7668 8.82692 53.3185 9.86539C53.9026 10.9038 54.1947 12.137 54.1947 13.5C54.1947 14.863 53.9026 16.0962 53.3185 17.1346C52.7668 18.1731 51.9879 19.0168 50.9819 19.5685Z" fill="#1454B2"/>
<path d="M73.0167 0.519165H65.2283V26.4807H85.1213V20.185H73.0167V0.519165Z" fill="#1454B2"/>
<path d="M90.833 0.519165H82.428L93.5265 26.4807H100.99L101.347 25.6694L90.833 0.519165Z" fill="#1454B2"/>
<path d="M104.073 19.2439L112.121 0.519165H104.365L100.276 10.0925L104.073 19.2439Z" fill="#3B9BF2"/>
<path d="M126.465 0.519165H119.423L125.492 15.6418H119.877H112.316L107.546 26.4807H115.529L117.541 21.548H127.861L129.84 26.4807H137.986L126.465 0.519165Z" fill="#1454B2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,192 @@
var CanvasKitInit = (() => {
var _scriptName = import.meta.url;
return (
function(moduleArg = {}) {
var moduleRtn;
var r=moduleArg,aa,ca,da=new Promise((a,b)=>{aa=a;ca=b}),ea="object"==typeof window,ha="function"==typeof importScripts;
(function(a){a.ce=a.ce||[];a.ce.push(function(){a.MakeSWCanvasSurface=function(b){var c=b,e="undefined"!==typeof OffscreenCanvas&&c instanceof OffscreenCanvas;if(!("undefined"!==typeof HTMLCanvasElement&&c instanceof HTMLCanvasElement||e||(c=document.getElementById(b),c)))throw"Canvas with id "+b+" was not found";if(b=a.MakeSurface(c.width,c.height))b.Ae=c;return b};a.MakeCanvasSurface||(a.MakeCanvasSurface=a.MakeSWCanvasSurface);a.MakeSurface=function(b,c){var e={width:b,height:c,colorType:a.ColorType.RGBA_8888,
alphaType:a.AlphaType.Unpremul,colorSpace:a.ColorSpace.SRGB},f=b*c*4,k=a._malloc(f);if(e=a.Surface._makeRasterDirect(e,k,4*b))e.Ae=null,e.$e=b,e.Xe=c,e.Ye=f,e.He=k,e.getCanvas().clear(a.TRANSPARENT);return e};a.MakeRasterDirectSurface=function(b,c,e){return a.Surface._makeRasterDirect(b,c.byteOffset,e)};a.Surface.prototype.flush=function(b){a.$d(this.Zd);this._flush();if(this.Ae){var c=new Uint8ClampedArray(a.HEAPU8.buffer,this.He,this.Ye);c=new ImageData(c,this.$e,this.Xe);b?this.Ae.getContext("2d").putImageData(c,
0,0,b[0],b[1],b[2]-b[0],b[3]-b[1]):this.Ae.getContext("2d").putImageData(c,0,0)}};a.Surface.prototype.dispose=function(){this.He&&a._free(this.He);this.delete()};a.$d=a.$d||function(){};a.Be=a.Be||function(){return null}})})(r);
(function(a){a.ce=a.ce||[];a.ce.push(function(){function b(l,p,v){return l&&l.hasOwnProperty(p)?l[p]:v}function c(l){var p=ja(ka);ka[p]=l;return p}function e(l){return l.naturalHeight||l.videoHeight||l.displayHeight||l.height}function f(l){return l.naturalWidth||l.videoWidth||l.displayWidth||l.width}function k(l,p,v,w){l.bindTexture(l.TEXTURE_2D,p);w||v.alphaType!==a.AlphaType.Premul||l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);return p}function n(l,p,v){v||p.alphaType!==a.AlphaType.Premul||
l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);l.bindTexture(l.TEXTURE_2D,null)}a.GetWebGLContext=function(l,p){if(!l)throw"null canvas passed into makeWebGLContext";var v={alpha:b(p,"alpha",1),depth:b(p,"depth",1),stencil:b(p,"stencil",8),antialias:b(p,"antialias",0),premultipliedAlpha:b(p,"premultipliedAlpha",1),preserveDrawingBuffer:b(p,"preserveDrawingBuffer",0),preferLowPowerToHighPerformance:b(p,"preferLowPowerToHighPerformance",0),failIfMajorPerformanceCaveat:b(p,"failIfMajorPerformanceCaveat",
0),enableExtensionsByDefault:b(p,"enableExtensionsByDefault",1),explicitSwapControl:b(p,"explicitSwapControl",0),renderViaOffscreenBackBuffer:b(p,"renderViaOffscreenBackBuffer",0)};v.majorVersion=p&&p.majorVersion?p.majorVersion:"undefined"!==typeof WebGL2RenderingContext?2:1;if(v.explicitSwapControl)throw"explicitSwapControl is not supported";l=la(l,v);if(!l)return 0;oa(l);z.le.getExtension("WEBGL_debug_renderer_info");return l};a.deleteContext=function(l){z===pa[l]&&(z=null);"object"==typeof JSEvents&&
JSEvents.Af(pa[l].le.canvas);pa[l]&&pa[l].le.canvas&&(pa[l].le.canvas.Ve=void 0);pa[l]=null};a._setTextureCleanup({deleteTexture:function(l,p){var v=ka[p];v&&pa[l].le.deleteTexture(v);ka[p]=null}});a.MakeWebGLContext=function(l){if(!this.$d(l))return null;var p=this._MakeGrContext();if(!p)return null;p.Zd=l;var v=p.delete.bind(p);p["delete"]=function(){a.$d(this.Zd);v()}.bind(p);return z.Je=p};a.MakeGrContext=a.MakeWebGLContext;a.GrDirectContext.prototype.getResourceCacheLimitBytes=function(){a.$d(this.Zd);
this._getResourceCacheLimitBytes()};a.GrDirectContext.prototype.getResourceCacheUsageBytes=function(){a.$d(this.Zd);this._getResourceCacheUsageBytes()};a.GrDirectContext.prototype.releaseResourcesAndAbandonContext=function(){a.$d(this.Zd);this._releaseResourcesAndAbandonContext()};a.GrDirectContext.prototype.setResourceCacheLimitBytes=function(l){a.$d(this.Zd);this._setResourceCacheLimitBytes(l)};a.MakeOnScreenGLSurface=function(l,p,v,w,A,D){if(!this.$d(l.Zd))return null;p=void 0===A||void 0===D?
this._MakeOnScreenGLSurface(l,p,v,w):this._MakeOnScreenGLSurface(l,p,v,w,A,D);if(!p)return null;p.Zd=l.Zd;return p};a.MakeRenderTarget=function(){var l=arguments[0];if(!this.$d(l.Zd))return null;if(3===arguments.length){var p=this._MakeRenderTargetWH(l,arguments[1],arguments[2]);if(!p)return null}else if(2===arguments.length){if(p=this._MakeRenderTargetII(l,arguments[1]),!p)return null}else return null;p.Zd=l.Zd;return p};a.MakeWebGLCanvasSurface=function(l,p,v){p=p||null;var w=l,A="undefined"!==
typeof OffscreenCanvas&&w instanceof OffscreenCanvas;if(!("undefined"!==typeof HTMLCanvasElement&&w instanceof HTMLCanvasElement||A||(w=document.getElementById(l),w)))throw"Canvas with id "+l+" was not found";l=this.GetWebGLContext(w,v);if(!l||0>l)throw"failed to create webgl context: err "+l;l=this.MakeWebGLContext(l);p=this.MakeOnScreenGLSurface(l,w.width,w.height,p);return p?p:(p=w.cloneNode(!0),w.parentNode.replaceChild(p,w),p.classList.add("ck-replaced"),a.MakeSWCanvasSurface(p))};a.MakeCanvasSurface=
a.MakeWebGLCanvasSurface;a.Surface.prototype.makeImageFromTexture=function(l,p){a.$d(this.Zd);l=c(l);if(p=this._makeImageFromTexture(this.Zd,l,p))p.ue=l;return p};a.Surface.prototype.makeImageFromTextureSource=function(l,p,v){p||={height:e(l),width:f(l),colorType:a.ColorType.RGBA_8888,alphaType:v?a.AlphaType.Premul:a.AlphaType.Unpremul};p.colorSpace||(p.colorSpace=a.ColorSpace.SRGB);a.$d(this.Zd);var w=z.le;v=k(w,w.createTexture(),p,v);2===z.version?w.texImage2D(w.TEXTURE_2D,0,w.RGBA,p.width,p.height,
0,w.RGBA,w.UNSIGNED_BYTE,l):w.texImage2D(w.TEXTURE_2D,0,w.RGBA,w.RGBA,w.UNSIGNED_BYTE,l);n(w,p);this._resetContext();return this.makeImageFromTexture(v,p)};a.Surface.prototype.updateTextureFromSource=function(l,p,v){if(l.ue){a.$d(this.Zd);var w=l.getImageInfo(),A=z.le,D=k(A,ka[l.ue],w,v);2===z.version?A.texImage2D(A.TEXTURE_2D,0,A.RGBA,f(p),e(p),0,A.RGBA,A.UNSIGNED_BYTE,p):A.texImage2D(A.TEXTURE_2D,0,A.RGBA,A.RGBA,A.UNSIGNED_BYTE,p);n(A,w,v);this._resetContext();ka[l.ue]=null;l.ue=c(D);w.colorSpace=
l.getColorSpace();p=this._makeImageFromTexture(this.Zd,l.ue,w);v=l.Yd.ae;A=l.Yd.ee;l.Yd.ae=p.Yd.ae;l.Yd.ee=p.Yd.ee;p.Yd.ae=v;p.Yd.ee=A;p.delete();w.colorSpace.delete()}};a.MakeLazyImageFromTextureSource=function(l,p,v){p||={height:e(l),width:f(l),colorType:a.ColorType.RGBA_8888,alphaType:v?a.AlphaType.Premul:a.AlphaType.Unpremul};p.colorSpace||(p.colorSpace=a.ColorSpace.SRGB);var w={makeTexture:function(){var A=z,D=A.le,I=k(D,D.createTexture(),p,v);2===A.version?D.texImage2D(D.TEXTURE_2D,0,D.RGBA,
p.width,p.height,0,D.RGBA,D.UNSIGNED_BYTE,l):D.texImage2D(D.TEXTURE_2D,0,D.RGBA,D.RGBA,D.UNSIGNED_BYTE,l);n(D,p,v);return c(I)},freeSrc:function(){}};"VideoFrame"===l.constructor.name&&(w.freeSrc=function(){l.close()});return a.Image._makeFromGenerator(p,w)};a.$d=function(l){return l?oa(l):!1};a.Be=function(){return z&&z.Je&&!z.Je.isDeleted()?z.Je:null}})})(r);
(function(a){function b(g){return(f(255*g[3])<<24|f(255*g[0])<<16|f(255*g[1])<<8|f(255*g[2])<<0)>>>0}function c(g){if(g&&g._ck)return g;if(g instanceof Float32Array){for(var d=Math.floor(g.length/4),h=new Uint32Array(d),m=0;m<d;m++)h[m]=b(g.slice(4*m,4*(m+1)));return h}if(g instanceof Uint32Array)return g;if(g instanceof Array&&g[0]instanceof Float32Array)return g.map(b)}function e(g){if(void 0===g)return 1;var d=parseFloat(g);return g&&-1!==g.indexOf("%")?d/100:d}function f(g){return Math.round(Math.max(0,
Math.min(g||0,255)))}function k(g,d){d&&d._ck||a._free(g)}function n(g,d,h){if(!g||!g.length)return K;if(g&&g._ck)return g.byteOffset;var m=a[d].BYTES_PER_ELEMENT;h||=a._malloc(g.length*m);a[d].set(g,h/m);return h}function l(g){var d={he:K,count:g.length,colorType:a.ColorType.RGBA_F32};if(g instanceof Float32Array)d.he=n(g,"HEAPF32"),d.count=g.length/4;else if(g instanceof Uint32Array)d.he=n(g,"HEAPU32"),d.colorType=a.ColorType.RGBA_8888;else if(g instanceof Array){if(g&&g.length){for(var h=a._malloc(16*
g.length),m=0,t=h/4,u=0;u<g.length;u++)for(var x=0;4>x;x++)a.HEAPF32[t+m]=g[u][x],m++;g=h}else g=K;d.he=g}else throw"Invalid argument to copyFlexibleColorArray, Not a color array "+typeof g;return d}function p(g){if(!g)return K;var d=ba.toTypedArray();if(g.length){if(6===g.length||9===g.length)return n(g,"HEAPF32",P),6===g.length&&a.HEAPF32.set(Wc,6+P/4),P;if(16===g.length)return d[0]=g[0],d[1]=g[1],d[2]=g[3],d[3]=g[4],d[4]=g[5],d[5]=g[7],d[6]=g[12],d[7]=g[13],d[8]=g[15],P;throw"invalid matrix size";
}if(void 0===g.m11)throw"invalid matrix argument";d[0]=g.m11;d[1]=g.m21;d[2]=g.m41;d[3]=g.m12;d[4]=g.m22;d[5]=g.m42;d[6]=g.m14;d[7]=g.m24;d[8]=g.m44;return P}function v(g){if(!g)return K;var d=Y.toTypedArray();if(g.length){if(16!==g.length&&6!==g.length&&9!==g.length)throw"invalid matrix size";if(16===g.length)return n(g,"HEAPF32",ma);d.fill(0);d[0]=g[0];d[1]=g[1];d[3]=g[2];d[4]=g[3];d[5]=g[4];d[7]=g[5];d[10]=1;d[12]=g[6];d[13]=g[7];d[15]=g[8];6===g.length&&(d[12]=0,d[13]=0,d[15]=1);return ma}if(void 0===
g.m11)throw"invalid matrix argument";d[0]=g.m11;d[1]=g.m21;d[2]=g.m31;d[3]=g.m41;d[4]=g.m12;d[5]=g.m22;d[6]=g.m32;d[7]=g.m42;d[8]=g.m13;d[9]=g.m23;d[10]=g.m33;d[11]=g.m43;d[12]=g.m14;d[13]=g.m24;d[14]=g.m34;d[15]=g.m44;return ma}function w(g,d){return n(g,"HEAPF32",d||ia)}function A(g,d,h,m){var t=Ea.toTypedArray();t[0]=g;t[1]=d;t[2]=h;t[3]=m;return ia}function D(g){for(var d=new Float32Array(4),h=0;4>h;h++)d[h]=a.HEAPF32[g/4+h];return d}function I(g,d){return n(g,"HEAPF32",d||W)}function R(g,d){return n(g,
"HEAPF32",d||ub)}a.Color=function(g,d,h,m){void 0===m&&(m=1);return a.Color4f(f(g)/255,f(d)/255,f(h)/255,m)};a.ColorAsInt=function(g,d,h,m){void 0===m&&(m=255);return(f(m)<<24|f(g)<<16|f(d)<<8|f(h)<<0&268435455)>>>0};a.Color4f=function(g,d,h,m){void 0===m&&(m=1);return Float32Array.of(g,d,h,m)};Object.defineProperty(a,"TRANSPARENT",{get:function(){return a.Color4f(0,0,0,0)}});Object.defineProperty(a,"BLACK",{get:function(){return a.Color4f(0,0,0,1)}});Object.defineProperty(a,"WHITE",{get:function(){return a.Color4f(1,
1,1,1)}});Object.defineProperty(a,"RED",{get:function(){return a.Color4f(1,0,0,1)}});Object.defineProperty(a,"GREEN",{get:function(){return a.Color4f(0,1,0,1)}});Object.defineProperty(a,"BLUE",{get:function(){return a.Color4f(0,0,1,1)}});Object.defineProperty(a,"YELLOW",{get:function(){return a.Color4f(1,1,0,1)}});Object.defineProperty(a,"CYAN",{get:function(){return a.Color4f(0,1,1,1)}});Object.defineProperty(a,"MAGENTA",{get:function(){return a.Color4f(1,0,1,1)}});a.getColorComponents=function(g){return[Math.floor(255*
g[0]),Math.floor(255*g[1]),Math.floor(255*g[2]),g[3]]};a.parseColorString=function(g,d){g=g.toLowerCase();if(g.startsWith("#")){d=255;switch(g.length){case 9:d=parseInt(g.slice(7,9),16);case 7:var h=parseInt(g.slice(1,3),16);var m=parseInt(g.slice(3,5),16);var t=parseInt(g.slice(5,7),16);break;case 5:d=17*parseInt(g.slice(4,5),16);case 4:h=17*parseInt(g.slice(1,2),16),m=17*parseInt(g.slice(2,3),16),t=17*parseInt(g.slice(3,4),16)}return a.Color(h,m,t,d/255)}return g.startsWith("rgba")?(g=g.slice(5,
-1),g=g.split(","),a.Color(+g[0],+g[1],+g[2],e(g[3]))):g.startsWith("rgb")?(g=g.slice(4,-1),g=g.split(","),a.Color(+g[0],+g[1],+g[2],e(g[3]))):g.startsWith("gray(")||g.startsWith("hsl")||!d||(g=d[g],void 0===g)?a.BLACK:g};a.multiplyByAlpha=function(g,d){g=g.slice();g[3]=Math.max(0,Math.min(g[3]*d,1));return g};a.Malloc=function(g,d){var h=a._malloc(d*g.BYTES_PER_ELEMENT);return{_ck:!0,length:d,byteOffset:h,qe:null,subarray:function(m,t){m=this.toTypedArray().subarray(m,t);m._ck=!0;return m},toTypedArray:function(){if(this.qe&&
this.qe.length)return this.qe;this.qe=new g(a.HEAPU8.buffer,h,d);this.qe._ck=!0;return this.qe}}};a.Free=function(g){a._free(g.byteOffset);g.byteOffset=K;g.toTypedArray=null;g.qe=null};var P=K,ba,ma=K,Y,ia=K,Ea,fa,W=K,Ub,Ba=K,Vb,vb=K,Wb,wb=K,$a,Na=K,Xb,ub=K,Yb,Zb=K,Wc=Float32Array.of(0,0,1),K=0;a.onRuntimeInitialized=function(){function g(d,h,m,t,u,x,C){x||(x=4*t.width,t.colorType===a.ColorType.RGBA_F16?x*=2:t.colorType===a.ColorType.RGBA_F32&&(x*=4));var G=x*t.height;var F=u?u.byteOffset:a._malloc(G);
if(C?!d._readPixels(t,F,x,h,m,C):!d._readPixels(t,F,x,h,m))return u||a._free(F),null;if(u)return u.toTypedArray();switch(t.colorType){case a.ColorType.RGBA_8888:case a.ColorType.RGBA_F16:d=(new Uint8Array(a.HEAPU8.buffer,F,G)).slice();break;case a.ColorType.RGBA_F32:d=(new Float32Array(a.HEAPU8.buffer,F,G)).slice();break;default:return null}a._free(F);return d}Ea=a.Malloc(Float32Array,4);ia=Ea.byteOffset;Y=a.Malloc(Float32Array,16);ma=Y.byteOffset;ba=a.Malloc(Float32Array,9);P=ba.byteOffset;Xb=a.Malloc(Float32Array,
12);ub=Xb.byteOffset;Yb=a.Malloc(Float32Array,12);Zb=Yb.byteOffset;fa=a.Malloc(Float32Array,4);W=fa.byteOffset;Ub=a.Malloc(Float32Array,4);Ba=Ub.byteOffset;Vb=a.Malloc(Float32Array,3);vb=Vb.byteOffset;Wb=a.Malloc(Float32Array,3);wb=Wb.byteOffset;$a=a.Malloc(Int32Array,4);Na=$a.byteOffset;a.ColorSpace.SRGB=a.ColorSpace._MakeSRGB();a.ColorSpace.DISPLAY_P3=a.ColorSpace._MakeDisplayP3();a.ColorSpace.ADOBE_RGB=a.ColorSpace._MakeAdobeRGB();a.GlyphRunFlags={IsWhiteSpace:a._GlyphRunFlags_isWhiteSpace};a.Path.MakeFromCmds=
function(d){var h=n(d,"HEAPF32"),m=a.Path._MakeFromCmds(h,d.length);k(h,d);return m};a.Path.MakeFromVerbsPointsWeights=function(d,h,m){var t=n(d,"HEAPU8"),u=n(h,"HEAPF32"),x=n(m,"HEAPF32"),C=a.Path._MakeFromVerbsPointsWeights(t,d.length,u,h.length,x,m&&m.length||0);k(t,d);k(u,h);k(x,m);return C};a.Path.prototype.addArc=function(d,h,m){d=I(d);this._addArc(d,h,m);return this};a.Path.prototype.addCircle=function(d,h,m,t){this._addCircle(d,h,m,!!t);return this};a.Path.prototype.addOval=function(d,h,m){void 0===
m&&(m=1);d=I(d);this._addOval(d,!!h,m);return this};a.Path.prototype.addPath=function(){var d=Array.prototype.slice.call(arguments),h=d[0],m=!1;"boolean"===typeof d[d.length-1]&&(m=d.pop());if(1===d.length)this._addPath(h,1,0,0,0,1,0,0,0,1,m);else if(2===d.length)d=d[1],this._addPath(h,d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1,m);else if(7===d.length||10===d.length)this._addPath(h,d[1],d[2],d[3],d[4],d[5],d[6],d[7]||0,d[8]||0,d[9]||1,m);else return null;return this};a.Path.prototype.addPoly=
function(d,h){var m=n(d,"HEAPF32");this._addPoly(m,d.length/2,h);k(m,d);return this};a.Path.prototype.addRect=function(d,h){d=I(d);this._addRect(d,!!h);return this};a.Path.prototype.addRRect=function(d,h){d=R(d);this._addRRect(d,!!h);return this};a.Path.prototype.addVerbsPointsWeights=function(d,h,m){var t=n(d,"HEAPU8"),u=n(h,"HEAPF32"),x=n(m,"HEAPF32");this._addVerbsPointsWeights(t,d.length,u,h.length,x,m&&m.length||0);k(t,d);k(u,h);k(x,m)};a.Path.prototype.arc=function(d,h,m,t,u,x){d=a.LTRBRect(d-
m,h-m,d+m,h+m);u=(u-t)/Math.PI*180-360*!!x;x=new a.Path;x.addArc(d,t/Math.PI*180,u);this.addPath(x,!0);x.delete();return this};a.Path.prototype.arcToOval=function(d,h,m,t){d=I(d);this._arcToOval(d,h,m,t);return this};a.Path.prototype.arcToRotated=function(d,h,m,t,u,x,C){this._arcToRotated(d,h,m,!!t,!!u,x,C);return this};a.Path.prototype.arcToTangent=function(d,h,m,t,u){this._arcToTangent(d,h,m,t,u);return this};a.Path.prototype.close=function(){this._close();return this};a.Path.prototype.conicTo=
function(d,h,m,t,u){this._conicTo(d,h,m,t,u);return this};a.Path.prototype.computeTightBounds=function(d){this._computeTightBounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.Path.prototype.cubicTo=function(d,h,m,t,u,x){this._cubicTo(d,h,m,t,u,x);return this};a.Path.prototype.dash=function(d,h,m){return this._dash(d,h,m)?this:null};a.Path.prototype.getBounds=function(d){this._getBounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.Path.prototype.lineTo=function(d,
h){this._lineTo(d,h);return this};a.Path.prototype.moveTo=function(d,h){this._moveTo(d,h);return this};a.Path.prototype.offset=function(d,h){this._transform(1,0,d,0,1,h,0,0,1);return this};a.Path.prototype.quadTo=function(d,h,m,t){this._quadTo(d,h,m,t);return this};a.Path.prototype.rArcTo=function(d,h,m,t,u,x,C){this._rArcTo(d,h,m,t,u,x,C);return this};a.Path.prototype.rConicTo=function(d,h,m,t,u){this._rConicTo(d,h,m,t,u);return this};a.Path.prototype.rCubicTo=function(d,h,m,t,u,x){this._rCubicTo(d,
h,m,t,u,x);return this};a.Path.prototype.rLineTo=function(d,h){this._rLineTo(d,h);return this};a.Path.prototype.rMoveTo=function(d,h){this._rMoveTo(d,h);return this};a.Path.prototype.rQuadTo=function(d,h,m,t){this._rQuadTo(d,h,m,t);return this};a.Path.prototype.stroke=function(d){d=d||{};d.width=d.width||1;d.miter_limit=d.miter_limit||4;d.cap=d.cap||a.StrokeCap.Butt;d.join=d.join||a.StrokeJoin.Miter;d.precision=d.precision||1;return this._stroke(d)?this:null};a.Path.prototype.transform=function(){if(1===
arguments.length){var d=arguments[0];this._transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1)}else if(6===arguments.length||9===arguments.length)d=arguments,this._transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1);else throw"transform expected to take 1 or 9 arguments. Got "+arguments.length;return this};a.Path.prototype.trim=function(d,h,m){return this._trim(d,h,!!m)?this:null};a.Image.prototype.encodeToBytes=function(d,h){var m=a.Be();d=d||a.ImageFormat.PNG;h=h||100;
return m?this._encodeToBytes(d,h,m):this._encodeToBytes(d,h)};a.Image.prototype.makeShaderCubic=function(d,h,m,t,u){u=p(u);return this._makeShaderCubic(d,h,m,t,u)};a.Image.prototype.makeShaderOptions=function(d,h,m,t,u){u=p(u);return this._makeShaderOptions(d,h,m,t,u)};a.Image.prototype.readPixels=function(d,h,m,t,u){var x=a.Be();return g(this,d,h,m,t,u,x)};a.Canvas.prototype.clear=function(d){a.$d(this.Zd);d=w(d);this._clear(d)};a.Canvas.prototype.clipRRect=function(d,h,m){a.$d(this.Zd);d=R(d);this._clipRRect(d,
h,m)};a.Canvas.prototype.clipRect=function(d,h,m){a.$d(this.Zd);d=I(d);this._clipRect(d,h,m)};a.Canvas.prototype.concat=function(d){a.$d(this.Zd);d=v(d);this._concat(d)};a.Canvas.prototype.drawArc=function(d,h,m,t,u){a.$d(this.Zd);d=I(d);this._drawArc(d,h,m,t,u)};a.Canvas.prototype.drawAtlas=function(d,h,m,t,u,x,C){if(d&&t&&h&&m&&h.length===m.length){a.$d(this.Zd);u||(u=a.BlendMode.SrcOver);var G=n(h,"HEAPF32"),F=n(m,"HEAPF32"),T=m.length/4,U=n(c(x),"HEAPU32");if(C&&"B"in C&&"C"in C)this._drawAtlasCubic(d,
F,G,U,T,u,C.B,C.C,t);else{let q=a.FilterMode.Linear,y=a.MipmapMode.None;C&&(q=C.filter,"mipmap"in C&&(y=C.mipmap));this._drawAtlasOptions(d,F,G,U,T,u,q,y,t)}k(G,h);k(F,m);k(U,x)}};a.Canvas.prototype.drawCircle=function(d,h,m,t){a.$d(this.Zd);this._drawCircle(d,h,m,t)};a.Canvas.prototype.drawColor=function(d,h){a.$d(this.Zd);d=w(d);void 0!==h?this._drawColor(d,h):this._drawColor(d)};a.Canvas.prototype.drawColorInt=function(d,h){a.$d(this.Zd);this._drawColorInt(d,h||a.BlendMode.SrcOver)};a.Canvas.prototype.drawColorComponents=
function(d,h,m,t,u){a.$d(this.Zd);d=A(d,h,m,t);void 0!==u?this._drawColor(d,u):this._drawColor(d)};a.Canvas.prototype.drawDRRect=function(d,h,m){a.$d(this.Zd);d=R(d,ub);h=R(h,Zb);this._drawDRRect(d,h,m)};a.Canvas.prototype.drawImage=function(d,h,m,t){a.$d(this.Zd);this._drawImage(d,h,m,t||null)};a.Canvas.prototype.drawImageCubic=function(d,h,m,t,u,x){a.$d(this.Zd);this._drawImageCubic(d,h,m,t,u,x||null)};a.Canvas.prototype.drawImageOptions=function(d,h,m,t,u,x){a.$d(this.Zd);this._drawImageOptions(d,
h,m,t,u,x||null)};a.Canvas.prototype.drawImageNine=function(d,h,m,t,u){a.$d(this.Zd);h=n(h,"HEAP32",Na);m=I(m);this._drawImageNine(d,h,m,t,u||null)};a.Canvas.prototype.drawImageRect=function(d,h,m,t,u){a.$d(this.Zd);I(h,W);I(m,Ba);this._drawImageRect(d,W,Ba,t,!!u)};a.Canvas.prototype.drawImageRectCubic=function(d,h,m,t,u,x){a.$d(this.Zd);I(h,W);I(m,Ba);this._drawImageRectCubic(d,W,Ba,t,u,x||null)};a.Canvas.prototype.drawImageRectOptions=function(d,h,m,t,u,x){a.$d(this.Zd);I(h,W);I(m,Ba);this._drawImageRectOptions(d,
W,Ba,t,u,x||null)};a.Canvas.prototype.drawLine=function(d,h,m,t,u){a.$d(this.Zd);this._drawLine(d,h,m,t,u)};a.Canvas.prototype.drawOval=function(d,h){a.$d(this.Zd);d=I(d);this._drawOval(d,h)};a.Canvas.prototype.drawPaint=function(d){a.$d(this.Zd);this._drawPaint(d)};a.Canvas.prototype.drawParagraph=function(d,h,m){a.$d(this.Zd);this._drawParagraph(d,h,m)};a.Canvas.prototype.drawPatch=function(d,h,m,t,u){if(24>d.length)throw"Need 12 cubic points";if(h&&4>h.length)throw"Need 4 colors";if(m&&8>m.length)throw"Need 4 shader coordinates";
a.$d(this.Zd);const x=n(d,"HEAPF32"),C=h?n(c(h),"HEAPU32"):K,G=m?n(m,"HEAPF32"):K;t||(t=a.BlendMode.Modulate);this._drawPatch(x,C,G,t,u);k(G,m);k(C,h);k(x,d)};a.Canvas.prototype.drawPath=function(d,h){a.$d(this.Zd);this._drawPath(d,h)};a.Canvas.prototype.drawPicture=function(d){a.$d(this.Zd);this._drawPicture(d)};a.Canvas.prototype.drawPoints=function(d,h,m){a.$d(this.Zd);var t=n(h,"HEAPF32");this._drawPoints(d,t,h.length/2,m);k(t,h)};a.Canvas.prototype.drawRRect=function(d,h){a.$d(this.Zd);d=R(d);
this._drawRRect(d,h)};a.Canvas.prototype.drawRect=function(d,h){a.$d(this.Zd);d=I(d);this._drawRect(d,h)};a.Canvas.prototype.drawRect4f=function(d,h,m,t,u){a.$d(this.Zd);this._drawRect4f(d,h,m,t,u)};a.Canvas.prototype.drawShadow=function(d,h,m,t,u,x,C){a.$d(this.Zd);var G=n(u,"HEAPF32"),F=n(x,"HEAPF32");h=n(h,"HEAPF32",vb);m=n(m,"HEAPF32",wb);this._drawShadow(d,h,m,t,G,F,C);k(G,u);k(F,x)};a.getShadowLocalBounds=function(d,h,m,t,u,x,C){d=p(d);m=n(m,"HEAPF32",vb);t=n(t,"HEAPF32",wb);if(!this._getShadowLocalBounds(d,
h,m,t,u,x,W))return null;h=fa.toTypedArray();return C?(C.set(h),C):h.slice()};a.Canvas.prototype.drawTextBlob=function(d,h,m,t){a.$d(this.Zd);this._drawTextBlob(d,h,m,t)};a.Canvas.prototype.drawVertices=function(d,h,m){a.$d(this.Zd);this._drawVertices(d,h,m)};a.Canvas.prototype.getDeviceClipBounds=function(d){this._getDeviceClipBounds(Na);var h=$a.toTypedArray();d?d.set(h):d=h.slice();return d};a.Canvas.prototype.quickReject=function(d){d=I(d);return this._quickReject(d)};a.Canvas.prototype.getLocalToDevice=
function(){this._getLocalToDevice(ma);for(var d=ma,h=Array(16),m=0;16>m;m++)h[m]=a.HEAPF32[d/4+m];return h};a.Canvas.prototype.getTotalMatrix=function(){this._getTotalMatrix(P);for(var d=Array(9),h=0;9>h;h++)d[h]=a.HEAPF32[P/4+h];return d};a.Canvas.prototype.makeSurface=function(d){d=this._makeSurface(d);d.Zd=this.Zd;return d};a.Canvas.prototype.readPixels=function(d,h,m,t,u){a.$d(this.Zd);return g(this,d,h,m,t,u)};a.Canvas.prototype.saveLayer=function(d,h,m,t,u){h=I(h);return this._saveLayer(d||
null,h,m||null,t||0,u||a.TileMode.Clamp)};a.Canvas.prototype.writePixels=function(d,h,m,t,u,x,C,G){if(d.byteLength%(h*m))throw"pixels length must be a multiple of the srcWidth * srcHeight";a.$d(this.Zd);var F=d.byteLength/(h*m);x=x||a.AlphaType.Unpremul;C=C||a.ColorType.RGBA_8888;G=G||a.ColorSpace.SRGB;var T=F*h;F=n(d,"HEAPU8");h=this._writePixels({width:h,height:m,colorType:C,alphaType:x,colorSpace:G},F,T,t,u);k(F,d);return h};a.ColorFilter.MakeBlend=function(d,h,m){d=w(d);m=m||a.ColorSpace.SRGB;
return a.ColorFilter._MakeBlend(d,h,m)};a.ColorFilter.MakeMatrix=function(d){if(!d||20!==d.length)throw"invalid color matrix";var h=n(d,"HEAPF32"),m=a.ColorFilter._makeMatrix(h);k(h,d);return m};a.ContourMeasure.prototype.getPosTan=function(d,h){this._getPosTan(d,W);d=fa.toTypedArray();return h?(h.set(d),h):d.slice()};a.ImageFilter.prototype.getOutputBounds=function(d,h,m){d=I(d,W);h=p(h);this._getOutputBounds(d,h,Na);h=$a.toTypedArray();return m?(m.set(h),m):h.slice()};a.ImageFilter.MakeDropShadow=
function(d,h,m,t,u,x){u=w(u,ia);return a.ImageFilter._MakeDropShadow(d,h,m,t,u,x)};a.ImageFilter.MakeDropShadowOnly=function(d,h,m,t,u,x){u=w(u,ia);return a.ImageFilter._MakeDropShadowOnly(d,h,m,t,u,x)};a.ImageFilter.MakeImage=function(d,h,m,t){m=I(m,W);t=I(t,Ba);if("B"in h&&"C"in h)return a.ImageFilter._MakeImageCubic(d,h.B,h.C,m,t);const u=h.filter;let x=a.MipmapMode.None;"mipmap"in h&&(x=h.mipmap);return a.ImageFilter._MakeImageOptions(d,u,x,m,t)};a.ImageFilter.MakeMatrixTransform=function(d,h,
m){d=p(d);if("B"in h&&"C"in h)return a.ImageFilter._MakeMatrixTransformCubic(d,h.B,h.C,m);const t=h.filter;let u=a.MipmapMode.None;"mipmap"in h&&(u=h.mipmap);return a.ImageFilter._MakeMatrixTransformOptions(d,t,u,m)};a.Paint.prototype.getColor=function(){this._getColor(ia);return D(ia)};a.Paint.prototype.setColor=function(d,h){h=h||null;d=w(d);this._setColor(d,h)};a.Paint.prototype.setColorComponents=function(d,h,m,t,u){u=u||null;d=A(d,h,m,t);this._setColor(d,u)};a.Path.prototype.getPoint=function(d,
h){this._getPoint(d,W);d=fa.toTypedArray();return h?(h[0]=d[0],h[1]=d[1],h):d.slice(0,2)};a.Picture.prototype.makeShader=function(d,h,m,t,u){t=p(t);u=I(u);return this._makeShader(d,h,m,t,u)};a.Picture.prototype.cullRect=function(d){this._cullRect(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.PictureRecorder.prototype.beginRecording=function(d,h){d=I(d);return this._beginRecording(d,!!h)};a.Surface.prototype.getCanvas=function(){var d=this._getCanvas();d.Zd=this.Zd;return d};a.Surface.prototype.makeImageSnapshot=
function(d){a.$d(this.Zd);d=n(d,"HEAP32",Na);return this._makeImageSnapshot(d)};a.Surface.prototype.makeSurface=function(d){a.$d(this.Zd);d=this._makeSurface(d);d.Zd=this.Zd;return d};a.Surface.prototype.Ze=function(d,h){this.te||(this.te=this.getCanvas());return requestAnimationFrame(function(){a.$d(this.Zd);d(this.te);this.flush(h)}.bind(this))};a.Surface.prototype.requestAnimationFrame||(a.Surface.prototype.requestAnimationFrame=a.Surface.prototype.Ze);a.Surface.prototype.We=function(d,h){this.te||
(this.te=this.getCanvas());requestAnimationFrame(function(){a.$d(this.Zd);d(this.te);this.flush(h);this.dispose()}.bind(this))};a.Surface.prototype.drawOnce||(a.Surface.prototype.drawOnce=a.Surface.prototype.We);a.PathEffect.MakeDash=function(d,h){h||=0;if(!d.length||1===d.length%2)throw"Intervals array must have even length";var m=n(d,"HEAPF32");h=a.PathEffect._MakeDash(m,d.length,h);k(m,d);return h};a.PathEffect.MakeLine2D=function(d,h){h=p(h);return a.PathEffect._MakeLine2D(d,h)};a.PathEffect.MakePath2D=
function(d,h){d=p(d);return a.PathEffect._MakePath2D(d,h)};a.Shader.MakeColor=function(d,h){h=h||null;d=w(d);return a.Shader._MakeColor(d,h)};a.Shader.Blend=a.Shader.MakeBlend;a.Shader.Color=a.Shader.MakeColor;a.Shader.MakeLinearGradient=function(d,h,m,t,u,x,C,G){G=G||null;var F=l(m),T=n(t,"HEAPF32");C=C||0;x=p(x);var U=fa.toTypedArray();U.set(d);U.set(h,2);d=a.Shader._MakeLinearGradient(W,F.he,F.colorType,T,F.count,u,C,x,G);k(F.he,m);t&&k(T,t);return d};a.Shader.MakeRadialGradient=function(d,h,m,
t,u,x,C,G){G=G||null;var F=l(m),T=n(t,"HEAPF32");C=C||0;x=p(x);d=a.Shader._MakeRadialGradient(d[0],d[1],h,F.he,F.colorType,T,F.count,u,C,x,G);k(F.he,m);t&&k(T,t);return d};a.Shader.MakeSweepGradient=function(d,h,m,t,u,x,C,G,F,T){T=T||null;var U=l(m),q=n(t,"HEAPF32");C=C||0;G=G||0;F=F||360;x=p(x);d=a.Shader._MakeSweepGradient(d,h,U.he,U.colorType,q,U.count,u,G,F,C,x,T);k(U.he,m);t&&k(q,t);return d};a.Shader.MakeTwoPointConicalGradient=function(d,h,m,t,u,x,C,G,F,T){T=T||null;var U=l(u),q=n(x,"HEAPF32");
F=F||0;G=p(G);var y=fa.toTypedArray();y.set(d);y.set(m,2);d=a.Shader._MakeTwoPointConicalGradient(W,h,t,U.he,U.colorType,q,U.count,C,F,G,T);k(U.he,u);x&&k(q,x);return d};a.Vertices.prototype.bounds=function(d){this._bounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.ce&&a.ce.forEach(function(d){d()})};a.computeTonalColors=function(g){var d=n(g.ambient,"HEAPF32"),h=n(g.spot,"HEAPF32");this._computeTonalColors(d,h);var m={ambient:D(d),spot:D(h)};k(d,g.ambient);k(h,g.spot);return m};
a.LTRBRect=function(g,d,h,m){return Float32Array.of(g,d,h,m)};a.XYWHRect=function(g,d,h,m){return Float32Array.of(g,d,g+h,d+m)};a.LTRBiRect=function(g,d,h,m){return Int32Array.of(g,d,h,m)};a.XYWHiRect=function(g,d,h,m){return Int32Array.of(g,d,g+h,d+m)};a.RRectXY=function(g,d,h){return Float32Array.of(g[0],g[1],g[2],g[3],d,h,d,h,d,h,d,h)};a.MakeAnimatedImageFromEncoded=function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._decodeAnimatedImage(d,g.byteLength))?
g:null};a.MakeImageFromEncoded=function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._decodeImage(d,g.byteLength))?g:null};var ab=null;a.MakeImageFromCanvasImageSource=function(g){var d=g.width,h=g.height;ab||=document.createElement("canvas");ab.width=d;ab.height=h;var m=ab.getContext("2d",{willReadFrequently:!0});m.drawImage(g,0,0);g=m.getImageData(0,0,d,h);return a.MakeImage({width:d,height:h,alphaType:a.AlphaType.Unpremul,colorType:a.ColorType.RGBA_8888,colorSpace:a.ColorSpace.SRGB},
g.data,4*d)};a.MakeImage=function(g,d,h){var m=a._malloc(d.length);a.HEAPU8.set(d,m);return a._MakeImage(g,m,d.length,h)};a.MakeVertices=function(g,d,h,m,t,u){var x=t&&t.length||0,C=0;h&&h.length&&(C|=1);m&&m.length&&(C|=2);void 0===u||u||(C|=4);g=new a._VerticesBuilder(g,d.length/2,x,C);n(d,"HEAPF32",g.positions());g.texCoords()&&n(h,"HEAPF32",g.texCoords());g.colors()&&n(c(m),"HEAPU32",g.colors());g.indices()&&n(t,"HEAPU16",g.indices());return g.detach()};(function(g){g.ce=g.ce||[];g.ce.push(function(){function d(q){q&&
(q.dir=0===q.dir?g.TextDirection.RTL:g.TextDirection.LTR);return q}function h(q){if(!q||!q.length)return[];for(var y=[],N=0;N<q.length;N+=5){var X=g.LTRBRect(q[N],q[N+1],q[N+2],q[N+3]),xa=g.TextDirection.LTR;0===q[N+4]&&(xa=g.TextDirection.RTL);y.push({rect:X,dir:xa})}g._free(q.byteOffset);return y}function m(q){q=q||{};void 0===q.weight&&(q.weight=g.FontWeight.Normal);q.width=q.width||g.FontWidth.Normal;q.slant=q.slant||g.FontSlant.Upright;return q}function t(q){if(!q||!q.length)return K;for(var y=
[],N=0;N<q.length;N++){var X=u(q[N]);y.push(X)}return n(y,"HEAPU32")}function u(q){if(G[q])return G[q];var y=qa(q)+1,N=g._malloc(y);ra(q,N,y);return G[q]=N}function x(q){q._colorPtr=w(q.color);q._foregroundColorPtr=K;q._backgroundColorPtr=K;q._decorationColorPtr=K;q.foregroundColor&&(q._foregroundColorPtr=w(q.foregroundColor,F));q.backgroundColor&&(q._backgroundColorPtr=w(q.backgroundColor,T));q.decorationColor&&(q._decorationColorPtr=w(q.decorationColor,U));Array.isArray(q.fontFamilies)&&q.fontFamilies.length?
(q._fontFamiliesPtr=t(q.fontFamilies),q._fontFamiliesLen=q.fontFamilies.length):(q._fontFamiliesPtr=K,q._fontFamiliesLen=0);if(q.locale){var y=q.locale;q._localePtr=u(y);q._localeLen=qa(y)}else q._localePtr=K,q._localeLen=0;if(Array.isArray(q.shadows)&&q.shadows.length){y=q.shadows;var N=y.map(function(na){return na.color||g.BLACK}),X=y.map(function(na){return na.blurRadius||0});q._shadowLen=y.length;for(var xa=g._malloc(8*y.length),xb=xa/4,yb=0;yb<y.length;yb++){var $b=y[yb].offset||[0,0];g.HEAPF32[xb]=
$b[0];g.HEAPF32[xb+1]=$b[1];xb+=2}q._shadowColorsPtr=l(N).he;q._shadowOffsetsPtr=xa;q._shadowBlurRadiiPtr=n(X,"HEAPF32")}else q._shadowLen=0,q._shadowColorsPtr=K,q._shadowOffsetsPtr=K,q._shadowBlurRadiiPtr=K;Array.isArray(q.fontFeatures)&&q.fontFeatures.length?(y=q.fontFeatures,N=y.map(function(na){return na.name}),X=y.map(function(na){return na.value}),q._fontFeatureLen=y.length,q._fontFeatureNamesPtr=t(N),q._fontFeatureValuesPtr=n(X,"HEAPU32")):(q._fontFeatureLen=0,q._fontFeatureNamesPtr=K,q._fontFeatureValuesPtr=
K);Array.isArray(q.fontVariations)&&q.fontVariations.length?(y=q.fontVariations,N=y.map(function(na){return na.axis}),X=y.map(function(na){return na.value}),q._fontVariationLen=y.length,q._fontVariationAxesPtr=t(N),q._fontVariationValuesPtr=n(X,"HEAPF32")):(q._fontVariationLen=0,q._fontVariationAxesPtr=K,q._fontVariationValuesPtr=K)}function C(q){g._free(q._fontFamiliesPtr);g._free(q._shadowColorsPtr);g._free(q._shadowOffsetsPtr);g._free(q._shadowBlurRadiiPtr);g._free(q._fontFeatureNamesPtr);g._free(q._fontFeatureValuesPtr);
g._free(q._fontVariationAxesPtr);g._free(q._fontVariationValuesPtr)}g.Paragraph.prototype.getRectsForRange=function(q,y,N,X){q=this._getRectsForRange(q,y,N,X);return h(q)};g.Paragraph.prototype.getRectsForPlaceholders=function(){var q=this._getRectsForPlaceholders();return h(q)};g.Paragraph.prototype.getGlyphInfoAt=function(q){return d(this._getGlyphInfoAt(q))};g.Paragraph.prototype.getClosestGlyphInfoAtCoordinate=function(q,y){return d(this._getClosestGlyphInfoAtCoordinate(q,y))};g.TypefaceFontProvider.prototype.registerFont=
function(q,y){q=g.Typeface.MakeTypefaceFromData(q);if(!q)return null;y=u(y);this._registerFont(q,y)};g.ParagraphStyle=function(q){q.disableHinting=q.disableHinting||!1;if(q.ellipsis){var y=q.ellipsis;q._ellipsisPtr=u(y);q._ellipsisLen=qa(y)}else q._ellipsisPtr=K,q._ellipsisLen=0;null==q.heightMultiplier&&(q.heightMultiplier=-1);q.maxLines=q.maxLines||0;q.replaceTabCharacters=q.replaceTabCharacters||!1;y=(y=q.strutStyle)||{};y.strutEnabled=y.strutEnabled||!1;y.strutEnabled&&Array.isArray(y.fontFamilies)&&
y.fontFamilies.length?(y._fontFamiliesPtr=t(y.fontFamilies),y._fontFamiliesLen=y.fontFamilies.length):(y._fontFamiliesPtr=K,y._fontFamiliesLen=0);y.fontStyle=m(y.fontStyle);null==y.fontSize&&(y.fontSize=-1);null==y.heightMultiplier&&(y.heightMultiplier=-1);y.halfLeading=y.halfLeading||!1;y.leading=y.leading||0;y.forceStrutHeight=y.forceStrutHeight||!1;q.strutStyle=y;q.textAlign=q.textAlign||g.TextAlign.Start;q.textDirection=q.textDirection||g.TextDirection.LTR;q.textHeightBehavior=q.textHeightBehavior||
g.TextHeightBehavior.All;q.textStyle=g.TextStyle(q.textStyle);q.applyRoundingHack=!1!==q.applyRoundingHack;return q};g.TextStyle=function(q){q.color||(q.color=g.BLACK);q.decoration=q.decoration||0;q.decorationThickness=q.decorationThickness||0;q.decorationStyle=q.decorationStyle||g.DecorationStyle.Solid;q.textBaseline=q.textBaseline||g.TextBaseline.Alphabetic;null==q.fontSize&&(q.fontSize=-1);q.letterSpacing=q.letterSpacing||0;q.wordSpacing=q.wordSpacing||0;null==q.heightMultiplier&&(q.heightMultiplier=
-1);q.halfLeading=q.halfLeading||!1;q.fontStyle=m(q.fontStyle);return q};var G={},F=g._malloc(16),T=g._malloc(16),U=g._malloc(16);g.ParagraphBuilder.Make=function(q,y){x(q.textStyle);y=g.ParagraphBuilder._Make(q,y);C(q.textStyle);return y};g.ParagraphBuilder.MakeFromFontProvider=function(q,y){x(q.textStyle);y=g.ParagraphBuilder._MakeFromFontProvider(q,y);C(q.textStyle);return y};g.ParagraphBuilder.MakeFromFontCollection=function(q,y){x(q.textStyle);y=g.ParagraphBuilder._MakeFromFontCollection(q,y);
C(q.textStyle);return y};g.ParagraphBuilder.ShapeText=function(q,y,N){let X=0;for(const xa of y)X+=xa.length;if(X!==q.length)throw"Accumulated block lengths must equal text.length";return g.ParagraphBuilder._ShapeText(q,y,N)};g.ParagraphBuilder.prototype.pushStyle=function(q){x(q);this._pushStyle(q);C(q)};g.ParagraphBuilder.prototype.pushPaintStyle=function(q,y,N){x(q);this._pushPaintStyle(q,y,N);C(q)};g.ParagraphBuilder.prototype.addPlaceholder=function(q,y,N,X,xa){N=N||g.PlaceholderAlignment.Baseline;
X=X||g.TextBaseline.Alphabetic;this._addPlaceholder(q||0,y||0,N,X,xa||0)};g.ParagraphBuilder.prototype.setWordsUtf8=function(q){var y=n(q,"HEAPU32");this._setWordsUtf8(y,q&&q.length||0);k(y,q)};g.ParagraphBuilder.prototype.setWordsUtf16=function(q){var y=n(q,"HEAPU32");this._setWordsUtf16(y,q&&q.length||0);k(y,q)};g.ParagraphBuilder.prototype.setGraphemeBreaksUtf8=function(q){var y=n(q,"HEAPU32");this._setGraphemeBreaksUtf8(y,q&&q.length||0);k(y,q)};g.ParagraphBuilder.prototype.setGraphemeBreaksUtf16=
function(q){var y=n(q,"HEAPU32");this._setGraphemeBreaksUtf16(y,q&&q.length||0);k(y,q)};g.ParagraphBuilder.prototype.setLineBreaksUtf8=function(q){var y=n(q,"HEAPU32");this._setLineBreaksUtf8(y,q&&q.length||0);k(y,q)};g.ParagraphBuilder.prototype.setLineBreaksUtf16=function(q){var y=n(q,"HEAPU32");this._setLineBreaksUtf16(y,q&&q.length||0);k(y,q)}})})(r);a.ce=a.ce||[];a.ce.push(function(){a.Path.prototype.op=function(g,d){return this._op(g,d)?this:null};a.Path.prototype.simplify=function(){return this._simplify()?
this:null}});a.ce=a.ce||[];a.ce.push(function(){a.Canvas.prototype.drawText=function(g,d,h,m,t){var u=qa(g),x=a._malloc(u+1);ra(g,x,u+1);this._drawSimpleText(x,u,d,h,t,m);a._free(x)};a.Canvas.prototype.drawGlyphs=function(g,d,h,m,t,u){if(!(2*g.length<=d.length))throw"Not enough positions for the array of gyphs";a.$d(this.Zd);const x=n(g,"HEAPU16"),C=n(d,"HEAPF32");this._drawGlyphs(g.length,x,C,h,m,t,u);k(C,d);k(x,g)};a.Font.prototype.getGlyphBounds=function(g,d,h){var m=n(g,"HEAPU16"),t=a._malloc(16*
g.length);this._getGlyphWidthBounds(m,g.length,K,t,d||null);d=new Float32Array(a.HEAPU8.buffer,t,4*g.length);k(m,g);if(h)return h.set(d),a._free(t),h;g=Float32Array.from(d);a._free(t);return g};a.Font.prototype.getGlyphIDs=function(g,d,h){d||(d=g.length);var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=a._malloc(2*d);d=this._getGlyphIDs(t,m-1,d,g);a._free(t);if(0>d)return a._free(g),null;t=new Uint16Array(a.HEAPU8.buffer,g,d);if(h)return h.set(t),a._free(g),h;h=Uint16Array.from(t);a._free(g);return h};a.Font.prototype.getGlyphIntercepts=
function(g,d,h,m){var t=n(g,"HEAPU16"),u=n(d,"HEAPF32");return this._getGlyphIntercepts(t,g.length,!(g&&g._ck),u,d.length,!(d&&d._ck),h,m)};a.Font.prototype.getGlyphWidths=function(g,d,h){var m=n(g,"HEAPU16"),t=a._malloc(4*g.length);this._getGlyphWidthBounds(m,g.length,t,K,d||null);d=new Float32Array(a.HEAPU8.buffer,t,g.length);k(m,g);if(h)return h.set(d),a._free(t),h;g=Float32Array.from(d);a._free(t);return g};a.FontMgr.FromData=function(){if(!arguments.length)return null;var g=arguments;1===g.length&&
Array.isArray(g[0])&&(g=arguments[0]);if(!g.length)return null;for(var d=[],h=[],m=0;m<g.length;m++){var t=new Uint8Array(g[m]),u=n(t,"HEAPU8");d.push(u);h.push(t.byteLength)}d=n(d,"HEAPU32");h=n(h,"HEAPU32");g=a.FontMgr._fromData(d,h,g.length);a._free(d);a._free(h);return g};a.Typeface.MakeTypefaceFromData=function(g){g=new Uint8Array(g);var d=n(g,"HEAPU8");return(g=a.Typeface._MakeTypefaceFromData(d,g.byteLength))?g:null};a.Typeface.MakeFreeTypeFaceFromData=a.Typeface.MakeTypefaceFromData;a.Typeface.prototype.getGlyphIDs=
function(g,d,h){d||(d=g.length);var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=a._malloc(2*d);d=this._getGlyphIDs(t,m-1,d,g);a._free(t);if(0>d)return a._free(g),null;t=new Uint16Array(a.HEAPU8.buffer,g,d);if(h)return h.set(t),a._free(g),h;h=Uint16Array.from(t);a._free(g);return h};a.TextBlob.MakeOnPath=function(g,d,h,m){if(g&&g.length&&d&&d.countPoints()){if(1===d.countPoints())return this.MakeFromText(g,h);m||=0;var t=h.getGlyphIDs(g);t=h.getGlyphWidths(t);var u=[];d=new a.ContourMeasureIter(d,!1,1);for(var x=
d.next(),C=new Float32Array(4),G=0;G<g.length&&x;G++){var F=t[G];m+=F/2;if(m>x.length()){x.delete();x=d.next();if(!x){g=g.substring(0,G);break}m=F/2}x.getPosTan(m,C);var T=C[2],U=C[3];u.push(T,U,C[0]-F/2*T,C[1]-F/2*U);m+=F/2}g=this.MakeFromRSXform(g,u,h);x&&x.delete();d.delete();return g}};a.TextBlob.MakeFromRSXform=function(g,d,h){var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=n(d,"HEAPF32");h=a.TextBlob._MakeFromRSXform(t,m-1,g,h);a._free(t);return h?h:null};a.TextBlob.MakeFromRSXformGlyphs=function(g,
d,h){var m=n(g,"HEAPU16");d=n(d,"HEAPF32");h=a.TextBlob._MakeFromRSXformGlyphs(m,2*g.length,d,h);k(m,g);return h?h:null};a.TextBlob.MakeFromGlyphs=function(g,d){var h=n(g,"HEAPU16");d=a.TextBlob._MakeFromGlyphs(h,2*g.length,d);k(h,g);return d?d:null};a.TextBlob.MakeFromText=function(g,d){var h=qa(g)+1,m=a._malloc(h);ra(g,m,h);g=a.TextBlob._MakeFromText(m,h-1,d);a._free(m);return g?g:null};a.MallocGlyphIDs=function(g){return a.Malloc(Uint16Array,g)}});a.ce=a.ce||[];a.ce.push(function(){a.MakePicture=
function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._MakePicture(d,g.byteLength))?g:null}});a.ce=a.ce||[];a.ce.push(function(){a.RuntimeEffect.Make=function(g,d){return a.RuntimeEffect._Make(g,{onError:d||function(h){console.log("RuntimeEffect error",h)}})};a.RuntimeEffect.MakeForBlender=function(g,d){return a.RuntimeEffect._MakeForBlender(g,{onError:d||function(h){console.log("RuntimeEffect error",h)}})};a.RuntimeEffect.prototype.makeShader=function(g,d){var h=
!g._ck,m=n(g,"HEAPF32");d=p(d);return this._makeShader(m,4*g.length,h,d)};a.RuntimeEffect.prototype.makeShaderWithChildren=function(g,d,h){var m=!g._ck,t=n(g,"HEAPF32");h=p(h);for(var u=[],x=0;x<d.length;x++)u.push(d[x].Yd.ae);d=n(u,"HEAPU32");return this._makeShaderWithChildren(t,4*g.length,m,d,u.length,h)};a.RuntimeEffect.prototype.makeBlender=function(g){var d=!g._ck,h=n(g,"HEAPF32");return this._makeBlender(h,4*g.length,d)}})})(r);var sa=Object.assign({},r),ta="",ua,va;
if(ea||ha)ha?ta=self.location.href:"undefined"!=typeof document&&document.currentScript&&(ta=document.currentScript.src),_scriptName&&(ta=_scriptName),ta.startsWith("blob:")?ta="":ta=ta.substr(0,ta.replace(/[?#].*/,"").lastIndexOf("/")+1),ha&&(va=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),ua=a=>fetch(a,{credentials:"same-origin"}).then(b=>b.ok?b.arrayBuffer():Promise.reject(Error(b.status+" : "+b.url)));
var wa=console.log.bind(console),ya=console.error.bind(console);Object.assign(r,sa);sa=null;var za,Aa=!1,Ca,B,Da,Fa,E,H,J,Ga;function Ha(){var a=za.buffer;r.HEAP8=Ca=new Int8Array(a);r.HEAP16=Da=new Int16Array(a);r.HEAPU8=B=new Uint8Array(a);r.HEAPU16=Fa=new Uint16Array(a);r.HEAP32=E=new Int32Array(a);r.HEAPU32=H=new Uint32Array(a);r.HEAPF32=J=new Float32Array(a);r.HEAPF64=Ga=new Float64Array(a)}var Ia=[],Ja=[],Ka=[],La=0,Ma=null,Oa=null;
function Pa(a){a="Aborted("+a+")";ya(a);Aa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ca(a);throw a;}var Qa=a=>a.startsWith("data:application/octet-stream;base64,"),Ra;function Sa(a){return ua(a).then(b=>new Uint8Array(b),()=>{if(va)var b=va(a);else throw"both async and sync fetching of the wasm failed";return b})}function Ta(a,b,c){return Sa(a).then(e=>WebAssembly.instantiate(e,b)).then(c,e=>{ya(`failed to asynchronously prepare wasm: ${e}`);Pa(e)})}
function Ua(a,b){var c=Ra;return"function"!=typeof WebAssembly.instantiateStreaming||Qa(c)||"function"!=typeof fetch?Ta(c,a,b):fetch(c,{credentials:"same-origin"}).then(e=>WebAssembly.instantiateStreaming(e,a).then(b,function(f){ya(`wasm streaming compile failed: ${f}`);ya("falling back to ArrayBuffer instantiation");return Ta(c,a,b)}))}function Va(a){this.name="ExitStatus";this.message=`Program terminated with exit(${a})`;this.status=a}var Wa=a=>{a.forEach(b=>b(r))};
class Xa{constructor(a){this.ae=a-24}}
var Ya=0,Za=0,bb="undefined"!=typeof TextDecoder?new TextDecoder:void 0,cb=(a,b=0,c=NaN)=>{var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&bb)return bb.decode(a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var k=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|k);else{var n=a[b++]&63;f=224==(f&240)?(f&15)<<12|k<<6|n:(f&7)<<18|k<<12|n<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e},
db={},eb=a=>{for(;a.length;){var b=a.pop();a.pop()(b)}};function fb(a){return this.fromWireType(H[a>>2])}
var gb={},hb={},ib={},jb,lb=(a,b,c)=>{function e(l){l=c(l);if(l.length!==a.length)throw new jb("Mismatched type converter count");for(var p=0;p<a.length;++p)kb(a[p],l[p])}a.forEach(l=>ib[l]=b);var f=Array(b.length),k=[],n=0;b.forEach((l,p)=>{hb.hasOwnProperty(l)?f[p]=hb[l]:(k.push(l),gb.hasOwnProperty(l)||(gb[l]=[]),gb[l].push(()=>{f[p]=hb[l];++n;n===k.length&&e(f)}))});0===k.length&&e(f)},mb,L=a=>{for(var b="";B[a];)b+=mb[B[a++]];return b},M;
function nb(a,b,c={}){var e=b.name;if(!a)throw new M(`type "${e}" must have a positive integer typeid pointer`);if(hb.hasOwnProperty(a)){if(c.lf)return;throw new M(`Cannot register type '${e}' twice`);}hb[a]=b;delete ib[a];gb.hasOwnProperty(a)&&(b=gb[a],delete gb[a],b.forEach(f=>f()))}function kb(a,b,c={}){return nb(a,b,c)}
var ob=a=>{throw new M(a.Yd.de.be.name+" instance already deleted");},pb=!1,qb=()=>{},rb=(a,b,c)=>{if(b===c)return a;if(void 0===c.ge)return null;a=rb(a,b,c.ge);return null===a?null:c.cf(a)},sb={},tb={},zb=(a,b)=>{if(void 0===b)throw new M("ptr should not be undefined");for(;a.ge;)b=a.ye(b),a=a.ge;return tb[b]},Bb=(a,b)=>{if(!b.de||!b.ae)throw new jb("makeClassHandle requires ptr and ptrType");if(!!b.ie!==!!b.ee)throw new jb("Both smartPtrType and smartPtr must be specified");b.count={value:1};return Ab(Object.create(a,
{Yd:{value:b,writable:!0}}))},Ab=a=>{if("undefined"===typeof FinalizationRegistry)return Ab=b=>b,a;pb=new FinalizationRegistry(b=>{b=b.Yd;--b.count.value;0===b.count.value&&(b.ee?b.ie.ne(b.ee):b.de.be.ne(b.ae))});Ab=b=>{var c=b.Yd;c.ee&&pb.register(b,{Yd:c},b);return b};qb=b=>{pb.unregister(b)};return Ab(a)},Cb=[];function Db(){}
var Eb=(a,b)=>Object.defineProperty(b,"name",{value:a}),Fb=(a,b,c)=>{if(void 0===a[b].fe){var e=a[b];a[b]=function(...f){if(!a[b].fe.hasOwnProperty(f.length))throw new M(`Function '${c}' called with an invalid number of arguments (${f.length}) - expects one of (${a[b].fe})!`);return a[b].fe[f.length].apply(this,f)};a[b].fe=[];a[b].fe[e.oe]=e}},Gb=(a,b,c)=>{if(r.hasOwnProperty(a)){if(void 0===c||void 0!==r[a].fe&&void 0!==r[a].fe[c])throw new M(`Cannot register public name '${a}' twice`);Fb(r,a,a);
if(r[a].fe.hasOwnProperty(c))throw new M(`Cannot register multiple overloads of a function with the same number of arguments (${c})!`);r[a].fe[c]=b}else r[a]=b,r[a].oe=c},Hb=a=>{a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?`_${a}`:a};function Ib(a,b,c,e,f,k,n,l){this.name=a;this.constructor=b;this.se=c;this.ne=e;this.ge=f;this.ff=k;this.ye=n;this.cf=l;this.pf=[]}
var Jb=(a,b,c)=>{for(;b!==c;){if(!b.ye)throw new M(`Expected null or instance of ${c.name}, got an instance of ${b.name}`);a=b.ye(a);b=b.ge}return a};function Kb(a,b){if(null===b){if(this.Ke)throw new M(`null is not a valid ${this.name}`);return 0}if(!b.Yd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Yd.ae)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);return Jb(b.Yd.ae,b.Yd.de.be,this.be)}
function Mb(a,b){if(null===b){if(this.Ke)throw new M(`null is not a valid ${this.name}`);if(this.De){var c=this.Le();null!==a&&a.push(this.ne,c);return c}return 0}if(!b||!b.Yd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Yd.ae)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);if(!this.Ce&&b.Yd.de.Ce)throw new M(`Cannot convert argument of type ${b.Yd.ie?b.Yd.ie.name:b.Yd.de.name} to parameter type ${this.name}`);c=Jb(b.Yd.ae,b.Yd.de.be,this.be);if(this.De){if(void 0===
b.Yd.ee)throw new M("Passing raw pointer to smart pointer is illegal");switch(this.uf){case 0:if(b.Yd.ie===this)c=b.Yd.ee;else throw new M(`Cannot convert argument of type ${b.Yd.ie?b.Yd.ie.name:b.Yd.de.name} to parameter type ${this.name}`);break;case 1:c=b.Yd.ee;break;case 2:if(b.Yd.ie===this)c=b.Yd.ee;else{var e=b.clone();c=this.qf(c,Nb(()=>e["delete"]()));null!==a&&a.push(this.ne,c)}break;default:throw new M("Unsupporting sharing policy");}}return c}
function Ob(a,b){if(null===b){if(this.Ke)throw new M(`null is not a valid ${this.name}`);return 0}if(!b.Yd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Yd.ae)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);if(b.Yd.de.Ce)throw new M(`Cannot convert argument of type ${b.Yd.de.name} to parameter type ${this.name}`);return Jb(b.Yd.ae,b.Yd.de.be,this.be)}
function Pb(a,b,c,e,f,k,n,l,p,v,w){this.name=a;this.be=b;this.Ke=c;this.Ce=e;this.De=f;this.nf=k;this.uf=n;this.Se=l;this.Le=p;this.qf=v;this.ne=w;f||void 0!==b.ge?this.toWireType=Mb:(this.toWireType=e?Kb:Ob,this.ke=null)}
var Qb=(a,b,c)=>{if(!r.hasOwnProperty(a))throw new jb("Replacing nonexistent public symbol");void 0!==r[a].fe&&void 0!==c?r[a].fe[c]=b:(r[a]=b,r[a].oe=c)},O,Rb=(a,b,c=[])=>{a.includes("j")?(a=a.replace(/p/g,"i"),b=(0,r["dynCall_"+a])(b,...c)):b=O.get(b)(...c);return b},Sb=(a,b)=>(...c)=>Rb(a,b,c),Tb=(a,b)=>{a=L(a);var c=a.includes("j")?Sb(a,b):O.get(b);if("function"!=typeof c)throw new M(`unknown function pointer with signature ${a}: ${b}`);return c},ac,dc=a=>{a=bc(a);var b=L(a);cc(a);return b},ec=
(a,b)=>{function c(k){f[k]||hb[k]||(ib[k]?ib[k].forEach(c):(e.push(k),f[k]=!0))}var e=[],f={};b.forEach(c);throw new ac(`${a}: `+e.map(dc).join([", "]));};function fc(a){for(var b=1;b<a.length;++b)if(null!==a[b]&&void 0===a[b].ke)return!0;return!1}
function gc(a,b,c,e,f){var k=b.length;if(2>k)throw new M("argTypes array size mismatch! Must at least get return value and 'this' types!");var n=null!==b[1]&&null!==c,l=fc(b),p="void"!==b[0].name,v=k-2,w=Array(v),A=[],D=[];return Eb(a,function(...I){D.length=0;A.length=n?2:1;A[0]=f;if(n){var R=b[1].toWireType(D,this);A[1]=R}for(var P=0;P<v;++P)w[P]=b[P+2].toWireType(D,I[P]),A.push(w[P]);I=e(...A);if(l)eb(D);else for(P=n?1:2;P<b.length;P++){var ba=1===P?R:w[P-2];null!==b[P].ke&&b[P].ke(ba)}R=p?b[0].fromWireType(I):
void 0;return R})}
var hc=(a,b)=>{for(var c=[],e=0;e<a;e++)c.push(H[b+4*e>>2]);return c},ic=a=>{a=a.trim();const b=a.indexOf("(");return-1!==b?a.substr(0,b):a},jc=[],kc=[],lc=a=>{9<a&&0===--kc[a+1]&&(kc[a]=void 0,jc.push(a))},mc=a=>{if(!a)throw new M("Cannot use deleted val. handle = "+a);return kc[a]},Nb=a=>{switch(a){case void 0:return 2;case null:return 4;case !0:return 6;case !1:return 8;default:const b=jc.pop()||kc.length;kc[b]=a;kc[b+1]=1;return b}},nc={name:"emscripten::val",fromWireType:a=>{var b=mc(a);lc(a);
return b},toWireType:(a,b)=>Nb(b),je:8,readValueFromPointer:fb,ke:null},oc=(a,b,c)=>{switch(b){case 1:return c?function(e){return this.fromWireType(Ca[e])}:function(e){return this.fromWireType(B[e])};case 2:return c?function(e){return this.fromWireType(Da[e>>1])}:function(e){return this.fromWireType(Fa[e>>1])};case 4:return c?function(e){return this.fromWireType(E[e>>2])}:function(e){return this.fromWireType(H[e>>2])};default:throw new TypeError(`invalid integer width (${b}): ${a}`);}},pc=(a,b)=>
{var c=hb[a];if(void 0===c)throw a=`${b} has unknown type ${dc(a)}`,new M(a);return c},Lb=a=>{if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a},qc=(a,b)=>{switch(b){case 4:return function(c){return this.fromWireType(J[c>>2])};case 8:return function(c){return this.fromWireType(Ga[c>>3])};default:throw new TypeError(`invalid float width (${b}): ${a}`);}},rc=(a,b,c)=>{switch(b){case 1:return c?e=>Ca[e]:e=>B[e];case 2:return c?e=>Da[e>>1]:e=>Fa[e>>
1];case 4:return c?e=>E[e>>2]:e=>H[e>>2];default:throw new TypeError(`invalid integer width (${b}): ${a}`);}},ra=(a,b,c)=>{var e=B;if(!(0<c))return 0;var f=b;c=b+c-1;for(var k=0;k<a.length;++k){var n=a.charCodeAt(k);if(55296<=n&&57343>=n){var l=a.charCodeAt(++k);n=65536+((n&1023)<<10)|l&1023}if(127>=n){if(b>=c)break;e[b++]=n}else{if(2047>=n){if(b+1>=c)break;e[b++]=192|n>>6}else{if(65535>=n){if(b+2>=c)break;e[b++]=224|n>>12}else{if(b+3>=c)break;e[b++]=240|n>>18;e[b++]=128|n>>12&63}e[b++]=128|n>>6&
63}e[b++]=128|n&63}}e[b]=0;return b-f},qa=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b},sc="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0,tc=(a,b)=>{var c=a>>1;for(var e=c+b/2;!(c>=e)&&Fa[c];)++c;c<<=1;if(32<c-a&&sc)return sc.decode(B.subarray(a,c));c="";for(e=0;!(e>=b/2);++e){var f=Da[a+2*e>>1];if(0==f)break;c+=String.fromCharCode(f)}return c},uc=(a,b,c)=>{c??=2147483647;if(2>c)return 0;c-=2;var e=
b;c=c<2*a.length?c/2:a.length;for(var f=0;f<c;++f)Da[b>>1]=a.charCodeAt(f),b+=2;Da[b>>1]=0;return b-e},vc=a=>2*a.length,wc=(a,b)=>{for(var c=0,e="";!(c>=b/4);){var f=E[a+4*c>>2];if(0==f)break;++c;65536<=f?(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023)):e+=String.fromCharCode(f)}return e},xc=(a,b,c)=>{c??=2147483647;if(4>c)return 0;var e=b;c=e+c-4;for(var f=0;f<a.length;++f){var k=a.charCodeAt(f);if(55296<=k&&57343>=k){var n=a.charCodeAt(++f);k=65536+((k&1023)<<10)|n&1023}E[b>>2]=k;b+=
4;if(b+4>c)break}E[b>>2]=0;return b-e},yc=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);55296<=e&&57343>=e&&++c;b+=4}return b},zc=(a,b,c)=>{var e=[];a=a.toWireType(e,c);e.length&&(H[b>>2]=Nb(e));return a},Ac=[],Bc={},Cc=a=>{var b=Bc[a];return void 0===b?L(a):b},Dc=()=>{function a(b){b.$$$embind_global$$$=b;var c="object"==typeof $$$embind_global$$$&&b.$$$embind_global$$$==b;c||delete b.$$$embind_global$$$;return c}if("object"==typeof globalThis)return globalThis;if("object"==typeof $$$embind_global$$$)return $$$embind_global$$$;
"object"==typeof global&&a(global)?$$$embind_global$$$=global:"object"==typeof self&&a(self)&&($$$embind_global$$$=self);if("object"==typeof $$$embind_global$$$)return $$$embind_global$$$;throw Error("unable to get global object.");},Ec=a=>{var b=Ac.length;Ac.push(a);return b},Fc=(a,b)=>{for(var c=Array(a),e=0;e<a;++e)c[e]=pc(H[b+4*e>>2],"parameter "+e);return c},Gc=Reflect.construct,Q,Hc=a=>{var b=a.getExtension("ANGLE_instanced_arrays");b&&(a.vertexAttribDivisor=(c,e)=>b.vertexAttribDivisorANGLE(c,
e),a.drawArraysInstanced=(c,e,f,k)=>b.drawArraysInstancedANGLE(c,e,f,k),a.drawElementsInstanced=(c,e,f,k,n)=>b.drawElementsInstancedANGLE(c,e,f,k,n))},Ic=a=>{var b=a.getExtension("OES_vertex_array_object");b&&(a.createVertexArray=()=>b.createVertexArrayOES(),a.deleteVertexArray=c=>b.deleteVertexArrayOES(c),a.bindVertexArray=c=>b.bindVertexArrayOES(c),a.isVertexArray=c=>b.isVertexArrayOES(c))},Jc=a=>{var b=a.getExtension("WEBGL_draw_buffers");b&&(a.drawBuffers=(c,e)=>b.drawBuffersWEBGL(c,e))},Kc=a=>
{var b="ANGLE_instanced_arrays EXT_blend_minmax EXT_disjoint_timer_query EXT_frag_depth EXT_shader_texture_lod EXT_sRGB OES_element_index_uint OES_fbo_render_mipmap OES_standard_derivatives OES_texture_float OES_texture_half_float OES_texture_half_float_linear OES_vertex_array_object WEBGL_color_buffer_float WEBGL_depth_texture WEBGL_draw_buffers EXT_color_buffer_float EXT_conservative_depth EXT_disjoint_timer_query_webgl2 EXT_texture_norm16 NV_shader_noperspective_interpolation WEBGL_clip_cull_distance EXT_clip_control EXT_color_buffer_half_float EXT_depth_clamp EXT_float_blend EXT_polygon_offset_clamp EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic KHR_parallel_shader_compile OES_texture_float_linear WEBGL_blend_func_extended WEBGL_compressed_texture_astc WEBGL_compressed_texture_etc WEBGL_compressed_texture_etc1 WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw WEBGL_polygon_mode".split(" ");
return(a.getSupportedExtensions()||[]).filter(c=>b.includes(c))},Lc=1,Mc=[],Nc=[],Oc=[],Pc=[],ka=[],Qc=[],Rc=[],pa=[],Sc=[],Tc=[],Uc=[],Vc={},Xc={},Yc=4,Zc=0,ja=a=>{for(var b=Lc++,c=a.length;c<b;c++)a[c]=null;return b},$c=(a,b,c,e)=>{for(var f=0;f<a;f++){var k=Q[c](),n=k&&ja(e);k?(k.name=n,e[n]=k):S||=1282;E[b+4*f>>2]=n}},la=(a,b)=>{a.Ne||(a.Ne=a.getContext,a.getContext=function(e,f){f=a.Ne(e,f);return"webgl"==e==f instanceof WebGLRenderingContext?f:null});var c=1<b.majorVersion?a.getContext("webgl2",
b):a.getContext("webgl",b);return c?ad(c,b):0},ad=(a,b)=>{var c=ja(pa),e={handle:c,attributes:b,version:b.majorVersion,le:a};a.canvas&&(a.canvas.Ve=e);pa[c]=e;("undefined"==typeof b.df||b.df)&&bd(e);return c},oa=a=>{z=pa[a];r.vf=Q=z?.le;return!(a&&!Q)},bd=a=>{a||=z;if(!a.mf){a.mf=!0;var b=a.le;b.zf=b.getExtension("WEBGL_multi_draw");b.xf=b.getExtension("EXT_polygon_offset_clamp");b.wf=b.getExtension("EXT_clip_control");b.Bf=b.getExtension("WEBGL_polygon_mode");Hc(b);Ic(b);Jc(b);b.Pe=b.getExtension("WEBGL_draw_instanced_base_vertex_base_instance");
b.Re=b.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance");2<=a.version&&(b.me=b.getExtension("EXT_disjoint_timer_query_webgl2"));if(2>a.version||!b.me)b.me=b.getExtension("EXT_disjoint_timer_query");Kc(b).forEach(c=>{c.includes("lose_context")||c.includes("debug")||b.getExtension(c)})}},z,S,cd=(a,b)=>{Q.bindFramebuffer(a,Oc[b])},dd=a=>{Q.bindVertexArray(Rc[a])},ed=a=>Q.clear(a),fd=(a,b,c,e)=>Q.clearColor(a,b,c,e),gd=a=>Q.clearStencil(a),hd=(a,b)=>{for(var c=0;c<a;c++){var e=E[b+
4*c>>2];Q.deleteVertexArray(Rc[e]);Rc[e]=null}},jd=[],kd=(a,b)=>{$c(a,b,"createVertexArray",Rc)};function ld(){var a=Kc(Q);return a=a.concat(a.map(b=>"GL_"+b))}
var md=(a,b,c)=>{if(b){var e=void 0;switch(a){case 36346:e=1;break;case 36344:0!=c&&1!=c&&(S||=1280);return;case 34814:case 36345:e=0;break;case 34466:var f=Q.getParameter(34467);e=f?f.length:0;break;case 33309:if(2>z.version){S||=1282;return}e=ld().length;break;case 33307:case 33308:if(2>z.version){S||=1280;return}e=33307==a?3:0}if(void 0===e)switch(f=Q.getParameter(a),typeof f){case "number":e=f;break;case "boolean":e=f?1:0;break;case "string":S||=1280;return;case "object":if(null===f)switch(a){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:e=
0;break;default:S||=1280;return}else{if(f instanceof Float32Array||f instanceof Uint32Array||f instanceof Int32Array||f instanceof Array){for(a=0;a<f.length;++a)switch(c){case 0:E[b+4*a>>2]=f[a];break;case 2:J[b+4*a>>2]=f[a];break;case 4:Ca[b+a]=f[a]?1:0}return}try{e=f.name|0}catch(k){S||=1280;ya(`GL_INVALID_ENUM in glGet${c}v: Unknown object returned from WebGL getParameter(${a})! (error: ${k})`);return}}break;default:S||=1280;ya(`GL_INVALID_ENUM in glGet${c}v: Native code calling glGet${c}v(${a}) and it returns ${f} of type ${typeof f}!`);
return}switch(c){case 1:c=e;H[b>>2]=c;H[b+4>>2]=(c-H[b>>2])/4294967296;break;case 0:E[b>>2]=e;break;case 2:J[b>>2]=e;break;case 4:Ca[b]=e?1:0}}else S||=1281},nd=(a,b)=>md(a,b,0),od=(a,b,c)=>{if(c){a=Sc[a];b=2>z.version?Q.me.getQueryObjectEXT(a,b):Q.getQueryParameter(a,b);var e;"boolean"==typeof b?e=b?1:0:e=b;H[c>>2]=e;H[c+4>>2]=(e-H[c>>2])/4294967296}else S||=1281},qd=a=>{var b=qa(a)+1,c=pd(b);c&&ra(a,c,b);return c},rd=a=>{var b=Vc[a];if(!b){switch(a){case 7939:b=qd(ld().join(" "));break;case 7936:case 7937:case 37445:case 37446:(b=
Q.getParameter(a))||(S||=1280);b=b?qd(b):0;break;case 7938:b=Q.getParameter(7938);var c=`OpenGL ES 2.0 (${b})`;2<=z.version&&(c=`OpenGL ES 3.0 (${b})`);b=qd(c);break;case 35724:b=Q.getParameter(35724);c=b.match(/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/);null!==c&&(3==c[1].length&&(c[1]+="0"),b=`OpenGL ES GLSL ES ${c[1]} (${b})`);b=qd(b);break;default:S||=1280}Vc[a]=b}return b},sd=(a,b)=>{if(2>z.version)return S||=1282,0;var c=Xc[a];if(c)return 0>b||b>=c.length?(S||=1281,0):c[b];switch(a){case 7939:return c=
ld().map(qd),c=Xc[a]=c,0>b||b>=c.length?(S||=1281,0):c[b];default:return S||=1280,0}},td=a=>"]"==a.slice(-1)&&a.lastIndexOf("["),ud=a=>{a-=5120;return 0==a?Ca:1==a?B:2==a?Da:4==a?E:6==a?J:5==a||28922==a||28520==a||30779==a||30782==a?H:Fa},vd=(a,b,c,e,f)=>{a=ud(a);b=e*((Zc||c)*({5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4}[b-6402]||1)*a.BYTES_PER_ELEMENT+Yc-1&-Yc);return a.subarray(f>>>31-Math.clz32(a.BYTES_PER_ELEMENT),f+b>>>31-Math.clz32(a.BYTES_PER_ELEMENT))},V=a=>{var b=Q.bf;if(b){var c=
b.xe[a];"number"==typeof c&&(b.xe[a]=c=Q.getUniformLocation(b,b.Te[a]+(0<c?`[${c}]`:"")));return c}S||=1282},wd=[],xd=[],yd={},Ad=()=>{if(!zd){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:"./this.program"},b;for(b in yd)void 0===yd[b]?delete a[b]:a[b]=yd[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);zd=c}return zd},zd,Bd=[null,[],[]];
jb=r.InternalError=class extends Error{constructor(a){super(a);this.name="InternalError"}};for(var Cd=Array(256),Dd=0;256>Dd;++Dd)Cd[Dd]=String.fromCharCode(Dd);mb=Cd;M=r.BindingError=class extends Error{constructor(a){super(a);this.name="BindingError"}};
Object.assign(Db.prototype,{isAliasOf:function(a){if(!(this instanceof Db&&a instanceof Db))return!1;var b=this.Yd.de.be,c=this.Yd.ae;a.Yd=a.Yd;var e=a.Yd.de.be;for(a=a.Yd.ae;b.ge;)c=b.ye(c),b=b.ge;for(;e.ge;)a=e.ye(a),e=e.ge;return b===e&&c===a},clone:function(){this.Yd.ae||ob(this);if(this.Yd.we)return this.Yd.count.value+=1,this;var a=Ab,b=Object,c=b.create,e=Object.getPrototypeOf(this),f=this.Yd;a=a(c.call(b,e,{Yd:{value:{count:f.count,ve:f.ve,we:f.we,ae:f.ae,de:f.de,ee:f.ee,ie:f.ie}}}));a.Yd.count.value+=
1;a.Yd.ve=!1;return a},["delete"](){this.Yd.ae||ob(this);if(this.Yd.ve&&!this.Yd.we)throw new M("Object already scheduled for deletion");qb(this);var a=this.Yd;--a.count.value;0===a.count.value&&(a.ee?a.ie.ne(a.ee):a.de.be.ne(a.ae));this.Yd.we||(this.Yd.ee=void 0,this.Yd.ae=void 0)},isDeleted:function(){return!this.Yd.ae},deleteLater:function(){this.Yd.ae||ob(this);if(this.Yd.ve&&!this.Yd.we)throw new M("Object already scheduled for deletion");Cb.push(this);this.Yd.ve=!0;return this}});
Object.assign(Pb.prototype,{gf(a){this.Se&&(a=this.Se(a));return a},Oe(a){this.ne?.(a)},je:8,readValueFromPointer:fb,fromWireType:function(a){function b(){return this.De?Bb(this.be.se,{de:this.nf,ae:c,ie:this,ee:a}):Bb(this.be.se,{de:this,ae:a})}var c=this.gf(a);if(!c)return this.Oe(a),null;var e=zb(this.be,c);if(void 0!==e){if(0===e.Yd.count.value)return e.Yd.ae=c,e.Yd.ee=a,e.clone();e=e.clone();this.Oe(a);return e}e=this.be.ff(c);e=sb[e];if(!e)return b.call(this);e=this.Ce?e.af:e.pointerType;var f=
rb(c,this.be,e.be);return null===f?b.call(this):this.De?Bb(e.be.se,{de:e,ae:f,ie:this,ee:a}):Bb(e.be.se,{de:e,ae:f})}});ac=r.UnboundTypeError=((a,b)=>{var c=Eb(b,function(e){this.name=b;this.message=e;e=Error(e).stack;void 0!==e&&(this.stack=this.toString()+"\n"+e.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(a.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:`${this.name}: ${this.message}`};return c})(Error,"UnboundTypeError");
kc.push(0,1,void 0,1,null,1,!0,1,!1,1);r.count_emval_handles=()=>kc.length/2-5-jc.length;for(var Ed=0;32>Ed;++Ed)jd.push(Array(Ed));var Fd=new Float32Array(288);for(Ed=0;288>=Ed;++Ed)wd[Ed]=Fd.subarray(0,Ed);var Gd=new Int32Array(288);for(Ed=0;288>=Ed;++Ed)xd[Ed]=Gd.subarray(0,Ed);
var Vd={F:(a,b,c)=>{var e=new Xa(a);H[e.ae+16>>2]=0;H[e.ae+4>>2]=b;H[e.ae+8>>2]=c;Ya=a;Za++;throw Ya;},V:function(){return 0},vd:()=>{},ud:function(){return 0},td:()=>{},sd:()=>{},U:function(){},rd:()=>{},nd:()=>{Pa("")},B:a=>{var b=db[a];delete db[a];var c=b.Le,e=b.ne,f=b.Qe,k=f.map(n=>n.kf).concat(f.map(n=>n.sf));lb([a],k,n=>{var l={};f.forEach((p,v)=>{var w=n[v],A=p.hf,D=p.jf,I=n[v+f.length],R=p.rf,P=p.tf;l[p.ef]={read:ba=>w.fromWireType(A(D,ba)),write:(ba,ma)=>{var Y=[];R(P,ba,I.toWireType(Y,
ma));eb(Y)}}});return[{name:b.name,fromWireType:p=>{var v={},w;for(w in l)v[w]=l[w].read(p);e(p);return v},toWireType:(p,v)=>{for(var w in l)if(!(w in v))throw new TypeError(`Missing field: "${w}"`);var A=c();for(w in l)l[w].write(A,v[w]);null!==p&&p.push(e,A);return A},je:8,readValueFromPointer:fb,ke:e}]})},Y:()=>{},md:(a,b,c,e)=>{b=L(b);kb(a,{name:b,fromWireType:function(f){return!!f},toWireType:function(f,k){return k?c:e},je:8,readValueFromPointer:function(f){return this.fromWireType(B[f])},ke:null})},
l:(a,b,c,e,f,k,n,l,p,v,w,A,D)=>{w=L(w);k=Tb(f,k);l&&=Tb(n,l);v&&=Tb(p,v);D=Tb(A,D);var I=Hb(w);Gb(I,function(){ec(`Cannot construct ${w} due to unbound types`,[e])});lb([a,b,c],e?[e]:[],R=>{R=R[0];if(e){var P=R.be;var ba=P.se}else ba=Db.prototype;R=Eb(w,function(...Ea){if(Object.getPrototypeOf(this)!==ma)throw new M("Use 'new' to construct "+w);if(void 0===Y.pe)throw new M(w+" has no accessible constructor");var fa=Y.pe[Ea.length];if(void 0===fa)throw new M(`Tried to invoke ctor of ${w} with invalid number of parameters (${Ea.length}) - expected (${Object.keys(Y.pe).toString()}) parameters instead!`);
return fa.apply(this,Ea)});var ma=Object.create(ba,{constructor:{value:R}});R.prototype=ma;var Y=new Ib(w,R,ma,D,P,k,l,v);if(Y.ge){var ia;(ia=Y.ge).ze??(ia.ze=[]);Y.ge.ze.push(Y)}P=new Pb(w,Y,!0,!1,!1);ia=new Pb(w+"*",Y,!1,!1,!1);ba=new Pb(w+" const*",Y,!1,!0,!1);sb[a]={pointerType:ia,af:ba};Qb(I,R);return[P,ia,ba]})},e:(a,b,c,e,f,k,n)=>{var l=hc(c,e);b=L(b);b=ic(b);k=Tb(f,k);lb([],[a],p=>{function v(){ec(`Cannot call ${w} due to unbound types`,l)}p=p[0];var w=`${p.name}.${b}`;b.startsWith("@@")&&
(b=Symbol[b.substring(2)]);var A=p.be.constructor;void 0===A[b]?(v.oe=c-1,A[b]=v):(Fb(A,b,w),A[b].fe[c-1]=v);lb([],l,D=>{D=[D[0],null].concat(D.slice(1));D=gc(w,D,null,k,n);void 0===A[b].fe?(D.oe=c-1,A[b]=D):A[b].fe[c-1]=D;if(p.be.ze)for(const I of p.be.ze)I.constructor.hasOwnProperty(b)||(I.constructor[b]=D);return[]});return[]})},z:(a,b,c,e,f,k)=>{var n=hc(b,c);f=Tb(e,f);lb([],[a],l=>{l=l[0];var p=`constructor ${l.name}`;void 0===l.be.pe&&(l.be.pe=[]);if(void 0!==l.be.pe[b-1])throw new M(`Cannot register multiple constructors with identical number of parameters (${b-
1}) for class '${l.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`);l.be.pe[b-1]=()=>{ec(`Cannot construct ${l.name} due to unbound types`,n)};lb([],n,v=>{v.splice(1,0,null);l.be.pe[b-1]=gc(p,v,null,f,k);return[]});return[]})},a:(a,b,c,e,f,k,n,l)=>{var p=hc(c,e);b=L(b);b=ic(b);k=Tb(f,k);lb([],[a],v=>{function w(){ec(`Cannot call ${A} due to unbound types`,p)}v=v[0];var A=`${v.name}.${b}`;b.startsWith("@@")&&(b=Symbol[b.substring(2)]);l&&v.be.pf.push(b);
var D=v.be.se,I=D[b];void 0===I||void 0===I.fe&&I.className!==v.name&&I.oe===c-2?(w.oe=c-2,w.className=v.name,D[b]=w):(Fb(D,b,A),D[b].fe[c-2]=w);lb([],p,R=>{R=gc(A,R,v,k,n);void 0===D[b].fe?(R.oe=c-2,D[b]=R):D[b].fe[c-2]=R;return[]});return[]})},q:(a,b,c)=>{a=L(a);lb([],[b],e=>{e=e[0];r[a]=e.fromWireType(c);return[]})},ld:a=>kb(a,nc),j:(a,b,c,e)=>{function f(){}b=L(b);f.values={};kb(a,{name:b,constructor:f,fromWireType:function(k){return this.constructor.values[k]},toWireType:(k,n)=>n.value,je:8,
readValueFromPointer:oc(b,c,e),ke:null});Gb(b,f)},b:(a,b,c)=>{var e=pc(a,"enum");b=L(b);a=e.constructor;e=Object.create(e.constructor.prototype,{value:{value:c},constructor:{value:Eb(`${e.name}_${b}`,function(){})}});a.values[c]=e;a[b]=e},S:(a,b,c)=>{b=L(b);kb(a,{name:b,fromWireType:e=>e,toWireType:(e,f)=>f,je:8,readValueFromPointer:qc(b,c),ke:null})},w:(a,b,c,e,f,k)=>{var n=hc(b,c);a=L(a);a=ic(a);f=Tb(e,f);Gb(a,function(){ec(`Cannot call ${a} due to unbound types`,n)},b-1);lb([],n,l=>{l=[l[0],null].concat(l.slice(1));
Qb(a,gc(a,l,null,f,k),b-1);return[]})},C:(a,b,c,e,f)=>{b=L(b);-1===f&&(f=4294967295);f=l=>l;if(0===e){var k=32-8*c;f=l=>l<<k>>>k}var n=b.includes("unsigned")?function(l,p){return p>>>0}:function(l,p){return p};kb(a,{name:b,fromWireType:f,toWireType:n,je:8,readValueFromPointer:rc(b,c,0!==e),ke:null})},p:(a,b,c)=>{function e(k){return new f(Ca.buffer,H[k+4>>2],H[k>>2])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=L(c);kb(a,{name:c,fromWireType:e,
je:8,readValueFromPointer:e},{lf:!0})},o:(a,b,c,e,f,k,n,l,p,v,w,A)=>{c=L(c);k=Tb(f,k);l=Tb(n,l);v=Tb(p,v);A=Tb(w,A);lb([a],[b],D=>{D=D[0];return[new Pb(c,D.be,!1,!1,!0,D,e,k,l,v,A)]})},R:(a,b)=>{b=L(b);var c="std::string"===b;kb(a,{name:b,fromWireType:function(e){var f=H[e>>2],k=e+4;if(c)for(var n=k,l=0;l<=f;++l){var p=k+l;if(l==f||0==B[p]){n=n?cb(B,n,p-n):"";if(void 0===v)var v=n;else v+=String.fromCharCode(0),v+=n;n=p+1}}else{v=Array(f);for(l=0;l<f;++l)v[l]=String.fromCharCode(B[k+l]);v=v.join("")}cc(e);
return v},toWireType:function(e,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var k="string"==typeof f;if(!(k||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array))throw new M("Cannot pass non-string to std::string");var n=c&&k?qa(f):f.length;var l=pd(4+n+1),p=l+4;H[l>>2]=n;if(c&&k)ra(f,p,n+1);else if(k)for(k=0;k<n;++k){var v=f.charCodeAt(k);if(255<v)throw cc(p),new M("String has UTF-16 code units that do not fit in 8 bits");B[p+k]=v}else for(k=0;k<n;++k)B[p+k]=f[k];
null!==e&&e.push(cc,l);return l},je:8,readValueFromPointer:fb,ke(e){cc(e)}})},M:(a,b,c)=>{c=L(c);if(2===b){var e=tc;var f=uc;var k=vc;var n=l=>Fa[l>>1]}else 4===b&&(e=wc,f=xc,k=yc,n=l=>H[l>>2]);kb(a,{name:c,fromWireType:l=>{for(var p=H[l>>2],v,w=l+4,A=0;A<=p;++A){var D=l+4+A*b;if(A==p||0==n(D))w=e(w,D-w),void 0===v?v=w:(v+=String.fromCharCode(0),v+=w),w=D+b}cc(l);return v},toWireType:(l,p)=>{if("string"!=typeof p)throw new M(`Cannot pass non-string to C++ string type ${c}`);var v=k(p),w=pd(4+v+b);
H[w>>2]=v/b;f(p,w+4,v+b);null!==l&&l.push(cc,w);return w},je:8,readValueFromPointer:fb,ke(l){cc(l)}})},A:(a,b,c,e,f,k)=>{db[a]={name:L(b),Le:Tb(c,e),ne:Tb(f,k),Qe:[]}},d:(a,b,c,e,f,k,n,l,p,v)=>{db[a].Qe.push({ef:L(b),kf:c,hf:Tb(e,f),jf:k,sf:n,rf:Tb(l,p),tf:v})},kd:(a,b)=>{b=L(b);kb(a,{yf:!0,name:b,je:0,fromWireType:()=>{},toWireType:()=>{}})},jd:()=>1,id:()=>{throw Infinity;},E:(a,b,c)=>{a=mc(a);b=pc(b,"emval::as");return zc(b,c,a)},L:(a,b,c,e)=>{a=Ac[a];b=mc(b);return a(null,b,c,e)},t:(a,b,c,e,f)=>
{a=Ac[a];b=mc(b);c=Cc(c);return a(b,b[c],e,f)},c:lc,K:a=>{if(0===a)return Nb(Dc());a=Cc(a);return Nb(Dc()[a])},n:(a,b,c)=>{var e=Fc(a,b),f=e.shift();a--;var k=Array(a);b=`methodCaller<(${e.map(n=>n.name).join(", ")}) => ${f.name}>`;return Ec(Eb(b,(n,l,p,v)=>{for(var w=0,A=0;A<a;++A)k[A]=e[A].readValueFromPointer(v+w),w+=e[A].je;n=1===c?Gc(l,k):l.apply(n,k);return zc(f,p,n)}))},y:(a,b)=>{a=mc(a);b=mc(b);return Nb(a[b])},H:a=>{9<a&&(kc[a+1]+=1)},G:()=>Nb([]),f:a=>Nb(Cc(a)),D:()=>Nb({}),hd:a=>{a=mc(a);
return!a},m:a=>{var b=mc(a);eb(b);lc(a)},h:(a,b,c)=>{a=mc(a);b=mc(b);c=mc(c);a[b]=c},g:(a,b)=>{a=pc(a,"_emval_take_value");a=a.readValueFromPointer(b);return Nb(a)},X:function(){return-52},W:function(){},gd:(a,b,c,e)=>{var f=(new Date).getFullYear(),k=(new Date(f,0,1)).getTimezoneOffset();f=(new Date(f,6,1)).getTimezoneOffset();H[a>>2]=60*Math.max(k,f);E[b>>2]=Number(k!=f);b=n=>{var l=Math.abs(n);return`UTC${0<=n?"-":"+"}${String(Math.floor(l/60)).padStart(2,"0")}${String(l%60).padStart(2,"0")}`};
a=b(k);b=b(f);f<k?(ra(a,c,17),ra(b,e,17)):(ra(a,e,17),ra(b,c,17))},fd:()=>performance.now(),ed:a=>Q.activeTexture(a),dd:(a,b)=>{Q.attachShader(Nc[a],Qc[b])},cd:(a,b)=>{Q.beginQuery(a,Sc[b])},bd:(a,b)=>{Q.me.beginQueryEXT(a,Sc[b])},ad:(a,b,c)=>{Q.bindAttribLocation(Nc[a],b,c?cb(B,c):"")},$c:(a,b)=>{35051==a?Q.Ie=b:35052==a&&(Q.re=b);Q.bindBuffer(a,Mc[b])},_c:cd,Zc:(a,b)=>{Q.bindRenderbuffer(a,Pc[b])},Yc:(a,b)=>{Q.bindSampler(a,Tc[b])},Xc:(a,b)=>{Q.bindTexture(a,ka[b])},Wc:dd,Vc:dd,Uc:(a,b,c,e)=>Q.blendColor(a,
b,c,e),Tc:a=>Q.blendEquation(a),Sc:(a,b)=>Q.blendFunc(a,b),Rc:(a,b,c,e,f,k,n,l,p,v)=>Q.blitFramebuffer(a,b,c,e,f,k,n,l,p,v),Qc:(a,b,c,e)=>{2<=z.version?c&&b?Q.bufferData(a,B,e,c,b):Q.bufferData(a,b,e):Q.bufferData(a,c?B.subarray(c,c+b):b,e)},Pc:(a,b,c,e)=>{2<=z.version?c&&Q.bufferSubData(a,b,B,e,c):Q.bufferSubData(a,b,B.subarray(e,e+c))},Oc:a=>Q.checkFramebufferStatus(a),Nc:ed,Mc:fd,Lc:gd,Kc:(a,b,c,e)=>Q.clientWaitSync(Uc[a],b,(c>>>0)+4294967296*e),Jc:(a,b,c,e)=>{Q.colorMask(!!a,!!b,!!c,!!e)},Ic:a=>
{Q.compileShader(Qc[a])},Hc:(a,b,c,e,f,k,n,l)=>{2<=z.version?Q.re||!n?Q.compressedTexImage2D(a,b,c,e,f,k,n,l):Q.compressedTexImage2D(a,b,c,e,f,k,B,l,n):Q.compressedTexImage2D(a,b,c,e,f,k,B.subarray(l,l+n))},Gc:(a,b,c,e,f,k,n,l,p)=>{2<=z.version?Q.re||!l?Q.compressedTexSubImage2D(a,b,c,e,f,k,n,l,p):Q.compressedTexSubImage2D(a,b,c,e,f,k,n,B,p,l):Q.compressedTexSubImage2D(a,b,c,e,f,k,n,B.subarray(p,p+l))},Fc:(a,b,c,e,f)=>Q.copyBufferSubData(a,b,c,e,f),Ec:(a,b,c,e,f,k,n,l)=>Q.copyTexSubImage2D(a,b,c,
e,f,k,n,l),Dc:()=>{var a=ja(Nc),b=Q.createProgram();b.name=a;b.Ge=b.Ee=b.Fe=0;b.Me=1;Nc[a]=b;return a},Cc:a=>{var b=ja(Qc);Qc[b]=Q.createShader(a);return b},Bc:a=>Q.cullFace(a),Ac:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Mc[e];f&&(Q.deleteBuffer(f),f.name=0,Mc[e]=null,e==Q.Ie&&(Q.Ie=0),e==Q.re&&(Q.re=0))}},zc:(a,b)=>{for(var c=0;c<a;++c){var e=E[b+4*c>>2],f=Oc[e];f&&(Q.deleteFramebuffer(f),f.name=0,Oc[e]=null)}},yc:a=>{if(a){var b=Nc[a];b?(Q.deleteProgram(b),b.name=0,Nc[a]=null):S||=1281}},
xc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Sc[e];f&&(Q.deleteQuery(f),Sc[e]=null)}},wc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Sc[e];f&&(Q.me.deleteQueryEXT(f),Sc[e]=null)}},vc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Pc[e];f&&(Q.deleteRenderbuffer(f),f.name=0,Pc[e]=null)}},uc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Tc[e];f&&(Q.deleteSampler(f),f.name=0,Tc[e]=null)}},tc:a=>{if(a){var b=Qc[a];b?(Q.deleteShader(b),Qc[a]=null):S||=1281}},sc:a=>{if(a){var b=Uc[a];b?
(Q.deleteSync(b),b.name=0,Uc[a]=null):S||=1281}},rc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=ka[e];f&&(Q.deleteTexture(f),f.name=0,ka[e]=null)}},qc:hd,pc:hd,oc:a=>{Q.depthMask(!!a)},nc:a=>Q.disable(a),mc:a=>{Q.disableVertexAttribArray(a)},lc:(a,b,c)=>{Q.drawArrays(a,b,c)},kc:(a,b,c,e)=>{Q.drawArraysInstanced(a,b,c,e)},jc:(a,b,c,e,f)=>{Q.Pe.drawArraysInstancedBaseInstanceWEBGL(a,b,c,e,f)},ic:(a,b)=>{for(var c=jd[a],e=0;e<a;e++)c[e]=E[b+4*e>>2];Q.drawBuffers(c)},hc:(a,b,c,e)=>{Q.drawElements(a,
b,c,e)},gc:(a,b,c,e,f)=>{Q.drawElementsInstanced(a,b,c,e,f)},fc:(a,b,c,e,f,k,n)=>{Q.Pe.drawElementsInstancedBaseVertexBaseInstanceWEBGL(a,b,c,e,f,k,n)},ec:(a,b,c,e,f,k)=>{Q.drawElements(a,e,f,k)},dc:a=>Q.enable(a),cc:a=>{Q.enableVertexAttribArray(a)},bc:a=>Q.endQuery(a),ac:a=>{Q.me.endQueryEXT(a)},$b:(a,b)=>(a=Q.fenceSync(a,b))?(b=ja(Uc),a.name=b,Uc[b]=a,b):0,_b:()=>Q.finish(),Zb:()=>Q.flush(),Yb:(a,b,c,e)=>{Q.framebufferRenderbuffer(a,b,c,Pc[e])},Xb:(a,b,c,e,f)=>{Q.framebufferTexture2D(a,b,c,ka[e],
f)},Wb:a=>Q.frontFace(a),Vb:(a,b)=>{$c(a,b,"createBuffer",Mc)},Ub:(a,b)=>{$c(a,b,"createFramebuffer",Oc)},Tb:(a,b)=>{$c(a,b,"createQuery",Sc)},Sb:(a,b)=>{for(var c=0;c<a;c++){var e=Q.me.createQueryEXT();if(!e){for(S||=1282;c<a;)E[b+4*c++>>2]=0;break}var f=ja(Sc);e.name=f;Sc[f]=e;E[b+4*c>>2]=f}},Rb:(a,b)=>{$c(a,b,"createRenderbuffer",Pc)},Qb:(a,b)=>{$c(a,b,"createSampler",Tc)},Pb:(a,b)=>{$c(a,b,"createTexture",ka)},Ob:kd,Nb:kd,Mb:a=>Q.generateMipmap(a),Lb:(a,b,c)=>{c?E[c>>2]=Q.getBufferParameter(a,
b):S||=1281},Kb:()=>{var a=Q.getError()||S;S=0;return a},Jb:(a,b)=>md(a,b,2),Ib:(a,b,c,e)=>{a=Q.getFramebufferAttachmentParameter(a,b,c);if(a instanceof WebGLRenderbuffer||a instanceof WebGLTexture)a=a.name|0;E[e>>2]=a},Hb:nd,Gb:(a,b,c,e)=>{a=Q.getProgramInfoLog(Nc[a]);null===a&&(a="(unknown error)");b=0<b&&e?ra(a,e,b):0;c&&(E[c>>2]=b)},Fb:(a,b,c)=>{if(c)if(a>=Lc)S||=1281;else if(a=Nc[a],35716==b)a=Q.getProgramInfoLog(a),null===a&&(a="(unknown error)"),E[c>>2]=a.length+1;else if(35719==b){if(!a.Ge){var e=
Q.getProgramParameter(a,35718);for(b=0;b<e;++b)a.Ge=Math.max(a.Ge,Q.getActiveUniform(a,b).name.length+1)}E[c>>2]=a.Ge}else if(35722==b){if(!a.Ee)for(e=Q.getProgramParameter(a,35721),b=0;b<e;++b)a.Ee=Math.max(a.Ee,Q.getActiveAttrib(a,b).name.length+1);E[c>>2]=a.Ee}else if(35381==b){if(!a.Fe)for(e=Q.getProgramParameter(a,35382),b=0;b<e;++b)a.Fe=Math.max(a.Fe,Q.getActiveUniformBlockName(a,b).length+1);E[c>>2]=a.Fe}else E[c>>2]=Q.getProgramParameter(a,b);else S||=1281},Eb:od,Db:od,Cb:(a,b,c)=>{if(c){a=
Q.getQueryParameter(Sc[a],b);var e;"boolean"==typeof a?e=a?1:0:e=a;E[c>>2]=e}else S||=1281},Bb:(a,b,c)=>{if(c){a=Q.me.getQueryObjectEXT(Sc[a],b);var e;"boolean"==typeof a?e=a?1:0:e=a;E[c>>2]=e}else S||=1281},Ab:(a,b,c)=>{c?E[c>>2]=Q.getQuery(a,b):S||=1281},zb:(a,b,c)=>{c?E[c>>2]=Q.me.getQueryEXT(a,b):S||=1281},yb:(a,b,c)=>{c?E[c>>2]=Q.getRenderbufferParameter(a,b):S||=1281},xb:(a,b,c,e)=>{a=Q.getShaderInfoLog(Qc[a]);null===a&&(a="(unknown error)");b=0<b&&e?ra(a,e,b):0;c&&(E[c>>2]=b)},wb:(a,b,c,e)=>
{a=Q.getShaderPrecisionFormat(a,b);E[c>>2]=a.rangeMin;E[c+4>>2]=a.rangeMax;E[e>>2]=a.precision},vb:(a,b,c)=>{c?35716==b?(a=Q.getShaderInfoLog(Qc[a]),null===a&&(a="(unknown error)"),E[c>>2]=a?a.length+1:0):35720==b?(a=Q.getShaderSource(Qc[a]),E[c>>2]=a?a.length+1:0):E[c>>2]=Q.getShaderParameter(Qc[a],b):S||=1281},ub:rd,tb:sd,sb:(a,b)=>{b=b?cb(B,b):"";if(a=Nc[a]){var c=a,e=c.xe,f=c.Ue,k;if(!e){c.xe=e={};c.Te={};var n=Q.getProgramParameter(c,35718);for(k=0;k<n;++k){var l=Q.getActiveUniform(c,k);var p=
l.name;l=l.size;var v=td(p);v=0<v?p.slice(0,v):p;var w=c.Me;c.Me+=l;f[v]=[l,w];for(p=0;p<l;++p)e[w]=p,c.Te[w++]=v}}c=a.xe;e=0;f=b;k=td(b);0<k&&(e=parseInt(b.slice(k+1))>>>0,f=b.slice(0,k));if((f=a.Ue[f])&&e<f[0]&&(e+=f[1],c[e]=c[e]||Q.getUniformLocation(a,b)))return e}else S||=1281;return-1},rb:(a,b,c)=>{for(var e=jd[b],f=0;f<b;f++)e[f]=E[c+4*f>>2];Q.invalidateFramebuffer(a,e)},qb:(a,b,c,e,f,k,n)=>{for(var l=jd[b],p=0;p<b;p++)l[p]=E[c+4*p>>2];Q.invalidateSubFramebuffer(a,l,e,f,k,n)},pb:a=>Q.isSync(Uc[a]),
ob:a=>(a=ka[a])?Q.isTexture(a):0,nb:a=>Q.lineWidth(a),mb:a=>{a=Nc[a];Q.linkProgram(a);a.xe=0;a.Ue={}},lb:(a,b,c,e,f,k)=>{Q.Re.multiDrawArraysInstancedBaseInstanceWEBGL(a,E,b>>2,E,c>>2,E,e>>2,H,f>>2,k)},kb:(a,b,c,e,f,k,n,l)=>{Q.Re.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(a,E,b>>2,c,E,e>>2,E,f>>2,E,k>>2,H,n>>2,l)},jb:(a,b)=>{3317==a?Yc=b:3314==a&&(Zc=b);Q.pixelStorei(a,b)},ib:(a,b)=>{Q.me.queryCounterEXT(Sc[a],b)},hb:a=>Q.readBuffer(a),gb:(a,b,c,e,f,k,n)=>{if(2<=z.version)if(Q.Ie)Q.readPixels(a,
b,c,e,f,k,n);else{var l=ud(k);n>>>=31-Math.clz32(l.BYTES_PER_ELEMENT);Q.readPixels(a,b,c,e,f,k,l,n)}else(l=vd(k,f,c,e,n))?Q.readPixels(a,b,c,e,f,k,l):S||=1280},fb:(a,b,c,e)=>Q.renderbufferStorage(a,b,c,e),eb:(a,b,c,e,f)=>Q.renderbufferStorageMultisample(a,b,c,e,f),db:(a,b,c)=>{Q.samplerParameterf(Tc[a],b,c)},cb:(a,b,c)=>{Q.samplerParameteri(Tc[a],b,c)},bb:(a,b,c)=>{Q.samplerParameteri(Tc[a],b,E[c>>2])},ab:(a,b,c,e)=>Q.scissor(a,b,c,e),$a:(a,b,c,e)=>{for(var f="",k=0;k<b;++k){var n=(n=H[c+4*k>>2])?
cb(B,n,e?H[e+4*k>>2]:void 0):"";f+=n}Q.shaderSource(Qc[a],f)},_a:(a,b,c)=>Q.stencilFunc(a,b,c),Za:(a,b,c,e)=>Q.stencilFuncSeparate(a,b,c,e),Ya:a=>Q.stencilMask(a),Xa:(a,b)=>Q.stencilMaskSeparate(a,b),Wa:(a,b,c)=>Q.stencilOp(a,b,c),Va:(a,b,c,e)=>Q.stencilOpSeparate(a,b,c,e),Ua:(a,b,c,e,f,k,n,l,p)=>{if(2<=z.version){if(Q.re){Q.texImage2D(a,b,c,e,f,k,n,l,p);return}if(p){var v=ud(l);p>>>=31-Math.clz32(v.BYTES_PER_ELEMENT);Q.texImage2D(a,b,c,e,f,k,n,l,v,p);return}}v=p?vd(l,n,e,f,p):null;Q.texImage2D(a,
b,c,e,f,k,n,l,v)},Ta:(a,b,c)=>Q.texParameterf(a,b,c),Sa:(a,b,c)=>{Q.texParameterf(a,b,J[c>>2])},Ra:(a,b,c)=>Q.texParameteri(a,b,c),Qa:(a,b,c)=>{Q.texParameteri(a,b,E[c>>2])},Pa:(a,b,c,e,f)=>Q.texStorage2D(a,b,c,e,f),Oa:(a,b,c,e,f,k,n,l,p)=>{if(2<=z.version){if(Q.re){Q.texSubImage2D(a,b,c,e,f,k,n,l,p);return}if(p){var v=ud(l);Q.texSubImage2D(a,b,c,e,f,k,n,l,v,p>>>31-Math.clz32(v.BYTES_PER_ELEMENT));return}}p=p?vd(l,n,f,k,p):null;Q.texSubImage2D(a,b,c,e,f,k,n,l,p)},Na:(a,b)=>{Q.uniform1f(V(a),b)},Ma:(a,
b,c)=>{if(2<=z.version)b&&Q.uniform1fv(V(a),J,c>>2,b);else{if(288>=b)for(var e=wd[b],f=0;f<b;++f)e[f]=J[c+4*f>>2];else e=J.subarray(c>>2,c+4*b>>2);Q.uniform1fv(V(a),e)}},La:(a,b)=>{Q.uniform1i(V(a),b)},Ka:(a,b,c)=>{if(2<=z.version)b&&Q.uniform1iv(V(a),E,c>>2,b);else{if(288>=b)for(var e=xd[b],f=0;f<b;++f)e[f]=E[c+4*f>>2];else e=E.subarray(c>>2,c+4*b>>2);Q.uniform1iv(V(a),e)}},Ja:(a,b,c)=>{Q.uniform2f(V(a),b,c)},Ia:(a,b,c)=>{if(2<=z.version)b&&Q.uniform2fv(V(a),J,c>>2,2*b);else{if(144>=b){b*=2;for(var e=
wd[b],f=0;f<b;f+=2)e[f]=J[c+4*f>>2],e[f+1]=J[c+(4*f+4)>>2]}else e=J.subarray(c>>2,c+8*b>>2);Q.uniform2fv(V(a),e)}},Ha:(a,b,c)=>{Q.uniform2i(V(a),b,c)},Ga:(a,b,c)=>{if(2<=z.version)b&&Q.uniform2iv(V(a),E,c>>2,2*b);else{if(144>=b){b*=2;for(var e=xd[b],f=0;f<b;f+=2)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2]}else e=E.subarray(c>>2,c+8*b>>2);Q.uniform2iv(V(a),e)}},Fa:(a,b,c,e)=>{Q.uniform3f(V(a),b,c,e)},Ea:(a,b,c)=>{if(2<=z.version)b&&Q.uniform3fv(V(a),J,c>>2,3*b);else{if(96>=b){b*=3;for(var e=wd[b],f=0;f<
b;f+=3)e[f]=J[c+4*f>>2],e[f+1]=J[c+(4*f+4)>>2],e[f+2]=J[c+(4*f+8)>>2]}else e=J.subarray(c>>2,c+12*b>>2);Q.uniform3fv(V(a),e)}},Da:(a,b,c,e)=>{Q.uniform3i(V(a),b,c,e)},Ca:(a,b,c)=>{if(2<=z.version)b&&Q.uniform3iv(V(a),E,c>>2,3*b);else{if(96>=b){b*=3;for(var e=xd[b],f=0;f<b;f+=3)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2],e[f+2]=E[c+(4*f+8)>>2]}else e=E.subarray(c>>2,c+12*b>>2);Q.uniform3iv(V(a),e)}},Ba:(a,b,c,e,f)=>{Q.uniform4f(V(a),b,c,e,f)},Aa:(a,b,c)=>{if(2<=z.version)b&&Q.uniform4fv(V(a),J,c>>2,4*
b);else{if(72>=b){var e=wd[4*b],f=J;c>>=2;b*=4;for(var k=0;k<b;k+=4){var n=c+k;e[k]=f[n];e[k+1]=f[n+1];e[k+2]=f[n+2];e[k+3]=f[n+3]}}else e=J.subarray(c>>2,c+16*b>>2);Q.uniform4fv(V(a),e)}},za:(a,b,c,e,f)=>{Q.uniform4i(V(a),b,c,e,f)},ya:(a,b,c)=>{if(2<=z.version)b&&Q.uniform4iv(V(a),E,c>>2,4*b);else{if(72>=b){b*=4;for(var e=xd[b],f=0;f<b;f+=4)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2],e[f+2]=E[c+(4*f+8)>>2],e[f+3]=E[c+(4*f+12)>>2]}else e=E.subarray(c>>2,c+16*b>>2);Q.uniform4iv(V(a),e)}},xa:(a,b,c,e)=>
{if(2<=z.version)b&&Q.uniformMatrix2fv(V(a),!!c,J,e>>2,4*b);else{if(72>=b){b*=4;for(var f=wd[b],k=0;k<b;k+=4)f[k]=J[e+4*k>>2],f[k+1]=J[e+(4*k+4)>>2],f[k+2]=J[e+(4*k+8)>>2],f[k+3]=J[e+(4*k+12)>>2]}else f=J.subarray(e>>2,e+16*b>>2);Q.uniformMatrix2fv(V(a),!!c,f)}},wa:(a,b,c,e)=>{if(2<=z.version)b&&Q.uniformMatrix3fv(V(a),!!c,J,e>>2,9*b);else{if(32>=b){b*=9;for(var f=wd[b],k=0;k<b;k+=9)f[k]=J[e+4*k>>2],f[k+1]=J[e+(4*k+4)>>2],f[k+2]=J[e+(4*k+8)>>2],f[k+3]=J[e+(4*k+12)>>2],f[k+4]=J[e+(4*k+16)>>2],f[k+
5]=J[e+(4*k+20)>>2],f[k+6]=J[e+(4*k+24)>>2],f[k+7]=J[e+(4*k+28)>>2],f[k+8]=J[e+(4*k+32)>>2]}else f=J.subarray(e>>2,e+36*b>>2);Q.uniformMatrix3fv(V(a),!!c,f)}},va:(a,b,c,e)=>{if(2<=z.version)b&&Q.uniformMatrix4fv(V(a),!!c,J,e>>2,16*b);else{if(18>=b){var f=wd[16*b],k=J;e>>=2;b*=16;for(var n=0;n<b;n+=16){var l=e+n;f[n]=k[l];f[n+1]=k[l+1];f[n+2]=k[l+2];f[n+3]=k[l+3];f[n+4]=k[l+4];f[n+5]=k[l+5];f[n+6]=k[l+6];f[n+7]=k[l+7];f[n+8]=k[l+8];f[n+9]=k[l+9];f[n+10]=k[l+10];f[n+11]=k[l+11];f[n+12]=k[l+12];f[n+
13]=k[l+13];f[n+14]=k[l+14];f[n+15]=k[l+15]}}else f=J.subarray(e>>2,e+64*b>>2);Q.uniformMatrix4fv(V(a),!!c,f)}},ua:a=>{a=Nc[a];Q.useProgram(a);Q.bf=a},ta:(a,b)=>Q.vertexAttrib1f(a,b),sa:(a,b)=>{Q.vertexAttrib2f(a,J[b>>2],J[b+4>>2])},ra:(a,b)=>{Q.vertexAttrib3f(a,J[b>>2],J[b+4>>2],J[b+8>>2])},qa:(a,b)=>{Q.vertexAttrib4f(a,J[b>>2],J[b+4>>2],J[b+8>>2],J[b+12>>2])},pa:(a,b)=>{Q.vertexAttribDivisor(a,b)},oa:(a,b,c,e,f)=>{Q.vertexAttribIPointer(a,b,c,e,f)},na:(a,b,c,e,f,k)=>{Q.vertexAttribPointer(a,b,c,
!!e,f,k)},ma:(a,b,c,e)=>Q.viewport(a,b,c,e),la:(a,b,c,e)=>{Q.waitSync(Uc[a],b,(c>>>0)+4294967296*e)},ka:a=>{var b=B.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+1/c);e=Math.min(e,a+100663296);a:{e=(Math.min(2147483648,65536*Math.ceil(Math.max(a,e)/65536))-za.buffer.byteLength+65535)/65536|0;try{za.grow(e);Ha();var f=1;break a}catch(k){}f=void 0}if(f)return!0}return!1},ja:()=>z?z.handle:0,qd:(a,b)=>{var c=0;Ad().forEach((e,f)=>{var k=b+c;f=H[a+4*f>>2]=k;for(k=0;k<e.length;++k)Ca[f++]=
e.charCodeAt(k);Ca[f]=0;c+=e.length+1});return 0},pd:(a,b)=>{var c=Ad();H[a>>2]=c.length;var e=0;c.forEach(f=>e+=f.length+1);H[b>>2]=e;return 0},ia:a=>{throw new Va(a);},N:()=>52,_:function(){return 52},od:()=>52,Z:function(){return 70},T:(a,b,c,e)=>{for(var f=0,k=0;k<c;k++){var n=H[b>>2],l=H[b+4>>2];b+=8;for(var p=0;p<l;p++){var v=B[n+p],w=Bd[a];0===v||10===v?((1===a?wa:ya)(cb(w)),w.length=0):w.push(v)}f+=l}H[e>>2]=f;return 0},ha:cd,ga:ed,fa:fd,ea:gd,J:nd,Q:rd,da:sd,k:Hd,u:Id,i:Jd,I:Kd,ca:Ld,P:Md,
O:Nd,s:Od,x:Pd,r:Qd,v:Rd,ba:Sd,aa:Td,$:Ud},Z=function(){var a={a:Vd};La++;Ra??=r.locateFile?Qa("canvaskit.wasm")?"canvaskit.wasm":ta+"canvaskit.wasm":(new URL("canvaskit.wasm",import.meta.url)).href;Ua(a,function(b){Z=b.instance.exports;za=Z.wd;Ha();O=Z.zd;Ja.unshift(Z.xd);La--;0==La&&(null!==Ma&&(clearInterval(Ma),Ma=null),Oa&&(b=Oa,Oa=null,b()))}).catch(ca);return{}}(),bc=a=>(bc=Z.yd)(a),pd=r._malloc=a=>(pd=r._malloc=Z.Ad)(a),cc=r._free=a=>(cc=r._free=Z.Bd)(a),Wd=(a,b)=>(Wd=Z.Cd)(a,b),
Xd=a=>(Xd=Z.Dd)(a),Yd=()=>(Yd=Z.Ed)();r.dynCall_viji=(a,b,c,e,f)=>(r.dynCall_viji=Z.Fd)(a,b,c,e,f);r.dynCall_vijiii=(a,b,c,e,f,k,n)=>(r.dynCall_vijiii=Z.Gd)(a,b,c,e,f,k,n);r.dynCall_viiiiij=(a,b,c,e,f,k,n,l)=>(r.dynCall_viiiiij=Z.Hd)(a,b,c,e,f,k,n,l);r.dynCall_iiiji=(a,b,c,e,f,k)=>(r.dynCall_iiiji=Z.Id)(a,b,c,e,f,k);r.dynCall_jii=(a,b,c)=>(r.dynCall_jii=Z.Jd)(a,b,c);r.dynCall_vij=(a,b,c,e)=>(r.dynCall_vij=Z.Kd)(a,b,c,e);r.dynCall_jiiiiii=(a,b,c,e,f,k,n)=>(r.dynCall_jiiiiii=Z.Ld)(a,b,c,e,f,k,n);
r.dynCall_jiiiiji=(a,b,c,e,f,k,n,l)=>(r.dynCall_jiiiiji=Z.Md)(a,b,c,e,f,k,n,l);r.dynCall_ji=(a,b)=>(r.dynCall_ji=Z.Nd)(a,b);r.dynCall_iijj=(a,b,c,e,f,k)=>(r.dynCall_iijj=Z.Od)(a,b,c,e,f,k);r.dynCall_iiji=(a,b,c,e,f)=>(r.dynCall_iiji=Z.Pd)(a,b,c,e,f);r.dynCall_iijjiii=(a,b,c,e,f,k,n,l,p)=>(r.dynCall_iijjiii=Z.Qd)(a,b,c,e,f,k,n,l,p);r.dynCall_iij=(a,b,c,e)=>(r.dynCall_iij=Z.Rd)(a,b,c,e);r.dynCall_vijjjii=(a,b,c,e,f,k,n,l,p,v)=>(r.dynCall_vijjjii=Z.Sd)(a,b,c,e,f,k,n,l,p,v);
r.dynCall_jiji=(a,b,c,e,f)=>(r.dynCall_jiji=Z.Td)(a,b,c,e,f);r.dynCall_viijii=(a,b,c,e,f,k,n)=>(r.dynCall_viijii=Z.Ud)(a,b,c,e,f,k,n);r.dynCall_iiiiij=(a,b,c,e,f,k,n)=>(r.dynCall_iiiiij=Z.Vd)(a,b,c,e,f,k,n);r.dynCall_iiiiijj=(a,b,c,e,f,k,n,l,p)=>(r.dynCall_iiiiijj=Z.Wd)(a,b,c,e,f,k,n,l,p);r.dynCall_iiiiiijj=(a,b,c,e,f,k,n,l,p,v)=>(r.dynCall_iiiiiijj=Z.Xd)(a,b,c,e,f,k,n,l,p,v);function Rd(a,b,c,e,f){var k=Yd();try{O.get(a)(b,c,e,f)}catch(n){Xd(k);if(n!==n+0)throw n;Wd(1,0)}}
function Id(a,b,c){var e=Yd();try{return O.get(a)(b,c)}catch(f){Xd(e);if(f!==f+0)throw f;Wd(1,0)}}function Pd(a,b,c){var e=Yd();try{O.get(a)(b,c)}catch(f){Xd(e);if(f!==f+0)throw f;Wd(1,0)}}function Hd(a,b){var c=Yd();try{return O.get(a)(b)}catch(e){Xd(c);if(e!==e+0)throw e;Wd(1,0)}}function Od(a,b){var c=Yd();try{O.get(a)(b)}catch(e){Xd(c);if(e!==e+0)throw e;Wd(1,0)}}function Jd(a,b,c,e){var f=Yd();try{return O.get(a)(b,c,e)}catch(k){Xd(f);if(k!==k+0)throw k;Wd(1,0)}}
function Ud(a,b,c,e,f,k,n,l,p,v){var w=Yd();try{O.get(a)(b,c,e,f,k,n,l,p,v)}catch(A){Xd(w);if(A!==A+0)throw A;Wd(1,0)}}function Qd(a,b,c,e){var f=Yd();try{O.get(a)(b,c,e)}catch(k){Xd(f);if(k!==k+0)throw k;Wd(1,0)}}function Td(a,b,c,e,f,k,n){var l=Yd();try{O.get(a)(b,c,e,f,k,n)}catch(p){Xd(l);if(p!==p+0)throw p;Wd(1,0)}}function Md(a,b,c,e,f,k,n,l){var p=Yd();try{return O.get(a)(b,c,e,f,k,n,l)}catch(v){Xd(p);if(v!==v+0)throw v;Wd(1,0)}}
function Sd(a,b,c,e,f,k){var n=Yd();try{O.get(a)(b,c,e,f,k)}catch(l){Xd(n);if(l!==l+0)throw l;Wd(1,0)}}function Kd(a,b,c,e,f){var k=Yd();try{return O.get(a)(b,c,e,f)}catch(n){Xd(k);if(n!==n+0)throw n;Wd(1,0)}}function Nd(a,b,c,e,f,k,n,l,p,v){var w=Yd();try{return O.get(a)(b,c,e,f,k,n,l,p,v)}catch(A){Xd(w);if(A!==A+0)throw A;Wd(1,0)}}function Ld(a,b,c,e,f,k,n){var l=Yd();try{return O.get(a)(b,c,e,f,k,n)}catch(p){Xd(l);if(p!==p+0)throw p;Wd(1,0)}}var Zd,$d;Oa=function ae(){Zd||be();Zd||(Oa=ae)};
function be(){if(!(0<La)){if(!$d&&($d=1,Wa(Ia),0<La))return;Zd||(Zd=1,r.calledRun=1,Aa||(Wa(Ja),aa(r),r.onRuntimeInitialized?.(),Wa(Ka)))}}be();moduleRtn=da;
return moduleRtn;
}
);
})();
export default CanvasKitInit;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,191 @@
var CanvasKitInit = (() => {
var _scriptName = import.meta.url;
return (
function(moduleArg = {}) {
var moduleRtn;
var r=moduleArg,aa,ca,da=new Promise((a,b)=>{aa=a;ca=b}),ea="object"==typeof window,ha="function"==typeof importScripts;
(function(a){a.Xd=a.Xd||[];a.Xd.push(function(){a.MakeSWCanvasSurface=function(b){var c=b,e="undefined"!==typeof OffscreenCanvas&&c instanceof OffscreenCanvas;if(!("undefined"!==typeof HTMLCanvasElement&&c instanceof HTMLCanvasElement||e||(c=document.getElementById(b),c)))throw"Canvas with id "+b+" was not found";if(b=a.MakeSurface(c.width,c.height))b.ue=c;return b};a.MakeCanvasSurface||(a.MakeCanvasSurface=a.MakeSWCanvasSurface);a.MakeSurface=function(b,c){var e={width:b,height:c,colorType:a.ColorType.RGBA_8888,
alphaType:a.AlphaType.Unpremul,colorSpace:a.ColorSpace.SRGB},f=b*c*4,k=a._malloc(f);if(e=a.Surface._makeRasterDirect(e,k,4*b))e.ue=null,e.Ue=b,e.Re=c,e.Se=f,e.Be=k,e.getCanvas().clear(a.TRANSPARENT);return e};a.MakeRasterDirectSurface=function(b,c,e){return a.Surface._makeRasterDirect(b,c.byteOffset,e)};a.Surface.prototype.flush=function(b){a.Ud(this.Td);this._flush();if(this.ue){var c=new Uint8ClampedArray(a.HEAPU8.buffer,this.Be,this.Se);c=new ImageData(c,this.Ue,this.Re);b?this.ue.getContext("2d").putImageData(c,
0,0,b[0],b[1],b[2]-b[0],b[3]-b[1]):this.ue.getContext("2d").putImageData(c,0,0)}};a.Surface.prototype.dispose=function(){this.Be&&a._free(this.Be);this.delete()};a.Ud=a.Ud||function(){};a.ve=a.ve||function(){return null}})})(r);
(function(a){a.Xd=a.Xd||[];a.Xd.push(function(){function b(l,q,v){return l&&l.hasOwnProperty(q)?l[q]:v}function c(l){var q=ja(ka);ka[q]=l;return q}function e(l){return l.naturalHeight||l.videoHeight||l.displayHeight||l.height}function f(l){return l.naturalWidth||l.videoWidth||l.displayWidth||l.width}function k(l,q,v,w){l.bindTexture(l.TEXTURE_2D,q);w||v.alphaType!==a.AlphaType.Premul||l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);return q}function n(l,q,v){v||q.alphaType!==a.AlphaType.Premul||
l.pixelStorei(l.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);l.bindTexture(l.TEXTURE_2D,null)}a.GetWebGLContext=function(l,q){if(!l)throw"null canvas passed into makeWebGLContext";var v={alpha:b(q,"alpha",1),depth:b(q,"depth",1),stencil:b(q,"stencil",8),antialias:b(q,"antialias",0),premultipliedAlpha:b(q,"premultipliedAlpha",1),preserveDrawingBuffer:b(q,"preserveDrawingBuffer",0),preferLowPowerToHighPerformance:b(q,"preferLowPowerToHighPerformance",0),failIfMajorPerformanceCaveat:b(q,"failIfMajorPerformanceCaveat",
0),enableExtensionsByDefault:b(q,"enableExtensionsByDefault",1),explicitSwapControl:b(q,"explicitSwapControl",0),renderViaOffscreenBackBuffer:b(q,"renderViaOffscreenBackBuffer",0)};v.majorVersion=q&&q.majorVersion?q.majorVersion:"undefined"!==typeof WebGL2RenderingContext?2:1;if(v.explicitSwapControl)throw"explicitSwapControl is not supported";l=la(l,v);if(!l)return 0;oa(l);A.fe.getExtension("WEBGL_debug_renderer_info");return l};a.deleteContext=function(l){A===pa[l]&&(A=null);"object"==typeof JSEvents&&
JSEvents.uf(pa[l].fe.canvas);pa[l]&&pa[l].fe.canvas&&(pa[l].fe.canvas.Pe=void 0);pa[l]=null};a._setTextureCleanup({deleteTexture:function(l,q){var v=ka[q];v&&pa[l].fe.deleteTexture(v);ka[q]=null}});a.MakeWebGLContext=function(l){if(!this.Ud(l))return null;var q=this._MakeGrContext();if(!q)return null;q.Td=l;var v=q.delete.bind(q);q["delete"]=function(){a.Ud(this.Td);v()}.bind(q);return A.De=q};a.MakeGrContext=a.MakeWebGLContext;a.GrDirectContext.prototype.getResourceCacheLimitBytes=function(){a.Ud(this.Td);
this._getResourceCacheLimitBytes()};a.GrDirectContext.prototype.getResourceCacheUsageBytes=function(){a.Ud(this.Td);this._getResourceCacheUsageBytes()};a.GrDirectContext.prototype.releaseResourcesAndAbandonContext=function(){a.Ud(this.Td);this._releaseResourcesAndAbandonContext()};a.GrDirectContext.prototype.setResourceCacheLimitBytes=function(l){a.Ud(this.Td);this._setResourceCacheLimitBytes(l)};a.MakeOnScreenGLSurface=function(l,q,v,w,z,D){if(!this.Ud(l.Td))return null;q=void 0===z||void 0===D?
this._MakeOnScreenGLSurface(l,q,v,w):this._MakeOnScreenGLSurface(l,q,v,w,z,D);if(!q)return null;q.Td=l.Td;return q};a.MakeRenderTarget=function(){var l=arguments[0];if(!this.Ud(l.Td))return null;if(3===arguments.length){var q=this._MakeRenderTargetWH(l,arguments[1],arguments[2]);if(!q)return null}else if(2===arguments.length){if(q=this._MakeRenderTargetII(l,arguments[1]),!q)return null}else return null;q.Td=l.Td;return q};a.MakeWebGLCanvasSurface=function(l,q,v){q=q||null;var w=l,z="undefined"!==
typeof OffscreenCanvas&&w instanceof OffscreenCanvas;if(!("undefined"!==typeof HTMLCanvasElement&&w instanceof HTMLCanvasElement||z||(w=document.getElementById(l),w)))throw"Canvas with id "+l+" was not found";l=this.GetWebGLContext(w,v);if(!l||0>l)throw"failed to create webgl context: err "+l;l=this.MakeWebGLContext(l);q=this.MakeOnScreenGLSurface(l,w.width,w.height,q);return q?q:(q=w.cloneNode(!0),w.parentNode.replaceChild(q,w),q.classList.add("ck-replaced"),a.MakeSWCanvasSurface(q))};a.MakeCanvasSurface=
a.MakeWebGLCanvasSurface;a.Surface.prototype.makeImageFromTexture=function(l,q){a.Ud(this.Td);l=c(l);if(q=this._makeImageFromTexture(this.Td,l,q))q.oe=l;return q};a.Surface.prototype.makeImageFromTextureSource=function(l,q,v){q||={height:e(l),width:f(l),colorType:a.ColorType.RGBA_8888,alphaType:v?a.AlphaType.Premul:a.AlphaType.Unpremul};q.colorSpace||(q.colorSpace=a.ColorSpace.SRGB);a.Ud(this.Td);var w=A.fe;v=k(w,w.createTexture(),q,v);2===A.version?w.texImage2D(w.TEXTURE_2D,0,w.RGBA,q.width,q.height,
0,w.RGBA,w.UNSIGNED_BYTE,l):w.texImage2D(w.TEXTURE_2D,0,w.RGBA,w.RGBA,w.UNSIGNED_BYTE,l);n(w,q);this._resetContext();return this.makeImageFromTexture(v,q)};a.Surface.prototype.updateTextureFromSource=function(l,q,v){if(l.oe){a.Ud(this.Td);var w=l.getImageInfo(),z=A.fe,D=k(z,ka[l.oe],w,v);2===A.version?z.texImage2D(z.TEXTURE_2D,0,z.RGBA,f(q),e(q),0,z.RGBA,z.UNSIGNED_BYTE,q):z.texImage2D(z.TEXTURE_2D,0,z.RGBA,z.RGBA,z.UNSIGNED_BYTE,q);n(z,w,v);this._resetContext();ka[l.oe]=null;l.oe=c(D);w.colorSpace=
l.getColorSpace();q=this._makeImageFromTexture(this.Td,l.oe,w);v=l.Sd.Vd;z=l.Sd.Zd;l.Sd.Vd=q.Sd.Vd;l.Sd.Zd=q.Sd.Zd;q.Sd.Vd=v;q.Sd.Zd=z;q.delete();w.colorSpace.delete()}};a.MakeLazyImageFromTextureSource=function(l,q,v){q||={height:e(l),width:f(l),colorType:a.ColorType.RGBA_8888,alphaType:v?a.AlphaType.Premul:a.AlphaType.Unpremul};q.colorSpace||(q.colorSpace=a.ColorSpace.SRGB);var w={makeTexture:function(){var z=A,D=z.fe,I=k(D,D.createTexture(),q,v);2===z.version?D.texImage2D(D.TEXTURE_2D,0,D.RGBA,
q.width,q.height,0,D.RGBA,D.UNSIGNED_BYTE,l):D.texImage2D(D.TEXTURE_2D,0,D.RGBA,D.RGBA,D.UNSIGNED_BYTE,l);n(D,q,v);return c(I)},freeSrc:function(){}};"VideoFrame"===l.constructor.name&&(w.freeSrc=function(){l.close()});return a.Image._makeFromGenerator(q,w)};a.Ud=function(l){return l?oa(l):!1};a.ve=function(){return A&&A.De&&!A.De.isDeleted()?A.De:null}})})(r);
(function(a){function b(g){return(f(255*g[3])<<24|f(255*g[0])<<16|f(255*g[1])<<8|f(255*g[2])<<0)>>>0}function c(g){if(g&&g._ck)return g;if(g instanceof Float32Array){for(var d=Math.floor(g.length/4),h=new Uint32Array(d),m=0;m<d;m++)h[m]=b(g.slice(4*m,4*(m+1)));return h}if(g instanceof Uint32Array)return g;if(g instanceof Array&&g[0]instanceof Float32Array)return g.map(b)}function e(g){if(void 0===g)return 1;var d=parseFloat(g);return g&&-1!==g.indexOf("%")?d/100:d}function f(g){return Math.round(Math.max(0,
Math.min(g||0,255)))}function k(g,d){d&&d._ck||a._free(g)}function n(g,d,h){if(!g||!g.length)return K;if(g&&g._ck)return g.byteOffset;var m=a[d].BYTES_PER_ELEMENT;h||=a._malloc(g.length*m);a[d].set(g,h/m);return h}function l(g){var d={be:K,count:g.length,colorType:a.ColorType.RGBA_F32};if(g instanceof Float32Array)d.be=n(g,"HEAPF32"),d.count=g.length/4;else if(g instanceof Uint32Array)d.be=n(g,"HEAPU32"),d.colorType=a.ColorType.RGBA_8888;else if(g instanceof Array){if(g&&g.length){for(var h=a._malloc(16*
g.length),m=0,t=h/4,u=0;u<g.length;u++)for(var x=0;4>x;x++)a.HEAPF32[t+m]=g[u][x],m++;g=h}else g=K;d.be=g}else throw"Invalid argument to copyFlexibleColorArray, Not a color array "+typeof g;return d}function q(g){if(!g)return K;var d=ba.toTypedArray();if(g.length){if(6===g.length||9===g.length)return n(g,"HEAPF32",P),6===g.length&&a.HEAPF32.set(Wc,6+P/4),P;if(16===g.length)return d[0]=g[0],d[1]=g[1],d[2]=g[3],d[3]=g[4],d[4]=g[5],d[5]=g[7],d[6]=g[12],d[7]=g[13],d[8]=g[15],P;throw"invalid matrix size";
}if(void 0===g.m11)throw"invalid matrix argument";d[0]=g.m11;d[1]=g.m21;d[2]=g.m41;d[3]=g.m12;d[4]=g.m22;d[5]=g.m42;d[6]=g.m14;d[7]=g.m24;d[8]=g.m44;return P}function v(g){if(!g)return K;var d=Y.toTypedArray();if(g.length){if(16!==g.length&&6!==g.length&&9!==g.length)throw"invalid matrix size";if(16===g.length)return n(g,"HEAPF32",ma);d.fill(0);d[0]=g[0];d[1]=g[1];d[3]=g[2];d[4]=g[3];d[5]=g[4];d[7]=g[5];d[10]=1;d[12]=g[6];d[13]=g[7];d[15]=g[8];6===g.length&&(d[12]=0,d[13]=0,d[15]=1);return ma}if(void 0===
g.m11)throw"invalid matrix argument";d[0]=g.m11;d[1]=g.m21;d[2]=g.m31;d[3]=g.m41;d[4]=g.m12;d[5]=g.m22;d[6]=g.m32;d[7]=g.m42;d[8]=g.m13;d[9]=g.m23;d[10]=g.m33;d[11]=g.m43;d[12]=g.m14;d[13]=g.m24;d[14]=g.m34;d[15]=g.m44;return ma}function w(g,d){return n(g,"HEAPF32",d||ia)}function z(g,d,h,m){var t=Ea.toTypedArray();t[0]=g;t[1]=d;t[2]=h;t[3]=m;return ia}function D(g){for(var d=new Float32Array(4),h=0;4>h;h++)d[h]=a.HEAPF32[g/4+h];return d}function I(g,d){return n(g,"HEAPF32",d||W)}function Q(g,d){return n(g,
"HEAPF32",d||ub)}a.Color=function(g,d,h,m){void 0===m&&(m=1);return a.Color4f(f(g)/255,f(d)/255,f(h)/255,m)};a.ColorAsInt=function(g,d,h,m){void 0===m&&(m=255);return(f(m)<<24|f(g)<<16|f(d)<<8|f(h)<<0&268435455)>>>0};a.Color4f=function(g,d,h,m){void 0===m&&(m=1);return Float32Array.of(g,d,h,m)};Object.defineProperty(a,"TRANSPARENT",{get:function(){return a.Color4f(0,0,0,0)}});Object.defineProperty(a,"BLACK",{get:function(){return a.Color4f(0,0,0,1)}});Object.defineProperty(a,"WHITE",{get:function(){return a.Color4f(1,
1,1,1)}});Object.defineProperty(a,"RED",{get:function(){return a.Color4f(1,0,0,1)}});Object.defineProperty(a,"GREEN",{get:function(){return a.Color4f(0,1,0,1)}});Object.defineProperty(a,"BLUE",{get:function(){return a.Color4f(0,0,1,1)}});Object.defineProperty(a,"YELLOW",{get:function(){return a.Color4f(1,1,0,1)}});Object.defineProperty(a,"CYAN",{get:function(){return a.Color4f(0,1,1,1)}});Object.defineProperty(a,"MAGENTA",{get:function(){return a.Color4f(1,0,1,1)}});a.getColorComponents=function(g){return[Math.floor(255*
g[0]),Math.floor(255*g[1]),Math.floor(255*g[2]),g[3]]};a.parseColorString=function(g,d){g=g.toLowerCase();if(g.startsWith("#")){d=255;switch(g.length){case 9:d=parseInt(g.slice(7,9),16);case 7:var h=parseInt(g.slice(1,3),16);var m=parseInt(g.slice(3,5),16);var t=parseInt(g.slice(5,7),16);break;case 5:d=17*parseInt(g.slice(4,5),16);case 4:h=17*parseInt(g.slice(1,2),16),m=17*parseInt(g.slice(2,3),16),t=17*parseInt(g.slice(3,4),16)}return a.Color(h,m,t,d/255)}return g.startsWith("rgba")?(g=g.slice(5,
-1),g=g.split(","),a.Color(+g[0],+g[1],+g[2],e(g[3]))):g.startsWith("rgb")?(g=g.slice(4,-1),g=g.split(","),a.Color(+g[0],+g[1],+g[2],e(g[3]))):g.startsWith("gray(")||g.startsWith("hsl")||!d||(g=d[g],void 0===g)?a.BLACK:g};a.multiplyByAlpha=function(g,d){g=g.slice();g[3]=Math.max(0,Math.min(g[3]*d,1));return g};a.Malloc=function(g,d){var h=a._malloc(d*g.BYTES_PER_ELEMENT);return{_ck:!0,length:d,byteOffset:h,ke:null,subarray:function(m,t){m=this.toTypedArray().subarray(m,t);m._ck=!0;return m},toTypedArray:function(){if(this.ke&&
this.ke.length)return this.ke;this.ke=new g(a.HEAPU8.buffer,h,d);this.ke._ck=!0;return this.ke}}};a.Free=function(g){a._free(g.byteOffset);g.byteOffset=K;g.toTypedArray=null;g.ke=null};var P=K,ba,ma=K,Y,ia=K,Ea,fa,W=K,Ub,Ba=K,Vb,vb=K,Wb,wb=K,$a,Na=K,Xb,ub=K,Yb,Zb=K,Wc=Float32Array.of(0,0,1),K=0;a.onRuntimeInitialized=function(){function g(d,h,m,t,u,x,C){x||(x=4*t.width,t.colorType===a.ColorType.RGBA_F16?x*=2:t.colorType===a.ColorType.RGBA_F32&&(x*=4));var G=x*t.height;var F=u?u.byteOffset:a._malloc(G);
if(C?!d._readPixels(t,F,x,h,m,C):!d._readPixels(t,F,x,h,m))return u||a._free(F),null;if(u)return u.toTypedArray();switch(t.colorType){case a.ColorType.RGBA_8888:case a.ColorType.RGBA_F16:d=(new Uint8Array(a.HEAPU8.buffer,F,G)).slice();break;case a.ColorType.RGBA_F32:d=(new Float32Array(a.HEAPU8.buffer,F,G)).slice();break;default:return null}a._free(F);return d}Ea=a.Malloc(Float32Array,4);ia=Ea.byteOffset;Y=a.Malloc(Float32Array,16);ma=Y.byteOffset;ba=a.Malloc(Float32Array,9);P=ba.byteOffset;Xb=a.Malloc(Float32Array,
12);ub=Xb.byteOffset;Yb=a.Malloc(Float32Array,12);Zb=Yb.byteOffset;fa=a.Malloc(Float32Array,4);W=fa.byteOffset;Ub=a.Malloc(Float32Array,4);Ba=Ub.byteOffset;Vb=a.Malloc(Float32Array,3);vb=Vb.byteOffset;Wb=a.Malloc(Float32Array,3);wb=Wb.byteOffset;$a=a.Malloc(Int32Array,4);Na=$a.byteOffset;a.ColorSpace.SRGB=a.ColorSpace._MakeSRGB();a.ColorSpace.DISPLAY_P3=a.ColorSpace._MakeDisplayP3();a.ColorSpace.ADOBE_RGB=a.ColorSpace._MakeAdobeRGB();a.GlyphRunFlags={IsWhiteSpace:a._GlyphRunFlags_isWhiteSpace};a.Path.MakeFromCmds=
function(d){var h=n(d,"HEAPF32"),m=a.Path._MakeFromCmds(h,d.length);k(h,d);return m};a.Path.MakeFromVerbsPointsWeights=function(d,h,m){var t=n(d,"HEAPU8"),u=n(h,"HEAPF32"),x=n(m,"HEAPF32"),C=a.Path._MakeFromVerbsPointsWeights(t,d.length,u,h.length,x,m&&m.length||0);k(t,d);k(u,h);k(x,m);return C};a.Path.prototype.addArc=function(d,h,m){d=I(d);this._addArc(d,h,m);return this};a.Path.prototype.addCircle=function(d,h,m,t){this._addCircle(d,h,m,!!t);return this};a.Path.prototype.addOval=function(d,h,m){void 0===
m&&(m=1);d=I(d);this._addOval(d,!!h,m);return this};a.Path.prototype.addPath=function(){var d=Array.prototype.slice.call(arguments),h=d[0],m=!1;"boolean"===typeof d[d.length-1]&&(m=d.pop());if(1===d.length)this._addPath(h,1,0,0,0,1,0,0,0,1,m);else if(2===d.length)d=d[1],this._addPath(h,d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1,m);else if(7===d.length||10===d.length)this._addPath(h,d[1],d[2],d[3],d[4],d[5],d[6],d[7]||0,d[8]||0,d[9]||1,m);else return null;return this};a.Path.prototype.addPoly=
function(d,h){var m=n(d,"HEAPF32");this._addPoly(m,d.length/2,h);k(m,d);return this};a.Path.prototype.addRect=function(d,h){d=I(d);this._addRect(d,!!h);return this};a.Path.prototype.addRRect=function(d,h){d=Q(d);this._addRRect(d,!!h);return this};a.Path.prototype.addVerbsPointsWeights=function(d,h,m){var t=n(d,"HEAPU8"),u=n(h,"HEAPF32"),x=n(m,"HEAPF32");this._addVerbsPointsWeights(t,d.length,u,h.length,x,m&&m.length||0);k(t,d);k(u,h);k(x,m)};a.Path.prototype.arc=function(d,h,m,t,u,x){d=a.LTRBRect(d-
m,h-m,d+m,h+m);u=(u-t)/Math.PI*180-360*!!x;x=new a.Path;x.addArc(d,t/Math.PI*180,u);this.addPath(x,!0);x.delete();return this};a.Path.prototype.arcToOval=function(d,h,m,t){d=I(d);this._arcToOval(d,h,m,t);return this};a.Path.prototype.arcToRotated=function(d,h,m,t,u,x,C){this._arcToRotated(d,h,m,!!t,!!u,x,C);return this};a.Path.prototype.arcToTangent=function(d,h,m,t,u){this._arcToTangent(d,h,m,t,u);return this};a.Path.prototype.close=function(){this._close();return this};a.Path.prototype.conicTo=
function(d,h,m,t,u){this._conicTo(d,h,m,t,u);return this};a.Path.prototype.computeTightBounds=function(d){this._computeTightBounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.Path.prototype.cubicTo=function(d,h,m,t,u,x){this._cubicTo(d,h,m,t,u,x);return this};a.Path.prototype.dash=function(d,h,m){return this._dash(d,h,m)?this:null};a.Path.prototype.getBounds=function(d){this._getBounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.Path.prototype.lineTo=function(d,
h){this._lineTo(d,h);return this};a.Path.prototype.moveTo=function(d,h){this._moveTo(d,h);return this};a.Path.prototype.offset=function(d,h){this._transform(1,0,d,0,1,h,0,0,1);return this};a.Path.prototype.quadTo=function(d,h,m,t){this._quadTo(d,h,m,t);return this};a.Path.prototype.rArcTo=function(d,h,m,t,u,x,C){this._rArcTo(d,h,m,t,u,x,C);return this};a.Path.prototype.rConicTo=function(d,h,m,t,u){this._rConicTo(d,h,m,t,u);return this};a.Path.prototype.rCubicTo=function(d,h,m,t,u,x){this._rCubicTo(d,
h,m,t,u,x);return this};a.Path.prototype.rLineTo=function(d,h){this._rLineTo(d,h);return this};a.Path.prototype.rMoveTo=function(d,h){this._rMoveTo(d,h);return this};a.Path.prototype.rQuadTo=function(d,h,m,t){this._rQuadTo(d,h,m,t);return this};a.Path.prototype.stroke=function(d){d=d||{};d.width=d.width||1;d.miter_limit=d.miter_limit||4;d.cap=d.cap||a.StrokeCap.Butt;d.join=d.join||a.StrokeJoin.Miter;d.precision=d.precision||1;return this._stroke(d)?this:null};a.Path.prototype.transform=function(){if(1===
arguments.length){var d=arguments[0];this._transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1)}else if(6===arguments.length||9===arguments.length)d=arguments,this._transform(d[0],d[1],d[2],d[3],d[4],d[5],d[6]||0,d[7]||0,d[8]||1);else throw"transform expected to take 1 or 9 arguments. Got "+arguments.length;return this};a.Path.prototype.trim=function(d,h,m){return this._trim(d,h,!!m)?this:null};a.Image.prototype.encodeToBytes=function(d,h){var m=a.ve();d=d||a.ImageFormat.PNG;h=h||100;
return m?this._encodeToBytes(d,h,m):this._encodeToBytes(d,h)};a.Image.prototype.makeShaderCubic=function(d,h,m,t,u){u=q(u);return this._makeShaderCubic(d,h,m,t,u)};a.Image.prototype.makeShaderOptions=function(d,h,m,t,u){u=q(u);return this._makeShaderOptions(d,h,m,t,u)};a.Image.prototype.readPixels=function(d,h,m,t,u){var x=a.ve();return g(this,d,h,m,t,u,x)};a.Canvas.prototype.clear=function(d){a.Ud(this.Td);d=w(d);this._clear(d)};a.Canvas.prototype.clipRRect=function(d,h,m){a.Ud(this.Td);d=Q(d);this._clipRRect(d,
h,m)};a.Canvas.prototype.clipRect=function(d,h,m){a.Ud(this.Td);d=I(d);this._clipRect(d,h,m)};a.Canvas.prototype.concat=function(d){a.Ud(this.Td);d=v(d);this._concat(d)};a.Canvas.prototype.drawArc=function(d,h,m,t,u){a.Ud(this.Td);d=I(d);this._drawArc(d,h,m,t,u)};a.Canvas.prototype.drawAtlas=function(d,h,m,t,u,x,C){if(d&&t&&h&&m&&h.length===m.length){a.Ud(this.Td);u||(u=a.BlendMode.SrcOver);var G=n(h,"HEAPF32"),F=n(m,"HEAPF32"),T=m.length/4,U=n(c(x),"HEAPU32");if(C&&"B"in C&&"C"in C)this._drawAtlasCubic(d,
F,G,U,T,u,C.B,C.C,t);else{let p=a.FilterMode.Linear,y=a.MipmapMode.None;C&&(p=C.filter,"mipmap"in C&&(y=C.mipmap));this._drawAtlasOptions(d,F,G,U,T,u,p,y,t)}k(G,h);k(F,m);k(U,x)}};a.Canvas.prototype.drawCircle=function(d,h,m,t){a.Ud(this.Td);this._drawCircle(d,h,m,t)};a.Canvas.prototype.drawColor=function(d,h){a.Ud(this.Td);d=w(d);void 0!==h?this._drawColor(d,h):this._drawColor(d)};a.Canvas.prototype.drawColorInt=function(d,h){a.Ud(this.Td);this._drawColorInt(d,h||a.BlendMode.SrcOver)};a.Canvas.prototype.drawColorComponents=
function(d,h,m,t,u){a.Ud(this.Td);d=z(d,h,m,t);void 0!==u?this._drawColor(d,u):this._drawColor(d)};a.Canvas.prototype.drawDRRect=function(d,h,m){a.Ud(this.Td);d=Q(d,ub);h=Q(h,Zb);this._drawDRRect(d,h,m)};a.Canvas.prototype.drawImage=function(d,h,m,t){a.Ud(this.Td);this._drawImage(d,h,m,t||null)};a.Canvas.prototype.drawImageCubic=function(d,h,m,t,u,x){a.Ud(this.Td);this._drawImageCubic(d,h,m,t,u,x||null)};a.Canvas.prototype.drawImageOptions=function(d,h,m,t,u,x){a.Ud(this.Td);this._drawImageOptions(d,
h,m,t,u,x||null)};a.Canvas.prototype.drawImageNine=function(d,h,m,t,u){a.Ud(this.Td);h=n(h,"HEAP32",Na);m=I(m);this._drawImageNine(d,h,m,t,u||null)};a.Canvas.prototype.drawImageRect=function(d,h,m,t,u){a.Ud(this.Td);I(h,W);I(m,Ba);this._drawImageRect(d,W,Ba,t,!!u)};a.Canvas.prototype.drawImageRectCubic=function(d,h,m,t,u,x){a.Ud(this.Td);I(h,W);I(m,Ba);this._drawImageRectCubic(d,W,Ba,t,u,x||null)};a.Canvas.prototype.drawImageRectOptions=function(d,h,m,t,u,x){a.Ud(this.Td);I(h,W);I(m,Ba);this._drawImageRectOptions(d,
W,Ba,t,u,x||null)};a.Canvas.prototype.drawLine=function(d,h,m,t,u){a.Ud(this.Td);this._drawLine(d,h,m,t,u)};a.Canvas.prototype.drawOval=function(d,h){a.Ud(this.Td);d=I(d);this._drawOval(d,h)};a.Canvas.prototype.drawPaint=function(d){a.Ud(this.Td);this._drawPaint(d)};a.Canvas.prototype.drawParagraph=function(d,h,m){a.Ud(this.Td);this._drawParagraph(d,h,m)};a.Canvas.prototype.drawPatch=function(d,h,m,t,u){if(24>d.length)throw"Need 12 cubic points";if(h&&4>h.length)throw"Need 4 colors";if(m&&8>m.length)throw"Need 4 shader coordinates";
a.Ud(this.Td);const x=n(d,"HEAPF32"),C=h?n(c(h),"HEAPU32"):K,G=m?n(m,"HEAPF32"):K;t||(t=a.BlendMode.Modulate);this._drawPatch(x,C,G,t,u);k(G,m);k(C,h);k(x,d)};a.Canvas.prototype.drawPath=function(d,h){a.Ud(this.Td);this._drawPath(d,h)};a.Canvas.prototype.drawPicture=function(d){a.Ud(this.Td);this._drawPicture(d)};a.Canvas.prototype.drawPoints=function(d,h,m){a.Ud(this.Td);var t=n(h,"HEAPF32");this._drawPoints(d,t,h.length/2,m);k(t,h)};a.Canvas.prototype.drawRRect=function(d,h){a.Ud(this.Td);d=Q(d);
this._drawRRect(d,h)};a.Canvas.prototype.drawRect=function(d,h){a.Ud(this.Td);d=I(d);this._drawRect(d,h)};a.Canvas.prototype.drawRect4f=function(d,h,m,t,u){a.Ud(this.Td);this._drawRect4f(d,h,m,t,u)};a.Canvas.prototype.drawShadow=function(d,h,m,t,u,x,C){a.Ud(this.Td);var G=n(u,"HEAPF32"),F=n(x,"HEAPF32");h=n(h,"HEAPF32",vb);m=n(m,"HEAPF32",wb);this._drawShadow(d,h,m,t,G,F,C);k(G,u);k(F,x)};a.getShadowLocalBounds=function(d,h,m,t,u,x,C){d=q(d);m=n(m,"HEAPF32",vb);t=n(t,"HEAPF32",wb);if(!this._getShadowLocalBounds(d,
h,m,t,u,x,W))return null;h=fa.toTypedArray();return C?(C.set(h),C):h.slice()};a.Canvas.prototype.drawTextBlob=function(d,h,m,t){a.Ud(this.Td);this._drawTextBlob(d,h,m,t)};a.Canvas.prototype.drawVertices=function(d,h,m){a.Ud(this.Td);this._drawVertices(d,h,m)};a.Canvas.prototype.getDeviceClipBounds=function(d){this._getDeviceClipBounds(Na);var h=$a.toTypedArray();d?d.set(h):d=h.slice();return d};a.Canvas.prototype.quickReject=function(d){d=I(d);return this._quickReject(d)};a.Canvas.prototype.getLocalToDevice=
function(){this._getLocalToDevice(ma);for(var d=ma,h=Array(16),m=0;16>m;m++)h[m]=a.HEAPF32[d/4+m];return h};a.Canvas.prototype.getTotalMatrix=function(){this._getTotalMatrix(P);for(var d=Array(9),h=0;9>h;h++)d[h]=a.HEAPF32[P/4+h];return d};a.Canvas.prototype.makeSurface=function(d){d=this._makeSurface(d);d.Td=this.Td;return d};a.Canvas.prototype.readPixels=function(d,h,m,t,u){a.Ud(this.Td);return g(this,d,h,m,t,u)};a.Canvas.prototype.saveLayer=function(d,h,m,t,u){h=I(h);return this._saveLayer(d||
null,h,m||null,t||0,u||a.TileMode.Clamp)};a.Canvas.prototype.writePixels=function(d,h,m,t,u,x,C,G){if(d.byteLength%(h*m))throw"pixels length must be a multiple of the srcWidth * srcHeight";a.Ud(this.Td);var F=d.byteLength/(h*m);x=x||a.AlphaType.Unpremul;C=C||a.ColorType.RGBA_8888;G=G||a.ColorSpace.SRGB;var T=F*h;F=n(d,"HEAPU8");h=this._writePixels({width:h,height:m,colorType:C,alphaType:x,colorSpace:G},F,T,t,u);k(F,d);return h};a.ColorFilter.MakeBlend=function(d,h,m){d=w(d);m=m||a.ColorSpace.SRGB;
return a.ColorFilter._MakeBlend(d,h,m)};a.ColorFilter.MakeMatrix=function(d){if(!d||20!==d.length)throw"invalid color matrix";var h=n(d,"HEAPF32"),m=a.ColorFilter._makeMatrix(h);k(h,d);return m};a.ContourMeasure.prototype.getPosTan=function(d,h){this._getPosTan(d,W);d=fa.toTypedArray();return h?(h.set(d),h):d.slice()};a.ImageFilter.prototype.getOutputBounds=function(d,h,m){d=I(d,W);h=q(h);this._getOutputBounds(d,h,Na);h=$a.toTypedArray();return m?(m.set(h),m):h.slice()};a.ImageFilter.MakeDropShadow=
function(d,h,m,t,u,x){u=w(u,ia);return a.ImageFilter._MakeDropShadow(d,h,m,t,u,x)};a.ImageFilter.MakeDropShadowOnly=function(d,h,m,t,u,x){u=w(u,ia);return a.ImageFilter._MakeDropShadowOnly(d,h,m,t,u,x)};a.ImageFilter.MakeImage=function(d,h,m,t){m=I(m,W);t=I(t,Ba);if("B"in h&&"C"in h)return a.ImageFilter._MakeImageCubic(d,h.B,h.C,m,t);const u=h.filter;let x=a.MipmapMode.None;"mipmap"in h&&(x=h.mipmap);return a.ImageFilter._MakeImageOptions(d,u,x,m,t)};a.ImageFilter.MakeMatrixTransform=function(d,h,
m){d=q(d);if("B"in h&&"C"in h)return a.ImageFilter._MakeMatrixTransformCubic(d,h.B,h.C,m);const t=h.filter;let u=a.MipmapMode.None;"mipmap"in h&&(u=h.mipmap);return a.ImageFilter._MakeMatrixTransformOptions(d,t,u,m)};a.Paint.prototype.getColor=function(){this._getColor(ia);return D(ia)};a.Paint.prototype.setColor=function(d,h){h=h||null;d=w(d);this._setColor(d,h)};a.Paint.prototype.setColorComponents=function(d,h,m,t,u){u=u||null;d=z(d,h,m,t);this._setColor(d,u)};a.Path.prototype.getPoint=function(d,
h){this._getPoint(d,W);d=fa.toTypedArray();return h?(h[0]=d[0],h[1]=d[1],h):d.slice(0,2)};a.Picture.prototype.makeShader=function(d,h,m,t,u){t=q(t);u=I(u);return this._makeShader(d,h,m,t,u)};a.Picture.prototype.cullRect=function(d){this._cullRect(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.PictureRecorder.prototype.beginRecording=function(d,h){d=I(d);return this._beginRecording(d,!!h)};a.Surface.prototype.getCanvas=function(){var d=this._getCanvas();d.Td=this.Td;return d};a.Surface.prototype.makeImageSnapshot=
function(d){a.Ud(this.Td);d=n(d,"HEAP32",Na);return this._makeImageSnapshot(d)};a.Surface.prototype.makeSurface=function(d){a.Ud(this.Td);d=this._makeSurface(d);d.Td=this.Td;return d};a.Surface.prototype.Te=function(d,h){this.ne||(this.ne=this.getCanvas());return requestAnimationFrame(function(){a.Ud(this.Td);d(this.ne);this.flush(h)}.bind(this))};a.Surface.prototype.requestAnimationFrame||(a.Surface.prototype.requestAnimationFrame=a.Surface.prototype.Te);a.Surface.prototype.Qe=function(d,h){this.ne||
(this.ne=this.getCanvas());requestAnimationFrame(function(){a.Ud(this.Td);d(this.ne);this.flush(h);this.dispose()}.bind(this))};a.Surface.prototype.drawOnce||(a.Surface.prototype.drawOnce=a.Surface.prototype.Qe);a.PathEffect.MakeDash=function(d,h){h||=0;if(!d.length||1===d.length%2)throw"Intervals array must have even length";var m=n(d,"HEAPF32");h=a.PathEffect._MakeDash(m,d.length,h);k(m,d);return h};a.PathEffect.MakeLine2D=function(d,h){h=q(h);return a.PathEffect._MakeLine2D(d,h)};a.PathEffect.MakePath2D=
function(d,h){d=q(d);return a.PathEffect._MakePath2D(d,h)};a.Shader.MakeColor=function(d,h){h=h||null;d=w(d);return a.Shader._MakeColor(d,h)};a.Shader.Blend=a.Shader.MakeBlend;a.Shader.Color=a.Shader.MakeColor;a.Shader.MakeLinearGradient=function(d,h,m,t,u,x,C,G){G=G||null;var F=l(m),T=n(t,"HEAPF32");C=C||0;x=q(x);var U=fa.toTypedArray();U.set(d);U.set(h,2);d=a.Shader._MakeLinearGradient(W,F.be,F.colorType,T,F.count,u,C,x,G);k(F.be,m);t&&k(T,t);return d};a.Shader.MakeRadialGradient=function(d,h,m,
t,u,x,C,G){G=G||null;var F=l(m),T=n(t,"HEAPF32");C=C||0;x=q(x);d=a.Shader._MakeRadialGradient(d[0],d[1],h,F.be,F.colorType,T,F.count,u,C,x,G);k(F.be,m);t&&k(T,t);return d};a.Shader.MakeSweepGradient=function(d,h,m,t,u,x,C,G,F,T){T=T||null;var U=l(m),p=n(t,"HEAPF32");C=C||0;G=G||0;F=F||360;x=q(x);d=a.Shader._MakeSweepGradient(d,h,U.be,U.colorType,p,U.count,u,G,F,C,x,T);k(U.be,m);t&&k(p,t);return d};a.Shader.MakeTwoPointConicalGradient=function(d,h,m,t,u,x,C,G,F,T){T=T||null;var U=l(u),p=n(x,"HEAPF32");
F=F||0;G=q(G);var y=fa.toTypedArray();y.set(d);y.set(m,2);d=a.Shader._MakeTwoPointConicalGradient(W,h,t,U.be,U.colorType,p,U.count,C,F,G,T);k(U.be,u);x&&k(p,x);return d};a.Vertices.prototype.bounds=function(d){this._bounds(W);var h=fa.toTypedArray();return d?(d.set(h),d):h.slice()};a.Xd&&a.Xd.forEach(function(d){d()})};a.computeTonalColors=function(g){var d=n(g.ambient,"HEAPF32"),h=n(g.spot,"HEAPF32");this._computeTonalColors(d,h);var m={ambient:D(d),spot:D(h)};k(d,g.ambient);k(h,g.spot);return m};
a.LTRBRect=function(g,d,h,m){return Float32Array.of(g,d,h,m)};a.XYWHRect=function(g,d,h,m){return Float32Array.of(g,d,g+h,d+m)};a.LTRBiRect=function(g,d,h,m){return Int32Array.of(g,d,h,m)};a.XYWHiRect=function(g,d,h,m){return Int32Array.of(g,d,g+h,d+m)};a.RRectXY=function(g,d,h){return Float32Array.of(g[0],g[1],g[2],g[3],d,h,d,h,d,h,d,h)};a.MakeAnimatedImageFromEncoded=function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._decodeAnimatedImage(d,g.byteLength))?
g:null};a.MakeImageFromEncoded=function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._decodeImage(d,g.byteLength))?g:null};var ab=null;a.MakeImageFromCanvasImageSource=function(g){var d=g.width,h=g.height;ab||=document.createElement("canvas");ab.width=d;ab.height=h;var m=ab.getContext("2d",{willReadFrequently:!0});m.drawImage(g,0,0);g=m.getImageData(0,0,d,h);return a.MakeImage({width:d,height:h,alphaType:a.AlphaType.Unpremul,colorType:a.ColorType.RGBA_8888,colorSpace:a.ColorSpace.SRGB},
g.data,4*d)};a.MakeImage=function(g,d,h){var m=a._malloc(d.length);a.HEAPU8.set(d,m);return a._MakeImage(g,m,d.length,h)};a.MakeVertices=function(g,d,h,m,t,u){var x=t&&t.length||0,C=0;h&&h.length&&(C|=1);m&&m.length&&(C|=2);void 0===u||u||(C|=4);g=new a._VerticesBuilder(g,d.length/2,x,C);n(d,"HEAPF32",g.positions());g.texCoords()&&n(h,"HEAPF32",g.texCoords());g.colors()&&n(c(m),"HEAPU32",g.colors());g.indices()&&n(t,"HEAPU16",g.indices());return g.detach()};(function(g){g.Xd=g.Xd||[];g.Xd.push(function(){function d(p){p&&
(p.dir=0===p.dir?g.TextDirection.RTL:g.TextDirection.LTR);return p}function h(p){if(!p||!p.length)return[];for(var y=[],N=0;N<p.length;N+=5){var X=g.LTRBRect(p[N],p[N+1],p[N+2],p[N+3]),xa=g.TextDirection.LTR;0===p[N+4]&&(xa=g.TextDirection.RTL);y.push({rect:X,dir:xa})}g._free(p.byteOffset);return y}function m(p){p=p||{};void 0===p.weight&&(p.weight=g.FontWeight.Normal);p.width=p.width||g.FontWidth.Normal;p.slant=p.slant||g.FontSlant.Upright;return p}function t(p){if(!p||!p.length)return K;for(var y=
[],N=0;N<p.length;N++){var X=u(p[N]);y.push(X)}return n(y,"HEAPU32")}function u(p){if(G[p])return G[p];var y=qa(p)+1,N=g._malloc(y);ra(p,N,y);return G[p]=N}function x(p){p._colorPtr=w(p.color);p._foregroundColorPtr=K;p._backgroundColorPtr=K;p._decorationColorPtr=K;p.foregroundColor&&(p._foregroundColorPtr=w(p.foregroundColor,F));p.backgroundColor&&(p._backgroundColorPtr=w(p.backgroundColor,T));p.decorationColor&&(p._decorationColorPtr=w(p.decorationColor,U));Array.isArray(p.fontFamilies)&&p.fontFamilies.length?
(p._fontFamiliesPtr=t(p.fontFamilies),p._fontFamiliesLen=p.fontFamilies.length):(p._fontFamiliesPtr=K,p._fontFamiliesLen=0);if(p.locale){var y=p.locale;p._localePtr=u(y);p._localeLen=qa(y)}else p._localePtr=K,p._localeLen=0;if(Array.isArray(p.shadows)&&p.shadows.length){y=p.shadows;var N=y.map(function(na){return na.color||g.BLACK}),X=y.map(function(na){return na.blurRadius||0});p._shadowLen=y.length;for(var xa=g._malloc(8*y.length),xb=xa/4,yb=0;yb<y.length;yb++){var $b=y[yb].offset||[0,0];g.HEAPF32[xb]=
$b[0];g.HEAPF32[xb+1]=$b[1];xb+=2}p._shadowColorsPtr=l(N).be;p._shadowOffsetsPtr=xa;p._shadowBlurRadiiPtr=n(X,"HEAPF32")}else p._shadowLen=0,p._shadowColorsPtr=K,p._shadowOffsetsPtr=K,p._shadowBlurRadiiPtr=K;Array.isArray(p.fontFeatures)&&p.fontFeatures.length?(y=p.fontFeatures,N=y.map(function(na){return na.name}),X=y.map(function(na){return na.value}),p._fontFeatureLen=y.length,p._fontFeatureNamesPtr=t(N),p._fontFeatureValuesPtr=n(X,"HEAPU32")):(p._fontFeatureLen=0,p._fontFeatureNamesPtr=K,p._fontFeatureValuesPtr=
K);Array.isArray(p.fontVariations)&&p.fontVariations.length?(y=p.fontVariations,N=y.map(function(na){return na.axis}),X=y.map(function(na){return na.value}),p._fontVariationLen=y.length,p._fontVariationAxesPtr=t(N),p._fontVariationValuesPtr=n(X,"HEAPF32")):(p._fontVariationLen=0,p._fontVariationAxesPtr=K,p._fontVariationValuesPtr=K)}function C(p){g._free(p._fontFamiliesPtr);g._free(p._shadowColorsPtr);g._free(p._shadowOffsetsPtr);g._free(p._shadowBlurRadiiPtr);g._free(p._fontFeatureNamesPtr);g._free(p._fontFeatureValuesPtr);
g._free(p._fontVariationAxesPtr);g._free(p._fontVariationValuesPtr)}g.Paragraph.prototype.getRectsForRange=function(p,y,N,X){p=this._getRectsForRange(p,y,N,X);return h(p)};g.Paragraph.prototype.getRectsForPlaceholders=function(){var p=this._getRectsForPlaceholders();return h(p)};g.Paragraph.prototype.getGlyphInfoAt=function(p){return d(this._getGlyphInfoAt(p))};g.Paragraph.prototype.getClosestGlyphInfoAtCoordinate=function(p,y){return d(this._getClosestGlyphInfoAtCoordinate(p,y))};g.TypefaceFontProvider.prototype.registerFont=
function(p,y){p=g.Typeface.MakeTypefaceFromData(p);if(!p)return null;y=u(y);this._registerFont(p,y)};g.ParagraphStyle=function(p){p.disableHinting=p.disableHinting||!1;if(p.ellipsis){var y=p.ellipsis;p._ellipsisPtr=u(y);p._ellipsisLen=qa(y)}else p._ellipsisPtr=K,p._ellipsisLen=0;null==p.heightMultiplier&&(p.heightMultiplier=-1);p.maxLines=p.maxLines||0;p.replaceTabCharacters=p.replaceTabCharacters||!1;y=(y=p.strutStyle)||{};y.strutEnabled=y.strutEnabled||!1;y.strutEnabled&&Array.isArray(y.fontFamilies)&&
y.fontFamilies.length?(y._fontFamiliesPtr=t(y.fontFamilies),y._fontFamiliesLen=y.fontFamilies.length):(y._fontFamiliesPtr=K,y._fontFamiliesLen=0);y.fontStyle=m(y.fontStyle);null==y.fontSize&&(y.fontSize=-1);null==y.heightMultiplier&&(y.heightMultiplier=-1);y.halfLeading=y.halfLeading||!1;y.leading=y.leading||0;y.forceStrutHeight=y.forceStrutHeight||!1;p.strutStyle=y;p.textAlign=p.textAlign||g.TextAlign.Start;p.textDirection=p.textDirection||g.TextDirection.LTR;p.textHeightBehavior=p.textHeightBehavior||
g.TextHeightBehavior.All;p.textStyle=g.TextStyle(p.textStyle);p.applyRoundingHack=!1!==p.applyRoundingHack;return p};g.TextStyle=function(p){p.color||(p.color=g.BLACK);p.decoration=p.decoration||0;p.decorationThickness=p.decorationThickness||0;p.decorationStyle=p.decorationStyle||g.DecorationStyle.Solid;p.textBaseline=p.textBaseline||g.TextBaseline.Alphabetic;null==p.fontSize&&(p.fontSize=-1);p.letterSpacing=p.letterSpacing||0;p.wordSpacing=p.wordSpacing||0;null==p.heightMultiplier&&(p.heightMultiplier=
-1);p.halfLeading=p.halfLeading||!1;p.fontStyle=m(p.fontStyle);return p};var G={},F=g._malloc(16),T=g._malloc(16),U=g._malloc(16);g.ParagraphBuilder.Make=function(p,y){x(p.textStyle);y=g.ParagraphBuilder._Make(p,y);C(p.textStyle);return y};g.ParagraphBuilder.MakeFromFontProvider=function(p,y){x(p.textStyle);y=g.ParagraphBuilder._MakeFromFontProvider(p,y);C(p.textStyle);return y};g.ParagraphBuilder.MakeFromFontCollection=function(p,y){x(p.textStyle);y=g.ParagraphBuilder._MakeFromFontCollection(p,y);
C(p.textStyle);return y};g.ParagraphBuilder.ShapeText=function(p,y,N){let X=0;for(const xa of y)X+=xa.length;if(X!==p.length)throw"Accumulated block lengths must equal text.length";return g.ParagraphBuilder._ShapeText(p,y,N)};g.ParagraphBuilder.prototype.pushStyle=function(p){x(p);this._pushStyle(p);C(p)};g.ParagraphBuilder.prototype.pushPaintStyle=function(p,y,N){x(p);this._pushPaintStyle(p,y,N);C(p)};g.ParagraphBuilder.prototype.addPlaceholder=function(p,y,N,X,xa){N=N||g.PlaceholderAlignment.Baseline;
X=X||g.TextBaseline.Alphabetic;this._addPlaceholder(p||0,y||0,N,X,xa||0)};g.ParagraphBuilder.prototype.setWordsUtf8=function(p){var y=n(p,"HEAPU32");this._setWordsUtf8(y,p&&p.length||0);k(y,p)};g.ParagraphBuilder.prototype.setWordsUtf16=function(p){var y=n(p,"HEAPU32");this._setWordsUtf16(y,p&&p.length||0);k(y,p)};g.ParagraphBuilder.prototype.setGraphemeBreaksUtf8=function(p){var y=n(p,"HEAPU32");this._setGraphemeBreaksUtf8(y,p&&p.length||0);k(y,p)};g.ParagraphBuilder.prototype.setGraphemeBreaksUtf16=
function(p){var y=n(p,"HEAPU32");this._setGraphemeBreaksUtf16(y,p&&p.length||0);k(y,p)};g.ParagraphBuilder.prototype.setLineBreaksUtf8=function(p){var y=n(p,"HEAPU32");this._setLineBreaksUtf8(y,p&&p.length||0);k(y,p)};g.ParagraphBuilder.prototype.setLineBreaksUtf16=function(p){var y=n(p,"HEAPU32");this._setLineBreaksUtf16(y,p&&p.length||0);k(y,p)}})})(r);a.Xd=a.Xd||[];a.Xd.push(function(){a.Path.prototype.op=function(g,d){return this._op(g,d)?this:null};a.Path.prototype.simplify=function(){return this._simplify()?
this:null}});a.Xd=a.Xd||[];a.Xd.push(function(){a.Canvas.prototype.drawText=function(g,d,h,m,t){var u=qa(g),x=a._malloc(u+1);ra(g,x,u+1);this._drawSimpleText(x,u,d,h,t,m);a._free(x)};a.Canvas.prototype.drawGlyphs=function(g,d,h,m,t,u){if(!(2*g.length<=d.length))throw"Not enough positions for the array of gyphs";a.Ud(this.Td);const x=n(g,"HEAPU16"),C=n(d,"HEAPF32");this._drawGlyphs(g.length,x,C,h,m,t,u);k(C,d);k(x,g)};a.Font.prototype.getGlyphBounds=function(g,d,h){var m=n(g,"HEAPU16"),t=a._malloc(16*
g.length);this._getGlyphWidthBounds(m,g.length,K,t,d||null);d=new Float32Array(a.HEAPU8.buffer,t,4*g.length);k(m,g);if(h)return h.set(d),a._free(t),h;g=Float32Array.from(d);a._free(t);return g};a.Font.prototype.getGlyphIDs=function(g,d,h){d||(d=g.length);var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=a._malloc(2*d);d=this._getGlyphIDs(t,m-1,d,g);a._free(t);if(0>d)return a._free(g),null;t=new Uint16Array(a.HEAPU8.buffer,g,d);if(h)return h.set(t),a._free(g),h;h=Uint16Array.from(t);a._free(g);return h};a.Font.prototype.getGlyphIntercepts=
function(g,d,h,m){var t=n(g,"HEAPU16"),u=n(d,"HEAPF32");return this._getGlyphIntercepts(t,g.length,!(g&&g._ck),u,d.length,!(d&&d._ck),h,m)};a.Font.prototype.getGlyphWidths=function(g,d,h){var m=n(g,"HEAPU16"),t=a._malloc(4*g.length);this._getGlyphWidthBounds(m,g.length,t,K,d||null);d=new Float32Array(a.HEAPU8.buffer,t,g.length);k(m,g);if(h)return h.set(d),a._free(t),h;g=Float32Array.from(d);a._free(t);return g};a.FontMgr.FromData=function(){if(!arguments.length)return null;var g=arguments;1===g.length&&
Array.isArray(g[0])&&(g=arguments[0]);if(!g.length)return null;for(var d=[],h=[],m=0;m<g.length;m++){var t=new Uint8Array(g[m]),u=n(t,"HEAPU8");d.push(u);h.push(t.byteLength)}d=n(d,"HEAPU32");h=n(h,"HEAPU32");g=a.FontMgr._fromData(d,h,g.length);a._free(d);a._free(h);return g};a.Typeface.MakeTypefaceFromData=function(g){g=new Uint8Array(g);var d=n(g,"HEAPU8");return(g=a.Typeface._MakeTypefaceFromData(d,g.byteLength))?g:null};a.Typeface.MakeFreeTypeFaceFromData=a.Typeface.MakeTypefaceFromData;a.Typeface.prototype.getGlyphIDs=
function(g,d,h){d||(d=g.length);var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=a._malloc(2*d);d=this._getGlyphIDs(t,m-1,d,g);a._free(t);if(0>d)return a._free(g),null;t=new Uint16Array(a.HEAPU8.buffer,g,d);if(h)return h.set(t),a._free(g),h;h=Uint16Array.from(t);a._free(g);return h};a.TextBlob.MakeOnPath=function(g,d,h,m){if(g&&g.length&&d&&d.countPoints()){if(1===d.countPoints())return this.MakeFromText(g,h);m||=0;var t=h.getGlyphIDs(g);t=h.getGlyphWidths(t);var u=[];d=new a.ContourMeasureIter(d,!1,1);for(var x=
d.next(),C=new Float32Array(4),G=0;G<g.length&&x;G++){var F=t[G];m+=F/2;if(m>x.length()){x.delete();x=d.next();if(!x){g=g.substring(0,G);break}m=F/2}x.getPosTan(m,C);var T=C[2],U=C[3];u.push(T,U,C[0]-F/2*T,C[1]-F/2*U);m+=F/2}g=this.MakeFromRSXform(g,u,h);x&&x.delete();d.delete();return g}};a.TextBlob.MakeFromRSXform=function(g,d,h){var m=qa(g)+1,t=a._malloc(m);ra(g,t,m);g=n(d,"HEAPF32");h=a.TextBlob._MakeFromRSXform(t,m-1,g,h);a._free(t);return h?h:null};a.TextBlob.MakeFromRSXformGlyphs=function(g,
d,h){var m=n(g,"HEAPU16");d=n(d,"HEAPF32");h=a.TextBlob._MakeFromRSXformGlyphs(m,2*g.length,d,h);k(m,g);return h?h:null};a.TextBlob.MakeFromGlyphs=function(g,d){var h=n(g,"HEAPU16");d=a.TextBlob._MakeFromGlyphs(h,2*g.length,d);k(h,g);return d?d:null};a.TextBlob.MakeFromText=function(g,d){var h=qa(g)+1,m=a._malloc(h);ra(g,m,h);g=a.TextBlob._MakeFromText(m,h-1,d);a._free(m);return g?g:null};a.MallocGlyphIDs=function(g){return a.Malloc(Uint16Array,g)}});a.Xd=a.Xd||[];a.Xd.push(function(){a.MakePicture=
function(g){g=new Uint8Array(g);var d=a._malloc(g.byteLength);a.HEAPU8.set(g,d);return(g=a._MakePicture(d,g.byteLength))?g:null}});a.Xd=a.Xd||[];a.Xd.push(function(){a.RuntimeEffect.Make=function(g,d){return a.RuntimeEffect._Make(g,{onError:d||function(h){console.log("RuntimeEffect error",h)}})};a.RuntimeEffect.MakeForBlender=function(g,d){return a.RuntimeEffect._MakeForBlender(g,{onError:d||function(h){console.log("RuntimeEffect error",h)}})};a.RuntimeEffect.prototype.makeShader=function(g,d){var h=
!g._ck,m=n(g,"HEAPF32");d=q(d);return this._makeShader(m,4*g.length,h,d)};a.RuntimeEffect.prototype.makeShaderWithChildren=function(g,d,h){var m=!g._ck,t=n(g,"HEAPF32");h=q(h);for(var u=[],x=0;x<d.length;x++)u.push(d[x].Sd.Vd);d=n(u,"HEAPU32");return this._makeShaderWithChildren(t,4*g.length,m,d,u.length,h)};a.RuntimeEffect.prototype.makeBlender=function(g){var d=!g._ck,h=n(g,"HEAPF32");return this._makeBlender(h,4*g.length,d)}})})(r);var sa=Object.assign({},r),ta="",ua,va;
if(ea||ha)ha?ta=self.location.href:"undefined"!=typeof document&&document.currentScript&&(ta=document.currentScript.src),_scriptName&&(ta=_scriptName),ta.startsWith("blob:")?ta="":ta=ta.substr(0,ta.replace(/[?#].*/,"").lastIndexOf("/")+1),ha&&(va=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),ua=a=>fetch(a,{credentials:"same-origin"}).then(b=>b.ok?b.arrayBuffer():Promise.reject(Error(b.status+" : "+b.url)));
var wa=console.log.bind(console),ya=console.error.bind(console);Object.assign(r,sa);sa=null;var za,Aa=!1,Ca,B,Da,Fa,E,H,J,Ga;function Ha(){var a=za.buffer;r.HEAP8=Ca=new Int8Array(a);r.HEAP16=Da=new Int16Array(a);r.HEAPU8=B=new Uint8Array(a);r.HEAPU16=Fa=new Uint16Array(a);r.HEAP32=E=new Int32Array(a);r.HEAPU32=H=new Uint32Array(a);r.HEAPF32=J=new Float32Array(a);r.HEAPF64=Ga=new Float64Array(a)}var Ia=[],Ja=[],Ka=[],La=0,Ma=null,Oa=null;
function Pa(a){a="Aborted("+a+")";ya(a);Aa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ca(a);throw a;}var Qa=a=>a.startsWith("data:application/octet-stream;base64,"),Ra;function Sa(a){return ua(a).then(b=>new Uint8Array(b),()=>{if(va)var b=va(a);else throw"both async and sync fetching of the wasm failed";return b})}function Ta(a,b,c){return Sa(a).then(e=>WebAssembly.instantiate(e,b)).then(c,e=>{ya(`failed to asynchronously prepare wasm: ${e}`);Pa(e)})}
function Ua(a,b){var c=Ra;return"function"!=typeof WebAssembly.instantiateStreaming||Qa(c)||"function"!=typeof fetch?Ta(c,a,b):fetch(c,{credentials:"same-origin"}).then(e=>WebAssembly.instantiateStreaming(e,a).then(b,function(f){ya(`wasm streaming compile failed: ${f}`);ya("falling back to ArrayBuffer instantiation");return Ta(c,a,b)}))}function Va(a){this.name="ExitStatus";this.message=`Program terminated with exit(${a})`;this.status=a}var Wa=a=>{a.forEach(b=>b(r))};
class Xa{constructor(a){this.Vd=a-24}}
var Ya=0,Za=0,bb="undefined"!=typeof TextDecoder?new TextDecoder:void 0,cb=(a,b=0,c=NaN)=>{var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&bb)return bb.decode(a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var k=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|k);else{var n=a[b++]&63;f=224==(f&240)?(f&15)<<12|k<<6|n:(f&7)<<18|k<<12|n<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e},
db={},eb=a=>{for(;a.length;){var b=a.pop();a.pop()(b)}};function fb(a){return this.fromWireType(H[a>>2])}
var gb={},hb={},ib={},jb,lb=(a,b,c)=>{function e(l){l=c(l);if(l.length!==a.length)throw new jb("Mismatched type converter count");for(var q=0;q<a.length;++q)kb(a[q],l[q])}a.forEach(l=>ib[l]=b);var f=Array(b.length),k=[],n=0;b.forEach((l,q)=>{hb.hasOwnProperty(l)?f[q]=hb[l]:(k.push(l),gb.hasOwnProperty(l)||(gb[l]=[]),gb[l].push(()=>{f[q]=hb[l];++n;n===k.length&&e(f)}))});0===k.length&&e(f)},mb,L=a=>{for(var b="";B[a];)b+=mb[B[a++]];return b},M;
function nb(a,b,c={}){var e=b.name;if(!a)throw new M(`type "${e}" must have a positive integer typeid pointer`);if(hb.hasOwnProperty(a)){if(c.ef)return;throw new M(`Cannot register type '${e}' twice`);}hb[a]=b;delete ib[a];gb.hasOwnProperty(a)&&(b=gb[a],delete gb[a],b.forEach(f=>f()))}function kb(a,b,c={}){return nb(a,b,c)}
var ob=a=>{throw new M(a.Sd.Yd.Wd.name+" instance already deleted");},pb=!1,qb=()=>{},rb=(a,b,c)=>{if(b===c)return a;if(void 0===c.ae)return null;a=rb(a,b,c.ae);return null===a?null:c.Xe(a)},sb={},tb={},zb=(a,b)=>{if(void 0===b)throw new M("ptr should not be undefined");for(;a.ae;)b=a.se(b),a=a.ae;return tb[b]},Bb=(a,b)=>{if(!b.Yd||!b.Vd)throw new jb("makeClassHandle requires ptr and ptrType");if(!!b.ce!==!!b.Zd)throw new jb("Both smartPtrType and smartPtr must be specified");b.count={value:1};return Ab(Object.create(a,
{Sd:{value:b,writable:!0}}))},Ab=a=>{if("undefined"===typeof FinalizationRegistry)return Ab=b=>b,a;pb=new FinalizationRegistry(b=>{b=b.Sd;--b.count.value;0===b.count.value&&(b.Zd?b.ce.he(b.Zd):b.Yd.Wd.he(b.Vd))});Ab=b=>{var c=b.Sd;c.Zd&&pb.register(b,{Sd:c},b);return b};qb=b=>{pb.unregister(b)};return Ab(a)},Cb=[];function Db(){}
var Eb=(a,b)=>Object.defineProperty(b,"name",{value:a}),Fb=(a,b,c)=>{if(void 0===a[b].$d){var e=a[b];a[b]=function(...f){if(!a[b].$d.hasOwnProperty(f.length))throw new M(`Function '${c}' called with an invalid number of arguments (${f.length}) - expects one of (${a[b].$d})!`);return a[b].$d[f.length].apply(this,f)};a[b].$d=[];a[b].$d[e.ie]=e}},Gb=(a,b,c)=>{if(r.hasOwnProperty(a)){if(void 0===c||void 0!==r[a].$d&&void 0!==r[a].$d[c])throw new M(`Cannot register public name '${a}' twice`);Fb(r,a,a);
if(r[a].$d.hasOwnProperty(c))throw new M(`Cannot register multiple overloads of a function with the same number of arguments (${c})!`);r[a].$d[c]=b}else r[a]=b,r[a].ie=c},Hb=a=>{a=a.replace(/[^a-zA-Z0-9_]/g,"$");var b=a.charCodeAt(0);return 48<=b&&57>=b?`_${a}`:a};function Ib(a,b,c,e,f,k,n,l){this.name=a;this.constructor=b;this.me=c;this.he=e;this.ae=f;this.$e=k;this.se=n;this.Xe=l;this.hf=[]}
var Jb=(a,b,c)=>{for(;b!==c;){if(!b.se)throw new M(`Expected null or instance of ${c.name}, got an instance of ${b.name}`);a=b.se(a);b=b.ae}return a};function Kb(a,b){if(null===b){if(this.Ee)throw new M(`null is not a valid ${this.name}`);return 0}if(!b.Sd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Sd.Vd)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);return Jb(b.Sd.Vd,b.Sd.Yd.Wd,this.Wd)}
function Mb(a,b){if(null===b){if(this.Ee)throw new M(`null is not a valid ${this.name}`);if(this.xe){var c=this.Fe();null!==a&&a.push(this.he,c);return c}return 0}if(!b||!b.Sd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Sd.Vd)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);if(!this.we&&b.Sd.Yd.we)throw new M(`Cannot convert argument of type ${b.Sd.ce?b.Sd.ce.name:b.Sd.Yd.name} to parameter type ${this.name}`);c=Jb(b.Sd.Vd,b.Sd.Yd.Wd,this.Wd);if(this.xe){if(void 0===
b.Sd.Zd)throw new M("Passing raw pointer to smart pointer is illegal");switch(this.nf){case 0:if(b.Sd.ce===this)c=b.Sd.Zd;else throw new M(`Cannot convert argument of type ${b.Sd.ce?b.Sd.ce.name:b.Sd.Yd.name} to parameter type ${this.name}`);break;case 1:c=b.Sd.Zd;break;case 2:if(b.Sd.ce===this)c=b.Sd.Zd;else{var e=b.clone();c=this.jf(c,Nb(()=>e["delete"]()));null!==a&&a.push(this.he,c)}break;default:throw new M("Unsupporting sharing policy");}}return c}
function Ob(a,b){if(null===b){if(this.Ee)throw new M(`null is not a valid ${this.name}`);return 0}if(!b.Sd)throw new M(`Cannot pass "${Lb(b)}" as a ${this.name}`);if(!b.Sd.Vd)throw new M(`Cannot pass deleted object as a pointer of type ${this.name}`);if(b.Sd.Yd.we)throw new M(`Cannot convert argument of type ${b.Sd.Yd.name} to parameter type ${this.name}`);return Jb(b.Sd.Vd,b.Sd.Yd.Wd,this.Wd)}
function Pb(a,b,c,e,f,k,n,l,q,v,w){this.name=a;this.Wd=b;this.Ee=c;this.we=e;this.xe=f;this.gf=k;this.nf=n;this.Me=l;this.Fe=q;this.jf=v;this.he=w;f||void 0!==b.ae?this.toWireType=Mb:(this.toWireType=e?Kb:Ob,this.ee=null)}
var Qb=(a,b,c)=>{if(!r.hasOwnProperty(a))throw new jb("Replacing nonexistent public symbol");void 0!==r[a].$d&&void 0!==c?r[a].$d[c]=b:(r[a]=b,r[a].ie=c)},O,Rb=(a,b,c=[])=>{a.includes("j")?(a=a.replace(/p/g,"i"),b=(0,r["dynCall_"+a])(b,...c)):b=O.get(b)(...c);return b},Sb=(a,b)=>(...c)=>Rb(a,b,c),Tb=(a,b)=>{a=L(a);var c=a.includes("j")?Sb(a,b):O.get(b);if("function"!=typeof c)throw new M(`unknown function pointer with signature ${a}: ${b}`);return c},ac,dc=a=>{a=bc(a);var b=L(a);cc(a);return b},ec=
(a,b)=>{function c(k){f[k]||hb[k]||(ib[k]?ib[k].forEach(c):(e.push(k),f[k]=!0))}var e=[],f={};b.forEach(c);throw new ac(`${a}: `+e.map(dc).join([", "]));};function fc(a){for(var b=1;b<a.length;++b)if(null!==a[b]&&void 0===a[b].ee)return!0;return!1}
function gc(a,b,c,e,f){var k=b.length;if(2>k)throw new M("argTypes array size mismatch! Must at least get return value and 'this' types!");var n=null!==b[1]&&null!==c,l=fc(b),q="void"!==b[0].name,v=k-2,w=Array(v),z=[],D=[];return Eb(a,function(...I){D.length=0;z.length=n?2:1;z[0]=f;if(n){var Q=b[1].toWireType(D,this);z[1]=Q}for(var P=0;P<v;++P)w[P]=b[P+2].toWireType(D,I[P]),z.push(w[P]);I=e(...z);if(l)eb(D);else for(P=n?1:2;P<b.length;P++){var ba=1===P?Q:w[P-2];null!==b[P].ee&&b[P].ee(ba)}Q=q?b[0].fromWireType(I):
void 0;return Q})}
var hc=(a,b)=>{for(var c=[],e=0;e<a;e++)c.push(H[b+4*e>>2]);return c},ic=a=>{a=a.trim();const b=a.indexOf("(");return-1!==b?a.substr(0,b):a},jc=[],kc=[],lc=a=>{9<a&&0===--kc[a+1]&&(kc[a]=void 0,jc.push(a))},mc=a=>{if(!a)throw new M("Cannot use deleted val. handle = "+a);return kc[a]},Nb=a=>{switch(a){case void 0:return 2;case null:return 4;case !0:return 6;case !1:return 8;default:const b=jc.pop()||kc.length;kc[b]=a;kc[b+1]=1;return b}},nc={name:"emscripten::val",fromWireType:a=>{var b=mc(a);lc(a);
return b},toWireType:(a,b)=>Nb(b),de:8,readValueFromPointer:fb,ee:null},oc=(a,b,c)=>{switch(b){case 1:return c?function(e){return this.fromWireType(Ca[e])}:function(e){return this.fromWireType(B[e])};case 2:return c?function(e){return this.fromWireType(Da[e>>1])}:function(e){return this.fromWireType(Fa[e>>1])};case 4:return c?function(e){return this.fromWireType(E[e>>2])}:function(e){return this.fromWireType(H[e>>2])};default:throw new TypeError(`invalid integer width (${b}): ${a}`);}},pc=(a,b)=>
{var c=hb[a];if(void 0===c)throw a=`${b} has unknown type ${dc(a)}`,new M(a);return c},Lb=a=>{if(null===a)return"null";var b=typeof a;return"object"===b||"array"===b||"function"===b?a.toString():""+a},qc=(a,b)=>{switch(b){case 4:return function(c){return this.fromWireType(J[c>>2])};case 8:return function(c){return this.fromWireType(Ga[c>>3])};default:throw new TypeError(`invalid float width (${b}): ${a}`);}},rc=(a,b,c)=>{switch(b){case 1:return c?e=>Ca[e]:e=>B[e];case 2:return c?e=>Da[e>>1]:e=>Fa[e>>
1];case 4:return c?e=>E[e>>2]:e=>H[e>>2];default:throw new TypeError(`invalid integer width (${b}): ${a}`);}},ra=(a,b,c)=>{var e=B;if(!(0<c))return 0;var f=b;c=b+c-1;for(var k=0;k<a.length;++k){var n=a.charCodeAt(k);if(55296<=n&&57343>=n){var l=a.charCodeAt(++k);n=65536+((n&1023)<<10)|l&1023}if(127>=n){if(b>=c)break;e[b++]=n}else{if(2047>=n){if(b+1>=c)break;e[b++]=192|n>>6}else{if(65535>=n){if(b+2>=c)break;e[b++]=224|n>>12}else{if(b+3>=c)break;e[b++]=240|n>>18;e[b++]=128|n>>12&63}e[b++]=128|n>>6&
63}e[b++]=128|n&63}}e[b]=0;return b-f},qa=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b},sc="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0,tc=(a,b)=>{var c=a>>1;for(var e=c+b/2;!(c>=e)&&Fa[c];)++c;c<<=1;if(32<c-a&&sc)return sc.decode(B.subarray(a,c));c="";for(e=0;!(e>=b/2);++e){var f=Da[a+2*e>>1];if(0==f)break;c+=String.fromCharCode(f)}return c},uc=(a,b,c)=>{c??=2147483647;if(2>c)return 0;c-=2;var e=
b;c=c<2*a.length?c/2:a.length;for(var f=0;f<c;++f)Da[b>>1]=a.charCodeAt(f),b+=2;Da[b>>1]=0;return b-e},vc=a=>2*a.length,wc=(a,b)=>{for(var c=0,e="";!(c>=b/4);){var f=E[a+4*c>>2];if(0==f)break;++c;65536<=f?(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023)):e+=String.fromCharCode(f)}return e},xc=(a,b,c)=>{c??=2147483647;if(4>c)return 0;var e=b;c=e+c-4;for(var f=0;f<a.length;++f){var k=a.charCodeAt(f);if(55296<=k&&57343>=k){var n=a.charCodeAt(++f);k=65536+((k&1023)<<10)|n&1023}E[b>>2]=k;b+=
4;if(b+4>c)break}E[b>>2]=0;return b-e},yc=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);55296<=e&&57343>=e&&++c;b+=4}return b},zc=(a,b,c)=>{var e=[];a=a.toWireType(e,c);e.length&&(H[b>>2]=Nb(e));return a},Ac=[],Bc={},Cc=a=>{var b=Bc[a];return void 0===b?L(a):b},Dc=()=>{function a(b){b.$$$embind_global$$$=b;var c="object"==typeof $$$embind_global$$$&&b.$$$embind_global$$$==b;c||delete b.$$$embind_global$$$;return c}if("object"==typeof globalThis)return globalThis;if("object"==typeof $$$embind_global$$$)return $$$embind_global$$$;
"object"==typeof global&&a(global)?$$$embind_global$$$=global:"object"==typeof self&&a(self)&&($$$embind_global$$$=self);if("object"==typeof $$$embind_global$$$)return $$$embind_global$$$;throw Error("unable to get global object.");},Ec=a=>{var b=Ac.length;Ac.push(a);return b},Fc=(a,b)=>{for(var c=Array(a),e=0;e<a;++e)c[e]=pc(H[b+4*e>>2],"parameter "+e);return c},Gc=Reflect.construct,R,Hc=a=>{var b=a.getExtension("ANGLE_instanced_arrays");b&&(a.vertexAttribDivisor=(c,e)=>b.vertexAttribDivisorANGLE(c,
e),a.drawArraysInstanced=(c,e,f,k)=>b.drawArraysInstancedANGLE(c,e,f,k),a.drawElementsInstanced=(c,e,f,k,n)=>b.drawElementsInstancedANGLE(c,e,f,k,n))},Ic=a=>{var b=a.getExtension("OES_vertex_array_object");b&&(a.createVertexArray=()=>b.createVertexArrayOES(),a.deleteVertexArray=c=>b.deleteVertexArrayOES(c),a.bindVertexArray=c=>b.bindVertexArrayOES(c),a.isVertexArray=c=>b.isVertexArrayOES(c))},Jc=a=>{var b=a.getExtension("WEBGL_draw_buffers");b&&(a.drawBuffers=(c,e)=>b.drawBuffersWEBGL(c,e))},Kc=a=>
{var b="ANGLE_instanced_arrays EXT_blend_minmax EXT_disjoint_timer_query EXT_frag_depth EXT_shader_texture_lod EXT_sRGB OES_element_index_uint OES_fbo_render_mipmap OES_standard_derivatives OES_texture_float OES_texture_half_float OES_texture_half_float_linear OES_vertex_array_object WEBGL_color_buffer_float WEBGL_depth_texture WEBGL_draw_buffers EXT_color_buffer_float EXT_conservative_depth EXT_disjoint_timer_query_webgl2 EXT_texture_norm16 NV_shader_noperspective_interpolation WEBGL_clip_cull_distance EXT_clip_control EXT_color_buffer_half_float EXT_depth_clamp EXT_float_blend EXT_polygon_offset_clamp EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic KHR_parallel_shader_compile OES_texture_float_linear WEBGL_blend_func_extended WEBGL_compressed_texture_astc WEBGL_compressed_texture_etc WEBGL_compressed_texture_etc1 WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw WEBGL_polygon_mode".split(" ");
return(a.getSupportedExtensions()||[]).filter(c=>b.includes(c))},Lc=1,Mc=[],Nc=[],Oc=[],Pc=[],ka=[],Qc=[],Rc=[],pa=[],Sc=[],Tc=[],Uc=[],Vc={},Xc={},Yc=4,Zc=0,ja=a=>{for(var b=Lc++,c=a.length;c<b;c++)a[c]=null;return b},$c=(a,b,c,e)=>{for(var f=0;f<a;f++){var k=R[c](),n=k&&ja(e);k?(k.name=n,e[n]=k):S||=1282;E[b+4*f>>2]=n}},la=(a,b)=>{a.He||(a.He=a.getContext,a.getContext=function(e,f){f=a.He(e,f);return"webgl"==e==f instanceof WebGLRenderingContext?f:null});var c=1<b.majorVersion?a.getContext("webgl2",
b):a.getContext("webgl",b);return c?ad(c,b):0},ad=(a,b)=>{var c=ja(pa),e={handle:c,attributes:b,version:b.majorVersion,fe:a};a.canvas&&(a.canvas.Pe=e);pa[c]=e;("undefined"==typeof b.Ye||b.Ye)&&bd(e);return c},oa=a=>{A=pa[a];r.pf=R=A?.fe;return!(a&&!R)},bd=a=>{a||=A;if(!a.ff){a.ff=!0;var b=a.fe;b.tf=b.getExtension("WEBGL_multi_draw");b.rf=b.getExtension("EXT_polygon_offset_clamp");b.qf=b.getExtension("EXT_clip_control");b.vf=b.getExtension("WEBGL_polygon_mode");Hc(b);Ic(b);Jc(b);b.Je=b.getExtension("WEBGL_draw_instanced_base_vertex_base_instance");
b.Le=b.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance");2<=a.version&&(b.ge=b.getExtension("EXT_disjoint_timer_query_webgl2"));if(2>a.version||!b.ge)b.ge=b.getExtension("EXT_disjoint_timer_query");Kc(b).forEach(c=>{c.includes("lose_context")||c.includes("debug")||b.getExtension(c)})}},A,S,cd=(a,b)=>{R.bindFramebuffer(a,Oc[b])},dd=a=>{R.bindVertexArray(Rc[a])},ed=a=>R.clear(a),fd=(a,b,c,e)=>R.clearColor(a,b,c,e),gd=a=>R.clearStencil(a),hd=(a,b)=>{for(var c=0;c<a;c++){var e=E[b+
4*c>>2];R.deleteVertexArray(Rc[e]);Rc[e]=null}},jd=[],kd=(a,b)=>{$c(a,b,"createVertexArray",Rc)};function ld(){var a=Kc(R);return a=a.concat(a.map(b=>"GL_"+b))}
var md=(a,b,c)=>{if(b){var e=void 0;switch(a){case 36346:e=1;break;case 36344:0!=c&&1!=c&&(S||=1280);return;case 34814:case 36345:e=0;break;case 34466:var f=R.getParameter(34467);e=f?f.length:0;break;case 33309:if(2>A.version){S||=1282;return}e=ld().length;break;case 33307:case 33308:if(2>A.version){S||=1280;return}e=33307==a?3:0}if(void 0===e)switch(f=R.getParameter(a),typeof f){case "number":e=f;break;case "boolean":e=f?1:0;break;case "string":S||=1280;return;case "object":if(null===f)switch(a){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:e=
0;break;default:S||=1280;return}else{if(f instanceof Float32Array||f instanceof Uint32Array||f instanceof Int32Array||f instanceof Array){for(a=0;a<f.length;++a)switch(c){case 0:E[b+4*a>>2]=f[a];break;case 2:J[b+4*a>>2]=f[a];break;case 4:Ca[b+a]=f[a]?1:0}return}try{e=f.name|0}catch(k){S||=1280;ya(`GL_INVALID_ENUM in glGet${c}v: Unknown object returned from WebGL getParameter(${a})! (error: ${k})`);return}}break;default:S||=1280;ya(`GL_INVALID_ENUM in glGet${c}v: Native code calling glGet${c}v(${a}) and it returns ${f} of type ${typeof f}!`);
return}switch(c){case 1:c=e;H[b>>2]=c;H[b+4>>2]=(c-H[b>>2])/4294967296;break;case 0:E[b>>2]=e;break;case 2:J[b>>2]=e;break;case 4:Ca[b]=e?1:0}}else S||=1281},nd=(a,b)=>md(a,b,0),od=(a,b,c)=>{if(c){a=Sc[a];b=2>A.version?R.ge.getQueryObjectEXT(a,b):R.getQueryParameter(a,b);var e;"boolean"==typeof b?e=b?1:0:e=b;H[c>>2]=e;H[c+4>>2]=(e-H[c>>2])/4294967296}else S||=1281},qd=a=>{var b=qa(a)+1,c=pd(b);c&&ra(a,c,b);return c},rd=a=>{var b=Vc[a];if(!b){switch(a){case 7939:b=qd(ld().join(" "));break;case 7936:case 7937:case 37445:case 37446:(b=
R.getParameter(a))||(S||=1280);b=b?qd(b):0;break;case 7938:b=R.getParameter(7938);var c=`OpenGL ES 2.0 (${b})`;2<=A.version&&(c=`OpenGL ES 3.0 (${b})`);b=qd(c);break;case 35724:b=R.getParameter(35724);c=b.match(/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/);null!==c&&(3==c[1].length&&(c[1]+="0"),b=`OpenGL ES GLSL ES ${c[1]} (${b})`);b=qd(b);break;default:S||=1280}Vc[a]=b}return b},sd=(a,b)=>{if(2>A.version)return S||=1282,0;var c=Xc[a];if(c)return 0>b||b>=c.length?(S||=1281,0):c[b];switch(a){case 7939:return c=
ld().map(qd),c=Xc[a]=c,0>b||b>=c.length?(S||=1281,0):c[b];default:return S||=1280,0}},td=a=>"]"==a.slice(-1)&&a.lastIndexOf("["),ud=a=>{a-=5120;return 0==a?Ca:1==a?B:2==a?Da:4==a?E:6==a?J:5==a||28922==a||28520==a||30779==a||30782==a?H:Fa},vd=(a,b,c,e,f)=>{a=ud(a);b=e*((Zc||c)*({5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4}[b-6402]||1)*a.BYTES_PER_ELEMENT+Yc-1&-Yc);return a.subarray(f>>>31-Math.clz32(a.BYTES_PER_ELEMENT),f+b>>>31-Math.clz32(a.BYTES_PER_ELEMENT))},V=a=>{var b=R.We;if(b){var c=
b.re[a];"number"==typeof c&&(b.re[a]=c=R.getUniformLocation(b,b.Ne[a]+(0<c?`[${c}]`:"")));return c}S||=1282},wd=[],xd=[],yd={},Ad=()=>{if(!zd){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:"./this.program"},b;for(b in yd)void 0===yd[b]?delete a[b]:a[b]=yd[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);zd=c}return zd},zd,Bd=[null,[],[]];
jb=r.InternalError=class extends Error{constructor(a){super(a);this.name="InternalError"}};for(var Cd=Array(256),Dd=0;256>Dd;++Dd)Cd[Dd]=String.fromCharCode(Dd);mb=Cd;M=r.BindingError=class extends Error{constructor(a){super(a);this.name="BindingError"}};
Object.assign(Db.prototype,{isAliasOf:function(a){if(!(this instanceof Db&&a instanceof Db))return!1;var b=this.Sd.Yd.Wd,c=this.Sd.Vd;a.Sd=a.Sd;var e=a.Sd.Yd.Wd;for(a=a.Sd.Vd;b.ae;)c=b.se(c),b=b.ae;for(;e.ae;)a=e.se(a),e=e.ae;return b===e&&c===a},clone:function(){this.Sd.Vd||ob(this);if(this.Sd.qe)return this.Sd.count.value+=1,this;var a=Ab,b=Object,c=b.create,e=Object.getPrototypeOf(this),f=this.Sd;a=a(c.call(b,e,{Sd:{value:{count:f.count,pe:f.pe,qe:f.qe,Vd:f.Vd,Yd:f.Yd,Zd:f.Zd,ce:f.ce}}}));a.Sd.count.value+=
1;a.Sd.pe=!1;return a},["delete"](){this.Sd.Vd||ob(this);if(this.Sd.pe&&!this.Sd.qe)throw new M("Object already scheduled for deletion");qb(this);var a=this.Sd;--a.count.value;0===a.count.value&&(a.Zd?a.ce.he(a.Zd):a.Yd.Wd.he(a.Vd));this.Sd.qe||(this.Sd.Zd=void 0,this.Sd.Vd=void 0)},isDeleted:function(){return!this.Sd.Vd},deleteLater:function(){this.Sd.Vd||ob(this);if(this.Sd.pe&&!this.Sd.qe)throw new M("Object already scheduled for deletion");Cb.push(this);this.Sd.pe=!0;return this}});
Object.assign(Pb.prototype,{af(a){this.Me&&(a=this.Me(a));return a},Ie(a){this.he?.(a)},de:8,readValueFromPointer:fb,fromWireType:function(a){function b(){return this.xe?Bb(this.Wd.me,{Yd:this.gf,Vd:c,ce:this,Zd:a}):Bb(this.Wd.me,{Yd:this,Vd:a})}var c=this.af(a);if(!c)return this.Ie(a),null;var e=zb(this.Wd,c);if(void 0!==e){if(0===e.Sd.count.value)return e.Sd.Vd=c,e.Sd.Zd=a,e.clone();e=e.clone();this.Ie(a);return e}e=this.Wd.$e(c);e=sb[e];if(!e)return b.call(this);e=this.we?e.Ve:e.pointerType;var f=
rb(c,this.Wd,e.Wd);return null===f?b.call(this):this.xe?Bb(e.Wd.me,{Yd:e,Vd:f,ce:this,Zd:a}):Bb(e.Wd.me,{Yd:e,Vd:f})}});ac=r.UnboundTypeError=((a,b)=>{var c=Eb(b,function(e){this.name=b;this.message=e;e=Error(e).stack;void 0!==e&&(this.stack=this.toString()+"\n"+e.replace(/^Error(:[^\n]*)?\n/,""))});c.prototype=Object.create(a.prototype);c.prototype.constructor=c;c.prototype.toString=function(){return void 0===this.message?this.name:`${this.name}: ${this.message}`};return c})(Error,"UnboundTypeError");
kc.push(0,1,void 0,1,null,1,!0,1,!1,1);r.count_emval_handles=()=>kc.length/2-5-jc.length;for(var Ed=0;32>Ed;++Ed)jd.push(Array(Ed));var Fd=new Float32Array(288);for(Ed=0;288>=Ed;++Ed)wd[Ed]=Fd.subarray(0,Ed);var Gd=new Int32Array(288);for(Ed=0;288>=Ed;++Ed)xd[Ed]=Gd.subarray(0,Ed);
var Vd={F:(a,b,c)=>{var e=new Xa(a);H[e.Vd+16>>2]=0;H[e.Vd+4>>2]=b;H[e.Vd+8>>2]=c;Ya=a;Za++;throw Ya;},U:function(){return 0},ud:()=>{},td:function(){return 0},sd:()=>{},rd:function(){},qd:()=>{},md:()=>{Pa("")},B:a=>{var b=db[a];delete db[a];var c=b.Fe,e=b.he,f=b.Ke,k=f.map(n=>n.df).concat(f.map(n=>n.lf));lb([a],k,n=>{var l={};f.forEach((q,v)=>{var w=n[v],z=q.bf,D=q.cf,I=n[v+f.length],Q=q.kf,P=q.mf;l[q.Ze]={read:ba=>w.fromWireType(z(D,ba)),write:(ba,ma)=>{var Y=[];Q(P,ba,I.toWireType(Y,ma));eb(Y)}}});
return[{name:b.name,fromWireType:q=>{var v={},w;for(w in l)v[w]=l[w].read(q);e(q);return v},toWireType:(q,v)=>{for(var w in l)if(!(w in v))throw new TypeError(`Missing field: "${w}"`);var z=c();for(w in l)l[w].write(z,v[w]);null!==q&&q.push(e,z);return z},de:8,readValueFromPointer:fb,ee:e}]})},X:()=>{},ld:(a,b,c,e)=>{b=L(b);kb(a,{name:b,fromWireType:function(f){return!!f},toWireType:function(f,k){return k?c:e},de:8,readValueFromPointer:function(f){return this.fromWireType(B[f])},ee:null})},l:(a,b,
c,e,f,k,n,l,q,v,w,z,D)=>{w=L(w);k=Tb(f,k);l&&=Tb(n,l);v&&=Tb(q,v);D=Tb(z,D);var I=Hb(w);Gb(I,function(){ec(`Cannot construct ${w} due to unbound types`,[e])});lb([a,b,c],e?[e]:[],Q=>{Q=Q[0];if(e){var P=Q.Wd;var ba=P.me}else ba=Db.prototype;Q=Eb(w,function(...Ea){if(Object.getPrototypeOf(this)!==ma)throw new M("Use 'new' to construct "+w);if(void 0===Y.je)throw new M(w+" has no accessible constructor");var fa=Y.je[Ea.length];if(void 0===fa)throw new M(`Tried to invoke ctor of ${w} with invalid number of parameters (${Ea.length}) - expected (${Object.keys(Y.je).toString()}) parameters instead!`);
return fa.apply(this,Ea)});var ma=Object.create(ba,{constructor:{value:Q}});Q.prototype=ma;var Y=new Ib(w,Q,ma,D,P,k,l,v);if(Y.ae){var ia;(ia=Y.ae).te??(ia.te=[]);Y.ae.te.push(Y)}P=new Pb(w,Y,!0,!1,!1);ia=new Pb(w+"*",Y,!1,!1,!1);ba=new Pb(w+" const*",Y,!1,!0,!1);sb[a]={pointerType:ia,Ve:ba};Qb(I,Q);return[P,ia,ba]})},e:(a,b,c,e,f,k,n)=>{var l=hc(c,e);b=L(b);b=ic(b);k=Tb(f,k);lb([],[a],q=>{function v(){ec(`Cannot call ${w} due to unbound types`,l)}q=q[0];var w=`${q.name}.${b}`;b.startsWith("@@")&&
(b=Symbol[b.substring(2)]);var z=q.Wd.constructor;void 0===z[b]?(v.ie=c-1,z[b]=v):(Fb(z,b,w),z[b].$d[c-1]=v);lb([],l,D=>{D=[D[0],null].concat(D.slice(1));D=gc(w,D,null,k,n);void 0===z[b].$d?(D.ie=c-1,z[b]=D):z[b].$d[c-1]=D;if(q.Wd.te)for(const I of q.Wd.te)I.constructor.hasOwnProperty(b)||(I.constructor[b]=D);return[]});return[]})},z:(a,b,c,e,f,k)=>{var n=hc(b,c);f=Tb(e,f);lb([],[a],l=>{l=l[0];var q=`constructor ${l.name}`;void 0===l.Wd.je&&(l.Wd.je=[]);if(void 0!==l.Wd.je[b-1])throw new M(`Cannot register multiple constructors with identical number of parameters (${b-
1}) for class '${l.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`);l.Wd.je[b-1]=()=>{ec(`Cannot construct ${l.name} due to unbound types`,n)};lb([],n,v=>{v.splice(1,0,null);l.Wd.je[b-1]=gc(q,v,null,f,k);return[]});return[]})},a:(a,b,c,e,f,k,n,l)=>{var q=hc(c,e);b=L(b);b=ic(b);k=Tb(f,k);lb([],[a],v=>{function w(){ec(`Cannot call ${z} due to unbound types`,q)}v=v[0];var z=`${v.name}.${b}`;b.startsWith("@@")&&(b=Symbol[b.substring(2)]);l&&v.Wd.hf.push(b);
var D=v.Wd.me,I=D[b];void 0===I||void 0===I.$d&&I.className!==v.name&&I.ie===c-2?(w.ie=c-2,w.className=v.name,D[b]=w):(Fb(D,b,z),D[b].$d[c-2]=w);lb([],q,Q=>{Q=gc(z,Q,v,k,n);void 0===D[b].$d?(Q.ie=c-2,D[b]=Q):D[b].$d[c-2]=Q;return[]});return[]})},q:(a,b,c)=>{a=L(a);lb([],[b],e=>{e=e[0];r[a]=e.fromWireType(c);return[]})},kd:a=>kb(a,nc),j:(a,b,c,e)=>{function f(){}b=L(b);f.values={};kb(a,{name:b,constructor:f,fromWireType:function(k){return this.constructor.values[k]},toWireType:(k,n)=>n.value,de:8,
readValueFromPointer:oc(b,c,e),ee:null});Gb(b,f)},b:(a,b,c)=>{var e=pc(a,"enum");b=L(b);a=e.constructor;e=Object.create(e.constructor.prototype,{value:{value:c},constructor:{value:Eb(`${e.name}_${b}`,function(){})}});a.values[c]=e;a[b]=e},R:(a,b,c)=>{b=L(b);kb(a,{name:b,fromWireType:e=>e,toWireType:(e,f)=>f,de:8,readValueFromPointer:qc(b,c),ee:null})},w:(a,b,c,e,f,k)=>{var n=hc(b,c);a=L(a);a=ic(a);f=Tb(e,f);Gb(a,function(){ec(`Cannot call ${a} due to unbound types`,n)},b-1);lb([],n,l=>{l=[l[0],null].concat(l.slice(1));
Qb(a,gc(a,l,null,f,k),b-1);return[]})},C:(a,b,c,e,f)=>{b=L(b);-1===f&&(f=4294967295);f=l=>l;if(0===e){var k=32-8*c;f=l=>l<<k>>>k}var n=b.includes("unsigned")?function(l,q){return q>>>0}:function(l,q){return q};kb(a,{name:b,fromWireType:f,toWireType:n,de:8,readValueFromPointer:rc(b,c,0!==e),ee:null})},p:(a,b,c)=>{function e(k){return new f(Ca.buffer,H[k+4>>2],H[k>>2])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=L(c);kb(a,{name:c,fromWireType:e,
de:8,readValueFromPointer:e},{ef:!0})},o:(a,b,c,e,f,k,n,l,q,v,w,z)=>{c=L(c);k=Tb(f,k);l=Tb(n,l);v=Tb(q,v);z=Tb(w,z);lb([a],[b],D=>{D=D[0];return[new Pb(c,D.Wd,!1,!1,!0,D,e,k,l,v,z)]})},Q:(a,b)=>{b=L(b);var c="std::string"===b;kb(a,{name:b,fromWireType:function(e){var f=H[e>>2],k=e+4;if(c)for(var n=k,l=0;l<=f;++l){var q=k+l;if(l==f||0==B[q]){n=n?cb(B,n,q-n):"";if(void 0===v)var v=n;else v+=String.fromCharCode(0),v+=n;n=q+1}}else{v=Array(f);for(l=0;l<f;++l)v[l]=String.fromCharCode(B[k+l]);v=v.join("")}cc(e);
return v},toWireType:function(e,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var k="string"==typeof f;if(!(k||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array))throw new M("Cannot pass non-string to std::string");var n=c&&k?qa(f):f.length;var l=pd(4+n+1),q=l+4;H[l>>2]=n;if(c&&k)ra(f,q,n+1);else if(k)for(k=0;k<n;++k){var v=f.charCodeAt(k);if(255<v)throw cc(q),new M("String has UTF-16 code units that do not fit in 8 bits");B[q+k]=v}else for(k=0;k<n;++k)B[q+k]=f[k];
null!==e&&e.push(cc,l);return l},de:8,readValueFromPointer:fb,ee(e){cc(e)}})},M:(a,b,c)=>{c=L(c);if(2===b){var e=tc;var f=uc;var k=vc;var n=l=>Fa[l>>1]}else 4===b&&(e=wc,f=xc,k=yc,n=l=>H[l>>2]);kb(a,{name:c,fromWireType:l=>{for(var q=H[l>>2],v,w=l+4,z=0;z<=q;++z){var D=l+4+z*b;if(z==q||0==n(D))w=e(w,D-w),void 0===v?v=w:(v+=String.fromCharCode(0),v+=w),w=D+b}cc(l);return v},toWireType:(l,q)=>{if("string"!=typeof q)throw new M(`Cannot pass non-string to C++ string type ${c}`);var v=k(q),w=pd(4+v+b);
H[w>>2]=v/b;f(q,w+4,v+b);null!==l&&l.push(cc,w);return w},de:8,readValueFromPointer:fb,ee(l){cc(l)}})},A:(a,b,c,e,f,k)=>{db[a]={name:L(b),Fe:Tb(c,e),he:Tb(f,k),Ke:[]}},d:(a,b,c,e,f,k,n,l,q,v)=>{db[a].Ke.push({Ze:L(b),df:c,bf:Tb(e,f),cf:k,lf:n,kf:Tb(l,q),mf:v})},jd:(a,b)=>{b=L(b);kb(a,{sf:!0,name:b,de:0,fromWireType:()=>{},toWireType:()=>{}})},id:()=>1,hd:()=>{throw Infinity;},E:(a,b,c)=>{a=mc(a);b=pc(b,"emval::as");return zc(b,c,a)},L:(a,b,c,e)=>{a=Ac[a];b=mc(b);return a(null,b,c,e)},t:(a,b,c,e,f)=>
{a=Ac[a];b=mc(b);c=Cc(c);return a(b,b[c],e,f)},c:lc,K:a=>{if(0===a)return Nb(Dc());a=Cc(a);return Nb(Dc()[a])},n:(a,b,c)=>{var e=Fc(a,b),f=e.shift();a--;var k=Array(a);b=`methodCaller<(${e.map(n=>n.name).join(", ")}) => ${f.name}>`;return Ec(Eb(b,(n,l,q,v)=>{for(var w=0,z=0;z<a;++z)k[z]=e[z].readValueFromPointer(v+w),w+=e[z].de;n=1===c?Gc(l,k):l.apply(n,k);return zc(f,q,n)}))},y:(a,b)=>{a=mc(a);b=mc(b);return Nb(a[b])},H:a=>{9<a&&(kc[a+1]+=1)},G:()=>Nb([]),f:a=>Nb(Cc(a)),D:()=>Nb({}),gd:a=>{a=mc(a);
return!a},m:a=>{var b=mc(a);eb(b);lc(a)},h:(a,b,c)=>{a=mc(a);b=mc(b);c=mc(c);a[b]=c},g:(a,b)=>{a=pc(a,"_emval_take_value");a=a.readValueFromPointer(b);return Nb(a)},W:function(){return-52},V:function(){},fd:(a,b,c,e)=>{var f=(new Date).getFullYear(),k=(new Date(f,0,1)).getTimezoneOffset();f=(new Date(f,6,1)).getTimezoneOffset();H[a>>2]=60*Math.max(k,f);E[b>>2]=Number(k!=f);b=n=>{var l=Math.abs(n);return`UTC${0<=n?"-":"+"}${String(Math.floor(l/60)).padStart(2,"0")}${String(l%60).padStart(2,"0")}`};
a=b(k);b=b(f);f<k?(ra(a,c,17),ra(b,e,17)):(ra(a,e,17),ra(b,c,17))},ed:()=>performance.now(),dd:a=>R.activeTexture(a),cd:(a,b)=>{R.attachShader(Nc[a],Qc[b])},bd:(a,b)=>{R.beginQuery(a,Sc[b])},ad:(a,b)=>{R.ge.beginQueryEXT(a,Sc[b])},$c:(a,b,c)=>{R.bindAttribLocation(Nc[a],b,c?cb(B,c):"")},_c:(a,b)=>{35051==a?R.Ce=b:35052==a&&(R.le=b);R.bindBuffer(a,Mc[b])},Zc:cd,Yc:(a,b)=>{R.bindRenderbuffer(a,Pc[b])},Xc:(a,b)=>{R.bindSampler(a,Tc[b])},Wc:(a,b)=>{R.bindTexture(a,ka[b])},Vc:dd,Uc:dd,Tc:(a,b,c,e)=>R.blendColor(a,
b,c,e),Sc:a=>R.blendEquation(a),Rc:(a,b)=>R.blendFunc(a,b),Qc:(a,b,c,e,f,k,n,l,q,v)=>R.blitFramebuffer(a,b,c,e,f,k,n,l,q,v),Pc:(a,b,c,e)=>{2<=A.version?c&&b?R.bufferData(a,B,e,c,b):R.bufferData(a,b,e):R.bufferData(a,c?B.subarray(c,c+b):b,e)},Oc:(a,b,c,e)=>{2<=A.version?c&&R.bufferSubData(a,b,B,e,c):R.bufferSubData(a,b,B.subarray(e,e+c))},Nc:a=>R.checkFramebufferStatus(a),Mc:ed,Lc:fd,Kc:gd,Jc:(a,b,c,e)=>R.clientWaitSync(Uc[a],b,(c>>>0)+4294967296*e),Ic:(a,b,c,e)=>{R.colorMask(!!a,!!b,!!c,!!e)},Hc:a=>
{R.compileShader(Qc[a])},Gc:(a,b,c,e,f,k,n,l)=>{2<=A.version?R.le||!n?R.compressedTexImage2D(a,b,c,e,f,k,n,l):R.compressedTexImage2D(a,b,c,e,f,k,B,l,n):R.compressedTexImage2D(a,b,c,e,f,k,B.subarray(l,l+n))},Fc:(a,b,c,e,f,k,n,l,q)=>{2<=A.version?R.le||!l?R.compressedTexSubImage2D(a,b,c,e,f,k,n,l,q):R.compressedTexSubImage2D(a,b,c,e,f,k,n,B,q,l):R.compressedTexSubImage2D(a,b,c,e,f,k,n,B.subarray(q,q+l))},Ec:(a,b,c,e,f)=>R.copyBufferSubData(a,b,c,e,f),Dc:(a,b,c,e,f,k,n,l)=>R.copyTexSubImage2D(a,b,c,
e,f,k,n,l),Cc:()=>{var a=ja(Nc),b=R.createProgram();b.name=a;b.Ae=b.ye=b.ze=0;b.Ge=1;Nc[a]=b;return a},Bc:a=>{var b=ja(Qc);Qc[b]=R.createShader(a);return b},Ac:a=>R.cullFace(a),zc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Mc[e];f&&(R.deleteBuffer(f),f.name=0,Mc[e]=null,e==R.Ce&&(R.Ce=0),e==R.le&&(R.le=0))}},yc:(a,b)=>{for(var c=0;c<a;++c){var e=E[b+4*c>>2],f=Oc[e];f&&(R.deleteFramebuffer(f),f.name=0,Oc[e]=null)}},xc:a=>{if(a){var b=Nc[a];b?(R.deleteProgram(b),b.name=0,Nc[a]=null):S||=1281}},
wc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Sc[e];f&&(R.deleteQuery(f),Sc[e]=null)}},vc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Sc[e];f&&(R.ge.deleteQueryEXT(f),Sc[e]=null)}},uc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Pc[e];f&&(R.deleteRenderbuffer(f),f.name=0,Pc[e]=null)}},tc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=Tc[e];f&&(R.deleteSampler(f),f.name=0,Tc[e]=null)}},sc:a=>{if(a){var b=Qc[a];b?(R.deleteShader(b),Qc[a]=null):S||=1281}},rc:a=>{if(a){var b=Uc[a];b?
(R.deleteSync(b),b.name=0,Uc[a]=null):S||=1281}},qc:(a,b)=>{for(var c=0;c<a;c++){var e=E[b+4*c>>2],f=ka[e];f&&(R.deleteTexture(f),f.name=0,ka[e]=null)}},pc:hd,oc:hd,nc:a=>{R.depthMask(!!a)},mc:a=>R.disable(a),lc:a=>{R.disableVertexAttribArray(a)},kc:(a,b,c)=>{R.drawArrays(a,b,c)},jc:(a,b,c,e)=>{R.drawArraysInstanced(a,b,c,e)},ic:(a,b,c,e,f)=>{R.Je.drawArraysInstancedBaseInstanceWEBGL(a,b,c,e,f)},hc:(a,b)=>{for(var c=jd[a],e=0;e<a;e++)c[e]=E[b+4*e>>2];R.drawBuffers(c)},gc:(a,b,c,e)=>{R.drawElements(a,
b,c,e)},fc:(a,b,c,e,f)=>{R.drawElementsInstanced(a,b,c,e,f)},ec:(a,b,c,e,f,k,n)=>{R.Je.drawElementsInstancedBaseVertexBaseInstanceWEBGL(a,b,c,e,f,k,n)},dc:(a,b,c,e,f,k)=>{R.drawElements(a,e,f,k)},cc:a=>R.enable(a),bc:a=>{R.enableVertexAttribArray(a)},ac:a=>R.endQuery(a),$b:a=>{R.ge.endQueryEXT(a)},_b:(a,b)=>(a=R.fenceSync(a,b))?(b=ja(Uc),a.name=b,Uc[b]=a,b):0,Zb:()=>R.finish(),Yb:()=>R.flush(),Xb:(a,b,c,e)=>{R.framebufferRenderbuffer(a,b,c,Pc[e])},Wb:(a,b,c,e,f)=>{R.framebufferTexture2D(a,b,c,ka[e],
f)},Vb:a=>R.frontFace(a),Ub:(a,b)=>{$c(a,b,"createBuffer",Mc)},Tb:(a,b)=>{$c(a,b,"createFramebuffer",Oc)},Sb:(a,b)=>{$c(a,b,"createQuery",Sc)},Rb:(a,b)=>{for(var c=0;c<a;c++){var e=R.ge.createQueryEXT();if(!e){for(S||=1282;c<a;)E[b+4*c++>>2]=0;break}var f=ja(Sc);e.name=f;Sc[f]=e;E[b+4*c>>2]=f}},Qb:(a,b)=>{$c(a,b,"createRenderbuffer",Pc)},Pb:(a,b)=>{$c(a,b,"createSampler",Tc)},Ob:(a,b)=>{$c(a,b,"createTexture",ka)},Nb:kd,Mb:kd,Lb:a=>R.generateMipmap(a),Kb:(a,b,c)=>{c?E[c>>2]=R.getBufferParameter(a,
b):S||=1281},Jb:()=>{var a=R.getError()||S;S=0;return a},Ib:(a,b)=>md(a,b,2),Hb:(a,b,c,e)=>{a=R.getFramebufferAttachmentParameter(a,b,c);if(a instanceof WebGLRenderbuffer||a instanceof WebGLTexture)a=a.name|0;E[e>>2]=a},Gb:nd,Fb:(a,b,c,e)=>{a=R.getProgramInfoLog(Nc[a]);null===a&&(a="(unknown error)");b=0<b&&e?ra(a,e,b):0;c&&(E[c>>2]=b)},Eb:(a,b,c)=>{if(c)if(a>=Lc)S||=1281;else if(a=Nc[a],35716==b)a=R.getProgramInfoLog(a),null===a&&(a="(unknown error)"),E[c>>2]=a.length+1;else if(35719==b){if(!a.Ae){var e=
R.getProgramParameter(a,35718);for(b=0;b<e;++b)a.Ae=Math.max(a.Ae,R.getActiveUniform(a,b).name.length+1)}E[c>>2]=a.Ae}else if(35722==b){if(!a.ye)for(e=R.getProgramParameter(a,35721),b=0;b<e;++b)a.ye=Math.max(a.ye,R.getActiveAttrib(a,b).name.length+1);E[c>>2]=a.ye}else if(35381==b){if(!a.ze)for(e=R.getProgramParameter(a,35382),b=0;b<e;++b)a.ze=Math.max(a.ze,R.getActiveUniformBlockName(a,b).length+1);E[c>>2]=a.ze}else E[c>>2]=R.getProgramParameter(a,b);else S||=1281},Db:od,Cb:od,Bb:(a,b,c)=>{if(c){a=
R.getQueryParameter(Sc[a],b);var e;"boolean"==typeof a?e=a?1:0:e=a;E[c>>2]=e}else S||=1281},Ab:(a,b,c)=>{if(c){a=R.ge.getQueryObjectEXT(Sc[a],b);var e;"boolean"==typeof a?e=a?1:0:e=a;E[c>>2]=e}else S||=1281},zb:(a,b,c)=>{c?E[c>>2]=R.getQuery(a,b):S||=1281},yb:(a,b,c)=>{c?E[c>>2]=R.ge.getQueryEXT(a,b):S||=1281},xb:(a,b,c)=>{c?E[c>>2]=R.getRenderbufferParameter(a,b):S||=1281},wb:(a,b,c,e)=>{a=R.getShaderInfoLog(Qc[a]);null===a&&(a="(unknown error)");b=0<b&&e?ra(a,e,b):0;c&&(E[c>>2]=b)},vb:(a,b,c,e)=>
{a=R.getShaderPrecisionFormat(a,b);E[c>>2]=a.rangeMin;E[c+4>>2]=a.rangeMax;E[e>>2]=a.precision},ub:(a,b,c)=>{c?35716==b?(a=R.getShaderInfoLog(Qc[a]),null===a&&(a="(unknown error)"),E[c>>2]=a?a.length+1:0):35720==b?(a=R.getShaderSource(Qc[a]),E[c>>2]=a?a.length+1:0):E[c>>2]=R.getShaderParameter(Qc[a],b):S||=1281},tb:rd,sb:sd,rb:(a,b)=>{b=b?cb(B,b):"";if(a=Nc[a]){var c=a,e=c.re,f=c.Oe,k;if(!e){c.re=e={};c.Ne={};var n=R.getProgramParameter(c,35718);for(k=0;k<n;++k){var l=R.getActiveUniform(c,k);var q=
l.name;l=l.size;var v=td(q);v=0<v?q.slice(0,v):q;var w=c.Ge;c.Ge+=l;f[v]=[l,w];for(q=0;q<l;++q)e[w]=q,c.Ne[w++]=v}}c=a.re;e=0;f=b;k=td(b);0<k&&(e=parseInt(b.slice(k+1))>>>0,f=b.slice(0,k));if((f=a.Oe[f])&&e<f[0]&&(e+=f[1],c[e]=c[e]||R.getUniformLocation(a,b)))return e}else S||=1281;return-1},qb:(a,b,c)=>{for(var e=jd[b],f=0;f<b;f++)e[f]=E[c+4*f>>2];R.invalidateFramebuffer(a,e)},pb:(a,b,c,e,f,k,n)=>{for(var l=jd[b],q=0;q<b;q++)l[q]=E[c+4*q>>2];R.invalidateSubFramebuffer(a,l,e,f,k,n)},ob:a=>R.isSync(Uc[a]),
nb:a=>(a=ka[a])?R.isTexture(a):0,mb:a=>R.lineWidth(a),lb:a=>{a=Nc[a];R.linkProgram(a);a.re=0;a.Oe={}},kb:(a,b,c,e,f,k)=>{R.Le.multiDrawArraysInstancedBaseInstanceWEBGL(a,E,b>>2,E,c>>2,E,e>>2,H,f>>2,k)},jb:(a,b,c,e,f,k,n,l)=>{R.Le.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(a,E,b>>2,c,E,e>>2,E,f>>2,E,k>>2,H,n>>2,l)},ib:(a,b)=>{3317==a?Yc=b:3314==a&&(Zc=b);R.pixelStorei(a,b)},hb:(a,b)=>{R.ge.queryCounterEXT(Sc[a],b)},gb:a=>R.readBuffer(a),fb:(a,b,c,e,f,k,n)=>{if(2<=A.version)if(R.Ce)R.readPixels(a,
b,c,e,f,k,n);else{var l=ud(k);n>>>=31-Math.clz32(l.BYTES_PER_ELEMENT);R.readPixels(a,b,c,e,f,k,l,n)}else(l=vd(k,f,c,e,n))?R.readPixels(a,b,c,e,f,k,l):S||=1280},eb:(a,b,c,e)=>R.renderbufferStorage(a,b,c,e),db:(a,b,c,e,f)=>R.renderbufferStorageMultisample(a,b,c,e,f),cb:(a,b,c)=>{R.samplerParameterf(Tc[a],b,c)},bb:(a,b,c)=>{R.samplerParameteri(Tc[a],b,c)},ab:(a,b,c)=>{R.samplerParameteri(Tc[a],b,E[c>>2])},$a:(a,b,c,e)=>R.scissor(a,b,c,e),_a:(a,b,c,e)=>{for(var f="",k=0;k<b;++k){var n=(n=H[c+4*k>>2])?
cb(B,n,e?H[e+4*k>>2]:void 0):"";f+=n}R.shaderSource(Qc[a],f)},Za:(a,b,c)=>R.stencilFunc(a,b,c),Ya:(a,b,c,e)=>R.stencilFuncSeparate(a,b,c,e),Xa:a=>R.stencilMask(a),Wa:(a,b)=>R.stencilMaskSeparate(a,b),Va:(a,b,c)=>R.stencilOp(a,b,c),Ua:(a,b,c,e)=>R.stencilOpSeparate(a,b,c,e),Ta:(a,b,c,e,f,k,n,l,q)=>{if(2<=A.version){if(R.le){R.texImage2D(a,b,c,e,f,k,n,l,q);return}if(q){var v=ud(l);q>>>=31-Math.clz32(v.BYTES_PER_ELEMENT);R.texImage2D(a,b,c,e,f,k,n,l,v,q);return}}v=q?vd(l,n,e,f,q):null;R.texImage2D(a,
b,c,e,f,k,n,l,v)},Sa:(a,b,c)=>R.texParameterf(a,b,c),Ra:(a,b,c)=>{R.texParameterf(a,b,J[c>>2])},Qa:(a,b,c)=>R.texParameteri(a,b,c),Pa:(a,b,c)=>{R.texParameteri(a,b,E[c>>2])},Oa:(a,b,c,e,f)=>R.texStorage2D(a,b,c,e,f),Na:(a,b,c,e,f,k,n,l,q)=>{if(2<=A.version){if(R.le){R.texSubImage2D(a,b,c,e,f,k,n,l,q);return}if(q){var v=ud(l);R.texSubImage2D(a,b,c,e,f,k,n,l,v,q>>>31-Math.clz32(v.BYTES_PER_ELEMENT));return}}q=q?vd(l,n,f,k,q):null;R.texSubImage2D(a,b,c,e,f,k,n,l,q)},Ma:(a,b)=>{R.uniform1f(V(a),b)},La:(a,
b,c)=>{if(2<=A.version)b&&R.uniform1fv(V(a),J,c>>2,b);else{if(288>=b)for(var e=wd[b],f=0;f<b;++f)e[f]=J[c+4*f>>2];else e=J.subarray(c>>2,c+4*b>>2);R.uniform1fv(V(a),e)}},Ka:(a,b)=>{R.uniform1i(V(a),b)},Ja:(a,b,c)=>{if(2<=A.version)b&&R.uniform1iv(V(a),E,c>>2,b);else{if(288>=b)for(var e=xd[b],f=0;f<b;++f)e[f]=E[c+4*f>>2];else e=E.subarray(c>>2,c+4*b>>2);R.uniform1iv(V(a),e)}},Ia:(a,b,c)=>{R.uniform2f(V(a),b,c)},Ha:(a,b,c)=>{if(2<=A.version)b&&R.uniform2fv(V(a),J,c>>2,2*b);else{if(144>=b){b*=2;for(var e=
wd[b],f=0;f<b;f+=2)e[f]=J[c+4*f>>2],e[f+1]=J[c+(4*f+4)>>2]}else e=J.subarray(c>>2,c+8*b>>2);R.uniform2fv(V(a),e)}},Ga:(a,b,c)=>{R.uniform2i(V(a),b,c)},Fa:(a,b,c)=>{if(2<=A.version)b&&R.uniform2iv(V(a),E,c>>2,2*b);else{if(144>=b){b*=2;for(var e=xd[b],f=0;f<b;f+=2)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2]}else e=E.subarray(c>>2,c+8*b>>2);R.uniform2iv(V(a),e)}},Ea:(a,b,c,e)=>{R.uniform3f(V(a),b,c,e)},Da:(a,b,c)=>{if(2<=A.version)b&&R.uniform3fv(V(a),J,c>>2,3*b);else{if(96>=b){b*=3;for(var e=wd[b],f=0;f<
b;f+=3)e[f]=J[c+4*f>>2],e[f+1]=J[c+(4*f+4)>>2],e[f+2]=J[c+(4*f+8)>>2]}else e=J.subarray(c>>2,c+12*b>>2);R.uniform3fv(V(a),e)}},Ca:(a,b,c,e)=>{R.uniform3i(V(a),b,c,e)},Ba:(a,b,c)=>{if(2<=A.version)b&&R.uniform3iv(V(a),E,c>>2,3*b);else{if(96>=b){b*=3;for(var e=xd[b],f=0;f<b;f+=3)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2],e[f+2]=E[c+(4*f+8)>>2]}else e=E.subarray(c>>2,c+12*b>>2);R.uniform3iv(V(a),e)}},Aa:(a,b,c,e,f)=>{R.uniform4f(V(a),b,c,e,f)},za:(a,b,c)=>{if(2<=A.version)b&&R.uniform4fv(V(a),J,c>>2,4*
b);else{if(72>=b){var e=wd[4*b],f=J;c>>=2;b*=4;for(var k=0;k<b;k+=4){var n=c+k;e[k]=f[n];e[k+1]=f[n+1];e[k+2]=f[n+2];e[k+3]=f[n+3]}}else e=J.subarray(c>>2,c+16*b>>2);R.uniform4fv(V(a),e)}},ya:(a,b,c,e,f)=>{R.uniform4i(V(a),b,c,e,f)},xa:(a,b,c)=>{if(2<=A.version)b&&R.uniform4iv(V(a),E,c>>2,4*b);else{if(72>=b){b*=4;for(var e=xd[b],f=0;f<b;f+=4)e[f]=E[c+4*f>>2],e[f+1]=E[c+(4*f+4)>>2],e[f+2]=E[c+(4*f+8)>>2],e[f+3]=E[c+(4*f+12)>>2]}else e=E.subarray(c>>2,c+16*b>>2);R.uniform4iv(V(a),e)}},wa:(a,b,c,e)=>
{if(2<=A.version)b&&R.uniformMatrix2fv(V(a),!!c,J,e>>2,4*b);else{if(72>=b){b*=4;for(var f=wd[b],k=0;k<b;k+=4)f[k]=J[e+4*k>>2],f[k+1]=J[e+(4*k+4)>>2],f[k+2]=J[e+(4*k+8)>>2],f[k+3]=J[e+(4*k+12)>>2]}else f=J.subarray(e>>2,e+16*b>>2);R.uniformMatrix2fv(V(a),!!c,f)}},va:(a,b,c,e)=>{if(2<=A.version)b&&R.uniformMatrix3fv(V(a),!!c,J,e>>2,9*b);else{if(32>=b){b*=9;for(var f=wd[b],k=0;k<b;k+=9)f[k]=J[e+4*k>>2],f[k+1]=J[e+(4*k+4)>>2],f[k+2]=J[e+(4*k+8)>>2],f[k+3]=J[e+(4*k+12)>>2],f[k+4]=J[e+(4*k+16)>>2],f[k+
5]=J[e+(4*k+20)>>2],f[k+6]=J[e+(4*k+24)>>2],f[k+7]=J[e+(4*k+28)>>2],f[k+8]=J[e+(4*k+32)>>2]}else f=J.subarray(e>>2,e+36*b>>2);R.uniformMatrix3fv(V(a),!!c,f)}},ua:(a,b,c,e)=>{if(2<=A.version)b&&R.uniformMatrix4fv(V(a),!!c,J,e>>2,16*b);else{if(18>=b){var f=wd[16*b],k=J;e>>=2;b*=16;for(var n=0;n<b;n+=16){var l=e+n;f[n]=k[l];f[n+1]=k[l+1];f[n+2]=k[l+2];f[n+3]=k[l+3];f[n+4]=k[l+4];f[n+5]=k[l+5];f[n+6]=k[l+6];f[n+7]=k[l+7];f[n+8]=k[l+8];f[n+9]=k[l+9];f[n+10]=k[l+10];f[n+11]=k[l+11];f[n+12]=k[l+12];f[n+
13]=k[l+13];f[n+14]=k[l+14];f[n+15]=k[l+15]}}else f=J.subarray(e>>2,e+64*b>>2);R.uniformMatrix4fv(V(a),!!c,f)}},ta:a=>{a=Nc[a];R.useProgram(a);R.We=a},sa:(a,b)=>R.vertexAttrib1f(a,b),ra:(a,b)=>{R.vertexAttrib2f(a,J[b>>2],J[b+4>>2])},qa:(a,b)=>{R.vertexAttrib3f(a,J[b>>2],J[b+4>>2],J[b+8>>2])},pa:(a,b)=>{R.vertexAttrib4f(a,J[b>>2],J[b+4>>2],J[b+8>>2],J[b+12>>2])},oa:(a,b)=>{R.vertexAttribDivisor(a,b)},na:(a,b,c,e,f)=>{R.vertexAttribIPointer(a,b,c,e,f)},ma:(a,b,c,e,f,k)=>{R.vertexAttribPointer(a,b,c,
!!e,f,k)},la:(a,b,c,e)=>R.viewport(a,b,c,e),ka:(a,b,c,e)=>{R.waitSync(Uc[a],b,(c>>>0)+4294967296*e)},ja:a=>{var b=B.length;a>>>=0;if(2147483648<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+1/c);e=Math.min(e,a+100663296);a:{e=(Math.min(2147483648,65536*Math.ceil(Math.max(a,e)/65536))-za.buffer.byteLength+65535)/65536|0;try{za.grow(e);Ha();var f=1;break a}catch(k){}f=void 0}if(f)return!0}return!1},ia:()=>A?A.handle:0,pd:(a,b)=>{var c=0;Ad().forEach((e,f)=>{var k=b+c;f=H[a+4*f>>2]=k;for(k=0;k<e.length;++k)Ca[f++]=
e.charCodeAt(k);Ca[f]=0;c+=e.length+1});return 0},od:(a,b)=>{var c=Ad();H[a>>2]=c.length;var e=0;c.forEach(f=>e+=f.length+1);H[b>>2]=e;return 0},ha:a=>{throw new Va(a);},T:()=>52,Z:function(){return 52},nd:()=>52,Y:function(){return 70},S:(a,b,c,e)=>{for(var f=0,k=0;k<c;k++){var n=H[b>>2],l=H[b+4>>2];b+=8;for(var q=0;q<l;q++){var v=B[n+q],w=Bd[a];0===v||10===v?((1===a?wa:ya)(cb(w)),w.length=0):w.push(v)}f+=l}H[e>>2]=f;return 0},ga:cd,fa:ed,ea:fd,da:gd,J:nd,P:rd,ca:sd,k:Hd,u:Id,i:Jd,I:Kd,ba:Ld,O:Md,
N:Nd,s:Od,x:Pd,r:Qd,v:Rd,aa:Sd,$:Td,_:Ud},Z=function(){var a={a:Vd};La++;Ra??=r.locateFile?Qa("canvaskit.wasm")?"canvaskit.wasm":ta+"canvaskit.wasm":(new URL("canvaskit.wasm",import.meta.url)).href;Ua(a,function(b){Z=b.instance.exports;za=Z.vd;Ha();O=Z.yd;Ja.unshift(Z.wd);La--;0==La&&(null!==Ma&&(clearInterval(Ma),Ma=null),Oa&&(b=Oa,Oa=null,b()))}).catch(ca);return{}}(),bc=a=>(bc=Z.xd)(a),pd=r._malloc=a=>(pd=r._malloc=Z.zd)(a),cc=r._free=a=>(cc=r._free=Z.Ad)(a),Wd=(a,b)=>(Wd=Z.Bd)(a,b),
Xd=a=>(Xd=Z.Cd)(a),Yd=()=>(Yd=Z.Dd)();r.dynCall_viji=(a,b,c,e,f)=>(r.dynCall_viji=Z.Ed)(a,b,c,e,f);r.dynCall_vijiii=(a,b,c,e,f,k,n)=>(r.dynCall_vijiii=Z.Fd)(a,b,c,e,f,k,n);r.dynCall_viiiiij=(a,b,c,e,f,k,n,l)=>(r.dynCall_viiiiij=Z.Gd)(a,b,c,e,f,k,n,l);r.dynCall_jii=(a,b,c)=>(r.dynCall_jii=Z.Hd)(a,b,c);r.dynCall_vij=(a,b,c,e)=>(r.dynCall_vij=Z.Id)(a,b,c,e);r.dynCall_jiiiiii=(a,b,c,e,f,k,n)=>(r.dynCall_jiiiiii=Z.Jd)(a,b,c,e,f,k,n);
r.dynCall_jiiiiji=(a,b,c,e,f,k,n,l)=>(r.dynCall_jiiiiji=Z.Kd)(a,b,c,e,f,k,n,l);r.dynCall_ji=(a,b)=>(r.dynCall_ji=Z.Ld)(a,b);r.dynCall_iijj=(a,b,c,e,f,k)=>(r.dynCall_iijj=Z.Md)(a,b,c,e,f,k);r.dynCall_jiji=(a,b,c,e,f)=>(r.dynCall_jiji=Z.Nd)(a,b,c,e,f);r.dynCall_viijii=(a,b,c,e,f,k,n)=>(r.dynCall_viijii=Z.Od)(a,b,c,e,f,k,n);r.dynCall_iiiiij=(a,b,c,e,f,k,n)=>(r.dynCall_iiiiij=Z.Pd)(a,b,c,e,f,k,n);r.dynCall_iiiiijj=(a,b,c,e,f,k,n,l,q)=>(r.dynCall_iiiiijj=Z.Qd)(a,b,c,e,f,k,n,l,q);
r.dynCall_iiiiiijj=(a,b,c,e,f,k,n,l,q,v)=>(r.dynCall_iiiiiijj=Z.Rd)(a,b,c,e,f,k,n,l,q,v);function Rd(a,b,c,e,f){var k=Yd();try{O.get(a)(b,c,e,f)}catch(n){Xd(k);if(n!==n+0)throw n;Wd(1,0)}}function Id(a,b,c){var e=Yd();try{return O.get(a)(b,c)}catch(f){Xd(e);if(f!==f+0)throw f;Wd(1,0)}}function Pd(a,b,c){var e=Yd();try{O.get(a)(b,c)}catch(f){Xd(e);if(f!==f+0)throw f;Wd(1,0)}}function Hd(a,b){var c=Yd();try{return O.get(a)(b)}catch(e){Xd(c);if(e!==e+0)throw e;Wd(1,0)}}
function Od(a,b){var c=Yd();try{O.get(a)(b)}catch(e){Xd(c);if(e!==e+0)throw e;Wd(1,0)}}function Jd(a,b,c,e){var f=Yd();try{return O.get(a)(b,c,e)}catch(k){Xd(f);if(k!==k+0)throw k;Wd(1,0)}}function Ud(a,b,c,e,f,k,n,l,q,v){var w=Yd();try{O.get(a)(b,c,e,f,k,n,l,q,v)}catch(z){Xd(w);if(z!==z+0)throw z;Wd(1,0)}}function Qd(a,b,c,e){var f=Yd();try{O.get(a)(b,c,e)}catch(k){Xd(f);if(k!==k+0)throw k;Wd(1,0)}}
function Td(a,b,c,e,f,k,n){var l=Yd();try{O.get(a)(b,c,e,f,k,n)}catch(q){Xd(l);if(q!==q+0)throw q;Wd(1,0)}}function Md(a,b,c,e,f,k,n,l){var q=Yd();try{return O.get(a)(b,c,e,f,k,n,l)}catch(v){Xd(q);if(v!==v+0)throw v;Wd(1,0)}}function Sd(a,b,c,e,f,k){var n=Yd();try{O.get(a)(b,c,e,f,k)}catch(l){Xd(n);if(l!==l+0)throw l;Wd(1,0)}}function Kd(a,b,c,e,f){var k=Yd();try{return O.get(a)(b,c,e,f)}catch(n){Xd(k);if(n!==n+0)throw n;Wd(1,0)}}
function Nd(a,b,c,e,f,k,n,l,q,v){var w=Yd();try{return O.get(a)(b,c,e,f,k,n,l,q,v)}catch(z){Xd(w);if(z!==z+0)throw z;Wd(1,0)}}function Ld(a,b,c,e,f,k,n){var l=Yd();try{return O.get(a)(b,c,e,f,k,n)}catch(q){Xd(l);if(q!==q+0)throw q;Wd(1,0)}}var Zd,$d;Oa=function ae(){Zd||be();Zd||(Oa=ae)};function be(){if(!(0<La)){if(!$d&&($d=1,Wa(Ia),0<La))return;Zd||(Zd=1,r.calledRun=1,Aa||(Wa(Ja),aa(r),r.onRuntimeInitialized?.(),Wa(Ka)))}}be();moduleRtn=da;
return moduleRtn;
}
);
})();
export default CanvasKitInit;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,158 @@
var skwasm = (() => {
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
return (
function(moduleArg = {}) {
var moduleRtn;
function aa(){e.buffer!=h.buffer&&k();return h}function n(){e.buffer!=h.buffer&&k();return ba}function q(){e.buffer!=h.buffer&&k();return ca}function t(){e.buffer!=h.buffer&&k();return da}function u(){e.buffer!=h.buffer&&k();return ea}function fa(){e.buffer!=h.buffer&&k();return ha}var v=moduleArg,ia,ja,ka=new Promise((a,b)=>{ia=a;ja=b}),la="object"==typeof window,ma="function"==typeof importScripts,w=ma&&self.name?.startsWith("em-pthread"),na=Object.assign({},v),x="",oa,pa;
if(la||ma)ma?x=self.location.href:"undefined"!=typeof document&&document.currentScript&&(x=document.currentScript.src),_scriptName&&(x=_scriptName),x.startsWith("blob:")?x="":x=x.substr(0,x.replace(/[?#].*/,"").lastIndexOf("/")+1),ma&&(pa=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),oa=a=>fetch(a,{credentials:"same-origin"}).then(b=>b.ok?b.arrayBuffer():Promise.reject(Error(b.status+" : "+b.url)));
var qa=console.log.bind(console),y=console.error.bind(console);Object.assign(v,na);na=null;var e,ra,sa=!1,ta,h,ba,ua,va,ca,da,ea,ha;function k(){var a=e.buffer;h=new Int8Array(a);ua=new Int16Array(a);ba=new Uint8Array(a);va=new Uint16Array(a);ca=new Int32Array(a);da=new Uint32Array(a);ea=new Float32Array(a);ha=new Float64Array(a)}
if(w){var wa,xa=!1;y=function(...b){console.error(b.join(" "))};self.alert=function(...b){postMessage({g:"alert",text:b.join(" "),na:ya()})};v.instantiateWasm=(b,c)=>new Promise(d=>{wa=f=>{f=new WebAssembly.Instance(f,za());c(f);d()}});self.onunhandledrejection=b=>{throw b.reason||b;};function a(b){try{var c=b.data,d=c.g;if("load"===d){let f=[];self.onmessage=g=>f.push(g);self.startWorker=()=>{postMessage({g:"loaded"});for(let g of f)a(g);self.onmessage=a};for(const g of c.ca)if(!v[g]||v[g].proxy)v[g]=
(...l)=>{postMessage({g:"callHandler",ba:g,X:l})},"print"==g&&(qa=v[g]),"printErr"==g&&(y=v[g]);e=c.pa;k();wa(c.qa)}else if("run"===d){Aa(c.l);Ba(c.l,0,0,1,0,0);Ca(c);Da();Ea(c.l);xa||=!0;try{Fa(c.la,c.J)}catch(f){if("unwind"!=f)throw f;}}else"setimmediate"!==c.target&&("checkMailbox"===d?xa&&Ga():d&&(y(`worker: received unknown command ${d}`),y(c)))}catch(f){throw Ha(),f;}}self.onmessage=a}w||(e=new WebAssembly.Memory({initial:256,maximum:32768,shared:!0}),k());
var Ia=[],Ja=[],Ka=[],z=0,La=null,Ma=null;function Na(){z--;if(0==z&&(null!==La&&(clearInterval(La),La=null),Ma)){var a=Ma;Ma=null;a()}}function Oa(a){a="Aborted("+a+")";y(a);sa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ja(a);throw a;}var Pa=a=>a.startsWith("data:application/octet-stream;base64,"),Qa;function Ra(a){return oa(a).then(b=>new Uint8Array(b),()=>{if(pa)var b=pa(a);else throw"both async and sync fetching of the wasm failed";return b})}
function Sa(a,b,c){return Ra(a).then(d=>WebAssembly.instantiate(d,b)).then(c,d=>{y(`failed to asynchronously prepare wasm: ${d}`);Oa(d)})}function Ta(a,b){var c=Qa;return"function"!=typeof WebAssembly.instantiateStreaming||Pa(c)||"function"!=typeof fetch?Sa(c,a,b):fetch(c,{credentials:"same-origin"}).then(d=>WebAssembly.instantiateStreaming(d,a).then(b,function(f){y(`wasm streaming compile failed: ${f}`);y("falling back to ArrayBuffer instantiation");return Sa(c,a,b)}))}
function za(){Ua={__cxa_throw:Va,__pthread_create_js:Wa,__syscall_fcntl64:Xa,__syscall_fstat64:Ya,__syscall_ioctl:Za,__syscall_openat:$a,_abort_js:ab,_emscripten_get_now_is_monotonic:bb,_emscripten_init_main_thread_js:cb,_emscripten_notify_mailbox_postmessage:db,_emscripten_receive_on_main_thread_js:eb,_emscripten_runtime_keepalive_clear:fb,_emscripten_thread_cleanup:gb,_emscripten_thread_mailbox_await:Ea,_emscripten_thread_set_strongref:hb,_emscripten_throw_longjmp:ib,_mmap_js:jb,_munmap_js:kb,_setitimer_js:lb,
_tzset_js:mb,emscripten_check_blocking_allowed:nb,emscripten_exit_with_live_runtime:ob,emscripten_get_now:pb,emscripten_glActiveTexture:qb,emscripten_glAttachShader:rb,emscripten_glBeginQuery:sb,emscripten_glBeginQueryEXT:tb,emscripten_glBindAttribLocation:ub,emscripten_glBindBuffer:vb,emscripten_glBindFramebuffer:wb,emscripten_glBindRenderbuffer:xb,emscripten_glBindSampler:yb,emscripten_glBindTexture:zb,emscripten_glBindVertexArray:Ab,emscripten_glBindVertexArrayOES:Ab,emscripten_glBlendColor:Bb,
emscripten_glBlendEquation:Cb,emscripten_glBlendFunc:Db,emscripten_glBlitFramebuffer:Eb,emscripten_glBufferData:Fb,emscripten_glBufferSubData:Gb,emscripten_glCheckFramebufferStatus:Hb,emscripten_glClear:Ib,emscripten_glClearColor:Jb,emscripten_glClearStencil:Kb,emscripten_glClientWaitSync:Lb,emscripten_glColorMask:Mb,emscripten_glCompileShader:Nb,emscripten_glCompressedTexImage2D:Ob,emscripten_glCompressedTexSubImage2D:Pb,emscripten_glCopyBufferSubData:Qb,emscripten_glCopyTexSubImage2D:Rb,emscripten_glCreateProgram:Sb,
emscripten_glCreateShader:Tb,emscripten_glCullFace:Ub,emscripten_glDeleteBuffers:Vb,emscripten_glDeleteFramebuffers:Wb,emscripten_glDeleteProgram:Xb,emscripten_glDeleteQueries:Yb,emscripten_glDeleteQueriesEXT:Zb,emscripten_glDeleteRenderbuffers:$b,emscripten_glDeleteSamplers:ac,emscripten_glDeleteShader:bc,emscripten_glDeleteSync:cc,emscripten_glDeleteTextures:dc,emscripten_glDeleteVertexArrays:ec,emscripten_glDeleteVertexArraysOES:ec,emscripten_glDepthMask:fc,emscripten_glDisable:gc,emscripten_glDisableVertexAttribArray:hc,
emscripten_glDrawArrays:ic,emscripten_glDrawArraysInstanced:jc,emscripten_glDrawArraysInstancedBaseInstanceWEBGL:kc,emscripten_glDrawBuffers:lc,emscripten_glDrawElements:mc,emscripten_glDrawElementsInstanced:nc,emscripten_glDrawElementsInstancedBaseVertexBaseInstanceWEBGL:oc,emscripten_glDrawRangeElements:pc,emscripten_glEnable:qc,emscripten_glEnableVertexAttribArray:rc,emscripten_glEndQuery:sc,emscripten_glEndQueryEXT:tc,emscripten_glFenceSync:uc,emscripten_glFinish:vc,emscripten_glFlush:wc,emscripten_glFramebufferRenderbuffer:xc,
emscripten_glFramebufferTexture2D:yc,emscripten_glFrontFace:zc,emscripten_glGenBuffers:Ac,emscripten_glGenFramebuffers:Bc,emscripten_glGenQueries:Cc,emscripten_glGenQueriesEXT:Dc,emscripten_glGenRenderbuffers:Ec,emscripten_glGenSamplers:Fc,emscripten_glGenTextures:Gc,emscripten_glGenVertexArrays:Hc,emscripten_glGenVertexArraysOES:Hc,emscripten_glGenerateMipmap:Ic,emscripten_glGetBufferParameteriv:Jc,emscripten_glGetError:Kc,emscripten_glGetFloatv:Lc,emscripten_glGetFramebufferAttachmentParameteriv:Mc,
emscripten_glGetIntegerv:Nc,emscripten_glGetProgramInfoLog:Oc,emscripten_glGetProgramiv:Pc,emscripten_glGetQueryObjecti64vEXT:Qc,emscripten_glGetQueryObjectui64vEXT:Qc,emscripten_glGetQueryObjectuiv:Rc,emscripten_glGetQueryObjectuivEXT:Sc,emscripten_glGetQueryiv:Tc,emscripten_glGetQueryivEXT:Uc,emscripten_glGetRenderbufferParameteriv:Vc,emscripten_glGetShaderInfoLog:Wc,emscripten_glGetShaderPrecisionFormat:Xc,emscripten_glGetShaderiv:Yc,emscripten_glGetString:Zc,emscripten_glGetStringi:$c,emscripten_glGetUniformLocation:ad,
emscripten_glInvalidateFramebuffer:bd,emscripten_glInvalidateSubFramebuffer:cd,emscripten_glIsSync:dd,emscripten_glIsTexture:ed,emscripten_glLineWidth:fd,emscripten_glLinkProgram:gd,emscripten_glMultiDrawArraysInstancedBaseInstanceWEBGL:hd,emscripten_glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL:jd,emscripten_glPixelStorei:kd,emscripten_glQueryCounterEXT:ld,emscripten_glReadBuffer:md,emscripten_glReadPixels:nd,emscripten_glRenderbufferStorage:od,emscripten_glRenderbufferStorageMultisample:pd,
emscripten_glSamplerParameterf:qd,emscripten_glSamplerParameteri:rd,emscripten_glSamplerParameteriv:sd,emscripten_glScissor:td,emscripten_glShaderSource:ud,emscripten_glStencilFunc:vd,emscripten_glStencilFuncSeparate:wd,emscripten_glStencilMask:xd,emscripten_glStencilMaskSeparate:yd,emscripten_glStencilOp:zd,emscripten_glStencilOpSeparate:Ad,emscripten_glTexImage2D:Bd,emscripten_glTexParameterf:Cd,emscripten_glTexParameterfv:Dd,emscripten_glTexParameteri:Ed,emscripten_glTexParameteriv:Fd,emscripten_glTexStorage2D:Gd,
emscripten_glTexSubImage2D:Hd,emscripten_glUniform1f:Id,emscripten_glUniform1fv:Jd,emscripten_glUniform1i:Kd,emscripten_glUniform1iv:Ld,emscripten_glUniform2f:Md,emscripten_glUniform2fv:Nd,emscripten_glUniform2i:Od,emscripten_glUniform2iv:Pd,emscripten_glUniform3f:Qd,emscripten_glUniform3fv:Rd,emscripten_glUniform3i:Sd,emscripten_glUniform3iv:Td,emscripten_glUniform4f:Ud,emscripten_glUniform4fv:Vd,emscripten_glUniform4i:Wd,emscripten_glUniform4iv:Xd,emscripten_glUniformMatrix2fv:Yd,emscripten_glUniformMatrix3fv:Zd,
emscripten_glUniformMatrix4fv:$d,emscripten_glUseProgram:ae,emscripten_glVertexAttrib1f:be,emscripten_glVertexAttrib2fv:ce,emscripten_glVertexAttrib3fv:de,emscripten_glVertexAttrib4fv:ee,emscripten_glVertexAttribDivisor:fe,emscripten_glVertexAttribIPointer:ge,emscripten_glVertexAttribPointer:he,emscripten_glViewport:ie,emscripten_glWaitSync:je,emscripten_resize_heap:ke,emscripten_webgl_enable_extension:le,emscripten_webgl_get_current_context:me,emscripten_webgl_make_context_current:ne,environ_get:oe,
environ_sizes_get:pe,exit:qe,fd_close:re,fd_pread:se,fd_read:te,fd_seek:ue,fd_write:ve,glDeleteTextures:dc,glGetIntegerv:Nc,glGetString:Zc,glGetStringi:$c,invoke_ii:we,invoke_iii:xe,invoke_iiii:ye,invoke_iiiii:ze,invoke_iiiiiii:Ae,invoke_vi:Be,invoke_vii:Ce,invoke_viii:De,invoke_viiii:Ee,invoke_viiiiiii:Fe,memory:e,proc_exit:Ge,skwasm_captureImageBitmap:He,skwasm_connectThread:Ie,skwasm_createGlTextureFromTextureSource:Je,skwasm_createOffscreenCanvas:Ke,skwasm_dispatchDisposeSurface:Le,skwasm_dispatchRasterizeImage:Me,
skwasm_dispatchRenderPictures:Ne,skwasm_disposeAssociatedObjectOnThread:Oe,skwasm_getAssociatedObject:Pe,skwasm_postRasterizeResult:Qe,skwasm_resizeCanvas:Re,skwasm_resolveAndPostImages:Se,skwasm_setAssociatedObjectOnThread:Te};return{env:Ua,wasi_snapshot_preview1:Ua}}function Ue(a){this.name="ExitStatus";this.message=`Program terminated with exit(${a})`;this.status=a}
var Ve=a=>{a.terminate();a.onmessage=()=>{}},Ze=a=>{0==A.length&&(We(),Xe(A[0]));var b=A.pop();if(!b)return 6;Ye.push(b);B[a.l]=b;b.l=a.l;var c={g:"run",la:a.ka,J:a.J,l:a.l};c.B=a.B;c.L=a.L;b.postMessage(c,a.U);return 0},D=0,af=a=>$e(a);v.stackAlloc=af;var H=(a,b,...c)=>{for(var d=c.length,f=E(),g=$e(8*d),l=g>>3,m=0;m<c.length;m++){var p=c[m];fa()[l+m]=p}a=bf(a,0,d,g,b);G(f);return a};
function Ge(a){if(w)return H(0,1,a);ta=a;if(!(cf||0<D)){for(var b of Ye)Ve(b);for(b of A)Ve(b);A=[];Ye=[];B=[];sa=!0}throw new Ue(a);}var df=a=>{if(!(a instanceof Ue||"unwind"==a))throw a;};function ef(a){if(w)return H(1,0,a);qe(a)}var qe=a=>{ta=a;if(w)throw ef(a),"unwind";Ge(a)},A=[],Ye=[],ff=[],B={};function gf(){for(var a=1;a--;)We();Ia.unshift(()=>{z++;hf(()=>Na())})}var kf=a=>{var b=a.l;delete B[b];A.push(a);Ye.splice(Ye.indexOf(a),1);a.l=0;jf(b)};
function Ca(a){"undefined"!=typeof lf&&(Object.assign(mf,a.L),!v.canvas&&a.B&&mf[a.B]&&(v.canvas=mf[a.B].T,v.canvas.id=a.B))}function Da(){ff.forEach(a=>a())}
var Xe=a=>new Promise(b=>{a.onmessage=g=>{g=g.data;var l=g.g;if(g.I&&g.I!=ya()){var m=B[g.I];m?m.postMessage(g,g.U):y(`Internal error! Worker sent a message "${l}" to target pthread ${g.I}, but that thread no longer exists!`)}else if("checkMailbox"===l)Ga();else if("spawnThread"===l)Ze(g);else if("cleanupThread"===l)kf(B[g.ma]);else if("loaded"===l)a.loaded=!0,b(a);else if("alert"===l)alert(`Thread ${g.na}: ${g.text}`);else if("setimmediate"===g.target)a.postMessage(g);else if("callHandler"===l)v[g.ba](...g.X);
else l&&y(`worker sent an unknown command ${l}`)};a.onerror=g=>{y(`${"worker sent an error!"} ${g.filename}:${g.lineno}: ${g.message}`);throw g;};var c=[],d=[],f;for(f of d)v.propertyIsEnumerable(f)&&c.push(f);a.postMessage({g:"load",ca:c,pa:e,qa:ra})});function hf(a){w?a():Promise.all(A.map(Xe)).then(a)}function We(){var a=_scriptName;v.mainScriptUrlOrBlob&&(a=v.mainScriptUrlOrBlob,"string"!=typeof a&&(a=URL.createObjectURL(a)));a=new Worker(a,{type:"module",name:"em-pthread"});A.push(a)}
var nf=a=>{a.forEach(b=>b(v))},Aa=a=>{k();var b=t()[a+52>>2];a=t()[a+56>>2];of(b,b-a);G(b)},I,Fa=(a,b)=>{cf=D=0;a=I.get(a)(b);cf||0<D?ta=a:pf(a)},cf=v.noExitRuntime||!0;class qf{constructor(a){this.A=a-24}}var rf=0,sf=0,Va=(a,b,c)=>{var d=new qf(a);t()[d.A+16>>2]=0;t()[d.A+4>>2]=b;t()[d.A+8>>2]=c;rf=a;sf++;throw rf;};function tf(a,b,c,d){return w?H(2,1,a,b,c,d):Wa(a,b,c,d)}
var uf="undefined"!=typeof TextDecoder?new TextDecoder:void 0,vf=(a,b=0,c=NaN)=>{var d=b+c;for(c=b;a[c]&&!(c>=d);)++c;if(16<c-b&&a.buffer&&uf)return uf.decode(a.slice(b,c));for(d="";b<c;){var f=a[b++];if(f&128){var g=a[b++]&63;if(192==(f&224))d+=String.fromCharCode((f&31)<<6|g);else{var l=a[b++]&63;f=224==(f&240)?(f&15)<<12|g<<6|l:(f&7)<<18|g<<12|l<<6|a[b++]&63;65536>f?d+=String.fromCharCode(f):(f-=65536,d+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else d+=String.fromCharCode(f)}return d},wf=
(a,b)=>a?vf(n(),a,b):"",Wa=(a,b,c,d)=>{if("undefined"==typeof SharedArrayBuffer)return 6;var f=[],g=0,l=b?t()[b+40>>2]:0;l=(l=4294967295==l?"#canvas":wf(l).trim())?l.split(","):[];var m={},p=v.canvas?.id||"";for(r of l){var r=r.trim();try{if("#canvas"==r){if(!v.canvas){y(`pthread_create: could not find canvas with ID "${r}" to transfer to thread!`);g=28;break}r=v.canvas.id}if(mf[r]){var F=mf[r];mf[r]=null;v.canvas instanceof OffscreenCanvas&&r===v.canvas.id&&(v.canvas=null)}else if(!w){var C=v.canvas&&
v.canvas.id===r?v.canvas:document.querySelector(r);if(!C){y(`pthread_create: could not find canvas with ID "${r}" to transfer to thread!`);g=28;break}if(C.Y){y(`pthread_create: cannot transfer canvas with ID "${r}" to thread, since the current thread does not have control over it!`);g=63;break}if(C.transferControlToOffscreen)C.u||(C.u=xf(12),q()[C.u>>2]=C.width,q()[C.u+4>>2]=C.height,t()[C.u+8>>2]=0),F={T:C.transferControlToOffscreen(),u:C.u,id:C.id},C.Y=!0;else return y(`pthread_create: cannot transfer control of canvas "${r}" to pthread, because current browser does not support OffscreenCanvas!`),
y("pthread_create: Build with -sOFFSCREEN_FRAMEBUFFER to enable fallback proxying of GL commands from pthread to main thread."),52}F&&(f.push(F.T),m[F.id]=F)}catch(rg){return y(`pthread_create: failed to transfer control of canvas "${r}" to OffscreenCanvas! Error: ${rg}`),28}}if(w&&(0===f.length||g))return tf(a,b,c,d);if(g)return g;for(C of Object.values(m))t()[C.u+8>>2]=a;a={ka:c,l:a,J:d,B:p,L:m,U:f};return w?(a.g="spawnThread",postMessage(a,f),0):Ze(a)};
function Xa(a,b,c){return w?H(3,1,a,b,c):0}function Ya(a,b){if(w)return H(4,1,a,b)}function Za(a,b,c){return w?H(5,1,a,b,c):0}function $a(a,b,c,d){if(w)return H(6,1,a,b,c,d)}
var ab=()=>{Oa("")},bb=()=>1,cb=a=>{Ba(a,!ma,1,!la,65536,!1);Da()},yf=a=>{if(!sa)try{if(a(),!(cf||0<D))try{w?pf(ta):qe(ta)}catch(b){df(b)}}catch(b){df(b)}},Ea=a=>{"function"===typeof Atomics.oa&&(Atomics.oa(q(),a>>2,a).value.then(Ga),a+=128,Atomics.store(q(),a>>2,1))},Ga=()=>{var a=ya();a&&(Ea(a),yf(zf))},db=(a,b)=>{a==b?setTimeout(Ga):w?postMessage({I:a,g:"checkMailbox"}):(a=B[a])&&a.postMessage({g:"checkMailbox"})},Af=[],eb=(a,b,c,d,f)=>{Af.length=d;b=f>>3;for(c=0;c<d;c++)Af[c]=fa()[b+c];return(0,Bf[a])(...Af)},
fb=()=>{cf=!1;D=0},gb=a=>{w?postMessage({g:"cleanupThread",ma:a}):kf(B[a])},hb=()=>{},ib=()=>{throw Infinity;};function jb(a,b,c,d,f,g,l,m){return w?H(7,1,a,b,c,d,f,g,l,m):-52}function kb(a,b,c,d,f,g,l){if(w)return H(8,1,a,b,c,d,f,g,l)}var Cf={},pb=()=>performance.timeOrigin+performance.now();
function lb(a,b){if(w)return H(9,1,a,b);Cf[a]&&(clearTimeout(Cf[a].id),delete Cf[a]);if(!b)return 0;var c=setTimeout(()=>{delete Cf[a];yf(()=>Df(a,performance.timeOrigin+performance.now()))},b);Cf[a]={id:c,ua:b};return 0}
var J=(a,b,c)=>{var d=n();if(0<c){var f=b;c=b+c-1;for(var g=0;g<a.length;++g){var l=a.charCodeAt(g);if(55296<=l&&57343>=l){var m=a.charCodeAt(++g);l=65536+((l&1023)<<10)|m&1023}if(127>=l){if(b>=c)break;d[b++]=l}else{if(2047>=l){if(b+1>=c)break;d[b++]=192|l>>6}else{if(65535>=l){if(b+2>=c)break;d[b++]=224|l>>12}else{if(b+3>=c)break;d[b++]=240|l>>18;d[b++]=128|l>>12&63}d[b++]=128|l>>6&63}d[b++]=128|l&63}}d[b]=0;a=b-f}else a=0;return a},mb=(a,b,c,d)=>{var f=(new Date).getFullYear(),g=(new Date(f,0,1)).getTimezoneOffset();
f=(new Date(f,6,1)).getTimezoneOffset();var l=Math.max(g,f);t()[a>>2]=60*l;q()[b>>2]=Number(g!=f);b=m=>{var p=Math.abs(m);return`UTC${0<=m?"-":"+"}${String(Math.floor(p/60)).padStart(2,"0")}${String(p%60).padStart(2,"0")}`};a=b(g);b=b(f);f<g?(J(a,c,17),J(b,d,17)):(J(a,d,17),J(b,c,17))},nb=()=>{},ob=()=>{D+=1;throw"unwind";},K,Ef=a=>{var b=a.getExtension("ANGLE_instanced_arrays");b&&(a.vertexAttribDivisor=(c,d)=>b.vertexAttribDivisorANGLE(c,d),a.drawArraysInstanced=(c,d,f,g)=>b.drawArraysInstancedANGLE(c,
d,f,g),a.drawElementsInstanced=(c,d,f,g,l)=>b.drawElementsInstancedANGLE(c,d,f,g,l))},Ff=a=>{var b=a.getExtension("OES_vertex_array_object");b&&(a.createVertexArray=()=>b.createVertexArrayOES(),a.deleteVertexArray=c=>b.deleteVertexArrayOES(c),a.bindVertexArray=c=>b.bindVertexArrayOES(c),a.isVertexArray=c=>b.isVertexArrayOES(c))},Gf=a=>{var b=a.getExtension("WEBGL_draw_buffers");b&&(a.drawBuffers=(c,d)=>b.drawBuffersWEBGL(c,d))},Hf=a=>{a.O=a.getExtension("WEBGL_draw_instanced_base_vertex_base_instance")},
If=a=>{a.S=a.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")},Jf=a=>{var b="ANGLE_instanced_arrays EXT_blend_minmax EXT_disjoint_timer_query EXT_frag_depth EXT_shader_texture_lod EXT_sRGB OES_element_index_uint OES_fbo_render_mipmap OES_standard_derivatives OES_texture_float OES_texture_half_float OES_texture_half_float_linear OES_vertex_array_object WEBGL_color_buffer_float WEBGL_depth_texture WEBGL_draw_buffers EXT_color_buffer_float EXT_conservative_depth EXT_disjoint_timer_query_webgl2 EXT_texture_norm16 NV_shader_noperspective_interpolation WEBGL_clip_cull_distance EXT_clip_control EXT_color_buffer_half_float EXT_depth_clamp EXT_float_blend EXT_polygon_offset_clamp EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic KHR_parallel_shader_compile OES_texture_float_linear WEBGL_blend_func_extended WEBGL_compressed_texture_astc WEBGL_compressed_texture_etc WEBGL_compressed_texture_etc1 WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw WEBGL_polygon_mode".split(" ");
return(a.getSupportedExtensions()||[]).filter(c=>b.includes(c))},Kf=1,Lf=[],L=[],Mf=[],Nf=[],M=[],N=[],Of=[],Pf={},mf={},O=[],P=[],Q=[],Qf={},Rf={},Sf=4,Tf=0,Uf=a=>{for(var b=Kf++,c=a.length;c<b;c++)a[c]=null;return b},S=(a,b,c,d)=>{for(var f=0;f<a;f++){var g=K[c](),l=g&&Uf(d);g?(g.name=l,d[l]=g):R||=1282;q()[b+4*f>>2]=l}},Wf=a=>{var b={R:2,alpha:!0,depth:!0,stencil:!0,antialias:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1,powerPreference:"default",failIfMajorPerformanceCaveat:!1,P:!0};a.A||
(a.A=a.getContext,a.getContext=function(d,f){f=a.A(d,f);return"webgl"==d==f instanceof WebGLRenderingContext?f:null});var c=1<b.R?a.getContext("webgl2",b):a.getContext("webgl",b);return c?Vf(c,b):0},Vf=(a,b)=>{var c=xf(8);t()[c+4>>2]=ya();var d={handle:c,attributes:b,version:b.R,D:a};a.canvas&&(a.canvas.sa=d);Pf[c]=d;("undefined"==typeof b.P||b.P)&&Xf(d);return c},Xf=a=>{a||=T;if(!a.ea){a.ea=!0;var b=a.D;b.fa=b.getExtension("WEBGL_multi_draw");b.aa=b.getExtension("EXT_polygon_offset_clamp");b.$=b.getExtension("EXT_clip_control");
b.ra=b.getExtension("WEBGL_polygon_mode");Ef(b);Ff(b);Gf(b);Hf(b);If(b);2<=a.version&&(b.h=b.getExtension("EXT_disjoint_timer_query_webgl2"));if(2>a.version||!b.h)b.h=b.getExtension("EXT_disjoint_timer_query");Jf(b).forEach(c=>{c.includes("lose_context")||c.includes("debug")||b.getExtension(c)})}},lf={},R,T,qb=a=>K.activeTexture(a),rb=(a,b)=>{K.attachShader(L[a],N[b])},sb=(a,b)=>{K.beginQuery(a,O[b])},tb=(a,b)=>{K.h.beginQueryEXT(a,O[b])},ub=(a,b,c)=>{K.bindAttribLocation(L[a],b,wf(c))},vb=(a,b)=>
{35051==a?K.K=b:35052==a&&(K.v=b);K.bindBuffer(a,Lf[b])},wb=(a,b)=>{K.bindFramebuffer(a,Mf[b])},xb=(a,b)=>{K.bindRenderbuffer(a,Nf[b])},yb=(a,b)=>{K.bindSampler(a,P[b])},zb=(a,b)=>{K.bindTexture(a,M[b])},Ab=a=>{K.bindVertexArray(Of[a])},Bb=(a,b,c,d)=>K.blendColor(a,b,c,d),Cb=a=>K.blendEquation(a),Db=(a,b)=>K.blendFunc(a,b),Eb=(a,b,c,d,f,g,l,m,p,r)=>K.blitFramebuffer(a,b,c,d,f,g,l,m,p,r),Fb=(a,b,c,d)=>{2<=T.version?c&&b?K.bufferData(a,n(),d,c,b):K.bufferData(a,b,d):K.bufferData(a,c?n().subarray(c,
c+b):b,d)},Gb=(a,b,c,d)=>{2<=T.version?c&&K.bufferSubData(a,b,n(),d,c):K.bufferSubData(a,b,n().subarray(d,d+c))},Hb=a=>K.checkFramebufferStatus(a),Ib=a=>K.clear(a),Jb=(a,b,c,d)=>K.clearColor(a,b,c,d),Kb=a=>K.clearStencil(a),Lb=(a,b,c,d)=>K.clientWaitSync(Q[a],b,(c>>>0)+4294967296*d),Mb=(a,b,c,d)=>{K.colorMask(!!a,!!b,!!c,!!d)},Nb=a=>{K.compileShader(N[a])},Ob=(a,b,c,d,f,g,l,m)=>{2<=T.version?K.v||!l?K.compressedTexImage2D(a,b,c,d,f,g,l,m):K.compressedTexImage2D(a,b,c,d,f,g,n(),m,l):K.compressedTexImage2D(a,
b,c,d,f,g,n().subarray(m,m+l))},Pb=(a,b,c,d,f,g,l,m,p)=>{2<=T.version?K.v||!m?K.compressedTexSubImage2D(a,b,c,d,f,g,l,m,p):K.compressedTexSubImage2D(a,b,c,d,f,g,l,n(),p,m):K.compressedTexSubImage2D(a,b,c,d,f,g,l,n().subarray(p,p+m))},Qb=(a,b,c,d,f)=>K.copyBufferSubData(a,b,c,d,f),Rb=(a,b,c,d,f,g,l,m)=>K.copyTexSubImage2D(a,b,c,d,f,g,l,m),Sb=()=>{var a=Uf(L),b=K.createProgram();b.name=a;b.H=b.F=b.G=0;b.N=1;L[a]=b;return a},Tb=a=>{var b=Uf(N);N[b]=K.createShader(a);return b},Ub=a=>K.cullFace(a),Vb=
(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=Lf[d];f&&(K.deleteBuffer(f),f.name=0,Lf[d]=null,d==K.K&&(K.K=0),d==K.v&&(K.v=0))}},Wb=(a,b)=>{for(var c=0;c<a;++c){var d=q()[b+4*c>>2],f=Mf[d];f&&(K.deleteFramebuffer(f),f.name=0,Mf[d]=null)}},Xb=a=>{if(a){var b=L[a];b?(K.deleteProgram(b),b.name=0,L[a]=null):R||=1281}},Yb=(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=O[d];f&&(K.deleteQuery(f),O[d]=null)}},Zb=(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=O[d];f&&(K.h.deleteQueryEXT(f),O[d]=
null)}},$b=(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=Nf[d];f&&(K.deleteRenderbuffer(f),f.name=0,Nf[d]=null)}},ac=(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=P[d];f&&(K.deleteSampler(f),f.name=0,P[d]=null)}},bc=a=>{if(a){var b=N[a];b?(K.deleteShader(b),N[a]=null):R||=1281}},cc=a=>{if(a){var b=Q[a];b?(K.deleteSync(b),b.name=0,Q[a]=null):R||=1281}},dc=(a,b)=>{for(var c=0;c<a;c++){var d=q()[b+4*c>>2],f=M[d];f&&(K.deleteTexture(f),f.name=0,M[d]=null)}},ec=(a,b)=>{for(var c=0;c<a;c++){var d=
q()[b+4*c>>2];K.deleteVertexArray(Of[d]);Of[d]=null}},fc=a=>{K.depthMask(!!a)},gc=a=>K.disable(a),hc=a=>{K.disableVertexAttribArray(a)},ic=(a,b,c)=>{K.drawArrays(a,b,c)},jc=(a,b,c,d)=>{K.drawArraysInstanced(a,b,c,d)},kc=(a,b,c,d,f)=>{K.O.drawArraysInstancedBaseInstanceWEBGL(a,b,c,d,f)},Yf=[],lc=(a,b)=>{for(var c=Yf[a],d=0;d<a;d++)c[d]=q()[b+4*d>>2];K.drawBuffers(c)},mc=(a,b,c,d)=>{K.drawElements(a,b,c,d)},nc=(a,b,c,d,f)=>{K.drawElementsInstanced(a,b,c,d,f)},oc=(a,b,c,d,f,g,l)=>{K.O.drawElementsInstancedBaseVertexBaseInstanceWEBGL(a,
b,c,d,f,g,l)},pc=(a,b,c,d,f,g)=>{K.drawElements(a,d,f,g)},qc=a=>K.enable(a),rc=a=>{K.enableVertexAttribArray(a)},sc=a=>K.endQuery(a),tc=a=>{K.h.endQueryEXT(a)},uc=(a,b)=>(a=K.fenceSync(a,b))?(b=Uf(Q),a.name=b,Q[b]=a,b):0,vc=()=>K.finish(),wc=()=>K.flush(),xc=(a,b,c,d)=>{K.framebufferRenderbuffer(a,b,c,Nf[d])},yc=(a,b,c,d,f)=>{K.framebufferTexture2D(a,b,c,M[d],f)},zc=a=>K.frontFace(a),Ac=(a,b)=>{S(a,b,"createBuffer",Lf)},Bc=(a,b)=>{S(a,b,"createFramebuffer",Mf)},Cc=(a,b)=>{S(a,b,"createQuery",O)},
Dc=(a,b)=>{for(var c=0;c<a;c++){var d=K.h.createQueryEXT();if(!d){for(R||=1282;c<a;)q()[b+4*c++>>2]=0;break}var f=Uf(O);d.name=f;O[f]=d;q()[b+4*c>>2]=f}},Ec=(a,b)=>{S(a,b,"createRenderbuffer",Nf)},Fc=(a,b)=>{S(a,b,"createSampler",P)},Gc=(a,b)=>{S(a,b,"createTexture",M)},Hc=(a,b)=>{S(a,b,"createVertexArray",Of)},Ic=a=>K.generateMipmap(a),Jc=(a,b,c)=>{c?q()[c>>2]=K.getBufferParameter(a,b):R||=1281},Kc=()=>{var a=K.getError()||R;R=0;return a},Zf=(a,b)=>{t()[a>>2]=b;var c=t()[a>>2];t()[a+4>>2]=(b-c)/
4294967296};function $f(){var a=Jf(K);return a=a.concat(a.map(b=>"GL_"+b))}
var ag=(a,b,c)=>{if(b){var d=void 0;switch(a){case 36346:d=1;break;case 36344:0!=c&&1!=c&&(R||=1280);return;case 34814:case 36345:d=0;break;case 34466:var f=K.getParameter(34467);d=f?f.length:0;break;case 33309:if(2>T.version){R||=1282;return}d=$f().length;break;case 33307:case 33308:if(2>T.version){R||=1280;return}d=33307==a?3:0}if(void 0===d)switch(f=K.getParameter(a),typeof f){case "number":d=f;break;case "boolean":d=f?1:0;break;case "string":R||=1280;return;case "object":if(null===f)switch(a){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:d=
0;break;default:R||=1280;return}else{if(f instanceof Float32Array||f instanceof Uint32Array||f instanceof Int32Array||f instanceof Array){for(a=0;a<f.length;++a)switch(c){case 0:q()[b+4*a>>2]=f[a];break;case 2:u()[b+4*a>>2]=f[a];break;case 4:aa()[b+a]=f[a]?1:0}return}try{d=f.name|0}catch(g){R||=1280;y(`GL_INVALID_ENUM in glGet${c}v: Unknown object returned from WebGL getParameter(${a})! (error: ${g})`);return}}break;default:R||=1280;y(`GL_INVALID_ENUM in glGet${c}v: Native code calling glGet${c}v(${a}) and it returns ${f} of type ${typeof f}!`);
return}switch(c){case 1:Zf(b,d);break;case 0:q()[b>>2]=d;break;case 2:u()[b>>2]=d;break;case 4:aa()[b]=d?1:0}}else R||=1281},Lc=(a,b)=>ag(a,b,2),Mc=(a,b,c,d)=>{a=K.getFramebufferAttachmentParameter(a,b,c);if(a instanceof WebGLRenderbuffer||a instanceof WebGLTexture)a=a.name|0;q()[d>>2]=a},Nc=(a,b)=>ag(a,b,0),Oc=(a,b,c,d)=>{a=K.getProgramInfoLog(L[a]);null===a&&(a="(unknown error)");b=0<b&&d?J(a,d,b):0;c&&(q()[c>>2]=b)},Pc=(a,b,c)=>{if(c)if(a>=Kf)R||=1281;else if(a=L[a],35716==b)a=K.getProgramInfoLog(a),
null===a&&(a="(unknown error)"),q()[c>>2]=a.length+1;else if(35719==b){if(!a.H){var d=K.getProgramParameter(a,35718);for(b=0;b<d;++b)a.H=Math.max(a.H,K.getActiveUniform(a,b).name.length+1)}q()[c>>2]=a.H}else if(35722==b){if(!a.F)for(d=K.getProgramParameter(a,35721),b=0;b<d;++b)a.F=Math.max(a.F,K.getActiveAttrib(a,b).name.length+1);q()[c>>2]=a.F}else if(35381==b){if(!a.G)for(d=K.getProgramParameter(a,35382),b=0;b<d;++b)a.G=Math.max(a.G,K.getActiveUniformBlockName(a,b).length+1);q()[c>>2]=a.G}else q()[c>>
2]=K.getProgramParameter(a,b);else R||=1281},Qc=(a,b,c)=>{if(c){a=O[a];b=2>T.version?K.h.getQueryObjectEXT(a,b):K.getQueryParameter(a,b);var d;"boolean"==typeof b?d=b?1:0:d=b;Zf(c,d)}else R||=1281},Rc=(a,b,c)=>{if(c){a=K.getQueryParameter(O[a],b);var d;"boolean"==typeof a?d=a?1:0:d=a;q()[c>>2]=d}else R||=1281},Sc=(a,b,c)=>{if(c){a=K.h.getQueryObjectEXT(O[a],b);var d;"boolean"==typeof a?d=a?1:0:d=a;q()[c>>2]=d}else R||=1281},Tc=(a,b,c)=>{c?q()[c>>2]=K.getQuery(a,b):R||=1281},Uc=(a,b,c)=>{c?q()[c>>
2]=K.h.getQueryEXT(a,b):R||=1281},Vc=(a,b,c)=>{c?q()[c>>2]=K.getRenderbufferParameter(a,b):R||=1281},Wc=(a,b,c,d)=>{a=K.getShaderInfoLog(N[a]);null===a&&(a="(unknown error)");b=0<b&&d?J(a,d,b):0;c&&(q()[c>>2]=b)},Xc=(a,b,c,d)=>{a=K.getShaderPrecisionFormat(a,b);q()[c>>2]=a.rangeMin;q()[c+4>>2]=a.rangeMax;q()[d>>2]=a.precision},Yc=(a,b,c)=>{c?35716==b?(a=K.getShaderInfoLog(N[a]),null===a&&(a="(unknown error)"),a=a?a.length+1:0,q()[c>>2]=a):35720==b?(a=(a=K.getShaderSource(N[a]))?a.length+1:0,q()[c>>
2]=a):q()[c>>2]=K.getShaderParameter(N[a],b):R||=1281},bg=a=>{for(var b=0,c=0;c<a.length;++c){var d=a.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=d?(b+=4,++c):b+=3}b+=1;(c=xf(b))&&J(a,c,b);return c},Zc=a=>{var b=Qf[a];if(!b){switch(a){case 7939:b=bg($f().join(" "));break;case 7936:case 7937:case 37445:case 37446:(b=K.getParameter(a))||(R||=1280);b=b?bg(b):0;break;case 7938:b=K.getParameter(7938);var c=`OpenGL ES 2.0 (${b})`;2<=T.version&&(c=`OpenGL ES 3.0 (${b})`);b=bg(c);break;case 35724:b=
K.getParameter(35724);c=b.match(/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/);null!==c&&(3==c[1].length&&(c[1]+="0"),b=`OpenGL ES GLSL ES ${c[1]} (${b})`);b=bg(b);break;default:R||=1280}Qf[a]=b}return b},$c=(a,b)=>{if(2>T.version)return R||=1282,0;var c=Rf[a];if(c)return 0>b||b>=c.length?(R||=1281,0):c[b];switch(a){case 7939:return c=$f().map(bg),c=Rf[a]=c,0>b||b>=c.length?(R||=1281,0):c[b];default:return R||=1280,0}},cg=a=>"]"==a.slice(-1)&&a.lastIndexOf("["),ad=(a,b)=>{b=wf(b);if(a=L[a]){var c=
a,d=c.C,f=c.W,g;if(!d){c.C=d={};c.V={};var l=K.getProgramParameter(c,35718);for(g=0;g<l;++g){var m=K.getActiveUniform(c,g);var p=m.name;m=m.size;var r=cg(p);r=0<r?p.slice(0,r):p;var F=c.N;c.N+=m;f[r]=[m,F];for(p=0;p<m;++p)d[F]=p,c.V[F++]=r}}c=a.C;d=0;f=b;g=cg(b);0<g&&(d=parseInt(b.slice(g+1))>>>0,f=b.slice(0,g));if((f=a.W[f])&&d<f[0]&&(d+=f[1],c[d]=c[d]||K.getUniformLocation(a,b)))return d}else R||=1281;return-1},bd=(a,b,c)=>{for(var d=Yf[b],f=0;f<b;f++)d[f]=q()[c+4*f>>2];K.invalidateFramebuffer(a,
d)},cd=(a,b,c,d,f,g,l)=>{for(var m=Yf[b],p=0;p<b;p++)m[p]=q()[c+4*p>>2];K.invalidateSubFramebuffer(a,m,d,f,g,l)},dd=a=>K.isSync(Q[a]),ed=a=>(a=M[a])?K.isTexture(a):0,fd=a=>K.lineWidth(a),gd=a=>{a=L[a];K.linkProgram(a);a.C=0;a.W={}},hd=(a,b,c,d,f,g)=>{K.S.multiDrawArraysInstancedBaseInstanceWEBGL(a,q(),b>>2,q(),c>>2,q(),d>>2,t(),f>>2,g)},jd=(a,b,c,d,f,g,l,m)=>{K.S.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(a,q(),b>>2,c,q(),d>>2,q(),f>>2,q(),g>>2,t(),l>>2,m)},kd=(a,b)=>{3317==a?Sf=b:3314==
a&&(Tf=b);K.pixelStorei(a,b)},ld=(a,b)=>{K.h.queryCounterEXT(O[a],b)},md=a=>K.readBuffer(a),dg=a=>{a-=5120;0==a?a=aa():1==a?a=n():2==a?(e.buffer!=h.buffer&&k(),a=ua):4==a?a=q():6==a?a=u():5==a||28922==a||28520==a||30779==a||30782==a?a=t():(e.buffer!=h.buffer&&k(),a=va);return a},eg=(a,b,c,d,f)=>{a=dg(a);b=d*((Tf||c)*({5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4}[b-6402]||1)*a.BYTES_PER_ELEMENT+Sf-1&-Sf);return a.subarray(f>>>31-Math.clz32(a.BYTES_PER_ELEMENT),f+b>>>31-Math.clz32(a.BYTES_PER_ELEMENT))},
nd=(a,b,c,d,f,g,l)=>{if(2<=T.version)if(K.K)K.readPixels(a,b,c,d,f,g,l);else{var m=dg(g);l>>>=31-Math.clz32(m.BYTES_PER_ELEMENT);K.readPixels(a,b,c,d,f,g,m,l)}else(m=eg(g,f,c,d,l))?K.readPixels(a,b,c,d,f,g,m):R||=1280},od=(a,b,c,d)=>K.renderbufferStorage(a,b,c,d),pd=(a,b,c,d,f)=>K.renderbufferStorageMultisample(a,b,c,d,f),qd=(a,b,c)=>{K.samplerParameterf(P[a],b,c)},rd=(a,b,c)=>{K.samplerParameteri(P[a],b,c)},sd=(a,b,c)=>{c=q()[c>>2];K.samplerParameteri(P[a],b,c)},td=(a,b,c,d)=>K.scissor(a,b,c,d),
ud=(a,b,c,d)=>{for(var f="",g=0;g<b;++g){var l=d?t()[d+4*g>>2]:void 0;f+=wf(t()[c+4*g>>2],l)}K.shaderSource(N[a],f)},vd=(a,b,c)=>K.stencilFunc(a,b,c),wd=(a,b,c,d)=>K.stencilFuncSeparate(a,b,c,d),xd=a=>K.stencilMask(a),yd=(a,b)=>K.stencilMaskSeparate(a,b),zd=(a,b,c)=>K.stencilOp(a,b,c),Ad=(a,b,c,d)=>K.stencilOpSeparate(a,b,c,d),Bd=(a,b,c,d,f,g,l,m,p)=>{if(2<=T.version){if(K.v){K.texImage2D(a,b,c,d,f,g,l,m,p);return}if(p){var r=dg(m);p>>>=31-Math.clz32(r.BYTES_PER_ELEMENT);K.texImage2D(a,b,c,d,f,g,
l,m,r,p);return}}r=p?eg(m,l,d,f,p):null;K.texImage2D(a,b,c,d,f,g,l,m,r)},Cd=(a,b,c)=>K.texParameterf(a,b,c),Dd=(a,b,c)=>{c=u()[c>>2];K.texParameterf(a,b,c)},Ed=(a,b,c)=>K.texParameteri(a,b,c),Fd=(a,b,c)=>{c=q()[c>>2];K.texParameteri(a,b,c)},Gd=(a,b,c,d,f)=>K.texStorage2D(a,b,c,d,f),Hd=(a,b,c,d,f,g,l,m,p)=>{if(2<=T.version){if(K.v){K.texSubImage2D(a,b,c,d,f,g,l,m,p);return}if(p){var r=dg(m);K.texSubImage2D(a,b,c,d,f,g,l,m,r,p>>>31-Math.clz32(r.BYTES_PER_ELEMENT));return}}p=p?eg(m,l,f,g,p):null;K.texSubImage2D(a,
b,c,d,f,g,l,m,p)},U=a=>{var b=K.Z;if(b){var c=b.C[a];"number"==typeof c&&(b.C[a]=c=K.getUniformLocation(b,b.V[a]+(0<c?`[${c}]`:"")));return c}R||=1282},Id=(a,b)=>{K.uniform1f(U(a),b)},V=[],Jd=(a,b,c)=>{if(2<=T.version)b&&K.uniform1fv(U(a),u(),c>>2,b);else{if(288>=b)for(var d=V[b],f=0;f<b;++f)d[f]=u()[c+4*f>>2];else d=u().subarray(c>>2,c+4*b>>2);K.uniform1fv(U(a),d)}},Kd=(a,b)=>{K.uniform1i(U(a),b)},fg=[],Ld=(a,b,c)=>{if(2<=T.version)b&&K.uniform1iv(U(a),q(),c>>2,b);else{if(288>=b)for(var d=fg[b],
f=0;f<b;++f)d[f]=q()[c+4*f>>2];else d=q().subarray(c>>2,c+4*b>>2);K.uniform1iv(U(a),d)}},Md=(a,b,c)=>{K.uniform2f(U(a),b,c)},Nd=(a,b,c)=>{if(2<=T.version)b&&K.uniform2fv(U(a),u(),c>>2,2*b);else{if(144>=b){b*=2;for(var d=V[b],f=0;f<b;f+=2)d[f]=u()[c+4*f>>2],d[f+1]=u()[c+(4*f+4)>>2]}else d=u().subarray(c>>2,c+8*b>>2);K.uniform2fv(U(a),d)}},Od=(a,b,c)=>{K.uniform2i(U(a),b,c)},Pd=(a,b,c)=>{if(2<=T.version)b&&K.uniform2iv(U(a),q(),c>>2,2*b);else{if(144>=b){b*=2;for(var d=fg[b],f=0;f<b;f+=2)d[f]=q()[c+
4*f>>2],d[f+1]=q()[c+(4*f+4)>>2]}else d=q().subarray(c>>2,c+8*b>>2);K.uniform2iv(U(a),d)}},Qd=(a,b,c,d)=>{K.uniform3f(U(a),b,c,d)},Rd=(a,b,c)=>{if(2<=T.version)b&&K.uniform3fv(U(a),u(),c>>2,3*b);else{if(96>=b){b*=3;for(var d=V[b],f=0;f<b;f+=3)d[f]=u()[c+4*f>>2],d[f+1]=u()[c+(4*f+4)>>2],d[f+2]=u()[c+(4*f+8)>>2]}else d=u().subarray(c>>2,c+12*b>>2);K.uniform3fv(U(a),d)}},Sd=(a,b,c,d)=>{K.uniform3i(U(a),b,c,d)},Td=(a,b,c)=>{if(2<=T.version)b&&K.uniform3iv(U(a),q(),c>>2,3*b);else{if(96>=b){b*=3;for(var d=
fg[b],f=0;f<b;f+=3)d[f]=q()[c+4*f>>2],d[f+1]=q()[c+(4*f+4)>>2],d[f+2]=q()[c+(4*f+8)>>2]}else d=q().subarray(c>>2,c+12*b>>2);K.uniform3iv(U(a),d)}},Ud=(a,b,c,d,f)=>{K.uniform4f(U(a),b,c,d,f)},Vd=(a,b,c)=>{if(2<=T.version)b&&K.uniform4fv(U(a),u(),c>>2,4*b);else{if(72>=b){var d=V[4*b],f=u();c>>=2;b*=4;for(var g=0;g<b;g+=4){var l=c+g;d[g]=f[l];d[g+1]=f[l+1];d[g+2]=f[l+2];d[g+3]=f[l+3]}}else d=u().subarray(c>>2,c+16*b>>2);K.uniform4fv(U(a),d)}},Wd=(a,b,c,d,f)=>{K.uniform4i(U(a),b,c,d,f)},Xd=(a,b,c)=>{if(2<=
T.version)b&&K.uniform4iv(U(a),q(),c>>2,4*b);else{if(72>=b){b*=4;for(var d=fg[b],f=0;f<b;f+=4)d[f]=q()[c+4*f>>2],d[f+1]=q()[c+(4*f+4)>>2],d[f+2]=q()[c+(4*f+8)>>2],d[f+3]=q()[c+(4*f+12)>>2]}else d=q().subarray(c>>2,c+16*b>>2);K.uniform4iv(U(a),d)}},Yd=(a,b,c,d)=>{if(2<=T.version)b&&K.uniformMatrix2fv(U(a),!!c,u(),d>>2,4*b);else{if(72>=b){b*=4;for(var f=V[b],g=0;g<b;g+=4)f[g]=u()[d+4*g>>2],f[g+1]=u()[d+(4*g+4)>>2],f[g+2]=u()[d+(4*g+8)>>2],f[g+3]=u()[d+(4*g+12)>>2]}else f=u().subarray(d>>2,d+16*b>>2);
K.uniformMatrix2fv(U(a),!!c,f)}},Zd=(a,b,c,d)=>{if(2<=T.version)b&&K.uniformMatrix3fv(U(a),!!c,u(),d>>2,9*b);else{if(32>=b){b*=9;for(var f=V[b],g=0;g<b;g+=9)f[g]=u()[d+4*g>>2],f[g+1]=u()[d+(4*g+4)>>2],f[g+2]=u()[d+(4*g+8)>>2],f[g+3]=u()[d+(4*g+12)>>2],f[g+4]=u()[d+(4*g+16)>>2],f[g+5]=u()[d+(4*g+20)>>2],f[g+6]=u()[d+(4*g+24)>>2],f[g+7]=u()[d+(4*g+28)>>2],f[g+8]=u()[d+(4*g+32)>>2]}else f=u().subarray(d>>2,d+36*b>>2);K.uniformMatrix3fv(U(a),!!c,f)}},$d=(a,b,c,d)=>{if(2<=T.version)b&&K.uniformMatrix4fv(U(a),
!!c,u(),d>>2,16*b);else{if(18>=b){var f=V[16*b],g=u();d>>=2;b*=16;for(var l=0;l<b;l+=16){var m=d+l;f[l]=g[m];f[l+1]=g[m+1];f[l+2]=g[m+2];f[l+3]=g[m+3];f[l+4]=g[m+4];f[l+5]=g[m+5];f[l+6]=g[m+6];f[l+7]=g[m+7];f[l+8]=g[m+8];f[l+9]=g[m+9];f[l+10]=g[m+10];f[l+11]=g[m+11];f[l+12]=g[m+12];f[l+13]=g[m+13];f[l+14]=g[m+14];f[l+15]=g[m+15]}}else f=u().subarray(d>>2,d+64*b>>2);K.uniformMatrix4fv(U(a),!!c,f)}},ae=a=>{a=L[a];K.useProgram(a);K.Z=a},be=(a,b)=>K.vertexAttrib1f(a,b),ce=(a,b)=>{K.vertexAttrib2f(a,u()[b>>
2],u()[b+4>>2])},de=(a,b)=>{K.vertexAttrib3f(a,u()[b>>2],u()[b+4>>2],u()[b+8>>2])},ee=(a,b)=>{K.vertexAttrib4f(a,u()[b>>2],u()[b+4>>2],u()[b+8>>2],u()[b+12>>2])},fe=(a,b)=>{K.vertexAttribDivisor(a,b)},ge=(a,b,c,d,f)=>{K.vertexAttribIPointer(a,b,c,d,f)},he=(a,b,c,d,f,g)=>{K.vertexAttribPointer(a,b,c,!!d,f,g)},ie=(a,b,c,d)=>K.viewport(a,b,c,d),je=(a,b,c,d)=>{K.waitSync(Q[a],b,(c>>>0)+4294967296*d)},ke=a=>{var b=n().length;a>>>=0;if(a<=b||2147483648<a)return!1;for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);
d=Math.min(d,a+100663296);a:{d=(Math.min(2147483648,65536*Math.ceil(Math.max(a,d)/65536))-e.buffer.byteLength+65535)/65536|0;try{e.grow(d);k();var f=1;break a}catch(g){}f=void 0}if(f)return!0}return!1};
function le(a,b){a=Pf[a];b=wf(b);b.startsWith("GL_")&&(b=b.substr(3));"ANGLE_instanced_arrays"==b&&Ef(K);"OES_vertex_array_object"==b&&Ff(K);"WEBGL_draw_buffers"==b&&Gf(K);"WEBGL_draw_instanced_base_vertex_base_instance"==b&&Hf(K);"WEBGL_multi_draw_instanced_base_vertex_base_instance"==b&&If(K);"WEBGL_multi_draw"==b&&(K.fa=K.getExtension("WEBGL_multi_draw"));"EXT_polygon_offset_clamp"==b&&(K.aa=K.getExtension("EXT_polygon_offset_clamp"));"EXT_clip_control"==b&&(K.$=K.getExtension("EXT_clip_control"));
"WEBGL_polygon_mode"==b&&(K.ra=K.getExtension("WEBGL_polygon_mode"));return!!a.D.getExtension(b)}
var me=()=>T?T.handle:0,ne=a=>{T=Pf[a];v.ta=K=T?.D;return!a||K?0:-5},gg={},ig=()=>{if(!hg){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:"./this.program"},b;for(b in gg)void 0===gg[b]?delete a[b]:a[b]=gg[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);hg=c}return hg},hg;
function oe(a,b){if(w)return H(10,1,a,b);var c=0;ig().forEach((d,f)=>{var g=b+c;f=t()[a+4*f>>2]=g;for(g=0;g<d.length;++g)aa()[f++]=d.charCodeAt(g);aa()[f]=0;c+=d.length+1});return 0}function pe(a,b){if(w)return H(11,1,a,b);var c=ig();t()[a>>2]=c.length;var d=0;c.forEach(f=>d+=f.length+1);t()[b>>2]=d;return 0}function re(a){return w?H(12,1,a):52}function se(a,b,c,d,f,g){return w?H(13,1,a,b,c,d,f,g):52}function te(a,b,c,d){return w?H(14,1,a,b,c,d):52}
function ue(a,b,c,d,f){return w?H(15,1,a,b,c,d,f):70}var jg=[null,[],[]];function ve(a,b,c,d){if(w)return H(16,1,a,b,c,d);for(var f=0,g=0;g<c;g++){var l=t()[b>>2],m=t()[b+4>>2];b+=8;for(var p=0;p<m;p++){var r=n()[l+p],F=jg[a];0===r||10===r?((1===a?qa:y)(vf(F)),F.length=0):F.push(r)}f+=m}t()[d>>2]=f;return 0}function kg(){}function lg(){}function W(){}function He(){}function Ie(){}function Je(){}function Ke(){}function Le(){}function Me(){}function Ne(){}function Oe(){}function Pe(){}
function Qe(){}function Re(){}function Se(){}function Te(){}var mg,ng=[];w||gf();for(var X=0;32>X;++X)Yf.push(Array(X));var og=new Float32Array(288);for(X=0;288>=X;++X)V[X]=og.subarray(0,X);var pg=new Int32Array(288);for(X=0;288>=X;++X)fg[X]=pg.subarray(0,X);
(function(){const a=new Map,b=new Map;Te=function(c,d,f){W({m:"setAssociatedObject",M:d,object:f},[f],c)};Pe=function(c){return b.get(c)};Ie=function(c){kg(c,function(d){var f=d.m;if(f)switch(f){case "renderPictures":qg(d.o,d.ha,d.ga,d.s,lg());break;case "onRenderComplete":sg(d.o,d.s,{imageBitmaps:d.da,rasterStartMilliseconds:d.ja,rasterEndMilliseconds:d.ia});break;case "setAssociatedObject":b.set(d.M,d.object);break;case "disposeAssociatedObject":d=d.M;f=b.get(d);f.close&&f.close();b.delete(d);break;
case "disposeSurface":tg(d.o);break;case "rasterizeImage":ug(d.o,d.image,d.format,d.s);break;case "onRasterizeComplete":vg(d.o,d.data,d.s);break;default:console.warn(`unrecognized skwasm message: ${f}`)}})};Ne=function(c,d,f,g,l){W({m:"renderPictures",o:d,ha:f,ga:g,s:l},[],c)};Ke=function(c,d){c=new OffscreenCanvas(c,d);d=Wf(c);a.set(d,c);return d};Re=function(c,d,f){c=a.get(c);c.width=d;c.height=f};He=function(c,d,f,g){g||=[];c=a.get(c);g.push(createImageBitmap(c,0,0,d,f));return g};Se=async function(c,
d,f,g){d=d?await Promise.all(d):[];W({m:"onRenderComplete",o:c,s:g,da:d,ja:f,ia:lg()},[...d])};Je=function(c,d,f){const g=T.D,l=g.createTexture();g.bindTexture(g.TEXTURE_2D,l);g.pixelStorei(g.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);g.texImage2D(g.TEXTURE_2D,0,g.RGBA,d,f,0,g.RGBA,g.UNSIGNED_BYTE,c);g.pixelStorei(g.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);g.bindTexture(g.TEXTURE_2D,null);c=Uf(M);M[c]=l;return c};Oe=function(c,d){W({m:"disposeAssociatedObject",M:d},[],c)};Le=function(c,d){W({m:"disposeSurface",
o:d},[],c)};Me=function(c,d,f,g,l){W({m:"rasterizeImage",o:d,image:f,format:g,s:l},[],c)};Qe=function(c,d,f){W({m:"onRasterizeComplete",o:c,data:d,s:f})}})();
(function(){let a=0;kg=function(b,c){function d({data:f}){const g=f.m;g&&("syncTimeOrigin"==g?a=performance.timeOrigin-f.timeOrigin:c(f))}b?(B[b].addEventListener("message",d),B[b].postMessage({m:"syncTimeOrigin",timeOrigin:performance.timeOrigin})):addEventListener("message",d)};lg=function(){return performance.now()+a};W=function(b,c,d){d?B[d].postMessage(b,c):postMessage(b,c)}})();
var Bf=[Ge,ef,tf,Xa,Ya,Za,$a,jb,kb,lb,oe,pe,re,se,te,ue,ve],Ua,Y=function(){function a(c,d){Y=c.exports;v.wasmExports=Y;ff.push(Y._emscripten_tls_init);I=Y.__indirect_function_table;Ja.unshift(Y.__wasm_call_ctors);ra=d;Na();return Y}var b=za();z++;if(v.instantiateWasm)try{return v.instantiateWasm(b,a)}catch(c){y(`Module.instantiateWasm callback failed with error: ${c}`),ja(c)}Qa??=Pa("skwasm.wasm")?"skwasm.wasm":x+"skwasm.wasm";Ta(b,function(c){a(c.instance,c.module)}).catch(ja);return{}}();
v._canvas_saveLayer=(a,b,c,d,f)=>(v._canvas_saveLayer=Y.canvas_saveLayer)(a,b,c,d,f);v._canvas_save=a=>(v._canvas_save=Y.canvas_save)(a);v._canvas_restore=a=>(v._canvas_restore=Y.canvas_restore)(a);v._canvas_restoreToCount=(a,b)=>(v._canvas_restoreToCount=Y.canvas_restoreToCount)(a,b);v._canvas_getSaveCount=a=>(v._canvas_getSaveCount=Y.canvas_getSaveCount)(a);v._canvas_translate=(a,b,c)=>(v._canvas_translate=Y.canvas_translate)(a,b,c);
v._canvas_scale=(a,b,c)=>(v._canvas_scale=Y.canvas_scale)(a,b,c);v._canvas_rotate=(a,b)=>(v._canvas_rotate=Y.canvas_rotate)(a,b);v._canvas_skew=(a,b,c)=>(v._canvas_skew=Y.canvas_skew)(a,b,c);v._canvas_transform=(a,b)=>(v._canvas_transform=Y.canvas_transform)(a,b);v._canvas_clipRect=(a,b,c,d)=>(v._canvas_clipRect=Y.canvas_clipRect)(a,b,c,d);v._canvas_clipRRect=(a,b,c)=>(v._canvas_clipRRect=Y.canvas_clipRRect)(a,b,c);v._canvas_clipPath=(a,b,c)=>(v._canvas_clipPath=Y.canvas_clipPath)(a,b,c);
v._canvas_drawColor=(a,b,c)=>(v._canvas_drawColor=Y.canvas_drawColor)(a,b,c);v._canvas_drawLine=(a,b,c,d,f,g)=>(v._canvas_drawLine=Y.canvas_drawLine)(a,b,c,d,f,g);v._canvas_drawPaint=(a,b)=>(v._canvas_drawPaint=Y.canvas_drawPaint)(a,b);v._canvas_drawRect=(a,b,c)=>(v._canvas_drawRect=Y.canvas_drawRect)(a,b,c);v._canvas_drawRRect=(a,b,c)=>(v._canvas_drawRRect=Y.canvas_drawRRect)(a,b,c);v._canvas_drawDRRect=(a,b,c,d)=>(v._canvas_drawDRRect=Y.canvas_drawDRRect)(a,b,c,d);
v._canvas_drawOval=(a,b,c)=>(v._canvas_drawOval=Y.canvas_drawOval)(a,b,c);v._canvas_drawCircle=(a,b,c,d,f)=>(v._canvas_drawCircle=Y.canvas_drawCircle)(a,b,c,d,f);v._canvas_drawArc=(a,b,c,d,f,g)=>(v._canvas_drawArc=Y.canvas_drawArc)(a,b,c,d,f,g);v._canvas_drawPath=(a,b,c)=>(v._canvas_drawPath=Y.canvas_drawPath)(a,b,c);v._canvas_drawShadow=(a,b,c,d,f,g)=>(v._canvas_drawShadow=Y.canvas_drawShadow)(a,b,c,d,f,g);
v._canvas_drawParagraph=(a,b,c,d)=>(v._canvas_drawParagraph=Y.canvas_drawParagraph)(a,b,c,d);v._canvas_drawPicture=(a,b)=>(v._canvas_drawPicture=Y.canvas_drawPicture)(a,b);v._canvas_drawImage=(a,b,c,d,f,g)=>(v._canvas_drawImage=Y.canvas_drawImage)(a,b,c,d,f,g);v._canvas_drawImageRect=(a,b,c,d,f,g)=>(v._canvas_drawImageRect=Y.canvas_drawImageRect)(a,b,c,d,f,g);v._canvas_drawImageNine=(a,b,c,d,f,g)=>(v._canvas_drawImageNine=Y.canvas_drawImageNine)(a,b,c,d,f,g);
v._canvas_drawVertices=(a,b,c,d)=>(v._canvas_drawVertices=Y.canvas_drawVertices)(a,b,c,d);v._canvas_drawPoints=(a,b,c,d,f)=>(v._canvas_drawPoints=Y.canvas_drawPoints)(a,b,c,d,f);v._canvas_drawAtlas=(a,b,c,d,f,g,l,m,p)=>(v._canvas_drawAtlas=Y.canvas_drawAtlas)(a,b,c,d,f,g,l,m,p);v._canvas_getTransform=(a,b)=>(v._canvas_getTransform=Y.canvas_getTransform)(a,b);v._canvas_getLocalClipBounds=(a,b)=>(v._canvas_getLocalClipBounds=Y.canvas_getLocalClipBounds)(a,b);
v._canvas_getDeviceClipBounds=(a,b)=>(v._canvas_getDeviceClipBounds=Y.canvas_getDeviceClipBounds)(a,b);v._contourMeasureIter_create=(a,b,c)=>(v._contourMeasureIter_create=Y.contourMeasureIter_create)(a,b,c);v._contourMeasureIter_next=a=>(v._contourMeasureIter_next=Y.contourMeasureIter_next)(a);v._contourMeasureIter_dispose=a=>(v._contourMeasureIter_dispose=Y.contourMeasureIter_dispose)(a);v._contourMeasure_dispose=a=>(v._contourMeasure_dispose=Y.contourMeasure_dispose)(a);
v._contourMeasure_length=a=>(v._contourMeasure_length=Y.contourMeasure_length)(a);v._contourMeasure_isClosed=a=>(v._contourMeasure_isClosed=Y.contourMeasure_isClosed)(a);v._contourMeasure_getPosTan=(a,b,c,d)=>(v._contourMeasure_getPosTan=Y.contourMeasure_getPosTan)(a,b,c,d);v._contourMeasure_getSegment=(a,b,c,d)=>(v._contourMeasure_getSegment=Y.contourMeasure_getSegment)(a,b,c,d);v._skData_create=a=>(v._skData_create=Y.skData_create)(a);v._skData_getPointer=a=>(v._skData_getPointer=Y.skData_getPointer)(a);
v._skData_getConstPointer=a=>(v._skData_getConstPointer=Y.skData_getConstPointer)(a);v._skData_getSize=a=>(v._skData_getSize=Y.skData_getSize)(a);v._skData_dispose=a=>(v._skData_dispose=Y.skData_dispose)(a);v._imageFilter_createBlur=(a,b,c)=>(v._imageFilter_createBlur=Y.imageFilter_createBlur)(a,b,c);v._imageFilter_createDilate=(a,b)=>(v._imageFilter_createDilate=Y.imageFilter_createDilate)(a,b);v._imageFilter_createErode=(a,b)=>(v._imageFilter_createErode=Y.imageFilter_createErode)(a,b);
v._imageFilter_createMatrix=(a,b)=>(v._imageFilter_createMatrix=Y.imageFilter_createMatrix)(a,b);v._imageFilter_createFromColorFilter=a=>(v._imageFilter_createFromColorFilter=Y.imageFilter_createFromColorFilter)(a);v._imageFilter_compose=(a,b)=>(v._imageFilter_compose=Y.imageFilter_compose)(a,b);v._imageFilter_dispose=a=>(v._imageFilter_dispose=Y.imageFilter_dispose)(a);v._imageFilter_getFilterBounds=(a,b)=>(v._imageFilter_getFilterBounds=Y.imageFilter_getFilterBounds)(a,b);
v._colorFilter_createMode=(a,b)=>(v._colorFilter_createMode=Y.colorFilter_createMode)(a,b);v._colorFilter_createMatrix=a=>(v._colorFilter_createMatrix=Y.colorFilter_createMatrix)(a);v._colorFilter_createSRGBToLinearGamma=()=>(v._colorFilter_createSRGBToLinearGamma=Y.colorFilter_createSRGBToLinearGamma)();v._colorFilter_createLinearToSRGBGamma=()=>(v._colorFilter_createLinearToSRGBGamma=Y.colorFilter_createLinearToSRGBGamma)();
v._colorFilter_compose=(a,b)=>(v._colorFilter_compose=Y.colorFilter_compose)(a,b);v._colorFilter_dispose=a=>(v._colorFilter_dispose=Y.colorFilter_dispose)(a);v._maskFilter_createBlur=(a,b)=>(v._maskFilter_createBlur=Y.maskFilter_createBlur)(a,b);v._maskFilter_dispose=a=>(v._maskFilter_dispose=Y.maskFilter_dispose)(a);v._fontCollection_create=()=>(v._fontCollection_create=Y.fontCollection_create)();v._fontCollection_dispose=a=>(v._fontCollection_dispose=Y.fontCollection_dispose)(a);
v._typeface_create=a=>(v._typeface_create=Y.typeface_create)(a);v._typeface_dispose=a=>(v._typeface_dispose=Y.typeface_dispose)(a);v._typefaces_filterCoveredCodePoints=(a,b,c,d)=>(v._typefaces_filterCoveredCodePoints=Y.typefaces_filterCoveredCodePoints)(a,b,c,d);v._fontCollection_registerTypeface=(a,b,c)=>(v._fontCollection_registerTypeface=Y.fontCollection_registerTypeface)(a,b,c);v._fontCollection_clearCaches=a=>(v._fontCollection_clearCaches=Y.fontCollection_clearCaches)(a);
v._image_createFromPicture=(a,b,c)=>(v._image_createFromPicture=Y.image_createFromPicture)(a,b,c);v._image_createFromPixels=(a,b,c,d,f)=>(v._image_createFromPixels=Y.image_createFromPixels)(a,b,c,d,f);v._image_createFromTextureSource=(a,b,c,d)=>(v._image_createFromTextureSource=Y.image_createFromTextureSource)(a,b,c,d);v._image_ref=a=>(v._image_ref=Y.image_ref)(a);v._image_dispose=a=>(v._image_dispose=Y.image_dispose)(a);v._image_getWidth=a=>(v._image_getWidth=Y.image_getWidth)(a);
v._image_getHeight=a=>(v._image_getHeight=Y.image_getHeight)(a);v._paint_create=(a,b,c,d,f,g,l,m)=>(v._paint_create=Y.paint_create)(a,b,c,d,f,g,l,m);v._paint_dispose=a=>(v._paint_dispose=Y.paint_dispose)(a);v._paint_setShader=(a,b)=>(v._paint_setShader=Y.paint_setShader)(a,b);v._paint_setImageFilter=(a,b)=>(v._paint_setImageFilter=Y.paint_setImageFilter)(a,b);v._paint_setColorFilter=(a,b)=>(v._paint_setColorFilter=Y.paint_setColorFilter)(a,b);
v._paint_setMaskFilter=(a,b)=>(v._paint_setMaskFilter=Y.paint_setMaskFilter)(a,b);v._path_create=()=>(v._path_create=Y.path_create)();v._path_dispose=a=>(v._path_dispose=Y.path_dispose)(a);v._path_copy=a=>(v._path_copy=Y.path_copy)(a);v._path_setFillType=(a,b)=>(v._path_setFillType=Y.path_setFillType)(a,b);v._path_getFillType=a=>(v._path_getFillType=Y.path_getFillType)(a);v._path_moveTo=(a,b,c)=>(v._path_moveTo=Y.path_moveTo)(a,b,c);
v._path_relativeMoveTo=(a,b,c)=>(v._path_relativeMoveTo=Y.path_relativeMoveTo)(a,b,c);v._path_lineTo=(a,b,c)=>(v._path_lineTo=Y.path_lineTo)(a,b,c);v._path_relativeLineTo=(a,b,c)=>(v._path_relativeLineTo=Y.path_relativeLineTo)(a,b,c);v._path_quadraticBezierTo=(a,b,c,d,f)=>(v._path_quadraticBezierTo=Y.path_quadraticBezierTo)(a,b,c,d,f);v._path_relativeQuadraticBezierTo=(a,b,c,d,f)=>(v._path_relativeQuadraticBezierTo=Y.path_relativeQuadraticBezierTo)(a,b,c,d,f);
v._path_cubicTo=(a,b,c,d,f,g,l)=>(v._path_cubicTo=Y.path_cubicTo)(a,b,c,d,f,g,l);v._path_relativeCubicTo=(a,b,c,d,f,g,l)=>(v._path_relativeCubicTo=Y.path_relativeCubicTo)(a,b,c,d,f,g,l);v._path_conicTo=(a,b,c,d,f,g)=>(v._path_conicTo=Y.path_conicTo)(a,b,c,d,f,g);v._path_relativeConicTo=(a,b,c,d,f,g)=>(v._path_relativeConicTo=Y.path_relativeConicTo)(a,b,c,d,f,g);v._path_arcToOval=(a,b,c,d,f)=>(v._path_arcToOval=Y.path_arcToOval)(a,b,c,d,f);
v._path_arcToRotated=(a,b,c,d,f,g,l,m)=>(v._path_arcToRotated=Y.path_arcToRotated)(a,b,c,d,f,g,l,m);v._path_relativeArcToRotated=(a,b,c,d,f,g,l,m)=>(v._path_relativeArcToRotated=Y.path_relativeArcToRotated)(a,b,c,d,f,g,l,m);v._path_addRect=(a,b)=>(v._path_addRect=Y.path_addRect)(a,b);v._path_addOval=(a,b)=>(v._path_addOval=Y.path_addOval)(a,b);v._path_addArc=(a,b,c,d)=>(v._path_addArc=Y.path_addArc)(a,b,c,d);v._path_addPolygon=(a,b,c,d)=>(v._path_addPolygon=Y.path_addPolygon)(a,b,c,d);
v._path_addRRect=(a,b)=>(v._path_addRRect=Y.path_addRRect)(a,b);v._path_addPath=(a,b,c,d)=>(v._path_addPath=Y.path_addPath)(a,b,c,d);v._path_close=a=>(v._path_close=Y.path_close)(a);v._path_reset=a=>(v._path_reset=Y.path_reset)(a);v._path_contains=(a,b,c)=>(v._path_contains=Y.path_contains)(a,b,c);v._path_transform=(a,b)=>(v._path_transform=Y.path_transform)(a,b);v._path_getBounds=(a,b)=>(v._path_getBounds=Y.path_getBounds)(a,b);v._path_combine=(a,b,c)=>(v._path_combine=Y.path_combine)(a,b,c);
v._path_getSvgString=a=>(v._path_getSvgString=Y.path_getSvgString)(a);v._pictureRecorder_create=()=>(v._pictureRecorder_create=Y.pictureRecorder_create)();v._pictureRecorder_dispose=a=>(v._pictureRecorder_dispose=Y.pictureRecorder_dispose)(a);v._pictureRecorder_beginRecording=(a,b)=>(v._pictureRecorder_beginRecording=Y.pictureRecorder_beginRecording)(a,b);v._pictureRecorder_endRecording=a=>(v._pictureRecorder_endRecording=Y.pictureRecorder_endRecording)(a);
v._picture_getCullRect=(a,b)=>(v._picture_getCullRect=Y.picture_getCullRect)(a,b);v._picture_dispose=a=>(v._picture_dispose=Y.picture_dispose)(a);v._picture_approximateBytesUsed=a=>(v._picture_approximateBytesUsed=Y.picture_approximateBytesUsed)(a);v._shader_createLinearGradient=(a,b,c,d,f,g)=>(v._shader_createLinearGradient=Y.shader_createLinearGradient)(a,b,c,d,f,g);v._shader_createRadialGradient=(a,b,c,d,f,g,l,m)=>(v._shader_createRadialGradient=Y.shader_createRadialGradient)(a,b,c,d,f,g,l,m);
v._shader_createConicalGradient=(a,b,c,d,f,g,l,m)=>(v._shader_createConicalGradient=Y.shader_createConicalGradient)(a,b,c,d,f,g,l,m);v._shader_createSweepGradient=(a,b,c,d,f,g,l,m,p)=>(v._shader_createSweepGradient=Y.shader_createSweepGradient)(a,b,c,d,f,g,l,m,p);v._shader_dispose=a=>(v._shader_dispose=Y.shader_dispose)(a);v._runtimeEffect_create=a=>(v._runtimeEffect_create=Y.runtimeEffect_create)(a);v._runtimeEffect_dispose=a=>(v._runtimeEffect_dispose=Y.runtimeEffect_dispose)(a);
v._runtimeEffect_getUniformSize=a=>(v._runtimeEffect_getUniformSize=Y.runtimeEffect_getUniformSize)(a);v._shader_createRuntimeEffectShader=(a,b,c,d)=>(v._shader_createRuntimeEffectShader=Y.shader_createRuntimeEffectShader)(a,b,c,d);v._shader_createFromImage=(a,b,c,d,f)=>(v._shader_createFromImage=Y.shader_createFromImage)(a,b,c,d,f);v._skString_allocate=a=>(v._skString_allocate=Y.skString_allocate)(a);v._skString_getData=a=>(v._skString_getData=Y.skString_getData)(a);
v._skString_getLength=a=>(v._skString_getLength=Y.skString_getLength)(a);v._skString_free=a=>(v._skString_free=Y.skString_free)(a);v._skString16_allocate=a=>(v._skString16_allocate=Y.skString16_allocate)(a);v._skString16_getData=a=>(v._skString16_getData=Y.skString16_getData)(a);v._skString16_free=a=>(v._skString16_free=Y.skString16_free)(a);v._surface_create=()=>(v._surface_create=Y.surface_create)();v._surface_getThreadId=a=>(v._surface_getThreadId=Y.surface_getThreadId)(a);
v._surface_setCallbackHandler=(a,b)=>(v._surface_setCallbackHandler=Y.surface_setCallbackHandler)(a,b);v._surface_destroy=a=>(v._surface_destroy=Y.surface_destroy)(a);var tg=v._surface_dispose=a=>(tg=v._surface_dispose=Y.surface_dispose)(a);v._surface_renderPictures=(a,b,c)=>(v._surface_renderPictures=Y.surface_renderPictures)(a,b,c);var qg=v._surface_renderPicturesOnWorker=(a,b,c,d,f)=>(qg=v._surface_renderPicturesOnWorker=Y.surface_renderPicturesOnWorker)(a,b,c,d,f);
v._surface_rasterizeImage=(a,b,c)=>(v._surface_rasterizeImage=Y.surface_rasterizeImage)(a,b,c);var ug=v._surface_rasterizeImageOnWorker=(a,b,c,d)=>(ug=v._surface_rasterizeImageOnWorker=Y.surface_rasterizeImageOnWorker)(a,b,c,d),sg=v._surface_onRenderComplete=(a,b,c)=>(sg=v._surface_onRenderComplete=Y.surface_onRenderComplete)(a,b,c),vg=v._surface_onRasterizeComplete=(a,b,c)=>(vg=v._surface_onRasterizeComplete=Y.surface_onRasterizeComplete)(a,b,c);
v._lineMetrics_create=(a,b,c,d,f,g,l,m,p)=>(v._lineMetrics_create=Y.lineMetrics_create)(a,b,c,d,f,g,l,m,p);v._lineMetrics_dispose=a=>(v._lineMetrics_dispose=Y.lineMetrics_dispose)(a);v._lineMetrics_getHardBreak=a=>(v._lineMetrics_getHardBreak=Y.lineMetrics_getHardBreak)(a);v._lineMetrics_getAscent=a=>(v._lineMetrics_getAscent=Y.lineMetrics_getAscent)(a);v._lineMetrics_getDescent=a=>(v._lineMetrics_getDescent=Y.lineMetrics_getDescent)(a);
v._lineMetrics_getUnscaledAscent=a=>(v._lineMetrics_getUnscaledAscent=Y.lineMetrics_getUnscaledAscent)(a);v._lineMetrics_getHeight=a=>(v._lineMetrics_getHeight=Y.lineMetrics_getHeight)(a);v._lineMetrics_getWidth=a=>(v._lineMetrics_getWidth=Y.lineMetrics_getWidth)(a);v._lineMetrics_getLeft=a=>(v._lineMetrics_getLeft=Y.lineMetrics_getLeft)(a);v._lineMetrics_getBaseline=a=>(v._lineMetrics_getBaseline=Y.lineMetrics_getBaseline)(a);v._lineMetrics_getLineNumber=a=>(v._lineMetrics_getLineNumber=Y.lineMetrics_getLineNumber)(a);
v._lineMetrics_getStartIndex=a=>(v._lineMetrics_getStartIndex=Y.lineMetrics_getStartIndex)(a);v._lineMetrics_getEndIndex=a=>(v._lineMetrics_getEndIndex=Y.lineMetrics_getEndIndex)(a);v._paragraph_dispose=a=>(v._paragraph_dispose=Y.paragraph_dispose)(a);v._paragraph_getWidth=a=>(v._paragraph_getWidth=Y.paragraph_getWidth)(a);v._paragraph_getHeight=a=>(v._paragraph_getHeight=Y.paragraph_getHeight)(a);v._paragraph_getLongestLine=a=>(v._paragraph_getLongestLine=Y.paragraph_getLongestLine)(a);
v._paragraph_getMinIntrinsicWidth=a=>(v._paragraph_getMinIntrinsicWidth=Y.paragraph_getMinIntrinsicWidth)(a);v._paragraph_getMaxIntrinsicWidth=a=>(v._paragraph_getMaxIntrinsicWidth=Y.paragraph_getMaxIntrinsicWidth)(a);v._paragraph_getAlphabeticBaseline=a=>(v._paragraph_getAlphabeticBaseline=Y.paragraph_getAlphabeticBaseline)(a);v._paragraph_getIdeographicBaseline=a=>(v._paragraph_getIdeographicBaseline=Y.paragraph_getIdeographicBaseline)(a);
v._paragraph_getDidExceedMaxLines=a=>(v._paragraph_getDidExceedMaxLines=Y.paragraph_getDidExceedMaxLines)(a);v._paragraph_layout=(a,b)=>(v._paragraph_layout=Y.paragraph_layout)(a,b);v._paragraph_getPositionForOffset=(a,b,c,d)=>(v._paragraph_getPositionForOffset=Y.paragraph_getPositionForOffset)(a,b,c,d);v._paragraph_getClosestGlyphInfoAtCoordinate=(a,b,c,d,f,g)=>(v._paragraph_getClosestGlyphInfoAtCoordinate=Y.paragraph_getClosestGlyphInfoAtCoordinate)(a,b,c,d,f,g);
v._paragraph_getGlyphInfoAt=(a,b,c,d,f)=>(v._paragraph_getGlyphInfoAt=Y.paragraph_getGlyphInfoAt)(a,b,c,d,f);v._paragraph_getWordBoundary=(a,b,c)=>(v._paragraph_getWordBoundary=Y.paragraph_getWordBoundary)(a,b,c);v._paragraph_getLineCount=a=>(v._paragraph_getLineCount=Y.paragraph_getLineCount)(a);v._paragraph_getLineNumberAt=(a,b)=>(v._paragraph_getLineNumberAt=Y.paragraph_getLineNumberAt)(a,b);
v._paragraph_getLineMetricsAtIndex=(a,b)=>(v._paragraph_getLineMetricsAtIndex=Y.paragraph_getLineMetricsAtIndex)(a,b);v._textBoxList_dispose=a=>(v._textBoxList_dispose=Y.textBoxList_dispose)(a);v._textBoxList_getLength=a=>(v._textBoxList_getLength=Y.textBoxList_getLength)(a);v._textBoxList_getBoxAtIndex=(a,b,c)=>(v._textBoxList_getBoxAtIndex=Y.textBoxList_getBoxAtIndex)(a,b,c);v._paragraph_getBoxesForRange=(a,b,c,d,f)=>(v._paragraph_getBoxesForRange=Y.paragraph_getBoxesForRange)(a,b,c,d,f);
v._paragraph_getBoxesForPlaceholders=a=>(v._paragraph_getBoxesForPlaceholders=Y.paragraph_getBoxesForPlaceholders)(a);v._paragraph_getUnresolvedCodePoints=(a,b,c)=>(v._paragraph_getUnresolvedCodePoints=Y.paragraph_getUnresolvedCodePoints)(a,b,c);v._paragraphBuilder_create=(a,b)=>(v._paragraphBuilder_create=Y.paragraphBuilder_create)(a,b);v._paragraphBuilder_dispose=a=>(v._paragraphBuilder_dispose=Y.paragraphBuilder_dispose)(a);
v._paragraphBuilder_addPlaceholder=(a,b,c,d,f,g)=>(v._paragraphBuilder_addPlaceholder=Y.paragraphBuilder_addPlaceholder)(a,b,c,d,f,g);v._paragraphBuilder_addText=(a,b)=>(v._paragraphBuilder_addText=Y.paragraphBuilder_addText)(a,b);v._paragraphBuilder_getUtf8Text=(a,b)=>(v._paragraphBuilder_getUtf8Text=Y.paragraphBuilder_getUtf8Text)(a,b);v._paragraphBuilder_pushStyle=(a,b)=>(v._paragraphBuilder_pushStyle=Y.paragraphBuilder_pushStyle)(a,b);v._paragraphBuilder_pop=a=>(v._paragraphBuilder_pop=Y.paragraphBuilder_pop)(a);
v._paragraphBuilder_build=a=>(v._paragraphBuilder_build=Y.paragraphBuilder_build)(a);v._unicodePositionBuffer_create=a=>(v._unicodePositionBuffer_create=Y.unicodePositionBuffer_create)(a);v._unicodePositionBuffer_getDataPointer=a=>(v._unicodePositionBuffer_getDataPointer=Y.unicodePositionBuffer_getDataPointer)(a);v._unicodePositionBuffer_free=a=>(v._unicodePositionBuffer_free=Y.unicodePositionBuffer_free)(a);v._lineBreakBuffer_create=a=>(v._lineBreakBuffer_create=Y.lineBreakBuffer_create)(a);
v._lineBreakBuffer_getDataPointer=a=>(v._lineBreakBuffer_getDataPointer=Y.lineBreakBuffer_getDataPointer)(a);v._lineBreakBuffer_free=a=>(v._lineBreakBuffer_free=Y.lineBreakBuffer_free)(a);v._paragraphBuilder_setGraphemeBreaksUtf16=(a,b)=>(v._paragraphBuilder_setGraphemeBreaksUtf16=Y.paragraphBuilder_setGraphemeBreaksUtf16)(a,b);v._paragraphBuilder_setWordBreaksUtf16=(a,b)=>(v._paragraphBuilder_setWordBreaksUtf16=Y.paragraphBuilder_setWordBreaksUtf16)(a,b);
v._paragraphBuilder_setLineBreaksUtf16=(a,b)=>(v._paragraphBuilder_setLineBreaksUtf16=Y.paragraphBuilder_setLineBreaksUtf16)(a,b);v._paragraphStyle_create=()=>(v._paragraphStyle_create=Y.paragraphStyle_create)();v._paragraphStyle_dispose=a=>(v._paragraphStyle_dispose=Y.paragraphStyle_dispose)(a);v._paragraphStyle_setTextAlign=(a,b)=>(v._paragraphStyle_setTextAlign=Y.paragraphStyle_setTextAlign)(a,b);
v._paragraphStyle_setTextDirection=(a,b)=>(v._paragraphStyle_setTextDirection=Y.paragraphStyle_setTextDirection)(a,b);v._paragraphStyle_setMaxLines=(a,b)=>(v._paragraphStyle_setMaxLines=Y.paragraphStyle_setMaxLines)(a,b);v._paragraphStyle_setHeight=(a,b)=>(v._paragraphStyle_setHeight=Y.paragraphStyle_setHeight)(a,b);v._paragraphStyle_setTextHeightBehavior=(a,b,c)=>(v._paragraphStyle_setTextHeightBehavior=Y.paragraphStyle_setTextHeightBehavior)(a,b,c);
v._paragraphStyle_setEllipsis=(a,b)=>(v._paragraphStyle_setEllipsis=Y.paragraphStyle_setEllipsis)(a,b);v._paragraphStyle_setStrutStyle=(a,b)=>(v._paragraphStyle_setStrutStyle=Y.paragraphStyle_setStrutStyle)(a,b);v._paragraphStyle_setTextStyle=(a,b)=>(v._paragraphStyle_setTextStyle=Y.paragraphStyle_setTextStyle)(a,b);v._paragraphStyle_setApplyRoundingHack=(a,b)=>(v._paragraphStyle_setApplyRoundingHack=Y.paragraphStyle_setApplyRoundingHack)(a,b);v._strutStyle_create=()=>(v._strutStyle_create=Y.strutStyle_create)();
v._strutStyle_dispose=a=>(v._strutStyle_dispose=Y.strutStyle_dispose)(a);v._strutStyle_setFontFamilies=(a,b,c)=>(v._strutStyle_setFontFamilies=Y.strutStyle_setFontFamilies)(a,b,c);v._strutStyle_setFontSize=(a,b)=>(v._strutStyle_setFontSize=Y.strutStyle_setFontSize)(a,b);v._strutStyle_setHeight=(a,b)=>(v._strutStyle_setHeight=Y.strutStyle_setHeight)(a,b);v._strutStyle_setHalfLeading=(a,b)=>(v._strutStyle_setHalfLeading=Y.strutStyle_setHalfLeading)(a,b);
v._strutStyle_setLeading=(a,b)=>(v._strutStyle_setLeading=Y.strutStyle_setLeading)(a,b);v._strutStyle_setFontStyle=(a,b,c)=>(v._strutStyle_setFontStyle=Y.strutStyle_setFontStyle)(a,b,c);v._strutStyle_setForceStrutHeight=(a,b)=>(v._strutStyle_setForceStrutHeight=Y.strutStyle_setForceStrutHeight)(a,b);v._textStyle_create=()=>(v._textStyle_create=Y.textStyle_create)();v._textStyle_copy=a=>(v._textStyle_copy=Y.textStyle_copy)(a);v._textStyle_dispose=a=>(v._textStyle_dispose=Y.textStyle_dispose)(a);
v._textStyle_setColor=(a,b)=>(v._textStyle_setColor=Y.textStyle_setColor)(a,b);v._textStyle_setDecoration=(a,b)=>(v._textStyle_setDecoration=Y.textStyle_setDecoration)(a,b);v._textStyle_setDecorationColor=(a,b)=>(v._textStyle_setDecorationColor=Y.textStyle_setDecorationColor)(a,b);v._textStyle_setDecorationStyle=(a,b)=>(v._textStyle_setDecorationStyle=Y.textStyle_setDecorationStyle)(a,b);
v._textStyle_setDecorationThickness=(a,b)=>(v._textStyle_setDecorationThickness=Y.textStyle_setDecorationThickness)(a,b);v._textStyle_setFontStyle=(a,b,c)=>(v._textStyle_setFontStyle=Y.textStyle_setFontStyle)(a,b,c);v._textStyle_setTextBaseline=(a,b)=>(v._textStyle_setTextBaseline=Y.textStyle_setTextBaseline)(a,b);v._textStyle_clearFontFamilies=a=>(v._textStyle_clearFontFamilies=Y.textStyle_clearFontFamilies)(a);
v._textStyle_addFontFamilies=(a,b,c)=>(v._textStyle_addFontFamilies=Y.textStyle_addFontFamilies)(a,b,c);v._textStyle_setFontSize=(a,b)=>(v._textStyle_setFontSize=Y.textStyle_setFontSize)(a,b);v._textStyle_setLetterSpacing=(a,b)=>(v._textStyle_setLetterSpacing=Y.textStyle_setLetterSpacing)(a,b);v._textStyle_setWordSpacing=(a,b)=>(v._textStyle_setWordSpacing=Y.textStyle_setWordSpacing)(a,b);v._textStyle_setHeight=(a,b)=>(v._textStyle_setHeight=Y.textStyle_setHeight)(a,b);
v._textStyle_setHalfLeading=(a,b)=>(v._textStyle_setHalfLeading=Y.textStyle_setHalfLeading)(a,b);v._textStyle_setLocale=(a,b)=>(v._textStyle_setLocale=Y.textStyle_setLocale)(a,b);v._textStyle_setBackground=(a,b)=>(v._textStyle_setBackground=Y.textStyle_setBackground)(a,b);v._textStyle_setForeground=(a,b)=>(v._textStyle_setForeground=Y.textStyle_setForeground)(a,b);v._textStyle_addShadow=(a,b,c,d,f)=>(v._textStyle_addShadow=Y.textStyle_addShadow)(a,b,c,d,f);
v._textStyle_addFontFeature=(a,b,c)=>(v._textStyle_addFontFeature=Y.textStyle_addFontFeature)(a,b,c);v._textStyle_setFontVariations=(a,b,c,d)=>(v._textStyle_setFontVariations=Y.textStyle_setFontVariations)(a,b,c,d);v._vertices_create=(a,b,c,d,f,g,l)=>(v._vertices_create=Y.vertices_create)(a,b,c,d,f,g,l);v._vertices_dispose=a=>(v._vertices_dispose=Y.vertices_dispose)(a);v._skwasm_isMultiThreaded=()=>(v._skwasm_isMultiThreaded=Y.skwasm_isMultiThreaded)();
var ya=()=>(ya=Y.pthread_self)(),xf=a=>(xf=Y.malloc)(a),Ba=(a,b,c,d,f,g)=>(Ba=Y._emscripten_thread_init)(a,b,c,d,f,g),Ha=()=>(Ha=Y._emscripten_thread_crashed)(),bf=(a,b,c,d,f)=>(bf=Y._emscripten_run_on_main_thread_js)(a,b,c,d,f),jf=a=>(jf=Y._emscripten_thread_free_data)(a),pf=a=>(pf=Y._emscripten_thread_exit)(a),Df=(a,b)=>(Df=Y._emscripten_timeout)(a,b),zf=()=>(zf=Y._emscripten_check_mailbox)(),Z=(a,b)=>(Z=Y.setThrew)(a,b),of=(a,b)=>(of=Y.emscripten_stack_set_limits)(a,b),G=a=>(G=Y._emscripten_stack_restore)(a),
$e=a=>($e=Y._emscripten_stack_alloc)(a),E=()=>(E=Y.emscripten_stack_get_current)();function xe(a,b,c){var d=E();try{return I.get(a)(b,c)}catch(f){G(d);if(f!==f+0)throw f;Z(1,0)}}function Ce(a,b,c){var d=E();try{I.get(a)(b,c)}catch(f){G(d);if(f!==f+0)throw f;Z(1,0)}}function we(a,b){var c=E();try{return I.get(a)(b)}catch(d){G(c);if(d!==d+0)throw d;Z(1,0)}}function De(a,b,c,d){var f=E();try{I.get(a)(b,c,d)}catch(g){G(f);if(g!==g+0)throw g;Z(1,0)}}
function ye(a,b,c,d){var f=E();try{return I.get(a)(b,c,d)}catch(g){G(f);if(g!==g+0)throw g;Z(1,0)}}function Ee(a,b,c,d,f){var g=E();try{I.get(a)(b,c,d,f)}catch(l){G(g);if(l!==l+0)throw l;Z(1,0)}}function Fe(a,b,c,d,f,g,l,m){var p=E();try{I.get(a)(b,c,d,f,g,l,m)}catch(r){G(p);if(r!==r+0)throw r;Z(1,0)}}function Be(a,b){var c=E();try{I.get(a)(b)}catch(d){G(c);if(d!==d+0)throw d;Z(1,0)}}function Ae(a,b,c,d,f,g,l){var m=E();try{return I.get(a)(b,c,d,f,g,l)}catch(p){G(m);if(p!==p+0)throw p;Z(1,0)}}
function ze(a,b,c,d,f){var g=E();try{return I.get(a)(b,c,d,f)}catch(l){G(g);if(l!==l+0)throw l;Z(1,0)}}v.wasmMemory=e;v.wasmExports=Y;v.stackAlloc=af;
v.addFunction=(a,b)=>{if(!mg){mg=new WeakMap;var c=I.length;if(mg)for(var d=0;d<0+c;d++){var f=I.get(d);f&&mg.set(f,d)}}if(c=mg.get(a)||0)return c;if(ng.length)c=ng.pop();else{try{I.grow(1)}catch(m){if(!(m instanceof RangeError))throw m;throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";}c=I.length-1}try{I.set(c,a)}catch(m){if(!(m instanceof TypeError))throw m;if("function"==typeof WebAssembly.Function){d=WebAssembly.Function;f={i:"i32",j:"i64",f:"f32",d:"f64",e:"externref",p:"i32"};for(var g=
{parameters:[],results:"v"==b[0]?[]:[f[b[0]]]},l=1;l<b.length;++l)g.parameters.push(f[b[l]]);b=new d(g,a)}else{d=[1];f=b.slice(0,1);b=b.slice(1);g={i:127,p:127,j:126,f:125,d:124,e:111};d.push(96);l=b.length;128>l?d.push(l):d.push(l%128|128,l>>7);for(l=0;l<b.length;++l)d.push(g[b[l]]);"v"==f?d.push(0):d.push(1,g[f]);b=[0,97,115,109,1,0,0,0,1];f=d.length;128>f?b.push(f):b.push(f%128|128,f>>7);b.push(...d);b.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);b=new WebAssembly.Module(new Uint8Array(b));b=(new WebAssembly.Instance(b,
{e:{f:a}})).exports.f}I.set(c,b)}mg.set(a,c);return c};var wg,xg;Ma=function yg(){wg||zg();wg||(Ma=yg)};function zg(){if(!(0<z))if(w)ia(v),w||nf(Ja),startWorker(v);else{if(!xg&&(xg=1,nf(Ia),0<z))return;wg||(wg=1,v.calledRun=1,sa||(w||nf(Ja),ia(v),w||nf(Ka)))}}zg();moduleRtn=ka;
return moduleRtn;
}
);
})();
export default skwasm;
var isPthread = globalThis.self?.name?.startsWith('em-pthread');
// When running as a pthread, construct a new instance on startup
isPthread && skwasm();

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,134 @@
var skwasm_st = (() => {
var _scriptName = typeof document != 'undefined' ? document.currentScript?.src : undefined;
return (
function(moduleArg = {}) {
var moduleRtn;
function d(){g.buffer!=k.buffer&&n();return k}function q(){g.buffer!=k.buffer&&n();return aa}function r(){g.buffer!=k.buffer&&n();return ba}function t(){g.buffer!=k.buffer&&n();return ca}function u(){g.buffer!=k.buffer&&n();return da}var w=moduleArg,ea,fa,ha=new Promise((a,b)=>{ea=a;fa=b}),ia="object"==typeof window,ja="function"==typeof importScripts,ka=Object.assign({},w),x="",la,ma;
if(ia||ja)ja?x=self.location.href:"undefined"!=typeof document&&document.currentScript&&(x=document.currentScript.src),_scriptName&&(x=_scriptName),x.startsWith("blob:")?x="":x=x.substr(0,x.replace(/[?#].*/,"").lastIndexOf("/")+1),ja&&(ma=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),la=a=>fetch(a,{credentials:"same-origin"}).then(b=>b.ok?b.arrayBuffer():Promise.reject(Error(b.status+" : "+b.url)));
var na=console.log.bind(console),y=console.error.bind(console);Object.assign(w,ka);ka=null;var g,oa=!1,pa,k,aa,qa,ra,ba,ca,da;function n(){var a=g.buffer;k=new Int8Array(a);qa=new Int16Array(a);aa=new Uint8Array(a);ra=new Uint16Array(a);ba=new Int32Array(a);ca=new Uint32Array(a);da=new Float32Array(a);new Float64Array(a)}var sa=[],ta=[],ua=[],z=0,va=null,A=null;
function wa(a){a="Aborted("+a+")";y(a);oa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");fa(a);throw a;}var xa=a=>a.startsWith("data:application/octet-stream;base64,"),ya;function za(a){return la(a).then(b=>new Uint8Array(b),()=>{if(ma)var b=ma(a);else throw"both async and sync fetching of the wasm failed";return b})}function Aa(a,b,c){return za(a).then(e=>WebAssembly.instantiate(e,b)).then(c,e=>{y(`failed to asynchronously prepare wasm: ${e}`);wa(e)})}
function Ba(a,b){var c=ya;return"function"!=typeof WebAssembly.instantiateStreaming||xa(c)||"function"!=typeof fetch?Aa(c,a,b):fetch(c,{credentials:"same-origin"}).then(e=>WebAssembly.instantiateStreaming(e,a).then(b,function(f){y(`wasm streaming compile failed: ${f}`);y("falling back to ArrayBuffer instantiation");return Aa(c,a,b)}))}function Ca(a){this.name="ExitStatus";this.message=`Program terminated with exit(${a})`;this.status=a}var Da=a=>{a.forEach(b=>b(w))},Ea=w.noExitRuntime||!0;
class Fa{constructor(a){this.s=a-24}}
var Ga=0,Ha=0,Ia="undefined"!=typeof TextDecoder?new TextDecoder:void 0,Ja=(a,b=0,c=NaN)=>{var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&Ia)return Ia.decode(a.slice(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|h);else{var l=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|l:(f&7)<<18|h<<12|l<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e},
Ka=(a,b)=>a?Ja(q(),a,b):"",B={},La=a=>{if(!(a instanceof Ca||"unwind"==a))throw a;},Ma=0,Na=a=>{pa=a;Ea||0<Ma||(oa=!0);throw new Ca(a);},Oa=a=>{if(!oa)try{if(a(),!(Ea||0<Ma))try{pa=a=pa,Na(a)}catch(b){La(b)}}catch(b){La(b)}},C=(a,b,c)=>{var e=q();if(0<c){var f=b;c=b+c-1;for(var h=0;h<a.length;++h){var l=a.charCodeAt(h);if(55296<=l&&57343>=l){var m=a.charCodeAt(++h);l=65536+((l&1023)<<10)|m&1023}if(127>=l){if(b>=c)break;e[b++]=l}else{if(2047>=l){if(b+1>=c)break;e[b++]=192|l>>6}else{if(65535>=l){if(b+
2>=c)break;e[b++]=224|l>>12}else{if(b+3>=c)break;e[b++]=240|l>>18;e[b++]=128|l>>12&63}e[b++]=128|l>>6&63}e[b++]=128|l&63}}e[b]=0;a=b-f}else a=0;return a},D,Pa=a=>{var b=a.getExtension("ANGLE_instanced_arrays");b&&(a.vertexAttribDivisor=(c,e)=>b.vertexAttribDivisorANGLE(c,e),a.drawArraysInstanced=(c,e,f,h)=>b.drawArraysInstancedANGLE(c,e,f,h),a.drawElementsInstanced=(c,e,f,h,l)=>b.drawElementsInstancedANGLE(c,e,f,h,l))},Qa=a=>{var b=a.getExtension("OES_vertex_array_object");b&&(a.createVertexArray=
()=>b.createVertexArrayOES(),a.deleteVertexArray=c=>b.deleteVertexArrayOES(c),a.bindVertexArray=c=>b.bindVertexArrayOES(c),a.isVertexArray=c=>b.isVertexArrayOES(c))},Ra=a=>{var b=a.getExtension("WEBGL_draw_buffers");b&&(a.drawBuffers=(c,e)=>b.drawBuffersWEBGL(c,e))},Sa=a=>{a.H=a.getExtension("WEBGL_draw_instanced_base_vertex_base_instance")},Ta=a=>{a.K=a.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance")},Ua=a=>{var b="ANGLE_instanced_arrays EXT_blend_minmax EXT_disjoint_timer_query EXT_frag_depth EXT_shader_texture_lod EXT_sRGB OES_element_index_uint OES_fbo_render_mipmap OES_standard_derivatives OES_texture_float OES_texture_half_float OES_texture_half_float_linear OES_vertex_array_object WEBGL_color_buffer_float WEBGL_depth_texture WEBGL_draw_buffers EXT_color_buffer_float EXT_conservative_depth EXT_disjoint_timer_query_webgl2 EXT_texture_norm16 NV_shader_noperspective_interpolation WEBGL_clip_cull_distance EXT_clip_control EXT_color_buffer_half_float EXT_depth_clamp EXT_float_blend EXT_polygon_offset_clamp EXT_texture_compression_bptc EXT_texture_compression_rgtc EXT_texture_filter_anisotropic KHR_parallel_shader_compile OES_texture_float_linear WEBGL_blend_func_extended WEBGL_compressed_texture_astc WEBGL_compressed_texture_etc WEBGL_compressed_texture_etc1 WEBGL_compressed_texture_s3tc WEBGL_compressed_texture_s3tc_srgb WEBGL_debug_renderer_info WEBGL_debug_shaders WEBGL_lose_context WEBGL_multi_draw WEBGL_polygon_mode".split(" ");
return(a.getSupportedExtensions()||[]).filter(c=>b.includes(c))},Va=1,Wa=[],E=[],Xa=[],F=[],G=[],H=[],Ya=[],Za=[],I=[],J=[],K=[],$a={},ab={},bb=4,cb=0,L=a=>{for(var b=Va++,c=a.length;c<b;c++)a[c]=null;return b},N=(a,b,c,e)=>{for(var f=0;f<a;f++){var h=D[c](),l=h&&L(e);h?(h.name=l,e[l]=h):M||=1282;r()[b+4*f>>2]=l}},eb=a=>{var b={J:2,alpha:!0,depth:!0,stencil:!0,antialias:!1,premultipliedAlpha:!0,preserveDrawingBuffer:!1,powerPreference:"default",failIfMajorPerformanceCaveat:!1,I:!0};a.s||(a.s=a.getContext,
a.getContext=function(e,f){f=a.s(e,f);return"webgl"==e==f instanceof WebGLRenderingContext?f:null});var c=1<b.J?a.getContext("webgl2",b):a.getContext("webgl",b);return c?db(c,b):0},db=(a,b)=>{var c=L(Za),e={handle:c,attributes:b,version:b.J,v:a};a.canvas&&(a.canvas.Z=e);Za[c]=e;("undefined"==typeof b.I||b.I)&&fb(e);return c},fb=a=>{a||=O;if(!a.S){a.S=!0;var b=a.v;b.T=b.getExtension("WEBGL_multi_draw");b.P=b.getExtension("EXT_polygon_offset_clamp");b.O=b.getExtension("EXT_clip_control");b.Y=b.getExtension("WEBGL_polygon_mode");
Pa(b);Qa(b);Ra(b);Sa(b);Ta(b);2<=a.version&&(b.g=b.getExtension("EXT_disjoint_timer_query_webgl2"));if(2>a.version||!b.g)b.g=b.getExtension("EXT_disjoint_timer_query");Ua(b).forEach(c=>{c.includes("lose_context")||c.includes("debug")||b.getExtension(c)})}},M,O,gb=a=>{D.bindVertexArray(Ya[a])},hb=(a,b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2],f=G[e];f&&(D.deleteTexture(f),f.name=0,G[e]=null)}},ib=(a,b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2];D.deleteVertexArray(Ya[e]);Ya[e]=null}},jb=[],kb=(a,
b)=>{N(a,b,"createVertexArray",Ya)},lb=(a,b)=>{t()[a>>2]=b;var c=t()[a>>2];t()[a+4>>2]=(b-c)/4294967296};function mb(){var a=Ua(D);return a=a.concat(a.map(b=>"GL_"+b))}
var nb=(a,b,c)=>{if(b){var e=void 0;switch(a){case 36346:e=1;break;case 36344:0!=c&&1!=c&&(M||=1280);return;case 34814:case 36345:e=0;break;case 34466:var f=D.getParameter(34467);e=f?f.length:0;break;case 33309:if(2>O.version){M||=1282;return}e=mb().length;break;case 33307:case 33308:if(2>O.version){M||=1280;return}e=33307==a?3:0}if(void 0===e)switch(f=D.getParameter(a),typeof f){case "number":e=f;break;case "boolean":e=f?1:0;break;case "string":M||=1280;return;case "object":if(null===f)switch(a){case 34964:case 35725:case 34965:case 36006:case 36007:case 32873:case 34229:case 36662:case 36663:case 35053:case 35055:case 36010:case 35097:case 35869:case 32874:case 36389:case 35983:case 35368:case 34068:e=
0;break;default:M||=1280;return}else{if(f instanceof Float32Array||f instanceof Uint32Array||f instanceof Int32Array||f instanceof Array){for(a=0;a<f.length;++a)switch(c){case 0:r()[b+4*a>>2]=f[a];break;case 2:u()[b+4*a>>2]=f[a];break;case 4:d()[b+a]=f[a]?1:0}return}try{e=f.name|0}catch(h){M||=1280;y(`GL_INVALID_ENUM in glGet${c}v: Unknown object returned from WebGL getParameter(${a})! (error: ${h})`);return}}break;default:M||=1280;y(`GL_INVALID_ENUM in glGet${c}v: Native code calling glGet${c}v(${a}) and it returns ${f} of type ${typeof f}!`);
return}switch(c){case 1:lb(b,e);break;case 0:r()[b>>2]=e;break;case 2:u()[b>>2]=e;break;case 4:d()[b]=e?1:0}}else M||=1281},ob=(a,b)=>nb(a,b,0),pb=(a,b,c)=>{if(c){a=I[a];b=2>O.version?D.g.getQueryObjectEXT(a,b):D.getQueryParameter(a,b);var e;"boolean"==typeof b?e=b?1:0:e=b;lb(c,e)}else M||=1281},rb=a=>{for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}b+=1;(c=qb(b))&&C(a,c,b);return c},sb=a=>{var b=$a[a];if(!b){switch(a){case 7939:b=rb(mb().join(" "));
break;case 7936:case 7937:case 37445:case 37446:(b=D.getParameter(a))||(M||=1280);b=b?rb(b):0;break;case 7938:b=D.getParameter(7938);var c=`OpenGL ES 2.0 (${b})`;2<=O.version&&(c=`OpenGL ES 3.0 (${b})`);b=rb(c);break;case 35724:b=D.getParameter(35724);c=b.match(/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/);null!==c&&(3==c[1].length&&(c[1]+="0"),b=`OpenGL ES GLSL ES ${c[1]} (${b})`);b=rb(b);break;default:M||=1280}$a[a]=b}return b},tb=(a,b)=>{if(2>O.version)return M||=1282,0;var c=ab[a];if(c)return 0>
b||b>=c.length?(M||=1281,0):c[b];switch(a){case 7939:return c=mb().map(rb),c=ab[a]=c,0>b||b>=c.length?(M||=1281,0):c[b];default:return M||=1280,0}},ub=a=>"]"==a.slice(-1)&&a.lastIndexOf("["),vb=a=>{a-=5120;0==a?a=d():1==a?a=q():2==a?(g.buffer!=k.buffer&&n(),a=qa):4==a?a=r():6==a?a=u():5==a||28922==a||28520==a||30779==a||30782==a?a=t():(g.buffer!=k.buffer&&n(),a=ra);return a},wb=(a,b,c,e,f)=>{a=vb(a);b=e*((cb||c)*({5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4}[b-6402]||1)*a.BYTES_PER_ELEMENT+
bb-1&-bb);return a.subarray(f>>>31-Math.clz32(a.BYTES_PER_ELEMENT),f+b>>>31-Math.clz32(a.BYTES_PER_ELEMENT))},P=a=>{var b=D.N;if(b){var c=b.u[a];"number"==typeof c&&(b.u[a]=c=D.getUniformLocation(b,b.L[a]+(0<c?`[${c}]`:"")));return c}M||=1282},Q=[],xb=[],yb={},Ab=()=>{if(!zb){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:"./this.program"},b;for(b in yb)void 0===
yb[b]?delete a[b]:a[b]=yb[b];var c=[];for(b in a)c.push(`${b}=${a[b]}`);zb=c}return zb},zb,Bb=[null,[],[]];function Cb(){}function Db(){}function R(){}function Eb(){}function Fb(){}function Gb(){}function Hb(){}function Ib(){}function Jb(){}function Kb(){}function Lb(){}function Mb(){}function Nb(){}function Ob(){}function Pb(){}function Qb(){}var S,U,Rb=[],Tb=a=>Sb(a);w.stackAlloc=Tb;for(var V=0;32>V;++V)jb.push(Array(V));var Ub=new Float32Array(288);for(V=0;288>=V;++V)Q[V]=Ub.subarray(0,V);
var Vb=new Int32Array(288);for(V=0;288>=V;++V)xb[V]=Vb.subarray(0,V);
(function(){const a=new Map,b=new Map;Qb=function(c,e,f){R({m:"setAssociatedObject",F:e,object:f})};Mb=function(c){return b.get(c)};Fb=function(){Cb(function(c){var e=c.m;if(e)switch(e){case "renderPictures":Wb(c.h,c.V,c.U,c.l,Db());break;case "onRenderComplete":Xb(c.h,c.l,{imageBitmaps:c.R,rasterStartMilliseconds:c.X,rasterEndMilliseconds:c.W});break;case "setAssociatedObject":b.set(c.F,c.object);break;case "disposeAssociatedObject":c=c.F;e=b.get(c);e.close&&e.close();b.delete(c);break;case "disposeSurface":Yb(c.h);
break;case "rasterizeImage":Zb(c.h,c.image,c.format,c.l);break;case "onRasterizeComplete":$b(c.h,c.data,c.l);break;default:console.warn(`unrecognized skwasm message: ${e}`)}})};Kb=function(c,e,f,h,l){R({m:"renderPictures",h:e,V:f,U:h,l})};Hb=function(c,e){c=new OffscreenCanvas(c,e);e=eb(c);a.set(e,c);return e};Ob=function(c,e,f){c=a.get(c);c.width=e;c.height=f};Eb=function(c,e,f,h){h||=[];c=a.get(c);h.push(createImageBitmap(c,0,0,e,f));return h};Pb=async function(c,e,f,h){e=e?await Promise.all(e):
[];R({m:"onRenderComplete",h:c,l:h,R:e,X:f,W:Db()},[...e])};Gb=function(c,e,f){const h=O.v,l=h.createTexture();h.bindTexture(h.TEXTURE_2D,l);h.pixelStorei(h.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);h.texImage2D(h.TEXTURE_2D,0,h.RGBA,e,f,0,h.RGBA,h.UNSIGNED_BYTE,c);h.pixelStorei(h.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);h.bindTexture(h.TEXTURE_2D,null);c=L(G);G[c]=l;return c};Lb=function(c,e){R({m:"disposeAssociatedObject",F:e})};Ib=function(c,e){R({m:"disposeSurface",h:e})};Jb=function(c,e,f,h,l){R({m:"rasterizeImage",
h:e,image:f,format:h,l})};Nb=function(c,e,f){R({m:"onRasterizeComplete",h:c,data:e,l:f})}})();(function(){let a;Cb=function(b){a=b};Db=function(){return performance.now()};R=function(b){queueMicrotask(()=>{a(b)})}})();
var lc={__cxa_throw:(a,b,c)=>{var e=new Fa(a);t()[e.s+16>>2]=0;t()[e.s+4>>2]=b;t()[e.s+8>>2]=c;Ga=a;Ha++;throw Ga;},__syscall_fcntl64:function(){return 0},__syscall_fstat64:()=>{},__syscall_ioctl:function(){return 0},__syscall_openat:function(){},_abort_js:()=>{wa("")},_emscripten_get_now_is_monotonic:()=>1,_emscripten_runtime_keepalive_clear:()=>{Ea=!1;Ma=0},_emscripten_throw_longjmp:()=>{throw Infinity;},_mmap_js:function(){return-52},_munmap_js:function(){},_setitimer_js:(a,b)=>{B[a]&&(clearTimeout(B[a].id),
delete B[a]);if(!b)return 0;var c=setTimeout(()=>{delete B[a];Oa(()=>ac(a,performance.now()))},b);B[a]={id:c,aa:b};return 0},_tzset_js:(a,b,c,e)=>{var f=(new Date).getFullYear(),h=(new Date(f,0,1)).getTimezoneOffset();f=(new Date(f,6,1)).getTimezoneOffset();var l=Math.max(h,f);t()[a>>2]=60*l;r()[b>>2]=Number(h!=f);b=m=>{var p=Math.abs(m);return`UTC${0<=m?"-":"+"}${String(Math.floor(p/60)).padStart(2,"0")}${String(p%60).padStart(2,"0")}`};a=b(h);b=b(f);f<h?(C(a,c,17),C(b,e,17)):(C(a,e,17),C(b,c,17))},
emscripten_get_now:()=>performance.now(),emscripten_glActiveTexture:a=>D.activeTexture(a),emscripten_glAttachShader:(a,b)=>{D.attachShader(E[a],H[b])},emscripten_glBeginQuery:(a,b)=>{D.beginQuery(a,I[b])},emscripten_glBeginQueryEXT:(a,b)=>{D.g.beginQueryEXT(a,I[b])},emscripten_glBindAttribLocation:(a,b,c)=>{D.bindAttribLocation(E[a],b,Ka(c))},emscripten_glBindBuffer:(a,b)=>{35051==a?D.D=b:35052==a&&(D.o=b);D.bindBuffer(a,Wa[b])},emscripten_glBindFramebuffer:(a,b)=>{D.bindFramebuffer(a,Xa[b])},emscripten_glBindRenderbuffer:(a,
b)=>{D.bindRenderbuffer(a,F[b])},emscripten_glBindSampler:(a,b)=>{D.bindSampler(a,J[b])},emscripten_glBindTexture:(a,b)=>{D.bindTexture(a,G[b])},emscripten_glBindVertexArray:gb,emscripten_glBindVertexArrayOES:gb,emscripten_glBlendColor:(a,b,c,e)=>D.blendColor(a,b,c,e),emscripten_glBlendEquation:a=>D.blendEquation(a),emscripten_glBlendFunc:(a,b)=>D.blendFunc(a,b),emscripten_glBlitFramebuffer:(a,b,c,e,f,h,l,m,p,v)=>D.blitFramebuffer(a,b,c,e,f,h,l,m,p,v),emscripten_glBufferData:(a,b,c,e)=>{2<=O.version?
c&&b?D.bufferData(a,q(),e,c,b):D.bufferData(a,b,e):D.bufferData(a,c?q().subarray(c,c+b):b,e)},emscripten_glBufferSubData:(a,b,c,e)=>{2<=O.version?c&&D.bufferSubData(a,b,q(),e,c):D.bufferSubData(a,b,q().subarray(e,e+c))},emscripten_glCheckFramebufferStatus:a=>D.checkFramebufferStatus(a),emscripten_glClear:a=>D.clear(a),emscripten_glClearColor:(a,b,c,e)=>D.clearColor(a,b,c,e),emscripten_glClearStencil:a=>D.clearStencil(a),emscripten_glClientWaitSync:(a,b,c,e)=>D.clientWaitSync(K[a],b,(c>>>0)+4294967296*
e),emscripten_glColorMask:(a,b,c,e)=>{D.colorMask(!!a,!!b,!!c,!!e)},emscripten_glCompileShader:a=>{D.compileShader(H[a])},emscripten_glCompressedTexImage2D:(a,b,c,e,f,h,l,m)=>{2<=O.version?D.o||!l?D.compressedTexImage2D(a,b,c,e,f,h,l,m):D.compressedTexImage2D(a,b,c,e,f,h,q(),m,l):D.compressedTexImage2D(a,b,c,e,f,h,q().subarray(m,m+l))},emscripten_glCompressedTexSubImage2D:(a,b,c,e,f,h,l,m,p)=>{2<=O.version?D.o||!m?D.compressedTexSubImage2D(a,b,c,e,f,h,l,m,p):D.compressedTexSubImage2D(a,b,c,e,f,h,
l,q(),p,m):D.compressedTexSubImage2D(a,b,c,e,f,h,l,q().subarray(p,p+m))},emscripten_glCopyBufferSubData:(a,b,c,e,f)=>D.copyBufferSubData(a,b,c,e,f),emscripten_glCopyTexSubImage2D:(a,b,c,e,f,h,l,m)=>D.copyTexSubImage2D(a,b,c,e,f,h,l,m),emscripten_glCreateProgram:()=>{var a=L(E),b=D.createProgram();b.name=a;b.C=b.A=b.B=0;b.G=1;E[a]=b;return a},emscripten_glCreateShader:a=>{var b=L(H);H[b]=D.createShader(a);return b},emscripten_glCullFace:a=>D.cullFace(a),emscripten_glDeleteBuffers:(a,b)=>{for(var c=
0;c<a;c++){var e=r()[b+4*c>>2],f=Wa[e];f&&(D.deleteBuffer(f),f.name=0,Wa[e]=null,e==D.D&&(D.D=0),e==D.o&&(D.o=0))}},emscripten_glDeleteFramebuffers:(a,b)=>{for(var c=0;c<a;++c){var e=r()[b+4*c>>2],f=Xa[e];f&&(D.deleteFramebuffer(f),f.name=0,Xa[e]=null)}},emscripten_glDeleteProgram:a=>{if(a){var b=E[a];b?(D.deleteProgram(b),b.name=0,E[a]=null):M||=1281}},emscripten_glDeleteQueries:(a,b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2],f=I[e];f&&(D.deleteQuery(f),I[e]=null)}},emscripten_glDeleteQueriesEXT:(a,
b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2],f=I[e];f&&(D.g.deleteQueryEXT(f),I[e]=null)}},emscripten_glDeleteRenderbuffers:(a,b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2],f=F[e];f&&(D.deleteRenderbuffer(f),f.name=0,F[e]=null)}},emscripten_glDeleteSamplers:(a,b)=>{for(var c=0;c<a;c++){var e=r()[b+4*c>>2],f=J[e];f&&(D.deleteSampler(f),f.name=0,J[e]=null)}},emscripten_glDeleteShader:a=>{if(a){var b=H[a];b?(D.deleteShader(b),H[a]=null):M||=1281}},emscripten_glDeleteSync:a=>{if(a){var b=K[a];b?(D.deleteSync(b),
b.name=0,K[a]=null):M||=1281}},emscripten_glDeleteTextures:hb,emscripten_glDeleteVertexArrays:ib,emscripten_glDeleteVertexArraysOES:ib,emscripten_glDepthMask:a=>{D.depthMask(!!a)},emscripten_glDisable:a=>D.disable(a),emscripten_glDisableVertexAttribArray:a=>{D.disableVertexAttribArray(a)},emscripten_glDrawArrays:(a,b,c)=>{D.drawArrays(a,b,c)},emscripten_glDrawArraysInstanced:(a,b,c,e)=>{D.drawArraysInstanced(a,b,c,e)},emscripten_glDrawArraysInstancedBaseInstanceWEBGL:(a,b,c,e,f)=>{D.H.drawArraysInstancedBaseInstanceWEBGL(a,
b,c,e,f)},emscripten_glDrawBuffers:(a,b)=>{for(var c=jb[a],e=0;e<a;e++)c[e]=r()[b+4*e>>2];D.drawBuffers(c)},emscripten_glDrawElements:(a,b,c,e)=>{D.drawElements(a,b,c,e)},emscripten_glDrawElementsInstanced:(a,b,c,e,f)=>{D.drawElementsInstanced(a,b,c,e,f)},emscripten_glDrawElementsInstancedBaseVertexBaseInstanceWEBGL:(a,b,c,e,f,h,l)=>{D.H.drawElementsInstancedBaseVertexBaseInstanceWEBGL(a,b,c,e,f,h,l)},emscripten_glDrawRangeElements:(a,b,c,e,f,h)=>{D.drawElements(a,e,f,h)},emscripten_glEnable:a=>D.enable(a),
emscripten_glEnableVertexAttribArray:a=>{D.enableVertexAttribArray(a)},emscripten_glEndQuery:a=>D.endQuery(a),emscripten_glEndQueryEXT:a=>{D.g.endQueryEXT(a)},emscripten_glFenceSync:(a,b)=>(a=D.fenceSync(a,b))?(b=L(K),a.name=b,K[b]=a,b):0,emscripten_glFinish:()=>D.finish(),emscripten_glFlush:()=>D.flush(),emscripten_glFramebufferRenderbuffer:(a,b,c,e)=>{D.framebufferRenderbuffer(a,b,c,F[e])},emscripten_glFramebufferTexture2D:(a,b,c,e,f)=>{D.framebufferTexture2D(a,b,c,G[e],f)},emscripten_glFrontFace:a=>
D.frontFace(a),emscripten_glGenBuffers:(a,b)=>{N(a,b,"createBuffer",Wa)},emscripten_glGenFramebuffers:(a,b)=>{N(a,b,"createFramebuffer",Xa)},emscripten_glGenQueries:(a,b)=>{N(a,b,"createQuery",I)},emscripten_glGenQueriesEXT:(a,b)=>{for(var c=0;c<a;c++){var e=D.g.createQueryEXT();if(!e){for(M||=1282;c<a;)r()[b+4*c++>>2]=0;break}var f=L(I);e.name=f;I[f]=e;r()[b+4*c>>2]=f}},emscripten_glGenRenderbuffers:(a,b)=>{N(a,b,"createRenderbuffer",F)},emscripten_glGenSamplers:(a,b)=>{N(a,b,"createSampler",J)},
emscripten_glGenTextures:(a,b)=>{N(a,b,"createTexture",G)},emscripten_glGenVertexArrays:kb,emscripten_glGenVertexArraysOES:kb,emscripten_glGenerateMipmap:a=>D.generateMipmap(a),emscripten_glGetBufferParameteriv:(a,b,c)=>{c?r()[c>>2]=D.getBufferParameter(a,b):M||=1281},emscripten_glGetError:()=>{var a=D.getError()||M;M=0;return a},emscripten_glGetFloatv:(a,b)=>nb(a,b,2),emscripten_glGetFramebufferAttachmentParameteriv:(a,b,c,e)=>{a=D.getFramebufferAttachmentParameter(a,b,c);if(a instanceof WebGLRenderbuffer||
a instanceof WebGLTexture)a=a.name|0;r()[e>>2]=a},emscripten_glGetIntegerv:ob,emscripten_glGetProgramInfoLog:(a,b,c,e)=>{a=D.getProgramInfoLog(E[a]);null===a&&(a="(unknown error)");b=0<b&&e?C(a,e,b):0;c&&(r()[c>>2]=b)},emscripten_glGetProgramiv:(a,b,c)=>{if(c)if(a>=Va)M||=1281;else if(a=E[a],35716==b)a=D.getProgramInfoLog(a),null===a&&(a="(unknown error)"),r()[c>>2]=a.length+1;else if(35719==b){if(!a.C){var e=D.getProgramParameter(a,35718);for(b=0;b<e;++b)a.C=Math.max(a.C,D.getActiveUniform(a,b).name.length+
1)}r()[c>>2]=a.C}else if(35722==b){if(!a.A)for(e=D.getProgramParameter(a,35721),b=0;b<e;++b)a.A=Math.max(a.A,D.getActiveAttrib(a,b).name.length+1);r()[c>>2]=a.A}else if(35381==b){if(!a.B)for(e=D.getProgramParameter(a,35382),b=0;b<e;++b)a.B=Math.max(a.B,D.getActiveUniformBlockName(a,b).length+1);r()[c>>2]=a.B}else r()[c>>2]=D.getProgramParameter(a,b);else M||=1281},emscripten_glGetQueryObjecti64vEXT:pb,emscripten_glGetQueryObjectui64vEXT:pb,emscripten_glGetQueryObjectuiv:(a,b,c)=>{if(c){a=D.getQueryParameter(I[a],
b);var e;"boolean"==typeof a?e=a?1:0:e=a;r()[c>>2]=e}else M||=1281},emscripten_glGetQueryObjectuivEXT:(a,b,c)=>{if(c){a=D.g.getQueryObjectEXT(I[a],b);var e;"boolean"==typeof a?e=a?1:0:e=a;r()[c>>2]=e}else M||=1281},emscripten_glGetQueryiv:(a,b,c)=>{c?r()[c>>2]=D.getQuery(a,b):M||=1281},emscripten_glGetQueryivEXT:(a,b,c)=>{c?r()[c>>2]=D.g.getQueryEXT(a,b):M||=1281},emscripten_glGetRenderbufferParameteriv:(a,b,c)=>{c?r()[c>>2]=D.getRenderbufferParameter(a,b):M||=1281},emscripten_glGetShaderInfoLog:(a,
b,c,e)=>{a=D.getShaderInfoLog(H[a]);null===a&&(a="(unknown error)");b=0<b&&e?C(a,e,b):0;c&&(r()[c>>2]=b)},emscripten_glGetShaderPrecisionFormat:(a,b,c,e)=>{a=D.getShaderPrecisionFormat(a,b);r()[c>>2]=a.rangeMin;r()[c+4>>2]=a.rangeMax;r()[e>>2]=a.precision},emscripten_glGetShaderiv:(a,b,c)=>{c?35716==b?(a=D.getShaderInfoLog(H[a]),null===a&&(a="(unknown error)"),a=a?a.length+1:0,r()[c>>2]=a):35720==b?(a=(a=D.getShaderSource(H[a]))?a.length+1:0,r()[c>>2]=a):r()[c>>2]=D.getShaderParameter(H[a],b):M||=
1281},emscripten_glGetString:sb,emscripten_glGetStringi:tb,emscripten_glGetUniformLocation:(a,b)=>{b=Ka(b);if(a=E[a]){var c=a,e=c.u,f=c.M,h;if(!e){c.u=e={};c.L={};var l=D.getProgramParameter(c,35718);for(h=0;h<l;++h){var m=D.getActiveUniform(c,h);var p=m.name;m=m.size;var v=ub(p);v=0<v?p.slice(0,v):p;var T=c.G;c.G+=m;f[v]=[m,T];for(p=0;p<m;++p)e[T]=p,c.L[T++]=v}}c=a.u;e=0;f=b;h=ub(b);0<h&&(e=parseInt(b.slice(h+1))>>>0,f=b.slice(0,h));if((f=a.M[f])&&e<f[0]&&(e+=f[1],c[e]=c[e]||D.getUniformLocation(a,
b)))return e}else M||=1281;return-1},emscripten_glInvalidateFramebuffer:(a,b,c)=>{for(var e=jb[b],f=0;f<b;f++)e[f]=r()[c+4*f>>2];D.invalidateFramebuffer(a,e)},emscripten_glInvalidateSubFramebuffer:(a,b,c,e,f,h,l)=>{for(var m=jb[b],p=0;p<b;p++)m[p]=r()[c+4*p>>2];D.invalidateSubFramebuffer(a,m,e,f,h,l)},emscripten_glIsSync:a=>D.isSync(K[a]),emscripten_glIsTexture:a=>(a=G[a])?D.isTexture(a):0,emscripten_glLineWidth:a=>D.lineWidth(a),emscripten_glLinkProgram:a=>{a=E[a];D.linkProgram(a);a.u=0;a.M={}},
emscripten_glMultiDrawArraysInstancedBaseInstanceWEBGL:(a,b,c,e,f,h)=>{D.K.multiDrawArraysInstancedBaseInstanceWEBGL(a,r(),b>>2,r(),c>>2,r(),e>>2,t(),f>>2,h)},emscripten_glMultiDrawElementsInstancedBaseVertexBaseInstanceWEBGL:(a,b,c,e,f,h,l,m)=>{D.K.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(a,r(),b>>2,c,r(),e>>2,r(),f>>2,r(),h>>2,t(),l>>2,m)},emscripten_glPixelStorei:(a,b)=>{3317==a?bb=b:3314==a&&(cb=b);D.pixelStorei(a,b)},emscripten_glQueryCounterEXT:(a,b)=>{D.g.queryCounterEXT(I[a],
b)},emscripten_glReadBuffer:a=>D.readBuffer(a),emscripten_glReadPixels:(a,b,c,e,f,h,l)=>{if(2<=O.version)if(D.D)D.readPixels(a,b,c,e,f,h,l);else{var m=vb(h);l>>>=31-Math.clz32(m.BYTES_PER_ELEMENT);D.readPixels(a,b,c,e,f,h,m,l)}else(m=wb(h,f,c,e,l))?D.readPixels(a,b,c,e,f,h,m):M||=1280},emscripten_glRenderbufferStorage:(a,b,c,e)=>D.renderbufferStorage(a,b,c,e),emscripten_glRenderbufferStorageMultisample:(a,b,c,e,f)=>D.renderbufferStorageMultisample(a,b,c,e,f),emscripten_glSamplerParameterf:(a,b,c)=>
{D.samplerParameterf(J[a],b,c)},emscripten_glSamplerParameteri:(a,b,c)=>{D.samplerParameteri(J[a],b,c)},emscripten_glSamplerParameteriv:(a,b,c)=>{c=r()[c>>2];D.samplerParameteri(J[a],b,c)},emscripten_glScissor:(a,b,c,e)=>D.scissor(a,b,c,e),emscripten_glShaderSource:(a,b,c,e)=>{for(var f="",h=0;h<b;++h){var l=e?t()[e+4*h>>2]:void 0;f+=Ka(t()[c+4*h>>2],l)}D.shaderSource(H[a],f)},emscripten_glStencilFunc:(a,b,c)=>D.stencilFunc(a,b,c),emscripten_glStencilFuncSeparate:(a,b,c,e)=>D.stencilFuncSeparate(a,
b,c,e),emscripten_glStencilMask:a=>D.stencilMask(a),emscripten_glStencilMaskSeparate:(a,b)=>D.stencilMaskSeparate(a,b),emscripten_glStencilOp:(a,b,c)=>D.stencilOp(a,b,c),emscripten_glStencilOpSeparate:(a,b,c,e)=>D.stencilOpSeparate(a,b,c,e),emscripten_glTexImage2D:(a,b,c,e,f,h,l,m,p)=>{if(2<=O.version){if(D.o){D.texImage2D(a,b,c,e,f,h,l,m,p);return}if(p){var v=vb(m);p>>>=31-Math.clz32(v.BYTES_PER_ELEMENT);D.texImage2D(a,b,c,e,f,h,l,m,v,p);return}}v=p?wb(m,l,e,f,p):null;D.texImage2D(a,b,c,e,f,h,l,
m,v)},emscripten_glTexParameterf:(a,b,c)=>D.texParameterf(a,b,c),emscripten_glTexParameterfv:(a,b,c)=>{c=u()[c>>2];D.texParameterf(a,b,c)},emscripten_glTexParameteri:(a,b,c)=>D.texParameteri(a,b,c),emscripten_glTexParameteriv:(a,b,c)=>{c=r()[c>>2];D.texParameteri(a,b,c)},emscripten_glTexStorage2D:(a,b,c,e,f)=>D.texStorage2D(a,b,c,e,f),emscripten_glTexSubImage2D:(a,b,c,e,f,h,l,m,p)=>{if(2<=O.version){if(D.o){D.texSubImage2D(a,b,c,e,f,h,l,m,p);return}if(p){var v=vb(m);D.texSubImage2D(a,b,c,e,f,h,l,
m,v,p>>>31-Math.clz32(v.BYTES_PER_ELEMENT));return}}p=p?wb(m,l,f,h,p):null;D.texSubImage2D(a,b,c,e,f,h,l,m,p)},emscripten_glUniform1f:(a,b)=>{D.uniform1f(P(a),b)},emscripten_glUniform1fv:(a,b,c)=>{if(2<=O.version)b&&D.uniform1fv(P(a),u(),c>>2,b);else{if(288>=b)for(var e=Q[b],f=0;f<b;++f)e[f]=u()[c+4*f>>2];else e=u().subarray(c>>2,c+4*b>>2);D.uniform1fv(P(a),e)}},emscripten_glUniform1i:(a,b)=>{D.uniform1i(P(a),b)},emscripten_glUniform1iv:(a,b,c)=>{if(2<=O.version)b&&D.uniform1iv(P(a),r(),c>>2,b);else{if(288>=
b)for(var e=xb[b],f=0;f<b;++f)e[f]=r()[c+4*f>>2];else e=r().subarray(c>>2,c+4*b>>2);D.uniform1iv(P(a),e)}},emscripten_glUniform2f:(a,b,c)=>{D.uniform2f(P(a),b,c)},emscripten_glUniform2fv:(a,b,c)=>{if(2<=O.version)b&&D.uniform2fv(P(a),u(),c>>2,2*b);else{if(144>=b){b*=2;for(var e=Q[b],f=0;f<b;f+=2)e[f]=u()[c+4*f>>2],e[f+1]=u()[c+(4*f+4)>>2]}else e=u().subarray(c>>2,c+8*b>>2);D.uniform2fv(P(a),e)}},emscripten_glUniform2i:(a,b,c)=>{D.uniform2i(P(a),b,c)},emscripten_glUniform2iv:(a,b,c)=>{if(2<=O.version)b&&
D.uniform2iv(P(a),r(),c>>2,2*b);else{if(144>=b){b*=2;for(var e=xb[b],f=0;f<b;f+=2)e[f]=r()[c+4*f>>2],e[f+1]=r()[c+(4*f+4)>>2]}else e=r().subarray(c>>2,c+8*b>>2);D.uniform2iv(P(a),e)}},emscripten_glUniform3f:(a,b,c,e)=>{D.uniform3f(P(a),b,c,e)},emscripten_glUniform3fv:(a,b,c)=>{if(2<=O.version)b&&D.uniform3fv(P(a),u(),c>>2,3*b);else{if(96>=b){b*=3;for(var e=Q[b],f=0;f<b;f+=3)e[f]=u()[c+4*f>>2],e[f+1]=u()[c+(4*f+4)>>2],e[f+2]=u()[c+(4*f+8)>>2]}else e=u().subarray(c>>2,c+12*b>>2);D.uniform3fv(P(a),e)}},
emscripten_glUniform3i:(a,b,c,e)=>{D.uniform3i(P(a),b,c,e)},emscripten_glUniform3iv:(a,b,c)=>{if(2<=O.version)b&&D.uniform3iv(P(a),r(),c>>2,3*b);else{if(96>=b){b*=3;for(var e=xb[b],f=0;f<b;f+=3)e[f]=r()[c+4*f>>2],e[f+1]=r()[c+(4*f+4)>>2],e[f+2]=r()[c+(4*f+8)>>2]}else e=r().subarray(c>>2,c+12*b>>2);D.uniform3iv(P(a),e)}},emscripten_glUniform4f:(a,b,c,e,f)=>{D.uniform4f(P(a),b,c,e,f)},emscripten_glUniform4fv:(a,b,c)=>{if(2<=O.version)b&&D.uniform4fv(P(a),u(),c>>2,4*b);else{if(72>=b){var e=Q[4*b],f=
u();c>>=2;b*=4;for(var h=0;h<b;h+=4){var l=c+h;e[h]=f[l];e[h+1]=f[l+1];e[h+2]=f[l+2];e[h+3]=f[l+3]}}else e=u().subarray(c>>2,c+16*b>>2);D.uniform4fv(P(a),e)}},emscripten_glUniform4i:(a,b,c,e,f)=>{D.uniform4i(P(a),b,c,e,f)},emscripten_glUniform4iv:(a,b,c)=>{if(2<=O.version)b&&D.uniform4iv(P(a),r(),c>>2,4*b);else{if(72>=b){b*=4;for(var e=xb[b],f=0;f<b;f+=4)e[f]=r()[c+4*f>>2],e[f+1]=r()[c+(4*f+4)>>2],e[f+2]=r()[c+(4*f+8)>>2],e[f+3]=r()[c+(4*f+12)>>2]}else e=r().subarray(c>>2,c+16*b>>2);D.uniform4iv(P(a),
e)}},emscripten_glUniformMatrix2fv:(a,b,c,e)=>{if(2<=O.version)b&&D.uniformMatrix2fv(P(a),!!c,u(),e>>2,4*b);else{if(72>=b){b*=4;for(var f=Q[b],h=0;h<b;h+=4)f[h]=u()[e+4*h>>2],f[h+1]=u()[e+(4*h+4)>>2],f[h+2]=u()[e+(4*h+8)>>2],f[h+3]=u()[e+(4*h+12)>>2]}else f=u().subarray(e>>2,e+16*b>>2);D.uniformMatrix2fv(P(a),!!c,f)}},emscripten_glUniformMatrix3fv:(a,b,c,e)=>{if(2<=O.version)b&&D.uniformMatrix3fv(P(a),!!c,u(),e>>2,9*b);else{if(32>=b){b*=9;for(var f=Q[b],h=0;h<b;h+=9)f[h]=u()[e+4*h>>2],f[h+1]=u()[e+
(4*h+4)>>2],f[h+2]=u()[e+(4*h+8)>>2],f[h+3]=u()[e+(4*h+12)>>2],f[h+4]=u()[e+(4*h+16)>>2],f[h+5]=u()[e+(4*h+20)>>2],f[h+6]=u()[e+(4*h+24)>>2],f[h+7]=u()[e+(4*h+28)>>2],f[h+8]=u()[e+(4*h+32)>>2]}else f=u().subarray(e>>2,e+36*b>>2);D.uniformMatrix3fv(P(a),!!c,f)}},emscripten_glUniformMatrix4fv:(a,b,c,e)=>{if(2<=O.version)b&&D.uniformMatrix4fv(P(a),!!c,u(),e>>2,16*b);else{if(18>=b){var f=Q[16*b],h=u();e>>=2;b*=16;for(var l=0;l<b;l+=16){var m=e+l;f[l]=h[m];f[l+1]=h[m+1];f[l+2]=h[m+2];f[l+3]=h[m+3];f[l+
4]=h[m+4];f[l+5]=h[m+5];f[l+6]=h[m+6];f[l+7]=h[m+7];f[l+8]=h[m+8];f[l+9]=h[m+9];f[l+10]=h[m+10];f[l+11]=h[m+11];f[l+12]=h[m+12];f[l+13]=h[m+13];f[l+14]=h[m+14];f[l+15]=h[m+15]}}else f=u().subarray(e>>2,e+64*b>>2);D.uniformMatrix4fv(P(a),!!c,f)}},emscripten_glUseProgram:a=>{a=E[a];D.useProgram(a);D.N=a},emscripten_glVertexAttrib1f:(a,b)=>D.vertexAttrib1f(a,b),emscripten_glVertexAttrib2fv:(a,b)=>{D.vertexAttrib2f(a,u()[b>>2],u()[b+4>>2])},emscripten_glVertexAttrib3fv:(a,b)=>{D.vertexAttrib3f(a,u()[b>>
2],u()[b+4>>2],u()[b+8>>2])},emscripten_glVertexAttrib4fv:(a,b)=>{D.vertexAttrib4f(a,u()[b>>2],u()[b+4>>2],u()[b+8>>2],u()[b+12>>2])},emscripten_glVertexAttribDivisor:(a,b)=>{D.vertexAttribDivisor(a,b)},emscripten_glVertexAttribIPointer:(a,b,c,e,f)=>{D.vertexAttribIPointer(a,b,c,e,f)},emscripten_glVertexAttribPointer:(a,b,c,e,f,h)=>{D.vertexAttribPointer(a,b,c,!!e,f,h)},emscripten_glViewport:(a,b,c,e)=>D.viewport(a,b,c,e),emscripten_glWaitSync:(a,b,c,e)=>{D.waitSync(K[a],b,(c>>>0)+4294967296*e)},
emscripten_resize_heap:a=>{var b=q().length;a>>>=0;if(a<=b||2147483648<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);a:{e=(Math.min(2147483648,65536*Math.ceil(Math.max(a,e)/65536))-g.buffer.byteLength+65535)/65536|0;try{g.grow(e);n();var f=1;break a}catch(h){}f=void 0}if(f)return!0}return!1},emscripten_webgl_enable_extension:function(a,b){a=Za[a];b=Ka(b);b.startsWith("GL_")&&(b=b.substr(3));"ANGLE_instanced_arrays"==b&&Pa(D);"OES_vertex_array_object"==b&&Qa(D);"WEBGL_draw_buffers"==
b&&Ra(D);"WEBGL_draw_instanced_base_vertex_base_instance"==b&&Sa(D);"WEBGL_multi_draw_instanced_base_vertex_base_instance"==b&&Ta(D);"WEBGL_multi_draw"==b&&(D.T=D.getExtension("WEBGL_multi_draw"));"EXT_polygon_offset_clamp"==b&&(D.P=D.getExtension("EXT_polygon_offset_clamp"));"EXT_clip_control"==b&&(D.O=D.getExtension("EXT_clip_control"));"WEBGL_polygon_mode"==b&&(D.Y=D.getExtension("WEBGL_polygon_mode"));return!!a.v.getExtension(b)},emscripten_webgl_get_current_context:()=>O?O.handle:0,emscripten_webgl_make_context_current:a=>
{O=Za[a];w.$=D=O?.v;return!a||D?0:-5},environ_get:(a,b)=>{var c=0;Ab().forEach((e,f)=>{var h=b+c;f=t()[a+4*f>>2]=h;for(h=0;h<e.length;++h)d()[f++]=e.charCodeAt(h);d()[f]=0;c+=e.length+1});return 0},environ_sizes_get:(a,b)=>{var c=Ab();t()[a>>2]=c.length;var e=0;c.forEach(f=>e+=f.length+1);t()[b>>2]=e;return 0},fd_close:()=>52,fd_pread:function(){return 52},fd_read:()=>52,fd_seek:function(){return 70},fd_write:(a,b,c,e)=>{for(var f=0,h=0;h<c;h++){var l=t()[b>>2],m=t()[b+4>>2];b+=8;for(var p=0;p<m;p++){var v=
q()[l+p],T=Bb[a];0===v||10===v?((1===a?na:y)(Ja(T)),T.length=0):T.push(v)}f+=m}t()[e>>2]=f;return 0},glDeleteTextures:hb,glGetIntegerv:ob,glGetString:sb,glGetStringi:tb,invoke_ii:bc,invoke_iii:cc,invoke_iiii:dc,invoke_iiiii:ec,invoke_iiiiiii:fc,invoke_vi:gc,invoke_vii:hc,invoke_viii:ic,invoke_viiii:jc,invoke_viiiiiii:kc,proc_exit:Na,skwasm_captureImageBitmap:Eb,skwasm_connectThread:Fb,skwasm_createGlTextureFromTextureSource:Gb,skwasm_createOffscreenCanvas:Hb,skwasm_dispatchDisposeSurface:Ib,skwasm_dispatchRasterizeImage:Jb,
skwasm_dispatchRenderPictures:Kb,skwasm_disposeAssociatedObjectOnThread:Lb,skwasm_getAssociatedObject:Mb,skwasm_postRasterizeResult:Nb,skwasm_resizeCanvas:Ob,skwasm_resolveAndPostImages:Pb,skwasm_setAssociatedObjectOnThread:Qb},W=function(){function a(c){W=c.exports;w.wasmExports=W;g=W.memory;w.wasmMemory=g;n();S=W.__indirect_function_table;ta.unshift(W.__wasm_call_ctors);z--;0==z&&(null!==va&&(clearInterval(va),va=null),A&&(c=A,A=null,c()));return W}var b={env:lc,wasi_snapshot_preview1:lc};z++;if(w.instantiateWasm)try{return w.instantiateWasm(b,
a)}catch(c){y(`Module.instantiateWasm callback failed with error: ${c}`),fa(c)}ya??=xa("skwasm_st.wasm")?"skwasm_st.wasm":x+"skwasm_st.wasm";Ba(b,function(c){a(c.instance,c.module)}).catch(fa);return{}}();w._canvas_saveLayer=(a,b,c,e,f)=>(w._canvas_saveLayer=W.canvas_saveLayer)(a,b,c,e,f);w._canvas_save=a=>(w._canvas_save=W.canvas_save)(a);w._canvas_restore=a=>(w._canvas_restore=W.canvas_restore)(a);w._canvas_restoreToCount=(a,b)=>(w._canvas_restoreToCount=W.canvas_restoreToCount)(a,b);
w._canvas_getSaveCount=a=>(w._canvas_getSaveCount=W.canvas_getSaveCount)(a);w._canvas_translate=(a,b,c)=>(w._canvas_translate=W.canvas_translate)(a,b,c);w._canvas_scale=(a,b,c)=>(w._canvas_scale=W.canvas_scale)(a,b,c);w._canvas_rotate=(a,b)=>(w._canvas_rotate=W.canvas_rotate)(a,b);w._canvas_skew=(a,b,c)=>(w._canvas_skew=W.canvas_skew)(a,b,c);w._canvas_transform=(a,b)=>(w._canvas_transform=W.canvas_transform)(a,b);w._canvas_clipRect=(a,b,c,e)=>(w._canvas_clipRect=W.canvas_clipRect)(a,b,c,e);
w._canvas_clipRRect=(a,b,c)=>(w._canvas_clipRRect=W.canvas_clipRRect)(a,b,c);w._canvas_clipPath=(a,b,c)=>(w._canvas_clipPath=W.canvas_clipPath)(a,b,c);w._canvas_drawColor=(a,b,c)=>(w._canvas_drawColor=W.canvas_drawColor)(a,b,c);w._canvas_drawLine=(a,b,c,e,f,h)=>(w._canvas_drawLine=W.canvas_drawLine)(a,b,c,e,f,h);w._canvas_drawPaint=(a,b)=>(w._canvas_drawPaint=W.canvas_drawPaint)(a,b);w._canvas_drawRect=(a,b,c)=>(w._canvas_drawRect=W.canvas_drawRect)(a,b,c);
w._canvas_drawRRect=(a,b,c)=>(w._canvas_drawRRect=W.canvas_drawRRect)(a,b,c);w._canvas_drawDRRect=(a,b,c,e)=>(w._canvas_drawDRRect=W.canvas_drawDRRect)(a,b,c,e);w._canvas_drawOval=(a,b,c)=>(w._canvas_drawOval=W.canvas_drawOval)(a,b,c);w._canvas_drawCircle=(a,b,c,e,f)=>(w._canvas_drawCircle=W.canvas_drawCircle)(a,b,c,e,f);w._canvas_drawArc=(a,b,c,e,f,h)=>(w._canvas_drawArc=W.canvas_drawArc)(a,b,c,e,f,h);w._canvas_drawPath=(a,b,c)=>(w._canvas_drawPath=W.canvas_drawPath)(a,b,c);
w._canvas_drawShadow=(a,b,c,e,f,h)=>(w._canvas_drawShadow=W.canvas_drawShadow)(a,b,c,e,f,h);w._canvas_drawParagraph=(a,b,c,e)=>(w._canvas_drawParagraph=W.canvas_drawParagraph)(a,b,c,e);w._canvas_drawPicture=(a,b)=>(w._canvas_drawPicture=W.canvas_drawPicture)(a,b);w._canvas_drawImage=(a,b,c,e,f,h)=>(w._canvas_drawImage=W.canvas_drawImage)(a,b,c,e,f,h);w._canvas_drawImageRect=(a,b,c,e,f,h)=>(w._canvas_drawImageRect=W.canvas_drawImageRect)(a,b,c,e,f,h);
w._canvas_drawImageNine=(a,b,c,e,f,h)=>(w._canvas_drawImageNine=W.canvas_drawImageNine)(a,b,c,e,f,h);w._canvas_drawVertices=(a,b,c,e)=>(w._canvas_drawVertices=W.canvas_drawVertices)(a,b,c,e);w._canvas_drawPoints=(a,b,c,e,f)=>(w._canvas_drawPoints=W.canvas_drawPoints)(a,b,c,e,f);w._canvas_drawAtlas=(a,b,c,e,f,h,l,m,p)=>(w._canvas_drawAtlas=W.canvas_drawAtlas)(a,b,c,e,f,h,l,m,p);w._canvas_getTransform=(a,b)=>(w._canvas_getTransform=W.canvas_getTransform)(a,b);
w._canvas_getLocalClipBounds=(a,b)=>(w._canvas_getLocalClipBounds=W.canvas_getLocalClipBounds)(a,b);w._canvas_getDeviceClipBounds=(a,b)=>(w._canvas_getDeviceClipBounds=W.canvas_getDeviceClipBounds)(a,b);w._contourMeasureIter_create=(a,b,c)=>(w._contourMeasureIter_create=W.contourMeasureIter_create)(a,b,c);w._contourMeasureIter_next=a=>(w._contourMeasureIter_next=W.contourMeasureIter_next)(a);w._contourMeasureIter_dispose=a=>(w._contourMeasureIter_dispose=W.contourMeasureIter_dispose)(a);
w._contourMeasure_dispose=a=>(w._contourMeasure_dispose=W.contourMeasure_dispose)(a);w._contourMeasure_length=a=>(w._contourMeasure_length=W.contourMeasure_length)(a);w._contourMeasure_isClosed=a=>(w._contourMeasure_isClosed=W.contourMeasure_isClosed)(a);w._contourMeasure_getPosTan=(a,b,c,e)=>(w._contourMeasure_getPosTan=W.contourMeasure_getPosTan)(a,b,c,e);w._contourMeasure_getSegment=(a,b,c,e)=>(w._contourMeasure_getSegment=W.contourMeasure_getSegment)(a,b,c,e);
w._skData_create=a=>(w._skData_create=W.skData_create)(a);w._skData_getPointer=a=>(w._skData_getPointer=W.skData_getPointer)(a);w._skData_getConstPointer=a=>(w._skData_getConstPointer=W.skData_getConstPointer)(a);w._skData_getSize=a=>(w._skData_getSize=W.skData_getSize)(a);w._skData_dispose=a=>(w._skData_dispose=W.skData_dispose)(a);w._imageFilter_createBlur=(a,b,c)=>(w._imageFilter_createBlur=W.imageFilter_createBlur)(a,b,c);
w._imageFilter_createDilate=(a,b)=>(w._imageFilter_createDilate=W.imageFilter_createDilate)(a,b);w._imageFilter_createErode=(a,b)=>(w._imageFilter_createErode=W.imageFilter_createErode)(a,b);w._imageFilter_createMatrix=(a,b)=>(w._imageFilter_createMatrix=W.imageFilter_createMatrix)(a,b);w._imageFilter_createFromColorFilter=a=>(w._imageFilter_createFromColorFilter=W.imageFilter_createFromColorFilter)(a);w._imageFilter_compose=(a,b)=>(w._imageFilter_compose=W.imageFilter_compose)(a,b);
w._imageFilter_dispose=a=>(w._imageFilter_dispose=W.imageFilter_dispose)(a);w._imageFilter_getFilterBounds=(a,b)=>(w._imageFilter_getFilterBounds=W.imageFilter_getFilterBounds)(a,b);w._colorFilter_createMode=(a,b)=>(w._colorFilter_createMode=W.colorFilter_createMode)(a,b);w._colorFilter_createMatrix=a=>(w._colorFilter_createMatrix=W.colorFilter_createMatrix)(a);w._colorFilter_createSRGBToLinearGamma=()=>(w._colorFilter_createSRGBToLinearGamma=W.colorFilter_createSRGBToLinearGamma)();
w._colorFilter_createLinearToSRGBGamma=()=>(w._colorFilter_createLinearToSRGBGamma=W.colorFilter_createLinearToSRGBGamma)();w._colorFilter_compose=(a,b)=>(w._colorFilter_compose=W.colorFilter_compose)(a,b);w._colorFilter_dispose=a=>(w._colorFilter_dispose=W.colorFilter_dispose)(a);w._maskFilter_createBlur=(a,b)=>(w._maskFilter_createBlur=W.maskFilter_createBlur)(a,b);w._maskFilter_dispose=a=>(w._maskFilter_dispose=W.maskFilter_dispose)(a);w._fontCollection_create=()=>(w._fontCollection_create=W.fontCollection_create)();
w._fontCollection_dispose=a=>(w._fontCollection_dispose=W.fontCollection_dispose)(a);w._typeface_create=a=>(w._typeface_create=W.typeface_create)(a);w._typeface_dispose=a=>(w._typeface_dispose=W.typeface_dispose)(a);w._typefaces_filterCoveredCodePoints=(a,b,c,e)=>(w._typefaces_filterCoveredCodePoints=W.typefaces_filterCoveredCodePoints)(a,b,c,e);w._fontCollection_registerTypeface=(a,b,c)=>(w._fontCollection_registerTypeface=W.fontCollection_registerTypeface)(a,b,c);
w._fontCollection_clearCaches=a=>(w._fontCollection_clearCaches=W.fontCollection_clearCaches)(a);w._image_createFromPicture=(a,b,c)=>(w._image_createFromPicture=W.image_createFromPicture)(a,b,c);w._image_createFromPixels=(a,b,c,e,f)=>(w._image_createFromPixels=W.image_createFromPixels)(a,b,c,e,f);w._image_createFromTextureSource=(a,b,c,e)=>(w._image_createFromTextureSource=W.image_createFromTextureSource)(a,b,c,e);w._image_ref=a=>(w._image_ref=W.image_ref)(a);
w._image_dispose=a=>(w._image_dispose=W.image_dispose)(a);w._image_getWidth=a=>(w._image_getWidth=W.image_getWidth)(a);w._image_getHeight=a=>(w._image_getHeight=W.image_getHeight)(a);w._paint_create=(a,b,c,e,f,h,l,m)=>(w._paint_create=W.paint_create)(a,b,c,e,f,h,l,m);w._paint_dispose=a=>(w._paint_dispose=W.paint_dispose)(a);w._paint_setShader=(a,b)=>(w._paint_setShader=W.paint_setShader)(a,b);w._paint_setImageFilter=(a,b)=>(w._paint_setImageFilter=W.paint_setImageFilter)(a,b);
w._paint_setColorFilter=(a,b)=>(w._paint_setColorFilter=W.paint_setColorFilter)(a,b);w._paint_setMaskFilter=(a,b)=>(w._paint_setMaskFilter=W.paint_setMaskFilter)(a,b);w._path_create=()=>(w._path_create=W.path_create)();w._path_dispose=a=>(w._path_dispose=W.path_dispose)(a);w._path_copy=a=>(w._path_copy=W.path_copy)(a);w._path_setFillType=(a,b)=>(w._path_setFillType=W.path_setFillType)(a,b);w._path_getFillType=a=>(w._path_getFillType=W.path_getFillType)(a);
w._path_moveTo=(a,b,c)=>(w._path_moveTo=W.path_moveTo)(a,b,c);w._path_relativeMoveTo=(a,b,c)=>(w._path_relativeMoveTo=W.path_relativeMoveTo)(a,b,c);w._path_lineTo=(a,b,c)=>(w._path_lineTo=W.path_lineTo)(a,b,c);w._path_relativeLineTo=(a,b,c)=>(w._path_relativeLineTo=W.path_relativeLineTo)(a,b,c);w._path_quadraticBezierTo=(a,b,c,e,f)=>(w._path_quadraticBezierTo=W.path_quadraticBezierTo)(a,b,c,e,f);
w._path_relativeQuadraticBezierTo=(a,b,c,e,f)=>(w._path_relativeQuadraticBezierTo=W.path_relativeQuadraticBezierTo)(a,b,c,e,f);w._path_cubicTo=(a,b,c,e,f,h,l)=>(w._path_cubicTo=W.path_cubicTo)(a,b,c,e,f,h,l);w._path_relativeCubicTo=(a,b,c,e,f,h,l)=>(w._path_relativeCubicTo=W.path_relativeCubicTo)(a,b,c,e,f,h,l);w._path_conicTo=(a,b,c,e,f,h)=>(w._path_conicTo=W.path_conicTo)(a,b,c,e,f,h);w._path_relativeConicTo=(a,b,c,e,f,h)=>(w._path_relativeConicTo=W.path_relativeConicTo)(a,b,c,e,f,h);
w._path_arcToOval=(a,b,c,e,f)=>(w._path_arcToOval=W.path_arcToOval)(a,b,c,e,f);w._path_arcToRotated=(a,b,c,e,f,h,l,m)=>(w._path_arcToRotated=W.path_arcToRotated)(a,b,c,e,f,h,l,m);w._path_relativeArcToRotated=(a,b,c,e,f,h,l,m)=>(w._path_relativeArcToRotated=W.path_relativeArcToRotated)(a,b,c,e,f,h,l,m);w._path_addRect=(a,b)=>(w._path_addRect=W.path_addRect)(a,b);w._path_addOval=(a,b)=>(w._path_addOval=W.path_addOval)(a,b);w._path_addArc=(a,b,c,e)=>(w._path_addArc=W.path_addArc)(a,b,c,e);
w._path_addPolygon=(a,b,c,e)=>(w._path_addPolygon=W.path_addPolygon)(a,b,c,e);w._path_addRRect=(a,b)=>(w._path_addRRect=W.path_addRRect)(a,b);w._path_addPath=(a,b,c,e)=>(w._path_addPath=W.path_addPath)(a,b,c,e);w._path_close=a=>(w._path_close=W.path_close)(a);w._path_reset=a=>(w._path_reset=W.path_reset)(a);w._path_contains=(a,b,c)=>(w._path_contains=W.path_contains)(a,b,c);w._path_transform=(a,b)=>(w._path_transform=W.path_transform)(a,b);
w._path_getBounds=(a,b)=>(w._path_getBounds=W.path_getBounds)(a,b);w._path_combine=(a,b,c)=>(w._path_combine=W.path_combine)(a,b,c);w._path_getSvgString=a=>(w._path_getSvgString=W.path_getSvgString)(a);w._pictureRecorder_create=()=>(w._pictureRecorder_create=W.pictureRecorder_create)();w._pictureRecorder_dispose=a=>(w._pictureRecorder_dispose=W.pictureRecorder_dispose)(a);w._pictureRecorder_beginRecording=(a,b)=>(w._pictureRecorder_beginRecording=W.pictureRecorder_beginRecording)(a,b);
w._pictureRecorder_endRecording=a=>(w._pictureRecorder_endRecording=W.pictureRecorder_endRecording)(a);w._picture_getCullRect=(a,b)=>(w._picture_getCullRect=W.picture_getCullRect)(a,b);w._picture_dispose=a=>(w._picture_dispose=W.picture_dispose)(a);w._picture_approximateBytesUsed=a=>(w._picture_approximateBytesUsed=W.picture_approximateBytesUsed)(a);w._shader_createLinearGradient=(a,b,c,e,f,h)=>(w._shader_createLinearGradient=W.shader_createLinearGradient)(a,b,c,e,f,h);
w._shader_createRadialGradient=(a,b,c,e,f,h,l,m)=>(w._shader_createRadialGradient=W.shader_createRadialGradient)(a,b,c,e,f,h,l,m);w._shader_createConicalGradient=(a,b,c,e,f,h,l,m)=>(w._shader_createConicalGradient=W.shader_createConicalGradient)(a,b,c,e,f,h,l,m);w._shader_createSweepGradient=(a,b,c,e,f,h,l,m,p)=>(w._shader_createSweepGradient=W.shader_createSweepGradient)(a,b,c,e,f,h,l,m,p);w._shader_dispose=a=>(w._shader_dispose=W.shader_dispose)(a);
w._runtimeEffect_create=a=>(w._runtimeEffect_create=W.runtimeEffect_create)(a);w._runtimeEffect_dispose=a=>(w._runtimeEffect_dispose=W.runtimeEffect_dispose)(a);w._runtimeEffect_getUniformSize=a=>(w._runtimeEffect_getUniformSize=W.runtimeEffect_getUniformSize)(a);w._shader_createRuntimeEffectShader=(a,b,c,e)=>(w._shader_createRuntimeEffectShader=W.shader_createRuntimeEffectShader)(a,b,c,e);w._shader_createFromImage=(a,b,c,e,f)=>(w._shader_createFromImage=W.shader_createFromImage)(a,b,c,e,f);
w._skString_allocate=a=>(w._skString_allocate=W.skString_allocate)(a);w._skString_getData=a=>(w._skString_getData=W.skString_getData)(a);w._skString_getLength=a=>(w._skString_getLength=W.skString_getLength)(a);w._skString_free=a=>(w._skString_free=W.skString_free)(a);w._skString16_allocate=a=>(w._skString16_allocate=W.skString16_allocate)(a);w._skString16_getData=a=>(w._skString16_getData=W.skString16_getData)(a);w._skString16_free=a=>(w._skString16_free=W.skString16_free)(a);
w._surface_create=()=>(w._surface_create=W.surface_create)();w._surface_getThreadId=a=>(w._surface_getThreadId=W.surface_getThreadId)(a);w._surface_setCallbackHandler=(a,b)=>(w._surface_setCallbackHandler=W.surface_setCallbackHandler)(a,b);w._surface_destroy=a=>(w._surface_destroy=W.surface_destroy)(a);var Yb=w._surface_dispose=a=>(Yb=w._surface_dispose=W.surface_dispose)(a);w._surface_renderPictures=(a,b,c)=>(w._surface_renderPictures=W.surface_renderPictures)(a,b,c);
var Wb=w._surface_renderPicturesOnWorker=(a,b,c,e,f)=>(Wb=w._surface_renderPicturesOnWorker=W.surface_renderPicturesOnWorker)(a,b,c,e,f);w._surface_rasterizeImage=(a,b,c)=>(w._surface_rasterizeImage=W.surface_rasterizeImage)(a,b,c);
var Zb=w._surface_rasterizeImageOnWorker=(a,b,c,e)=>(Zb=w._surface_rasterizeImageOnWorker=W.surface_rasterizeImageOnWorker)(a,b,c,e),Xb=w._surface_onRenderComplete=(a,b,c)=>(Xb=w._surface_onRenderComplete=W.surface_onRenderComplete)(a,b,c),$b=w._surface_onRasterizeComplete=(a,b,c)=>($b=w._surface_onRasterizeComplete=W.surface_onRasterizeComplete)(a,b,c);w._lineMetrics_create=(a,b,c,e,f,h,l,m,p)=>(w._lineMetrics_create=W.lineMetrics_create)(a,b,c,e,f,h,l,m,p);
w._lineMetrics_dispose=a=>(w._lineMetrics_dispose=W.lineMetrics_dispose)(a);w._lineMetrics_getHardBreak=a=>(w._lineMetrics_getHardBreak=W.lineMetrics_getHardBreak)(a);w._lineMetrics_getAscent=a=>(w._lineMetrics_getAscent=W.lineMetrics_getAscent)(a);w._lineMetrics_getDescent=a=>(w._lineMetrics_getDescent=W.lineMetrics_getDescent)(a);w._lineMetrics_getUnscaledAscent=a=>(w._lineMetrics_getUnscaledAscent=W.lineMetrics_getUnscaledAscent)(a);w._lineMetrics_getHeight=a=>(w._lineMetrics_getHeight=W.lineMetrics_getHeight)(a);
w._lineMetrics_getWidth=a=>(w._lineMetrics_getWidth=W.lineMetrics_getWidth)(a);w._lineMetrics_getLeft=a=>(w._lineMetrics_getLeft=W.lineMetrics_getLeft)(a);w._lineMetrics_getBaseline=a=>(w._lineMetrics_getBaseline=W.lineMetrics_getBaseline)(a);w._lineMetrics_getLineNumber=a=>(w._lineMetrics_getLineNumber=W.lineMetrics_getLineNumber)(a);w._lineMetrics_getStartIndex=a=>(w._lineMetrics_getStartIndex=W.lineMetrics_getStartIndex)(a);w._lineMetrics_getEndIndex=a=>(w._lineMetrics_getEndIndex=W.lineMetrics_getEndIndex)(a);
w._paragraph_dispose=a=>(w._paragraph_dispose=W.paragraph_dispose)(a);w._paragraph_getWidth=a=>(w._paragraph_getWidth=W.paragraph_getWidth)(a);w._paragraph_getHeight=a=>(w._paragraph_getHeight=W.paragraph_getHeight)(a);w._paragraph_getLongestLine=a=>(w._paragraph_getLongestLine=W.paragraph_getLongestLine)(a);w._paragraph_getMinIntrinsicWidth=a=>(w._paragraph_getMinIntrinsicWidth=W.paragraph_getMinIntrinsicWidth)(a);w._paragraph_getMaxIntrinsicWidth=a=>(w._paragraph_getMaxIntrinsicWidth=W.paragraph_getMaxIntrinsicWidth)(a);
w._paragraph_getAlphabeticBaseline=a=>(w._paragraph_getAlphabeticBaseline=W.paragraph_getAlphabeticBaseline)(a);w._paragraph_getIdeographicBaseline=a=>(w._paragraph_getIdeographicBaseline=W.paragraph_getIdeographicBaseline)(a);w._paragraph_getDidExceedMaxLines=a=>(w._paragraph_getDidExceedMaxLines=W.paragraph_getDidExceedMaxLines)(a);w._paragraph_layout=(a,b)=>(w._paragraph_layout=W.paragraph_layout)(a,b);
w._paragraph_getPositionForOffset=(a,b,c,e)=>(w._paragraph_getPositionForOffset=W.paragraph_getPositionForOffset)(a,b,c,e);w._paragraph_getClosestGlyphInfoAtCoordinate=(a,b,c,e,f,h)=>(w._paragraph_getClosestGlyphInfoAtCoordinate=W.paragraph_getClosestGlyphInfoAtCoordinate)(a,b,c,e,f,h);w._paragraph_getGlyphInfoAt=(a,b,c,e,f)=>(w._paragraph_getGlyphInfoAt=W.paragraph_getGlyphInfoAt)(a,b,c,e,f);w._paragraph_getWordBoundary=(a,b,c)=>(w._paragraph_getWordBoundary=W.paragraph_getWordBoundary)(a,b,c);
w._paragraph_getLineCount=a=>(w._paragraph_getLineCount=W.paragraph_getLineCount)(a);w._paragraph_getLineNumberAt=(a,b)=>(w._paragraph_getLineNumberAt=W.paragraph_getLineNumberAt)(a,b);w._paragraph_getLineMetricsAtIndex=(a,b)=>(w._paragraph_getLineMetricsAtIndex=W.paragraph_getLineMetricsAtIndex)(a,b);w._textBoxList_dispose=a=>(w._textBoxList_dispose=W.textBoxList_dispose)(a);w._textBoxList_getLength=a=>(w._textBoxList_getLength=W.textBoxList_getLength)(a);
w._textBoxList_getBoxAtIndex=(a,b,c)=>(w._textBoxList_getBoxAtIndex=W.textBoxList_getBoxAtIndex)(a,b,c);w._paragraph_getBoxesForRange=(a,b,c,e,f)=>(w._paragraph_getBoxesForRange=W.paragraph_getBoxesForRange)(a,b,c,e,f);w._paragraph_getBoxesForPlaceholders=a=>(w._paragraph_getBoxesForPlaceholders=W.paragraph_getBoxesForPlaceholders)(a);w._paragraph_getUnresolvedCodePoints=(a,b,c)=>(w._paragraph_getUnresolvedCodePoints=W.paragraph_getUnresolvedCodePoints)(a,b,c);
w._paragraphBuilder_create=(a,b)=>(w._paragraphBuilder_create=W.paragraphBuilder_create)(a,b);w._paragraphBuilder_dispose=a=>(w._paragraphBuilder_dispose=W.paragraphBuilder_dispose)(a);w._paragraphBuilder_addPlaceholder=(a,b,c,e,f,h)=>(w._paragraphBuilder_addPlaceholder=W.paragraphBuilder_addPlaceholder)(a,b,c,e,f,h);w._paragraphBuilder_addText=(a,b)=>(w._paragraphBuilder_addText=W.paragraphBuilder_addText)(a,b);
w._paragraphBuilder_getUtf8Text=(a,b)=>(w._paragraphBuilder_getUtf8Text=W.paragraphBuilder_getUtf8Text)(a,b);w._paragraphBuilder_pushStyle=(a,b)=>(w._paragraphBuilder_pushStyle=W.paragraphBuilder_pushStyle)(a,b);w._paragraphBuilder_pop=a=>(w._paragraphBuilder_pop=W.paragraphBuilder_pop)(a);w._paragraphBuilder_build=a=>(w._paragraphBuilder_build=W.paragraphBuilder_build)(a);w._unicodePositionBuffer_create=a=>(w._unicodePositionBuffer_create=W.unicodePositionBuffer_create)(a);
w._unicodePositionBuffer_getDataPointer=a=>(w._unicodePositionBuffer_getDataPointer=W.unicodePositionBuffer_getDataPointer)(a);w._unicodePositionBuffer_free=a=>(w._unicodePositionBuffer_free=W.unicodePositionBuffer_free)(a);w._lineBreakBuffer_create=a=>(w._lineBreakBuffer_create=W.lineBreakBuffer_create)(a);w._lineBreakBuffer_getDataPointer=a=>(w._lineBreakBuffer_getDataPointer=W.lineBreakBuffer_getDataPointer)(a);w._lineBreakBuffer_free=a=>(w._lineBreakBuffer_free=W.lineBreakBuffer_free)(a);
w._paragraphBuilder_setGraphemeBreaksUtf16=(a,b)=>(w._paragraphBuilder_setGraphemeBreaksUtf16=W.paragraphBuilder_setGraphemeBreaksUtf16)(a,b);w._paragraphBuilder_setWordBreaksUtf16=(a,b)=>(w._paragraphBuilder_setWordBreaksUtf16=W.paragraphBuilder_setWordBreaksUtf16)(a,b);w._paragraphBuilder_setLineBreaksUtf16=(a,b)=>(w._paragraphBuilder_setLineBreaksUtf16=W.paragraphBuilder_setLineBreaksUtf16)(a,b);w._paragraphStyle_create=()=>(w._paragraphStyle_create=W.paragraphStyle_create)();
w._paragraphStyle_dispose=a=>(w._paragraphStyle_dispose=W.paragraphStyle_dispose)(a);w._paragraphStyle_setTextAlign=(a,b)=>(w._paragraphStyle_setTextAlign=W.paragraphStyle_setTextAlign)(a,b);w._paragraphStyle_setTextDirection=(a,b)=>(w._paragraphStyle_setTextDirection=W.paragraphStyle_setTextDirection)(a,b);w._paragraphStyle_setMaxLines=(a,b)=>(w._paragraphStyle_setMaxLines=W.paragraphStyle_setMaxLines)(a,b);
w._paragraphStyle_setHeight=(a,b)=>(w._paragraphStyle_setHeight=W.paragraphStyle_setHeight)(a,b);w._paragraphStyle_setTextHeightBehavior=(a,b,c)=>(w._paragraphStyle_setTextHeightBehavior=W.paragraphStyle_setTextHeightBehavior)(a,b,c);w._paragraphStyle_setEllipsis=(a,b)=>(w._paragraphStyle_setEllipsis=W.paragraphStyle_setEllipsis)(a,b);w._paragraphStyle_setStrutStyle=(a,b)=>(w._paragraphStyle_setStrutStyle=W.paragraphStyle_setStrutStyle)(a,b);
w._paragraphStyle_setTextStyle=(a,b)=>(w._paragraphStyle_setTextStyle=W.paragraphStyle_setTextStyle)(a,b);w._paragraphStyle_setApplyRoundingHack=(a,b)=>(w._paragraphStyle_setApplyRoundingHack=W.paragraphStyle_setApplyRoundingHack)(a,b);w._strutStyle_create=()=>(w._strutStyle_create=W.strutStyle_create)();w._strutStyle_dispose=a=>(w._strutStyle_dispose=W.strutStyle_dispose)(a);w._strutStyle_setFontFamilies=(a,b,c)=>(w._strutStyle_setFontFamilies=W.strutStyle_setFontFamilies)(a,b,c);
w._strutStyle_setFontSize=(a,b)=>(w._strutStyle_setFontSize=W.strutStyle_setFontSize)(a,b);w._strutStyle_setHeight=(a,b)=>(w._strutStyle_setHeight=W.strutStyle_setHeight)(a,b);w._strutStyle_setHalfLeading=(a,b)=>(w._strutStyle_setHalfLeading=W.strutStyle_setHalfLeading)(a,b);w._strutStyle_setLeading=(a,b)=>(w._strutStyle_setLeading=W.strutStyle_setLeading)(a,b);w._strutStyle_setFontStyle=(a,b,c)=>(w._strutStyle_setFontStyle=W.strutStyle_setFontStyle)(a,b,c);
w._strutStyle_setForceStrutHeight=(a,b)=>(w._strutStyle_setForceStrutHeight=W.strutStyle_setForceStrutHeight)(a,b);w._textStyle_create=()=>(w._textStyle_create=W.textStyle_create)();w._textStyle_copy=a=>(w._textStyle_copy=W.textStyle_copy)(a);w._textStyle_dispose=a=>(w._textStyle_dispose=W.textStyle_dispose)(a);w._textStyle_setColor=(a,b)=>(w._textStyle_setColor=W.textStyle_setColor)(a,b);w._textStyle_setDecoration=(a,b)=>(w._textStyle_setDecoration=W.textStyle_setDecoration)(a,b);
w._textStyle_setDecorationColor=(a,b)=>(w._textStyle_setDecorationColor=W.textStyle_setDecorationColor)(a,b);w._textStyle_setDecorationStyle=(a,b)=>(w._textStyle_setDecorationStyle=W.textStyle_setDecorationStyle)(a,b);w._textStyle_setDecorationThickness=(a,b)=>(w._textStyle_setDecorationThickness=W.textStyle_setDecorationThickness)(a,b);w._textStyle_setFontStyle=(a,b,c)=>(w._textStyle_setFontStyle=W.textStyle_setFontStyle)(a,b,c);
w._textStyle_setTextBaseline=(a,b)=>(w._textStyle_setTextBaseline=W.textStyle_setTextBaseline)(a,b);w._textStyle_clearFontFamilies=a=>(w._textStyle_clearFontFamilies=W.textStyle_clearFontFamilies)(a);w._textStyle_addFontFamilies=(a,b,c)=>(w._textStyle_addFontFamilies=W.textStyle_addFontFamilies)(a,b,c);w._textStyle_setFontSize=(a,b)=>(w._textStyle_setFontSize=W.textStyle_setFontSize)(a,b);w._textStyle_setLetterSpacing=(a,b)=>(w._textStyle_setLetterSpacing=W.textStyle_setLetterSpacing)(a,b);
w._textStyle_setWordSpacing=(a,b)=>(w._textStyle_setWordSpacing=W.textStyle_setWordSpacing)(a,b);w._textStyle_setHeight=(a,b)=>(w._textStyle_setHeight=W.textStyle_setHeight)(a,b);w._textStyle_setHalfLeading=(a,b)=>(w._textStyle_setHalfLeading=W.textStyle_setHalfLeading)(a,b);w._textStyle_setLocale=(a,b)=>(w._textStyle_setLocale=W.textStyle_setLocale)(a,b);w._textStyle_setBackground=(a,b)=>(w._textStyle_setBackground=W.textStyle_setBackground)(a,b);
w._textStyle_setForeground=(a,b)=>(w._textStyle_setForeground=W.textStyle_setForeground)(a,b);w._textStyle_addShadow=(a,b,c,e,f)=>(w._textStyle_addShadow=W.textStyle_addShadow)(a,b,c,e,f);w._textStyle_addFontFeature=(a,b,c)=>(w._textStyle_addFontFeature=W.textStyle_addFontFeature)(a,b,c);w._textStyle_setFontVariations=(a,b,c,e)=>(w._textStyle_setFontVariations=W.textStyle_setFontVariations)(a,b,c,e);w._vertices_create=(a,b,c,e,f,h,l)=>(w._vertices_create=W.vertices_create)(a,b,c,e,f,h,l);
w._vertices_dispose=a=>(w._vertices_dispose=W.vertices_dispose)(a);w._skwasm_isMultiThreaded=()=>(w._skwasm_isMultiThreaded=W.skwasm_isMultiThreaded)();var qb=a=>(qb=W.malloc)(a),ac=(a,b)=>(ac=W._emscripten_timeout)(a,b),X=(a,b)=>(X=W.setThrew)(a,b),Y=a=>(Y=W._emscripten_stack_restore)(a),Sb=a=>(Sb=W._emscripten_stack_alloc)(a),Z=()=>(Z=W.emscripten_stack_get_current)();function cc(a,b,c){var e=Z();try{return S.get(a)(b,c)}catch(f){Y(e);if(f!==f+0)throw f;X(1,0)}}
function hc(a,b,c){var e=Z();try{S.get(a)(b,c)}catch(f){Y(e);if(f!==f+0)throw f;X(1,0)}}function bc(a,b){var c=Z();try{return S.get(a)(b)}catch(e){Y(c);if(e!==e+0)throw e;X(1,0)}}function ic(a,b,c,e){var f=Z();try{S.get(a)(b,c,e)}catch(h){Y(f);if(h!==h+0)throw h;X(1,0)}}function dc(a,b,c,e){var f=Z();try{return S.get(a)(b,c,e)}catch(h){Y(f);if(h!==h+0)throw h;X(1,0)}}function jc(a,b,c,e,f){var h=Z();try{S.get(a)(b,c,e,f)}catch(l){Y(h);if(l!==l+0)throw l;X(1,0)}}
function kc(a,b,c,e,f,h,l,m){var p=Z();try{S.get(a)(b,c,e,f,h,l,m)}catch(v){Y(p);if(v!==v+0)throw v;X(1,0)}}function gc(a,b){var c=Z();try{S.get(a)(b)}catch(e){Y(c);if(e!==e+0)throw e;X(1,0)}}function fc(a,b,c,e,f,h,l){var m=Z();try{return S.get(a)(b,c,e,f,h,l)}catch(p){Y(m);if(p!==p+0)throw p;X(1,0)}}function ec(a,b,c,e,f){var h=Z();try{return S.get(a)(b,c,e,f)}catch(l){Y(h);if(l!==l+0)throw l;X(1,0)}}w.wasmMemory=g;w.wasmExports=W;w.stackAlloc=Tb;
w.addFunction=(a,b)=>{if(!U){U=new WeakMap;var c=S.length;if(U)for(var e=0;e<0+c;e++){var f=S.get(e);f&&U.set(f,e)}}if(c=U.get(a)||0)return c;if(Rb.length)c=Rb.pop();else{try{S.grow(1)}catch(m){if(!(m instanceof RangeError))throw m;throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.";}c=S.length-1}try{S.set(c,a)}catch(m){if(!(m instanceof TypeError))throw m;if("function"==typeof WebAssembly.Function){e=WebAssembly.Function;f={i:"i32",j:"i64",f:"f32",d:"f64",e:"externref",p:"i32"};for(var h={parameters:[],
results:"v"==b[0]?[]:[f[b[0]]]},l=1;l<b.length;++l)h.parameters.push(f[b[l]]);b=new e(h,a)}else{e=[1];f=b.slice(0,1);b=b.slice(1);h={i:127,p:127,j:126,f:125,d:124,e:111};e.push(96);l=b.length;128>l?e.push(l):e.push(l%128|128,l>>7);for(l=0;l<b.length;++l)e.push(h[b[l]]);"v"==f?e.push(0):e.push(1,h[f]);b=[0,97,115,109,1,0,0,0,1];f=e.length;128>f?b.push(f):b.push(f%128|128,f>>7);b.push(...e);b.push(2,7,1,1,101,1,102,0,0,7,5,1,1,102,0,0);b=new WebAssembly.Module(new Uint8Array(b));b=(new WebAssembly.Instance(b,
{e:{f:a}})).exports.f}S.set(c,b)}U.set(a,c);return c};var mc,nc;A=function oc(){mc||pc();mc||(A=oc)};function pc(){if(!(0<z)){if(!nc&&(nc=1,Da(sa),0<z))return;mc||(mc=1,w.calledRun=1,oa||(Da(ta),ea(w),Da(ua)))}}pc();moduleRtn=ha;
return moduleRtn;
}
);
})();
export default skwasm_st;

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,4 @@
(()=>{var P=()=>navigator.vendor==="Google Inc."||navigator.agent==="Edg/",E=()=>typeof ImageDecoder>"u"?!1:P(),L=()=>typeof Intl.v8BreakIterator<"u"&&typeof Intl.Segmenter<"u",W=()=>{let n=[0,97,115,109,1,0,0,0,1,5,1,95,1,120,0];return WebAssembly.validate(new Uint8Array(n))},w={hasImageCodecs:E(),hasChromiumBreakIterators:L(),supportsWasmGC:W(),crossOriginIsolated:window.crossOriginIsolated};function l(...n){return new URL(C(...n),document.baseURI).toString()}function C(...n){return n.filter(t=>!!t).map((t,i)=>i===0?_(t):j(_(t))).filter(t=>t.length).join("/")}function j(n){let t=0;for(;t<n.length&&n.charAt(t)==="/";)t++;return n.substring(t)}function _(n){let t=n.length;for(;t>0&&n.charAt(t-1)==="/";)t--;return n.substring(0,t)}function T(n,t){return n.canvasKitBaseUrl?n.canvasKitBaseUrl:t.engineRevision&&!t.useLocalCanvasKit?C("https://www.gstatic.com/flutter-canvaskit",t.engineRevision):"canvaskit"}var v=class{constructor(){this._scriptLoaded=!1}setTrustedTypesPolicy(t){this._ttPolicy=t}async loadEntrypoint(t){let{entrypointUrl:i=l("main.dart.js"),onEntrypointLoaded:r,nonce:e}=t||{};return this._loadJSEntrypoint(i,r,e)}async load(t,i,r,e,a){a??=o=>{o.initializeEngine(r).then(c=>c.runApp())};let{entryPointBaseUrl:s}=r;if(t.compileTarget==="dart2wasm")return this._loadWasmEntrypoint(t,i,s,a);{let o=t.mainJsPath??"main.dart.js",c=l(s,o);return this._loadJSEntrypoint(c,a,e)}}didCreateEngineInitializer(t){typeof this._didCreateEngineInitializerResolve=="function"&&(this._didCreateEngineInitializerResolve(t),this._didCreateEngineInitializerResolve=null,delete _flutter.loader.didCreateEngineInitializer),typeof this._onEntrypointLoaded=="function"&&this._onEntrypointLoaded(t)}_loadJSEntrypoint(t,i,r){let e=typeof i=="function";if(!this._scriptLoaded){this._scriptLoaded=!0;let a=this._createScriptTag(t,r);if(e)console.debug("Injecting <script> tag. Using callback."),this._onEntrypointLoaded=i,document.head.append(a);else return new Promise((s,o)=>{console.debug("Injecting <script> tag. Using Promises. Use the callback approach instead!"),this._didCreateEngineInitializerResolve=s,a.addEventListener("error",o),document.head.append(a)})}}async _loadWasmEntrypoint(t,i,r,e){if(!this._scriptLoaded){this._scriptLoaded=!0,this._onEntrypointLoaded=e;let{mainWasmPath:a,jsSupportRuntimePath:s}=t,o=l(r,a),c=l(r,s);this._ttPolicy!=null&&(c=this._ttPolicy.createScriptURL(c));let d=(await import(c)).compileStreaming(fetch(o)),f;t.renderer==="skwasm"?f=(async()=>{let m=await i.skwasm;return window._flutter_skwasmInstance=m,{skwasm:m.wasmExports,skwasmWrapper:m,ffi:{memory:m.wasmMemory}}})():f=Promise.resolve({}),await(await(await d).instantiate(await f)).invokeMain()}}_createScriptTag(t,i){let r=document.createElement("script");r.type="application/javascript",i&&(r.nonce=i);let e=t;return this._ttPolicy!=null&&(e=this._ttPolicy.createScriptURL(t)),r.src=e,r}};async function I(n,t,i){if(t<0)return n;let r,e=new Promise((a,s)=>{r=setTimeout(()=>{s(new Error(`${i} took more than ${t}ms to resolve. Moving on.`,{cause:I}))},t)});return Promise.race([n,e]).finally(()=>{clearTimeout(r)})}var y=class{setTrustedTypesPolicy(t){this._ttPolicy=t}loadServiceWorker(t){if(!t)return console.debug("Null serviceWorker configuration. Skipping."),Promise.resolve();if(!("serviceWorker"in navigator)){let o="Service Worker API unavailable.";return window.isSecureContext||(o+=`
The current context is NOT secure.`,o+=`
Read more: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts`),Promise.reject(new Error(o))}let{serviceWorkerVersion:i,serviceWorkerUrl:r=l(`flutter_service_worker.js?v=${i}`),timeoutMillis:e=4e3}=t,a=r;this._ttPolicy!=null&&(a=this._ttPolicy.createScriptURL(a));let s=navigator.serviceWorker.register(a).then(o=>this._getNewServiceWorker(o,i)).then(this._waitForServiceWorkerActivation);return I(s,e,"prepareServiceWorker")}async _getNewServiceWorker(t,i){if(!t.active&&(t.installing||t.waiting))return console.debug("Installing/Activating first service worker."),t.installing||t.waiting;if(t.active.scriptURL.endsWith(i))return console.debug("Loading from existing service worker."),t.active;{let r=await t.update();return console.debug("Updating service worker."),r.installing||r.waiting||r.active}}async _waitForServiceWorkerActivation(t){if(!t||t.state==="activated")if(t){console.debug("Service worker already active.");return}else throw new Error("Cannot activate a null service worker!");return new Promise((i,r)=>{t.addEventListener("statechange",()=>{t.state==="activated"&&(console.debug("Activated new service worker."),i())})})}};var g=class{constructor(t,i="flutter-js"){let r=t||[/\.js$/,/\.mjs$/];window.trustedTypes&&(this.policy=trustedTypes.createPolicy(i,{createScriptURL:function(e){if(e.startsWith("blob:"))return e;let a=new URL(e,window.location),s=a.pathname.split("/").pop();if(r.some(c=>c.test(s)))return a.toString();console.error("URL rejected by TrustedTypes policy",i,":",e,"(download prevented)")}}))}};var k=n=>{let t=WebAssembly.compileStreaming(fetch(n));return(i,r)=>((async()=>{let e=await t,a=await WebAssembly.instantiate(e,i);r(a,e)})(),{})};var b=(n,t,i,r)=>(window.flutterCanvasKitLoaded=(async()=>{if(window.flutterCanvasKit)return window.flutterCanvasKit;let e=i.hasChromiumBreakIterators&&i.hasImageCodecs;if(!e&&t.canvasKitVariant=="chromium")throw"Chromium CanvasKit variant specifically requested, but unsupported in this browser";let a=e&&t.canvasKitVariant!=="full",s=r;a&&(s=l(s,"chromium"));let o=l(s,"canvaskit.js");n.flutterTT.policy&&(o=n.flutterTT.policy.createScriptURL(o));let c=k(l(s,"canvaskit.wasm")),p=await import(o);return window.flutterCanvasKit=await p.default({instantiateWasm:c}),window.flutterCanvasKit})(),window.flutterCanvasKitLoaded);var U=async(n,t,i,r)=>{let e=i.crossOriginIsolated&&!t.forceSingleThreadedSkwasm?"skwasm":"skwasm_st",s=l(r,`${e}.js`);n.flutterTT.policy&&(s=n.flutterTT.policy.createScriptURL(s));let o=k(l(r,`${e}.wasm`));return await(await import(s)).default({instantiateWasm:o,mainScriptUrlOrBlob:new Blob([`import '${s}'`],{type:"application/javascript"})})};var S=class{async loadEntrypoint(t){let{serviceWorker:i,...r}=t||{},e=new g,a=new y;a.setTrustedTypesPolicy(e.policy),await a.loadServiceWorker(i).catch(o=>{console.warn("Exception while loading service worker:",o)});let s=new v;return s.setTrustedTypesPolicy(e.policy),this.didCreateEngineInitializer=s.didCreateEngineInitializer.bind(s),s.loadEntrypoint(r)}async load({serviceWorkerSettings:t,onEntrypointLoaded:i,nonce:r,config:e}={}){e??={};let a=_flutter.buildConfig;if(!a)throw"FlutterLoader.load requires _flutter.buildConfig to be set";let s=u=>{switch(u){case"skwasm":return w.hasChromiumBreakIterators&&w.hasImageCodecs&&w.supportsWasmGC;default:return!0}},o=(u,m)=>{switch(u.renderer){case"auto":return m=="canvaskit"||m=="html";default:return u.renderer==m}},c=u=>u.compileTarget==="dart2wasm"&&!w.supportsWasmGC||e.renderer&&!o(u,e.renderer)?!1:s(u.renderer),p=a.builds.find(c);if(!p)throw"FlutterLoader could not find a build compatible with configuration and environment.";let d={};d.flutterTT=new g,t&&(d.serviceWorkerLoader=new y,d.serviceWorkerLoader.setTrustedTypesPolicy(d.flutterTT.policy),await d.serviceWorkerLoader.loadServiceWorker(t).catch(u=>{console.warn("Exception while loading service worker:",u)}));let f=T(e,a);p.renderer==="canvaskit"?d.canvasKit=b(d,e,w,f):p.renderer==="skwasm"&&(d.skwasm=U(d,e,w,f));let h=new v;return h.setTrustedTypesPolicy(d.flutterTT.policy),this.didCreateEngineInitializer=h.didCreateEngineInitializer.bind(h),h.load(p,d,e,r,i)}};window._flutter||(window._flutter={});window._flutter.loader||(window._flutter.loader=new S);})();
//# sourceMappingURL=flutter.js.map

View File

@@ -0,0 +1,16 @@
(()=>{var P=()=>navigator.vendor==="Google Inc."||navigator.agent==="Edg/",E=()=>typeof ImageDecoder>"u"?!1:P(),L=()=>typeof Intl.v8BreakIterator<"u"&&typeof Intl.Segmenter<"u",W=()=>{let n=[0,97,115,109,1,0,0,0,1,5,1,95,1,120,0];return WebAssembly.validate(new Uint8Array(n))},w={hasImageCodecs:E(),hasChromiumBreakIterators:L(),supportsWasmGC:W(),crossOriginIsolated:window.crossOriginIsolated};function l(...n){return new URL(C(...n),document.baseURI).toString()}function C(...n){return n.filter(t=>!!t).map((t,i)=>i===0?_(t):j(_(t))).filter(t=>t.length).join("/")}function j(n){let t=0;for(;t<n.length&&n.charAt(t)==="/";)t++;return n.substring(t)}function _(n){let t=n.length;for(;t>0&&n.charAt(t-1)==="/";)t--;return n.substring(0,t)}function T(n,t){return n.canvasKitBaseUrl?n.canvasKitBaseUrl:t.engineRevision&&!t.useLocalCanvasKit?C("https://www.gstatic.com/flutter-canvaskit",t.engineRevision):"canvaskit"}var v=class{constructor(){this._scriptLoaded=!1}setTrustedTypesPolicy(t){this._ttPolicy=t}async loadEntrypoint(t){let{entrypointUrl:i=l("main.dart.js"),onEntrypointLoaded:r,nonce:e}=t||{};return this._loadJSEntrypoint(i,r,e)}async load(t,i,r,e,a){a??=o=>{o.initializeEngine(r).then(c=>c.runApp())};let{entryPointBaseUrl:s}=r;if(t.compileTarget==="dart2wasm")return this._loadWasmEntrypoint(t,i,s,a);{let o=t.mainJsPath??"main.dart.js",c=l(s,o);return this._loadJSEntrypoint(c,a,e)}}didCreateEngineInitializer(t){typeof this._didCreateEngineInitializerResolve=="function"&&(this._didCreateEngineInitializerResolve(t),this._didCreateEngineInitializerResolve=null,delete _flutter.loader.didCreateEngineInitializer),typeof this._onEntrypointLoaded=="function"&&this._onEntrypointLoaded(t)}_loadJSEntrypoint(t,i,r){let e=typeof i=="function";if(!this._scriptLoaded){this._scriptLoaded=!0;let a=this._createScriptTag(t,r);if(e)console.debug("Injecting <script> tag. Using callback."),this._onEntrypointLoaded=i,document.head.append(a);else return new Promise((s,o)=>{console.debug("Injecting <script> tag. Using Promises. Use the callback approach instead!"),this._didCreateEngineInitializerResolve=s,a.addEventListener("error",o),document.head.append(a)})}}async _loadWasmEntrypoint(t,i,r,e){if(!this._scriptLoaded){this._scriptLoaded=!0,this._onEntrypointLoaded=e;let{mainWasmPath:a,jsSupportRuntimePath:s}=t,o=l(r,a),c=l(r,s);this._ttPolicy!=null&&(c=this._ttPolicy.createScriptURL(c));let d=(await import(c)).compileStreaming(fetch(o)),f;t.renderer==="skwasm"?f=(async()=>{let m=await i.skwasm;return window._flutter_skwasmInstance=m,{skwasm:m.wasmExports,skwasmWrapper:m,ffi:{memory:m.wasmMemory}}})():f=Promise.resolve({}),await(await(await d).instantiate(await f)).invokeMain()}}_createScriptTag(t,i){let r=document.createElement("script");r.type="application/javascript",i&&(r.nonce=i);let e=t;return this._ttPolicy!=null&&(e=this._ttPolicy.createScriptURL(t)),r.src=e,r}};async function I(n,t,i){if(t<0)return n;let r,e=new Promise((a,s)=>{r=setTimeout(()=>{s(new Error(`${i} took more than ${t}ms to resolve. Moving on.`,{cause:I}))},t)});return Promise.race([n,e]).finally(()=>{clearTimeout(r)})}var y=class{setTrustedTypesPolicy(t){this._ttPolicy=t}loadServiceWorker(t){if(!t)return console.debug("Null serviceWorker configuration. Skipping."),Promise.resolve();if(!("serviceWorker"in navigator)){let o="Service Worker API unavailable.";return window.isSecureContext||(o+=`
The current context is NOT secure.`,o+=`
Read more: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts`),Promise.reject(new Error(o))}let{serviceWorkerVersion:i,serviceWorkerUrl:r=l(`flutter_service_worker.js?v=${i}`),timeoutMillis:e=4e3}=t,a=r;this._ttPolicy!=null&&(a=this._ttPolicy.createScriptURL(a));let s=navigator.serviceWorker.register(a).then(o=>this._getNewServiceWorker(o,i)).then(this._waitForServiceWorkerActivation);return I(s,e,"prepareServiceWorker")}async _getNewServiceWorker(t,i){if(!t.active&&(t.installing||t.waiting))return console.debug("Installing/Activating first service worker."),t.installing||t.waiting;if(t.active.scriptURL.endsWith(i))return console.debug("Loading from existing service worker."),t.active;{let r=await t.update();return console.debug("Updating service worker."),r.installing||r.waiting||r.active}}async _waitForServiceWorkerActivation(t){if(!t||t.state==="activated")if(t){console.debug("Service worker already active.");return}else throw new Error("Cannot activate a null service worker!");return new Promise((i,r)=>{t.addEventListener("statechange",()=>{t.state==="activated"&&(console.debug("Activated new service worker."),i())})})}};var g=class{constructor(t,i="flutter-js"){let r=t||[/\.js$/,/\.mjs$/];window.trustedTypes&&(this.policy=trustedTypes.createPolicy(i,{createScriptURL:function(e){if(e.startsWith("blob:"))return e;let a=new URL(e,window.location),s=a.pathname.split("/").pop();if(r.some(c=>c.test(s)))return a.toString();console.error("URL rejected by TrustedTypes policy",i,":",e,"(download prevented)")}}))}};var k=n=>{let t=WebAssembly.compileStreaming(fetch(n));return(i,r)=>((async()=>{let e=await t,a=await WebAssembly.instantiate(e,i);r(a,e)})(),{})};var b=(n,t,i,r)=>(window.flutterCanvasKitLoaded=(async()=>{if(window.flutterCanvasKit)return window.flutterCanvasKit;let e=i.hasChromiumBreakIterators&&i.hasImageCodecs;if(!e&&t.canvasKitVariant=="chromium")throw"Chromium CanvasKit variant specifically requested, but unsupported in this browser";let a=e&&t.canvasKitVariant!=="full",s=r;a&&(s=l(s,"chromium"));let o=l(s,"canvaskit.js");n.flutterTT.policy&&(o=n.flutterTT.policy.createScriptURL(o));let c=k(l(s,"canvaskit.wasm")),p=await import(o);return window.flutterCanvasKit=await p.default({instantiateWasm:c}),window.flutterCanvasKit})(),window.flutterCanvasKitLoaded);var U=async(n,t,i,r)=>{let e=i.crossOriginIsolated&&!t.forceSingleThreadedSkwasm?"skwasm":"skwasm_st",s=l(r,`${e}.js`);n.flutterTT.policy&&(s=n.flutterTT.policy.createScriptURL(s));let o=k(l(r,`${e}.wasm`));return await(await import(s)).default({instantiateWasm:o,mainScriptUrlOrBlob:new Blob([`import '${s}'`],{type:"application/javascript"})})};var S=class{async loadEntrypoint(t){let{serviceWorker:i,...r}=t||{},e=new g,a=new y;a.setTrustedTypesPolicy(e.policy),await a.loadServiceWorker(i).catch(o=>{console.warn("Exception while loading service worker:",o)});let s=new v;return s.setTrustedTypesPolicy(e.policy),this.didCreateEngineInitializer=s.didCreateEngineInitializer.bind(s),s.loadEntrypoint(r)}async load({serviceWorkerSettings:t,onEntrypointLoaded:i,nonce:r,config:e}={}){e??={};let a=_flutter.buildConfig;if(!a)throw"FlutterLoader.load requires _flutter.buildConfig to be set";let s=u=>{switch(u){case"skwasm":return w.hasChromiumBreakIterators&&w.hasImageCodecs&&w.supportsWasmGC;default:return!0}},o=(u,m)=>{switch(u.renderer){case"auto":return m=="canvaskit"||m=="html";default:return u.renderer==m}},c=u=>u.compileTarget==="dart2wasm"&&!w.supportsWasmGC||e.renderer&&!o(u,e.renderer)?!1:s(u.renderer),p=a.builds.find(c);if(!p)throw"FlutterLoader could not find a build compatible with configuration and environment.";let d={};d.flutterTT=new g,t&&(d.serviceWorkerLoader=new y,d.serviceWorkerLoader.setTrustedTypesPolicy(d.flutterTT.policy),await d.serviceWorkerLoader.loadServiceWorker(t).catch(u=>{console.warn("Exception while loading service worker:",u)}));let f=T(e,a);p.renderer==="canvaskit"?d.canvasKit=b(d,e,w,f):p.renderer==="skwasm"&&(d.skwasm=U(d,e,w,f));let h=new v;return h.setTrustedTypesPolicy(d.flutterTT.policy),this.didCreateEngineInitializer=h.didCreateEngineInitializer.bind(h),h.load(p,d,e,r,i)}};window._flutter||(window._flutter={});window._flutter.loader||(window._flutter.loader=new S);})();
//# sourceMappingURL=flutter.js.map
if (!window._flutter) {
window._flutter = {};
}
_flutter.buildConfig = {"engineRevision":"18b71d647a292a980abb405ac7d16fe1f0b20434","builds":[{"compileTarget":"dart2js","renderer":"canvaskit","mainJsPath":"main.dart.js"}]};
_flutter.loader.load({
serviceWorkerSettings: {
serviceWorkerVersion: "2389281828"
}
});

View File

@@ -0,0 +1,218 @@
'use strict';
const MANIFEST = 'flutter-app-manifest';
const TEMP = 'flutter-temp-cache';
const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"icons/Icon-maskable-512.png": "301a7604d45b3e739efc881eb04896ea",
"icons/Icon-maskable-192.png": "c457ef57daa1d16f64b27b786ec2ea3c",
"icons/Icon-512.png": "bc48e3cc3e85ab2b0d0ef914b4a6e382",
"icons/Icon-192.png": "3b057a05d8abc1604131b4bf70f7fd78",
"flutter.js": "76f08d47ff9f5715220992f993002504",
"index.html": "59c5932948135921d6bc7f653a605a17",
"/": "59c5932948135921d6bc7f653a605a17",
"favicon.png": "f32d5e86fa0e4006e9f570d17ee57a0b",
"version.json": "1bee6108c0b137ad55b03d38a79bba11",
"canvaskit/skwasm_st.wasm": "56c3973560dfcbf28ce47cebe40f3206",
"canvaskit/skwasm.js.symbols": "80806576fa1056b43dd6d0b445b4b6f7",
"canvaskit/skwasm.js": "f2ad9363618c5f62e813740099a80e63",
"canvaskit/skwasm_st.js": "d1326ceef381ad382ab492ba5d96f04d",
"canvaskit/chromium/canvaskit.js.symbols": "5a23598a2a8efd18ec3b60de5d28af8f",
"canvaskit/chromium/canvaskit.js": "34beda9f39eb7d992d46125ca868dc61",
"canvaskit/chromium/canvaskit.wasm": "64a386c87532ae52ae041d18a32a3635",
"canvaskit/canvaskit.js.symbols": "68eb703b9a609baef8ee0e413b442f33",
"canvaskit/canvaskit.js": "86e461cf471c1640fd2b461ece4589df",
"canvaskit/canvaskit.wasm": "efeeba7dcc952dae57870d4df3111fad",
"canvaskit/skwasm.wasm": "f0dfd99007f989368db17c9abeed5a49",
"canvaskit/skwasm_st.js.symbols": "c7e7aac7cd8b612defd62b43e3050bdd",
"assets/AssetManifest.bin.json": "804bafee7f3e2d49cef2cd7975a139c6",
"assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "33b7d9392238c04c131b6ce224e13711",
"assets/packages/quickalert/assets/success.gif": "dcede9f3064fe66b69f7bbe7b6e3849f",
"assets/packages/quickalert/assets/loading.gif": "ac70f280e4a1b90065fe981eafe8ae13",
"assets/packages/quickalert/assets/confirm.gif": "bdc3e511c73e97fbc5cfb0c2b5f78e00",
"assets/packages/quickalert/assets/warning.gif": "f45dfa3b5857b812e0c8227211635cc4",
"assets/packages/quickalert/assets/error.gif": "c307db003cf53e131f1c704bb16fb9bf",
"assets/packages/quickalert/assets/info.gif": "90d7fface6e2d52554f8614a1f5deb6b",
"assets/fonts/MaterialIcons-Regular.otf": "d40aed5a68282e4bd529de589ab20804",
"assets/AssetManifest.json": "a8ca1f71d3c77c4128047a86775cd5c1",
"assets/assets/favicon.png": "d5fb3b7c82e3233517e880ef62b755c9",
"assets/assets/images/send.svg": "e38b31ea755d9555fb44d7e9b03db490",
"assets/assets/images/resume-link.svg": "71232d92bdd73c2697243ca911451540",
"assets/assets/images/resume-file.svg": "1075e32928d6fdfbe4e488d326abaf3e",
"assets/assets/images/logo.svg": "66054164ee6d5dc3afd4eacd99db80e3",
"assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57",
"assets/shaders/ink_sparkle.frag": "ecc85a2e95f5e9f53123dcaf8cb9b6ce",
"assets/AssetManifest.bin": "d8837089cad8dcd9a4f7508d831c6370",
"assets/NOTICES": "30019a615949ce7923021e851dcdf776",
"manifest.json": "eedecdf540009c5b146d53466f940cf5",
"flutter_bootstrap.js": "f4f69d8e0ddb330c26b1f94cd0c3011f",
"main.dart.js": "43b25bdf7d31c1789a09fabd3d00baac"};
// The application shell files that are downloaded before a service worker can
// start.
const CORE = ["main.dart.js",
"index.html",
"flutter_bootstrap.js",
"assets/AssetManifest.bin.json",
"assets/FontManifest.json"];
// During install, the TEMP cache is populated with the application shell files.
self.addEventListener("install", (event) => {
self.skipWaiting();
return event.waitUntil(
caches.open(TEMP).then((cache) => {
return cache.addAll(
CORE.map((value) => new Request(value, {'cache': 'reload'})));
})
);
});
// During activate, the cache is populated with the temp files downloaded in
// install. If this service worker is upgrading from one with a saved
// MANIFEST, then use this to retain unchanged resource files.
self.addEventListener("activate", function(event) {
return event.waitUntil(async function() {
try {
var contentCache = await caches.open(CACHE_NAME);
var tempCache = await caches.open(TEMP);
var manifestCache = await caches.open(MANIFEST);
var manifest = await manifestCache.match('manifest');
// When there is no prior manifest, clear the entire cache.
if (!manifest) {
await caches.delete(CACHE_NAME);
contentCache = await caches.open(CACHE_NAME);
for (var request of await tempCache.keys()) {
var response = await tempCache.match(request);
await contentCache.put(request, response);
}
await caches.delete(TEMP);
// Save the manifest to make future upgrades efficient.
await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));
// Claim client to enable caching on first launch
self.clients.claim();
return;
}
var oldManifest = await manifest.json();
var origin = self.location.origin;
for (var request of await contentCache.keys()) {
var key = request.url.substring(origin.length + 1);
if (key == "") {
key = "/";
}
// If a resource from the old manifest is not in the new cache, or if
// the MD5 sum has changed, delete it. Otherwise the resource is left
// in the cache and can be reused by the new service worker.
if (!RESOURCES[key] || RESOURCES[key] != oldManifest[key]) {
await contentCache.delete(request);
}
}
// Populate the cache with the app shell TEMP files, potentially overwriting
// cache files preserved above.
for (var request of await tempCache.keys()) {
var response = await tempCache.match(request);
await contentCache.put(request, response);
}
await caches.delete(TEMP);
// Save the manifest to make future upgrades efficient.
await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES)));
// Claim client to enable caching on first launch
self.clients.claim();
return;
} catch (err) {
// On an unhandled exception the state of the cache cannot be guaranteed.
console.error('Failed to upgrade service worker: ' + err);
await caches.delete(CACHE_NAME);
await caches.delete(TEMP);
await caches.delete(MANIFEST);
}
}());
});
// The fetch handler redirects requests for RESOURCE files to the service
// worker cache.
self.addEventListener("fetch", (event) => {
if (event.request.method !== 'GET') {
return;
}
var origin = self.location.origin;
var key = event.request.url.substring(origin.length + 1);
// Redirect URLs to the index.html
if (key.indexOf('?v=') != -1) {
key = key.split('?v=')[0];
}
if (event.request.url == origin || event.request.url.startsWith(origin + '/#') || key == '') {
key = '/';
}
// If the URL is not the RESOURCE list then return to signal that the
// browser should take over.
if (!RESOURCES[key]) {
return;
}
// If the URL is the index.html, perform an online-first request.
if (key == '/') {
return onlineFirst(event);
}
event.respondWith(caches.open(CACHE_NAME)
.then((cache) => {
return cache.match(event.request).then((response) => {
// Either respond with the cached resource, or perform a fetch and
// lazily populate the cache only if the resource was successfully fetched.
return response || fetch(event.request).then((response) => {
if (response && Boolean(response.ok)) {
cache.put(event.request, response.clone());
}
return response;
});
})
})
);
});
self.addEventListener('message', (event) => {
// SkipWaiting can be used to immediately activate a waiting service worker.
// This will also require a page refresh triggered by the main worker.
if (event.data === 'skipWaiting') {
self.skipWaiting();
return;
}
if (event.data === 'downloadOffline') {
downloadOffline();
return;
}
});
// Download offline will check the RESOURCES for all files not in the cache
// and populate them.
async function downloadOffline() {
var resources = [];
var contentCache = await caches.open(CACHE_NAME);
var currentContent = {};
for (var request of await contentCache.keys()) {
var key = request.url.substring(origin.length + 1);
if (key == "") {
key = "/";
}
currentContent[key] = true;
}
for (var resourceKey of Object.keys(RESOURCES)) {
if (!currentContent[resourceKey]) {
resources.push(resourceKey);
}
}
return contentCache.addAll(resources);
}
// Attempt to download the resource online before falling back to
// the offline cache.
function onlineFirst(event) {
return event.respondWith(
fetch(event.request).then((response) => {
return caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, response.clone());
return response;
});
}).catch((error) => {
return caches.open(CACHE_NAME).then((cache) => {
return cache.match(event.request).then((response) => {
if (response != null) {
return response;
}
throw error;
});
});
})
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="/api/v1/anketa/static/">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="client_form">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png" />
<title>client_form</title>
<link rel="manifest" href="manifest.json">
<script>
window.agentID = "{{.AgentId}}";
window.vacancyID = "{{.VacancyId}}";
window.vacancyName = "{{.VacancyName}}";
window.vacancyAddress = "{{.Address}}";
window.vacancyWorkFormat = "{{.WorkFormat}}";
window.vacancySalaryTop = "{{.SalaryTop}}";
window.vacancySalaryBottom = "{{.SalaryBottom}}";
window.vacancyRequirements = "{{.Requirements}}";
window.vacancyResponsibilities = "{{.Responsibilities}}";
window.vacancyDescription = "{{.Description}}";
</script>
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,35 @@
{
"name": "client_form",
"short_name": "client_form",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

View File

@@ -0,0 +1 @@
{"app_name":"client_form","version":"1.0.0","build_number":"1","package_name":"client_form"}

Some files were not shown because too many files have changed in this diff Show More