commit 34bf3ea3910ba52cc24c9ac88d106ad1215b0166 Author: David Frassi Date: Sat Sep 26 09:00:54 2026 +0200 Initial commit: fork from canti diff --git a/.agents/AGENTS.md b/.agents/AGENTS.md new file mode 100644 index 0000000..2538a8f --- /dev/null +++ b/.agents/AGENTS.md @@ -0,0 +1,3 @@ +# Regole del Progetto + +Quando trovi dei trattini verticali `|` tra gli accordi, ricordati di inserirli all'interno della riga degli accordi (cioè racchiusi tra parentesi quadre, ad esempio come accordo `[|]`), non come testo normale. diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..3f85021 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,15 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.dev/reference/versions#browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +Chrome >=107 +Firefox >=106 +Edge >=107 +Safari >=16.1 +iOS >=16.1 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..59d9a3a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.env b/.env new file mode 100644 index 0000000..64de438 --- /dev/null +++ b/.env @@ -0,0 +1,9 @@ +FTP_PASSWORD=cantiDavid@72 +FTP_THREADS=100 +BASE_HREF=/ionic/ +CONTACT_EMAIL=info@canticristiani.it +API_AUTH_USER=canti +API_AUTH_PASS=antani2026 +VPS_HOST=185.193.67.105 +VPS_USER=root +VPS_PATH=/var/docker/canticristiani-pwa/html diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..5215f55 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,47 @@ +{ + "root": true, + "ignorePatterns": ["projects/**/*"], + "overrides": [ + { + "files": ["*.ts"], + "parserOptions": { + "project": ["tsconfig.json"], + "createDefaultProgram": true + }, + "extends": [ + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/prefer-standalone": "off", + "@angular-eslint/component-class-suffix": [ + "error", + { + "suffixes": ["Page", "Component"] + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ], + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@angular-eslint/template/recommended"], + "rules": {} + } + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b669df --- /dev/null +++ b/.gitignore @@ -0,0 +1,70 @@ +# Specifies intentionally untracked files to ignore when using Git +# http://git-scm.com/docs/gitignore + +*~ +*.sw[mnpcod] +.tmp +*.tmp +*.tmp.* +UserInterfaceState.xcuserstate +$RECYCLE.BIN/ + +*.log +log.txt + + +/.sourcemaps +/.versions +/coverage + +# Ionic +/.ionic +/www +/platforms +/plugins + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-project +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + + +# Miscellaneous +/.angular +/.angular/cache +.sass-cache/ +/.nx +/.nx/cache +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6d2c885 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "Webnative.webnative" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0abbfd2 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.preferences.autoImportFileExcludePatterns": ["@ionic/angular/common", "@ionic/angular/standalone"] +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7323127 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM node:22-bullseye + +# Install Ionic CLI +RUN npm install -g @ionic/cli @angular/cli + +# Set working directory +WORKDIR /app + +# Expose ports for Ionic dev server and live reload +EXPOSE 8100 8101 35729 + +# Start command (will be overridden by docker-compose for initial setup) +CMD ["ionic", "serve", "--host", "0.0.0.0", "--port", "8100"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f1dd74 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# CantiCristiani PWA + +Applicazione PWA moderna per la gestione di canti, accordi e karaoke integrato. Progettata per musicisti e cantanti per un uso fluido durante le celebrazioni o i momenti di preghiera. + +## Caratteristiche Principali + +- 🎤 **Karaoke Intelligente**: Avanzamento automatico del testo basato sul rilevamento vocale (microfono). +- 🎚️ **Sensibilità Dinamica**: Regolazione in tempo reale della sensibilità del microfono tramite slider verticale custom (50% - 100%). +- 🎼 **Accordi e Trasporto**: Visualizzazione accordi con possibilità di trasporto tonale istantaneo. +- 📋 **Gestione Playlist**: Creazione, modifica e condivisione di playlist tramite QR Code. +- 📱 **PWA Ready**: Installabile su Android e iOS come app nativa, con supporto offline. +- 🔆 **Schermo Sempre Acceso**: Opzione dedicata nelle impostazioni per evitare lo spegnimento dello schermo durante l'uso. +- 🔍 **Ricerca Rapida**: Filtri avanzati per categorie, tonalità e playlist. + +## Tecnologie Utilizzate + +- **Framework**: Ionic + Angular +- **State Management**: Angular Signals +- **PWA**: @angular/pwa +- **API**: Screen Wake Lock API, Media Session API + +## Installazione e Sviluppo + +### Prerequisiti +- Node.js (v18+) +- Ionic CLI + +### Comandi Locali +```bash +npm install +ionic serve +``` + +## Deploy + +Per distribuire l'applicazione in produzione (ambiente locale o server FTP): + +```bash +./deploy_pwa.sh +``` + +Lo script si occupa di: +1. Incrementare la versione dell'app. +2. Eseguire la build di produzione. +3. Distribuire i file nella cartella di distribuzione locale. + +--- +© 2026 CantiCristiani.it diff --git a/allineacanti.sh b/allineacanti.sh new file mode 100755 index 0000000..3f8d62f --- /dev/null +++ b/allineacanti.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# --- Caricamento variabili d'ambiente --- +if [ -f .env ]; then + export $(grep -v '^#' .env | xargs) +else + echo "❌ Errore: File .env non trovato." + exit 1 +fi + +# --- Configurazione FTP --- +FTP_HOST="ftp.canticristiani.it" +FTP_USER="canticristiani.it" +FTP_PASS="$FTP_PASSWORD" +SOURCE_URL="https://libretto.mmcinet.eu/canti/api/get_all_app_tables" +REMOTE_PATH="api/canti.json" + +if [ -z "$FTP_PASS" ]; then + echo "❌ Errore: FTP_PASSWORD non definita nel file .env" + exit 1 +fi + +# --- Download del file --- +echo "⬇️ Scaricamento dati da $SOURCE_URL..." +TEMP_FILE=$(mktemp) +if ! curl -s -L "$SOURCE_URL" -o "$TEMP_FILE"; then + echo "❌ Errore nel download dei dati." + rm "$TEMP_FILE" + exit 1 +fi + +# --- Rotazione e Caricamento file (FTP o VPS) --- +if [ -n "$VPS_HOST" ]; then + echo "🔄 Rotazione file su VPS ($VPS_HOST)..." + ssh "$VPS_USER@$VPS_HOST" "mkdir -p $VPS_PATH/api && mv $VPS_PATH/api/canti.json $VPS_PATH/api/canti_ex.json 2>/dev/null || true" + + echo "🚀 Caricamento nuovo file su VPS via SCP..." + if scp "$TEMP_FILE" "$VPS_USER@$VPS_HOST:$VPS_PATH/$REMOTE_PATH" && ssh "$VPS_USER@$VPS_HOST" "chmod 644 $VPS_PATH/$REMOTE_PATH"; then + echo "✅ Allineamento su VPS completato con successo!" + else + echo "❌ Errore durante il caricamento via SCP su VPS." + rm "$TEMP_FILE" + exit 1 + fi +else + echo "🔄 Rotazione file su FTP (canti.json -> canti_ex.json)..." + # Rinominiamo canti.json in canti_ex.json. + # Usiamo i percorsi assoluti per sicurezza. + curl -s -u "$FTP_USER:$FTP_PASS" \ + --ftp-pasv \ + -Q "*DELE /htdocs/api/canti_ex.json" \ + -Q "*RNFR /htdocs/api/canti.json" \ + -Q "*RNTO /htdocs/api/canti_ex.json" \ + "ftp://$FTP_HOST/" > /dev/null + + echo "🚀 Caricamento nuovo file su FTP ($FTP_HOST) via FTP..." + if curl -s -u "$FTP_USER:$FTP_PASS" --ftp-pasv --ftp-create-dirs -T "$TEMP_FILE" "ftp://$FTP_HOST/$REMOTE_PATH"; then + echo "✅ Allineamento su FTP completato con successo!" + else + echo "❌ Errore durante il caricamento FTP." + rm "$TEMP_FILE" + exit 1 + fi +fi + +# Cleanup +rm "$TEMP_FILE" diff --git a/allinealetture.sh b/allinealetture.sh new file mode 100755 index 0000000..e3ecdea --- /dev/null +++ b/allinealetture.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# --- Caricamento variabili d'ambiente --- +if [ -f .env ]; then + export $(grep -v '^#' .env | xargs) +else + echo "❌ Errore: File .env non trovato." + exit 1 +fi + +# --- Configurazione FTP --- +FTP_HOST="ftp.canticristiani.it" +FTP_USER="canticristiani.it" +FTP_PASS="$FTP_PASSWORD" +SOURCE_URL="https://api.canticristiani.it/cantiletture.json" +REMOTE_PATH="api/cantiletture.json" + +if [ -z "$FTP_PASS" ]; then + echo "❌ Errore: FTP_PASSWORD non definita nel file .env" + exit 1 +fi + +# --- Download del file --- +echo "⬇️ Scaricamento dati da $SOURCE_URL..." +TEMP_FILE=$(mktemp) +if ! curl -s -u "$API_AUTH_USER:$API_AUTH_PASS" -L "$SOURCE_URL" -o "$TEMP_FILE"; then + echo "❌ Errore nel download dei dati." + rm "$TEMP_FILE" + exit 1 +fi + +# --- Caricamento file (FTP o VPS) --- +if [ -n "$VPS_HOST" ]; then + echo "🚀 Caricamento nuovo file su VPS ($VPS_HOST) via SCP..." + ssh "$VPS_USER@$VPS_HOST" "mkdir -p $VPS_PATH/api" + if scp "$TEMP_FILE" "$VPS_USER@$VPS_HOST:$VPS_PATH/$REMOTE_PATH" && ssh "$VPS_USER@$VPS_HOST" "chmod 644 $VPS_PATH/$REMOTE_PATH"; then + echo "✅ Allineamento su VPS completato con successo!" + else + echo "❌ Errore durante il caricamento via SCP su VPS." + rm "$TEMP_FILE" + exit 1 + fi +else + echo "🚀 Caricamento nuovo file su FTP ($FTP_HOST) via FTP..." + if curl -s -u "$FTP_USER:$FTP_PASS" --ftp-pasv --ftp-create-dirs -T "$TEMP_FILE" "ftp://$FTP_HOST/$REMOTE_PATH"; then + echo "✅ Allineamento su FTP completato con successo!" + else + echo "❌ Errore durante il caricamento FTP." + rm "$TEMP_FILE" + exit 1 + fi +fi + +# Cleanup +rm "$TEMP_FILE" diff --git a/angular.json b/angular.json new file mode 100644 index 0000000..f2ce550 --- /dev/null +++ b/angular.json @@ -0,0 +1,168 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "app": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "www", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "src/assets", + "output": "assets" + }, + { + "glob": "**/*", + "input": "public", + "output": "." + }, + { + "glob": "**/*.svg", + "input": "node_modules/ionicons/dist/ionicons/svg", + "output": "./svg" + } + ], + "styles": ["src/global.scss", "src/theme/variables.scss"], + "scripts": [], + "serviceWorker": true, + "ngswConfigPath": "ngsw-config.json", + "allowedCommonJsDependencies": [ + "localforage", + "qrcode", + "mammoth", + "tesseract.js" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "32kb", + "maximumError": "48kb" + } + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "outputHashing": "all" + }, + "development": { + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true + }, + "ci": { + "progress": false + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "app:build:production" + }, + "development": { + "buildTarget": "app:build:development" + }, + "ci": { + "progress": false + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "app:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "tsconfig.spec.json", + "karmaConfig": "karma.conf.js", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "src/assets", + "output": "assets" + }, + { + "glob": "**/*", + "input": "public", + "output": "." + }, + { + "glob": "**/*.svg", + "input": "node_modules/ionicons/dist/ionicons/svg", + "output": "./svg" + } + ], + "styles": ["src/global.scss", "src/theme/variables.scss"], + "scripts": [] + }, + "configurations": { + "ci": { + "progress": false, + "watch": false + } + } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } + } + } + } + }, + "cli": { + "schematicCollections": [ + "@ionic/angular-toolkit" + ], + "analytics": false + }, + "schematics": { + "@ionic/angular-toolkit:component": { + "styleext": "scss" + }, + "@ionic/angular-toolkit:page": { + "styleext": "scss" + } + } +} diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..0abaa8d --- /dev/null +++ b/backup.sh @@ -0,0 +1,4 @@ +#!/bin/bash +echo "Creazione del backup del repository Git locale..." +zip -r git_backup.zip . -x "node_modules/*" ".angular/*" "www/*" "platforms/*" "plugins/*" ".ionic/*" "dist/*" ".nx/*" "*/.DS_Store" "git_backup.zip" "backup.sh" +echo "Backup completato! Creato il file git_backup.zip." diff --git a/cantiletture.md b/cantiletture.md new file mode 100644 index 0000000..a42be59 --- /dev/null +++ b/cantiletture.md @@ -0,0 +1,224 @@ +# Piano di Azione: Suggerimento Canti con AI (cantiletture.json) + +## Obiettivo + +Generare automaticamente, una volta a settimana, un file JSON con i canti suggeriti per ogni messa della settimana, analizzati da Gemini Flash a partire dalle letture liturgiche. La PWA scarica questo file statico e mostra i suggerimenti istantaneamente, senza alcun calcolo lato client. + +--- + +## Architettura + +``` +CRON Settimanale (Lunedì ore 6:00) + │ + ├─ 1. Fetch RSS liturgia.silvestrini.org/rss + │ → Estrae le letture di tutta la settimana (7 giorni) + │ + ├─ 2. Fetch canti.json dal server + │ → Carica il database completo dei canti con testi e momenti liturgici + │ + ├─ 3. Chiamata API Gemini Flash + │ → Invia prompt strutturato con letture + lista canti + │ → Riceve suggerimenti ragionati con score e motivazione + │ + └─ 4. Salva cantiletture.json + → Upload sul server web (stessa posizione di canti.json) +``` + +--- + +## Struttura del File cantiletture.json + +```json +{ + "generated_at": "2026-05-19T06:00:00Z", + "week_start": "2026-05-17", + "week_end": "2026-05-24", + "masses": { + "2026-05-17": { + "title": "Ascensione del Signore", + "day": "Domenica", + "moments": { + "Ingresso": [ + { + "id_canti": 42, + "titolo": "Cristo è risorto veramente", + "score": 95, + "motivo": "Il tema dell'ascensione e della gloria di Cristo risorto è centrale in questo canto." + }, + { + "id_canti": 118, + "titolo": "Alleluia, è risorto", + "score": 88, + "motivo": "Il tono gioioso e la proclamazione pasquale si collegano al mistero celebrato." + }, + { + "id_canti": 205, + "titolo": "Canto di lode al Signore", + "score": 82, + "motivo": "Richiama il tema della lode che accompagna l'ascensione di Gesù." + } + ], + "Offertorio": [ + { "...": "3 canti suggeriti" } + ], + "Comunione": [ + { "...": "3 canti suggeriti" } + ], + "Finale": [ + { "...": "3 canti suggeriti" } + ] + } + }, + "2026-05-18": { + "title": "Lunedì della VII settimana di Pasqua", + "day": "Lunedì", + "moments": { "...": "stessa struttura" } + } + } +} +``` + +### Campi per ogni canto suggerito: +| Campo | Tipo | Descrizione | +|-------|------|-------------| +| `id_canti` | number | ID del canto nel database (per collegamento diretto al player) | +| `titolo` | string | Titolo del canto (per visualizzazione rapida) | +| `score` | number (0-100) | Grado di affinità/affidabilità del suggerimento | +| `motivo` | string | Spiegazione testuale del perché il canto è adatto | + +--- + +## Componenti da Sviluppare + +### 1. Script di Generazione (`scripts/generate-cantiletture.ts`) + +Script Node.js/TypeScript che: + +- **Input**: RSS feed + canti.json +- **Elaborazione**: + 1. Parsing XML del feed RSS (estrazione letture per data) + 2. Preparazione del prompt per Gemini con: testo letture + lista canti (id, titolo, testo, momenti liturgici) + 3. Chiamata API Gemini Flash con output JSON strutturato + 4. Validazione della risposta (verifica che gli ID canti esistano, score nel range) +- **Output**: File `cantiletture.json` + +**Prompt di esempio per Gemini:** +``` +Sei un esperto liturgista cattolico. Ti fornisco le letture della messa +e un database di canti liturgici con i relativi momenti (Ingresso, +Offertorio, Comunione, Finale, ecc.). + +Per ogni giorno della settimana e per ogni momento liturgico, suggerisci +i 3 canti più adatti. Per ogni suggerimento indica: +- L'ID del canto (id_canti) +- Uno score da 0 a 100 che indica il grado di attinenza +- Una breve motivazione (max 1 frase) + +Considera: temi teologici, periodo liturgico, tono emotivo, +corrispondenze tra letture e testi dei canti. + +LETTURE DELLA SETTIMANA: +[...testo letture...] + +DATABASE CANTI: +[...lista canti con id, titolo, testo, momenti...] + +Rispondi SOLO con JSON valido nel formato specificato. +``` + +### 2. Configurazione API Key + +- Ottenere API Key gratuita da [Google AI Studio](https://aistudio.google.com/apikey) +- Salvarla come variabile d'ambiente `GEMINI_API_KEY` +- Non committarla nel repository (usare `.env` in `.gitignore`) + +### 3. Aggiornamento PWA + +#### 3.1 Nuovo Service: `CantiLettureService` +```typescript +// Logica semplificata: +// - Scarica cantiletture.json dal server (con cache) +// - Espone i suggerimenti per data selezionata +// - Fallback al keyword matching se il JSON non è disponibile +``` + +#### 3.2 Aggiornamento LiturgiaPage +- Rimuovere il tasto "Analizza e Suggerisci Canti" (non serve più) +- Rimuovere la sezione "Parole Chiave Rilevate" (non serve più) +- Mostrare automaticamente i suggerimenti raggruppati per momento liturgico +- Ogni card mostra: titolo, score (barra o badge), motivazione dell'AI +- Click sulla card → apre il canto nel player + +#### 3.3 Fallback +Se `cantiletture.json` non è disponibile o la data non è coperta: +- Mostrare un messaggio "Suggerimenti AI non disponibili per questa data" +- Opzionalmente, offrire il keyword matching come alternativa + +### 4. Automazione (CRON) + +#### Opzione A: Script locale con crontab +```bash +# Ogni lunedì alle 6:00 +0 6 * * 1 cd /path/to/canti && node scripts/generate-cantiletture.js +``` + +#### Opzione B: GitHub Action (se il repo viene messo su GitHub) +```yaml +# .github/workflows/generate-suggestions.yml +name: Generate Canti Suggestions +on: + schedule: + - cron: '0 6 * * 1' # Ogni lunedì alle 6:00 UTC + workflow_dispatch: # Esecuzione manuale +``` + +#### Opzione C: Script manuale +```bash +# Eseguibile a mano quando si vuole aggiornare +./scripts/generate-cantiletture.sh +``` + +--- + +## Stima Costi + +| Voce | Valore | +|------|--------| +| Chiamate API/settimana | 1 (una sola chiamata copre tutta la settimana) | +| Token input (letture + ~500 canti) | ~15.000 token | +| Token output (JSON suggerimenti) | ~3.000 token | +| Costo per chiamata (Gemini Flash) | ~0.001€ | +| **Costo mensile stimato** | **< 0.01€** | +| Rientra nell'abbonamento Google One | ✅ Sì | + +--- + +## Piano di Esecuzione (Step by Step) + +### Fase 1: Script di Generazione +1. [ ] Creare `scripts/generate-cantiletture.ts` +2. [ ] Implementare il parsing RSS +3. [ ] Implementare la chiamata Gemini con prompt ottimizzato +4. [ ] Testare con le letture della settimana corrente +5. [ ] Validare il JSON generato + +### Fase 2: Integrazione PWA +6. [ ] Creare `CantiLettureService` che scarica e gestisce il JSON +7. [ ] Aggiornare `LiturgiaPage` per mostrare i suggerimenti AI +8. [ ] Implementare il fallback al keyword matching +9. [ ] Testare l'interfaccia completa + +### Fase 3: Automazione +10. [ ] Configurare il cron/script di esecuzione automatica +11. [ ] Testare il ciclo completo (generazione → upload → visualizzazione) +12. [ ] Documentare la procedura nel README + +--- + +## Note Tecniche + +- **Dimensione stimata del JSON**: ~50-100 KB per settimana (7 giorni × 4-5 momenti × 3 canti) +- **Cache**: Il JSON viene cachato in localStorage con TTL di 24 ore +- **Compatibilità**: Il file viene servito dallo stesso server HTTP della PWA, nessun problema CORS +- **Retrocompatibilità**: Se il file non esiste, la PWA continua a funzionare con il keyword matching diff --git a/comunita_123456.json b/comunita_123456.json new file mode 100644 index 0000000..4d7cda6 --- /dev/null +++ b/comunita_123456.json @@ -0,0 +1,5 @@ +{ + "id_comunita": "123456", + "nome_comunita": "Comunità Test 123456", + "canti": [378, 379, 380] +} diff --git a/deploy_localpwa.sh b/deploy_localpwa.sh new file mode 100755 index 0000000..2949220 --- /dev/null +++ b/deploy_localpwa.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +# --- Configurazione --- +DIST_PATH="www" # Solitamente Ionic usa 'www' o 'dist/app-name' +APP_NAME="CantiCristiani" + +echo "🚀 Inizio procedura di deploy PWA per: $APP_NAME" + +# 1. Verifica dipendenze +if ! [ -x "$(command -v npm)" ]; then + echo "❌ Errore: npm non è installato." >&2 + exit 1 +fi + +# 1.5 Aggiornamento Versione +VERSION=$(date +'%Y.%m.%d.%H%M') +echo "export const VERSION = '$VERSION';" > src/app/version.ts +echo "🏷️ Versione aggiornata a: $VERSION" + +# --- Caricamento variabili d'ambiente --- +if [ -f .env ]; then + export $(grep -v '^#' .env | xargs) +fi + +# --- Configurazione Email e API Parametriche --- +node -e " +const fs = require('fs'); +const envEmail = process.env.CONTACT_EMAIL || 'info@canticristiani.it'; +const apiUser = process.env.API_AUTH_USER || 'canti'; +const apiPass = process.env.API_AUTH_PASS || 'antani2026'; +['src/environments/environment.ts', 'src/environments/environment.prod.ts'].forEach(file => { + if (fs.existsSync(file)) { + let content = fs.readFileSync(file, 'utf8'); + content = content.replace(/contactEmail:\s*'[^']*'/g, \`contactEmail: '\${envEmail}'\`); + content = content.replace(/apiAuthUser:\s*'[^']*'/g, \`apiAuthUser: '\${apiUser}'\`); + content = content.replace(/apiAuthPass:\s*'[^']*'/g, \`apiAuthPass: '\${apiPass}'\`); + fs.writeFileSync(file, content, 'utf8'); + console.log(\`📧 Aggiornate variabili di ambiente in \${file}\`); + } +}); +" + +# 2. Build dell'applicazione +echo "📦 Compilazione in corso (Production Build)..." +if ! npm run build -- --configuration=production --base-href=/; then + echo "❌ Errore: La compilazione è fallita. Controlla gli errori sopra." + exit 1 +fi + +# Verifico se la cartella www esiste (Ionic/Angular) +if [ ! -d "www" ]; then + # Se non c'è www, cerco in dist/ + DIST_PATH=$(ls -d dist/*/ 2>/dev/null | head -n 1) + if [ -z "$DIST_PATH" ]; then + echo "❌ Errore: Cartella di build non trovata. Controlla il comando 'npm run build'." + exit 1 + fi +fi + +echo "✅ Build completata con successo in: $DIST_PATH" + +# --- Genera version.json per il polling PWA --- +BUILD_TIMESTAMP=$(date +%s)000 +echo "{\"version\":\"$VERSION\",\"buildTime\":$BUILD_TIMESTAMP}" > www/version.json +echo "📄 Generato version.json: v$VERSION (timestamp: $BUILD_TIMESTAMP)" + +# 2.5 In locale usiamo la root +echo "📁 Build pronta nella root..." +# Nessuna sottocartella ionic necessaria in locale + +# Nessun redirect necessario in locale + +# 3. Recupero IP locale per connessione da cellulare +IP_ADDRESS=$(ipconfig getifaddr en0 || ipconfig getifaddr en1 || hostname -I | awk '{print $1}') + +if [ -z "$IP_ADDRESS" ]; then + IP_ADDRESS="localhost" +fi + +echo "" +echo "--------------------------------------------------------" +echo "📱 INSTALLAZIONE SU CELLULARE:" +echo "1. Assicurati che il cellulare sia sulla stessa rete Wi-Fi." +echo "2. Apri il browser (Chrome su Android, Safari su iOS)." +echo "3. Vai all'indirizzo: http://\$IP_ADDRESS:8080/" +echo " ⚠️ NOTA: Per usare il MICROFONO su cellulare, i browser richiedono HTTPS." +echo " Puoi usare uno strumento come 'ngrok' o 'local-ssl-proxy' per testarlo con HTTPS." +echo "4. Una volta caricata l'app:" +echo " - Android: Clicca sui 3 puntini -> 'Installa app' o 'Aggiungi a home'." +echo " - iOS: Clicca l'icona 'Condividi' (quadrato con freccia) -> 'Aggiungi a schermata Home'." +echo "--------------------------------------------------------" +echo "" + +# 4. Avvio server locale per test immediato +echo "🌐 Liberazione porta 8080 (se occupata)..." +lsof -ti:8080 | xargs kill -9 2>/dev/null || true + +echo "🌐 Avvio server di distribuzione su http://$IP_ADDRESS:8080/ ..." +echo "premi CTRL+C per fermare il server." + +npx http-server "$DIST_PATH" -p 8080 -c-1 --proxy "http://localhost:8080?" diff --git a/deploy_www.sh b/deploy_www.sh new file mode 100755 index 0000000..0d0acb6 --- /dev/null +++ b/deploy_www.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# --- Caricamento variabili d'ambiente --- +if [ -f .env ]; then + export $(grep -v '^#' .env | xargs) +else + echo "❌ Errore: File .env non trovato." + exit 1 +fi + +# --- Configurazione Target --- +TARGET="contabo" +echo "🎯 Target di deploy: $TARGET" + +# --- Validazione configurazione --- +if [ -z "$VPS_HOST" ] || [ -z "$VPS_USER" ] || [ -z "$VPS_PATH" ]; then + echo "❌ Errore: VPS_HOST, VPS_USER o VPS_PATH non definiti nel file .env" + exit 1 +fi + +# --- Aggiornamento Versione --- +VERSION=$(date +'%Y.%m.%d.%H%M') +echo "export const VERSION = '$VERSION';" > src/app/version.ts +echo "🏷️ Versione aggiornata a: $VERSION" + +# --- Configurazione Email e API Parametriche --- +node -e " +const fs = require('fs'); +const envEmail = process.env.CONTACT_EMAIL || 'info@canticristiani.it'; +const apiUser = process.env.API_AUTH_USER || 'canti'; +const apiPass = process.env.API_AUTH_PASS || 'antani2026'; +['src/environments/environment.ts', 'src/environments/environment.prod.ts'].forEach(file => { + if (fs.existsSync(file)) { + let content = fs.readFileSync(file, 'utf8'); + content = content.replace(/contactEmail:\s*'[^']*'/g, \`contactEmail: '\${envEmail}'\`); + content = content.replace(/apiAuthUser:\s*'[^']*'/g, \`apiAuthUser: '\${apiUser}'\`); + content = content.replace(/apiAuthPass:\s*'[^']*'/g, \`apiAuthPass: '\${apiPass}'\`); + fs.writeFileSync(file, content, 'utf8'); + console.log(\`📧 Aggiornate variabili di ambiente in \${file}\`); + } +}); +" + + +# --- Build della PWA (base-href=/ per installare nella root) --- +echo "📦 1/2 Build della PWA (Production) per ROOT (www.canticristiani.it) in corso..." +npm run build -- --configuration=production --base-href=/ || { echo "❌ Errore nella build"; exit 1; } + +if [ ! -d "www" ]; then + echo "❌ Errore: Cartella 'www' non trovata." + exit 1 +fi + +# --- Genera version.json per il polling PWA --- +BUILD_TIMESTAMP=$(date +%s)000 +echo "{\"version\":\"$VERSION\",\"buildTime\":$BUILD_TIMESTAMP}" > www/version.json +echo "📄 Generato version.json: v$VERSION (timestamp: $BUILD_TIMESTAMP)" + +# --- Upload --- +echo "🚀 Upload via SSH/rsync su Contabo ($VPS_HOST) in corso..." +rsync -avz --delete --exclude 'api' www/ "$VPS_USER@$VPS_HOST:$VPS_PATH" + +# --- Allineamento Cantiletture JSON --- +if [ -f "./allinealetture.sh" ]; then + echo "🔄 Sincronizzazione cantiletture.json su server..." + ./allinealetture.sh || echo "⚠️ Warning: Allineamento cantiletture.json fallito" +fi diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..410d1f6 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,17 @@ + +services: + app: + build: . + volumes: + - .:/app + - node_modules:/app/node_modules + ports: + - "8100:8100" + - "8101:8101" + - "35729:35729" + environment: + - CHOKIDAR_USEPOLLING=true + command: ionic serve --external --port 8100 --address 0.0.0.0 + +volumes: + node_modules: diff --git a/documenti/clonazione_opzione_1.md b/documenti/clonazione_opzione_1.md new file mode 100644 index 0000000..c59e006 --- /dev/null +++ b/documenti/clonazione_opzione_1.md @@ -0,0 +1,220 @@ +# Studio di Dettaglio: Opzione 1 - White-Label / Multi-Configuration + +Questo documento descrive in dettaglio la strategia, la configurazione e i passaggi necessari per implementare la clonazione del progetto **canti** per la variante **stereocomics** attraverso l'**Opzione 1: White-Label**. + +Con questo approccio, il codice sorgente rimane **unico al 100%**. La differenziazione tra l'applicazione originale (Canti) e il clone (Stereocomics) avviene esclusivamente a tempo di compilazione (build-time) o di esecuzione (run-time) tramite file di configurazione ambientale di Angular (`environment`), fogli di stile dedicati, e sostituzione degli asset. + +--- + +## 1. Architettura e Flusso di Configurazione + +Il concetto chiave è l'utilizzo delle funzionalità native di Angular CLI (`angular.json`) per iniettare le configurazioni specifiche del brand. + +```mermaid +graph TD + A[Codice Sorgente Comune] --> B{Build Command} + B -- "ng build" --> C[Canti App] + B -- "ng build --configuration=stereocomics" --> D[Stereocomics App] + + subgraph Sostituzioni Stereocomics + E[environment.ts -> environment.stereocomics.ts] + F[variables.scss -> variables.stereocomics.scss] + G[Asset Generici -> Asset Stereocomics] + end + + D -.-> Sostituzioni Stereocomics +``` + +--- + +## 2. Passaggi Operativi per l'Implementazione + +### Passo 2.1: Creazione dei File Ambientali (Environments) +Attualmente in `src/environments/` abbiamo `environment.ts` e `environment.prod.ts`. Creeremo le varianti per Stereocomics: + +#### [NEW] [environment.stereocomics.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/environments/environment.stereocomics.ts) +```typescript +export const environment = { + production: false, + contactEmail: 'info@stereocomics.it', + appName: 'Stereocomics', + apiAuthUser: 'stereocomics', + apiAuthPass: 'stereo2026', + brand: 'stereocomics' // Flag utile per abilitare o disabilitare funzionalità specifiche run-time +}; +``` + +#### [NEW] [environment.stereocomics.prod.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/environments/environment.stereocomics.prod.ts) +```typescript +export const environment = { + production: true, + contactEmail: 'info@stereocomics.it', + appName: 'Stereocomics', + apiAuthUser: 'stereocomics', + apiAuthPass: 'stereo2026_prod', + brand: 'stereocomics' +}; +``` + +--- + +### Passo 2.2: Configurazione di `angular.json` +Per permettere ad Angular di caricare la configurazione corretta, dobbiamo aggiungere una nuova build configuration in [angular.json](file:///Users/davidfrassi/SRC/agenti/canti/angular.json). + +Sotto `projects -> app -> architect -> build -> configurations`, aggiungeremo il blocco `stereocomics`: + +```json +"stereocomics": { + "buildOptimizer": true, + "optimization": true, + "vendorChunk": false, + "extractLicenses": true, + "sourceMap": false, + "namedChunks": false, + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.stereocomics.prod.ts" + }, + { + "replace": "src/theme/variables.scss", + "with": "src/theme/variables.stereocomics.scss" + } + ], + "assets": [ + { + "glob": "**/*", + "input": "src/assets/stereocomics", + "output": "assets" + }, + { + "glob": "**/*", + "input": "public/stereocomics", + "output": "." + } + ] +} +``` + +E sotto `projects -> app -> architect -> serve -> configurations`: +```json +"stereocomics": { + "buildTarget": "app:build:development", + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.stereocomics.ts" + }, + { + "replace": "src/theme/variables.scss", + "with": "src/theme/variables.stereocomics.scss" + } + ], + "assets": [ + { + "glob": "**/*", + "input": "src/assets/stereocomics", + "output": "assets" + }, + { + "glob": "**/*", + "input": "public/stereocomics", + "output": "." + } + ] +} +``` + +--- + +### Passo 2.3: Stile e Theming +Creeremo un file di variabili SCSS specifico per ridefinire i colori primari di Ionic in chiave "Stereocomics" (es. arancione/viola invece del blu/verde tipico dei Canti). + +#### [NEW] [variables.stereocomics.scss](file:///Users/davidfrassi/SRC/agenti/canti/src/theme/variables.stereocomics.scss) +Questo file conterrà le medesime variabili CSS di `src/theme/variables.scss` ma con la palette colori e i font scelti per Stereocomics: +```scss +// Stereocomics Palette +:root { + --ion-color-primary: #ff5722; + --ion-color-primary-rgb: 255,87,34; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255,255,255; + --ion-color-primary-shade: #e04d1d; + --ion-color-primary-tint: #ff6838; + + // Font personalizzati + --app-font-family: 'Outfit', sans-serif; +} +``` + +Nel file [global.scss](file:///Users/davidfrassi/SRC/agenti/canti/src/global.scss) o nei componenti useremo la variabile `--app-font-family` per rendere dinamico il font. + +--- + +### Passo 2.4: Gestione Asset e Icone PWA +Per evitare di caricare icone e manifest di CantiCristiani su Stereocomics: +1. Creeremo due sottocartelle in `src/assets/`: + - `src/assets/canti/` (per i loghi e immagini originali) + - `src/assets/stereocomics/` (per i loghi e immagini di Stereocomics) +2. Durante la build di `stereocomics`, mapperemo la cartella `src/assets/stereocomics` direttamente sull'output `assets/` (come specificato in `angular.json`), garantendo che i percorsi `/assets/logo.png` rimangano identici nel codice HTML, ma cambino fisicamente nel pacchetto generato. +3. Creeremo un file `manifest.stereocomics.webmanifest` in `public/stereocomics/manifest.webmanifest` contenente il nome "Stereocomics" e i riferimenti alle icone corrette per la PWA. + +--- + +### Passo 2.5: Script in `package.json` +Aggiungeremo comandi dedicati in [package.json](file:///Users/davidfrassi/SRC/agenti/canti/package.json) per facilitare lo sviluppo e la pubblicazione: + +```json +"scripts": { + "start:canti": "ng serve --configuration=development", + "start:stereocomics": "ng serve --configuration=stereocomics", + "build:canti": "ng build --configuration=production", + "build:stereocomics": "ng build --configuration=stereocomics" +} +``` + +--- + +### Passo 2.6: Gestione Capacitor (Mobile Native App) +Se l'app deve essere compilata per iOS/Android tramite Capacitor: +- Possiamo creare un file di configurazione dinamico `capacitor.config.ts` che esporta la configurazione a seconda di una variabile d'ambiente (es. `process.env['BRAND']`). + +```typescript +import { CapacitorConfig } from '@capacitor/cli'; + +const brand = process.env['BRAND'] || 'canti'; + +const config: CapacitorConfig = { + appId: brand === 'stereocomics' ? 'it.stereocomics.app' : 'it.canticristiani.app', + appName: brand === 'stereocomics' ? 'Stereocomics' : 'Canti Cristiani', + webDir: 'www', + bundledWebRuntime: false +}; + +export default config; +``` + +--- + +## 3. Vantaggi e Svantaggi dell'Opzione 1 + +### Vantaggi: +1. **Zero Duplicazione di Codice**: Se viene corretto un bug nella pagina di riproduzione audio o nel parser dei testi, la modifica è istantaneamente attiva per entrambi i brand. +2. **Semplicità di Manutenzione**: Un'unica pipeline di CI/CD che esegue i test unitari una sola volta per la codebase comune. +3. **Flessibilità Controllata**: È comunque possibile introdurre comportamenti run-time personalizzati leggendo `environment.brand` nel codice TypeScript (es. `if (environment.brand === 'stereocomics') { ... }`). + +### Svantaggi: +1. **Complessità Condizionale**: Se a lungo andare Stereocomics necessita di pagine con layout o logiche radicalmente diversi da Canti, il codice si riempirà di blocchi `if/else` o direttive condizionali (`*ngIf="isStereocomics"`), riducendo la leggibilità del codice. + +--- + +## 4. Criteri di Accettazione e Verifica (Verification Plan) + +### Verifica dello Sviluppo Locale +1. Eseguire `npm run start:canti` -> Verificare che il logo sia quello di CantiCristiani e il colore dominante sia il blu/verde originale. +2. Eseguire `npm run start:stereocomics` -> Verificare che l'interfaccia risponda con il branding Stereocomics (colore primario cambiato, nome app cambiato in testata, logo corretto). + +### Verifica PWA e Build di Produzione +1. Eseguire `npm run build:stereocomics`. +2. Controllare che la cartella `/www` contenga il file `manifest.webmanifest` con i riferimenti a Stereocomics. +3. Verificare che l'email di contatto visualizzata sia `info@stereocomics.it`. diff --git a/documenti/clonazione_opzione_2.md b/documenti/clonazione_opzione_2.md new file mode 100644 index 0000000..e35a9c5 --- /dev/null +++ b/documenti/clonazione_opzione_2.md @@ -0,0 +1,175 @@ +# Studio di Dettaglio: Opzione 2 - Angular Workspace Monorepo + +Questo documento descrive in dettaglio la strategia, la configurazione e i passaggi necessari per implementare la clonazione del progetto **canti** per la variante **stereocomics** attraverso l'**Opzione 2: Angular Workspace Monorepo**. + +Con questo approccio, il repository viene strutturato per ospitare **due applicazioni distinte** (`canti` e `stereocomics`) e **una o più librerie condivise** (`shared-core`) che conterranno la logica di business comune (servizi audio, parser di testi, database locale, integrazioni API). + +--- + +## 1. Architettura e Struttura delle Cartelle + +Nel modello Monorepo, la struttura dei file viene riorganizzata per isolare l'interfaccia utente (pagine, componenti, temi) e condividere i servizi fondamentali. + +```mermaid +graph TD + subgraph Monorepo Workspace + Shared[Libreria Condivisa: @shared/core] + AppCanti[App 1: Canti] + AppStereo[App 2: Stereocomics] + end + + AppCanti --> Shared + AppStereo --> Shared +``` + +La struttura delle cartelle diventerà simile alla seguente: +```text +canti/ +├── angular.json +├── package.json +├── tsconfig.json +├── src/ <-- Diventa l'applicazione Canti originale +│ ├── app/ +│ │ ├── pages/ <-- Pagine specifiche di Canti +│ │ └── app.module.ts +│ └── assets/ <-- Asset di Canti +├── projects/ +│ ├── shared-core/ <-- Libreria condivisa generata +│ │ ├── src/ +│ │ │ ├── public-api.ts +│ │ │ └── lib/ +│ │ │ └── services/ <-- AudioEngine, LyricsParser, CantiService, ecc. +│ └── stereocomics/ <-- Nuova applicazione Stereocomics +│ ├── src/ +│ │ ├── app/ +│ │ │ ├── pages/ <-- Pagine e UI customizzate di Stereocomics +│ │ │ └── app.module.ts +│ │ ├── assets/ <-- Asset di Stereocomics +│ │ └── theme/ <-- Fogli di stile di Stereocomics +``` + +--- + +## 2. Passaggi Operativi per l'Implementazione + +### Passo 2.1: Inizializzazione della Libreria Condivisa +Generiamo una libreria Angular per ospitare i servizi condivisi. + +```bash +ng generate library shared-core --prefix=shared +``` + +Questo comando creerà la cartella `projects/shared-core/` e aggiornerà [angular.json](file:///Users/davidfrassi/SRC/agenti/canti/angular.json) e [tsconfig.json](file:///Users/davidfrassi/SRC/agenti/canti/tsconfig.json) inserendo il path alias (es. `@shared/core`). + +--- + +### Passo 2.2: Migrazione dei Servizi Core +Sposteremo tutti i servizi non legati direttamente alla UI da `src/app/services/` a `projects/shared-core/src/lib/services/`. + +Servizi da migrare: +* [audio-engine.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/audio-engine.service.ts) +* [canti.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/canti.service.ts) +* [lyrics-parser.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/lyrics-parser.service.ts) +* Eventuali altri helper o interfacce dati comuni. + +Esponiamo i servizi nel file `projects/shared-core/src/public-api.ts`: +```typescript +export * from './lib/services/audio-engine.service'; +export * from './lib/services/canti.service'; +export * from './lib/services/lyrics-parser.service'; +``` + +Aggiorneremo quindi gli import all'interno dell'applicazione principale `canti` (e successivamente `stereocomics`): +```typescript +// Da: +import { CantiService } from '../services/canti.service'; +// A: +import { CantiService } from '@shared/core'; +``` + +--- + +### Passo 2.3: Generazione della Nuova Applicazione Stereocomics +Creiamo la seconda applicazione all'interno del workspace: + +```bash +ng generate application stereocomics --routing --style=scss +``` + +In [angular.json](file:///Users/davidfrassi/SRC/agenti/canti/angular.json) verrà aggiunto un nuovo progetto denominato `stereocomics`. + +#### Integrazione Ionic +Per abilitare le funzionalità Ionic (componenti UI, gesture, ecc.) nella nuova applicazione, occorre: +1. Importare `IonicModule.forRoot()` nel file `projects/stereocomics/src/app/app.module.ts`. +2. Copiare o adattare la struttura di theming da `src/theme/` a `projects/stereocomics/src/theme/`. + +--- + +### Passo 2.4: Personalizzazione delle Pagine e dei Componenti +A differenza dell'Opzione 1 (dove le pagine HTML sono identiche), nell'Opzione 2 `stereocomics` ha le sue pagine indipendenti in `projects/stereocomics/src/app/pages/`. + +È possibile: +* Creare layout completamente differenti. +* Aggiungere nuove feature o pagine esclusive (es. una sezione "Comics" o "Store") senza intaccare minimamente l'applicazione `canti`. +* Importare i servizi core da `@shared/core` in ciascuna pagina per gestire la logica dei canti e dell'audio. + +--- + +### Passo 2.5: Script in `package.json` +Modificheremo gli script di avvio e build per differenziare i target: + +```json +"scripts": { + "start:canti": "ng serve app --port=4200", + "start:stereocomics": "ng serve stereocomics --port=4300", + "build:shared": "ng build shared-core", + "build:canti": "npm run build:shared && ng build app --configuration=production", + "build:stereocomics": "npm run build:shared && ng build stereocomics --configuration=production" +} +``` + +--- + +### Passo 2.6: Gestione di Capacitor (Mobile Apps Separate) +Per compilare le due app per iOS/Android in modo totalmente indipendente: +1. L'app `canti` continuerà ad usare la configurazione di Capacitor a livello di root, oppure verrà spostata in una sottocartella. +2. Inizializziamo Capacitor specificamente per `stereocomics` posizionando un file `capacitor.config.ts` all'interno di `projects/stereocomics/`: + +```typescript +import { CapacitorConfig } from '@capacitor/cli'; + +const config: CapacitorConfig = { + appId: 'it.stereocomics.app', + appName: 'Stereocomics', + webDir: '../../dist/stereocomics', // Punterà alla cartella di build di Angular + bundledWebRuntime: false +}; + +export default config; +``` + +--- + +## 3. Vantaggi e Svantaggi dell'Opzione 2 + +### Vantaggi: +1. **Massima Libertà di Design e UX**: L'applicazione `stereocomics` può avere una struttura di navigazione, pagine e flussi utente completamente diversi da `canti`. +2. **Isolamento del Codice UI**: I cambiamenti estetici o le nuove feature di interfaccia introdotte su Stereocomics non rischiano di rompere l'applicazione Canti originale. +3. **Riutilizzo della Logica di Business**: Tutta la logica complessa dei database locali, del lettore audio e dei parser rimane centralizzata e testata una volta sola nella libreria `@shared/core`. + +### Svantaggi: +1. **Sforzo Iniziale Elevato**: Richiede un refactoring iniziale importante per estrarre tutti i servizi e ridefinire i path di importazione in tutto il progetto. +2. **Build più Lente**: La compilazione richiede prima la build delle librerie condivise e poi dell'applicazione specifica. +3. **Gestione delle Dipendenze**: Sebbene condividano lo stesso `package.json`, l'aggiornamento di una libreria esterna (es. Ionic o Angular) deve essere testato su entrambe le applicazioni per evitare regressioni. + +--- + +## 4. Criteri di Accettazione e Verifica (Verification Plan) + +### Verifica dello Sviluppo Locale +1. Eseguire `npm run start:canti` -> Verificare il funzionamento completo dell'app principale sulla porta `4200`. +2. Eseguire `npm run start:stereocomics` -> Verificare che la nuova app risponda sulla porta `4300` con il layout personalizzato. + +### Verifica della Compilazione Condivisa +1. Apportare una modifica al servizio `CantiService` (es. aggiungere un log). +2. Verificare che la modifica sia visibile ed efficace sia su `canti` che su `stereocomics` dopo aver compilato la libreria condivisa. diff --git a/documenti/clonazione_stereocomics.md b/documenti/clonazione_stereocomics.md new file mode 100644 index 0000000..579c8b0 --- /dev/null +++ b/documenti/clonazione_stereocomics.md @@ -0,0 +1,164 @@ +# Guida alla Creazione di "stereocomics" tramite Angular Workspace Monorepo + +Questo documento descrive dettagliatamente la strategia dell'**Opzione 2 (Monorepo)**. L'obiettivo è trasformare l'attuale struttura del progetto in un Workspace Angular multi-applicazione, dove le logiche funzionali (servizi, parser, gestione audio) risiedono in una libreria condivisa, mentre le applicazioni `canti` e `stereocomics` rimangono indipendenti per quanto riguarda interfacce grafiche, stili, asset e configurazioni. + +--- + +## Struttura Finale del Workspace Monorepo + +Al termine del processo, la struttura delle cartelle del progetto si presenterà così: + +```text +canti/ (Root del Workspace) +├── angular.json # Configurazione di build per entrambi i progetti +├── package.json # Dipendenze condivise +├── tsconfig.json # Configurazione TypeScript con path alias per il core +├── src/ # Codice sorgente dell'applicazione originale "canti" +│ ├── app/ # Componenti, pagine e routing specifici di canti +│ └── assets/ # Immagini, loghi e risorse di canti +└── projects/ + ├── core/ # LIBRERIA CONDIVISA (TypeScript puro) + │ └── src/ + │ ├── public-api.ts # Esporta i servizi core + │ └── lib/ + │ └── services/ # I servizi estratti (audio, parser, canti, settings, ecc.) + └── stereocomics/ # NUOVA APPLICAZIONE "stereocomics" + ├── src/ + │ ├── app/ # Pagine, componenti e routing specifici di stereocomics + │ ├── assets/ # Loghi, immagini e splash screen di stereocomics + │ └── theme/ # CSS/SCSS personalizzato (variabili di colore diverse) + └── capacitor.config.ts # Configurazione Capacitor specifica (es. per iOS/Android) +``` + +--- + +## Fasi di Implementazione Dettagliate + +### Fase 1: Creazione della Libreria Condivisa (`core`) +Il primo passo consiste nel creare un modulo di libreria all'interno del workspace. + +1. **Generazione della libreria**: + Utilizzando l'Angular CLI dalla root del progetto: + ```bash + ng generate library core --prefix=core + ``` + Questo comando creerà la cartella `projects/core` e configurerà automaticamente i path alias nel file `tsconfig.json` (es. `"@core/*"` o `"core"`). + +2. **Migrazione dei Servizi**: + Sposteremo i file dei servizi core da `src/app/services/` a `projects/core/src/lib/services/`. I file principali da migrare includono: + - [lyrics-parser.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/lyrics-parser.service.ts) + - [audio-engine.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/audio-engine.service.ts) + - [canti.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/canti.service.ts) + - [playlist.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/playlist.service.ts) + - [settings.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/settings.service.ts) + - [comunita.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/comunita.service.ts) + - E gli altri servizi correlati. + +3. **Esportazione delle API**: + Nel file `projects/core/src/public-api.ts`, esporteremo tutti i servizi migrati in modo che siano importabili dalle applicazioni esterne: + ```typescript + export * from './lib/services/canti.service'; + export * from './lib/services/lyrics-parser.service'; + // ... altre esportazioni + ``` + +4. **Compilazione iniziale**: + Si compila la libreria core affinché sia disponibile per i progetti: + ```bash + ng build core + ``` + +--- + +### Fase 2: Adeguamento dell'Applicazione `canti` +Dopo aver spostato i servizi nella libreria condivisa, dobbiamo aggiornare l'applicazione originale affinché consumi la libreria anziché i vecchi file locali. + +1. **Aggiornamento degli Import**: + In tutti i componenti e pagine di `canti` (es. `src/app/home/home.page.ts`), modificheremo gli import dei servizi: + *Prima:* + ```typescript + import { CantiService } from '../services/canti.service'; + ``` + *Dopo:* + ```typescript + import { CantiService } from 'core'; + ``` + +2. **Rimozione dei Vecchi Servizi**: + Elimineremo la cartella `src/app/services/` ormai vuota. + +3. **Test di Verifica**: + Avvieremo `canti` con `npm run start` (o `ng serve`) per assicurarci che l'applicazione funzioni correttamente importando i servizi dalla libreria. + +--- + +### Fase 3: Generazione dell'Applicazione `stereocomics` +Ora che le fondamenta condivise sono pronte, creiamo la nuova applicazione `stereocomics`. + +1. **Generazione**: + Sempre tramite Angular CLI: + ```bash + ng generate application stereocomics --style=scss --routing=true + ``` + Questo configurerà un nuovo blocco chiamato `stereocomics` in `angular.json` e creerà la cartella `projects/stereocomics`. + +2. **Integrazione con Ionic**: + Aggiungeremo il supporto a Ionic nella nuova applicazione importando `IonicModule.forRoot()` nel file `projects/stereocomics/src/app/app.module.ts`. + +--- + +### Fase 4: Sviluppo e Personalizzazione di `stereocomics` +A questo punto abbiamo un'applicazione vergine che possiamo strutturare come vogliamo, riutilizzando però i servizi core. + +1. **Struttura delle Pagine**: + Possiamo decidere di copiare le pagine esistenti di `canti` (se vogliamo che `stereocomics` parta con lo stesso layout per poi essere modificato) oppure creare pagine del tutto nuove. + Ad esempio, per generare una pagina specifica in stereocomics: + ```bash + ng generate page pages/home --project=stereocomics + ``` + +2. **Consumo dei Servizi Shared**: + Nel codice di `stereocomics`, per caricare i dati useremo la libreria condivisa: + ```typescript + import { Component, OnInit } from '@angular/core'; + import { CantiService } from 'core'; + + @Component({ ... }) + export class HomePage implements OnInit { + constructor(private cantiService: CantiService) {} + + ngOnInit() { + // Possiamo accedere a tutte le funzioni storiche + this.cantiService.loadCanti(); + } + } + ``` + +3. **Personalizzazione Visiva (Branding)**: + - Modificheremo `projects/stereocomics/src/theme/variables.scss` per definire la palette di colori di `stereocomics` (ad es. tonalità arancioni o viola, differenziandosi dal blu di `canti`). + - Sostituiremo gli asset in `projects/stereocomics/src/assets/` con loghi, icone e immagini dedicati a stereocomics. + +--- + +### Fase 5: Configurazione dei Comandi di Build +Aggiungeremo o modificheremo gli script nel file `package.json` per facilitare lo sviluppo parallelo: + +```json +"scripts": { + "start:canti": "ng serve app", + "start:stereocomics": "ng serve stereocomics", + "build:canti": "ng build app --configuration production", + "build:stereocomics": "ng build stereocomics --configuration production", + "watch:core": "ng build core --watch" +} +``` + +Durante lo sviluppo, se modifichi un servizio core, il comando `watch:core` ricompilerà automaticamente la libreria in background, aggiornando istantaneamente l'app che stai servendo localmente. + +--- + +## Vantaggi di questo Approccio + +* **Sorgente di Verità Unica (Single Source of Truth)**: La complessa logica di business (algoritmi di parsing, logica audio per i player, caching, sync) viene scritta, testata e manutenuta in un solo posto (`projects/core`). +* **Autonomia Grafica ed Esperienziale**: `stereocomics` ha le sue pagine HTML e i suoi fogli di stile CSS/SCSS. Può avere una navigazione a tab, mentre `canti` usa un menu laterale (sidemenu), senza alcun conflitto. +* **Semplicità di Aggiornamento delle Dipendenze**: Entrambe le applicazioni utilizzano gli stessi pacchetti npm (configurati nel `package.json` globale nella root), riducendo il disallineamento delle versioni delle librerie terze (es. Capacitor, Ionic, Angular). diff --git a/documenti/implementation_plan_stereocomics.md b/documenti/implementation_plan_stereocomics.md new file mode 100644 index 0000000..376acdf --- /dev/null +++ b/documenti/implementation_plan_stereocomics.md @@ -0,0 +1,72 @@ +# Piano Operativo: Clonazione e Personalizzazione in "stereocomics" + +Questo piano descrive le opzioni e le fasi operative per creare un clone del progetto **canti** denominato **stereocomics**. Il clone condividerà le stesse librerie funzionali di base (servizi, parser, logica audio, ecc.) offrendo al contempo completa libertà di personalizzazione (grafica, asset, configurazioni, ed eventuali pagine specifiche). + +--- + +## Opzioni Architetturali Proposte + +Prima di procedere con l'implementazione, è fondamentale scegliere l'approccio strutturale più adatto: + +### Opzione 1: White-Label / Multi-Configuration (Consigliata per Manutenibilità) +*Se l'applicazione stereocomics differisce principalmente per branding, colori, logo, configurazioni e alcuni testi, ma condivide la quasi totalità delle pagine e dei flussi.* +- **Come funziona**: Si mantiene un unico codice sorgente. Si usano i file di configurazione ambientale di Angular (`src/environments/`) e file CSS personalizzati per caricare dinamicamente loghi, stili (tramite variabili CSS/SCSS), e comportamenti in base alla build (es. `ng build --configuration=stereocomics`). +- **Pro**: Semplicità assoluta di manutenzione. Qualsiasi bug fix o nuova funzionalità su un servizio o una pagina si riflette istantaneamente su entrambi i brand senza duplicazione di codice. +- **Contro**: Meno flessibilità se le pagine di `stereocomics` dovranno divergere drasticamente a livello di layout HTML o logica di navigazione rispetto a `canti`. + +### Opzione 2: Angular Workspace Monorepo (Consigliata per Massima Personalizzazione) +*Se stereocomics deve avere pagine, componenti e flussi di navigazione diversi da canti, pur riutilizzando gli stessi servizi (audio, parser, database local, ecc.).* +- **Come funziona**: Si trasforma il progetto in un workspace Angular multi-applicazione. + 1. Si crea una libreria condivisa (es. `projects/shared-core`) dove vengono spostati tutti i servizi di base (`src/app/services/*`). + 2. L'applicazione attuale viene configurata come progetto `canti`. + 3. Viene generata una nuova applicazione Angular/Ionic nello stesso workspace (`projects/stereocomics`) che importa i servizi da `shared-core` ma ha le sue pagine, i suoi componenti e la sua veste grafica indipendenti. +- **Pro**: Massimo controllo. Ciascuna app ha la sua struttura di pagine, ma condividono al 100% la logica complessa dei servizi. +- **Contro**: Richiede una ristrutturazione iniziale dei path di importazione dei servizi nel progetto attuale. + +### Opzione 3: Repository / Cartella Indipendente +*Se si desidera un progetto completamente separato in una nuova cartella `/Users/davidfrassi/SRC/agenti/stereocomics`.* +- **Come funziona**: Si clona il progetto in una nuova cartella e si personalizza in modo indipendente. Per condividere le librerie, si può creare un package locale (`npm link`) o importare i servizi come sottomodulo git. +- **Pro**: Isolamento totale. +- **Contro**: Rischio elevato di divergenza del codice. I bug fix sui servizi in un progetto dovranno essere riportati manualmente o gestiti tramite rilasci di pacchetti. + +--- + +## User Review Required + +> [!IMPORTANT] +> Si prega di verificare quale delle tre opzioni si adatta meglio alle esigenze di sviluppo a lungo termine di **stereocomics**. +> +> - Se il clone differisce solo per loghi, colori e piccoli dettagli, l'**Opzione 1 (White-Label)** è la più rapida ed efficiente. +> - Se il clone deve avere un'interfaccia utente o funzionalità molto diverse pur usando la stessa logica di lettura/parsing, l'**Opzione 2 (Monorepo)** è la scelta ideale. + +--- + +## Fasi del Piano Operativo (Esempio basato sull'Opzione 2 - Monorepo) + +Se si sceglie l'approccio Monorepo, i passi saranno i seguenti: + +### Fase 1: Preparazione e Ristrutturazione (Refactoring dei Servizi) +1. Spostare i servizi core (ad es. [lyrics-parser.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/lyrics-parser.service.ts), [audio-engine.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/audio-engine.service.ts), [canti.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/canti.service.ts)) in una libreria condivisa o in una cartella core dedicata configurata con path alias in `tsconfig.json` (es. `@shared/services`). +2. Aggiornare gli import in tutto il progetto `canti` per utilizzare il nuovo path alias. + +### Fase 2: Creazione del Progetto Stereocomics +1. Generare la nuova applicazione all'interno del workspace o duplicare la struttura configurando il nuovo target in [angular.json](file:///Users/davidfrassi/SRC/agenti/canti/angular.json). +2. Configurare gli asset (immagini, loghi, splash screen) per `stereocomics` in una cartella dedicata. +3. Creare il file di configurazione specifico per stereocomics (`environment.stereocomics.ts`). + +### Fase 3: Personalizzazione e Stile +1. Creare un tema CSS/SCSS personalizzato per `stereocomics` modificando le variabili di colore Ionic/CSS. +2. Sviluppare eventuali componenti o pagine specifiche per `stereocomics`. + +### Fase 4: Configurazione della Build e Deploy +1. Configurare gli script npm in `package.json` per avviare e buildare specificamente il nuovo target (es. `npm run start:stereocomics`, `npm run build:stereocomics`). +2. Configurare Capacitor/PWA per il nuovo brand (nuovo package ID, nome dell'app, icone). + +--- + +## Verification Plan + +### Manual Verification +- Avvio di `canti` in modalità sviluppo per verificare che il refactoring dei servizi non abbia introdotto regressioni. +- Avvio di `stereocomics` per verificare il caricamento del nuovo tema, logo e impostazioni personalizzate. +- Test delle funzionalità core (riproduzione, parsing testi) in entrambe le applicazioni. diff --git a/editor-visuale.md b/editor-visuale.md new file mode 100644 index 0000000..53f73ed --- /dev/null +++ b/editor-visuale.md @@ -0,0 +1,164 @@ +# Specifiche e Considerazioni di Design: Editor Visuale Intelligente + +Questo documento raccoglie l'analisi e le specifiche di design per l'implementazione del sistema di **Scansione Fotocamera & AI** per la digitalizzazione rapida dei canti nella PWA. +L'obiettivo è progettare un'esperienza utente a "sfregamento zero" (zero friction), robusta anche in ambienti ostili (es. chiese senza campo) e capace di gestire le imperfezioni storiche dei libretti parrocchiali. + +--- + +## 1. Architettura della Pipeline Visiva + +Il processo si basa su un'interazione fluida tra client (PWA), proxy server ed il motore multimodale di visione artificiale (Google Gemini 2.5 Flash). + +```mermaid +graph TD + A[Inquadratura Fotocamera PWA] --> B[Compressione Client Canvas JPEG ~200KB] + B --> C{Connessione Rete?} + C -- Online --> D[Invia POST a /scanSong] + C -- Offline --> E[Salva in IndexedDB localmente] + E --> F[In attesa di Connessione...] + F --> C + D --> G[Chiamata a Gemini 2.5 Flash] + G --> H[Analisi Spaziale ed Estrazione JSON] + H --> I[Popolamento Automatico dell'Editor PWA] +``` + +--- + +## 2. Casi d'Uso Avanzati e Soluzioni Specifiche + +### A. Gestione Multi-Pagina (Canti Lunghi) +* **Problema**: Molti canti liturgici (es. Salmi o canti d'ingresso lunghi) si sviluppano su due pagine adiacenti o su foglietti fronte-retro separati. +* **Soluzione**: L'interfaccia dell'editor consentirà all'utente di aggiungere più scatti all'interno della stessa sessione di scansione prima dell'invio. +* **Gestione AI**: Le immagini verranno inviate in blocco al modello di visione (sfruttando l'enorme finestra di contesto di Gemini). Il prompt istruirà l'IA a considerare le foto come sequenziali, unendo il testo in un unico flusso coerente senza duplicare il titolo ed ordinando le strofe in modo corretto. + +### B. Correzione dei Refusi Storici (Libretti Anni '90) +* **Problema**: I libretti parrocchiali stampati decenni fa o digitati a macchina presentano spesso refusi tipografici, lettere scambiate o scorrettezze sugli accenti (es. `perche'` al posto di `perché`, `piu'` per `più`, `Gesu'` per `Gesù`). +* **Soluzione**: Sfruttando la comprensione semantica del modello di linguaggio (LLM), l'IA non effettua una mera trascrizione pixel-per-pixel, ma analizza il senso delle parole nel contesto dei canti liturgici italiani (molti dei quali fanno già parte della sua conoscenza pregressa). +* **Risultato**: Restituzione di un testo grammaticalmente perfetto e pulito, correggendo automaticamente i vecchi accenti e gli errori di battitura della carta originale. + +### C. Traduzione ed Uniformazione degli Accordi +* **Problema**: Gli spartiti o canzonieri cartacei possono utilizzare la notazione internazionale (`C, D, E, F, G, A, B`) anziché la notazione latina standard italiana (`Do, Re, Mi, Fa, Sol, La, Si`). +* **Soluzione**: Nel prompt di sistema, l'IA viene istruita ad uniformare tutti gli accordi alla notazione italiana standard. +* **Esempio**: Se l'utente inquadra un canzonierino scout o internazionale scritto in notazione inglese (es. `[C] [G] [Am]`), il sistema lo tradurrà istantaneamente in `[Do] [Sol] [Lam]` prima di inviarlo all'editor della PWA, garantendo la compatibilità al 100% con il modulo di trasposizione interna dei toni. + +--- + +## 3. Strategia Offline (Resilienza in Chiesa) + +Le chiese sono notoriamente ambienti difficili per la connettività di rete (mura in pietra spesse, sotterranei, assenza di ripetitori vicini). Il sistema non deve dipendere da una connessione sempre attiva. + +### Flusso Offline con IndexedDB +1. L'utente scatta la foto (o seleziona l'immagine) dall'editor mentre si trova offline. +2. L'app converte l'immagine in `Blob` e la salva localmente all'interno di **IndexedDB** associandola a una coda di scansioni pendenti (`scan-offline-queue`). +3. L'interfaccia mostra un avviso rassicurante: + > 💾 *Fogli acquisiti offline! L'app elaborerà automaticamente la scansione del canto non appena rileverai una connessione internet stabile.* +4. Il `ConnectivityService` della PWA monitora lo stato della rete. Non appena il dispositivo torna online (es. all'uscita dalla chiesa o sotto WiFi): + * L'app estrae l'immagine da IndexedDB. + * Effettua la chiamata POST a `/scanSong`. + * Riceve il JSON tradotto e notifica l'utente (o precompila la scheda dei canti proposti). + +--- + +## 4. Specifiche del Prompt di Sistema (System Prompt) + +L'output del backend deve essere rigidamente controllato e tipizzato per consentire al client Angular di digerirlo senza eccezioni di parsing. Il prompt di sistema da implementare sul proxy API sarà il seguente: + +```text +Sei un OCR musicale multimodale specializzato in canti liturgici e religiosi cristiani. +Analizza l'immagine fornita (o il set di immagini sequenziali) e restituisci ESCLUSIVAMENTE un oggetto JSON valido. Non aggiungere spiegazioni o markdown. + +Schema JSON di risposta: +{ + "titolo": "String (titolo del canto)", + "autore": "String o null", + "sezioni": [ + { + "tipo": "ritornello" | "strofa", + "numero": Number o null (solo per le strofe, es. 1, 2, 3), + "righe": [ + "Testo completo della riga con accordi musicali inseriti in linea tra parentesi quadre prima della sillaba corretta. Es: [Do]Tu sei la mia [Sol]vita" + ] + } + ] +} + +Regole di formattazione: +1. Traduci tutti gli accordi in notazione italiana (Do, Re, Mi, Fa, Sol, La, Si, con 'm' per i minori, '7' per le settime, ecc.). +2. Inserisci gli accordi esattamente nel punto in cui cadono spazialmente sopra le parole dell'immagine. +3. Correggi accenti storici errati (es. trasformando 'perche'' in 'perché') e refusi evidenti. +``` + +Questo approccio garantisce che la PWA riceva un formato perfettamente strutturato e pronto per essere inserito direttamente nelle righe del database locale. + +--- + +## 5. Approccio 100% Locale e Gratuito (Client-Side) + +Se il vincolo fondamentale è **non utilizzare alcun servizio cloud a pagamento o esterno**, possiamo spostare l'intero carico di elaborazione (OCR ed allineamento) **direttamente all'interno del browser dell'utente (client-side)** in modo 100% gratuito ed autonomo. + +Ciò è realizzabile integrando due componenti open-source nella PWA: + +1. **Tesseract.js** (compilato in WebAssembly per il browser): si occupa di estrarre il testo e, soprattutto, di fornirci i metadati spaziali di ogni singola parola. +2. **Algoritmo Euristico di Allineamento Spaziale**: un algoritmo scritto da noi in TypeScript che mappa la posizione fisica degli accordi rispetto al testo. + +### Come funziona l'algoritmo di allineamento locale? + +Quando Tesseract.js scansiona l'immagine, non restituisce solo una stringa, ma un array di parole in cui ogni parola contiene il testo ed il suo **Bounding Box (rettangolo di coordinate fisiche sull'immagine: `x0`, `y0`, `x1`, `y1`)**: + +```typescript +interface OCRWord { + text: string; + bbox: { x0: number; y0: number; x1: number; y1: number }; +} +``` + +L'algoritmo elabora questi dati in 4 fasi: + +#### Fase 1: Raggruppamento in Righe Fisiche +Le parole vengono ordinate per coordinata `y0`. Le parole che hanno valori di `y0` simili (con una tolleranza basata sull'altezza dei caratteri, es. ±15 pixel) vengono raggruppate nella stessa **riga orizzontale**. + +#### Fase 2: Classificazione delle Righe (Accordi vs. Testo) +Ogni riga viene analizzata per determinare la sua natura: +* **Riga di Accordi**: Se più del 70% delle parole nella riga corrisponde a pattern di accordi noti (es. parole corte come `Do`, `Sol`, `Re7`, `Lam`, `C`, `G`, `D7`), la riga viene marcata come riga di accordi. +* **Riga di Testo**: In tutti gli altri casi, viene considerata una riga di testo normale. + +#### Fase 3: Mappatura e Iniezione degli Accordi +Per ogni **Riga di Accordi**, individuiamo la **Riga di Testo** immediatamente sottostante (quella con coordinata `y` successiva più vicina). +Per ciascun accordo presente nella riga: +1. Calcoliamo la sua coordinata orizzontale centrale: `x_accordo = (bbox.x0 + bbox.x1) / 2`. +2. Scorriamo le parole della riga di testo sottostante per trovare quale parola (o lettera) ha la coordinata `x` più vicina a `x_accordo`. +3. Inseriamo la stringa dell'accordo tra parentesi quadre (es. `[Re]`) esattamente prima di quella parola nel testo finale. + +```text +Spaziatura fisica sull'immagine: +Riga 1 (Accordi): [Do] [Sol] +Riga 2 (Testo): Tu sei la mia vita, altro io non ho. + ↑ ↑ + x=120 x=480 +``` + +#### Fase 4: Segmentazione Strutturale delle Sezioni +L'algoritmo identifica i cambi di sezione (es. il passaggio da Ritornello a Strofa) misurando lo spazio verticale (`gap y`) tra le righe di testo. Un distanziamento verticale significativamente maggiore della media indica una separazione di strofa, consentendo di dividere il canto in blocchi strutturati. + +### Pro e Contro dell'Approccio Locale + +| Vantaggi | Svantaggi | +| :--- | :--- | +| 🟢 **100% Gratuito**: Nessun costo di licenza o API esterne. | 🔴 **Uso Risorse**: L'elaborazione OCR avviene sul telefono dell'utente (richiede 3-5 secondi). | +| 🟢 **Totale Privacy**: Le immagini non lasciano mai il dispositivo. | 🔴 **Meno tolleranza alle pieghe**: Rispetto a Gemini, un OCR locale soffre di più se la foto è storta o con ombre. | +| 🟢 **Funzionamento Offline**: Funziona anche nel deserto, senza alcuna rete. | 🔴 **Nessuna correzione lessicale**: Non corregge gli errori grammaticali storici del foglio cartaceo. | + +--- + +## 6. Il Compromesso Ideale: Gemini API Free Tier + +Esiste una terza via che unisce il meglio dei due mondi (la precisione assoluta dell'AI e il costo zero): **il Free Tier delle API di Google Gemini 2.5 Flash**. + +Google offre tramite **Google AI Studio** un piano d'uso completamente gratuito con i seguenti limiti: +* **15 Richieste al minuto (RPM)** +* **1500 Richieste al giorno (RPD)** + +Per un'applicazione di canti religiosi dove l'aggiunta di nuovi brani è un'operazione sporadica (eseguita da pochi amministratori/chitarristi solo quando si impara un canto nuovo), **questi limiti gratuiti non verranno mai superati**. + +* **Implementazione sicura**: Per evitare di inserire la chiave API gratuita all'interno del codice frontend (dove chiunque potrebbe rubarla), si fa passare la richiesta attraverso una semplice funzione serverless gratuita (es. su *Vercel Free Tier* o *Cloudflare Workers*), che funge da proxy sicuro e vi applica la chiave API prima di chiamare Google. + diff --git a/implementazione_servizio_miei.md b/implementazione_servizio_miei.md new file mode 100644 index 0000000..f542cfb --- /dev/null +++ b/implementazione_servizio_miei.md @@ -0,0 +1,84 @@ +# Specifiche Tecniche: Integrazione Servizio `/miei` con PWA Canti + +Questo documento descrive le specifiche dell'endpoint `/miei` implementato sul server Node.js e fornisce le linee guida per implementare la sincronizzazione e l'invio delle playlist locali e dei canti personalizzati ("canti miei") dalla PWA. + +--- + +## 🌐 Dettagli dell'Endpoint `/miei` + +- **Metodo HTTP**: `POST` +- **URL di Sviluppo**: `http://localhost:3000/miei` (o l'IP/porta del tuo server in produzione) +- **Content-Type**: `application/json` +- **Limite Dimensione Body**: `10MB` (per supportare liste e testi completi di canti) + +### 🔑 Identificazione Utente (`uid`) +L'endpoint richiede l'identificativo unico dell'utente (`uid`). Può essere trasmesso in tre modi (in ordine di priorità): +1. **Header HTTP**: `x-user-uid` (scelta consigliata) o `uid` +2. **Query Parameter**: `?uid=` +3. **Wrapper nel Body**: Se il corpo è un oggetto del tipo `{ "uid": "...", "canti": [...] }` + +> [!WARNING] +> L'UID dell'utente deve essere una stringa valida e sicura. Sono accettati solo caratteri alfanumerici, trattini e trattini bassi (`^[a-zA-Z0-9_\-]+$`). Qualsiasi tentativo di path traversal (es. contenente `.` o `/`) restituirà un errore `400 Bad Request`. + +--- + +## 📦 Formato dei Dati Richiesto (Payload) + +L'endpoint si aspetta di ricevere un **array JSON** contenente la lista dei canti dell'utente (formato analogo a `canti.json`). + +### Esempio di Payload (Array di Canti) +```json +[ + { + "id_canti": 9001, + "titolo": "Mio Canto Personalizzato 1", + "momenti": ["Ingresso"], + "periodi": ["Lode"], + "testo": "Testo del mio canto personalizzato...\nRit: Alleluia!" + }, + { + "id_canti": 9002, + "titolo": "Mio Canto Personalizzato 2", + "momenti": ["Comunione"], + "periodi": [], + "testo": "Testo del secondo canto..." + } +] +``` + +--- + +## 🔄 Comportamento del Server + +1. **Ricezione e Validazione**: + - Estrae l'UID ed il payload dei canti. + - Valida l'UID (sicurezza path traversal) e verifica che il payload sia un array JSON. In caso contrario, risponde con `400 Bad Request`. +2. **Logica di Backup**: + - Se nella cartella `data/` del server esiste già un file associato all'utente (`data/.json`), ne crea automaticamente una copia di backup rinominandola o copiandola in `data/.bak.json`. +3. **Salvataggio**: + - Scrive il nuovo JSON in `data/.json`. + - Risponde con `200 OK` e un JSON di conferma: + ```json + { + "success": true, + "message": "File salvato con successo.", + "uid": "utente_test_123", + "backupCreated": true + } + ``` + +--- + +## 🛠️ Requisiti per l'Implementazione nella PWA (Client Locale Mac M1) + +L'istanza di Antigravity che lavora sul codice della PWA locale dovrà implementare una funzione di sincronizzazione (es. `syncLocalDataToServer`) che esegua i seguenti passi: + +1. **Recupero dei dati locali**: + - Estrarre le playlist locali e i canti personalizzati creati dall'utente (solitamente salvati in `localStorage`, `IndexedDB`, o altro database locale). +2. **Normalizzazione e Formattazione**: + - Formattare e unire queste informazioni in un unico array JSON strutturato con i campi chiave per ciascun canto (`id_canti`, `titolo`, `momenti`, `periodi`, `testo`). +3. **Invio al Server**: + - Effettuare una chiamata `fetch` (POST) verso l'endpoint `/miei`. + - Passare l'UID dell'utente autenticato (es. da Firebase Auth o altro sistema di sessione) tramite l'header `x-user-uid`. +4. **Gestione del Feedback**: + - Mostrare all'utente una notifica di successo o gestire eventuali errori di rete o validazione. diff --git a/ionic.config.json b/ionic.config.json new file mode 100644 index 0000000..dd4ff56 --- /dev/null +++ b/ionic.config.json @@ -0,0 +1,5 @@ +{ + "name": "tmp-app", + "integrations": {}, + "type": "angular" +} diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..611c27f --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,44 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, './coverage/app'), + subdir: '.', + reporters: [ + { type: 'html' }, + { type: 'text-summary' } + ] + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true + }); +}; diff --git a/liturgia_strategy.md b/liturgia_strategy.md new file mode 100644 index 0000000..e4b9b56 --- /dev/null +++ b/liturgia_strategy.md @@ -0,0 +1,40 @@ +# Strategia di Suggerimento Canti Liturgici + +Questo documento descrive l'approccio tecnico utilizzato per suggerire i canti attinenti alle letture del giorno nella PWA "CantiCristiani". + +## 1. Algoritmo di Analisi (Keyword Matching) + +Al momento **non viene utilizzata un'Intelligenza Artificiale generativa (LLM)** per due motivi principali: +- **Performance**: L'analisi avviene istantaneamente sul dispositivo dell'utente senza chiamate API esterne lente. +- **Privacy e Offline**: Il sistema può funzionare anche con una connettività limitata una volta scaricato il testo delle letture. + +### Fasi dell'Algoritmo: + +1. **Keyword Extraction**: + - Il testo di tutte le letture (Prima, Salmo, Seconda, Vangelo) viene normalizzato in minuscolo. + - Vengono rimosse le "stop words" (parole comuni come articoli, preposizioni, congiunzioni). + - Vengono estratte solo le parole con lunghezza superiore a 3 caratteri per evitare rumore. +2. **Ponderazione e Scoring**: + - Ogni canto nel database viene analizzato cercando le keyword estratte. + - **Titolo (Peso 10)**: Se una parola chiave appare nel titolo, il punteggio del canto aumenta drasticamente. + - **Testo/Lyrics (Peso 1)**: Ogni occorrenza di una parola chiave nel testo del canto aggiunge 1 punto al punteggio totale. +3. **Classificazione per Momento Liturgico**: + - I canti vengono raggruppati in base alle categorie liturgiche (Ingresso, Gloria, Offertorio, Comunione, ecc.) definite nel database. + - Il sistema seleziona i migliori 3 canti per ogni categoria per offrire una scelta bilanciata. + +## 2. Selezione della Data Predefinita + +L'applicazione calcola automaticamente la **prossima domenica** come data di default. Questo perché la maggior parte degli utenti utilizza la funzione per preparare la liturgia festiva imminente. + +## 3. Sviluppi Futuri: Ricerca Semantica (Embeddings) + +Per superare i limiti del matching testuale, la strategia futura prevede l'integrazione di tecniche di **Semantic Search** che possono essere eseguite direttamente nella PWA: + +### Architettura Proposta: +- **Pre-calcolo dei Vettori**: Generazione dei vettori (embeddings) per l'intero database dei canti. Questi dati verrebbero inclusi in una versione estesa del file `canti.json`. +- **Analisi On-Device**: Utilizzo di librerie matematiche leggere (come `similarity-js`) per calcolare la "distanza del coseno" tra il vettore della lettura e quelli dei canti. +- **Vantaggi**: Il sistema identificherebbe correlazioni concettuali (es. "Luce" -> "Mondo", "Pane" -> "Eucarestia") anche in assenza di corrispondenze testuali esatte. + +### Implementazione Tecnica: +1. Integrazione di un modello di embedding (es. `all-MiniLM-L6-v2`) via Web Workers per non bloccare l'interfaccia. +2. Memorizzazione locale dei vettori tramite IndexedDB per garantire performance elevate dopo il primo caricamento. diff --git a/ngsw-config.json b/ngsw-config.json new file mode 100644 index 0000000..ae56e83 --- /dev/null +++ b/ngsw-config.json @@ -0,0 +1,43 @@ +{ + "$schema": "./node_modules/@angular/service-worker/config/schema.json", + "index": "/index.html", + "assetGroups": [ + { + "name": "app", + "installMode": "prefetch", + "resources": { + "files": [ + "/index.html", + "/manifest.webmanifest", + "/*.css", + "/*.js" + ] + } + }, + { + "name": "assets", + "installMode": "prefetch", + "updateMode": "prefetch", + "resources": { + "files": [ + "/assets/**/*", + "/**/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)" + ] + } + } + ], + "dataGroups": [ + { + "name": "canti-api", + "urls": [ + "https://www.canticristiani.it/it/api/canti.json" + ], + "cacheConfig": { + "maxSize": 1, + "maxAge": "7d", + "timeout": "10s", + "strategy": "performance" + } + } + ] +} diff --git a/nuova_funziona_importazione_comunity.md b/nuova_funziona_importazione_comunity.md new file mode 100644 index 0000000..7800de7 --- /dev/null +++ b/nuova_funziona_importazione_comunity.md @@ -0,0 +1,54 @@ +# Piano di Implementazione: Importazione Playlist e Canti della Comunità + +Questo piano descrive i dettagli tecnici per l'aggiunta di una funzione che consente di importare localmente tutte le playlist e i canti personalizzati di una comunità attiva. + +## User Review Required + +> [!IMPORTANT] +> L'importazione comporterà il salvataggio dei canti personalizzati della comunità direttamente nei "Miei Canti" dell'utente (evitando duplicati) e la creazione di playlist locali. Le playlist locali create includeranno: +> 1. Una playlist principale con il nome della comunità stessa contenente tutti i canti della comunità con le rispettive tonalità, velocità di scorrimento e testi personalizzati/aggiuntivi. +> 2. Tutte le singole scalette/playlist della comunità importate come playlist locali indipendenti e modificabili. + +## Proposed Changes + +### Servizi e Logica di Business + +#### [MODIFY] [playlist.service.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/services/playlist.service.ts) +Aggiungeremo un metodo helper o esporremo le funzioni di salvataggio di massa per le playlist importate, garantendo che le impostazioni dei brani (`songSettings` contenenti tonalità e velocità di scorrimento) siano preservate correttamente. + +### Pagina Impostazioni (Settings Page) + +#### [MODIFY] [settings.page.html](file:///Users/davidfrassi/SRC/agenti/canti/src/app/pages/settings/settings.page.html) +Nel gruppo "Comunità", quando una comunità è attiva, aggiungeremo un nuovo pulsante sotto i dettagli della comunità: +- **Pulsante**: "Importa Playlist e Canti" con icona `cloud-download-outline`. + +#### [MODIFY] [settings.page.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/pages/settings/settings.page.ts) +Implementeremo il metodo `importComunitaPlaylists()` che svolgerà i seguenti passaggi: +1. **Verifica dello Stato**: Si assicura che una comunità sia attiva e che i dati siano caricati. +2. **Importazione dei Canti Personalizzati**: + - Scorrerà i canti di `comunitaService.comunitaCantiPersonali()`. + - Per ciascun canto, verificherà se è già presente nei "Miei Canti" (tramite `myCantiService.myCanti()`). + - Se assente, lo aggiungerà con prefisso ID `my_` ed effettuerà il salvataggio in locale su `MyCantiService`. +3. **Creazione della Playlist della Comunità**: + - Creerà una playlist avente come nome il nome della comunità stessa. + - Popolerà i canti associando sia i canti standard sia i canti personali importati. + - Assocerà le impostazioni di tonalità e velocità di scorrimento da `comunitaCantiSettings()`. Per la velocità, si utilizzerà la formula di conversione standard (es. `Math.round(speed / 100)`). +4. **Importazione delle Scalette (Playlist) Aggiuntive**: + - Per ciascuna scaletta in `comunitaService.comunitaScalette()`, creerà una playlist locale corrispondente. + - Per ciascun canto della scaletta, cercherà se esiste un'impostazione in `comunitaCantiSettings()` per impostare tonalità e velocità specifiche all'interno della playlist. +5. **Salvataggio e Feedback**: + - Salverà tutte le nuove playlist tramite `playlistService.savePlaylist()`. + - Mostrerà un alert di conferma iniziale e un toast di successo finale. + +## Verification Plan + +### Manual Verification +- Attivare una comunità di prova (es. con codice noto o inserendone uno valido). +- Andare nelle impostazioni e cliccare sul nuovo pulsante "Importa Playlist e Canti". +- Verificare la comparsa dell'alert di conferma. +- Confermare l'importazione. +- Verificare tramite Toast e navigando nella home che: + - Sia presente una playlist locale con il nome della comunità contenente tutti i canti ordinati e configurati. + - Siano presenti le playlist secondarie della comunità convertite in playlist locali. + - Le tonalità modificate e le velocità di scorrimento siano state importate correttamente per ciascun canto all'interno delle playlist. + - I canti personali/aggiuntivi siano stati importati nella sezione "Miei Canti" e siano visualizzabili. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..bf6757e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,20266 @@ +{ + "name": "canticristiani", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "canticristiani", + "version": "0.0.1", + "dependencies": { + "@angular/animations": "^20.0.0", + "@angular/cdk": "^20.2.14", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/forms": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-browser-dynamic": "^20.0.0", + "@angular/router": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@capacitor/app": "8.1.0", + "@capacitor/core": "8.3.1", + "@capacitor/haptics": "8.0.2", + "@capacitor/keyboard": "8.0.3", + "@capacitor/preferences": "^8.0.1", + "@capacitor/status-bar": "8.0.2", + "@ionic/angular": "^8.0.0", + "@ionic/storage-angular": "^4.0.0", + "@zxing/browser": "^0.2.0", + "@zxing/library": "^0.23.0", + "@zxing/ngx-scanner": "^21.0.0", + "ionicons": "^7.0.0", + "mammoth": "^1.12.0", + "pdfjs-dist": "^5.7.284", + "qrcode": "^1.5.4", + "rxjs": "~7.8.0", + "tesseract.js": "^7.0.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.0", + "@angular-eslint/builder": "^20.0.0", + "@angular-eslint/eslint-plugin": "^20.0.0", + "@angular-eslint/eslint-plugin-template": "^20.0.0", + "@angular-eslint/schematics": "^20.0.0", + "@angular-eslint/template-parser": "^20.0.0", + "@angular/cli": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/language-service": "^20.0.0", + "@capacitor/cli": "8.3.1", + "@ionic/angular-toolkit": "^12.0.0", + "@types/jasmine": "~5.1.0", + "@types/qrcode": "^1.5.6", + "@typescript-eslint/eslint-plugin": "^8.18.0", + "@typescript-eslint/parser": "^8.18.0", + "eslint": "^9.16.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-prefer-arrow": "1.2.2", + "jasmine-core": "~5.1.0", + "jasmine-spec-reporter": "~5.0.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.9.0" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.1.0.tgz", + "integrity": "sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.35.0.tgz", + "integrity": "sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.35.0.tgz", + "integrity": "sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.35.0.tgz", + "integrity": "sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.35.0.tgz", + "integrity": "sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.35.0.tgz", + "integrity": "sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.35.0.tgz", + "integrity": "sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.35.0.tgz", + "integrity": "sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.35.0.tgz", + "integrity": "sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.35.0.tgz", + "integrity": "sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.35.0.tgz", + "integrity": "sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.35.0.tgz", + "integrity": "sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.35.0.tgz", + "integrity": "sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.35.0.tgz", + "integrity": "sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.25.tgz", + "integrity": "sha512-39pTqt4wSmpD1WeCee46oSGXRh6TR1PFd9GZEwyZoMvBTMs8mE2sXGxUgd4Qyi5CkQ1XnCM5XfgJcjUWUQRoGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.3.25", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.25.tgz", + "integrity": "sha512-jp2sbJhbVRT65RbGENY/lz3Z0W0D50Af3xzENmLDLBVp9uhlpIPSTC9LG4CEPV7T6H5Oq6ymHKM+OO5WwTlHHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/build-webpack": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular/build": "20.3.25", + "@babel/core": "7.28.3", + "@babel/generator": "7.28.3", + "@babel/helper-annotate-as-pure": "7.27.3", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.28.0", + "@babel/plugin-transform-async-to-generator": "7.27.1", + "@babel/plugin-transform-runtime": "7.28.3", + "@babel/preset-env": "7.28.3", + "@babel/runtime": "7.28.3", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "20.3.25", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.21", + "babel-loader": "10.0.0", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "14.0.0", + "css-loader": "7.1.2", + "esbuild-wasm": "0.28.0", + "fast-glob": "3.3.3", + "http-proxy-middleware": "3.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.4.0", + "less-loader": "12.3.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.4", + "open": "10.2.0", + "ora": "8.2.0", + "picomatch": "4.0.4", + "piscina": "5.1.3", + "postcss": "8.5.12", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.2", + "sass": "1.90.0", + "sass-loader": "16.0.5", + "semver": "7.7.2", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.43.1", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.105.0", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.2", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.28.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.3.25", + "@web/test-runner": "^0.20.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0 || ^30.2.0", + "jest-environment-jsdom": "^29.5.0 || ^30.2.0", + "karma": "^6.3.0", + "ng-packagr": "^20.0.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.8 <6.0" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.2003.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.25.tgz", + "integrity": "sha512-jJMpYBdWeRfvrCna7JWsyMBbvjMcPblyzh4/pSfWw5znla3hJGzDtmb84qKZ+IB8eZNEcky4iGR5LK2jdGFLAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2003.25", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/core": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.25.tgz", + "integrity": "sha512-pSfeWEoS1y9zxqTOw0Etj2NXkRmp/aU52wdnyq3KqVA9cJtgxtlOHlBBNswTil4dReojEy+0K1xJm+mLuWuLxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.18.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.25.tgz", + "integrity": "sha512-IB0IHf8ZRqr69hT/XIfHkYLPAYHWQ/WUc6+fKHBwq58jJlm/y5QUeTEuXvJ18IX/+hUIqw+E2Q3T0N9rLDLzXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.3.25", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "8.2.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-eslint/builder": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-20.7.0.tgz", + "integrity": "sha512-qgf4Cfs1z0VsVpzF/OnxDRvBp60OIzeCsp4mzlckWYVniKo19EPIN6kFDol5eTAIOMPgiBQlMIwgQMHgocXEig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": ">= 0.2000.0 < 0.2100.0", + "@angular-devkit/core": ">= 20.0.0 < 21.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-20.7.0.tgz", + "integrity": "sha512-9KPz24YoiL0SvTtTX6sd1zmysU5cKOCcmpEiXkCoO3L2oYZGlVxmMT4hfSaHMt8qmfvV2KzQMoR6DZM84BwRzQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-20.7.0.tgz", + "integrity": "sha512-aHH2YTiaonojsKN+y2z4IMugCwdsH/dYIjYBig6kfoSPyf9rGK4zx+gnNGq/pGRjF3bOYrmFgIviYpQVb80inQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "20.7.0", + "@angular-eslint/utils": "20.7.0", + "ts-api-utils": "^2.1.0" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-20.7.0.tgz", + "integrity": "sha512-WFmvW2vBR6ExsSKEaActQTteyw6ikWyuJau9XmWEPFd+2eusEt/+wO21ybjDn3uc5FTp1IcdhfYy+U5OdDjH5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "20.7.0", + "@angular-eslint/utils": "20.7.0", + "aria-query": "5.3.2", + "axobject-query": "4.1.0" + }, + "peerDependencies": { + "@angular-eslint/template-parser": "20.7.0", + "@typescript-eslint/types": "^7.11.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/schematics": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-20.7.0.tgz", + "integrity": "sha512-S0onfRipDUIL6gFGTFjiWwUDhi42XYrBoi3kJ3wBbKBeIgYv9SP1ppTKDD4ZoDaDU9cQE8nToX7iPn9ifMw6eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": ">= 20.0.0 < 21.0.0", + "@angular-devkit/schematics": ">= 20.0.0 < 21.0.0", + "@angular-eslint/eslint-plugin": "20.7.0", + "@angular-eslint/eslint-plugin-template": "20.7.0", + "ignore": "7.0.5", + "semver": "7.7.3", + "strip-json-comments": "3.1.1" + } + }, + "node_modules/@angular-eslint/schematics/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-eslint/template-parser": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-20.7.0.tgz", + "integrity": "sha512-CVskZnF38IIxVVlKWi1VCz7YH/gHMJu2IY9bD1AVoBBGIe0xA4FRXJkW2Y+EDs9vQqZTkZZljhK5gL65Ro1PeQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "20.7.0", + "eslint-scope": "^9.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/utils": { + "version": "20.7.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-20.7.0.tgz", + "integrity": "sha512-B6EJHbsk2W/lnS3kS/gm56VGvX735419z/DzgbRDcOvqMGMLwD1ILzv5OTEcL1rzpnB0AHW+IxOu6y/aCzSNUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "20.7.0" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular/animations": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.20.tgz", + "integrity": "sha512-pUb+fhYAzi36htMZRFBj2acrgj1ou/vdlOQ99bGrN16/OtKVhGiOeorONrUVJRAlDALDgE+XBMt+6M4jhL+36g==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "20.3.20" + } + }, + "node_modules/@angular/build": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.25.tgz", + "integrity": "sha512-ddWmPzYuzDWz9ql0262u9w3OJHXpSjHVNIDFIYOG2XYyMj/Xve0RkJ8/xvV+Hv7T3iqyyGKtsO+n/d0GCJQCtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2003.25", + "@babel/core": "7.28.3", + "@babel/helper-annotate-as-pure": "7.27.3", + "@babel/helper-split-export-declaration": "7.24.7", + "@inquirer/confirm": "5.1.14", + "@vitejs/plugin-basic-ssl": "2.1.0", + "beasties": "0.3.5", + "browserslist": "^4.23.0", + "esbuild": "0.28.0", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "listr2": "9.0.1", + "magic-string": "0.30.17", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "8.0.0", + "picomatch": "4.0.4", + "piscina": "5.1.3", + "rollup": "4.59.0", + "sass": "1.90.0", + "semver": "7.7.2", + "source-map-support": "0.5.21", + "tinyglobby": "0.2.14", + "vite": "7.3.2", + "watchpack": "2.4.4" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.4.2" + }, + "peerDependencies": { + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/localize": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-server": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@angular/ssr": "^20.3.25", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^20.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.8 <6.0", + "vitest": "^3.1.1" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@angular/cdk": { + "version": "20.2.14", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-20.2.14.tgz", + "integrity": "sha512-7bZxc01URbiPiIBWThQ69XwOxVduqEKN4PhpbF2AAyfMc/W8Hcr4VoIJOwL0O1Nkq5beS8pCAqoOeIgFyXd/kg==", + "license": "MIT", + "dependencies": { + "parse5": "^8.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^20.0.0 || ^21.0.0", + "@angular/core": "^20.0.0 || ^21.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.25.tgz", + "integrity": "sha512-QOSxza45CZY11kqPVpqsU+WGYF99rR/r9A9GykZQWuAHb5SEAxlXHyaaGMu/BMtBHy5HNIlJH25UlzelrbaNyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2003.25", + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", + "@inquirer/prompts": "7.8.2", + "@listr2/prompt-adapter-inquirer": "3.0.1", + "@modelcontextprotocol/sdk": "1.26.0", + "@schematics/angular": "20.3.25", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.35.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.1", + "npm-package-arg": "13.0.0", + "pacote": "21.0.4", + "resolve": "1.22.10", + "semver": "7.7.2", + "yargs": "18.0.0", + "zod": "4.1.13" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.20.tgz", + "integrity": "sha512-uluZKEHKVYRy30/G59HiUv977swzHZVU6F2zdq88bNo2AkOwodcsaGf3GmnhZhnv5nc4qXOZuZZ3mtxTS7o1xw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "20.3.20", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.20.tgz", + "integrity": "sha512-wLzXAtBdRH7LsgHSUmeGqFpkiGutr/Y8cpq4rhcX1J/OHQIWgFTW6+3LltMpKSfJn4wqHj8IIWc+TqrPHfkhKg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.20.tgz", + "integrity": "sha512-noO6SE2Dw9+wCCnmr5nG/gsvQicsrt+7QuaJR8gnnt+JvrDJ5pKkPLj4Rs+mZU86UAscg6LJ0dc8B+KPLKp9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.28.3", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.3.20", + "typescript": ">=5.8 <6.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular/core": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.20.tgz", + "integrity": "sha512-LwUFAGGlqFiu81Umf+oFmAS+swHR9xumNVradrFkDpmy4zkhveO2N2L4QUIm6ZcV0YBkNyoIa/IrJqyVAmwdWQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "20.3.20", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { + "optional": true + }, + "zone.js": { + "optional": true + } + } + }, + "node_modules/@angular/forms": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.20.tgz", + "integrity": "sha512-9l5TIniHls7JLjQVvXi18yNgoMY0VCtRgLDutXId9qq1lJJ1pGDg0IEHER1GS8Ukkws8n79jKZ0X27VFDt/xtA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.3.20", + "@angular/core": "20.3.20", + "@angular/platform-browser": "20.3.20", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/language-service": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.20.tgz", + "integrity": "sha512-Xx2UEvPJORpNP9wM5oom93Q718spTTFfBohroftotQFlYxoGjQF6IcbcG8LtTPA6eygfMCC1m6KaE9taIKwa/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.20.tgz", + "integrity": "sha512-FTWEoAmGGNLc9mZ9DfnzIp64p59vhTi9xYWADDWWYWWpXd4jPxifb8w6ZG+A31vUjq4hXPRj0yy72SyxTKCo5A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "20.3.20", + "@angular/common": "20.3.20", + "@angular/core": "20.3.20" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.20.tgz", + "integrity": "sha512-t4Rfph7P8DemGTkBMi3yQITixulwZCEDB0s4d5froPviNUXr8ogsgQIBTE4KOU1gHskHq/KlPvxstYmFYZJKsQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.3.20", + "@angular/compiler": "20.3.20", + "@angular/core": "20.3.20", + "@angular/platform-browser": "20.3.20" + } + }, + "node_modules/@angular/router": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.20.tgz", + "integrity": "sha512-4oIhW6h7zr16S5vvZNwgX+moJddHNpMk622hriygPXApaQWqJ2Mrp6wYYezpN3DZuE5hjB+f9KPZKq18JF58Ww==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "20.3.20", + "@angular/core": "20.3.20", + "@angular/platform-browser": "20.3.20", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/service-worker": { + "version": "20.3.20", + "resolved": "https://registry.npmjs.org/@angular/service-worker/-/service-worker-20.3.20.tgz", + "integrity": "sha512-9oBdj3Phe+JmeoQBDdx59WDEhKV5cWmdAt3IY7NawPGF4LPdHjEvB+UMSyUKjV0yanjAOoJR7x9jPcOgdN8/sg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "bin": { + "ngsw-config": "ngsw-config.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "20.3.20", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", + "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.3", + "@babel/parser": "^7.28.3", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.3.tgz", + "integrity": "sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.29.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.4.tgz", + "integrity": "sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz", + "integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@capacitor/app": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@capacitor/app/-/app-8.1.0.tgz", + "integrity": "sha512-MlmttTOWHDedr/G4SrhNRxsXMqY+R75S4MM4eIgzsgCzOYhb/MpCkA5Q3nuOCfL1oHm26xjUzqZ5aupbOwdfYg==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/cli": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.3.1.tgz", + "integrity": "sha512-1sPGW4THTDfR6YjXwZ0jM7oAfAtciPOHN00qs/3sNAQx1kKrrEYSfDPwCm1/xlAgi0OeL69SiRfw314Ans+1sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/cli-framework-output": "^2.2.8", + "@ionic/utils-subprocess": "^3.0.1", + "@ionic/utils-terminal": "^2.3.5", + "commander": "^12.1.0", + "debug": "^4.4.0", + "env-paths": "^2.2.0", + "fs-extra": "^11.2.0", + "kleur": "^4.1.5", + "native-run": "^2.0.3", + "open": "^8.4.0", + "plist": "^3.1.0", + "prompts": "^2.4.2", + "rimraf": "^6.0.1", + "semver": "^7.6.3", + "tar": "^7.5.3", + "tslib": "^2.8.1", + "xml2js": "^0.6.2" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/@capacitor/cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@capacitor/cli/node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@capacitor/cli/node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@capacitor/cli/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@capacitor/cli/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@capacitor/cli/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@capacitor/cli/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@capacitor/cli/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@capacitor/cli/node_modules/rimraf": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@capacitor/cli/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@capacitor/core": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.3.1.tgz", + "integrity": "sha512-UF8ItlHguU1Z6GXfPTeT2gakf+ctNI8pAS1kwSBQlsJMlfD4OPoto/SmKnOxKCQvnF4WRcdWeg6C0zREUNaAQg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@capacitor/haptics": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/haptics/-/haptics-8.0.2.tgz", + "integrity": "sha512-c2hZzRR5Fk1tbTvhG1jhh2XBAf3EhnIerMIb2sl7Mt41Gxx1fhBJFDa0/BI1IbY4loVepyyuqNC9820/GZuoWQ==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/keyboard": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@capacitor/keyboard/-/keyboard-8.0.3.tgz", + "integrity": "sha512-27Bv5/2w1Ss2njguBgTS98O0Bb8DRJhAARyzXYib0JlT/n6BrJw/EZ0CokM4C8GFUjFDjJnEKF1Ie01buTMEXQ==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/preferences": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/preferences/-/preferences-8.0.1.tgz", + "integrity": "sha512-T6no3ebi79XJCk91U3Jp/liJUwgBdvHR+s6vhvPkPxSuch7z3zx5Rv1bdWM6sWruNx+pViuEGqZvbfCdyBvcHQ==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@capacitor/status-bar": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-8.0.2.tgz", + "integrity": "sha512-WXs8YB8B9eEaPZz+bcdY6t2nForF1FLoj/JU0Dl9RRgQnddnS98FEEyDooQhaY7wivr000j4+SC1FyeJkrFO7A==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=8.0.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.46.0.tgz", + "integrity": "sha512-C3Axuq1xd/9VqFZpW4YAzOx5O9q/LP46uIQy/iNDpHG3fmPa6TBtvfglMCs3RBiBxAIi0Go97r8+jvTt55XMyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz", + "integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz", + "integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz", + "integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz", + "integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz", + "integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz", + "integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz", + "integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz", + "integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz", + "integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz", + "integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz", + "integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz", + "integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz", + "integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz", + "integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz", + "integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz", + "integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz", + "integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz", + "integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz", + "integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz", + "integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz", + "integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz", + "integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz", + "integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz", + "integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz", + "integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz", + "integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@gar/promise-retry": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.3.tgz", + "integrity": "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@hono/node-server": { + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.14.tgz", + "integrity": "sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.15", + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.2.tgz", + "integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.2.1", + "@inquirer/confirm": "^5.1.14", + "@inquirer/editor": "^4.2.17", + "@inquirer/expand": "^4.0.17", + "@inquirer/input": "^4.2.1", + "@inquirer/number": "^3.0.17", + "@inquirer/password": "^4.0.17", + "@inquirer/rawlist": "^4.1.5", + "@inquirer/search": "^3.1.0", + "@inquirer/select": "^4.3.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@ionic/angular": { + "version": "8.8.6", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.8.6.tgz", + "integrity": "sha512-hEBmuxssuR68D0uaFDiQWDh6FNXw3SDSl0FEXnhN5yD86J0pOrwADO9ks5u8ZFG4rGi39Edq0O5y5UaJWP/2SQ==", + "license": "MIT", + "dependencies": { + "@ionic/core": "8.8.6", + "ionicons": "^8.0.13", + "jsonc-parser": "^3.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=16.0.0", + "@angular/forms": ">=16.0.0", + "@angular/router": ">=16.0.0", + "rxjs": ">=7.5.0", + "zone.js": ">=0.13.0" + } + }, + "node_modules/@ionic/angular-toolkit": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-12.3.0.tgz", + "integrity": "sha512-9cPTMmwggviB2W7wf4sv4vFeQnYq5HbO6V89UqQHopShokdhSvUFpaQ2w1/Mdf/ot8PghGjR3t5IdnXV7i1LvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "^20.0.0", + "@angular-devkit/schematics": "^20.0.0", + "@schematics/angular": "^20.0.0" + } + }, + "node_modules/@ionic/angular/node_modules/ionicons": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz", + "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==", + "license": "MIT", + "dependencies": { + "@stencil/core": "^4.35.3" + } + }, + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/core": { + "version": "8.8.6", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.6.tgz", + "integrity": "sha512-bliMajAW7pHlC9rqUq6bBxUr+Dctv/f+OmCYyDcvoZ64UvWwpAfNC5JcKaWx6VMX4DF4KOmYmbAJO3RdZGKVRw==", + "license": "MIT", + "dependencies": { + "@stencil/core": "4.43.0", + "ionicons": "^8.0.13", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/@ionic/core/node_modules/ionicons": { + "version": "8.0.13", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-8.0.13.tgz", + "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==", + "license": "MIT", + "dependencies": { + "@stencil/core": "^4.35.3" + } + }, + "node_modules/@ionic/storage": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@ionic/storage/-/storage-4.0.0.tgz", + "integrity": "sha512-3N21P19Xk6cICLnSXZ3ilRqbSXAGSFeIF3HNqz+1kARcm0UFT/vwmZreaXtFyq437vvEWOfJ2enlj3JHLKS0FA==", + "license": "MIT", + "dependencies": { + "localforage": "^1.9.0" + } + }, + "node_modules/@ionic/storage-angular": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@ionic/storage-angular/-/storage-angular-4.0.0.tgz", + "integrity": "sha512-FeSmCMCm1bMRfu5TFSqLtjdfEo/dLLUhLIrPmbhSYomVZdV/dNn4mBZv9SabyxSqn4bF31hw40y+4buhG+durQ==", + "license": "MIT", + "dependencies": { + "@ionic/storage": "^4.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": "*", + "rxjs": "*" + } + }, + "node_modules/@ionic/utils-array": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz", + "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-fs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@ionic/utils-fs/node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@ionic/utils-fs/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-process/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@ionic/utils-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.7.tgz", + "integrity": "sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-subprocess": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-3.0.1.tgz", + "integrity": "sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-array": "2.1.6", + "@ionic/utils-fs": "3.1.7", + "@ionic/utils-process": "2.1.12", + "@ionic/utils-stream": "3.1.7", + "@ionic/utils-terminal": "2.3.5", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ionic/utils-terminal/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@ionic/utils-terminal/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@ionic/utils-terminal/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.2.tgz", + "integrity": "sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.2.tgz", + "integrity": "sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.2.tgz", + "integrity": "sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/fs-print": "4.57.2", + "@jsonjoy.com/fs-snapshot": "4.57.2", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.2.tgz", + "integrity": "sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.2.tgz", + "integrity": "sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.2.tgz", + "integrity": "sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.2" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.2.tgz", + "integrity": "sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.2", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.2.tgz", + "integrity": "sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.1.tgz", + "integrity": "sha512-3XFmGwm3u6ioREG+ynAQB7FoxfajgQnMhIu8wC5eo/Lsih4aKDg0VuIMGaOsYn7hJSJagSeaD4K8yfpkEoDEmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.1" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.4.2.tgz", + "integrity": "sha512-NK80WwDoODyPaSazKbzd3NEJ3ygePrkERilZshxBViBARNz21rmediktGHExoj9n5t9+ChlgLlxecdFKLCuCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.4.2.tgz", + "integrity": "sha512-zevaowQNmrp3U7Fz1s9pls5aIgpKRsKb3dZWDINtLiozh3jZI9fBrI19lYYBxqdyiIyNdlyiidPnwPShj4aK+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.4.2.tgz", + "integrity": "sha512-OmHCULY17rkx/RoCoXlzU7LyR8xqrksgdYWwtYa14l/sseezZ8seKWXcogHcjulBddER5NnEFV4L/Jtr2nyxeg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.4.2.tgz", + "integrity": "sha512-ZBEfbNZdkneebvZs98Lq30jMY8V9IJzckVeigGivV7nTHJc+89Ctomp1kAIWKlwIG0ovCDrFI448GzFPORANYg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.4.2.tgz", + "integrity": "sha512-vL9nM17C77lohPYE4YaAQvfZCSVJSryE4fXdi8M7uWPBnU+9DJabgKVAeyDb84ZM2vcFseoBE4/AagVtJeRE7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.4.2.tgz", + "integrity": "sha512-SXWjdBfNDze4ZPeLtYIzsIeDJDJ/SdsA0pEXcUBayUIMO0FQBHfVZZyHXQjjHr4cvOAzANBgIiqaXRwfMhzmLw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.4.2.tgz", + "integrity": "sha512-IY+r3bxKW6Q6sIPiMC0L533DEfRJSXibjSI3Ft/w9Q8KQBNqEIvUFXt+09wV8S5BRk0a8uSF19YWxuRwEfI90g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", + "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.100.tgz", + "integrity": "sha512-xglYA6q3XO5P3BNJYxVZ1IV7DLVjp1Py6nwag88YntrS+3vKHyYcMqXVS4ZztJmwz2uGvz1FWhI/4LgbR5uQDA==", + "license": "MIT", + "optional": true, + "workspaces": [ + "e2e/*" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.100", + "@napi-rs/canvas-darwin-arm64": "0.1.100", + "@napi-rs/canvas-darwin-x64": "0.1.100", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.100", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.100", + "@napi-rs/canvas-linux-arm64-musl": "0.1.100", + "@napi-rs/canvas-linux-riscv64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-gnu": "0.1.100", + "@napi-rs/canvas-linux-x64-musl": "0.1.100", + "@napi-rs/canvas-win32-arm64-msvc": "0.1.100", + "@napi-rs/canvas-win32-x64-msvc": "0.1.100" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.100.tgz", + "integrity": "sha512-hjhCKhntPv9+t4ckHymdx0phYNcVW+GKQR6Lzw2zE+pOVjOplSmtx9nNNknTjbEDLcuLZqA1y8ufKg1XfgftzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.100.tgz", + "integrity": "sha512-2PcswRaC7Ly645DGt88///zuFDhJxJYdKAs1uU3mfk1atYkXufgcgLfBpk6Tm12nCQBaNt1wpybuPZ4qOhTo8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.100.tgz", + "integrity": "sha512-ePNZtj7pNIva/siZMg+HmbeozkIjqUIYdoymH8HaA3qK7LfzFN4WMBM8G6HQ9ZC+H3+Dnn5pqtiXpgLykaPOhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.100.tgz", + "integrity": "sha512-d5cDB48oWFGU8/XPhUOFAlySgb/VAu7D+s8fi55K1Pcfg8aPplHWqMgibhVLU8ky7Pyg/fuiVLz4Nf3JrSTuUA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.100.tgz", + "integrity": "sha512-rDxgxRu69RvDlX/bh9o22DxLsGr8EqsNgotL9+RwQE1S0b0cqeatqsw6aW45mukm0B42DIAaAacKaYQ8cqS1nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.100.tgz", + "integrity": "sha512-K3mDW66N+xT2/V439u1alFANiBUjdEx2gLiNYnCmUsva5jZMxWTjafBYwTzYK+EMFMHrUoabuU+T1BIP5CgbYQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.100.tgz", + "integrity": "sha512-mooqUBTIsccZpnoQC4NgrC1v6C1vof39etLNMnBwCY+p0gajWJvAHLGQ6g/gGyS5YrpDW+GefSN4+Cvcr08UWw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.100.tgz", + "integrity": "sha512-1eCvkDCazm7FFhsT7DfGOdSaHgZVK3bt/dSBl5EWHOWmnz+I7j8tPseJqqD81NF+MH21jKUK4wQSDjN0mdhnTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.100.tgz", + "integrity": "sha512-20arT6lnI19S68qNlii73TSEDbECNgzMz2EpldC1V3mZFuRkeujXkcebRk0LRJe9SEUAooYiLokfMViY8IX7yA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-arm64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-arm64-msvc/-/canvas-win32-arm64-msvc-0.1.100.tgz", + "integrity": "sha512-DZFFT1wIAg37LJw37yhMRFfjATd3vTQzjZ1Yki8u2vhO6Hi5VE6BVaGQ1aaDu7xb4iMErz+9EOwjpS7xcxFeBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.100", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.100.tgz", + "integrity": "sha512-MyT1j3mHC2+Lu4pBi9mKyMJhtP6U7k7EldY7sj/uS5gJA65gTXt8MefJQXLJo5d/vZbuWmfxzkEUNc/urV3pHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.25.tgz", + "integrity": "sha512-p/YopAgukaIvezv3hsJzJevnNUBNTM8UQIkyDHPY5/aANdKraUTKDQUwlVxRiyD8U+PTSeD/BI56oOnuKrdFZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^20.0.0", + "typescript": ">=5.8 <6.0", + "webpack": "^5.54.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", + "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@npmcli/git/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.5.tgz", + "integrity": "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.4.tgz", + "integrity": "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@pkgr/core": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz", + "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", + "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", + "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", + "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", + "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", + "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", + "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", + "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.9", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", + "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@schematics/angular": { + "version": "20.3.25", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.25.tgz", + "integrity": "sha512-ezoJpPKhhjXgE3LxuNcJO/ghSXs8f73xrqGvqouag7IbuliJYbHrt22WH3X75XSbD0+iOdiqA2bARvAO/ezyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.3.25", + "@angular-devkit/schematics": "20.3.25", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.2.0.tgz", + "integrity": "sha512-kxHrDQ9YgfrWUSXU0cjsQGv8JykOFZQ9ErNKbFPWzk3Hgpwu8x2hHrQ9IdA8yl+j9RTLTC3sAF3Tdq1IQCP4oA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.1.tgz", + "integrity": "sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.1.tgz", + "integrity": "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.2.tgz", + "integrity": "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", + "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@stencil/core": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.43.0.tgz", + "integrity": "sha512-6Uj2Z3lzLuufYAE7asZ6NLKgSwsB9uxl84Eh34PASnUjfj32GkrP4DtKK7fNeh1WFGGyffsTDka3gwtl+4reUg==", + "license": "MIT", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=7.10.0" + }, + "optionalDependencies": { + "@rollup/rollup-darwin-arm64": "4.34.9", + "@rollup/rollup-darwin-x64": "4.34.9", + "@rollup/rollup-linux-arm64-gnu": "4.34.9", + "@rollup/rollup-linux-arm64-musl": "4.34.9", + "@rollup/rollup-linux-x64-gnu": "4.34.9", + "@rollup/rollup-linux-x64-musl": "4.34.9", + "@rollup/rollup-win32-arm64-msvc": "4.34.9", + "@rollup/rollup-win32-x64-msvc": "4.34.9" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.15", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.15.tgz", + "integrity": "sha512-ZAC8KjmV2MJxbNTrwXFN+HKeajpXQZp6KpPiR6Aa4XvaEnjP6qh23lL/Rqb7AYzlp3h/rcwDrQ7Gg7q28cQTQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz", + "integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.19.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", + "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qrcode": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.6.tgz", + "integrity": "sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", + "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/type-utils": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.59.2", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", + "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", + "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.59.2", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", + "integrity": "sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz", + "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@zxing/browser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@zxing/browser/-/browser-0.2.0.tgz", + "integrity": "sha512-+ORhrLva0vm6ck74NDCmvYNW3XLoAG81Mu90qfcssN1PBKJjQadxZGeMCcIk+BdJbD/zEAjjHDXOwEK1QCmRtw==", + "license": "MIT", + "optionalDependencies": { + "@zxing/text-encoding": "^0.9.0" + }, + "peerDependencies": { + "@zxing/library": "^0.22.0" + } + }, + "node_modules/@zxing/library": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.23.0.tgz", + "integrity": "sha512-6fkkoFwP8CHxl6ugnPsj74PLJgX2iRv5zczGAyt5OBzQgxFhuhF0NCEc4t4OvSr8xAv2MRLlI0Iu9ZGDZQ2urA==", + "license": "Apache-2.0", + "dependencies": { + "ts-custom-error": "^3.3.1" + }, + "engines": { + "node": ">= 24.0.0" + }, + "optionalDependencies": { + "@zxing/text-encoding": "~0.9.0" + } + }, + "node_modules/@zxing/ngx-scanner": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@zxing/ngx-scanner/-/ngx-scanner-21.0.0.tgz", + "integrity": "sha512-oiBCwXsIsBa1TKAlq8GWa0qoRQt9uHe2WaU6zUkgGe+cYOjgIrSvfdE/iE170NTc6OTaj8GjArIkVKhn6wqLIw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/forms": "^21.0.0", + "@zxing/browser": "^0.1.4", + "@zxing/library": "^0.21.0", + "rxjs": "^6.5.3 || ^7.4.0", + "typescript": "^5.9.0" + } + }, + "node_modules/@zxing/text-encoding": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", + "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", + "license": "(Unlicense OR Apache-2.0)", + "optional": true + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.35.0.tgz", + "integrity": "sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.1.0", + "@algolia/client-abtesting": "5.35.0", + "@algolia/client-analytics": "5.35.0", + "@algolia/client-common": "5.35.0", + "@algolia/client-insights": "5.35.0", + "@algolia/client-personalization": "5.35.0", + "@algolia/client-query-suggestions": "5.35.0", + "@algolia/client-search": "5.35.0", + "@algolia/ingestion": "1.35.0", + "@algolia/monitoring": "1.35.0", + "@algolia/recommend": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-loader": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", + "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": "^18.20.0 || ^20.10.0 || >=22.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5.61.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz", + "integrity": "sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/beasties": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.5.tgz", + "integrity": "sha512-NaWu+f4YrJxEttJSm16AzMIFtVldCvaJ68b1L098KpqXmxt9xOLtKoLkKxb8ekhOrLqEJAbvT6n6SEvB/sac7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^6.0.0", + "css-what": "^7.0.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", + "license": "MIT" + }, + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.4.tgz", + "integrity": "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", + "integrity": "sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^7.0.3", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", + "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^7.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "nth-check": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", + "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dijkstrajs": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", + "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==", + "license": "MIT" + }, + "node_modules/dingbat-to-unicode": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", + "integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==", + "license": "BSD-2-Clause" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duck": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/duck/-/duck-0.1.12.tgz", + "integrity": "sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg==", + "license": "BSD", + "dependencies": { + "underscore": "^1.13.1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.352", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.352.tgz", + "integrity": "sha512-9wHk8x6dyuimoe18EdiDPWKExNdxYqo4fn4FwOVVper6RxT3cmpBwBkWWfSOCYJjQdIco/nPhJhNLmn4Ufg1Yg==", + "dev": true, + "license": "ISC" + }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/elementtree/node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.7.tgz", + "integrity": "sha512-DgOngfDKM2EviOH3Mr9m7ks1q8roetLy/IMmYthAYzbpInMbYc/GS+fWFA3rl1gvwKVsQrVV61fo5emD1y3OJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "@types/ws": "^8.5.12", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.18.3" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/engine.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", + "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz", + "integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.0", + "@esbuild/android-arm": "0.28.0", + "@esbuild/android-arm64": "0.28.0", + "@esbuild/android-x64": "0.28.0", + "@esbuild/darwin-arm64": "0.28.0", + "@esbuild/darwin-x64": "0.28.0", + "@esbuild/freebsd-arm64": "0.28.0", + "@esbuild/freebsd-x64": "0.28.0", + "@esbuild/linux-arm": "0.28.0", + "@esbuild/linux-arm64": "0.28.0", + "@esbuild/linux-ia32": "0.28.0", + "@esbuild/linux-loong64": "0.28.0", + "@esbuild/linux-mips64el": "0.28.0", + "@esbuild/linux-ppc64": "0.28.0", + "@esbuild/linux-riscv64": "0.28.0", + "@esbuild/linux-s390x": "0.28.0", + "@esbuild/linux-x64": "0.28.0", + "@esbuild/netbsd-arm64": "0.28.0", + "@esbuild/netbsd-x64": "0.28.0", + "@esbuild/openbsd-arm64": "0.28.0", + "@esbuild/openbsd-x64": "0.28.0", + "@esbuild/openharmony-arm64": "0.28.0", + "@esbuild/sunos-x64": "0.28.0", + "@esbuild/win32-arm64": "0.28.0", + "@esbuild/win32-ia32": "0.28.0", + "@esbuild/win32-x64": "0.28.0" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.28.0.tgz", + "integrity": "sha512-5TRVKExcEmeMkccIZMzUq+Az6X2RoMAJyfl6SMMO1dMVhmvt0I2mx7gAb6zYi42n4d1ETcatFXazGKzA+aW7fg==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "48.11.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.11.0.tgz", + "integrity": "sha512-d12JHJDPNo7IFwTOAItCeJY1hcqoIxE0lHA8infQByLilQ9xkqrRa6laWCnsuCrf+8rUnvxXY1XuTbibRBNylA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.46.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.5", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-prefer-arrow": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-arrow/-/eslint-plugin-prefer-arrow-1.2.2.tgz", + "integrity": "sha512-C8YMhL+r8RMeMdYAw/rQtE6xNdMulj+zGWud/qIGnlmomiPRaLDGLMeskZ3alN6uMBojmooRimtdrXebLN4svQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=2.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.8.tgz", + "integrity": "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.1.tgz", + "integrity": "sha512-5O6KYmyJEpuPJV5hNTXKbAHWRqrzyu+OI3vUnSd2kXFubIVpG7ezpgxQy76Zo5GQZtrQBg86hF+CM/NX+cioiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.18", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.18.tgz", + "integrity": "sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/idb-keyval": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.2.tgz", + "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", + "license": "Apache-2.0" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/immutable": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", + "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ionicons": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ionicons/-/ionicons-7.4.0.tgz", + "integrity": "sha512-ZK94MMqgzMCPPMhmk8Ouu6goyVHFIlw/ACP6oe3FrikcI0N7CX0xcwVaEbUc0G/v3W0shI93vo+9ve/KpvcNhQ==", + "license": "MIT", + "dependencies": { + "@stencil/core": "^4.0.3" + } + }, + "node_modules/ip-address": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-network-error": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", + "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jasmine-core": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.1.2.tgz", + "integrity": "sha512-2oIUMGn00FdUiqz6epiiJr7xcFyNYj3rDcfmnzfkBnHyBQ3cBQUs4mmyGsOb7TTLb9kxk7dBcmEmqhDKkBoDyA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jasmine-spec-reporter": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-5.0.2.tgz", + "integrity": "sha512-6gP1LbVgJ+d7PKksQBc2H0oDGNRQI3gKUsWlswKaQ2fif9X5gzhQcgM5+kiJGCQVurOG09jqNhk7payggyp5+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "colors": "1.4.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-chrome-launcher/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-coverage/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/karma/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/karma/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/karma/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/karma/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/karma/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/karma/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/launch-editor": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", + "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.3" + } + }, + "node_modules/less": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/less/-/less-4.4.0.tgz", + "integrity": "sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.3.0.tgz", + "integrity": "sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", + "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.4.2.tgz", + "integrity": "sha512-nwVGUfTBUwJKXd6lRV8pFNfnrCC1+l49ESJRM19t/tFb/97QfJEixe5DYRvug5JO7DSFKoKaVy7oGMt5rVqZvg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.4.2", + "@lmdb/lmdb-darwin-x64": "3.4.2", + "@lmdb/lmdb-linux-arm": "3.4.2", + "@lmdb/lmdb-linux-arm64": "3.4.2", + "@lmdb/lmdb-linux-x64": "3.4.2", + "@lmdb/lmdb-win32-arm64": "3.4.2", + "@lmdb/lmdb-win32-x64": "3.4.2" + } + }, + "node_modules/loader-runner": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", + "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lop": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz", + "integrity": "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==", + "license": "BSD-2-Clause", + "dependencies": { + "duck": "^0.1.12", + "option": "~0.2.1", + "underscore": "^1.13.1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.5.tgz", + "integrity": "sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/make-fetch-happen/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/mammoth": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.12.0.tgz", + "integrity": "sha512-cwnK1RIcRdDMi2HRx2EXGYlxqIEh0Oo3bLhorgnsVJi2UkbX1+jKxuBNR9PC5+JaX7EkmJxFPmo6mjLpqShI2w==", + "license": "BSD-2-Clause", + "dependencies": { + "@xmldom/xmldom": "^0.8.6", + "argparse": "~1.0.3", + "base64-js": "^1.5.1", + "bluebird": "~3.4.0", + "dingbat-to-unicode": "^1.0.1", + "jszip": "^3.7.1", + "lop": "^0.4.2", + "path-is-absolute": "^1.0.0", + "underscore": "^1.13.1", + "xmlbuilder": "^10.0.0" + }, + "bin": { + "mammoth": "bin/mammoth" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/mammoth/node_modules/@xmldom/xmldom": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mammoth/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/mammoth/node_modules/xmlbuilder": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", + "integrity": "sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memfs": { + "version": "4.57.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.2.tgz", + "integrity": "sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.2", + "@jsonjoy.com/fs-fsa": "4.57.2", + "@jsonjoy.com/fs-node": "4.57.2", + "@jsonjoy.com/fs-node-builtins": "4.57.2", + "@jsonjoy.com/fs-node-to-fsa": "4.57.2", + "@jsonjoy.com/fs-node-utils": "4.57.2", + "@jsonjoy.com/fs-print": "4.57.2", + "@jsonjoy.com/fs-snapshot": "4.57.2", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", + "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "iconv-lite": "^0.7.2" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.12.tgz", + "integrity": "sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-run": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.3.tgz", + "integrity": "sha512-U1PllBuzW5d1gfan+88L+Hky2eZx+9gv3Pf6rNBxKbORxi7boHzqiA6QFGSnqMem4j0A9tZ08NMIs5+0m/VS1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/native-run/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/needle": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz", + "integrity": "sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", + "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.3.0.tgz", + "integrity": "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-package-arg": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.0.tgz", + "integrity": "sha512-+t2etZAGcB7TbbLHfDwooV9ppB2LhhcT6A+L9cahsf9mEUAoQ6CktLEVvEnpD0N5CkX7zJqnPGaFtoQDy9EkHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.4.tgz", + "integrity": "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", + "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", + "license": "MIT", + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/option": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz", + "integrity": "sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A==", + "license": "BSD-2-Clause" + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "21.0.4", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", + "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pacote/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", + "dev": true, + "license": "Apache-2.0 AND MIT", + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.0.tgz", + "integrity": "sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^8.0.0", + "parse5-sax-parser": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", + "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pdfjs-dist": { + "version": "5.7.284", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.7.284.tgz", + "integrity": "sha512-h4EdYQczmGhbOlqc3PPZwxevn7ApdWPbovAuWXOB/DjIyigSnwfy2oze7c6mRcSr9XgLp3eN3EeL4DyySTPMFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=22.13.0 || >=24" + }, + "optionalDependencies": { + "@napi-rs/canvas": "^0.1.100" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.3.tgz", + "integrity": "sha512-0u3N7H4+hbr40KjuVn2uNhOcthu/9usKhnw5vT3J7ply79v3D3M8naI00el9Klcy16x557VsEkkUQaHCWFXC/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.4" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/plist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", + "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.9.10", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", + "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", + "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qrcode": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz", + "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==", + "license": "MIT", + "dependencies": { + "dijkstrajs": "^1.0.1", + "pngjs": "^5.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "qrcode": "bin/qrcode" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/qrcode/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/qrcode/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/qrcode/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qrcode/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "license": "ISC" + }, + "node_modules/qrcode/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qrcode/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" + }, + "node_modules/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.1.tgz", + "integrity": "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "license": "ISC" + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/rollup/node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.90.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz", + "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" + }, + "engines": { + "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-index/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", + "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slashes": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", + "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", + "dev": true, + "license": "ISC" + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.3.tgz", + "integrity": "sha512-2Dd78bqzzjE6KPkD5fHZmDAKRNe3J15q+YHDrIsy9WEkqttc7GY+kT9OBLSMaPbQaEd0x1BjcmtMtXkfpc+T5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.4.1", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz", + "integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.4.1", + "ws": "~8.18.3" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", + "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/socket.io/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.8.tgz", + "integrity": "sha512-NlGELfPrgX2f1TAAcz0WawlLn+0r3FyhhCRpFFK2CemXenPYvzMWWZINv3eDNo9ucdwme7oCHRY0Jnbs4aIkog==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.3.tgz", + "integrity": "sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar": { + "version": "7.5.14", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.14.tgz", + "integrity": "sha512-/7sHKgQO3JLP9ESlwTYUUftHUadOURUqq23xs1vjcnp8Vss6k0wCfzulyEtk5g91pjvnuriimGlyG7k6msrzRw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-UYhptBwhWvfIjKd/UuFo6D8uq9xpGLDK+z8EDsj/zWhrTaH34cKEbrkMKfV5YWqGBvAYA3tlzZbs2R+qYrbQJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/tesseract.js": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tesseract.js/-/tesseract.js-7.0.0.tgz", + "integrity": "sha512-exPBkd+z+wM1BuMkx/Bjv43OeLBxhL5kKWsz/9JY+DXcXdiBjiAch0V49QR3oAJqCaL5qURE0vx9Eo+G5YE7mA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "bmp-js": "^0.1.0", + "idb-keyval": "^6.2.0", + "is-url": "^1.2.4", + "node-fetch": "^2.6.9", + "opencollective-postinstall": "^2.0.3", + "regenerator-runtime": "^0.13.3", + "tesseract.js-core": "^7.0.0", + "wasm-feature-detect": "^1.8.0", + "zlibjs": "^0.3.1" + } + }, + "node_modules/tesseract.js-core": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tesseract.js-core/-/tesseract.js-core-7.0.0.tgz", + "integrity": "sha512-WnNH518NzmbSq9zgTPeoF8c+xmilS8rFIl1YKbk/ptuuc7p6cLNELNuPAzcmsYw450ca6bLa8j3t0VAtq435Vw==", + "license": "Apache-2.0" + }, + "node_modules/thingies": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-custom-error": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", + "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", + "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "7.19.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz", + "integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", + "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/vite/node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wasm-feature-detect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz", + "integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==", + "license": "Apache-2.0" + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.3", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.14.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/webpack-dev-server/node_modules/express/node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/webpack-dev-server/node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webpack-dev-server/node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.4.0.tgz", + "integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-server/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server/node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/webpack-dev-server/node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/webpack-dev-server/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.4.1.tgz", + "integrity": "sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zlibjs": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/zlibjs/-/zlibjs-0.3.1.tgz", + "integrity": "sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/zod": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", + "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + }, + "node_modules/zone.js": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", + "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d461d83 --- /dev/null +++ b/package.json @@ -0,0 +1,76 @@ +{ + "name": "canticristiani", + "version": "0.0.1", + "author": "Ionic Framework", + "homepage": "https://ionicframework.com/", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "lint": "ng lint" + }, + "private": true, + "dependencies": { + "@angular/animations": "^20.0.0", + "@angular/cdk": "^20.2.14", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/forms": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "@angular/platform-browser-dynamic": "^20.0.0", + "@angular/router": "^20.0.0", + "@angular/service-worker": "^20.0.0", + "@capacitor/app": "8.1.0", + "@capacitor/core": "8.3.1", + "@capacitor/haptics": "8.0.2", + "@capacitor/keyboard": "8.0.3", + "@capacitor/preferences": "^8.0.1", + "@capacitor/status-bar": "8.0.2", + "@ionic/angular": "^8.0.0", + "@ionic/storage-angular": "^4.0.0", + "@zxing/browser": "^0.2.0", + "@zxing/library": "^0.23.0", + "@zxing/ngx-scanner": "^21.0.0", + "ionicons": "^7.0.0", + "mammoth": "^1.12.0", + "pdfjs-dist": "^5.7.284", + "qrcode": "^1.5.4", + "rxjs": "~7.8.0", + "tesseract.js": "^7.0.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^20.0.0", + "@angular-eslint/builder": "^20.0.0", + "@angular-eslint/eslint-plugin": "^20.0.0", + "@angular-eslint/eslint-plugin-template": "^20.0.0", + "@angular-eslint/schematics": "^20.0.0", + "@angular-eslint/template-parser": "^20.0.0", + "@angular/cli": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/language-service": "^20.0.0", + "@capacitor/cli": "8.3.1", + "@ionic/angular-toolkit": "^12.0.0", + "@types/jasmine": "~5.1.0", + "@types/qrcode": "^1.5.6", + "@typescript-eslint/eslint-plugin": "^8.18.0", + "@typescript-eslint/parser": "^8.18.0", + "eslint": "^9.16.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-prefer-arrow": "1.2.2", + "jasmine-core": "~5.1.0", + "jasmine-spec-reporter": "~5.0.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.9.0" + }, + "description": "An Ionic project" +} diff --git a/parametri_canti_comunita.md b/parametri_canti_comunita.md new file mode 100644 index 0000000..bf4744f --- /dev/null +++ b/parametri_canti_comunita.md @@ -0,0 +1,144 @@ +# Parametri letti da canti.json e da Comunità + +Questo documento elenca tutti i parametri e i campi strutturati che vengono letti, elaborati e salvati dall'applicazione a partire dal file globale `canti.json` e dalle API/file di configurazione delle **Comunità**. + +--- + +## 1. Parametri da `canti.json` + +Il file `canti.json` rappresenta il database globale dei canti dell'applicazione. Viene scaricato dall'endpoint configurato in `CantiService` (es. `https://www.canticristiani.it/api/canti.json`). + +### Struttura Principale del File + +Il JSON restituito contiene diversi nodi chiave, ciascuno contenente un array `data`: + +```json +{ + "canti": { "data": [...] }, + "indice_liturgico": { "data": [...] }, + "indice_tematico": { "data": [...] }, + "tema": { "data": [...] }, + "canti_eseguiti": { "data": [...] } +} +``` + +#### Nodo `canti.data` (Lista dei Canti) +Ciascun elemento rappresenta un canto e viene mappato nell'interfaccia `Canto`: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_canti` | `number` | Identificativo univoco del canto (usato internamente anche come stringa `id`). | +| `titolo` | `string` | Titolo del canto. | +| `testo` | `string` | Testo del canto (può includere indicazioni di accordi). | +| `accordi` | `string` (opzionale) | Accordi musicali associati al canto. | +| `autore` | `string` (opzionale) | Autore o autori del canto. | +| `link_youtube` | `string` (opzionale) | URL o ID del video di YouTube associato al canto. | +| `data_update` | `string` (opzionale) | Data dell'ultimo aggiornamento (formato `YYYY-MM-DD HH:mm:ss`, formattata a schermo in `DD/MM/YYYY`). | +| `nonValidato` | `boolean` (opzionale) | Indica se il canto è in attesa di validazione. | +| `isPersonal` | `boolean` (opzionale) | Flag locale per identificare se si tratta di un canto personale dell'utente. | + +*Nota: Durante l'importazione, viene aggiunto un array `id_momenti: number[]` ricavato dalla tabella pivot `tema.data`.* + +#### Nodo `indice_liturgico.data` e `indice_tematico.data` (Indici/Tag) +Mappati nell'interfaccia `Indice`: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_indice_liturgico` / `id_indice_tematico` | `number` | Identificativo dell'indice/momento. | +| `tag_name` | `string` | Nome visualizzato del tag (es. "Ingresso", "Offertorio"). | +| `slug` | `string` | Versione ottimizzata per URL del tag. | + +*Nota: A livello applicativo viene aggiunto il campo `type` con valore `'liturgico'` o `'tematico'`.* + +#### Nodo `tema.data` (Relazione Pivot Canti-Indici) +Utilizzato per associare a ogni canto i rispettivi momenti liturgici o tematici: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_canti` | `number` | ID del canto associato. | +| `id_momento` | `number` | ID del momento liturgico/tematico. | + +#### Nodo `canti_eseguiti.data` +Informazioni sull'esecuzione dei canti: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_canti` | `number` | ID del canto eseguito. | +| `num` | `number` | Numero di esecuzioni o indicatore di frequenza. | + +--- + +## 2. Parametri dalle Comunità + +I dati di una comunità vengono letti in due modi: tramite l'API di produzione (v3) oppure tramite un file JSON statico di fallback. + +### Opzione A: API di Produzione (`get_all_app_tables`) +Endpoint: `https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables` + +L'API risponde con un oggetto contenente diverse tabelle relazionali: + +#### 1. `parrocchia.data` (Dettagli della Comunità) +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_parrocchia` | `number` | ID interno della parrocchia/comunità. | +| `nome` | `string` | Nome della comunità (es. "Parrocchia S. Maria"). | +| `codice` | `string` | Codice alfanumerico della comunità. | +| `mail` | `string` | Email di riferimento della comunità. | +| `guid_parrocchia` | `string` | GUID univoco. | + +#### 2. `parrocchia_canti.data` (Associazione Canti-Comunità) +Indica quali canti del database generale appartengono al repertorio della comunità: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_parrocchia` | `number` | ID della parrocchia. | +| `id_canti` | `number` | ID del canto associato. | +| `num_canto` | `number` | Numero progressivo o di classificazione del canto all'interno della comunità. | + +#### 3. `canti_settings.data` (Impostazioni di Esecuzione personalizzate) +Configurazioni specifiche per l'esecuzione del canto in comunità: + +| Parametro Originale | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_canti` | `number` | ID del canto. | +| `speed` | `number` | Velocità di scorrimento (auto-scroll) consigliata. | +| `tonalita` | `number` | Semitoni di trasposizione (trasporto tonalità) consigliati. | + +#### 4. `canti_personali.data` (Canti personalizzati/inediti della Comunità) +Canti inseriti direttamente dalla comunità e non presenti nel database globale: + +| Parametro Originale | Tipo | Descrizione / Mapping Applicativo | +| :--- | :--- | :--- | +| `id_canti` | `number` | ID del canto personale. | +| `titolo` | `string` | Titolo del canto. | +| `accordi` | `string` | Testo con gli accordi del canto. | +| `autore` | `string` | Autore del canto. | +| `link_youtube` | `string` | Link YouTube. | +| `data_update` | `string` | Data dell'ultimo aggiornamento. | +| `stato` | `number` | Se uguale a `10`, il canto viene contrassegnato come `nonValidato = true`. | + +*Nota: Vengono impostati automaticamente `isPersonal = true` e `id_momenti = []`.* + +#### 5. Scalette della Comunità (`lista_nome` + `lista_esecuzione`) +L'applicazione ricostruisce l'elenco delle scalette (`ComunitaScaletta`): +* **`lista_nome.data`** (Testate delle scalette): + * `id_lista` (`string`/`number`): ID della scaletta. + * `nome` (`string`): Nome della scaletta (es. "Domenica delle Palme"). + * `progr` (`string`): Data o stringa di ordinamento (mappata in `date`). +* **`lista_esecuzione.data`** (Canti contenuti nelle scalette): + * `id_lista` (`string`/`number`): Associazione alla scaletta. + * `id_canti` (`number`): ID del canto. + * `progr` (`number`): Ordine progressivo del canto all'interno della scaletta (usato per l'ordinamento). + +--- + +### Opzione B: Fallback Statico (`comunita_[codice].json`) +Se l'API di produzione non è raggiungibile, viene tentato il download di un file statico (es. `comunita_123456.json`) dall'origine del sito. + +La struttura attesa per questo file è molto più semplice: + +| Parametro JSON | Tipo | Descrizione | +| :--- | :--- | :--- | +| `id_comunita` | `string` | Codice identificativo della comunità. | +| `nome_comunita` | `string` | Nome leggibile della comunità. | +| `canti` | `(number \| string)[]` | Array contenente gli ID di tutti i canti associati a questa comunità. | diff --git a/piano-generazione-test.md b/piano-generazione-test.md new file mode 100644 index 0000000..f8470eb --- /dev/null +++ b/piano-generazione-test.md @@ -0,0 +1,159 @@ +# Piano delle Azioni per la Generazione di una Batteria di Test (`.spec.ts`) + +Questo documento descrive in dettaglio la strategia, l'analisi dello stato attuale e l'elenco delle azioni sequenziali necessarie per implementare una suite completa di test unitari e di integrazione per tutte le classi (servizi, pagine e componenti) dell'applicazione Angular/Ionic. + +--- + +## 📊 Analisi dello Stato Attuale dei Test + +L'applicazione utilizza **Angular v20**, **Ionic v8**, e il framework di test standard **Jasmine** abbinato al test runner **Karma**. + +Un'analisi del codice ha rilevato la seguente situazione per ciascun componente chiave: + +### 1. Servizi (`src/app/services`) +I servizi gestiscono la logica di business fondamentale (audio, sincronizzazione, storage, stato). +* ❌ `audio-engine.service.ts` — **Nessun test** +* ❌ `canti-letture.service.ts` — **Nessun test** +* ❌ `canti.service.ts` — **Nessun test** +* ❌ `comunita.service.ts` — **Nessun test** +* ❌ `connectivity.service.ts` — **Nessun test** +* ❌ `lyrics-parser.service.ts` — **Nessun test** +* ❌ `media-session.service.ts` — **Nessun test** +* ⚠️ `my-canti.service.ts` — **Spec esistente ma corrotto/obsoleto** (`my-canti.spec.ts` fa riferimento a una classe `MyCanti` che non esiste, la classe reale è `MyCantiService`). +* ❌ `playlist.service.ts` — **Nessun test** +* ❌ `settings.service.ts` — **Nessun test** +* ❌ `stats.service.ts` — **Nessun test** +* ❌ `theme.service.ts` — **Nessun test** +* ❌ `youtube-player.service.ts` — **Nessun test** + +### 2. Pagine (`src/app/pages` & `src/app/home`) +Le pagine gestiscono la visualizzazione e l'interazione con l'utente. +* ⚠️ `home.page.ts` — Spec esistente (`home.page.spec.ts`) ma limitato al boilerplate base (verifica solo la creazione). +* ⚠️ `display.page.ts` — Spec esistente (`display.page.spec.ts`) solo boilerplate base. +* ⚠️ `player.page.ts` — Spec esistente (`player.page.spec.ts`) solo boilerplate base. +* ❌ `playlist.page.ts` — **Nessun test** +* ⚠️ `propose-canto.page.ts` — Spec esistente (`propose-canto.page.spec.ts`) solo boilerplate base. +* ❌ `settings.page.ts` — **Nessun test** + +### 3. Componenti (`src/app/components`) +* ❌ `qr-scanner/qr-scanner.component.ts` — **Nessun test** + +--- + +## 🛠️ Strategia di Mocking e Test in Angular/Ionic + +Per testare efficacemente queste classi in isolamento, definiremo una strategia di mocking standard: + +1. **Storage di Ionic (`@ionic/storage-angular`)**: + Molti servizi (`MyCantiService`, `SettingsService`, `ComunitaService`) dipendono dallo Storage. Creeremo un mock per simulare i metodi `get`, `set` e `remove` usando una mappa in memoria. +2. **Controller di Ionic (`ToastController`, `ModalController`, `AlertController`)**: + Utilizzeremo `jasmine.createSpyObj` per simulare la creazione e la presentazione dei componenti UI di Ionic senza istanziarli realmente nel DOM durante i test dei servizi. +3. **Ambiente HTML5 (Audio, Window)**: + Servizi come `AudioEngineService` e `YoutubePlayerService` interagiscono con le API audio del browser e l'oggetto `window`. Useremo dei mock o spy su `Audio`, `window.location`, ecc. + +--- + +## 🚀 Elenco Dettagliato delle Azioni da Compiere + +Le azioni sono suddivise in 6 fasi logiche per garantire un approccio sistematico e sicuro. + +### Fase 1: Verifica dell'Ambiente e Correzione dei Test Esistenti +Prima di scrivere nuovi test, dobbiamo assicurarci che l'infrastruttura di test esistente sia stabile e funzionante. + +- [ ] **Azione 1.1: Esecuzione iniziale dei test** + * Eseguire `npm run test` (o `ng test --watch=false`) per verificare se la suite iniziale compila ed è verde. +- [ ] **Azione 1.2: Correzione di `my-canti.spec.ts`** + * Rinominare il file in `my-canti.service.spec.ts` per uniformità. + * Correggere gli import: importare `MyCantiService` anziché `MyCanti`. + * Configurare il `TestBed` fornendo il mock per `Storage`, `CantiService` e `ToastController`. + * Verificare che il test passi con successo. +- [ ] **Azione 1.3: Aggiornamento dei boilerplate delle pagine esistenti** + * Risolvere eventuali errori nei test pregenerati (`home.page.spec.ts`, `display.page.spec.ts`, `player.page.spec.ts`, `propose-canto.page.spec.ts`) fornendo i moduli minimi (`IonicModule`, `RouterTestingModule`) e i mock dei servizi iniettati nei loro costruttori. + +--- + +### Fase 2: Implementazione dei Test sui Servizi (Core Logico) +I servizi sono la priorità in quanto non hanno dipendenze grafiche complesse e contengono la logica di business principale. + +- [ ] **Azione 2.1: Test per `connectivity.service.ts` e `theme.service.ts`** + * *Perché:* Sono i più semplici e privi di dipendenze esterne pesanti. + * *Test:* Cambiamenti di stato della rete online/offline, applicazione corretta delle classi CSS per i temi (scuro/chiaro). +- [ ] **Azione 2.2: Test per `lyrics-parser.service.ts`** + * *Casi di test:* Parsing corretto dei testi dei canti con accordi tra parentesi (es. `[Do]`), gestione delle righe vuote, estrazione del testo pulito, formattazione. +- [ ] **Azione 2.3: Test per `settings.service.ts`** + * *Casi di test:* Caricamento delle impostazioni di default da storage, salvataggio di nuove impostazioni, gestione del cambio di dimensione del testo, export/import delle impostazioni. +- [ ] **Azione 2.4: Test per `stats.service.ts`** + * *Casi di test:* Incremento delle statistiche di visualizzazione di un canto, persistenza su storage, generazione dei report dei canti più cantati. +- [ ] **Azione 2.5: Test per `canti.service.ts` e `canti-letture.service.ts`** + * *Casi di test:* Lettura del database dei canti, filtri di ricerca per titolo/testo/momento liturgico, associazione tra letture del giorno e canti consigliati (sulla base delle strategie liturgiche descritte in `liturgia_strategy.md`). +- [ ] **Azione 2.6: Test per `comunita.service.ts`** + * *Casi di test:* Gestione del codice comunità, sincronizzazione dei canti della comunità tramite chiamate HTTP (mocking di `HttpClient`), salvataggio in storage locale. +- [ ] **Azione 2.7: Test per `playlist.service.ts`** + * *Casi di test:* Creazione, modifica e cancellazione di playlist, riordino dei canti all'interno di una playlist, salvataggio e ripristino da storage. +- [ ] **Azione 2.8: Test per `media-session.service.ts`** + * *Casi di test:* Integrazione con l'API `navigator.mediaSession` del browser, aggiornamento dei metadati audio (titolo, autore, copertina), gestione degli eventi di riproduzione/pausa del sistema operativo. +- [ ] **Azione 2.9: Test per `audio-engine.service.ts` e `youtube-player.service.ts`** + * *Casi di test:* Avvio, pausa, stop e seek delle tracce audio locali e dei video YouTube, gestione degli eventi di fine riproduzione, aggiornamento dello stato tramite Signals/RxJS. + +--- + +### Fase 3: Implementazione dei Test sui Componenti Condivisi +- [ ] **Azione 3.1: Test per `qr-scanner.component.ts`** + * *Casi di test:* Inizializzazione della fotocamera, gestione dei permessi negati, decodifica del codice QR (simulando l'evento del decoder), emissione del codice scansionato tramite `@Output()`, interruzione dello streaming video alla distruzione del componente. + +--- + +### Fase 4: Implementazione e Arricchimento dei Test sulle Pagine (UI & Controller) +Qui testeremo l'integrazione tra i servizi (mockati) e l'interfaccia utente di Ionic. + +- [ ] **Azione 4.1: Test approfonditi per `home.page.ts`** + * *Casi di test:* Visualizzazione dell'elenco dei canti, funzionamento della barra di ricerca (filtro istantaneo), apertura dei dettagli del canto, gestione della navigazione verso le altre pagine. +- [ ] **Azione 4.2: Test approfonditi per `player.page.ts`** + * *Casi di test:* Interazione con i pulsanti di play/pause, scorrimento del testo a tempo, trasposizione degli accordi (es. +1 semitono, -1 semitono) con aggiornamento dinamico del testo a schermo. +- [ ] **Azione 4.3: Test approfonditi per `display.page.ts`** + * *Casi di test:* Rendering corretto del testo del canto, applicazione del tema visivo e della dimensione del font dalle impostazioni, gestione del blocco dello spegnimento dello schermo (se implementato). +- [ ] **Azione 4.4: Creazione e test per `playlist.page.ts`** + * *Casi di test:* Visualizzazione dell'elenco delle playlist dell'utente, creazione di una nuova playlist tramite popup, aggiunta di canti, eliminazione di canti con swipe. +- [ ] **Azione 4.5: Test approfonditi per `propose-canto.page.ts`** + * *Casi di test:* Validazione del form di proposta (titolo obbligatorio, testo minimo), generazione della mailto URL corretta con il body in formato JSON, comportamento del pulsante di invio. +- [ ] **Azione 4.6: Creazione e test per `settings.page.ts`** + * *Casi di test:* Toggle del tema scuro (con verifica dell'applicazione al DOM), selezione della dimensione del font, reset dei dati locali con richiesta di conferma tramite `AlertController`. + +--- + +### Fase 5: Raccolta delle Metriche di Coverage e Rifinitura +- [ ] **Azione 5.1: Configurazione del report di coverage** + * Assicurarsi che `karma.conf.js` sia configurato per esportare i dati in formato `lcov` o `html` (tramite `karma-coverage`). +- [ ] **Azione 5.2: Generazione del report** + * Eseguire `ng test --code-coverage --watch=false`. + * Esaminare la cartella `coverage/` generata per individuare eventuali rami logici (branches) o righe non coperte nei servizi core. +- [ ] **Azione 5.3: Incremento mirato del coverage** + * Aggiungere test specifici per coprire i casi limite (*edge cases*) e la gestione degli errori (es. fallimento delle chiamate HTTP, storage corrotto). + +--- + +### Fase 6: Automazione in CI/CD (Opzionale ma Consigliato) +- [ ] **Azione 6.1: Configurazione test headless** + * Configurare Karma per eseguire i test in modalità headless usando `ChromeHeadless` su sistemi di Continuous Integration (es. GitHub Actions). + * Aggiungere uno script npm `test:ci`: `"test:ci": "ng test --watch=false --browsers=ChromeHeadless"`. + +--- + +## 📈 Tabella di Marcia Consigliata + +```mermaid +gantt + title Roadmap per la Copertura dei Test + dateFormat YYYY-MM-DD + section Fase 1 + Verifica & Fix Esistenti :active, 2026-05-21, 2d + section Fase 2 + Test Servizi Core : 2026-05-23, 5d + section Fase 3 & 4 + Test Componenti & Pagine : 2026-05-28, 5d + section Fase 5 & 6 + Coverage & CI/CD : 2026-06-02, 2d +``` + +> [!TIP] +> **Consiglio per l'efficienza**: Si raccomanda di iniziare ad implementare i test partendo dai servizi a più basso livello (come `ConnectivityService`, `ThemeService`, `LyricsParserService`) perché sono privi di dipendenze e consentono di stabilire rapidamente dei pattern di test solidi prima di affrontare servizi più complessi o interfacce grafiche. diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..98055f2 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,19 @@ + + RewriteEngine On + + # Se il file o la directory richiesti esistono, li serve direttamente + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + + # Altrimenti reindirizza tutto a index.html (gestito da Angular) + RewriteRule ^ index.html [L] + + + + # Disabilita il caching per l'index.html, il manifesto e i file di configurazione del Service Worker + + Header set Cache-Control "no-cache, no-store, must-revalidate" + Header set Pragma "no-cache" + Header set Expires 0 + + diff --git a/public/icons/icon-128x128.png b/public/icons/icon-128x128.png new file mode 100644 index 0000000..f9375e1 Binary files /dev/null and b/public/icons/icon-128x128.png differ diff --git a/public/icons/icon-144x144.png b/public/icons/icon-144x144.png new file mode 100644 index 0000000..37894af Binary files /dev/null and b/public/icons/icon-144x144.png differ diff --git a/public/icons/icon-152x152.png b/public/icons/icon-152x152.png new file mode 100644 index 0000000..a856095 Binary files /dev/null and b/public/icons/icon-152x152.png differ diff --git a/public/icons/icon-192x192.png b/public/icons/icon-192x192.png new file mode 100644 index 0000000..750473c Binary files /dev/null and b/public/icons/icon-192x192.png differ diff --git a/public/icons/icon-384x384.png b/public/icons/icon-384x384.png new file mode 100644 index 0000000..d05a3d5 Binary files /dev/null and b/public/icons/icon-384x384.png differ diff --git a/public/icons/icon-512x512.png b/public/icons/icon-512x512.png new file mode 100644 index 0000000..f5a59bc Binary files /dev/null and b/public/icons/icon-512x512.png differ diff --git a/public/icons/icon-72x72.png b/public/icons/icon-72x72.png new file mode 100644 index 0000000..61c6986 Binary files /dev/null and b/public/icons/icon-72x72.png differ diff --git a/public/icons/icon-96x96.png b/public/icons/icon-96x96.png new file mode 100644 index 0000000..81dea00 Binary files /dev/null and b/public/icons/icon-96x96.png differ diff --git a/public/manifest.webmanifest b/public/manifest.webmanifest new file mode 100644 index 0000000..a303b9e --- /dev/null +++ b/public/manifest.webmanifest @@ -0,0 +1,80 @@ +{ + "name": "CantiCristiani", + "short_name": "CantiCristiani", + "display": "standalone", + "scope": "/", + "start_url": "/", + "theme_color": "#3880ff", + "background_color": "#ffffff", + "launch_handler": { + "client_mode": "focus-existing" + }, + "protocol_handlers": [ + { + "protocol": "web+canti", + "url": "/?url=%s" + } + ], + "icons": [ + { + "src": "assets/icons/icon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-128x128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-152x152.png", + "sizes": "152x152", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any" + }, + { + "src": "assets/icons/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "assets/icons/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/qr_test.png b/qr_test.png new file mode 100644 index 0000000..f9f7ce0 Binary files /dev/null and b/qr_test.png differ diff --git a/scratch/check_settings.py b/scratch/check_settings.py new file mode 100644 index 0000000..f6c3404 --- /dev/null +++ b/scratch/check_settings.py @@ -0,0 +1,13 @@ +import urllib.request +import json + +url = "https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables?uuid=pwa-cc-uuid&email=&platform=browser&version=1.0&gruppo=123456&all_song=false" +req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) +print("Fetching...") +with urllib.request.urlopen(req) as res: + data = json.loads(res.read().decode("utf-8")) + + settings = data.get("canti_settings", {}).get("data", []) + print(f"Total settings: {len(settings)}") + for s in settings[:10]: + print(s) diff --git a/scratch/deploy_ftp.py b/scratch/deploy_ftp.py new file mode 100644 index 0000000..69aa2b4 --- /dev/null +++ b/scratch/deploy_ftp.py @@ -0,0 +1,154 @@ +import os +import sys +import threading +from ftplib import FTP, error_perm +from concurrent.futures import ThreadPoolExecutor, as_completed + +thread_local = threading.local() + +def load_env(): + env = {} + if os.path.exists('.env'): + with open('.env', 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line and not line.startswith('#'): + if '=' in line: + key, val = line.split('=', 1) + env[key.strip()] = val.strip() + return env + +def get_ftp_connection(ftp_host, ftp_user, ftp_pass): + if not hasattr(thread_local, "ftp") or thread_local.ftp is None: + ftp = FTP(ftp_host, timeout=30) + ftp.login(ftp_user, ftp_pass) + ftp.passive = True + thread_local.ftp = ftp + return thread_local.ftp + +def close_thread_connection(): + if hasattr(thread_local, "ftp") and thread_local.ftp is not None: + try: + thread_local.ftp.quit() + except: + try: + thread_local.ftp.close() + except: + pass + thread_local.ftp = None + +def ensure_remote_dir(ftp, path): + parts = path.replace('\\', '/').strip('/').split('/') + current = "" + for part in parts: + if not part: + continue + current += "/" + part + try: + ftp.mkd(current) + print(f"\nCreated remote dir: {current}") + except error_perm: + # Directory already exists or permission error (which is normal if it exists) + pass + +def upload_file_task(local_path, rel_path, ftp_host, ftp_user, ftp_pass, created_dirs, created_dirs_lock): + ftp_path = rel_path.replace('\\', '/') + remote_dir = os.path.dirname(ftp_path) + + # Ensure remote directory exists + if remote_dir: + with created_dirs_lock: + if remote_dir not in created_dirs: + try: + ftp = get_ftp_connection(ftp_host, ftp_user, ftp_pass) + ensure_remote_dir(ftp, remote_dir) + created_dirs.add(remote_dir) + except Exception as e: + thread_local.ftp = None + try: + ftp = get_ftp_connection(ftp_host, ftp_user, ftp_pass) + ensure_remote_dir(ftp, remote_dir) + created_dirs.add(remote_dir) + except Exception as err2: + return False, ftp_path, f"Failed directory creation: {err2}" + + # Upload the file + for attempt in range(3): + try: + ftp = get_ftp_connection(ftp_host, ftp_user, ftp_pass) + with open(local_path, 'rb') as f: + ftp.storbinary(f"STOR {ftp_path}", f) + return True, ftp_path, None + except Exception as e: + thread_local.ftp = None # Force reconnect on next attempt + if attempt == 2: + return False, ftp_path, str(e) + return False, ftp_path, "Unknown error" + +def main(): + env = load_env() + ftp_host = "ftp.canticristiani.it" + ftp_user = "canticristiani.it" + ftp_pass = env.get("FTP_PASSWORD") + + if not ftp_pass: + print("❌ Error: FTP_PASSWORD not found in .env") + sys.exit(1) + + local_dir = "www" + if not os.path.isdir(local_dir): + print(f"❌ Error: Local dir '{local_dir}' not found.") + sys.exit(1) + + files_to_upload = [] + for root, dirs, files in os.walk(local_dir): + for file in files: + local_path = os.path.join(root, file) + rel_path = os.path.relpath(local_path, local_dir) + files_to_upload.append((local_path, rel_path)) + + total = len(files_to_upload) + uploaded = 0 + errors = [] + + created_dirs = set() + created_dirs_lock = threading.Lock() + progress_lock = threading.Lock() + + # Thread limit: default to 100 as requested + num_threads = int(os.environ.get("FTP_THREADS", env.get("FTP_THREADS", "100"))) + print(f"🚀 Starting parallel upload of {total} files using {num_threads} threads...") + + def run_task(item): + nonlocal uploaded + local_path, rel_path = item + success, ftp_path, err_msg = upload_file_task( + local_path, rel_path, ftp_host, ftp_user, ftp_pass, created_dirs, created_dirs_lock + ) + with progress_lock: + uploaded += 1 + print(f"\rUploading [{uploaded}/{total}] {ftp_path}...", end="", flush=True) + if not success: + errors.append((ftp_path, err_msg)) + + with ThreadPoolExecutor(max_workers=num_threads) as executor: + futures = [executor.submit(run_task, item) for item in files_to_upload] + for future in as_completed(futures): + pass + + # Cleanup connections + with ThreadPoolExecutor(max_workers=num_threads) as cleanup_executor: + cleanups = [cleanup_executor.submit(close_thread_connection) for _ in range(num_threads)] + for future in as_completed(cleanups): + pass + + if errors: + print(f"\n⚠️ Deploy completed with {len(errors)} errors:") + for path, err in errors: + print(f" {path}: {err}") + sys.exit(1) + else: + print("\n\n✅ Deploy completed successfully with 100% files uploaded without errors!") + +if __name__ == '__main__': + main() diff --git a/scratch/extract_icons.js b/scratch/extract_icons.js new file mode 100644 index 0000000..76b0d3f --- /dev/null +++ b/scratch/extract_icons.js @@ -0,0 +1,34 @@ +const fs = require('fs'); +const path = require('path'); + +function walkDir(dir, callback) { + fs.readdirSync(dir).forEach(f => { + let dirPath = path.join(dir, f); + let isDirectory = fs.statSync(dirPath).isDirectory(); + if (isDirectory) { + walkDir(dirPath, callback); + } else { + callback(dirPath); + } + }); +} + +const icons = new Set(); + +walkDir(path.join(__dirname, '../src/app'), (filePath) => { + if (filePath.endsWith('.html') || filePath.endsWith('.ts')) { + const content = fs.readFileSync(filePath, 'utf8'); + // Match name="icon-name" + const nameMatches = content.matchAll(/name=["']([a-zA-Z0-9-]+)["']/g); + for (const match of nameMatches) { + icons.add(match[1]); + } + // Match [name]="... ? 'icon-a' : 'icon-b'" + const ternaryMatches = content.matchAll(/'([a-zA-Z0-9-]+-outline|[a-zA-Z0-9-]+-sharp|[a-zA-Z0-9-]+)'/g); + for (const match of ternaryMatches) { + icons.add(match[1]); + } + } +}); + +console.log(JSON.stringify(Array.from(icons).sort(), null, 2)); diff --git a/scratch/parse_comunita.py b/scratch/parse_comunita.py new file mode 100644 index 0000000..d1d79ac --- /dev/null +++ b/scratch/parse_comunita.py @@ -0,0 +1,34 @@ +import urllib.request +import json + +url = "https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables?uuid=pwa-cc-uuid&email=&platform=browser&version=1.0&gruppo=123456&all_song=false" +req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) +print("Fetching...") +with urllib.request.urlopen(req) as res: + data = json.loads(res.read().decode("utf-8")) + + canti_pers = data.get("canti_personali", {}).get("data", []) + states = {} + for cp in canti_pers: + state = cp.get("stato") + states[state] = states.get(state, 0) + 1 + + print("States found in canti_personali:") + for state, count in states.items(): + print(f"- State {state}: {count} songs") + + # Let's also check if there are any duplicate IDs between canti and canti_personali + canti_ids = {c["id_canti"] for c in data.get("canti", {}).get("data", [])} + canti_pers_ids = {cp["id_canti"] for cp in canti_pers} + intersection = canti_ids.intersection(canti_pers_ids) + print(f"Number of duplicate song IDs between global catalog and canti_personali: {len(intersection)}") + if len(intersection) > 0: + print("First 5 duplicate IDs:") + print(list(intersection)[:5]) + # Find one example of duplicate + dup_id = list(intersection)[0] + global_dup = next(c for c in data["canti"]["data"] if c["id_canti"] == dup_id) + pers_dup = next(cp for cp in canti_pers if cp["id_canti"] == dup_id) + print(f"\nExample Duplicate (ID {dup_id}):") + print(f"Global: Title='{global_dup.get('titolo')}', Stato={global_dup.get('stato')}") + print(f"Personal: Title='{pers_dup.get('titolo')}', Stato={pers_dup.get('stato')}") diff --git a/scratch/probe_prod.py b/scratch/probe_prod.py new file mode 100644 index 0000000..241276a --- /dev/null +++ b/scratch/probe_prod.py @@ -0,0 +1,11 @@ +import urllib.request + +url = "https://app.canticristiani.it/js/db.js" +req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) +with urllib.request.urlopen(req) as res: + content = res.read().decode("utf-8") + lines = content.split("\n") + + print("================== js/db.js lines 1260 to 1310 ==================") + for i in range(1259, min(1310, len(lines))): + print(f"{i+1}: {lines[i]}") diff --git a/scratch/test-css.html b/scratch/test-css.html new file mode 100644 index 0000000..b7e96cf --- /dev/null +++ b/scratch/test-css.html @@ -0,0 +1,33 @@ + + + + + + +
+ ti amerò come + LA + MI +
+ + diff --git a/scratch/test_merge.ts b/scratch/test_merge.ts new file mode 100644 index 0000000..ae78a4d --- /dev/null +++ b/scratch/test_merge.ts @@ -0,0 +1,67 @@ +const textWords = [ + { text: 'come', bbox: { x0: 40, x1: 60 } }, + { text: 'sei', bbox: { x0: 70, x1: 90 } } +]; + +const chordWords = [ + { text: 'la', bbox: { x0: 65, x1: 75 } }, + { text: 'mi', bbox: { x0: 95, x1: 105 } } +]; + +function mergeChordsAndLyrics(chordWords: any[], textWords: any[]): string { + let result = ''; + const chordAssignments = new Map(); + + chordWords.forEach(chord => { + const chordX = (chord.bbox.x0 + chord.bbox.x1) / 2; + let closestWord: any = null; + let minDistance = Infinity; + + textWords.forEach(textWord => { + const wordXCenter = (textWord.bbox.x0 + textWord.bbox.x1) / 2; + const dist = Math.abs(chordX - wordXCenter); + if (dist < minDistance) { + minDistance = dist; + closestWord = textWord; + } + }); + + if (closestWord) { + if (!chordAssignments.has(closestWord)) { + chordAssignments.set(closestWord, []); + } + chordAssignments.get(closestWord)!.push(chord); + } + }); + + textWords.forEach((textWord, index) => { + const assignedChords = chordAssignments.get(textWord) || []; + + // Split chords into before and after the word + const chordsBefore = assignedChords.filter(c => (c.bbox.x0 + c.bbox.x1)/2 <= textWord.bbox.x1); + const chordsAfter = assignedChords.filter(c => (c.bbox.x0 + c.bbox.x1)/2 > textWord.bbox.x1); + + chordsBefore.sort((a, b) => a.bbox.x0 - b.bbox.x0); + chordsAfter.sort((a, b) => a.bbox.x0 - b.bbox.x0); + + chordsBefore.forEach(chord => { + const cleanChord = chord.text.replace(/[\(\)\[\]]/g, '').toUpperCase(); + result += `[${cleanChord}]`; + }); + + result += textWord.text; + + chordsAfter.forEach(chord => { + const cleanChord = chord.text.replace(/[\(\)\[\]]/g, '').toUpperCase(); + result += `[${cleanChord}]`; + }); + + if (index < textWords.length - 1) { + result += ' '; + } + }); + + return result; +} + +console.log(mergeChordsAndLyrics(chordWords, textWords)); diff --git a/scratch/test_transposition.ts b/scratch/test_transposition.ts new file mode 100644 index 0000000..c7fd61d --- /dev/null +++ b/scratch/test_transposition.ts @@ -0,0 +1,20 @@ + +import { LyricsParserService } from './src/app/services/lyrics-parser.service'; + +const parser = new LyricsParserService(); + +function testTranspose(chord, semitones) { + const result = parser.transposeChord(chord, semitones); + console.log(`${chord} + ${semitones} -> ${result}`); +} + +console.log('Testing Slash Chords:'); +testTranspose('DO/SOL', 2); +testTranspose('REm/LA', 1); +testTranspose('MIb/SIb', -1); +testTranspose('FA#/DO#', 2); + +console.log('\nTesting Single Chords:'); +testTranspose('DO', 2); +testTranspose('REm', 1); +testTranspose('SIb', -1); diff --git a/seo_pwa_strategy.md b/seo_pwa_strategy.md new file mode 100644 index 0000000..1f7c463 --- /dev/null +++ b/seo_pwa_strategy.md @@ -0,0 +1,184 @@ +# Strategia SEO e Indicizzazione per la PWA dei Canti + +Questo documento definisce la strategia tecnica per consentire l'indicizzazione dei testi dei canti da parte dei motori di ricerca (in particolare Googlebot) e la corretta generazione delle anteprime (social cards) su piattaforme di messaggistica e social media (WhatsApp, Telegram, Facebook, ecc.), mantenendo intatta l'architettura PWA (Progressive Web App) offline-ready. + +--- + +## 1. Il Contesto Tecnologico +L'applicazione è sviluppata con: +- **Angular 20** (Framework Core) +- **Ionic 8** (UI & Routing integration) +- **Angular Service Worker (`@angular/service-worker`)** per le funzionalità offline della PWA. + +--- + +## 2. La Strategia Selezionata: Prerendering / Static Site Generation (SSG) + +Dato che i testi dei canti sono **dati statici** (non cambiano in base all'utente connesso e variano molto raramente), la soluzione ottimale è la **Static Site Generation (SSG)**, nota anche come **Prerendering**. + +### Come Funziona la Sinergia SSG + PWA +1. **Fase di Build:** Durante la compilazione dell'app (`ng build`), Angular genera un file `index.html` statico e pre-renderizzato per ogni singolo canto (es. `/canti/tu-sei-sorgente/index.html`). +2. **Scansione dello Spider (SEO):** Quando Googlebot o i crawler dei social richiedono l'URL di un canto, il server o la CDN distribuiscono immediatamente il file HTML statico già popolato con il testo del canto e con i meta tag corretti. +3. **Idratazione e PWA (Client):** Quando un utente apre la pagina sul browser, Angular scarica i bundle JavaScript ed esegue l'**hydration** in background. L'applicazione "prende vita" come Single Page Application (SPA), attiva il Service Worker e abilita la navigazione offline e l'installabilità come PWA. + +--- + +## 3. Fasi e Dettagli di Implementazione + +### Fase 1: Struttura degli URL e Routing Semantico +Per facilitare la SEO, gli URL devono essere parlanti e privi di simboli di hash (`#`). Attualmente, l'applicazione utilizza già il routing basato su percorsi standard (PathLocationStrategy) in [app-routing.module.ts](file:///Users/davidfrassi/SRC/agenti/canti/src/app/app-routing.module.ts). + +È necessario definire una rotta dedicata per i singoli canti che accetti un parametro semantico (detto *slug* o *alias*), ad esempio: + +```typescript +// src/app/app-routing.module.ts +const routes: Routes = [ + // ... altre rotte + { + path: 'canti/:slug', + loadChildren: () => import('./pages/canto-detail/canto-detail.module').then(m => m.CantoDetailPageModule) + } +]; +``` + +I collegamenti all'interno dell'applicazione per navigare verso i canti devono utilizzare il tag semantico `` con la direttiva `routerLink`, per consentire a Googlebot di scoprire autonomamente tutte le pagine: + +```html + +... + + + + {{ canto.titolo }} + +``` + +--- + +### Fase 2: Gestione dei Meta Tag Dinamici +Ogni canto deve avere un titolo e una descrizione univoci e ottimizzati per la SEO. In Angular si utilizzano i servizi `Title` e `Meta` di `@angular/platform-browser` per aggiornare i metadati all'inizializzazione del componente: + +```typescript +// src/app/pages/canto-detail/canto-detail.page.ts +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Title, Meta } from '@angular/platform-browser'; +import { CantiService } from '../../services/canti.service'; + +@Component({ + selector: 'app-canto-detail', + templateUrl: './canto-detail.page.html', + styleUrls: ['./canto-detail.page.scss'], +}) +export class CantoDetailPage implements OnInit { + canto: any; + + constructor( + private route: ActivatedRoute, + private cantiService: CantiService, + private titleService: Title, + private metaService: Meta + ) {} + + ngOnInit() { + const slug = this.route.snapshot.paramMap.get('slug'); + if (slug) { + this.canto = this.cantiService.getCantoBySlug(slug); + this.updateSEOMetadata(); + } + } + + updateSEOMetadata() { + const titoloCompleto = `${this.canto.titolo} - Canti Cristiani`; + const descrizione = `Testo e accordi del canto "${this.canto.titolo}". ${this.canto.testo.substring(0, 150)}...`; + + // Imposta il titolo della pagina + this.titleService.setTitle(titoloCompleto); + + // Imposta i meta tag standard per la SEO + this.metaService.updateTag({ name: 'description', content: descrizione }); + + // Imposta i tag OpenGraph per la condivisione sui social (Facebook, WhatsApp, Telegram) + this.metaService.updateTag({ property: 'og:title', content: titoloCompleto }); + this.metaService.updateTag({ property: 'og:description', content: descrizione }); + this.metaService.updateTag({ property: 'og:type', content: 'article' }); + this.metaService.updateTag({ property: 'og:url', content: `https://canti.cristiani.it/canti/${this.canto.slug}` }); + + // Se c'è un'immagine associata o una copertina di default + this.metaService.updateTag({ property: 'og:image', content: 'https://canti.cristiani.it/assets/og-cover.png' }); + } +} +``` + +--- + +### Fase 3: Configurazione del Prerendering (SSG) in Angular 20 +In Angular 20, l'abilitazione del server-side rendering e del prerendering statico durante la compilazione avviene aggiungendo il pacchetto SSR ufficiale: + +```bash +ng add @angular/ssr +``` + +Questo comando configura automaticamente l'applicazione modificando `angular.json` e creando i file necessari per la compilazione lato server. + +#### Configurazione delle rotte da pre-renderizzare +Poiché l'elenco dei canti è dinamico (es. risiede in file JSON o database), dobbiamo indicare ad Angular quali rotte generare staticamente durante il comando `ng build`. + +Si crea un file di configurazione per definire le rotte o si utilizza uno script per estrarle dinamicamente: + +1. **Creare un file delle rotte statiche** `prerender-routes.txt`: + ```txt + /home + /settings + /canti/tu-sei-sorgente + /canti/re-dei-re + /canti/lodi-al-altissimo + ``` +2. **Automatizzare la generazione di questo file** inserendo uno script (es. `generate-routes.js`) da eseguire prima della build che legge l'elenco dei canti dal file JSON locale e scrive l'elenco dei percorsi in `prerender-routes.txt`. +3. **Configurare `angular.json`** per consumare questo file: + ```json + "prerender": { + "discoverRoutes": false, + "routesFile": "prerender-routes.txt" + } +``` + +Al termine della build (`npm run build`), nella cartella di distribuzione (es. `dist/canticristiani/browser`) verranno generate cartelle fisiche con i file `index.html` pronti all'uso per ciascuna rotta definita. + +--- + +### Fase 4: Sitemap.xml e Robots.txt +Per garantire che Googlebot trovi tempestivamente tutti i canti, è fondamentale generare un file `sitemap.xml` da posizionare nella radice del server web. + +#### Esempio di `sitemap.xml`: +```xml + + + + https://canti.cristiani.it/home + weekly + 1.0 + + + + https://canti.cristiani.it/canti/tu-sei-sorgente + monthly + 0.8 + + +``` + +#### Esempio di `robots.txt`: +```txt +User-agent: * +Allow: / + +Sitemap: https://canti.cristiani.it/sitemap.xml +``` + +--- + +## 4. Vantaggi e Risultati Attesi +- **Indicizzazione immediata:** Googlebot indicizzerà i testi dei canti all'istante, consentendo agli utenti di trovare la PWA cercando frammenti di testo o il titolo del canto direttamente su Google. +- **Anteprime nei Social Perfette:** La condivisione dei link sui canali di comunicazione mostrerà anteprime ricche (titolo corretto, frammento del testo del canto e logo dell'app). +- **Integrità PWA:** L'utente beneficerà di un caricamento iniziale ultra-veloce (grazie all'HTML pre-renderizzato) seguito dall'installazione offline e dall'esperienza fluida tipica dell'applicazione mobile. diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts new file mode 100644 index 0000000..cd6f74a --- /dev/null +++ b/src/app/app-routing.module.ts @@ -0,0 +1,38 @@ +import { NgModule } from '@angular/core'; +import { PreloadAllModules, RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: 'home', + loadChildren: () => import('./home/home.module').then( m => m.HomePageModule) + }, + { + path: '', + redirectTo: 'home', + pathMatch: 'full' + }, + { + path: 'player', + loadChildren: () => import('./pages/player/player.module').then( m => m.PlayerPageModule) + }, + { + path: 'display', + loadChildren: () => import('./pages/display/display.module').then( m => m.DisplayPageModule) + }, + { + path: 'settings', + loadChildren: () => import('./pages/settings/settings.module').then( m => m.SettingsPageModule) + }, + { + path: 'propose-canto', + loadComponent: () => import('./pages/propose-canto/propose-canto.page').then( m => m.ProposeCantoPage) + }, +]; + +@NgModule({ + imports: [ + RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) + ], + exports: [RouterModule] +}) +export class AppRoutingModule { } diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000..4dd1a68 --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,183 @@ + + +
+ + +
+
+
+ CantiCristiani +
+ + + +

Applicazione Installata

+
+ La app risulta già installata sul dispositivo, chiudi il browser ed usa quella oppure disinstallala se preferisci utilizzarla da qui. +
+
+ +
+
+ + + + + +

Apertura App in corso

+

+ Stiamo aprendo la PWA installata per caricare la playlist ed evitare cache del browser obsoleta. +

+
+ +
+ Per evitare problemi di cache, la navigazione da browser è disattivata se la PWA è installata.
+ Se preferisci usare il browser, disinstalla l'app dal dispositivo. +
+
+
+ + + + +
+

Aggiungi a Home (iOS)

+

+ Per aggiornamenti istantanei e uso offline, aggiungi l'app alla schermata Home di iOS: +

+
+
+
1
+
+ Tocca il pulsante Condividi 📤 in Safari. +
+
+
+
2
+
+ Scorri il menu e seleziona Aggiungi alla schermata Home ➕. +
+
+
+ +
+ + +
+

Installa CantiCristiani

+

+ Installa l'applicazione sul tuo dispositivo per evitare problemi di cache del browser ed usarla offline! +

+
+ + +
+
+
+
+
+
+ + +
+ + +
+
+ CantiCristiani +
+

Installa CantiCristiani

+

+ Installa l'applicazione sul tuo dispositivo per evitare problemi di cache del browser, aprirla all'istante ed usarla anche offline in chiesa! +

+ +
+ + +
+
+ + +
+
+
+ CantiCristiani +
+

Aggiungi a Home (iOS)

+

+ Per aggiornamenti istantanei e uso offline, aggiungi l'app alla schermata Home di iOS: +

+
+ +
+
+
1
+
+ Tocca il pulsante Condividi 📤 in Safari. +
+
+
+
2
+
+ Scorri il menu e seleziona Aggiungi alla schermata Home ➕. +
+
+
+ +
+ +
+
+ + +
+
+ CantiCristiani +
+

Installa CantiCristiani

+

+ Installa l'applicazione sul tuo computer per evitare problemi di cache del browser ed usarla offline! +

+ +
+ + +
+
+
+
diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 0000000..51b7b65 --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,21 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; + +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AppComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..e384fd2 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,756 @@ +import { Component, inject, NgZone, OnInit, signal, effect } from '@angular/core'; +import { ThemeService } from './services/theme.service'; +import { CantiService } from './services/canti.service'; +import { SettingsService } from './services/settings.service'; +import { VERSION } from './version'; +import { Router, ActivatedRoute, NavigationStart } from '@angular/router'; +import { ToastController, Platform, AlertController, NavController } from '@ionic/angular'; +import { Location } from '@angular/common'; +import { SwUpdate, VersionReadyEvent } from '@angular/service-worker'; +import { filter, first } from 'rxjs/operators'; +import { App } from '@capacitor/app'; +import { addIcons } from 'ionicons'; +import { + add, + addCircleOutline, + addOutline, + analyticsOutline, + arrowUpCircle, + bookOutline, + calendarOutline, + cameraOutline, + cameraReverseOutline, + carOutline, + chevronBack, + chevronBackOutline, + chevronDown, + chevronDownOutline, + chevronForward, + chevronForwardOutline, + chevronUp, + chevronUpOutline, + closeCircle, + closeCircleOutline, + closeOutline, + cloudDownloadOutline, + cloudOfflineOutline, + cloudUploadOutline, + contrastOutline, + copyOutline, + createOutline, + documentAttachOutline, + documentTextOutline, + downloadOutline, + eyeOutline, + informationCircleOutline, + keypadOutline, + listOutline, + logoApple, + logoYoutube, + mic, + micOutline, + musicalNote, + musicalNotesOutline, + pause, + pauseSharp, + peopleOutline, + personOutline, + phoneLandscapeOutline, + play, + playForwardOutline, + playSharp, + playSkipBackSharp, + playSkipForwardSharp, + pricetagsOutline, + qrCodeOutline, + refreshOutline, + remove, + removeCircleOutline, + removeOutline, + reorderTwoOutline, + saveOutline, + scanOutline, + searchOutline, + settingsOutline, + shareOutline, + shareSocialOutline, + sparklesOutline, + statsChartOutline, + swapVerticalOutline, + trashOutline, + arrowUndoOutline, + videocam, + videocamOffOutline +} from 'ionicons/icons'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', + styleUrls: ['app.component.scss'], + standalone: false, +}) +export class AppComponent implements OnInit { + private themeService = inject(ThemeService); // Ensures theme is initialized at boot + public cantiService = inject(CantiService); + public settingsService = inject(SettingsService); + public version = VERSION; + private platform = inject(Platform); + private router = inject(Router); + private route = inject(ActivatedRoute); + private location = inject(Location); + private navCtrl = inject(NavController); + private toastCtrl = inject(ToastController); + private alertCtrl = inject(AlertController); + private swUpdate = inject(SwUpdate); + private ngZone = inject(NgZone); + + public showRedirectOverlay = signal(false); + public showInstallOverlay = signal(false); + public isInstalling = signal(false); + public isRedirecting = signal(false); + public isPwaInstalled = signal(false); + public redirectFailed = signal(false); + public protocolLink = ''; + + + + + constructor() { + // Gli aggiornamenti automatici e periodici sono stati rimossi. + // L'aggiornamento viene gestito esclusivamente in modo manuale + // tramite il pulsante "Verifica Aggiornamenti App" in SettingsPage. + + addIcons({ + add, + 'add-circle-outline': addCircleOutline, + 'add-outline': addOutline, + 'analytics-outline': analyticsOutline, + 'arrow-up-circle': arrowUpCircle, + 'book-outline': bookOutline, + 'calendar-outline': calendarOutline, + 'camera-outline': cameraOutline, + 'camera-reverse-outline': cameraReverseOutline, + 'car-outline': carOutline, + 'chevron-back': chevronBack, + 'chevron-back-outline': chevronBackOutline, + 'chevron-down': chevronDown, + 'chevron-down-outline': chevronDownOutline, + 'chevron-forward': chevronForward, + 'chevron-forward-outline': chevronForwardOutline, + 'chevron-up': chevronUp, + 'chevron-up-outline': chevronUpOutline, + 'close-circle': closeCircle, + 'close-circle-outline': closeCircleOutline, + 'close-outline': closeOutline, + 'cloud-download-outline': cloudDownloadOutline, + 'cloud-offline-outline': cloudOfflineOutline, + 'cloud-upload-outline': cloudUploadOutline, + 'contrast-outline': contrastOutline, + 'copy-outline': copyOutline, + 'create-outline': createOutline, + 'document-attach-outline': documentAttachOutline, + 'document-text-outline': documentTextOutline, + 'download-outline': downloadOutline, + 'eye-outline': eyeOutline, + 'information-circle-outline': informationCircleOutline, + 'keypad-outline': keypadOutline, + 'list-outline': listOutline, + 'logo-apple': logoApple, + 'logo-youtube': logoYoutube, + mic, + 'mic-outline': micOutline, + 'musical-note': musicalNote, + 'musical-notes-outline': musicalNotesOutline, + pause, + 'pause-sharp': pauseSharp, + 'people-outline': peopleOutline, + 'person-outline': personOutline, + 'phone-landscape-outline': phoneLandscapeOutline, + play, + 'play-forward-outline': playForwardOutline, + 'play-sharp': playSharp, + 'play-skip-back-sharp': playSkipBackSharp, + 'play-skip-forward-sharp': playSkipForwardSharp, + 'pricetags-outline': pricetagsOutline, + 'qr-code-outline': qrCodeOutline, + 'refresh-outline': refreshOutline, + remove, + 'remove-circle-outline': removeCircleOutline, + 'remove-outline': removeOutline, + 'reorder-two-outline': reorderTwoOutline, + 'save-outline': saveOutline, + 'scan-outline': scanOutline, + 'search-outline': searchOutline, + 'settings-outline': settingsOutline, + 'share-outline': shareOutline, + 'share-social-outline': shareSocialOutline, + 'sparkles-outline': sparklesOutline, + 'stats-chart-outline': statsChartOutline, + 'swap-vertical-outline': swapVerticalOutline, + 'trash-outline': trashOutline, + 'arrow-undo-outline': arrowUndoOutline, + videocam, + 'videocam-off-outline': videocamOffOutline + }); + + effect(() => { + this.checkLoaderDismissal(); + }); + } + + checkLoaderDismissal() { + const ready = this.settingsService.isVersionCheckComplete() && this.cantiService.firstLoadCompleted(); + if (!ready) { + return; + } + + // Se stiamo attivamente installando o reindirizzando, NON nascondiamo il loader + if (this.isInstalling() || this.isRedirecting()) { + return; + } + + // Altrimenti, nascondiamo il loader per far entrare l'utente + if ((window as any).PwaLoader) { + (window as any).PwaLoader.hide(); + } + } + + async ngOnInit() { + // Gestione del tasto back (PWA/Browser e Nativo/Hardware) secondo le 3 specifiche: + // 1- Se siamo su un canto (/player o /display), premendo back andiamo sempre sulla home. + // 2- Se siamo sulla home (/home o /), premendo back l'app deve uscire. + // 3- Per tutto il resto, segue la logica standard andando alla pagina precedente nello storico. + + // Gestione popstate (tasto indietro browser / gesture PWA) + this.router.events.pipe( + filter((e): e is NavigationStart => e instanceof NavigationStart), + filter(e => e.navigationTrigger === 'popstate') + ).subscribe(() => { + const currentPath = this.router.url.split('?')[0]; + if (currentPath === '/home' || currentPath === '/') { + // Spec 2: Sulla home, usciamo dall'app + this.router.navigate(['/home'], { replaceUrl: true }); + this.exitApp(); + } else if (currentPath === '/player' || currentPath === '/display') { + // Spec 1: Su un canto, andiamo alla home azzerando lo stack + this.navCtrl.navigateRoot('/home', { animationDirection: 'back' }); + } + // Spec 3: Per il resto (es. /settings), popstate prosegue normalmente verso la pagina precedente + }); + + // Gestione tasto indietro hardware (es. Android / Capacitor / PWA) + this.platform.backButton.subscribeWithPriority(10, async () => { + const currentPath = this.router.url.split('?')[0]; + if (currentPath === '/home' || currentPath === '/') { + // Spec 2: Sulla home, usciamo dall'app + this.exitApp(); + } else if (currentPath === '/player' || currentPath === '/display') { + // Spec 1: Su un canto, andiamo alla home azzerando lo stack + this.navCtrl.navigateRoot('/home', { animationDirection: 'back' }); + } else { + // Spec 3: Per il resto, logica standard (pagina precedente) + if (window.history.length > 1) { + this.location.back(); + } else { + this.navCtrl.navigateRoot('/home', { animationDirection: 'back' }); + } + } + }); + + // Add global horizontal scroll support for wheel on horizontal containers + window.addEventListener('wheel', (event: WheelEvent) => { + if (Math.abs(event.deltaY) > 0 && Math.abs(event.deltaX) === 0) { + const path = event.composedPath(); + for (const target of path) { + if (target instanceof HTMLElement) { + const style = window.getComputedStyle(target); + const isHorizontalScroll = + (style.overflowX === 'auto' || style.overflowX === 'scroll') && + target.scrollWidth > target.clientWidth; + + if (isHorizontalScroll) { + target.scrollLeft += event.deltaY; + event.preventDefault(); + break; + } + } + } + } + }, { passive: false }); + + // 1. Allineamento istantaneo alla versione remota + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ + phase: 'Fase: Verifica Versione', + desc: 'Verifica della versione più recente in corso...' + }); + } + + const updated = await this.checkVersionSync(); + if (updated) { + return; // Reloading, skip further setup + } + + // Set signal indicating startup version check is complete + this.settingsService.isVersionCheckComplete.set(true); + + // Handle PWA Launch Queue if supported (focus-existing launch behavior) + if ('launchQueue' in window) { + (window as any).launchQueue.setConsumer((launchParams: any) => { + if (launchParams.targetURL) { + this.handleLaunchUrl(launchParams.targetURL); + } + }); + } + + this.route.queryParams.subscribe(params => { + const protocolUrl = params['url']; + if (protocolUrl && protocolUrl.startsWith('web+canti:')) { + try { + const cleanUrl = protocolUrl.replace('web+canti://', 'http://localhost/'); + const urlObj = new URL(cleanUrl); + + let targetPath = urlObj.pathname; + if (targetPath === '/open' || targetPath === '//open') { + targetPath = '/'; + } else if (targetPath.startsWith('/open/')) { + targetPath = targetPath.substring(5); + } + + const queryParams: any = {}; + urlObj.searchParams.forEach((value, key) => { + queryParams[key] = value; + }); + + this.router.navigate([targetPath], { queryParams, replaceUrl: true }); + } catch (e) { + console.error('Failed to parse protocol url:', protocolUrl, e); + } + } + }); + window.addEventListener('appinstalled', () => { + console.log('[AppComponent] PWA appinstalled event caught.'); + localStorage.setItem('pwa-installed', 'true'); + this.isPwaInstalled.set(true); + this.showInstallOverlay.set(false); + this.showRedirectOverlay.set(false); + + // Se la finestra è GIÀ stata trasformata in PWA standalone (es. Desktop Mac/Windows) + const isStandalone = window.matchMedia('(display-mode: standalone)').matches || (navigator as any).standalone; + if (isStandalone) { + this.isInstalling.set(false); + this.isRedirecting.set(false); + this.checkLoaderDismissal(); + return; + } + + // Su Android, l'evento 'appinstalled' scatta in 2-3 secondi, MA l'OS impiega 10-12s + // per pacchettizzare e registrare il WebAPK nella schermata Home. + // Calibriamo la progress bar spalmata su ~11 secondi reali prima del reindirizzamento. + this.isInstalling.set(true); + this.isRedirecting.set(false); + + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ + title: 'Installazione applicazione', + phase: 'Fase: Registrazione', + desc: 'Generazione e registrazione dell\'applicazione sul dispositivo in corso...', + percent: 15 + }); + } + + const startTime = Date.now(); + const TARGET_DURATION_MS = 11000; // 11 secondi reali per completare l'installazione WebAPK + + const timer = setInterval(() => { + const elapsed = Date.now() - startTime; + let pct = Math.min(100, Math.round(15 + (elapsed / TARGET_DURATION_MS) * 85)); + + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ percent: pct }); + } + + if (pct >= 100) { + clearInterval(timer); + this.isInstalling.set(false); + this.isRedirecting.set(true); + + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ + title: 'Chiudi il browser', + desc: 'Applicazione installata con successo! Chiudi il browser e continua sulla PWA.', + isRedirect: true + }); + } + + if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { + console.log('[AppComponent] Running on localhost - skipping protocol link redirect on appinstalled.'); + this.isRedirecting.set(false); + this.checkLoaderDismissal(); + return; + } + + setTimeout(() => { + window.location.href = this.protocolLink; + }, 1000); + } + }, 250); + }); + + this.checkAndRedirectToPwa(); + } + + handleLaunchUrl(urlStr: string) { + try { + const urlObj = new URL(urlStr); + + // 1. Check if it's a protocol link inside query params (e.g. /?url=web+canti://...) + const protocolUrl = urlObj.searchParams.get('url'); + if (protocolUrl && protocolUrl.startsWith('web+canti:')) { + const cleanUrl = protocolUrl.replace('web+canti://', 'http://localhost/'); + const innerUrlObj = new URL(cleanUrl); + + let targetPath = innerUrlObj.pathname; + if (targetPath === '/open' || targetPath === '//open') { + targetPath = '/'; + } else if (targetPath.startsWith('/open/')) { + targetPath = targetPath.substring(5); + } + + const queryParams: any = {}; + innerUrlObj.searchParams.forEach((value, key) => { + queryParams[key] = value; + }); + + console.log('[AppComponent] Launch queue routing (protocol) to:', targetPath, queryParams); + this.router.navigate([targetPath], { queryParams, replaceUrl: true }); + return; + } + + // 2. Otherwise, route directly to the pathname and query params of the URL + let targetPath = urlObj.pathname; + const queryParams: any = {}; + urlObj.searchParams.forEach((value, key) => { + queryParams[key] = value; + }); + + console.log('[AppComponent] Launch queue routing (direct) to:', targetPath, queryParams); + this.router.navigate([targetPath], { queryParams, replaceUrl: true }); + } catch (e) { + console.error('Failed to parse launch url:', urlStr, e); + } + } + + async checkVersionSync(): Promise { + // Verifica all'avvio se è disponibile una nuova versione remota (sia tramite version.json che SwUpdate) + // Se disponibile, viene aggiornata e attivata automaticamente senza richiedere l'intervento dell'utente. + try { + console.log(`[PWA-Update] Verifica version.json all'avvio (locale=${VERSION})...`); + const response = await Promise.race([ + fetch(`/version.json?cb=${Date.now()}`, { cache: 'no-store' }), + new Promise((resolve) => setTimeout(() => resolve(null), 5000)) + ]); + if (response && response.ok) { + const data = await response.json(); + if (data && data.version && data.version !== VERSION) { + console.log(`[PWA-Update] Mismatch rilevato: locale=${VERSION}, remota=${data.version}. Avvio aggiornamento automatico...`); + + // Scarica e attiva il nuovo Service Worker se abilitato + if (this.swUpdate.isEnabled) { + try { + const hasSwUpdate = await Promise.race([ + this.swUpdate.checkForUpdate(), + new Promise((resolve) => setTimeout(() => resolve(false), 8000)) + ]); + if (hasSwUpdate) { + console.log('[PWA-Update] SW aggiornamento disponibile, attivazione automatica...'); + await Promise.race([ + this.swUpdate.activateUpdate(), + new Promise((resolve) => setTimeout(resolve, 5000)) + ]); + } + } catch (e) { + console.warn('[PWA-Update] SwUpdate durante mismatch fallito:', e); + } + } + + // Forziamo il controllo di aggiornamento della registrazione Service Worker + if ('serviceWorker' in navigator) { + try { + const registration = await navigator.serviceWorker.ready; + await registration.update(); + } catch (e) { + console.warn('[PWA-Update] SW registration.update fallito:', e); + } + } + + // Deregistra i vecchi Service Worker per applicare la nuova versione pulita + if ('serviceWorker' in navigator) { + const registrations = await navigator.serviceWorker.getRegistrations(); + for (const registration of registrations) { + await registration.unregister(); + } + } + + // Pulisci le cache del browser + if ('caches' in window) { + const keys = await caches.keys(); + for (const key of keys) { + await caches.delete(key); + } + } + + // Ricarica la pagina in modo trasparente + const url = new URL(window.location.href); + url.searchParams.set('update_cb', Date.now().toString()); + window.location.replace(url.toString()); + return true; + } else { + console.log('[PWA-Update] Versione allineata, nessun aggiornamento necessario.'); + return false; + } + } + } catch (e) { + console.warn('[PWA-Update] version.json check fallito:', e); + } + + return false; + } + + async checkAndRedirectToPwa() { + if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { + console.log('[AppComponent] Running on localhost - skipping PWA redirect and install overlays.'); + this.checkLoaderDismissal(); + return; + } + + const isStandalone = window.matchMedia('(display-mode: standalone)').matches || (navigator as any).standalone; + if (isStandalone) { + localStorage.setItem('pwa-installed', 'true'); + this.checkLoaderDismissal(); + return; + } + + const search = window.location.search; + const path = window.location.pathname; + this.protocolLink = `web+canti://open${path}${search}`; + + let isInstalled = false; + if ('getInstalledRelatedApps' in navigator) { + try { + const relatedApps = await (navigator as any).getInstalledRelatedApps(); + isInstalled = relatedApps.length > 0; + } catch (e) { + console.warn('Failed to check installed apps:', e); + } + } else { + isInstalled = localStorage.getItem('pwa-installed') === 'true'; + } + + // Se prima era salvata come installata ma l'utente riceve il prima possibile un beforeinstallprompt, + // significa che l'app è stata disinstallata! + if (this.settingsService.deferredPrompt() || this.settingsService.showInstallButton()) { + isInstalled = false; + localStorage.setItem('pwa-installed', 'false'); + } + + this.isPwaInstalled.set(isInstalled); + + if (isInstalled) { + if (sessionStorage.getItem('skip-pwa-redirect') === 'true') { + this.showRedirectOverlay.set(false); + this.checkLoaderDismissal(); + return; + } + this.showRedirectOverlay.set(true); + this.redirectFailed.set(false); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ isRedirect: true }); + } + // Tentiamo il reindirizzamento automatico + setTimeout(() => { + window.location.href = this.protocolLink; + + // Se dopo 2 secondi l'utente è ancora qui, mostriamo lo stato fallito per aprire manualmente o indicare la disinstallazione + setTimeout(() => { + if (this.showRedirectOverlay()) { + this.redirectFailed.set(true); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.hide(); + } + } + }, 2000); + }, 800); + } else { + // Se non è installata, proponiamo l'installazione immediata per evitare la cache del browser e avere un'esperienza ottimale + const skipInstall = sessionStorage.getItem('skip-pwa-install') === 'true'; + const isMobile = this.settingsService.isAndroid() || this.settingsService.isIos(); + const hasDesktopPrompt = this.settingsService.showInstallButton() || this.settingsService.deferredPrompt(); + if (!skipInstall && (isMobile || hasDesktopPrompt)) { + this.showInstallOverlay.set(true); + } else { + this.checkLoaderDismissal(); + } + } + } + + openPwaManual() { + window.location.href = this.protocolLink; + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ isRedirect: true }); + } + // Se dopo 2 secondi l'utente è ancora qui, probabilmente l'app non è installata + setTimeout(() => { + if (this.showRedirectOverlay()) { + this.redirectFailed.set(true); + localStorage.setItem('pwa-installed', 'false'); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.hide(); + } + } + }, 2000); + } + + stayInBrowser() { + sessionStorage.setItem('skip-pwa-redirect', 'true'); + this.showRedirectOverlay.set(false); + this.checkLoaderDismissal(); + } + + stayInBrowserForceUninstallCheck() { + localStorage.setItem('pwa-installed', 'false'); + this.isPwaInstalled.set(false); + this.stayInBrowser(); + } + + closeInstallOverlay() { + sessionStorage.setItem('skip-pwa-install', 'true'); + this.showInstallOverlay.set(false); + this.checkLoaderDismissal(); + } + + async triggerInstall() { + this.isInstalling.set(true); + this.showInstallOverlay.set(false); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ + title: 'Installazione in corso...', + desc: 'Completa l\'installazione tramite la finestra del browser.' + }); + } + + const outcome = await this.settingsService.installPwa(); + if (outcome === 'accepted') { + this.isInstalling.set(false); + this.isRedirecting.set(true); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ + title: 'Apertura Applicazione...', + desc: 'Installazione completata! Chiudi il browser e continua sulla PWA.', + isRedirect: true + }); + } + } else { + this.isInstalling.set(false); + this.isRedirecting.set(false); + this.showInstallOverlay.set(true); + this.checkLoaderDismissal(); + } + } + + async triggerInstallFromRedirect() { + this.isInstalling.set(true); + this.showRedirectOverlay.set(false); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ + title: 'Installazione in corso...', + desc: 'Completa l\'installazione tramite la finestra del browser.' + }); + } + + const outcome = await this.settingsService.installPwa(); + if (outcome === 'accepted') { + sessionStorage.setItem('skip-pwa-redirect', 'true'); + this.isInstalling.set(false); + this.isRedirecting.set(true); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ + title: 'Apertura Applicazione...', + desc: 'Installazione completata! Chiudi il browser e continua sulla PWA.', + isRedirect: true + }); + } + } else { + this.isInstalling.set(false); + this.isRedirecting.set(false); + this.showRedirectOverlay.set(true); + this.checkLoaderDismissal(); + } + } + + private exitApp() { + try { + App.exitApp(); + } catch (e) {} + try { + if ((navigator as any)?.app?.exitApp) { + (navigator as any).app.exitApp(); + } + } catch (e) {} + try { + window.close(); + } catch (e) {} + } +} + +export function showFullscreenUpdateOverlay() { + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ + title: 'Download aggiornamento', + phase: 'Fase: Download', + desc: 'Scaricamento della nuova versione...', + percent: 0 + }); + } + + // Fetch remote version to display the version being downloaded + fetch(`/version.json?cb=${Date.now()}`) + .then(res => { + if (res.ok) return res.json(); + throw new Error('Fallback'); + }) + .then(data => { + if (data && data.version && (window as any).PwaLoader) { + (window as any).PwaLoader.update({ + version: 'Versione ' + data.version + }); + } + }) + .catch(() => {}); + + let percent = 0; + const interval = setInterval(() => { + if (percent < 95) { + percent += Math.floor(Math.random() * 5) + 2; + if (percent > 95) percent = 95; + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ percent }); + } + } + }, 150); + + return { + finish: () => { + clearInterval(interval); + if ((window as any).PwaLoader) { + (window as any).PwaLoader.update({ percent: 100 }); + } + } + }; +} + diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..f5ac7ea --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,34 @@ +import { NgModule, isDevMode } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouteReuseStrategy } from '@angular/router'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; +import { IonicStorageModule } from '@ionic/storage-angular'; + +import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; + +import { AppComponent } from './app.component'; +import { AppRoutingModule } from './app-routing.module'; +import { ServiceWorkerModule } from '@angular/service-worker'; +import { ApiAuthInterceptor } from './interceptors/api-auth.interceptor'; + +@NgModule({ + declarations: [AppComponent], + imports: [ + BrowserModule, + IonicModule.forRoot(), + AppRoutingModule, + HttpClientModule, + IonicStorageModule.forRoot(), + ServiceWorkerModule.register('ngsw-worker.js', { + enabled: !isDevMode(), + // Register the ServiceWorker as soon as possible + registrationStrategy: 'registerImmediately' + }) + ], + providers: [ + { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }, + { provide: HTTP_INTERCEPTORS, useClass: ApiAuthInterceptor, multi: true } + ], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/src/app/components/identity-qr-modal/identity-qr-modal.component.html b/src/app/components/identity-qr-modal/identity-qr-modal.component.html new file mode 100644 index 0000000..6067181 --- /dev/null +++ b/src/app/components/identity-qr-modal/identity-qr-modal.component.html @@ -0,0 +1,41 @@ + + + QR Code di Ripristino + + + + + + + + + +
+

+ Salva questo QR Code (fai uno screenshot o scaricalo) per ripristinare il tuo account e le tue comunità se cambi dispositivo o reinstalli l'applicazione. +

+ +
+
+ QR Code di Ripristino +
+ +
+ Codice Identificativo: + {{ userUuid }} +
+
+ +
+ + + Copia Codice Testuale + + + + + Scarica Immagine QR + +
+
+
diff --git a/src/app/components/identity-qr-modal/identity-qr-modal.component.scss b/src/app/components/identity-qr-modal/identity-qr-modal.component.scss new file mode 100644 index 0000000..25e4fe3 --- /dev/null +++ b/src/app/components/identity-qr-modal/identity-qr-modal.component.scss @@ -0,0 +1,121 @@ +.qr-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 16px 8px; + text-align: center; + min-height: 100%; +} + +.description { + font-size: 0.95rem; + line-height: 1.5; + color: var(--ion-text-color); + opacity: 0.9; + margin-bottom: 24px; + max-width: 320px; +} + +.qr-card { + padding: 24px; + border-radius: 24px; + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + margin-bottom: 24px; + width: 100%; + max-width: 340px; + box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.15); +} + +.qr-wrapper { + background: white; + padding: 12px; + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + width: 220px; + height: 220px; + box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05); + + .qr-image { + width: 100%; + height: 100%; + object-fit: contain; + } +} + +.uuid-box { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + width: 100%; + padding-top: 8px; + border-top: 1px solid rgba(255, 255, 255, 0.08); +} + +.uuid-label { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--ion-color-secondary); + font-weight: 600; +} + +.uuid-text { + font-size: 0.8rem; + color: var(--ion-text-color); + word-break: break-all; + opacity: 0.85; + font-family: monospace; + user-select: all; + background: rgba(var(--ion-text-color-rgb, 255, 255, 255), 0.04); + padding: 6px 10px; + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.04); +} + +.actions-wrapper { + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; + max-width: 340px; +} + +.action-btn { + margin: 0; + --border-radius: 14px; + --box-shadow: 0 4px 16px rgba(var(--ion-color-secondary-rgb), 0.2); + font-weight: 600; + height: 48px; +} + +.download-btn { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + text-decoration: none; + background: rgba(255, 255, 255, 0.06); + color: var(--ion-text-color); + border: 1px solid rgba(255, 255, 255, 0.1); + padding: 12px; + border-radius: 14px; + font-size: 0.9rem; + font-weight: 600; + transition: all 0.2s ease; + + ion-icon { + font-size: 1.2rem; + color: var(--ion-color-secondary); + } + + &:active { + background: rgba(255, 255, 255, 0.12); + } +} diff --git a/src/app/components/identity-qr-modal/identity-qr-modal.component.ts b/src/app/components/identity-qr-modal/identity-qr-modal.component.ts new file mode 100644 index 0000000..adf2df0 --- /dev/null +++ b/src/app/components/identity-qr-modal/identity-qr-modal.component.ts @@ -0,0 +1,58 @@ +import { Component, OnInit, inject, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IonicModule, ModalController, ToastController } from '@ionic/angular'; +import * as QRCode from 'qrcode'; + +@Component({ + selector: 'app-identity-qr-modal', + templateUrl: './identity-qr-modal.component.html', + styleUrls: ['./identity-qr-modal.component.scss'], + standalone: true, + imports: [CommonModule, IonicModule] +}) +export class IdentityQrModalComponent implements OnInit { + private modalCtrl = inject(ModalController); + private toastCtrl = inject(ToastController); + + @Input() userUuid!: string; + public qrCodeUrl: string = ''; + + ngOnInit() { + this.generateQr(); + } + + async generateQr() { + try { + this.qrCodeUrl = await QRCode.toDataURL(this.userUuid, { + errorCorrectionLevel: 'H', + margin: 2, + width: 400, + color: { + dark: '#1e293b', // Slate 800 for premium dark aesthetic contrast + light: '#ffffff' + } + }); + } catch (err) { + console.error('Failed to generate QR Code:', err); + } + } + + async copyToClipboard() { + try { + await navigator.clipboard.writeText(this.userUuid); + const toast = await this.toastCtrl.create({ + message: 'Codice copiato negli appunti!', + duration: 2000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + } catch (err) { + console.error('Failed to copy text:', err); + } + } + + dismiss() { + this.modalCtrl.dismiss(); + } +} diff --git a/src/app/components/qr-scanner/qr-scanner.component.html b/src/app/components/qr-scanner/qr-scanner.component.html new file mode 100644 index 0000000..a030978 --- /dev/null +++ b/src/app/components/qr-scanner/qr-scanner.component.html @@ -0,0 +1,44 @@ + + + Scansiona QR + + Chiudi + + + + + +
+ + + +
+
+

Inquadra il QR Code della tua parrocchia

+
+ + +
+ +
+ + +
+ +

+ Su iPad, se non vedi lo switch fotocamera, tocca l'icona "aA" in alto nella barra di Safari e seleziona "Richiedi sito mobile". +

+
+
+
diff --git a/src/app/components/qr-scanner/qr-scanner.component.scss b/src/app/components/qr-scanner/qr-scanner.component.scss new file mode 100644 index 0000000..0d1f105 --- /dev/null +++ b/src/app/components/qr-scanner/qr-scanner.component.scss @@ -0,0 +1,148 @@ +.scanner-container { + position: relative; + width: 100%; + height: 100%; + background: black; + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; + + zxing-scanner { + width: 100%; + height: 100%; + } + + .scan-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background: rgba(0, 0, 0, 0.4); + pointer-events: none; + + .scan-frame { + width: 250px; + height: 250px; + border: 2px solid white; + border-radius: 20px; + box-shadow: 0 0 0 4000px rgba(0, 0, 0, 0.5); + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2px; + background: var(--ion-color-secondary); + box-shadow: 0 0 10px var(--ion-color-secondary); + animation: scan 2s linear infinite; + } + } + + .scan-text { + color: white; + margin-top: 24px; + font-weight: 500; + text-align: center; + padding: 0 40px; + } + } + + .camera-toggle-container { + position: absolute; + bottom: 50px; + left: 0; + right: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 10; + } + + .camera-toggle-btn { + background: rgba(255, 255, 255, 0.15); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(255, 255, 255, 0.25); + color: white; + padding: 12px 24px; + border-radius: 30px; + font-family: 'Outfit', sans-serif; + font-size: 14px; + font-weight: 600; + display: flex; + align-items: center; + gap: 8px; + box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37); + cursor: pointer; + transition: background 0.2s, transform 0.2s, box-shadow 0.2s; + outline: none; + + &:hover { + background: rgba(255, 255, 255, 0.25); + } + + &:active { + background: rgba(255, 255, 255, 0.35); + transform: scale(0.96); + box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.37); + } + + ion-icon { + font-size: 20px; + } + } + + .ipad-warning-container { + position: absolute; + bottom: 40px; + left: 24px; + right: 24px; + background: rgba(0, 0, 0, 0.75); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 14px; + padding: 14px 18px; + display: flex; + align-items: flex-start; + gap: 12px; + color: white; + z-index: 10; + box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5); + + ion-icon { + font-size: 24px; + color: var(--ion-color-secondary); + flex-shrink: 0; + margin-top: 2px; + } + + p { + margin: 0; + font-family: 'Outfit', sans-serif; + font-size: 0.82rem; + line-height: 1.45; + font-weight: 500; + text-align: left; + + strong { + color: var(--ion-color-secondary); + font-weight: 700; + } + } + } +} + +@keyframes scan { + 0% { top: 0; } + 100% { top: 100%; } +} diff --git a/src/app/components/qr-scanner/qr-scanner.component.ts b/src/app/components/qr-scanner/qr-scanner.component.ts new file mode 100644 index 0000000..bd671e3 --- /dev/null +++ b/src/app/components/qr-scanner/qr-scanner.component.ts @@ -0,0 +1,76 @@ +import { Component, inject } from '@angular/core'; +import { ModalController } from '@ionic/angular'; +import { ZXingScannerModule } from '@zxing/ngx-scanner'; +import { CommonModule } from '@angular/common'; +import { IonicModule } from '@ionic/angular'; +import { BarcodeFormat } from '@zxing/library'; + +@Component({ + selector: 'app-qr-scanner', + templateUrl: './qr-scanner.component.html', + styleUrls: ['./qr-scanner.component.scss'], + standalone: true, + imports: [CommonModule, IonicModule, ZXingScannerModule] +}) +export class QrScannerComponent { + private modalCtrl = inject(ModalController); + public allowedFormats = [BarcodeFormat.QR_CODE]; + + public availableDevices: MediaDeviceInfo[] = []; + public currentDevice: MediaDeviceInfo | undefined = undefined; + + onCamerasFound(devices: MediaDeviceInfo[]) { + this.availableDevices = devices; + if (devices && devices.length > 0) { + // Cerca la fotocamera posteriore (etichette contenenti 'back', 'rear', 'environment', 'posteriore') + const backCamera = devices.find(d => { + const label = d.label.toLowerCase(); + return label.includes('back') || + label.includes('rear') || + label.includes('environment') || + label.includes('posteriore'); + }); + this.currentDevice = backCamera || devices[0]; + } + } + + toggleCamera() { + if (this.availableDevices.length <= 1) return; + const currentIndex = this.availableDevices.findIndex(d => d.deviceId === this.currentDevice?.deviceId); + const nextIndex = (currentIndex + 1) % this.availableDevices.length; + this.currentDevice = this.availableDevices[nextIndex]; + } + + get showIpadWarning(): boolean { + const isIPadDesktop = + /Macintosh/.test(navigator.userAgent) && + navigator.maxTouchPoints !== undefined && + navigator.maxTouchPoints > 1; + return isIPadDesktop && this.availableDevices.length <= 1; + } + + onCodeResult(result: string) { + if (result) { + this.modalCtrl.dismiss(result); + } + } + + onScanError(error: any) { + // Silenzia e ignora gli errori interni della libreria zxing + try { + if (error) { + // Previeni la propagazione a livello di window/console + if (typeof error.preventDefault === 'function') error.preventDefault(); + if (typeof error.stopPropagation === 'function') error.stopPropagation(); + } + } catch(e) {} + } + + onScanFailure(failure: any) { + // Ignora i tentativi falliti di decodifica frame per frame + } + + cancel() { + this.modalCtrl.dismiss(); + } +} diff --git a/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.html b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.html new file mode 100644 index 0000000..24a457b --- /dev/null +++ b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.html @@ -0,0 +1,41 @@ + + + Condividi Playlist + + + + + + + + + +
+

+ Fai scansionare questo QR Code da un altro dispositivo per condividere all'istante la playlist {{ playlistName }}. +

+ +
+
+ QR Code della Playlist +
+ +
+ Nome Playlist: + {{ playlistName }} +
+
+ +
+ + + Invia Link / Condividi + + + + + Copia Link + +
+
+
diff --git a/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.scss b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.scss new file mode 100644 index 0000000..86e0960 --- /dev/null +++ b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.scss @@ -0,0 +1,90 @@ +.qr-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 16px 8px; + text-align: center; + min-height: 100%; +} + +.description { + font-size: 0.95rem; + line-height: 1.5; + color: var(--ion-text-color); + opacity: 0.9; + margin-bottom: 24px; + max-width: 320px; +} + +.qr-card { + padding: 24px; + border-radius: 24px; + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + margin-bottom: 24px; + width: 100%; + max-width: 340px; + box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.15); +} + +.qr-wrapper { + background: white; + padding: 12px; + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + width: 220px; + height: 220px; + box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05); + + .qr-image { + width: 100%; + height: 100%; + object-fit: contain; + } +} + +.playlist-box { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + width: 100%; + padding-top: 8px; + border-top: 1px solid rgba(255, 255, 255, 0.08); +} + +.playlist-label { + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--ion-color-secondary); + font-weight: 600; +} + +.playlist-text { + font-size: 1rem; + color: var(--ion-text-color); + font-weight: bold; + word-break: break-word; + opacity: 0.95; +} + +.actions-wrapper { + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; + max-width: 340px; +} + +.action-btn { + margin: 0; + --border-radius: 14px; + font-weight: 600; + height: 48px; +} diff --git a/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.ts b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.ts new file mode 100644 index 0000000..2d75087 --- /dev/null +++ b/src/app/components/share-playlist-qr-modal/share-playlist-qr-modal.component.ts @@ -0,0 +1,90 @@ +import { Component, OnInit, inject, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IonicModule, ModalController, ToastController } from '@ionic/angular'; +import * as QRCode from 'qrcode'; + +@Component({ + selector: 'app-share-playlist-qr-modal', + templateUrl: './share-playlist-qr-modal.component.html', + styleUrls: ['./share-playlist-qr-modal.component.scss'], + standalone: true, + imports: [CommonModule, IonicModule] +}) +export class SharePlaylistQrModalComponent implements OnInit { + private modalCtrl = inject(ModalController); + private toastCtrl = inject(ToastController); + + @Input() playlistName!: string; + @Input() shareLink!: string; + + public qrCodeUrl: string = ''; + + ngOnInit() { + this.generateQr(); + } + + async generateQr() { + try { + this.qrCodeUrl = await QRCode.toDataURL(this.shareLink, { + errorCorrectionLevel: 'H', + margin: 2, + width: 400, + color: { + dark: '#1e293b', + light: '#ffffff' + } + }); + } catch (err) { + console.error('Failed to generate QR Code:', err); + } + } + + async shareLinkNative() { + const fileName = `${this.playlistName.toLowerCase().replace(/\s+/g, '_')}_qr.png`; + try { + const res = await fetch(this.qrCodeUrl); + const blob = await res.blob(); + const file = new File([blob], fileName, { type: 'image/png' }); + + const isMac = /Macintosh|MacIntel|MacPPC|Mac68K/.test(navigator.userAgent) || + (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); + + if (!isMac && navigator.share && navigator.canShare && navigator.canShare({ files: [file] })) { + await navigator.share({ + files: [file], + title: 'Playlist CantiCristiani', + text: `Ecco la playlist: ${this.playlistName}\n\nClicca qui per aprirla subito: ${this.shareLink}` + }); + } else if (navigator.share) { + await navigator.share({ + title: 'Playlist CantiCristiani', + text: `Ecco la playlist: ${this.playlistName}\n\nClicca qui per aprirla: ${this.shareLink}` + }); + } else { + await this.copyToClipboard(); + } + } catch (err) { + console.error('Share failed', err); + await this.copyToClipboard(); + } + } + + async copyToClipboard() { + try { + await navigator.clipboard.writeText(this.shareLink); + const toast = await this.toastCtrl.create({ + message: 'Link copiato negli appunti!', + duration: 2000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + } catch (err) { + console.error('Failed to copy text:', err); + } + } + + dismiss() { + this.modalCtrl.dismiss(); + } +} diff --git a/src/app/home/home-routing.module.ts b/src/app/home/home-routing.module.ts new file mode 100644 index 0000000..29c3f60 --- /dev/null +++ b/src/app/home/home-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { HomePage } from './home.page'; + +const routes: Routes = [ + { + path: '', + component: HomePage, + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class HomePageRoutingModule {} diff --git a/src/app/home/home.module.ts b/src/app/home/home.module.ts new file mode 100644 index 0000000..076260d --- /dev/null +++ b/src/app/home/home.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { IonicModule } from '@ionic/angular'; +import { FormsModule } from '@angular/forms'; +import { HomePage } from './home.page'; +import { HomePageRoutingModule } from './home-routing.module'; +import { DragDropModule } from '@angular/cdk/drag-drop'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + HomePageRoutingModule, + DragDropModule + ], + declarations: [HomePage] +}) +export class HomePageModule {} diff --git a/src/app/home/home.page.html b/src/app/home/home.page.html new file mode 100644 index 0000000..4c67aad --- /dev/null +++ b/src/app/home/home.page.html @@ -0,0 +1,651 @@ + + + +
+ +
+ {{ appName }} + + v{{ version }} + +
+
+
+ + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + + + + + + + +
+
+ + +
+
+
+ {{ filteredCanti().length }} +
+ + + +
+
+ + +
+
+
+ +
+ + + + + + +
+
+ +
+ +
+ + + + + + +
+
+ +
+ +
+ + + + + + +
+
+ +
+ +
+ + + + + + +
+
+
+
+ + +
+
+ Playlist +
+ +
+ + + {{ comunitaService.comunitaCode() ? comunitaService.comunitaNome() : 'Comunità' }} + +
+ + +
+ + {{ item.name }} + + + + + + +
+ + + Nessuna playlist creata + +
+
+ + +
+ + +
+ + +
+ Tipologia +
+
+ Validati + + + +
+
+ Non Validati + + + + + +
+
+
+ + +
+ Liturgia +
+
+ {{ item.tag_name }} + + + +
+
+
+ + +
+ Periodo +
+
+ {{ item.tag_name }} + + + +
+
+
+ + + +
+
+
+ + + +
+ +
+ + {{ totalPlaylistDuration() }} +
+ + +
+ {{ playlistService.activeListName() }} +
+ + +
+ + + + + + + + + + + + + + + + + + +
+ + +
+ {{ reorderList().length }} + + + + + + + + + + +
+
+
+
+ + + +
+ +
+
+ +
{{ cantiService.progress() }}%
+ +

Caricamento canti...

+
+
+ + +
+ + +
+
+
+
+ SINTESI MESSA + {{ getSelectedMassFormattedDate() }} +
+
+
+ + + + + + +
+ +
+
+ +
+
+ {{ getSelectedMassFormattedDate() }} +
+

{{ getSelectedMassTitle() }}

+

+ {{ getSelectedMassSummary() }} +

+
+
+
+ + + + +
+ +
+ +
+ +
+ + {{ canto.id.startsWith('my_') ? getMySongNumber(canto) : canto.id_canti }} + +
+ + +
+
+ +

+ {{ getCommunitySongNumber(canto) }} + {{ canto.titolo }} + Remoto + Mio +

+

+ {{ canto.autore || 'Autore sconosciuto' }} +

+

+ + + + {{ canto.durata }} + + + + {{ canto.bpm }} BPM + + + + {{ getSongTonality(canto) }} + + + + + agg. {{ cantiService.formatUpdateDate(canto.data_update) }} + + + + {{ getEsecuzioniCount(canto.id) }} esecuzioni + + + + Attinenza {{ getMassSuggestionWeight(canto.id_canti) }}% + +

+ + +
+ + {{ tag }} + +
+
+ + +
+
+ +
+ +
+ +
+
+
+ +
+ + +
+ +
+
+
+
+
+
+ + +
+ + + +
+
+
+ + +
+
+
+ + +
+ + + {{ isAddingSongs() ? 'Torna alla Playlist' : 'Aggiungi altri canti' }} + +
+ +
+

Nessun canto trovato.

+
+
+ + + + + + +
+ + + +
+ +
+ + + + + + + + + + {{ formatSeconds(youtubePlayerService.videoProgress()) }} + + + + + {{ formatSeconds(youtubePlayerService.videoDuration()) }} + + +
+ Audio non disponibile +
+
+ + + + +
+
+
+
+ +
+
+
+

Schermo nero attivo

+
+ +
+

{{ getPlayingCanto()?.titolo }}

+

{{ getPlayingCanto()?.autore }}

+
+ +
+ {{ formatSeconds(youtubePlayerService.videoProgress()) }} / {{ formatSeconds(youtubePlayerService.videoDuration()) }} +
+ +
+ + + + + + + + + +
+ +

Tocca lo sfondo o l'icona per sbloccare

+
+
+ + diff --git a/src/app/home/home.page.scss b/src/app/home/home.page.scss new file mode 100644 index 0000000..4a41ee1 --- /dev/null +++ b/src/app/home/home.page.scss @@ -0,0 +1,1874 @@ +.outfit-font { + font-family: 'Outfit', sans-serif; +} + +.bg-gradient { + --background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); + background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); +} + +.custom-searchbar { + flex: 1 !important; + --background: transparent !important; + --color: white; + --placeholder-color: rgba(255, 255, 255, 0.4); + --icon-color: var(--ion-color-secondary); + --box-shadow: none !important; + padding: 0 !important; + margin: 0 !important; + + &::part(container) { + background: transparent !important; + box-shadow: none !important; + padding: 0 !important; + } + + &::part(input-container) { + background: transparent !important; + } +} + +.search-wrapper-group { + display: flex; + flex-direction: column; + padding: 2px 16px 12px 16px; // Reduced top padding + gap: 12px; +} + +.search-row { + width: 100%; +} + +.search-wrapper { + display: flex; + align-items: center; + gap: 0; + padding: 2px 4px; + border-radius: 14px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + + .adv-search-btn, .voice-search-btn { + --padding-start: 6px; + --padding-end: 6px; + margin: 0; + height: 44px; + + ion-icon { + font-size: 1.4rem; + } + } + + .adv-search-btn.active { + opacity: 1; + } +} + +.advanced-search-toggle-row { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 2px; + gap: 4px; + flex-wrap: nowrap; + + .toggle-row-left { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: nowrap; + width: 100%; + justify-content: flex-start; + } + + .song-count-card { + display: inline-flex; + align-items: center; + justify-content: center; + background: rgba(var(--ion-color-secondary-rgb), 0.15); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.3); + padding: 0 8px; + border-radius: 12px; + height: 30px; + font-size: 0.8rem; + font-weight: 700; + color: var(--ion-color-secondary); + backdrop-filter: blur(10px); + flex-shrink: 0; + } + + .advanced-search-link, .clear-advanced-link { + background: transparent; + border: none; + outline: none; + color: var(--ion-color-secondary); + font-size: 0.8rem; + font-weight: 600; + display: inline-flex; + align-items: center; + gap: 3px; + cursor: pointer; + padding: 4px 5px; + border-radius: 8px; + transition: all 0.2s ease; + opacity: 0.9; + white-space: nowrap; + flex-shrink: 0; + + &:hover, &:active { + opacity: 1; + background: rgba(var(--ion-color-secondary-rgb), 0.12); + } + + ion-icon { + font-size: 1rem; + } + + .inline-clear-btn { + display: inline-flex; + align-items: center; + justify-content: center; + margin-left: 2px; + padding: 2px; + border-radius: 50%; + transition: transform 0.15s ease; + + ion-icon { + font-size: 1.1rem; + color: var(--ion-color-danger, #ff4961); + } + + &:hover { + transform: scale(1.2); + } + } + } + + .clear-advanced-link { + color: var(--ion-color-danger, #ff4961); + font-weight: 500; + + &:hover, &:active { + background: rgba(255, 73, 97, 0.12); + } + } +} + +.advanced-search-panel { + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 16px; + padding: 12px 14px; + backdrop-filter: blur(12px); + animation: advSearchFadeIn 0.25s ease-out; + + .adv-search-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 10px; + } + + .adv-input-group { + display: flex; + flex-direction: column; + gap: 4px; + + .adv-label { + font-size: 0.75rem; + font-weight: 600; + color: rgba(255, 255, 255, 0.7); + text-transform: uppercase; + letter-spacing: 0.5px; + margin-left: 2px; + } + + .adv-input-wrapper { + position: relative; + display: flex; + align-items: center; + background: rgba(0, 0, 0, 0.25); + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 10px; + padding: 0 10px; + height: 38px; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + + &:focus-within { + border-color: var(--ion-color-secondary); + box-shadow: 0 0 0 2px rgba(var(--ion-color-secondary-rgb), 0.2); + } + + .adv-input-icon { + font-size: 1.1rem; + color: var(--ion-color-secondary); + margin-right: 8px; + flex-shrink: 0; + } + + .adv-input { + flex: 1; + background: transparent; + border: none; + outline: none; + color: #ffffff; + font-size: 0.88rem; + font-family: inherit; + width: 100%; + + &::placeholder { + color: rgba(255, 255, 255, 0.35); + } + } + + .adv-clear-icon { + font-size: 1rem; + color: rgba(255, 255, 255, 0.4); + cursor: pointer; + margin-left: 4px; + + &:hover { + color: #ffffff; + } + } + + .adv-mic-btn { + --padding-start: 4px; + --padding-end: 4px; + margin: 0 0 0 2px; + height: 32px; + min-height: 32px; + + ion-icon { + font-size: 1.15rem; + } + } + } + } +} + +@keyframes advSearchFadeIn { + from { + opacity: 0; + transform: translateY(-6px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +:host-context(body.high-contrast) { + .advanced-search-link { + color: var(--ion-color-secondary) !important; + } + + .clear-advanced-link { + color: var(--ion-color-danger, #d32f2f) !important; + } + + .advanced-search-panel { + background: #ffffff !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08) !important; + + .adv-input-group { + .adv-label { + color: var(--ion-color-secondary, #d96b00) !important; + font-weight: 700 !important; + } + + .adv-input-wrapper { + background: #f4f5f8 !important; + border: 1px solid #c0c4cc !important; + + &:focus-within { + border-color: var(--ion-color-secondary, #d96b00) !important; + box-shadow: 0 0 0 2px rgba(217, 107, 0, 0.25) !important; + } + + .adv-input-icon { + color: var(--ion-color-secondary, #d96b00) !important; + } + + .adv-input { + color: #000000 !important; + font-weight: 600 !important; + + &::placeholder { + color: #666666 !important; + font-weight: 400 !important; + } + } + + .adv-clear-icon { + color: #666666 !important; + + &:hover { + color: #000000 !important; + } + } + } + } + } +} + +.filter-card { + background: rgba(255, 255, 255, 0.04); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 16px; + padding: 10px 12px; + display: flex; + flex-direction: column; + gap: 8px; + backdrop-filter: blur(12px); + margin-top: 4px; + + .filter-card-row { + display: flex; + align-items: center; + gap: 10px; + min-height: 34px; + + .filter-row-label { + font-weight: 700; + font-size: 0.8rem; + color: var(--ion-color-secondary); + width: 68px; + flex-shrink: 0; + text-transform: capitalize; + letter-spacing: 0.3px; + opacity: 0.9; + } + + .filter-row-items { + display: flex; + gap: 6px; + overflow-x: auto; + flex: 1; + align-items: center; + padding-bottom: 2px; + scrollbar-width: none; + -ms-overflow-style: none; + &::-webkit-scrollbar { + display: none; + } + + .empty-playlist-text { + font-size: 0.8rem; + color: rgba(255, 255, 255, 0.4); + font-style: italic; + } + } + } + + .filter-card-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-top: 2px; + padding-top: 8px; + border-top: 1px solid rgba(255, 255, 255, 0.08); + + .song-count-card { + display: flex; + align-items: center; + justify-content: center; + background: rgba(var(--ion-color-secondary-rgb), 0.15); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.3); + padding: 0 12px; + border-radius: 12px; + height: 32px; + font-size: 0.82rem; + font-weight: 700; + color: var(--ion-color-secondary); + backdrop-filter: blur(10px); + flex-shrink: 0; + } + + .footer-actions { + display: flex; + align-items: center; + gap: 8px; + + ion-button.filter-chip { + --border-radius: 20px; + --border-width: 1px; + font-family: 'Outfit', sans-serif; + font-weight: 500; + margin: 0; + min-height: 32px; + font-size: 0.85rem; + text-transform: none; + letter-spacing: normal; + + .close-icon-wrapper { + display: inline-flex; + align-items: center; + justify-content: center; + margin-left: 6px; + padding: 4px; + margin-right: -8px; + cursor: pointer; + + ion-icon { + font-size: 1.1rem; + margin: 0; + pointer-events: none; + } + } + } + } + } +} + + + + +ion-toolbar.playlist-toolbar { + --padding-top: 0px; + --padding-bottom: 8px; + --padding-start: 16px; + --padding-end: 16px; + --min-height: auto; +} + +.playlist-actions-bar { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + margin-top: 2px; + margin-bottom: 0px; + + .playlist-duration-pill { + display: inline-flex; + align-items: center; + gap: 4px; + background: rgba(var(--ion-color-secondary-rgb), 0.15); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.3); + padding: 0 10px; + border-radius: 12px; + height: 30px; + font-size: 0.82rem; + font-weight: 700; + color: var(--ion-color-secondary); + backdrop-filter: blur(10px); + flex-shrink: 0; + + ion-icon { + font-size: 0.95rem; + } + } + + .playlist-title-badge { + display: inline-flex; + align-items: center; + padding: 0 10px; + height: 30px; + font-size: 0.9rem; + font-weight: 700; + color: var(--ion-color-secondary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 50%; + margin: 0 8px; + flex-shrink: 1; + + .playlist-title-text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + .selection-pill { + margin: 0; + margin-left: auto; + } +} + +.transparent-list { + background: transparent !important; + padding-bottom: 120px; // Spazio per il player fisso +} + +ion-item.glass { + --background: rgba(255, 255, 255, 0.05); + --border-radius: 16px; + --padding-start: 16px; + --inner-padding-end: 16px; + margin-bottom: 12px; + transition: background 0.2s ease; + + &:active { + --background: rgba(255, 255, 255, 0.1); + } +} + +ion-title { + font-weight: 700; + letter-spacing: 1px; + color: var(--ion-color-secondary); + padding-inline: 0; +} + +ion-header { + padding-top: 6px; +} + +ion-buttons[slot="end"] { + gap: 0px; +} + +.update-btn, .add-btn, .settings-btn { + --color: var(--ion-color-secondary); + --padding-start: 0; + --padding-end: 0; + margin-left: -4px; + margin-right: 0; + width: 38px; + min-width: 38px; + height: 38px; + + ion-icon { + font-size: 1.6rem; + } +} + +.update-btn { + animation: pulse-update 2.5s infinite ease-in-out; +} + +@keyframes pulse-update { + 0% { + transform: scale(1); + opacity: 0.9; + } + 50% { + transform: scale(1.1); + opacity: 1; + filter: drop-shadow(0 0 6px rgba(var(--ion-color-secondary-rgb), 0.6)); + } + 100% { + transform: scale(1); + opacity: 0.9; + } +} + +@media (max-width: 375px) { + ion-buttons[slot="end"] { + gap: 0px; + } + .update-btn, .add-btn, .settings-btn { + --padding-start: 0; + --padding-end: 0; + margin-left: -5px; + width: 34px; + min-width: 34px; + height: 34px; + + ion-icon { + font-size: 1.4rem; + } + } + .settings-btn { + margin-right: 2px; + } +} +ion-title { + .header-logo-wrapper { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 8px; + padding: 10px 0 10px 8px; + } + + .header-logo { + width: 38px; + height: 38px; + border-radius: 50%; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); + border: 2px solid rgba(var(--ion-color-secondary-rgb), 0.2); + flex-shrink: 0; + } + + .header-text-group { + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + line-height: 1; + + .app-name { + font-size: clamp(1.1rem, 3.8vw, 1.25rem); + font-weight: 700; + color: var(--ion-color-secondary); + margin-bottom: 2px; + white-space: nowrap; + } + + .version-badge { + font-size: 0.75rem; + font-weight: 500; + color: rgba(255, 255, 255, 0.4); + letter-spacing: 0.5px; + white-space: nowrap; + } + } +} + + +.settings-btn { + margin-right: 8px; +} + +.special-list-banner { + --background: rgba(var(--ion-color-secondary-rgb), 0.1); + --border-style: none; + border-bottom: 1px solid rgba(var(--ion-color-secondary-rgb), 0.2); + + .banner-content { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + height: 40px; + + .banner-text { + display: flex; + align-items: center; + gap: 8px; + color: var(--ion-color-secondary); + font-weight: 600; + font-size: 0.9rem; + + small { + opacity: 0.6; + font-weight: 400; + font-size: 0.75rem; + } + } + + ion-button { + --padding-start: 4px; + --padding-end: 4px; + margin: 0; + height: 32px; + font-size: 1.2rem; + } + } +} + +.results-count { + display: flex; + align-items: center; + gap: 6px; + font-size: 0.8rem; + font-weight: 600; + color: var(--ion-color-secondary); + background: rgba(var(--ion-color-secondary-rgb), 0.1); + padding: 4px 12px; + border-radius: 20px; + margin-right: 0; + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.1); + transition: all 0.2s ease; + cursor: pointer; + + &.is-filtered { + background: rgba(var(--ion-color-secondary-rgb), 0.2); + border-color: var(--ion-color-secondary); + box-shadow: 0 0 10px rgba(var(--ion-color-secondary-rgb), 0.1); + } + + &:active { + transform: scale(0.95); + } + + ion-icon { + font-size: 1.1rem; + margin-left: 2px; + } + + .canti-label { + display: inline; + } + + @media (max-width: 380px) { + .canti-label { + display: none; + } + } +} + +.loading-container { + display: flex; + justify-content: center; + padding: 40px 0; +} + +.loading-wrapper { + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; +} + +.percentage-label { + font-size: 2rem; + font-weight: 700; + color: var(--ion-color-secondary); + text-shadow: 0 0 15px rgba(253, 203, 110, 0.3); +} + +.no-padding-top { + padding-top: 0 !important; +} + +.search-wrapper-group { + display: flex; + flex-direction: column; + padding: 6px 16px 8px 16px; // Added slight top padding for search bar breathing room + gap: 8px; +} + +.momentos-toolbar { + --min-height: 32px; + padding-bottom: 8px; +} + +.momento-scroll { + display: flex; + overflow-x: auto; + padding: 0 16px; + gap: 10px; + scrollbar-width: none; + &::-webkit-scrollbar { + display: none; + } +} + +.momento-chip { + flex: 0 0 auto; + padding: 6px 16px; + border-radius: 20px; + font-size: 0.8rem; + color: rgba(255, 255, 255, 0.6); + font-family: 'Outfit', sans-serif; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: all 0.3s ease; + white-space: nowrap; + + &.active { + background: var(--ion-color-secondary) !important; + color: #000; + font-weight: 600; + border-color: var(--ion-color-secondary); + } + + &.comunita-chip { + display: inline-flex; + align-items: center; + border-left: 3px solid rgba(var(--ion-color-secondary-rgb), 0.6); + background: rgba(var(--ion-color-secondary-rgb), 0.08); + + &.active { + border-left-color: #000; + } + } +} + +.non-validati-add-icon { + font-size: 1.1rem; + color: #000; + font-weight: bold; + background: rgba(0, 0, 0, 0.1); + border-radius: 50%; + padding: 2px; + display: inline-block; + vertical-align: middle; +} + +:host-context(body.high-contrast) { + .non-validati-add-icon { + color: #ffffff !important; + background: rgba(255, 255, 255, 0.2) !important; + } + .playlist-name-input { + color: #000000 !important; + &::placeholder { + color: rgba(0, 0, 0, 0.6) !important; + } + } +} + +// Custom Item Layout +.custom-item { + --padding-start: 16px; + --inner-padding-end: 16px; + --min-height: 70px; // Reduced height + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); + + &.is-playing { + --background: rgba(var(--ion-color-secondary-rgb), 0.15) !important; + border-left: 4px solid var(--ion-color-secondary); + box-shadow: inset 0 0 20px rgba(var(--ion-color-secondary-rgb), 0.1); + transform: scale(1.02); + margin-left: 8px; + margin-right: 8px; + border-radius: 12px; + z-index: 10; + } + + .playlist-name-chip { + margin-right: 8px; + max-width: 150px; + + span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .close-icon { + font-size: 1.2rem; + margin-left: 4px; + opacity: 0.8; + } + } + .item-wrapper { + display: flex; + align-items: center; + width: 100%; + + .selection-column { + padding: 12px 18px 12px 12px; + margin-left: -12px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + z-index: 100; + position: relative; + } + + .content-column { + flex: 1; + display: flex; + flex-direction: column; + padding: 10px 0; + cursor: pointer; + overflow: hidden; + transition: transform 0.2s ease; + + &:active { + transform: scale(0.98); + } + + .top-row { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + } + + .info-section { + flex: 1; + margin: 0; + padding: 0; + } + } + + .canto-number { + position: relative; + width: 32px; + height: 32px; + line-height: 28px; + text-align: center; + background: rgba(var(--ion-color-secondary-rgb), 0.1); + color: var(--ion-color-secondary); + font-size: 0.85rem; + border-radius: 8px; + font-weight: 700; + border: 2px solid var(--ion-color-secondary); + display: flex; + align-items: center; + justify-content: center; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + pointer-events: none; + + &.selected-number { + background: var(--ion-color-secondary) !important; + color: #000 !important; + box-shadow: 0 0 15px rgba(var(--ion-color-secondary-rgb), 0.5); + transform: scale(1.1); + } + } + } + .player-inline-row { + width: 100%; + display: flex; + align-items: center; + gap: 4px; + + &.full-width { + margin-top: 4px; + padding-top: 4px; + border-top: 1px solid rgba(255, 255, 255, 0.05); + } + + ion-range { + flex: 1; + padding: 0; + --bar-height: 2px; + --knob-size: 10px; + } + } + + .thumb-container { + &.compact { + width: 50px; + height: 38px; + border-radius: 8px; + margin-left: 12px; + } + } + + .thumb-wrapper { + width: 100%; + height: 100%; + position: relative; + cursor: pointer; + } + + .hidden-player { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; + pointer-events: none; + } + + .thumb-img { + width: 100%; + height: 100%; + object-fit: cover; + opacity: 0; + transition: opacity 0.5s ease; + + &.loaded { + opacity: 1; + } + } + + .skeleton { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient( + 90deg, + rgba(255, 255, 255, 0.05) 25%, + rgba(255, 255, 255, 0.1) 50%, + rgba(255, 255, 255, 0.05) 75% + ); + background-size: 200% 100%; + animation: shimmer 1.5s infinite; + } + + .play-overlay { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(0, 0, 0, 0.5); + border-radius: 50%; + width: 24px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; + color: white; + backdrop-filter: blur(4px); + z-index: 2; + pointer-events: none; + + ion-icon { + font-size: 14px; + margin-left: 2px; + } + } + + .youtube-overlay { + background: rgba(0, 0, 0, 0.6) !important; + ion-icon { + color: #ff0000; + font-size: 16px; + margin-left: 0; + } + } + + .offline-thumb { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.05); + color: rgba(255, 255, 255, 0.3); + gap: 4px; + + ion-icon { + font-size: 1.2rem; + } + span { + font-size: 0.6rem; + text-transform: uppercase; + font-weight: 700; + font-family: 'Outfit', sans-serif; + } + } +} + +@keyframes shimmer { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} +.finish-selection-fab { + --border-radius: 30px; + width: auto; + min-width: 120px; + + .fab-content { + display: flex; + align-items: center; + padding: 0 16px; + gap: 8px; + + ion-icon { + font-size: 1.4rem; + } + + .fab-label { + font-size: 0.9rem; + font-weight: 600; + text-transform: none; + } + } +} + +.selection-pill { + display: flex; + align-items: center; + gap: 4px; + background: rgba(var(--ion-color-secondary-rgb), 0.15) !important; + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.3); + padding: 2px 4px 2px 10px; + border-radius: 20px; + height: 32px; + flex-shrink: 0; + + .selection-count { + font-size: 0.9rem; + font-weight: 800; + color: var(--ion-color-secondary); + margin-right: 4px; + } + + .mini-action-btn { + --padding-start: 4px; + --padding-end: 4px; + margin: 0; + height: 28px; + min-width: 32px; + + ion-icon { + font-size: 1.2rem; + } + } + + .playlist-name-input { + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 10px; + color: white; + margin: 0 4px; + padding: 2px 8px; + font-size: 0.8rem; + width: 120px; + height: 24px; + outline: none; + transition: all 0.2s ease; + + &:focus { + border-color: var(--ion-color-secondary); + background: rgba(255, 255, 255, 0.12); + box-shadow: 0 0 6px rgba(var(--ion-color-secondary-rgb), 0.2); + } + + &::placeholder { + color: rgba(255, 255, 255, 0.4); + } + } +} + +.small-action-btn { + --padding-start: 4px; + --padding-end: 4px; + height: 32px; + margin: 0; + + ion-icon { + font-size: 1.3rem !important; + } +} + +.drag-handle { + display: flex; + align-items: center; + justify-content: center; + padding: 0 12px 0 0; + cursor: grab; + color: rgba(255, 255, 255, 0.5); + + ion-icon { + font-size: 1.8rem; + } + + &:active { + cursor: grabbing; + } +} + +.action-mode-btn { + --border-radius: 20px; + --box-shadow: 0 4px 15px rgba(0,0,0,0.3); + font-weight: 700; + letter-spacing: 0.5px; + height: 44px; +} + +@media (max-width: 360px) { + .header-logo-wrapper { + margin-bottom: 12px !important; + } +} +/* GLOBAL PLAYER FOOTER */ +.global-player-toolbar { + --background: transparent; + --padding-top: 4px; + --padding-bottom: 4px; + --padding-start: 12px; + --padding-end: 12px; + + &.glass { + background: rgba(26, 26, 46, 0.95) !important; + backdrop-filter: blur(20px); + border-radius: 0 !important; + box-shadow: none !important; + } + + .player-content { + display: flex; + flex-direction: column; + padding: 0; + } + + .controls-row { + display: flex; + align-items: center; + gap: 4px; + + .play-btn, .skip-btn, .close-btn { + --padding-start: 0; + --padding-end: 0; + height: 40px; + width: 40px; + + ion-icon { + font-size: 1.6rem; + } + } + + .global-range { + flex: 1; + --bar-height: 4px; + --knob-size: 14px; + padding-top: 0; + padding-bottom: 0; + } + } +} + +/* Adjust bottom spacing for list when player is active */ +.transparent-list { + padding-bottom: 100px !important; +} + +.suggeriti-header-card { + border-radius: 18px; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + overflow: hidden; + margin-left: 0; + margin-right: 0; + margin-bottom: 12px; + backdrop-filter: blur(15px); + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2); + cursor: pointer; + transition: background 0.3s ease, border-color 0.3s ease; + + &:active { + background: rgba(255, 255, 255, 0.08); + } + + .card-inner { + display: flex; + flex-direction: column; + gap: 0; + } + + .card-header-row { + display: flex; + justify-content: space-between; + align-items: center; + transition: padding-bottom 0.3s ease, border-bottom-color 0.3s ease; + } + + &.expanded { + .card-header-row { + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + padding-bottom: 6px; + } + } + + .card-header-left { + display: flex; + align-items: center; + } + + .expand-icon { + font-size: 1.25rem; + color: var(--ion-color-secondary); + transition: transform 0.3s ease; + } + + .card-label { + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.1em; + color: var(--ion-color-secondary); + } + + .card-date-compact { + font-size: 0.75rem; + font-weight: 600; + color: rgba(255, 255, 255, 0.6); + margin-left: 8px; + } + + .expandable-content { + max-height: 0; + opacity: 0; + overflow: hidden; + transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.35s ease, margin-top 0.35s ease; + + &.show { + max-height: 400px; /* High enough to fit summary */ + opacity: 1; + margin-top: 10px; + } + } + + .card-date-row { + margin-bottom: 6px; + } + + .card-date { + font-size: 0.75rem; + font-weight: 600; + color: rgba(255, 255, 255, 0.5); + } + + .card-title { + font-size: 1.25rem; + font-weight: 700; + color: white; + margin: 4px 0 0 0; + } + + .card-summary { + font-size: 0.85rem; + line-height: 1.45; + color: rgba(255, 255, 255, 0.75); + margin: 6px 0 0 0; + font-weight: 400; + } +} + +:host-context(body.high-contrast) .suggeriti-header-card { + background: #ffffff !important; + border-color: #000000 !important; + box-shadow: none !important; + + .card-date-compact { + color: black !important; + background: transparent !important; + } + + &.expanded { + .card-header-row { + border-bottom-color: rgba(0, 0, 0, 0.15); + } + } + + .card-label { + color: black !important; + } + + .card-date { + color: black !important; + } + + .card-title { + color: black !important; + } + + .card-summary { + color: black !important; + } +} + +:host-context(body.high-contrast) { + .drag-handle { + color: rgba(0, 0, 0, 0.6) !important; + } +} + +.song-tags-list { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin-top: 4px; +} + +.song-tag-badge { + font-size: 0.65rem; + background: rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.7); + padding: 1px 5px; + border-radius: 4px; + border: 1px solid rgba(255, 255, 255, 0.12); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.3px; +} + +/* High Contrast mode overrides */ +:host-context(body.high-contrast) .song-tag-badge { + background: rgba(0, 0, 0, 0.05) !important; + color: rgba(0, 0, 0, 0.7) !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; +} + +:host-context(body.high-contrast) .update-date-badge { + color: rgba(0, 0, 0, 0.5) !important; + ion-icon { + color: rgba(0, 0, 0, 0.5) !important; + } +} + +.non-validato-badge { + font-size: 0.65rem; + background: rgba(231, 76, 60, 0.15); /* Soft premium red */ + color: #e74c3c; + padding: 1px 6px; + border-radius: 6px; + border: 1px solid rgba(231, 76, 60, 0.3); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-left: 6px; + display: inline-block; + vertical-align: middle; + + &.mio-badge { + background: rgba(var(--ion-color-secondary-rgb), 0.15); + color: var(--ion-color-secondary); + border-color: rgba(var(--ion-color-secondary-rgb), 0.35); + } +} + +:host-context(body.high-contrast) .non-validato-badge { + background: rgba(231, 76, 60, 0.1) !important; + color: #c0392b !important; + border-color: #c0392b !important; + + &.mio-badge { + background: rgba(var(--ion-color-secondary-rgb), 0.1) !important; + color: var(--ion-color-secondary-shade, #007bb6) !important; + border-color: var(--ion-color-secondary-shade, #007bb6) !important; + } +} + +/* ========================================================================== + PWA INSTALLATION PROMOTIONS (Android & iOS) + ========================================================================== */ + +/* 1. Android Installation Banner */ +.pwa-android-banner { + --background: rgba(255, 255, 255, 0.04); + background: rgba(255, 255, 255, 0.04); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid rgba(255, 255, 255, 0.08); + border-left: 4px solid var(--ion-color-secondary); + border-radius: 16px; + overflow: hidden; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + animation: slideInBanner 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); + + &:hover { + background: rgba(255, 255, 255, 0.06); + border-color: rgba(255, 255, 255, 0.12); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25); + } + + .banner-inner { + display: flex; + align-items: center; + padding: 14px 16px; + gap: 12px; + } + + .banner-icon-wrapper { + display: flex; + align-items: center; + justify-content: center; + background: rgba(var(--ion-color-secondary-rgb), 0.12); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.2); + width: 42px; + height: 42px; + border-radius: 12px; + flex-shrink: 0; + + .banner-icon { + font-size: 1.5rem; + color: var(--ion-color-secondary); + } + } + + .banner-text-wrapper { + flex: 1; + display: flex; + flex-direction: column; + gap: 2px; + overflow: hidden; + + .banner-title { + font-size: 0.95rem; + font-weight: 700; + color: white; + margin: 0; + letter-spacing: 0.2px; + } + + .banner-subtitle { + font-size: 0.78rem; + line-height: 1.35; + color: rgba(255, 255, 255, 0.65); + margin: 0; + font-weight: 400; + } + } + + .banner-actions { + display: flex; + align-items: center; + gap: 4px; + flex-shrink: 0; + + .install-action-btn { + --border-radius: 10px; + --box-shadow: 0 4px 10px rgba(var(--ion-color-secondary-rgb), 0.2); + font-weight: 700; + font-size: 0.8rem; + height: 32px; + margin: 0; + text-transform: none; + letter-spacing: 0.2px; + transition: transform 0.2s ease; + + &:active { + transform: scale(0.95); + } + } + + .dismiss-action-btn { + --color: rgba(255, 255, 255, 0.5); + --padding-start: 4px; + --padding-end: 4px; + margin: 0; + height: 32px; + width: 32px; + + ion-icon { + font-size: 1.3rem; + } + + &:active { + opacity: 0.7; + } + } + } +} + +/* 2. iOS Safari Contextual Tooltip */ +.pwa-ios-tooltip-wrapper { + position: fixed; + bottom: 24px; + left: 50%; + transform: translateX(-50%); + z-index: 10000; + width: 90%; + max-width: 385px; + pointer-events: none; + filter: drop-shadow(0 12px 36px rgba(0, 0, 0, 0.45)); + transition: bottom 0.3s cubic-bezier(0.4, 0, 0.2, 1); + + &.has-player { + bottom: 84px; /* Float above active bottom player footer */ + } + + .pwa-ios-tooltip { + pointer-events: auto; + display: flex; + flex-direction: column; + background: rgba(26, 26, 46, 0.96) !important; + backdrop-filter: blur(25px); + -webkit-backdrop-filter: blur(25px); + border: 1.5px solid rgba(var(--ion-color-secondary-rgb), 0.25); + border-radius: 20px; + padding: 14px 16px; + position: relative; + box-shadow: inset 0 0 20px rgba(255, 255, 255, 0.02); + animation: floatTooltip 0.45s cubic-bezier(0.175, 0.885, 0.32, 1.275), bounceGently 3s ease-in-out infinite; + + .tooltip-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 6px; + + .tooltip-title { + font-size: 0.95rem; + font-weight: 700; + color: var(--ion-color-secondary); + letter-spacing: 0.3px; + } + + .dismiss-btn { + --color: rgba(255, 255, 255, 0.45); + --padding-start: 4px; + --padding-end: 4px; + margin: 0; + height: 24px; + width: 24px; + + ion-icon { + font-size: 1.2rem; + } + + &:active { + opacity: 0.7; + } + } + } + + .tooltip-body { + .tooltip-text { + font-size: 0.82rem; + line-height: 1.45; + color: rgba(255, 255, 255, 0.85); + margin: 0; + font-weight: 400; + + strong { + color: white; + font-weight: 600; + } + + .safari-icon-inline { + display: inline-flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.12); + padding: 3px; + border-radius: 6px; + vertical-align: middle; + margin: 0 3px; + width: 20px; + height: 20px; + + ion-icon { + font-size: 0.95rem; + color: #007aff; /* Apple System Blue */ + } + } + } + } + + .tooltip-arrow { + width: 0; + height: 0; + border-left: 12px solid transparent; + border-right: 12px solid transparent; + border-top: 12px solid rgba(26, 26, 46, 0.96); + position: absolute; + bottom: -11px; + left: 50%; + transform: translateX(-50%); + + &::after { + content: ''; + width: 0; + height: 0; + border-left: 12px solid transparent; + border-right: 12px solid transparent; + border-top: 12px solid rgba(var(--ion-color-secondary-rgb), 0.25); + position: absolute; + bottom: -1px; + left: -12px; + z-index: -1; + } + } + } +} + +/* Animations */ +@keyframes slideInBanner { + from { + opacity: 0; + transform: translateY(-16px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes floatTooltip { + from { + opacity: 0; + transform: translate(-50%, 20px) scale(0.95); + } + to { + opacity: 1; + transform: translate(-50%, 0) scale(1); + } +} + +@keyframes bounceGently { + 0%, 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-5px); + } +} + +/* High Contrast mode adaptations */ +:host-context(body.high-contrast) { + .pwa-android-banner { + background: #ffffff !important; + border: 2px solid #000000 !important; + border-left-width: 6px !important; + + .banner-title, .banner-subtitle { + color: #000000 !important; + } + .banner-icon { + color: #000000 !important; + } + .banner-icon-wrapper { + background: rgba(0, 0, 0, 0.05) !important; + border-color: #000000 !important; + } + .install-action-btn { + --background: #000000 !important; + --color: #ffffff !important; + } + .dismiss-action-btn { + --color: #000000 !important; + } + } + + .pwa-ios-tooltip { + background: #ffffff !important; + border: 2px solid #000000 !important; + + .tooltip-title, .tooltip-text, .tooltip-text strong { + color: #000000 !important; + } + .dismiss-btn { + --color: #000000 !important; + } + .tooltip-arrow { + border-top-color: #ffffff !important; + &::after { + border-top-color: #000000 !important; + } + } + .safari-icon-inline { + background: rgba(0, 0, 0, 0.05) !important; + border-color: #000000 !important; + ion-icon { + color: #000000 !important; + } + } + } +} + +.empty-playlist-container { + padding: 12px 16px; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + box-sizing: border-box; +} + +.empty-playlist-instruction { + margin: 0; + font-size: 0.85rem; + line-height: 1.4; + color: rgba(255, 255, 255, 0.8); + text-align: left; + background: rgba(var(--ion-color-secondary-rgb), 0.08); + border: 1px dashed rgba(var(--ion-color-secondary-rgb), 0.35); + padding: 12px 16px; + border-radius: 12px; + max-width: 480px; + width: 100%; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); +} + +:host-context(body.high-contrast) { + .empty-playlist-instruction { + color: #000000 !important; + background: rgba(var(--ion-color-secondary-rgb), 0.12) !important; + border-color: var(--ion-color-secondary) !important; + box-shadow: none !important; + } +} + +/* BLACK SCREEN OVERLAY FOR CAR MODE */ +.black-screen-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + background-color: #000000 !important; + z-index: 9999999 !important; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); + + .black-screen-content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: rgba(255, 255, 255, 0.25); + text-align: center; + padding: 20px; + gap: 12px; + + .car-mode-icon { + font-size: 3.5rem; + color: rgba(255, 255, 255, 0.2); + } + + .car-mode-text { + font-size: 1.2rem; + font-weight: 600; + margin: 0; + } + + .car-mode-subtext { + font-size: 0.85rem; + margin: 0; + opacity: 0.8; + } + + .car-mode-canto-info { + text-align: center; + margin-top: 10px; + + .car-mode-canto-title { + font-size: 1.4rem; + font-weight: 700; + color: rgba(255, 255, 255, 0.3); + margin: 0 0 4px 0; + } + + .car-mode-canto-author { + font-size: 0.95rem; + color: rgba(255, 255, 255, 0.2); + margin: 0; + } + } + + .car-mode-progress { + margin-top: 8px; + + .car-mode-time { + font-size: 1.1rem; + font-weight: 600; + color: rgba(255, 255, 255, 0.25); + } + } + + .car-mode-controls { + display: flex; + align-items: center; + gap: 24px; + margin-top: 15px; + + .car-mode-btn { + --color: rgba(255, 255, 255, 0.25); + --padding-start: 8px; + --padding-end: 8px; + height: 48px; + width: 48px; + margin: 0; + + ion-icon { + font-size: 1.8rem; + } + + &:active { + --color: rgba(255, 255, 255, 0.55); + } + } + } + } +} + + diff --git a/src/app/home/home.page.spec.ts b/src/app/home/home.page.spec.ts new file mode 100644 index 0000000..26eb973 --- /dev/null +++ b/src/app/home/home.page.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { HomePage } from './home.page'; + +describe('HomePage', () => { + let component: HomePage; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [HomePage], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(HomePage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts new file mode 100644 index 0000000..323e00a --- /dev/null +++ b/src/app/home/home.page.ts @@ -0,0 +1,2521 @@ +import { Component, computed, signal, inject, effect, OnDestroy, HostListener } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { CantiService } from '../services/canti.service'; +import { Router, ActivatedRoute } from '@angular/router'; +import { AudioEngineService } from '../services/audio-engine.service'; +import { ThemeService } from '../services/theme.service'; +import { ConnectivityService } from '../services/connectivity.service'; +import { PlaylistService } from '../services/playlist.service'; +import { SettingsService } from '../services/settings.service'; +import { VERSION } from '../version'; +import { YoutubePlayerService } from '../services/youtube-player.service'; +import { ModalController, AlertController, ToastController, LoadingController } from '@ionic/angular'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { MyCantiService } from '../services/my-canti.service'; +import { QrScannerComponent } from '../components/qr-scanner/qr-scanner.component'; +import { CantiLettureService } from '../services/canti-letture.service'; +import { ComunitaService } from '../services/comunita.service'; +import { environment } from '../../environments/environment'; +import { SwUpdate, VersionReadyEvent } from '@angular/service-worker'; +import { filter, first } from 'rxjs/operators'; +import { showFullscreenUpdateOverlay } from '../app.component'; +import { LyricsParserService } from '../services/lyrics-parser.service'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.page.html', + styleUrls: ['home.page.scss'], + standalone: false, +}) +export class HomePage implements OnDestroy { + @HostListener('window:keydown', ['$event']) + handleKeyDown(event: KeyboardEvent) { + // Only handle keys if a song is currently loaded in the player + if (!this.youtubePlayerService.currentCantoId()) { + return; + } + const target = event.target as HTMLElement; + if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)) { + return; + } + if (event.key === 'ArrowUp' || event.key === 'MediaTrackPrevious') { + this.playPrevPreview(); + event.preventDefault(); + } else if (event.key === 'ArrowDown' || event.key === 'MediaTrackNext') { + this.playNextPreview(); + event.preventDefault(); + } else if (event.key === 'MediaPlayPause') { + this.togglePlayPause(); + event.preventDefault(); + } + } + + public searchQuery = signal(''); + public isAdvancedSearchOpen = signal(false); + public isFilterCardOpen = signal(false); + public isPlaylistCardOpen = signal(false); + public searchTitle = signal(''); + public searchAuthor = signal(''); + public searchText = signal(''); + public searchNumber = signal(''); + public activeVoiceField = signal<'global' | 'title' | 'author' | 'text' | 'number'>('global'); + + public hasAdvancedSearchParams = computed(() => { + return !!(this.searchTitle().trim() || this.searchAuthor().trim() || this.searchText().trim() || this.searchNumber().trim()); + }); + public selectedLiturgico = signal(null); + public selectedTematico = signal(null); + public showOnlyMine = signal(false); + public showTopTen = signal(false); + public showSuggeriti = signal(false); + public showValidati = signal(false); + public showNonValidati = signal(false); + + public hasPlaylistCardParams = computed(() => { + return !!( + this.playlistService.activePlaylistId() !== null || + (this.settingsService.comunitaEnabled() && this.comunitaService.isFilterActive()) + ); + }); + + public hasFilterCardParams = computed(() => { + return !!( + this.selectedLiturgico() !== null || + this.selectedTematico() !== null || + this.showOnlyMine() || + this.showTopTen() || + this.showSuggeriti() || + this.showValidati() || + this.showNonValidati() + ); + }); + public isMassCardExpanded = signal(false); + public activeFilterType = signal<'liturgico' | 'tematico' | 'playlist' | 'lista_completa' | null>(null); + public loadedThumbs = new Set(); + public version = VERSION; + public appName = environment.appName; + public isAddingSongs = signal(false); + public reorderList = signal([]); + public limit = signal(30); + public hasUpdateAvailable = signal(false); + + public isBlackOverlayDismissed = signal(false); + public isBlackOverlayActive = computed(() => + this.settingsService.carModeBlackScreen() && + this.youtubePlayerService.currentCantoId() !== null && + !this.isBlackOverlayDismissed() + ); + + public fontSize = signal(1.0); + public youtubePlayerService = inject(YoutubePlayerService); + public comunitaService = inject(ComunitaService); + public isSeeking = false; + + private readonly MIN_FONT = 0.6; + private readonly MAX_FONT = 5.0; + private initialPinchDistance: number | null = null; + private initialFontSize: number = 1.0; + + private sanitizer = inject(DomSanitizer); + public audioEngine = inject(AudioEngineService); + public themeService = inject(ThemeService); + public connectivityService = inject(ConnectivityService); + public cantiService = inject(CantiService); + public myCantiService = inject(MyCantiService); + public playlistService = inject(PlaylistService); + public settingsService = inject(SettingsService); + public cantiLettureService = inject(CantiLettureService); + public lyricsParser = inject(LyricsParserService); + private router = inject(Router); + private route = inject(ActivatedRoute); + private modalCtrl = inject(ModalController); + private alertCtrl = inject(AlertController); + private toastCtrl = inject(ToastController); + private loadingCtrl = inject(LoadingController); + private swUpdate = inject(SwUpdate); + + private firstInteraction = true; + private updatePollInterval: any = null; + private queryParamsSubscription: any = null; + + async checkForAppUpdate(event?: Event) { + if (event) event.stopPropagation(); + + if (!this.swUpdate.isEnabled) { + const toast = await this.toastCtrl.create({ + message: 'Aggiornamenti non supportati su questo browser.', + duration: 3000, + color: 'medium' + }); + await toast.present(); + return; + } + + const toastLoading = await this.toastCtrl.create({ + message: 'Ricerca aggiornamenti in corso...', + duration: 1500, + color: 'secondary' + }); + await toastLoading.present(); + + const updateAvailable = await this.performUpdateCheck(); + + if (!updateAvailable) { + const toast = await this.toastCtrl.create({ + message: 'L\'applicazione è già aggiornata all\'ultima versione.', + duration: 3000, + color: 'success' + }); + await toast.present(); + } + } + + private async performUpdateCheck(): Promise { + try { + if ('serviceWorker' in navigator) { + const registration = await navigator.serviceWorker.ready; + await registration.update(); + } + + let sub: any = null; + let readyPromise: Promise | undefined = undefined; + + if (this.swUpdate.isEnabled) { + readyPromise = new Promise((resolve) => { + sub = this.swUpdate.versionUpdates + .pipe( + filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'), + first() + ) + .subscribe(() => { + resolve(); + }); + }); + } + + if (this.swUpdate.isEnabled) { + const swFoundUpdate = await this.swUpdate.checkForUpdate(); + if (swFoundUpdate) { + await this.applyUpdateAndReload(readyPromise, sub); + return true; + } + } + + if (sub) sub.unsubscribe(); + + const versionMismatch = await this.checkVersionJson(); + if (versionMismatch) { + await this.applyUpdateAndReload(); + return true; + } + + return false; + } catch (err) { + console.error('[PWA-Update] Update check failed from home:', err); + const toast = await this.toastCtrl.create({ + message: 'Errore durante la ricerca di aggiornamenti.', + duration: 3000, + color: 'danger' + }); + await toast.present(); + return false; + } + } + + private async applyUpdateAndReload(readyPromise?: Promise, subscription?: any) { + const overlay = showFullscreenUpdateOverlay(); + + let activated = false; + const activateAndReload = async () => { + if (activated) return; + activated = true; + try { + if (this.swUpdate.isEnabled) { + await this.swUpdate.activateUpdate(); + } + } catch (e) { + console.warn('[PWA-Update] activateUpdate failed:', e); + } + + try { + if ('serviceWorker' in navigator) { + const registrations = await navigator.serviceWorker.getRegistrations(); + for (const registration of registrations) { + await registration.unregister(); + } + } + if ('caches' in window) { + const keys = await caches.keys(); + for (const key of keys) { + await caches.delete(key); + } + } + } catch (e) { + console.warn('[PWA-Update] Cleanup failed:', e); + } + + overlay.finish(); + setTimeout(() => { + window.location.replace(window.location.origin + window.location.pathname + '?update=' + Date.now()); + }, 600); + }; + + if (readyPromise) { + Promise.race([ + readyPromise, + new Promise((resolve) => setTimeout(resolve, 25000)) + ]).then(() => { + if (subscription) subscription.unsubscribe(); + activateAndReload(); + }); + } else { + setTimeout(() => { + activateAndReload(); + }, 1000); + } + } + + private async checkVersionJson(): Promise { + try { + const response = await fetch(`/version.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (!response.ok) return false; + const data = await response.json(); + return data.version !== VERSION; + } catch (err) { + return false; + } + } + + private async checkUpdateStatus() { + try { + let swFoundUpdate = false; + if (this.swUpdate.isEnabled) { + swFoundUpdate = await this.swUpdate.checkForUpdate().catch(() => false); + } + const mismatch = await this.checkVersionJson(); + this.hasUpdateAvailable.set(swFoundUpdate || mismatch); + } catch (err) { + console.warn('Failed to check for updates on startup:', err); + } + } + + onInteraction() { + if (this.firstInteraction) { + this.firstInteraction = false; + } + } + + private scrollEffect = effect(() => { + const activeId = this.youtubePlayerService.currentCantoId(); + const list = this.filteredCanti(); + + if (activeId) { + const index = list.findIndex(c => c.id === activeId); + if (index !== -1 && index >= this.limit()) { + this.limit.set(index + 15); + } + + // Delay slightly to ensure DOM is updated and classes are applied + setTimeout(() => { + const element = document.getElementById('canto-' + activeId); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }, 500); + } + }, { allowSignalWrites: true }); + + private normalize(str: string | undefined): string { + if (!str) return ''; + return str + .toLowerCase() + .replace(/[’'‘’´`]/g, "'") + .normalize('NFD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/hallelujah/g, 'alleluia') + .replace(/halleluja/g, 'alleluia') + .replace(/alleluja/g, 'alleluia'); + } + + public filteredCanti = computed(() => { + const query = this.normalize(this.searchQuery()); + const litId = this.selectedLiturgico(); + const temId = this.selectedTematico(); + const onlyMine = this.showOnlyMine(); + const topTen = this.showTopTen(); + const suggeriti = this.showSuggeriti(); + const activeIds = this.playlistService.activeListIds(); + const selectionMode = this.playlistService.selectionMode(); + + // 1. Get base list depending on community filter + let list: any[] = []; + const comunitaCode = this.comunitaService.comunitaCode(); + const comunitaIds = this.comunitaService.comunitaCantiIds(); + + if (comunitaCode && this.comunitaService.isFilterActive()) { + // Base is standard canti + my canti + community custom canti + remote custom canti + remote share canti + list = [ + ...this.cantiService.canti(), + ...this.myCantiService.myCanti(), + ...this.playlistService.remoteCustomSongs(), + ...this.playlistService.remoteShareCanti(), + ...this.comunitaService.comunitaCantiPersonali() + ]; + + // Filter to only community canti, but preserve canti that are in the active playlist + list = list.filter(c => { + return comunitaIds.includes(c.id_canti) || comunitaIds.includes(c.id) || activeIds.includes(c.id); + }); + + // Deduplicate: parish-customized versions take precedence + const seen = new Map(); + for (const canto of list) { + const key = canto.id_canti || canto.id; + const existing = seen.get(key); + if (!existing) { + seen.set(key, canto); + } else { + if (!existing.isPersonal && canto.isPersonal) { + seen.set(key, canto); + } + } + } + list = Array.from(seen.values()); + + // Sort by community song number (num_canto) + const cantiInfo = this.comunitaService.comunitaCantiInfo(); + list.sort((a, b) => { + const infoA = cantiInfo.find(x => x.id_canti === a.id_canti || x.id_canti === Number(a.id)); + const infoB = cantiInfo.find(x => x.id_canti === b.id_canti || x.id_canti === Number(b.id)); + const numA = infoA ? Number(infoA.num_canto) : 999999; + const numB = infoB ? Number(infoB.num_canto) : 999999; + return numA - numB; + }); + } else { + // General context: only standard canti + my canti + remote custom canti + remote share canti + list = [ + ...this.cantiService.canti(), + ...this.myCantiService.myCanti(), + ...this.playlistService.remoteCustomSongs(), + ...this.playlistService.remoteShareCanti() + ]; + } + + // 2. Cumulative filtering + + // Filter by selectionMode / reorderList if in selection mode and not adding songs + if (selectionMode && !this.isAddingSongs()) { + return this.reorderList(); + } + + // A. Filter by Playlist (if activeIds is present) + if (activeIds.length > 0 && (!selectionMode || this.playlistService.activePlaylistId() === null)) { + list = activeIds + .map(id => list.find(c => c.id === id)) + .filter((c): c is any => !!c); + } + + // B. Filter by "Only Mine" (Miei) + if (onlyMine) { + const myIds = new Set(this.myCantiService.myCanti().map(c => c.id)); + list = list.filter(c => myIds.has(c.id)); + } + + // Filter by Validati (non personali e non contrassegnati come non validati) + if (this.showValidati()) { + list = list.filter(c => !c.nonValidato && (onlyMine || !c.id.startsWith('my_'))); + } + + // Filter by Non-Validati (personali o esplicitamente non validati) + if (this.showNonValidati()) { + list = list.filter(c => c.nonValidato || c.id.startsWith('my_')); + } + + // C. Filter by Liturgical Moment + if (litId !== null) { + list = list.filter(c => c.id_momenti?.includes(litId)); + } + + // D. Filter by Thematic Moment + if (temId !== null) { + list = list.filter(c => c.id_momenti?.includes(temId)); + } + + // E. Filter by Suggested (Suggeriti) + if (suggeriti) { + const suggMap = this.cantiLettureService.suggestionsMap(); + list = list.filter(c => suggMap.has(c.id_canti)); + } + + // F. Filter by Search Query + if (query) { + const processedQuery = query.replace(/\buno\b/g, '1'); + const numberMatchPattern = processedQuery.match(/^(?:numero|nr\.?)\s*(\d+)$/); + + if (numberMatchPattern) { + const targetId = numberMatchPattern[1]; + list = list.filter(c => { + const commNum = this.getCommunitySongNumber(c); + return commNum ? commNum === targetId : c.id_canti.toString() === targetId; + }); + } else { + const tokens = query.split(/\s+/).filter(t => t.length > 0); + + list = list.filter(c => { + const normTitle = this.normalize(c.titolo); + const normAuthor = this.normalize(c.autore); + const commNum = this.getCommunitySongNumber(c); + const songNum = commNum || c.id_canti.toString(); + + const lyricsPlain = (c.testo || '') + .replace(/{.*?}/g, '') + .replace(/\n/g, ' '); + const normLyrics = this.normalize(lyricsPlain); + + // Full string matches in title, author, lyrics, or song number + const titleMatch = normTitle.includes(query); + const authorMatch = normAuthor.includes(query); + const lyricsMatch = normLyrics.includes(query); + const numberMatch = songNum.includes(query); + + if (titleMatch || authorMatch || lyricsMatch || numberMatch) { + return true; + } + + // Multi-word token match across fields (e.g. title word + author word) + if (tokens.length > 1) { + return tokens.every(token => + normTitle.includes(token) || + normAuthor.includes(token) || + normLyrics.includes(token) || + songNum.includes(token) + ); + } + + return false; + }); + } + } + + // Advanced search filters (titolo, autore, testo, nr canto) + const advTitle = this.normalize(this.searchTitle()).trim(); + const advAuthor = this.normalize(this.searchAuthor()).trim(); + const advText = this.normalize(this.searchText()).trim(); + const advNumber = this.normalize(this.searchNumber()).trim(); + + if (advTitle) { + list = list.filter(c => this.normalize(c.titolo).includes(advTitle)); + } + + if (advAuthor) { + list = list.filter(c => this.normalize(c.autore || '').includes(advAuthor)); + } + + if (advText) { + list = list.filter(c => { + const lyricsPlain = (c.testo || '') + .replace(/{.*?}/g, '') + .replace(/\n/g, ' '); + return this.normalize(lyricsPlain).includes(advText); + }); + } + + if (advNumber) { + list = list.filter(c => { + const commNum = this.getCommunitySongNumber(c); + const songNum = (commNum ? commNum.toString() : c.id_canti.toString()).toLowerCase().trim(); + return songNum === advNumber.toLowerCase().trim(); + }); + } + + // G. Sorting/Ordering + if (topTen) { + list = [...list].sort((a, b) => { + const numA = this.getEsecuzioniCount(a.id) || 0; + const numB = this.getEsecuzioniCount(b.id) || 0; + return numB - numA; + }); + } else if (suggeriti) { + const suggMap = this.cantiLettureService.suggestionsMap(); + list = [...list].sort((a, b) => { + const pesoA = suggMap.get(a.id_canti) || 0; + const pesoB = suggMap.get(b.id_canti) || 0; + return pesoB - pesoA; + }); + } + + return list; + }); + + public visibleCanti = computed(() => { + if (this.playlistService.selectionMode() && !this.isAddingSongs()) { + return this.filteredCanti(); + } + if (this.comunitaService.isFilterActive() && this.comunitaService.comunitaCode()) { + return this.filteredCanti(); + } + return this.filteredCanti().slice(0, this.limit()); + }); + + public hasAnyFilter = computed(() => { + return ( + this.playlistService.activeListName() !== null || + this.selectedLiturgico() !== null || + this.selectedTematico() !== null || + this.showOnlyMine() || + this.showTopTen() || + this.showSuggeriti() || + this.showValidati() || + this.showNonValidati() || + !!this.searchQuery().trim() || + this.hasAdvancedSearchParams() || + (this.settingsService.comunitaEnabled() && this.comunitaService.isFilterActive()) + ); + }); + + public totalPlaylistDuration = computed(() => { + if (this.playlistService.activePlaylistId() === null) return ''; + const songs = this.filteredCanti(); + if (songs.length === 0) return ''; + + let totalSeconds = 0; + for (const song of songs) { + if (song.durata) { + totalSeconds += this.parseDuration(song.durata); + } + } + + if (totalSeconds === 0) return ''; + return this.formatTotalDuration(totalSeconds); + }); + + private parseDuration(dur: string): number { + if (!dur) return 0; + const parts = dur.split(':').map(Number); + if (parts.some(isNaN)) return 0; + if (parts.length === 2) { + return parts[0] * 60 + parts[1]; + } else if (parts.length === 3) { + return parts[0] * 3600 + parts[1] * 60 + parts[2]; + } + return 0; + } + + private formatTotalDuration(seconds: number): string { + const hh = Math.floor(seconds / 3600); + const mm = Math.floor((seconds % 3600) / 60); + const ss = seconds % 60; + + const pad = (n: number) => n.toString().padStart(2, '0'); + + if (hh > 0) { + return `${pad(hh)}:${pad(mm)}:${pad(ss)}`; + } + return `${pad(mm)}:${pad(ss)}`; + } + + constructor() { + // Check if there is an update available + this.checkUpdateStatus(); + if (this.swUpdate.isEnabled) { + this.swUpdate.versionUpdates.subscribe(evt => { + if (evt.type === 'VERSION_READY') { + this.hasUpdateAvailable.set(true); + } + }); + } + + // Polling setup: check for updates every 30 seconds + this.updatePollInterval = setInterval(() => { + this.checkUpdateStatus(); + if (this.isRemotePlaylist()) { + this.playlistService.checkForRemotePlaylistUpdates(); + } + }, 30000); + // Sync homepage filtered canti IDs to playlistService.filteredListIds + effect(() => { + const ids = this.filteredCanti().map(c => c.id); + this.playlistService.filteredListIds.set(ids); + }, { allowSignalWrites: true }); + + + // Track initial community filter state to avoid clearing during the initial run of the effect + let prevFilterActive = this.comunitaService.isFilterActive(); + let prevComunitaCode = this.comunitaService.comunitaCode(); + + // Automatically reset all other filters and active playlist when toggling the community filter or changing community + effect(() => { + const active = this.comunitaService.isFilterActive(); + const code = this.comunitaService.comunitaCode(); + + if (active !== prevFilterActive || code !== prevComunitaCode) { + prevFilterActive = active; + prevComunitaCode = code; + + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + this.showOnlyMine.set(false); + this.showTopTen.set(false); + this.showSuggeriti.set(false); + this.showValidati.set(false); + this.showNonValidati.set(false); + this.playlistService.activeListIds.set([]); + this.playlistService.activeListName.set(null); + this.playlistService.activePlaylistId.set(null); + this.searchQuery.set(''); + this.activeFilterType.set(null); + this.limit.set(10); + } + }, { allowSignalWrites: true }); + + // Sync speech recognition results to search query or advanced field + effect(() => { + const transcript = this.audioEngine.searchTranscript(); + if (transcript) { + const target = this.activeVoiceField(); + switch (target) { + case 'title': + this.searchTitle.set(transcript); + break; + case 'author': + this.searchAuthor.set(transcript); + break; + case 'text': + this.searchText.set(transcript); + break; + case 'number': + this.searchNumber.set(transcript); + break; + case 'global': + default: + this.searchQuery.set(transcript); + break; + } + } + }); + + + let queryParamsSubscribed = false; + effect(() => { + if (this.settingsService.isVersionCheckComplete() && !queryParamsSubscribed) { + queryParamsSubscribed = true; + this.queryParamsSubscription = this.route.queryParams.subscribe(params => { + if (params['id']) { + const idVal = params['id']; + this.router.navigate([], { queryParams: { id: null, t: null }, queryParamsHandling: 'merge', replaceUrl: true }).then(() => { + this.goToCanto(idVal); + }); + } + if (params['import']) { + this.handleImport(params['import']); + } + if (params['import-canto']) { + this.handleImportCanto(params['import-canto']); + } + if (params['song-uid'] && params['song-id']) { + this.handleRemoteSongImport(params['song-uid'], params['song-id']); + } + if (params['playlist-uid']) { + this.handleRemotePlaylistImport(params['playlist-uid'], params['playlist-id']); + } + if (params['restore-uid']) { + this.handleRemoteRestore(params['restore-uid']); + } + }); + } + }, { allowSignalWrites: true }); + + let hasAutoActivatedPlaylist = false; + effect(() => { + const lastPl = this.playlistService.lastPlaylist(); + const versionReady = this.settingsService.isVersionCheckComplete(); + + if (versionReady && lastPl && !hasAutoActivatedPlaylist) { + const params = this.route.snapshot.queryParams; + if (!params['id'] && !params['import'] && !params['playlist-uid'] && !params['restore-uid'] && !params['song-uid'] && !params['import-canto']) { + hasAutoActivatedPlaylist = true; + this.selectPlaylist(lastPl); + this.activeFilterType.set('playlist'); + } else { + hasAutoActivatedPlaylist = true; + } + } + }, { allowSignalWrites: true }); + + let prevSelectionMode = false; + + effect(() => { + const selectionMode = this.playlistService.selectionMode(); + const selectedIds = this.playlistService.selectedIds(); + const activeIds = this.playlistService.activeListIds(); + + if (selectionMode) { + if (!prevSelectionMode) { + if (activeIds.length === 0 || this.playlistService.activePlaylistId() === null) { + this.isAddingSongs.set(true); + } else { + this.isAddingSongs.set(false); + } + } + prevSelectionMode = true; + + const currentIds = this.reorderList().map(c => c.id); + const newIds = Array.from(selectedIds); + + // Use a set of IDs for faster lookup + const currentIdSet = new Set(currentIds); + const newIdSet = new Set(newIds); + + // Check if there are differences in the SET of IDs + const added = newIds.filter(id => !currentIdSet.has(id)); + const removed = currentIds.filter(id => !newIdSet.has(id)); + + if (added.length > 0 || removed.length > 0) { + let updatedList = [...this.reorderList()]; + + // Remove songs no longer selected + if (removed.length > 0) { + updatedList = updatedList.filter(c => newIdSet.has(c.id)); + } + + // Add newly selected songs at the end + if (added.length > 0) { + const newSongs = added.map(id => this.findCanto(id)).filter((c): c is any => !!c); + updatedList = [...updatedList, ...newSongs]; + } + + // Previeni cicli infiniti se il contenuto della lista non è effettivamente cambiato + const currentIdsStr = currentIds.join(','); + const updatedIdsStr = updatedList.map(c => c.id).join(','); + if (currentIdsStr !== updatedIdsStr) { + this.reorderList.set(updatedList); + } + } + } else { + prevSelectionMode = false; + this.isAddingSongs.set(false); + } + }, { allowSignalWrites: true }); + + // Fullscreen control when black screen overlay is active + effect(() => { + const isBlack = this.isBlackOverlayActive(); + if (isBlack) { + this.enterFullscreen(); + } else { + this.exitFullscreen(); + } + }); + } + + ionViewWillEnter() { + // Gestione dati QR scansionati e passati via router state dalle Impostazioni + const navigation = this.router.getCurrentNavigation(); + const state = navigation?.extras.state as { scannedQrData?: string } | undefined; + if (state?.scannedQrData) { + this.handleScannedData(state.scannedQrData); + } + } + + + + async handleImport(base64: string) { + try { + const base64Safe = base64.replace(/ /g, '+'); + const decoded = decodeURIComponent(escape(atob(base64Safe))); + const json = JSON.parse(decoded); + + if (json && json.comunitaCode) { + // 1. Abilita la funzionalità comunità nelle impostazioni + this.settingsService.comunitaEnabled.set(true); + localStorage.setItem('comunita-enabled', 'true'); + + // 2. Mostra un overlay di caricamento premium con indicatore di progresso + const loading = await this.loadingCtrl.create({ + message: 'Attivazione comunità: Caricamento 0%', + cssClass: 'premium-loading', + spinner: 'crescent' + }); + await loading.present(); + + // Iscrizione agli aggiornamenti di progresso + let progressInterval: any = null; + progressInterval = setInterval(() => { + const pct = this.comunitaService.loadingProgress(); + loading.message = `Attivazione comunità: Caricamento ${pct}%`; + if (pct >= 100) { + clearInterval(progressInterval); + } + }, 100); + + const success = await this.comunitaService.setComunitaCode(json.comunitaCode); + clearInterval(progressInterval); + await loading.dismiss(); + + if (success) { + const toast = await this.toastCtrl.create({ + message: `Comunità attivata: ${this.comunitaService.comunitaNome()}`, + duration: 2500, + color: 'success', + position: 'bottom' + }); + await toast.present(); + } else { + const toast = await this.toastCtrl.create({ + message: 'Codice comunità non trovato o errore di connessione.', + duration: 3000, + color: 'danger', + position: 'bottom' + }); + await toast.present(); + } + } + + if (this.playlistService.processImportJson(json)) { + this.limit.set(50); // Mostra più canti inizialmente per le playlist speciali + this.activeFilterType.set('playlist'); + await this.router.navigate([], { queryParams: { import: null, openFirst: null }, queryParamsHandling: 'merge', replaceUrl: true }); + } + } catch (e) { + console.error('Failed to import playlist', e); + const toast = await this.toastCtrl.create({ + message: 'Errore durante l\'importazione della playlist.', + duration: 3000, + color: 'danger', + position: 'bottom' + }); + await toast.present(); + } + } + + async handleImportCanto(base64: string) { + try { + const base64Safe = base64.replace(/ /g, '+'); + const decoded = decodeURIComponent(escape(atob(base64Safe))); + const json = JSON.parse(decoded); + + if (json && json.cantoShare && json.titolo) { + const id_canti = Date.now(); + const id = `remote_share_${id_canti}`; + + const canto: any = { + id: id, + id_canti: id_canti, + titolo: json.titolo, + autore: json.autore || '', + testo: json.testo || '', + accordi: json.accordi || '', + link_youtube: json.link_youtube || '', + id_momenti: json.id_momenti || [], + nonValidato: true + }; + + await this.playlistService.saveRemoteShareCanto(canto); + + const toast = await this.toastCtrl.create({ + message: `Canto "${canto.titolo}" importato nei brani remoti non validati!`, + duration: 3000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + + await this.router.navigate([], { queryParams: { 'import-canto': null }, queryParamsHandling: 'merge', replaceUrl: true }); + this.goToCanto(canto.id); + } + } catch (e) { + console.error('Failed to import canto', e); + const toast = await this.toastCtrl.create({ + message: 'Errore durante l\'importazione del canto.', + duration: 3000, + color: 'danger', + position: 'bottom' + }); + await toast.present(); + } + } + + async handleRemoteSongImport(uid: string, songId: string) { + const loading = await this.loadingCtrl.create({ + message: 'Scaricamento canto da remoto...' + }); + await loading.present(); + + try { + const response = await fetch(`https://api.canticristiani.it/${uid}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (!response.ok) { + throw new Error(`Risposta del server non valida: ${response.status}`); + } + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + const item = remoteJson.find((x: any) => + Number(x.id_canti) === Number(songId) && + (!x.momenti || (!x.momenti.includes('Playlist') && !x.momenti.includes('UserMetadata'))) + ); + + if (!item) { + throw new Error('Canto non trovato nel profilo remoto.'); + } + + const id = `remote_share_${item.id_canti}`; + const canto: any = { + id: id, + id_canti: Number(item.id_canti), + titolo: item.titolo || 'Senza Titolo', + autore: item.autore || '', + testo: item.testo || '', + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + nonValidato: true, + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + }; + + await this.playlistService.saveRemoteShareCanto(canto); + + const toast = await this.toastCtrl.create({ + message: `Canto "${canto.titolo}" importato nei brani remoti non validati!`, + duration: 3000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + + await this.router.navigate([], { queryParams: { 'song-uid': null, 'song-id': null }, queryParamsHandling: 'merge', replaceUrl: true }); + this.goToCanto(canto.id); + } else { + throw new Error('Formato dati non valido.'); + } + } catch (err: any) { + console.error('Failed to import remote song:', err); + const alert = await this.alertCtrl.create({ + header: 'Errore Importazione', + message: 'Impossibile scaricare il canto da remoto. Controlla la connessione o il link.', + buttons: ['OK'] + }); + await alert.present(); + await this.router.navigate([], { queryParams: { 'song-uid': null, 'song-id': null }, queryParamsHandling: 'merge', replaceUrl: true }); + } finally { + await loading.dismiss(); + } + } + + async handleRemotePlaylistImport(uid: string, pid?: string) { + const loading = await this.loadingCtrl.create({ + message: 'Scaricamento playlist da remoto...' + }); + await loading.present(); + + let hasNavigatedToCanto = false; + const openFirst = this.route.snapshot.queryParams['openFirst'] === '1'; + try { + const response = await fetch(`https://api.canticristiani.it/${uid}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (!response.ok) { + throw new Error(`Risposta del server non valida: ${response.status}`); + } + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + // 1. Reconstruct custom songs + const customSongs = remoteJson + .filter((item: any) => item.momenti && !item.momenti.includes('Playlist')) + .map((item: any) => ({ + id: `my_${item.id_canti}`, + id_canti: Number(item.id_canti), + titolo: item.titolo, + testo: item.testo, + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + autore: item.autore || '', + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + })); + + // 2. Reconstruct playlists + const playlists = remoteJson + .filter((item: any) => item.momenti && item.momenti.includes('Playlist')) + .map((item: any) => { + let songSettings = {}; + if (item.periodi && item.periodi.length > 0) { + try { + songSettings = JSON.parse(item.periodi[0]); + } catch (e) {} + } + return { + id: `remote_${uid}_${item.id_canti}`, + name: `[Remote] ${item.titolo}`, + ids: item.testo ? item.testo.split(',') : [], + songSettings: songSettings, + createdAt: new Date(), + isRemote: true + }; + }); + + if (playlists.length === 0) { + throw new Error('Nessuna playlist trovata in questa identità.'); + } + + // Find the selected one + let selectedPl = playlists[0]; + if (pid) { + const targetId = `remote_${uid}_${pid}`; + const found = playlists.find(p => p.id === targetId || p.id.endsWith(`_${pid}`)); + if (found) { + selectedPl = found; + } + } + + await this.playlistService.saveRemotePlaylist(selectedPl, customSongs); + + // Clear other filters to avoid confusion + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + + // Select it immediately + this.selectPlaylist(selectedPl); + this.playlistService.lastPlaylist.set(selectedPl); + this.activeFilterType.set('playlist'); + + await loading.dismiss(); + + const toast = await this.toastCtrl.create({ + message: `Playlist "${selectedPl.name}" caricata per consultazione!`, + duration: 3000, + color: 'success' + }); + await toast.present(); + + if (selectedPl.ids && selectedPl.ids.length > 0) { + await this.router.navigate([], { queryParams: { 'playlist-uid': null, 'playlist-id': null, 'openFirst': null }, queryParamsHandling: 'merge', replaceUrl: true }); + } + } else { + throw new Error('Formato dati non valido.'); + } + } catch (err: any) { + await loading.dismiss(); + console.error('Failed to import remote playlist:', err); + const alert = await this.alertCtrl.create({ + header: 'Errore Importazione', + message: 'Impossibile scaricare la playlist da remoto. Controlla la connessione o il codice.', + buttons: ['OK'] + }); + await alert.present(); + } finally { + if (!hasNavigatedToCanto) { + this.router.navigate([], { queryParams: { 'playlist-uid': null, 'playlist-id': null, 'openFirst': null }, queryParamsHandling: 'merge', replaceUrl: true }); + } + } + } + + async handleRemoteRestore(uid: string) { + const alert = await this.alertCtrl.create({ + header: 'Ripristina Identità', + message: 'Sei sicuro di voler scaricare e ripristinare i dati di questa identità? L\'ID attuale del dispositivo verrà sovrascritto.', + buttons: [ + { text: 'Annulla', role: 'cancel' }, + { + text: 'Ripristina', + role: 'destructive', + handler: async () => { + const loading = await this.loadingCtrl.create({ + message: 'Scaricamento dati da remoto...' + }); + await loading.present(); + + try { + const response = await fetch(`https://api.canticristiani.it/${uid}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (response.ok) { + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + // Reconstruct user name/metadata + const userMetadata = remoteJson.find((item: any) => item.momenti && item.momenti.includes('UserMetadata')); + if (userMetadata && userMetadata.titolo) { + this.settingsService.setUserName(userMetadata.titolo); + } + + // Reconstruct custom songs + const customSongs = remoteJson + .filter((item: any) => (!item.momenti || !item.momenti.includes('Playlist')) && (!item.momenti || !item.momenti.includes('UserMetadata'))) + .map((item: any) => ({ + id: `my_${item.id_canti}`, + id_canti: Number(item.id_canti), + titolo: item.titolo || 'Senza Titolo', + testo: item.testo || '', + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + autore: item.autore || '', + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + })); + + if (customSongs.length > 0) { + this.myCantiService.myCanti.set(customSongs); + const storage = this.cantiService.getStorage(); + if (storage) { + await storage.set('my-canti', customSongs); + } + } + + // Reconstruct playlists + const playlists = remoteJson + .filter((item: any) => item.momenti && item.momenti.includes('Playlist')) + .map((item: any) => { + let songSettings = {}; + if (item.periodi && item.periodi.length > 0) { + try { + songSettings = JSON.parse(item.periodi[0]); + } catch (e) {} + } + return { + id: String(item.id_canti), + name: item.titolo, + ids: item.testo ? item.testo.split(',') : [], + songSettings: songSettings, + createdAt: new Date() + }; + }); + + if (playlists.length > 0) { + this.playlistService.playlists.set(playlists); + if (this.playlistService['_storage']) { + const key = this.playlistService.getPlaylistsStorageKey(); + await this.playlistService['_storage'].set(key, playlists); + } + } + } + } + } catch (err) { + console.error('Failed to restore remote backup:', err); + } finally { + await loading.dismiss(); + } + + this.settingsService.setUserUuid(uid); + + const toast = await this.toastCtrl.create({ + message: 'Dati ripristinati con successo! Ricaricamento...', + duration: 2000, + color: 'success' + }); + await toast.present(); + + setTimeout(() => { + window.location.replace(window.location.origin + window.location.pathname); + }, 1500); + } + } + ] + }); + await alert.present(); + } + + ionViewWillLeave() { + } + + ngOnDestroy() { + this.audioEngine.stopSearchRecognition(); + if (this.updatePollInterval) { + clearInterval(this.updatePollInterval); + } + if (this.queryParamsSubscription) { + this.queryParamsSubscription.unsubscribe(); + } + } + + onSearch(event: any) { + this.searchQuery.set(event.detail.value); + this.limit.set(30); + } + + toggleAdvancedSearch() { + const willOpen = !this.isAdvancedSearchOpen(); + this.isAdvancedSearchOpen.set(willOpen); + if (willOpen) { + this.isFilterCardOpen.set(false); + this.isPlaylistCardOpen.set(false); + } + } + + toggleFilterCard() { + const willOpen = !this.isFilterCardOpen(); + this.isFilterCardOpen.set(willOpen); + if (willOpen) { + this.isAdvancedSearchOpen.set(false); + this.isPlaylistCardOpen.set(false); + } + } + + togglePlaylistCard() { + const willOpen = !this.isPlaylistCardOpen(); + this.isPlaylistCardOpen.set(willOpen); + if (willOpen) { + this.isAdvancedSearchOpen.set(false); + this.isFilterCardOpen.set(false); + } + } + + clearAdvancedSearch(event?: Event) { + if (event) { + event.stopPropagation(); + } + this.searchTitle.set(''); + this.searchAuthor.set(''); + this.searchText.set(''); + this.searchNumber.set(''); + this.limit.set(30); + } + + clearFilterCard(event?: Event) { + if (event) { + event.stopPropagation(); + } + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + this.showOnlyMine.set(false); + this.showTopTen.set(false); + this.showSuggeriti.set(false); + this.showValidati.set(false); + this.showNonValidati.set(false); + this.limit.set(30); + } + + clearPlaylistCard(event?: Event) { + if (event) { + event.stopPropagation(); + } + this.playlistService.activeListIds.set([]); + this.playlistService.activeListName.set(null); + this.playlistService.activePlaylistId.set(null); + if (this.settingsService.comunitaEnabled() && this.comunitaService.isFilterActive()) { + this.toggleComunitaFilter(); + } + this.limit.set(30); + } + + onSearchTitleInput(event: any) { + const val = event.target?.value ?? event.detail?.value ?? ''; + this.searchTitle.set(val); + this.limit.set(30); + } + + onSearchAuthorInput(event: any) { + const val = event.target?.value ?? event.detail?.value ?? ''; + this.searchAuthor.set(val); + this.limit.set(30); + } + + onSearchTextInput(event: any) { + const val = event.target?.value ?? event.detail?.value ?? ''; + this.searchText.set(val); + this.limit.set(30); + } + + onSearchNumberInput(event: any) { + const val = event.target?.value ?? event.detail?.value ?? ''; + this.searchNumber.set(val); + this.limit.set(30); + } + + async deleteMyCanto(id: string, event: Event) { + event.stopPropagation(); + const alert = await this.alertCtrl.create({ + header: 'Elimina Canto', + message: 'Sei sicuro di voler eliminare questo canto dai tuoi brani personali?', + buttons: [ + { text: 'Annulla', role: 'cancel' }, + { + text: 'Elimina', + role: 'destructive', + handler: () => { + this.myCantiService.deleteCanto(id); + } + } + ] + }); + await alert.present(); + } + + findCanto(id: string) { + if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + const personal = this.comunitaService.comunitaCantiPersonali().find(c => c.id === id); + if (personal) return personal; + } + return [ + ...this.cantiService.canti(), + ...this.myCantiService.myCanti(), + ...this.playlistService.remoteCustomSongs(), + ...this.playlistService.remoteShareCanti(), + ...this.comunitaService.comunitaCantiPersonali() + ].find(c => c.id === id || String(c.id_canti) === id); + } + + getPlayingCanto() { + const id = this.youtubePlayerService.currentCantoId(); + if (!id) return null; + return this.findCanto(id); + } + + goToCanto(id: string) { + const params: any = { id }; + const isPlaying = this.youtubePlayerService.isPlaying(); + + if (this.youtubePlayerService.currentCantoId() === id && isPlaying) { + params.t = Math.floor(this.youtubePlayerService.videoProgress()); + } + + this.playlistService.autoPlayPlaylist.set(isPlaying); + this.router.navigate(['/player'], { queryParams: params }); + } + + toggleOnlyMine() { + this.showOnlyMine.update(v => !v); + this.activeFilterType.set(null); + this.limit.set(10); + } + + clearOnlyMine(event: Event) { + event.stopPropagation(); + this.showOnlyMine.set(false); + this.limit.set(10); + } + + toggleIndex(id: number, type: 'liturgico' | 'tematico' | 'playlist' | 'lista_completa') { + if (type === 'liturgico') { + this.selectedLiturgico.update(cur => cur === id ? null : id); + } else if (type === 'tematico') { + this.selectedTematico.update(cur => cur === id ? null : id); + } + + // Mantieni aperto il menu di secondo livello se c'è una selezione attiva per quel tipo + let hasSelection = false; + if (type === 'liturgico' && this.selectedLiturgico() !== null) { + hasSelection = true; + } else if (type === 'tematico' && this.selectedTematico() !== null) { + hasSelection = true; + } + + if (!hasSelection) { + this.activeFilterType.set(null); + } + this.limit.set(10); + } + + clearLiturgico(event: Event) { + event.stopPropagation(); + this.selectedLiturgico.set(null); + this.activeFilterType.set(null); + this.limit.set(10); + } + + clearTematico(event: Event) { + event.stopPropagation(); + this.selectedTematico.set(null); + this.activeFilterType.set(null); + this.limit.set(10); + } + + isIndexSelected(id: number): boolean { + return this.selectedLiturgico() === id || this.selectedTematico() === id; + } + + clearFilters() { + const type = this.activeFilterType(); + + if (this.playlistService.activeListIds().length > 0) { + this.clearSpecialList(); + } + + if (type === 'liturgico') { + if (this.selectedLiturgico() === null) { + this.selectedTematico.set(null); + } else { + this.selectedLiturgico.set(null); + } + } else if (type === 'tematico') { + if (this.selectedTematico() === null) { + this.selectedLiturgico.set(null); + } else { + this.selectedTematico.set(null); + } + } else { + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + } + + this.showOnlyMine.set(false); + this.searchQuery.set(''); + this.audioEngine.clearSearchTranscript(); + } + + activeFiltersCount(): number { + let count = 0; + if (this.selectedLiturgico() !== null) count++; + if (this.selectedTematico() !== null) count++; + return count; + } + + getSelectedLiturgicoLabel(): string | null { + const id = this.selectedLiturgico(); + if (id === null) return null; + return this.cantiService.indiceLiturgico().find(m => m.id === id)?.tag_name || null; + } + + getSelectedTematicoLabel(): string | null { + const id = this.selectedTematico(); + if (id === null) return null; + return this.cantiService.indiceTematico().find(m => m.id === id)?.tag_name || null; + } + + hasActiveFilters(): boolean { + return this.selectedLiturgico() !== null || + this.selectedTematico() !== null || + this.showOnlyMine() || + this.showTopTen() || + this.showSuggeriti() || + this.showValidati() || + this.showNonValidati() || + this.playlistService.activeListName() !== null || + this.searchQuery() !== '' || + this.hasAdvancedSearchParams(); + } + + shouldShowSubSectionToolbar(): boolean { + if (this.playlistService.selectionMode() && this.reorderList().length > 0) { + return true; + } + const filterType = this.activeFilterType(); + if (filterType) { + return true; + } + return false; + } + + clearAllFilters() { + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + this.showOnlyMine.set(false); + this.showTopTen.set(false); + this.showSuggeriti.set(false); + this.showValidati.set(false); + this.showNonValidati.set(false); + this.playlistService.activeListIds.set([]); + this.playlistService.activeListName.set(null); + this.playlistService.activePlaylistId.set(null); + this.searchQuery.set(''); + this.clearAdvancedSearch(); + this.activeFilterType.set(null); + this.limit.set(10); + } + + toggleFilterType(type: 'liturgico' | 'tematico' | 'playlist' | 'lista_completa') { + if (this.activeFilterType() === type) { + // Chiudi solo se non ci sono selezioni di secondo livello attive per questo tipo + let hasSelection = false; + if (type === 'liturgico' && this.selectedLiturgico() !== null) { + hasSelection = true; + } else if (type === 'tematico' && this.selectedTematico() !== null) { + hasSelection = true; + } else if (type === 'playlist' && this.playlistService.activePlaylistId() !== null) { + hasSelection = true; + } else if (type === 'lista_completa' && (this.showValidati() || this.showNonValidati())) { + hasSelection = true; + } + + if (!hasSelection) { + this.activeFilterType.set(null); + } + } else { + this.activeFilterType.set(type); + } + } + + selectPlaylist(pl: any) { + this.playlistService.activeListIds.set(pl.ids); + this.playlistService.activeListName.set(pl.name); + this.playlistService.activePlaylistId.set(pl.id); + if (pl.isRemote || pl.id?.startsWith('remote_')) { + this.playlistService.checkForRemotePlaylistUpdates(); + } + this.isAdvancedSearchOpen.set(false); + this.isFilterCardOpen.set(false); + // Mantieni il menu aperto poiché la playlist è ora selezionata ed attiva + this.limit.set(50); + } + + toggleTopTen() { + this.showTopTen.update(v => !v); + this.activeFilterType.set(null); + this.limit.set(30); + } + + clearTopTen(event?: Event) { + if (event) event.stopPropagation(); + this.showTopTen.set(false); + this.limit.set(30); + } + + toggleValidati() { + this.showValidati.update(v => !v); + this.showNonValidati.set(false); + if (!this.showValidati()) { + this.activeFilterType.set(null); + } else { + this.activeFilterType.set('lista_completa'); + } + this.limit.set(30); + } + + clearValidati(event?: Event) { + if (event) event.stopPropagation(); + this.showValidati.set(false); + this.activeFilterType.set(null); + this.limit.set(30); + } + + toggleNonValidati() { + this.showNonValidati.update(v => !v); + this.showValidati.set(false); + if (!this.showNonValidati()) { + this.activeFilterType.set(null); + } else { + this.activeFilterType.set('lista_completa'); + } + this.limit.set(30); + } + + clearNonValidati(event?: Event) { + if (event) event.stopPropagation(); + this.showNonValidati.set(false); + this.activeFilterType.set(null); + this.limit.set(30); + } + + clearListaCompleta(event?: Event) { + if (event) event.stopPropagation(); + this.showValidati.set(false); + this.showNonValidati.set(false); + this.activeFilterType.set(null); + this.limit.set(10); + } + + toggleSuggeriti() { + this.showSuggeriti.update(v => !v); + if (this.showSuggeriti()) { + this.isMassCardExpanded.set(true); + } + this.activeFilterType.set(null); + this.limit.set(30); + } + + clearSuggeriti(event?: Event) { + if (event) event.stopPropagation(); + this.showSuggeriti.set(false); + this.limit.set(30); + } + + getMassSuggestionWeight(id_canti: number): number | null { + const weight = this.cantiLettureService.suggestionsMap().get(id_canti); + return weight !== undefined ? weight : null; + } + + getMassSuggestionMoment(id_canti: number): string | null { + const moments = this.cantiLettureService.suggestionsMomentsMap().get(id_canti); + return moments && moments.length > 0 ? moments.join(', ') : null; + } + + getSelectedMassFormattedDate(): string | null { + const dateStr = this.cantiLettureService.selectedMassDate(); + if (!dateStr) return null; + const parts = dateStr.split('-'); + if (parts.length === 3) { + return `${parts[2]}/${parts[1]}/${parts[0]}`; + } + return dateStr; + } + + getSelectedMassTitle(): string | null { + const dateStr = this.cantiLettureService.selectedMassDate(); + const data = this.cantiLettureService.data(); + if (dateStr && data && data.masses[dateStr]) { + return data.masses[dateStr].title; + } + return null; + } + + getSelectedMassSummary(): string | null { + const dateStr = this.cantiLettureService.selectedMassDate(); + const data = this.cantiLettureService.data(); + if (dateStr && data && data.masses[dateStr]) { + return data.masses[dateStr].summary || null; + } + return null; + } + + getEsecuzioniCount(id: string): number | null { + const numId = parseInt(id, 10); + if (isNaN(numId)) return null; + const es = this.cantiService.cantiEseguiti().find(x => x.id_canti === numId); + return es ? es.num : 0; + } + + onImgLoad(id: string) { + this.loadedThumbs.add(id); + } + + openYoutube(event: Event, link: string) { + event.stopPropagation(); + const videoId = this.cantiService.getYoutubeId(link); + if (videoId) { + window.open(`https://www.youtube.com/watch?v=${videoId}`, '_blank'); + } + } + + playVideo(event: Event, id: string) { + event.stopPropagation(); + if (!this.youtubePlayerService.isPlayerSupported()) { + return; + } + this.isBlackOverlayDismissed.set(false); + this.youtubePlayerService.setMediaSessionCallbacks( + () => this.playNextPreview(), + () => this.playPrevPreview() + ); + this.youtubePlayerService.initPlayer( + id, + 0, + () => { + if (this.settingsService.autoAdvance()) { + this.playNextPreview(); + } else { + this.youtubePlayerService.stop(); + } + }, + () => { + if (this.settingsService.autoAdvance()) { + setTimeout(() => this.playNextPreview(), 500); + } else { + this.youtubePlayerService.stop(); + } + } + ); + } + + stopVideo(event: Event) { + if (event) event.stopPropagation(); + this.youtubePlayerService.stop(); + this.playlistService.autoPlayPlaylist.set(false); + } + + pauseVideo(event: Event) { + if (event) event.stopPropagation(); + this.youtubePlayerService.pause(); + this.isBlackOverlayDismissed.set(true); + } + + togglePlayPause() { + if (!this.youtubePlayerService.isPlaying()) { + this.isBlackOverlayDismissed.set(false); + } + this.youtubePlayerService.togglePlayPause(); + } + + playNextPreview(event?: Event) { + if (event) event.stopPropagation(); + const currentId = this.youtubePlayerService.currentCantoId(); + if (!currentId) return; + + const list = this.visibleCanti(); + const currentIndex = list.findIndex(c => c.id === currentId); + + for (let i = currentIndex + 1; i < list.length; i++) { + if (list[i].link_youtube) { + this.playVideo(new Event('skip'), list[i].id); + + setTimeout(() => { + const el = document.getElementById('canto-' + list[i].id); + if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }, 300); + return; + } + } + + this.youtubePlayerService.stop(); + } + + playPrevPreview(event?: Event) { + if (event) event.stopPropagation(); + const currentId = this.youtubePlayerService.currentCantoId(); + if (!currentId) return; + + const list = this.visibleCanti(); + const currentIndex = list.findIndex(c => c.id === currentId); + + for (let i = currentIndex - 1; i >= 0; i--) { + if (list[i].link_youtube) { + this.playVideo(new Event('skip'), list[i].id); + + setTimeout(() => { + const el = document.getElementById('canto-' + list[i].id); + if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }, 300); + return; + } + } + } + + onSeek(event: any) { + this.youtubePlayerService.seekTo(event.detail.value); + } + + onSeekStart() { + this.isSeeking = true; + } + + onSeekEnd() { + this.isSeeking = false; + } + + getMomentiForCanto(ids: number[] | undefined): any[] { + if (!ids) return []; + return this.cantiService.momenti() + .filter(m => ids.includes(m.id)); + } + + filterByMomento(event: Event, id: number) { + event.stopPropagation(); + // Use liturgico as default for momento tags + this.toggleIndex(id, 'liturgico'); + // Scroll to top to show results + const content = document.querySelector('ion-content'); + if (content) (content as any).scrollToTop(300); + } + + loadData(event: any) { + setTimeout(() => { + this.limit.update(l => l + 10); + event.target.complete(); + }, 500); + } + + // --- Touch Gestures for Pinch-to-Zoom --- + onTouchStart(event: TouchEvent) { + if (event.touches.length === 2) { + this.initialPinchDistance = this.getDistance(event.touches[0], event.touches[1]); + this.initialFontSize = this.fontSize(); + } + } + + onTouchMove(event: TouchEvent) { + if (event.touches.length === 2 && this.initialPinchDistance !== null) { + // We don't preventDefault here to allow scrolling if needed, + // but usually pinch should be captured. + const currentDistance = this.getDistance(event.touches[0], event.touches[1]); + const ratio = currentDistance / this.initialPinchDistance; + let newSize = this.initialFontSize * ratio; + + // Clamp values + newSize = Math.max(this.MIN_FONT, Math.min(this.MAX_FONT, newSize)); + + if (Math.abs(newSize - this.fontSize()) > 0.01) { + this.fontSize.set(newSize); + } + } + } + + onTouchEnd() { + this.initialPinchDistance = null; + } + + private getDistance(t1: Touch, t2: Touch): number { + return Math.sqrt(Math.pow(t1.clientX - t2.clientX, 2) + Math.pow(t1.clientY - t2.clientY, 2)); + } + + handleScannedData(data: string) { + if (!data) return; + + if (data.includes('playlist-uid=')) { + try { + const urlObj = new URL(data); + const uid = urlObj.searchParams.get('playlist-uid'); + const pid = urlObj.searchParams.get('playlist-id'); + if (uid) { + this.handleRemotePlaylistImport(uid, pid || undefined); + return; + } + } catch (e) { + const uidMatch = data.match(/[?&]playlist-uid=([^&]+)/); + const pidMatch = data.match(/[?&]playlist-id=([^&]+)/); + if (uidMatch && uidMatch[1]) { + this.handleRemotePlaylistImport(uidMatch[1], pidMatch ? pidMatch[1] : undefined); + return; + } + } + } + + if (data.includes('restore-uid=')) { + try { + const urlObj = new URL(data); + const uid = urlObj.searchParams.get('restore-uid'); + if (uid) { + this.handleRemoteRestore(uid); + return; + } + } catch (e) { + const uidMatch = data.match(/[?&]restore-uid=([^&]+)/); + if (uidMatch && uidMatch[1]) { + this.handleRemoteRestore(uidMatch[1]); + return; + } + } + } + + if (data.includes('import-canto=')) { + try { + let base64 = ''; + if (data.includes('?import-canto=')) { + base64 = data.split('?import-canto=')[1]; + } else if (data.includes('&import-canto=')) { + base64 = data.split('&import-canto=')[1]; + } + + if (base64.includes('&')) { + base64 = base64.split('&')[0]; + } + if (base64.includes('#')) { + base64 = base64.split('#')[0]; + } + + this.handleImportCanto(base64); + return; + } catch (e) { + console.error('Failed to parse scanned canto link', e); + } + } + + if (data.includes('import=')) { + try { + let base64 = ''; + if (data.includes('?import=')) { + base64 = data.split('?import=')[1]; + } else if (data.includes('&import=')) { + base64 = data.split('&import=')[1]; + } + + if (base64.includes('&')) { + base64 = base64.split('&')[0]; + } + if (base64.includes('#')) { + base64 = base64.split('#')[0]; + } + + this.handleImport(base64); + return; + } catch (e) { + console.error('Failed to parse scanned link', e); + } + } + + if (data.startsWith('canti:')) { + const parts = data.replace('canti:', '').split(':'); + let idsStr = ''; + let playlistName = 'Lista Parrocchiale'; + if (parts.length > 1) { + playlistName = parts[0]; + idsStr = parts[1]; + } else { + idsStr = parts[0]; + } + + const ids = idsStr.split(',').map(id => id.trim()); + this.playlistService.activeListIds.set(ids); + this.playlistService.activeListName.set(playlistName); + this.limit.set(50); // Show more initially for special lists + + // Clear other filters to avoid confusion + this.selectedLiturgico.set(null); + this.selectedTematico.set(null); + + // Automatically save to the device! + this.playlistService.savePlaylist(playlistName, ids); + + // Activate the playlist filter + this.activeFilterType.set('playlist'); + } + } + + toggleVoiceSearch(target: 'global' | 'title' | 'author' | 'text' | 'number' = 'global') { + if (this.audioEngine.isSearching()) { + const currentTarget = this.activeVoiceField(); + this.audioEngine.stopSearchRecognition(); + if (currentTarget !== target) { + this.activeVoiceField.set(target); + this.audioEngine.startSearchRecognition(); + } + } else { + this.activeVoiceField.set(target); + this.audioEngine.startSearchRecognition(); + } + } + + async finishSelection() { + const alert = await this.alertCtrl.create({ + header: 'Salva Playlist', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'Nome della playlist', + value: this.playlistService.activeListName() || '' + } + ], + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Salva', + handler: async (data) => { + if (data.name) { + const ids = this.reorderList().map(s => s.id); + const activeId = this.playlistService.activePlaylistId(); + const pl = activeId ? this.playlistService.playlists().find(p => p.id === activeId) : null; + const songSettings = pl ? pl.songSettings : undefined; + await this.playlistService.savePlaylist(data.name, ids, songSettings); + + // Azzoppa / azzera il filtro cerca libera quando si salva + this.searchQuery.set(''); + + const toast = await this.toastCtrl.create({ + message: 'Playlist salvata!', + duration: 2000, + color: 'success' + }); + await toast.present(); + + this.isAddingSongs.set(false); + this.playlistService.selectionMode.set(false); + this.playlistService.selectedIds.set(new Set()); + return true; + } + return false; + } + } + ] + }); + await alert.present(); + } + + cancelSelection() { + const id = this.playlistService.activePlaylistId(); + if (id) { + const pl = this.playlistService.playlists().find(p => p.id === id); + if (pl) { + this.playlistService.activeListIds.set(pl.ids); + this.playlistService.activeListName.set(pl.name); + } + } + + this.playlistService.selectionMode.set(false); + this.playlistService.selectedIds.set(new Set()); + this.isAddingSongs.set(false); + } + + isComunitaPlaylist(): boolean { + const id = this.playlistService.activePlaylistId(); + if (id && id.startsWith('comunita_')) return true; + const name = this.playlistService.activeListName(); + if (name) { + const pl = this.playlistService.allPlaylists().find(p => p.name === name); + return !!pl?.isComunita; + } + return false; + } + + isRemotePlaylist(): boolean { + const id = this.playlistService.activePlaylistId(); + if (id && id.startsWith('remote_')) return true; + const name = this.playlistService.activeListName(); + if (name) { + const pl = this.playlistService.allPlaylists().find(p => p.name === name); + return !!pl?.isRemote; + } + return false; + } + + async refreshActiveRemotePlaylist() { + const loading = await this.loadingCtrl.create({ + message: 'Aggiornamento playlist...' + }); + await loading.present(); + try { + await this.playlistService.refreshRemotePlaylist(); + const toast = await this.toastCtrl.create({ + message: 'Playlist aggiornata da remoto!', + duration: 2000, + color: 'success' + }); + await toast.present(); + } catch (e) { + const alert = await this.alertCtrl.create({ + header: 'Errore', + message: 'Impossibile aggiornare la playlist da remoto.', + buttons: ['OK'] + }); + await alert.present(); + } finally { + await loading.dismiss(); + } + } + + isActivePlaylistSaved(): boolean { + const id = this.playlistService.activePlaylistId(); + if (id) return this.playlistService.playlists().some(p => p.id === id); + const name = this.playlistService.activeListName(); + if (name) return this.playlistService.playlists().some(p => p.name === name); + return false; + } + + clearSpecialList(event?: Event) { + if (event) event.stopPropagation(); + this.playlistService.activeListIds.set([]); + this.playlistService.activeListName.set(null); + this.playlistService.activePlaylistId.set(null); + this.limit.set(30); + } + + playPlaylist() { + const ids = this.playlistService.activeListIds(); + if (ids.length > 0) { + this.playlistService.autoPlayPlaylist.set(true); + this.router.navigate(['/player'], { queryParams: { id: ids[0] } }); + } + } + + shareActivePlaylist() { + const ids = this.playlistService.activeListIds(); + const name = this.playlistService.activeListName() || 'Playlist'; + + const id = this.playlistService.activePlaylistId(); + const pl = this.playlistService.playlists().find(p => p.id === id); + const songSettings = pl ? pl.songSettings : undefined; + + this.playlistService.sharePlaylistQR(ids, name, songSettings); + } + + async printActivePlaylist() { + const ids = this.playlistService.activeListIds(); + if (ids.length === 0) return; + + const allCanti = this.cantiService.canti(); + const myCantiList = this.myCantiService.myCanti(); + const comunitaCantiPers = this.comunitaService.comunitaCantiPersonali(); + const communityActive = this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive(); + + const songs = ids.map(id => { + let found: any = null; + if (communityActive) { + found = comunitaCantiPers.find(c => c.id === id); + } + if (!found) { + found = allCanti.find(c => c.id === id); + } + if (!found) { + found = myCantiList.find(c => c.id === id); + } + if (!found) { + found = comunitaCantiPers.find(c => c.id === id); + } + return found; + }).filter(c => !!c); + + const alert = await this.alertCtrl.create({ + header: 'Esporta in PDF', + message: 'Vuoi includere gli accordi nel PDF o esportare solo il testo?', + buttons: [ + { + text: 'Solo Testo', + handler: () => { + const name = this.playlistService.activeListName() || 'Playlist'; + this.playlistService.printPlaylist(name, songs, false); + } + }, + { + text: 'Testo e Accordi', + handler: () => { + const name = this.playlistService.activeListName() || 'Playlist'; + this.playlistService.printPlaylist(name, songs, true); + } + }, + { + text: 'Annulla', + role: 'cancel' + } + ] + }); + await alert.present(); + } + + async cloneActivePlaylist() { + const id = this.playlistService.activePlaylistId(); + const currentName = this.playlistService.activeListName() || 'Playlist'; + const activeIds = this.playlistService.activeListIds(); + + const allPls = this.playlistService.allPlaylists(); + const activePl = allPls.find(p => p.id === id); + const songSettings = activePl ? activePl.songSettings : undefined; + + const alert = await this.alertCtrl.create({ + header: 'Clona Playlist', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'Nome della nuova playlist', + value: `${currentName} (Copia)` + } + ], + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Clona', + handler: async (data) => { + if (data.name) { + await this.playlistService.clonePlaylist(data.name, [...activeIds], songSettings); + + const toast = await this.toastCtrl.create({ + message: `Playlist clonata nel profilo: ${data.name}`, + duration: 2500, + color: 'success' + }); + await toast.present(); + return true; + } + return false; + } + } + ] + }); + await alert.present(); + } + + async importPlaylist() { + const modal = await this.modalCtrl.create({ + component: QrScannerComponent + }); + await modal.present(); + + const { data } = await modal.onWillDismiss(); + if (!data) return; + this.handleScannedData(data); + } + + async deleteActivePlaylist() { + const id = this.playlistService.activePlaylistId(); + const name = this.playlistService.activeListName(); + if (!id || !name) return; + + const isRemote = this.isRemotePlaylist(); + + const alert = await this.alertCtrl.create({ + header: isRemote ? 'Rimuovi Playlist' : 'Elimina Playlist', + message: isRemote ? `Vuoi davvero rimuovere la playlist "${name}"?` : `Vuoi davvero eliminare "${name}"?`, + buttons: [ + { text: 'Annulla', role: 'cancel' }, + { + text: isRemote ? 'Rimuovi' : 'Elimina', + role: 'destructive', + handler: () => { + if (isRemote) { + this.playlistService.clearRemotePlaylist(); + } else { + this.playlistService.deletePlaylist(id); + } + this.clearSpecialList(); + } + } + ] + }); + await alert.present(); + } + + editPlaylist() { + const ids = this.playlistService.activeListIds(); + const name = this.playlistService.activeListName(); + + // Prova a recuperare l'ID se stiamo editando una playlist salvata + const found = this.playlistService.playlists().find(p => p.name === name); + if (found) { + this.playlistService.activePlaylistId.set(found.id); + } + + this.playlistService.selectedIds.set(new Set(ids)); + const songs = ids.map(id => this.findCanto(id)).filter((c): c is any => !!c); + this.reorderList.set(songs); + this.playlistService.selectionMode.set(true); + this.isAddingSongs.set(false); // Default to reorder view + + // Svuota la playlist attiva per mostrare tutto l'elenco in modalità selezione + this.playlistService.activeListIds.set([]); + this.playlistService.activeListName.set(name); + } + + toggleSongSelection(id: string) { + if (!this.playlistService.selectionMode()) { + const activeIds = this.playlistService.activeListIds(); + const activeName = this.playlistService.activeListName(); + + if (activeIds.length > 0) { + // Se selezioniamo i numerini di una playlist attiva, non andiamo in modifica di quella playlist + // ma avviamo la selezione partendo da questa lista per creare una nuova playlist. + this.playlistService.activePlaylistId.set(null); + + const clickedCanto = this.findCanto(id); + if (clickedCanto) { + this.playlistService.selectedIds.set(new Set([clickedCanto.id])); + this.reorderList.set([clickedCanto]); + } + + this.playlistService.selectionMode.set(true); + this.isAddingSongs.set(true); // Rimaniamo sulla lista filtrata per selezionare altri canti + return; + } + } + + this.playlistService.toggleSongSelection(id); + } + + drop(event: CdkDragDrop) { + const arr = [...this.reorderList()]; + moveItemInArray(arr, event.previousIndex, event.currentIndex); + this.reorderList.set(arr); + } + + toggleAddingSongs() { + this.isAddingSongs.update(v => !v); + this.limit.set(10); + } + + getCommunitySongNumber(canto: any): string | null { + if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) return null; + const cantiInfo = this.comunitaService.comunitaCantiInfo(); + const info = cantiInfo.find(x => x.id_canti === canto.id_canti || x.id_canti === Number(canto.id)); + return info && info.num_canto ? info.num_canto.toString() : null; + } + + getMySongNumber(canto: any): number { + if (!canto || !canto.id) return 0; + const index = this.myCantiService.myCanti().findIndex(c => c.id === canto.id); + return index !== -1 ? index + 1 : 0; + } + + getSongTonality(canto: any): string | null { + if (!canto) return null; + const baseKey = this.lyricsParser.deduceTonality(canto.accordi || canto.testo || ''); + if (!baseKey) return null; + + let semitones = 0; + const activePlaylistId = this.playlistService.activePlaylistId(); + if (activePlaylistId) { + let playlistSongSetting: any = null; + if (activePlaylistId.startsWith('remote_')) { + const pl = this.playlistService.remotePlaylist(); + if (pl && pl.songSettings && pl.songSettings[canto.id]) { + playlistSongSetting = pl.songSettings[canto.id]; + } + } else { + const pl = this.playlistService.playlists().find(p => p.id === activePlaylistId); + if (pl && pl.songSettings && pl.songSettings[canto.id]) { + playlistSongSetting = pl.songSettings[canto.id]; + } + } + if (playlistSongSetting && playlistSongSetting.tonalita !== undefined) { + semitones = playlistSongSetting.tonalita; + } + } else if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + const settings = this.comunitaService.comunitaCantiSettings(); + const songSetting = settings.find(s => s.id_canti === canto.id_canti || s.id_canti === Number(canto.id)); + if (songSetting && songSetting.tonalita !== undefined) { + semitones = songSetting.tonalita; + } + } + + if (semitones !== 0) { + return this.lyricsParser.transposeChord(baseKey, semitones); + } + + return baseKey; + } + + toggleComunitaFilter() { + if (this.comunitaService.comunitaCode()) { + this.comunitaService.isFilterActive.update(v => !v); + } + this.activeFilterType.set(null); + } + + private massCardStartX: number = 0; + private massCardStartY: number = 0; + + onMassCardTouchStart(event: TouchEvent) { + if (event.touches.length === 1) { + this.massCardStartX = event.touches[0].clientX; + this.massCardStartY = event.touches[0].clientY; + } + } + + onMassCardTouchEnd(event: TouchEvent) { + if (event.changedTouches.length === 1) { + const endX = event.changedTouches[0].clientX; + const endY = event.changedTouches[0].clientY; + const diffX = endX - this.massCardStartX; + const diffY = endY - this.massCardStartY; + + // Ensure it is a horizontal swipe (diffX is much larger than diffY) + if (Math.abs(diffX) > 60 && Math.abs(diffY) < 40) { + // Prevent triggering click expansion + event.stopPropagation(); + event.preventDefault(); + + if (diffX > 0) { + // Swiped right -> go to PREVIOUS date + this.navigateMassDate(-1); + } else { + // Swiped left -> go to NEXT date + this.navigateMassDate(1); + } + } + } + } + + private panelStartX: number = 0; + private panelStartY: number = 0; + + onPanelTouchStart(event: TouchEvent) { + if (event.touches.length === 1) { + this.panelStartX = event.touches[0].clientX; + this.panelStartY = event.touches[0].clientY; + } + } + + onPanelTouchEnd(event: TouchEvent, panelType: 'advancedSearch' | 'playlistCard' | 'filterCard') { + if (event.changedTouches.length === 1) { + const endX = event.changedTouches[0].clientX; + const endY = event.changedTouches[0].clientY; + const diffX = endX - this.panelStartX; + const diffY = endY - this.panelStartY; + + // Swipe UP: vertical movement upwards (diffY negative, e.g. < -40) and larger than horizontal diff + if (diffY < -40 && Math.abs(diffY) > Math.abs(diffX)) { + if (panelType === 'advancedSearch') { + this.isAdvancedSearchOpen.set(false); + } else if (panelType === 'playlistCard') { + this.isPlaylistCardOpen.set(false); + } else if (panelType === 'filterCard') { + this.isFilterCardOpen.set(false); + } + } + } + } + + async navigateMassDate(direction: number) { + const list = this.cantiLettureService.availableMasses(); + if (list.length === 0) return; + + const currentDate = this.cantiLettureService.selectedMassDate(); + if (!currentDate) { + this.cantiLettureService.selectedMassDate.set(list[0].date); + return; + } + + const currentIndex = list.findIndex(m => m.date === currentDate); + if (currentIndex === -1) { + this.cantiLettureService.selectedMassDate.set(list[0].date); + return; + } + + const nextIndex = currentIndex + direction; + if (nextIndex >= 0 && nextIndex < list.length) { + // Set the next/prev date + this.cantiLettureService.selectedMassDate.set(list[nextIndex].date); + + const toast = await this.toastCtrl.create({ + message: `Messa: ${list[nextIndex].day} ${this.formatCompactDate(list[nextIndex].date)}`, + duration: 1500, + color: 'secondary', + position: 'bottom' + }); + await toast.present(); + } else { + // "quando le messe sono finite rimani sull'ultima valorizzata, non dare errore" + const targetIndex = direction > 0 ? list.length - 1 : 0; + this.cantiLettureService.selectedMassDate.set(list[targetIndex].date); + + const toast = await this.toastCtrl.create({ + message: direction > 0 ? 'Nessun\'altra messa futura disponibile.' : 'Nessun\'altra messa passata disponibile.', + duration: 1500, + color: 'medium', + position: 'bottom' + }); + await toast.present(); + } + } + + private formatCompactDate(dateStr: string): string { + const parts = dateStr.split('-'); + if (parts.length === 3) { + return `${parts[2]}/${parts[1]}`; + } + return dateStr; + } + + formatSeconds(seconds: number | undefined | null): string { + if (seconds === undefined || seconds === null || isNaN(seconds)) { + return '0:00'; + } + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins}:${secs < 10 ? '0' : ''}${secs}`; + } + + private async enterFullscreen() { + try { + const docEl = document.documentElement; + if (docEl.requestFullscreen) { + await docEl.requestFullscreen(); + } else if ((docEl as any).webkitRequestFullscreen) { + await (docEl as any).webkitRequestFullscreen(); + } else if ((docEl as any).msRequestFullscreen) { + await (docEl as any).msRequestFullscreen(); + } + } catch (e) { + console.warn('[HomePage] Failed to enter fullscreen:', e); + } + } + + private async exitFullscreen() { + try { + if (document.exitFullscreen) { + if (document.fullscreenElement) { + await document.exitFullscreen(); + } + } else if ((document as any).webkitExitFullscreen) { + if ((document as any).webkitFullscreenElement) { + await (document as any).webkitExitFullscreen(); + } + } else if ((document as any).msExitFullscreen) { + if ((document as any).msFullscreenElement) { + await (document as any).msExitFullscreen(); + } + } + } catch (e) { + console.warn('[HomePage] Failed to exit fullscreen:', e); + } + } +} + diff --git a/src/app/interceptors/api-auth.interceptor.ts b/src/app/interceptors/api-auth.interceptor.ts new file mode 100644 index 0000000..a6b298e --- /dev/null +++ b/src/app/interceptors/api-auth.interceptor.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { environment } from '../../environments/environment'; + +@Injectable() +export class ApiAuthInterceptor implements HttpInterceptor { + intercept(req: HttpRequest, next: HttpHandler): Observable> { + if (req.url.includes('api.canticristiani.it')) { + const authHeader = 'Basic ' + btoa(`${environment.apiAuthUser}:${environment.apiAuthPass}`); + const authReq = req.clone({ + setHeaders: { + Authorization: authHeader + } + }); + return next.handle(authReq); + } + return next.handle(req); + } +} diff --git a/src/app/pages/display/display-routing.module.ts b/src/app/pages/display/display-routing.module.ts new file mode 100644 index 0000000..a177402 --- /dev/null +++ b/src/app/pages/display/display-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { DisplayPage } from './display.page'; + +const routes: Routes = [ + { + path: '', + component: DisplayPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class DisplayPageRoutingModule {} diff --git a/src/app/pages/display/display.module.ts b/src/app/pages/display/display.module.ts new file mode 100644 index 0000000..0b4d260 --- /dev/null +++ b/src/app/pages/display/display.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { DisplayPageRoutingModule } from './display-routing.module'; + +import { DisplayPage } from './display.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + DisplayPageRoutingModule + ], + declarations: [DisplayPage] +}) +export class DisplayPageModule {} diff --git a/src/app/pages/display/display.page.html b/src/app/pages/display/display.page.html new file mode 100644 index 0000000..774d3c8 --- /dev/null +++ b/src/app/pages/display/display.page.html @@ -0,0 +1,46 @@ + +
+
+ +
+ + + {{ seg.chord }} + {{ seg.text }} + + + {{ displayLines().prev!.text }} +
+ + +
+ + + {{ seg.chord }} + {{ seg.text }} + + + {{ displayLines().current!.text }} +
+ + +
+ + + {{ seg.chord }} + {{ seg.text }} + + + {{ displayLines().next!.text }} +
+
+ + +
+
diff --git a/src/app/pages/display/display.page.scss b/src/app/pages/display/display.page.scss new file mode 100644 index 0000000..a24917a --- /dev/null +++ b/src/app/pages/display/display.page.scss @@ -0,0 +1,95 @@ +.bg-gradient { + --background: radial-gradient(circle at top, #1e272e 0%, #000000 100%); + background: radial-gradient(circle at top, #1e272e 0%, #000000 100%); +} + +.display-wrapper { + height: 100vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 5% 10%; + text-align: center; + transition: font-size 0.2s ease; + touch-action: none; /* Support pinch-to-zoom */ +} + +.lyrics-window { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + gap: 2rem; + width: 100%; +} + +.active-line { + font-size: 5rem; + font-weight: 700; + color: var(--ion-color-secondary); + text-shadow: 0 0 20px rgba(253, 203, 110, 0.4); + line-height: 1.2; +} + +.prev-line, .next-line { + font-size: 2.5rem; + color: rgba(255, 255, 255, 0.2); + font-weight: 300; +} + +// ─── Chord segments for display ──────────────── +.chord-segment { + display: inline-flex; + flex-direction: column; + vertical-align: bottom; +} + +.chord { + color: #e74c3c; + font-weight: 700; + font-size: 0.4em; + line-height: 1.2; + min-height: 0.5em; + font-family: 'Outfit', sans-serif; + letter-spacing: 0.5px; + padding-right: 0.25em; +} + +.active-line .chord { + color: #e74c3c; + font-size: 0.35em; +} + +.prev-line .chord, .next-line .chord { + color: rgba(231, 76, 60, 0.4); + font-size: 0.5em; +} + +.active-line, .prev-line, .next-line { + display: flex; + flex-wrap: wrap; + align-items: flex-end; + justify-content: center; +} + +.seg-text { + white-space: pre-wrap; + &::after { + content: '\200b'; + } +} + +.footer-info { + margin-top: 2rem; + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding-top: 1rem; + width: 100%; + + .title-label { + font-size: 1.5rem; + color: rgba(255, 255, 255, 0.4); + text-transform: uppercase; + letter-spacing: 2px; + } +} diff --git a/src/app/pages/display/display.page.spec.ts b/src/app/pages/display/display.page.spec.ts new file mode 100644 index 0000000..11eaf40 --- /dev/null +++ b/src/app/pages/display/display.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { DisplayPage } from './display.page'; + +describe('DisplayPage', () => { + let component: DisplayPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(DisplayPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/display/display.page.ts b/src/app/pages/display/display.page.ts new file mode 100644 index 0000000..dda18e5 --- /dev/null +++ b/src/app/pages/display/display.page.ts @@ -0,0 +1,177 @@ +import { Component, OnInit, OnDestroy, signal, computed, effect, inject } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { CantiService, Canto } from '../../services/canti.service'; +import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser.service'; +import { ComunitaService } from '../../services/comunita.service'; + +@Component({ + selector: 'app-display', + templateUrl: './display.page.html', + styleUrls: ['./display.page.scss'], + standalone: false +}) +export class DisplayPage implements OnInit, OnDestroy { + public canto = signal(null); + public activeSongId = signal(null); + public showChords = signal(false); + public fontSize = signal(1.0); + public currentLineIndex = signal(0); + public transposeAmount = signal(0); + + public parsedSections = computed(() => { + const c = this.canto(); + if (!c) return []; + + let sections: ParsedSection[]; + const hasChordsInText = !c.accordi && c.testo?.includes('['); + + if ((this.showChords() && c.accordi) || (this.showChords() && hasChordsInText)) { + sections = this.lyricsParser.parseAccordi(c.accordi || c.testo); + } else { + sections = this.lyricsParser.parseText(c.testo); + } + + if (sections.length === 0 && c.testo) { + const fallbackLines = c.testo.split('\n') + .filter(l => l.trim().length > 0) + .map(l => ({ + text: l.trim(), + segments: [{ text: l.trim() }] + })); + + if (fallbackLines.length > 0) { + sections = [{ + type: 'verse', + lines: fallbackLines + }]; + } + } + + if (this.showChords()) { + return this.lyricsParser.transposeSections(sections, this.transposeAmount()); + } + + return sections; + }); + + /** Get the current line text and surrounding lines from flat index */ + public displayLines = computed(() => { + const sections = this.parsedSections(); + const idx = this.currentLineIndex(); + const allLines: { text: string; segments: any[]; sectionType: string }[] = []; + + for (const section of sections) { + for (const line of section.lines) { + allLines.push({ text: line.text, segments: line.segments, sectionType: section.type }); + } + } + + return { + prev: idx > 0 ? allLines[idx - 1] : null, + current: allLines[idx] || null, + next: idx < allLines.length - 1 ? allLines[idx + 1] : null + }; + }); + + private channel = new BroadcastChannel('karaoke_sync'); + + private readonly MIN_FONT = 0.6; + private readonly MAX_FONT = 5.0; + private initialPinchDistance: number | null = null; + private initialFontSize: number = 1.0; + + private route = inject(ActivatedRoute); + private cantiService = inject(CantiService); + public lyricsParser = inject(LyricsParserService); + private comunitaService = inject(ComunitaService); + + constructor() { + effect(() => { + const id = this.activeSongId(); + const allCanti = this.cantiService.canti(); + const comunitaCantiPers = this.comunitaService.comunitaCantiPersonali(); + if (id) { + let found: any = null; + if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + found = comunitaCantiPers.find(c => c.id === id); + } + if (!found) { + found = allCanti.find(c => c.id === id); + } + if (!found) { + found = comunitaCantiPers.find(c => c.id === id); + } + if (found) { + this.canto.set(found); + } + } + }, { allowSignalWrites: true }); + } + + ngOnInit() { + this.route.queryParams.subscribe(params => { + const id = params['id']; + if (id) { + this.activeSongId.set(id); + } + }); + + this.channel.onmessage = (event) => { + if (event.data.type === 'SYNC_INDEX') { + this.currentLineIndex.set(event.data.index); + } + if (event.data.type === 'SYNC_CANTO') { + this.activeSongId.set(event.data.id); + this.transposeAmount.set(0); + } + if (event.data.type === 'SYNC_CHORDS') { + this.showChords.set(event.data.showChords); + } + if (event.data.type === 'SYNC_FONT') { + this.fontSize.set(event.data.fontSize); + } + if (event.data.type === 'SYNC_TRANSPOSE') { + this.transposeAmount.set(event.data.amount); + } + }; + } + + ngOnDestroy() { + this.channel.close(); + } + + // --- Touch Gestures for Pinch-to-Zoom --- + onTouchStart(event: TouchEvent) { + if (event.touches.length === 2) { + this.initialPinchDistance = this.getDistance(event.touches[0], event.touches[1]); + this.initialFontSize = this.fontSize(); + } + } + + onTouchMove(event: TouchEvent) { + if (event.touches.length === 2 && this.initialPinchDistance !== null) { + event.preventDefault(); // Prevent browser zoom/scroll + const currentDistance = this.getDistance(event.touches[0], event.touches[1]); + const ratio = currentDistance / this.initialPinchDistance; + let newSize = this.initialFontSize * ratio; + + // Clamp values + newSize = Math.max(this.MIN_FONT, Math.min(this.MAX_FONT, newSize)); + + if (Math.abs(newSize - this.fontSize()) > 0.01) { + this.fontSize.set(newSize); + // Sync back to player if display is touched + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() }); + } + } + } + + onTouchEnd() { + this.initialPinchDistance = null; + } + + private getDistance(t1: Touch, t2: Touch): number { + return Math.sqrt(Math.pow(t1.clientX - t2.clientX, 2) + Math.pow(t1.clientY - t2.clientY, 2)); + } + // ---------------------------------------- +} diff --git a/src/app/pages/player/player-routing.module.ts b/src/app/pages/player/player-routing.module.ts new file mode 100644 index 0000000..9038ff0 --- /dev/null +++ b/src/app/pages/player/player-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { PlayerPage } from './player.page'; + +const routes: Routes = [ + { + path: '', + component: PlayerPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class PlayerPageRoutingModule {} diff --git a/src/app/pages/player/player.module.ts b/src/app/pages/player/player.module.ts new file mode 100644 index 0000000..fff3df2 --- /dev/null +++ b/src/app/pages/player/player.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { IonicModule } from '@ionic/angular'; + +import { PlayerPageRoutingModule } from './player-routing.module'; + +import { PlayerPage } from './player.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + PlayerPageRoutingModule, + DragDropModule + ], + declarations: [PlayerPage] +}) +export class PlayerPageModule {} diff --git a/src/app/pages/player/player.page.html b/src/app/pages/player/player.page.html new file mode 100644 index 0000000..58e0419 --- /dev/null +++ b/src/app/pages/player/player.page.html @@ -0,0 +1,369 @@ + + +
+ + +
+ + {{ canto()?.id?.startsWith('my_') ? getMySongNumber(canto()) : canto()?.id_canti }} + + + {{ getCommunitySongNumber(canto()) }} + {{ canto()?.titolo || 'Player' }} + + + + +
+ + +
+ + {{ canto()?.autore || 'Autore sconosciuto' }} + +
+ + +
+
+ + + + {{ canto()?.durata }} + + + + {{ canto()?.bpm }} BPM + + + + {{ tonality() }} + + +
+
+
+
+ + +
+ + +
+ + +
+
+ + +
+ + prv + +
+
+ + + +
+ +
+ + + +
+
+ + nxt + +
+ + +
+ + + +
+ + {{ fontSize().toFixed(1) }} +
+ + + +
+ + +
+ + + +
+ + V{{ autoscrollSpeed() }} +
+ + + +
+ +
+
+ + +
+
+ + + + + +
+ + + + + {{ seg.chord }} + {{ seg.text }} + + + + + + {{ line.text }} + +
+
+ +
+
+ +
+ + + +
+ + + + +
+
+ + + + + + + + + + + + + {{ formatSeconds(youtubePlayerService.videoProgress()) }} + + + + + {{ formatSeconds(youtubePlayerService.videoDuration()) }} + + +
+ Nessun audio disponibile +
+
+ + + + +
+
+
+ + +
+ +
+ + + +
+ + V{{ autoscrollSpeed() }} +
+ + + +
+ + +
+ + + + + +
+ + {{ (faceDetector.currentDistanceRatio() * 100).toFixed(0) }}% +
+ + +
+ + {{ faceDetector.currentTiltAngle() }}° +
+
+ + +
+ + + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + + +
+ + +
+ + + +
+ + {{ tonality() }} + ({{ transposeAmount() > 0 ? '+' : '' }}{{ transposeAmount() }}) +
+ + + +
+ + +
+ + + +
+ + {{ fontSize().toFixed(1) }} +
+ + + +
+ + +
+ + + +
+ + +
+
+
+ + +
+
+
+

Schermo nero attivo

+
+ +
+

{{ canto()?.titolo }}

+

{{ canto()?.autore }}

+
+ +
+ {{ formatSeconds(youtubePlayerService.videoProgress()) }} / {{ formatSeconds(youtubePlayerService.videoDuration()) }} +
+ +
+ + + + + + + + + +
+ diff --git a/src/app/pages/player/player.page.scss b/src/app/pages/player/player.page.scss new file mode 100644 index 0000000..91f3972 --- /dev/null +++ b/src/app/pages/player/player.page.scss @@ -0,0 +1,1146 @@ +.bg-gradient { + --background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); + background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); +} + +.canto-title { + transition: font-size 0.15s ease; + &.small-title { + font-size: 1.12rem !important; + } +} + +.outfit-font { + font-family: 'Outfit', sans-serif; +} + +// Header styles +.top-toolbar { + --padding-top: 4px; + --padding-bottom: 4px; + --min-height: 40px; + + // Force left alignment in Ionic toolbar + ion-title { + padding-inline-start: 56px; // Clear the back button on iOS/Apple devices + padding-inline-end: 8px; + text-align: left !important; + } + + .canto-number { + position: relative; + width: 32px; + height: 32px; + line-height: 28px; + text-align: center; + background: rgba(var(--ion-color-secondary-rgb), 0.1); + color: var(--ion-color-secondary); + font-size: 0.85rem; + border-radius: 8px; + font-weight: 700; + border: 2px solid var(--ion-color-secondary); + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); + + &.clickable { + cursor: pointer; + transition: all 0.2s ease; + &:active { transform: scale(0.9); } + } + + &.selected { + background: var(--ion-color-secondary); + color: #000; + border-color: var(--ion-color-secondary); + box-shadow: 0 0 10px rgba(var(--ion-color-secondary-rgb), 0.4); + } + } + + .settings-btn { + --color: var(--ion-color-secondary); + --padding-start: 0; + --padding-end: 0; + margin-left: 0; + margin-right: 0; + width: 38px; + min-width: 38px; + height: 38px; + + ion-icon { + font-size: 1.6rem; + } + } + + .title-main { + display: flex; + align-items: center; + justify-content: flex-start; + gap: 12px; + font-size: 1.15rem; // Fisso: non influenzato dallo zoom del testo + font-weight: 700; + color: var(--ion-color-secondary); + white-space: normal; + line-height: 1.2; + text-align: left; + + .song-author { + font-size: 0.75rem; + color: rgba(255, 255, 255, 0.55); + font-weight: 400; + display: inline-block; + font-family: 'Outfit', sans-serif; + } + + .title-text { + flex: 1; + text-align: left; + } + } + + .scroll-horizontal { + display: flex; + align-items: center; + flex-wrap: nowrap; + gap: 12px; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + .song-duration-badge, .song-bpm-badge, .song-tonality-badge { + font-size: 0.75rem; + padding: 2px 6px; + border-radius: 4px; + display: inline-flex; + align-items: center; + gap: 3px; + height: 26px; + flex-shrink: 0; + + ion-icon { + font-size: 1.05rem; + } + } + + .header-action-btn { + margin: 0; + --padding-start: 4px; + --padding-end: 4px; + height: 38px; + width: 38px; + flex-shrink: 0; + + ion-icon { + font-size: 1.65rem; + } + } + + // Responsive scaling based on viewport width + @media (max-width: 480px) { + gap: 4px; + + .song-duration-badge, .song-bpm-badge, .song-tonality-badge { + font-size: 0.68rem; + padding: 1px 3px; + height: 22px; + gap: 2px; + + ion-icon { + font-size: 0.9rem; + } + } + + .header-action-btn { + height: 32px; + width: 32px; + --padding-start: 0px; + --padding-end: 0px; + + ion-icon { + font-size: 1.35rem; + } + } + } + + @media (max-width: 360px) { + gap: 2px; + + .song-duration-badge, .song-bpm-badge, .song-tonality-badge { + font-size: 0.62rem; + padding: 1px 2px; + height: 20px; + gap: 1px; + + ion-icon { + font-size: 0.8rem; + } + } + + .header-action-btn { + height: 28px; + width: 28px; + --padding-start: 0px; + --padding-end: 0px; + + ion-icon { + font-size: 1.15rem; + } + } + } + } +} + +// Content and Lyrics +.lyrics-container { + padding: 8px 24px 140px 24px; // Increased bottom padding for global player + height: 100%; + overflow-y: auto; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; + + &.full-screen-container { + padding-bottom: 20px !important; + } +} + +// ... existing code ... + +/* GLOBAL PLAYER FOOTER */ +.global-player-toolbar { + --background: transparent; + --padding-top: 4px; + --padding-bottom: 4px; + --padding-start: 12px; + --padding-end: 12px; + + &.glass { + background: rgba(26, 26, 46, 0.95) !important; + backdrop-filter: blur(20px); + border-top: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 0 !important; + box-shadow: none !important; + } + + .player-content { + display: flex; + flex-direction: column; + padding: 0; + } + + .controls-row { + display: flex; + align-items: center; + gap: 4px; + + .play-btn, .skip-btn, .close-btn { + --padding-start: 0; + --padding-end: 0; + height: 40px; + width: 40px; + + ion-icon { + font-size: 1.6rem; + } + } + + .global-range { + flex: 1; + --bar-height: 4px; + --knob-size: 14px; + padding-top: 0; + padding-bottom: 0; + } + } +} + +.lyrics-view { + max-width: 900px; + margin-left: 0; // Always left aligned + text-align: left; +} + +.section { + margin-bottom: 1.2rem; + position: relative; + + &.chorus { + background: rgba(var(--ion-color-secondary-rgb), 0.03); + border-left: 3px solid var(--ion-color-secondary); + padding-left: 1rem; + margin-left: -1rem; + border-radius: 0 8px 8px 0; + } + + .section-label { + font-size: 0.7rem; + text-transform: uppercase; + font-weight: 700; + color: var(--ion-color-secondary); + margin-bottom: 0.25rem; + opacity: 0.7; + letter-spacing: 1px; + } +} + +.lyric-line { + margin-bottom: 0.4rem; + line-height: 1.35; + color: rgba(255, 255, 255, 0.9); + transition: all 0.3s ease; + min-height: 1.5em; + white-space: normal; + overflow-wrap: break-word; + word-break: break-word; + letter-spacing: 3px; + + &.active { + color: var(--ion-color-secondary); + font-weight: 700; + transform: scale(1.02); + text-shadow: 0 0 15px rgba(var(--ion-color-secondary-rgb), 0.3); + } +} + +.chord-segment { + display: inline-flex; + flex-direction: column; + vertical-align: bottom; + margin-right: 0.2em; + + &.contiguous-next { + margin-right: 0 !important; + } + + .chord { + font-size: 0.75em; + font-weight: 700; + color: var(--ion-color-secondary); + height: 1.2em; + margin-bottom: -0.2em; + padding-right: 0.25em; + } + + .seg-text { + white-space: pre; + &::after { + content: '\200b'; + } + } +} + +// Footer styles +.slim-toolbar { + --min-height: 48px; + backdrop-filter: blur(15px); + background: rgba(0,0,0,0.4) !important; +} + +.slim-controls { + display: flex; + justify-content: flex-start; + align-items: center; + width: 100%; + padding: 4px 12px; + overflow-x: auto; + gap: 16px; + -webkit-overflow-scrolling: touch; + + &::-webkit-scrollbar { + display: none; + } + + .mic-btn-portrait { + flex-shrink: 0; + } + + .group { + display: inline-flex; + align-items: center; + gap: 4px; + background: rgba(255, 255, 255, 0.05); + padding: 2px 6px; + border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + flex-shrink: 0; + } + + .page-indicator { + font-size: 0.8rem; + font-weight: 700; + color: var(--ion-color-secondary); + min-width: 40px; + text-align: center; + } + + .transpose-indicator { + display: flex; + align-items: center; + gap: 2px; + font-size: 0.8rem; + font-weight: 700; + color: var(--ion-color-secondary); + + ion-icon { font-size: 0.9rem; } + } + + .zoom-indicator { + display: flex; + align-items: center; + gap: 2px; + font-size: 0.8rem; + font-weight: 700; + color: var(--ion-color-secondary); + + ion-icon { font-size: 0.9rem; } + } + + .camera-indicator { + display: flex; + align-items: center; + gap: 4px; + font-size: 0.8rem; + font-weight: 700; + color: var(--ion-color-secondary); + padding: 0 4px; + transition: all 0.15s ease-out; + + ion-icon { + font-size: 1.1rem; + transition: transform 0.15s ease-out; + display: inline-block; + } + + &.tilted, &.approaching { + color: var(--ion-color-success, #2ed573); + text-shadow: 0 0 5px rgba(46, 213, 115, 0.6); + transform: scale(1.05); + } + + &.receding { + color: var(--ion-color-warning, #ffa502); + text-shadow: 0 0 5px rgba(255, 165, 2, 0.6); + transform: scale(1.05); + } + + &.distance-mode { + cursor: pointer; + user-select: none; + } + } +} + +// Transcript area +.transcript-area { + width: 100%; + + .energy-bar { + height: 100%; + background: var(--ion-color-danger); + transition: width 0.1s ease; + box-shadow: 0 0 10px var(--ion-color-danger); + } +} + +@keyframes pulse { + 0% { transform: scale(0.9); opacity: 0.6; } + 50% { transform: scale(1.15); opacity: 1; } + 100% { transform: scale(0.9); opacity: 0.6; } +} + +:host(.landscape-active) { + // Always hide footer in landscape as we have side controls + ion-footer { + display: none !important; + } + + .lyrics-container { + height: 100%; + padding-top: 4px; // Minimized + padding-bottom: 8px !important; + padding-right: 90px !important; // More room for side controls and zoom + } + + .lyrics-view { + max-width: 100% !important; + } + + ion-content { + --offset-bottom: 0px !important; + } +} + +.landscape-side-controls { + display: none !important; // Strict hidden in portrait + + :host(.landscape-active) & { + display: flex !important; + flex-direction: column; + position: fixed; + right: 0; + top: 56px !important; // Align below header + bottom: 0; + width: 50px; + background: rgba(0, 0, 0, 0.3); + backdrop-filter: blur(10px); + border-left: 1px solid rgba(255, 255, 255, 0.1); + z-index: 100; + } + + .side-scroll-container { + height: 100%; + overflow-y: auto; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + padding: 8px 0; + gap: 12px; + &::-webkit-scrollbar { display: none; } + } + + .side-group { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; // Reduced for a more compact layout + padding-bottom: 12px; + background: rgba(255, 255, 255, 0.05); + margin: 0 2px; + border-radius: 8px; + border: 1px solid rgba(255, 255, 255, 0.1); + padding-top: 6px; + + ion-button { + --padding-start: 0; + --padding-end: 0; + margin: 0; + height: 38px; + width: 38px; + ion-icon { font-size: 1.5rem; } + } + } + + .vertical-range-container { + height: 120px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + margin: 8px 0; + } + + .vertical-range { + transform: rotate(-90deg); + width: 120px; + --bar-height: 4px; + --knob-size: 14px; + padding: 0; + margin: 0; + } + + .side-indicator { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + font-size: 0.7rem; + font-weight: 700; + color: var(--ion-color-secondary); + padding: 4px 0; + cursor: pointer; + + ion-icon { + font-size: 1.0rem; + } + + &.tilted { + color: var(--ion-color-success, #2ed573); + text-shadow: 0 0 5px rgba(46, 213, 115, 0.6); + } + } + + .side-val { + font-size: 0.7rem; + font-weight: 700; + } + + .side-divider { + display: none; + } +} + +ion-content.full-screen-content { + --offset-bottom: 48px !important; // Footer height +} + +:host(.landscape-active) ion-content.full-screen-content { + --offset-bottom: 0px !important; +} + +.mic-sensitivity-overlay { + position: fixed; + right: 15px; + top: 50%; + transform: translateY(-50%); + z-index: 1000; + pointer-events: auto; + + :host(.landscape-active) & { + right: 80px; // Prossimo ai controlli laterali + } + + .slider-card { + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 6px 12px 6px; + background: rgba(18, 18, 18, 0.85) !important; + backdrop-filter: blur(25px); + border-radius: 24px; + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.4); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); + gap: 12px; + animation: slideInRight 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + } + + .close-slider-btn { + --padding-start: 0; + --padding-end: 0; + margin: 0; + height: 36px; + width: 36px; + --color: var(--ion-color-secondary); + + ion-icon { + font-size: 1.5rem; + } + } + + .slider-wrapper { + height: 180px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + padding: 10px 0; + } + + .custom-vertical-slider { + position: relative; + width: 8px; + height: 100%; + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; + + .slider-track { + position: absolute; + width: 100%; + height: 100%; + } + + .slider-fill { + position: absolute; + bottom: 0; + width: 100%; + background: var(--ion-color-secondary); + border-radius: 4px; + box-shadow: 0 0 10px rgba(var(--ion-color-secondary-rgb), 0.3); + transition: height 0.05s linear; + } + + .slider-knob { + position: absolute; + left: 50%; + transform: translate(-50%, 50%); + width: 28px; + height: 28px; + background: var(--ion-color-secondary); + border-radius: 50%; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5), 0 0 15px rgba(var(--ion-color-secondary-rgb), 0.5); + border: 2px solid #fff; + transition: bottom 0.05s linear; + } + } + + .sensitivity-label { + font-size: 0.8rem; + font-weight: 800; + color: var(--ion-color-secondary); + min-width: 40px; + text-align: center; + letter-spacing: 0.5px; + } +} + +@keyframes slideInRight { + from { + opacity: 0; + transform: translateX(20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.voice-threshold-overlay { + position: fixed; + left: 15px; + top: 50%; + transform: translateY(-50%); + z-index: 1000; + pointer-events: auto; + + .slider-card { + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 6px 12px 6px; + background: rgba(18, 18, 18, 0.85) !important; + backdrop-filter: blur(25px); + border-radius: 24px; + border: 1px solid rgba(46, 213, 115, 0.4); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6); + gap: 8px; + animation: slideInLeft 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + } + + .close-slider-btn { + --padding-start: 0; + --padding-end: 0; + margin: 0; + height: 36px; + width: 36px; + --color: var(--ion-color-secondary); + + ion-icon { + font-size: 1.5rem; + } + } + + .slider-wrapper { + height: 180px; + width: 40px; + display: flex; + align-items: center; + justify-content: center; + position: relative; + padding: 10px 0; + } + + .custom-vertical-slider { + position: relative; + width: 8px; + height: 100%; + background: rgba(255, 255, 255, 0.1); + border-radius: 4px; + + .slider-track { + position: absolute; + width: 100%; + height: 100%; + } + + .slider-fill { + position: absolute; + bottom: 0; + width: 100%; + background: linear-gradient(to top, #2ed573, #7bed9f); + border-radius: 4px; + box-shadow: 0 0 10px rgba(46, 213, 115, 0.3); + transition: height 0.05s linear; + } + + .slider-knob { + position: absolute; + left: 50%; + transform: translate(-50%, 50%); + width: 28px; + height: 28px; + background: #2ed573; + border-radius: 50%; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5), 0 0 15px rgba(46, 213, 115, 0.5); + border: 2px solid #fff; + transition: bottom 0.05s linear; + } + } + + .sensitivity-label { + font-size: 0.8rem; + font-weight: 800; + color: #2ed573; + min-width: 40px; + text-align: center; + letter-spacing: 0.5px; + } +} + +@keyframes slideInLeft { + from { + opacity: 0; + transform: translateX(-20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.floating-autoscroll-bar { + position: fixed; + bottom: 120px; + left: 50%; + transform: translateX(-50%); + display: flex; + align-items: center; + gap: 12px; + background: rgba(18, 18, 18, 0.85) !important; + backdrop-filter: blur(20px); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.3); + padding: 6px 16px; + border-radius: 30px; + z-index: 999; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + animation: slideUp 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + pointer-events: auto; + + &.fullscreen-active { + bottom: 24px !important; + } + + &.high-contrast { + background: #ffffff !important; + border-color: #555555 !important; + box-shadow: none !important; + + .autoscroll-control-center { + background: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.15); + + .speed-badge { + color: #000000 !important; + } + } + } + + ion-button { + --padding-start: 4px; + --padding-end: 4px; + margin: 0; + + ion-icon { + font-size: 1.4rem; + } + } + + .autoscroll-control-center { + display: flex; + align-items: center; + gap: 6px; + cursor: pointer; + background: rgba(255, 255, 255, 0.05); + padding: 4px 10px; + border-radius: 20px; + border: 1px solid rgba(255, 255, 255, 0.1); + transition: all 0.2s ease; + + &:active { + transform: scale(0.95); + } + + .speed-badge { + font-size: 0.75rem; + font-weight: 700; + color: var(--ion-color-secondary); + letter-spacing: 0.5px; + } + } +} + +:host-context(body.high-contrast) { + .title-main .song-author { + color: rgba(0, 0, 0, 0.6) !important; + } + + .slim-toolbar { + --background: #ffffff !important; + background: #ffffff !important; + border-top: 1px solid rgba(0, 0, 0, 0.2) !important; + backdrop-filter: none !important; + } + + .landscape-side-controls { + --background: #ffffff !important; + background: #ffffff !important; + border-left: 1px solid rgba(0, 0, 0, 0.2) !important; + backdrop-filter: none !important; + } + + .landscape-audio-player { + --background: #ffffff !important; + background: #ffffff !important; + border-left: 1px solid rgba(0, 0, 0, 0.2) !important; + backdrop-filter: none !important; + } + + .slim-controls .group { + background: rgba(0, 0, 0, 0.05) !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; + } + + .landscape-side-controls .side-scroll-container .side-group { + background: rgba(0, 0, 0, 0.05) !important; + border: 1px solid rgba(0, 0, 0, 0.15) !important; + } +} + +.non-validato-badge { + font-size: 0.6rem; + background: rgba(231, 76, 60, 0.15); /* Soft premium red */ + color: #e74c3c; + padding: 1px 6px; + border-radius: 6px; + border: 1px solid rgba(231, 76, 60, 0.3); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-left: 6px; + display: inline-block; + vertical-align: middle; +} + +:host-context(body.high-contrast) .non-validato-badge { + background: rgba(231, 76, 60, 0.1) !important; + color: #c0392b !important; + border-color: #c0392b !important; +} + +:host-context(.md) { + .top-toolbar ion-title { + padding-inline-start: 8px; + } +} + +.autoscroll-sync-status { + position: fixed; + top: 70px; + left: 50%; + transform: translateX(-50%); + display: inline-flex; + align-items: center; + gap: 8px; + background: rgba(212, 136, 0, 0.18) !important; + border: 1px solid rgba(253, 203, 110, 0.5); + padding: 6px 14px; + border-radius: 16px; + z-index: 999; + box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + animation: slideDownSync 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); + pointer-events: none; + + span { + font-size: 0.8rem; + font-weight: 700; + color: #fdcb6e; + letter-spacing: 0.3px; + } + + .spin-animation { + animation: spinSync 2s linear infinite; + font-size: 1.1rem; + } +} + +@keyframes spinSync { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +@keyframes slideDownSync { + from { + opacity: 0; + transform: translate(-50%, -20px); + } + to { + opacity: 1; + transform: translate(-50%, 0); + } +} + +.camera-preview-floating { + position: fixed; + bottom: 60px; + right: 15px; + padding: 8px 14px; + border-radius: 20px; + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.4); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); + z-index: 1000; + display: flex; + align-items: center; + justify-content: center; + background: rgba(18, 18, 18, 0.85); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + + :host(.landscape-active) & { + bottom: 15px; + right: 80px; + } + + video { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; + pointer-events: none; + } + + .camera-preview-overlay { + display: flex; + justify-content: center; + align-items: center; + + .angle-indicator { + font-size: 0.85rem; + font-weight: 700; + color: #fff; + display: flex; + align-items: center; + + &.tilted { + color: #2ed573; + text-shadow: 0 0 5px #2ed573; + } + } + } +} + +.black-screen-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + height: 100%; + background-color: #000000 !important; + z-index: 9999999 !important; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); + + .black-screen-content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: rgba(255, 255, 255, 0.25); + text-align: center; + padding: 20px; + gap: 12px; + + .car-mode-icon { + font-size: 3.5rem; + color: rgba(255, 255, 255, 0.2); + } + + .car-mode-text { + font-size: 1.2rem; + font-weight: 600; + margin: 0; + } + + .car-mode-subtext { + font-size: 0.85rem; + margin: 0; + opacity: 0.8; + } + + .car-mode-canto-info { + text-align: center; + margin-top: 10px; + + .car-mode-canto-title { + font-size: 1.4rem; + font-weight: 700; + color: rgba(255, 255, 255, 0.3); + margin: 0 0 4px 0; + } + + .car-mode-canto-author { + font-size: 0.95rem; + color: rgba(255, 255, 255, 0.2); + margin: 0; + } + } + + .car-mode-progress { + margin-top: 8px; + + .car-mode-time { + font-size: 1.1rem; + font-weight: 600; + color: rgba(255, 255, 255, 0.25); + } + } + + .car-mode-controls { + display: flex; + align-items: center; + gap: 24px; + margin-top: 15px; + + .car-mode-btn { + --color: rgba(255, 255, 255, 0.25); + --padding-start: 8px; + --padding-end: 8px; + height: 48px; + width: 48px; + margin: 0; + + ion-icon { + font-size: 1.8rem; + } + + &:active { + --color: rgba(255, 255, 255, 0.55); + } + } + } + } +} + +.landscape-playlist-btn { + writing-mode: vertical-rl; + text-transform: uppercase; + font-weight: 700; + font-size: 0.65rem; + letter-spacing: 1px; + height: auto; + min-height: 75px; + width: 30px; + margin: 0; + --padding-start: 2px; + --padding-end: 2px; + color: var(--ion-color-secondary); + display: flex; + align-items: center; + justify-content: center; + transform: rotate(180deg); +} + + diff --git a/src/app/pages/player/player.page.spec.ts b/src/app/pages/player/player.page.spec.ts new file mode 100644 index 0000000..ef54b27 --- /dev/null +++ b/src/app/pages/player/player.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { PlayerPage } from './player.page'; + +describe('PlayerPage', () => { + let component: PlayerPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(PlayerPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/player/player.page.ts b/src/app/pages/player/player.page.ts new file mode 100644 index 0000000..a7f52aa --- /dev/null +++ b/src/app/pages/player/player.page.ts @@ -0,0 +1,1466 @@ +import { Component, OnInit, OnDestroy, signal, computed, effect, inject, ElementRef, AfterViewInit, untracked, HostListener, ViewChild } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl, Meta } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; +import { AlertController, ToastController, GestureController } from '@ionic/angular'; +import { CantiService, Canto } from '../../services/canti.service'; +import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser.service'; +import { ThemeService } from '../../services/theme.service'; +import { SettingsService } from '../../services/settings.service'; +import { ConnectivityService } from '../../services/connectivity.service'; +import { PlaylistService } from '../../services/playlist.service'; +import { YoutubePlayerService } from '../../services/youtube-player.service'; +import { MyCantiService } from '../../services/my-canti.service'; +import { ComunitaService } from '../../services/comunita.service'; +import { StatsService } from '../../services/stats.service'; +import { FaceDetectorService } from '../../services/face-detector.service'; + +@Component({ + selector: 'app-player', + templateUrl: './player.page.html', + styleUrls: ['./player.page.scss'], + host: { + '[class.landscape-active]': 'isLandscapeActive()' + }, + standalone: false +}) +export class PlayerPage implements OnInit, AfterViewInit, OnDestroy { + @ViewChild('faceVideo', { static: false }) faceVideoRef!: ElementRef; + + public canto = signal(null); + public activeSongId = signal(null); + public isTitleWrapped = signal(false); + + @HostListener('window:keydown', ['$event']) + handleKeyDown(event: KeyboardEvent) { + const target = event.target as HTMLElement; + if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)) { + return; + } + if (event.key === 'ArrowUp' || event.key === 'MediaTrackPrevious') { + this.prevSong(); + event.preventDefault(); + } else if (event.key === 'ArrowDown' || event.key === 'MediaTrackNext') { + this.nextSong(); + event.preventDefault(); + } else if (event.key === 'MediaPlayPause') { + this.toggleAudio(); + event.preventDefault(); + } else if (event.key === 'PageUp' || event.key === 'ArrowLeft') { + this.prev(true); + event.preventDefault(); + } else if (event.key === 'PageDown' || event.key === 'ArrowRight') { + this.next(false, true); + event.preventDefault(); + } + } + + private clickTimeout: any = null; + + handleLyricsClick(event: MouseEvent) { + const target = event.target as HTMLElement; + if (target && (target.closest('button') || target.closest('ion-button') || target.closest('.side-indicator') || target.closest('.autoscroll-indicator') || target.closest('ion-icon'))) { + return; + } + const selection = window.getSelection(); + if (selection && selection.toString().length > 0) { + return; + } + + // Se c'è già un click in attesa, questo è il secondo tocco (Doppio Tap) -> Torna indietro + if (this.clickTimeout) { + clearTimeout(this.clickTimeout); + this.clickTimeout = null; + this.prev(true); + return; + } + + // Altrimenti imposta un timer per il singolo tocco -> Avanza + this.clickTimeout = setTimeout(() => { + this.clickTimeout = null; + this.next(false, true); + }, 250); + } + + + private windowLandscape = signal(window.innerWidth > window.innerHeight); + + public isLandscapeActive = computed(() => { + return this.windowLandscape() && this.settingsService.landscapeProjectionEnabled(); + }); + + /** true = show chords (accordi mode), false = text only */ + public showChords = signal(false); + + /** Autoscroll standard */ + public isAutoscrolling = signal(false); + public autoscrollSpeed = signal(2); + private autoscrollTimer: any = null; + + /** Font size scale factor (1.0 = default) */ + public fontSize = signal(1.0); + + /** Parsed sections for the current view mode */ + public parsedSections = computed(() => { + const c = this.canto(); + if (!c) return []; + + let sections: ParsedSection[]; + // For local songs, if accordi is missing but testo has chords, use parseAccordi on testo + const hasChordsInText = !c.accordi && c.testo?.includes('['); + + // Force text-only mode in landscape + const activeShowChords = this.showChords() && !this.isLandscapeActive(); + + if ((activeShowChords && c.accordi) || (activeShowChords && hasChordsInText)) { + sections = this.lyricsParser.parseAccordi(c.accordi || c.testo); + } else { + sections = this.lyricsParser.parseText(c.testo); + } + + // CRITICAL FIX: If sections are empty but we have text, force a manual section + if (sections.length === 0 && c.testo) { + const fallbackLines = c.testo.split('\n') + .filter(l => l.trim().length > 0) + .map(l => ({ + text: l.trim(), + segments: [{ text: l.trim() }] + })); + + if (fallbackLines.length > 0) { + sections = [{ + type: 'verse', + lines: fallbackLines + }]; + } + } + + // Apply transposition if in chords mode + if (activeShowChords) { + return this.lyricsParser.transposeSections(sections, this.transposeAmount()); + } + + return sections; + }); + + public transposeAmount = signal(0); + + public tonality = computed(() => { + const song = this.canto(); + if (!song) return null; + const baseKey = this.lyricsParser.deduceTonality(song.accordi || song.testo || ''); + if (!baseKey) return null; + + const amount = this.transposeAmount(); + if (amount === 0) return baseKey; + return this.lyricsParser.transposeChord(baseKey, amount); + }); + + public currentLineIndex = signal(0); + public math = Math; + public youtubePlayerService = inject(YoutubePlayerService); + private channel = new BroadcastChannel('karaoke_sync'); + + // Rimossi stati di freeze fragili per garantire fluidità e stabilità 100% dell'avanzamento + + private readonly MIN_FONT = 0.6; + private readonly MAX_FONT = 5.0; + private readonly FONT_STEP = 0.15; + + public minZoom = computed(() => this.isLandscapeActive() ? 2.0 : this.MIN_FONT); + public maxZoom = computed(() => this.isLandscapeActive() ? 3.0 : this.MAX_FONT); + + private initialPinchDistance: number | null = null; + private initialFontSize: number = 1.0; + public portraitFontSize: number = 1.0; + + private lastMatchedTranscript: string = ''; + + // --- Logic State --- + private lastAdvanceTimestamp: number = 0; // For safety cooldown + private readonly ADVANCE_COOLDOWN = 1500; // 1.5 seconds min + + public lastScrollBlock = signal<'start' | 'center'>('start'); + private lastProcessedTranscript: string = ''; + private initialStartTime: number = 0; + + private route = inject(ActivatedRoute); + public router = inject(Router); + public cantiService = inject(CantiService); + public lyricsParser = inject(LyricsParserService); + private alertCtrl = inject(AlertController); + private toastCtrl = inject(ToastController); + public themeService = inject(ThemeService); + public settingsService = inject(SettingsService); + public connectivityService = inject(ConnectivityService); + public playlistService = inject(PlaylistService); + public comunitaService = inject(ComunitaService); + private myCantiService = inject(MyCantiService); + private statsService = inject(StatsService); + private gestureCtrl = inject(GestureController); + private el = inject(ElementRef); + private sanitizer = inject(DomSanitizer); + public faceDetector = inject(FaceDetectorService); + private meta = inject(Meta); + + public enableCameraNavigation = computed(() => this.settingsService.cameraNavigationActive()); + + private songStartTime: number = 0; + + constructor() { + // Sync transposition automatically to display/projection page + effect(() => { + const amount = this.transposeAmount(); + this.channel.postMessage({ type: 'SYNC_TRANSPOSE', amount }); + }); + + // Sync mode from global settings + effect(() => { + this.showChords.set(this.settingsService.showChordsDefault()); + }, { allowSignalWrites: true }); + + // Auto-scroll logic: keep active line in view + effect(() => { + const idx = this.currentLineIndex(); + // Wait for DOM update + setTimeout(() => { + const activeElem = document.querySelector('.lyric-line.active'); + if (activeElem) { + // Usa l'allineamento calcolato dinamico (start per manuale a pagine, center per automatico e standard) + // Usiamo behavior: 'auto' poiché il container CSS ha già 'scroll-behavior: smooth', evitando blocchi/conflitti nativi Chromium + const scrollBlock = this.lastScrollBlock(); + activeElem.scrollIntoView({ behavior: 'auto', block: scrollBlock }); + } + }, 100); + }); + + effect(() => { + const c = this.canto(); + if (c) { + if (this.playlistService.autoPlayPlaylist()) { + setTimeout(() => this.initPlayer(c.id), 500); + } + this.isTitleWrapped.set(false); + setTimeout(() => this.checkTitleWrap(), 150); + } + }); + + // Reactive song loading based on activeSongId and available canti lists + effect(() => { + const id = this.activeSongId(); + const allCanti = this.cantiService.canti(); + const myCantiList = this.myCantiService.myCanti(); + const comunitaCantiPers = this.comunitaService.comunitaCantiPersonali(); + + if (id) { + let found: any = null; + if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + found = comunitaCantiPers.find(c => c.id === id); + } + if (!found) { + found = allCanti.find(c => c.id === id); + } + if (!found) { + found = myCantiList.find(c => c.id === id); + } + if (!found) { + found = this.playlistService.remoteCustomSongs().find(c => c.id === id || String(c.id_canti) === id); + } + if (!found) { + found = this.playlistService.remoteShareCanti().find(c => c.id === id || String(c.id_canti) === id); + } + if (!found) { + found = comunitaCantiPers.find(c => c.id === id); + } + + if (found) { + const current = untracked(() => this.canto()); + // Avoid duplicate triggers for the same song, but update if song content changed + const contentChanged = !current || + current.id !== found.id || + current.titolo !== found.titolo || + current.autore !== found.autore || + current.link_youtube !== found.link_youtube || + current.testo !== found.testo || + current.accordi !== found.accordi || + JSON.stringify(current.id_momenti) !== JSON.stringify(found.id_momenti); + + if (contentChanged) { + this.logPreviousSongTime(); + this.canto.set(found); + this.currentLineIndex.set(0); + this.lastScrollBlock.set('start'); + this.songStartTime = Date.now(); + this.cantiService.getStorage()?.set('last_song_id', id); + this.channel.postMessage({ type: 'SYNC_CANTO', id: found.id }); + this.channel.postMessage({ type: 'SYNC_INDEX', index: 0 }); + + // Update Open Graph Image tag dynamically + const thumb = this.cantiService.getYoutubeThumb(found.link_youtube); + if (thumb) { + this.meta.updateTag({ property: 'og:image', content: thumb }); + } else { + this.meta.updateTag({ property: 'og:image', content: window.location.origin + '/assets/icon/favicon.png' }); + } + + setTimeout(() => { + const scrollEl = this.el.nativeElement.querySelector('.lyrics-container'); + if (scrollEl) { + scrollEl.scrollTop = 0; + } + this.checkLandscapeZoom(); + }, 100); + } + } + } + }, { allowSignalWrites: true }); + + // Reactive transposition and speed determination based on canto, playlists, and community settings + effect(() => { + const c = this.canto(); + if (!c) return; + + const activePlaylistId = this.playlistService.activePlaylistId(); + let playlistSongSetting: any = null; + if (activePlaylistId) { + if (activePlaylistId.startsWith('remote_')) { + const pl = this.playlistService.remotePlaylist(); + if (pl && pl.songSettings && pl.songSettings[c.id]) { + playlistSongSetting = pl.songSettings[c.id]; + } + } else { + const pl = this.playlistService.playlists().find(p => p.id === activePlaylistId); + if (pl && pl.songSettings && pl.songSettings[c.id]) { + playlistSongSetting = pl.songSettings[c.id]; + } + } + } + + if (playlistSongSetting) { + this.transposeAmount.set(playlistSongSetting.tonalita !== undefined ? playlistSongSetting.tonalita : 0); + this.autoscrollSpeed.set(playlistSongSetting.speed !== undefined ? playlistSongSetting.speed : 2); + const gZoom = this.settingsService.globalZoom(); + this.fontSize.set(gZoom); + this.portraitFontSize = gZoom; + } else if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + const settings = this.comunitaService.comunitaCantiSettings(); + const songSetting = settings.find(s => s.id_canti === c.id_canti || s.id_canti === Number(c.id)); + if (songSetting) { + if (songSetting.tonalita !== undefined) { + this.transposeAmount.set(songSetting.tonalita); + } else { + this.transposeAmount.set(0); + } + if (songSetting.speed !== undefined && songSetting.speed > 0) { + const mappedSpeed = Math.max(1, Math.min(10, Math.round(songSetting.speed / 100))); + this.autoscrollSpeed.set(mappedSpeed); + } else { + this.autoscrollSpeed.set(2); + } + } else { + this.transposeAmount.set(0); + this.autoscrollSpeed.set(2); + } + const gZoom = this.settingsService.globalZoom(); + this.fontSize.set(gZoom); + this.portraitFontSize = gZoom; + } else { + this.transposeAmount.set(0); + this.autoscrollSpeed.set(2); + const gZoom = this.settingsService.globalZoom(); + this.fontSize.set(gZoom); + this.portraitFontSize = gZoom; + } + }, { allowSignalWrites: true }); + + // Fullscreen control in landscape mode or when black screen is active + effect(() => { + const isLandscape = this.isLandscapeActive(); + const isBlack = this.isBlackScreen(); + + if (isLandscape || isBlack) { + this.enterFullscreen(); + } else { + this.exitFullscreen(); + } + }); + } + + public isBlackScreen = signal(false); + + @HostListener('window:resize', ['$event']) + onResize(event: any) { + this.windowLandscape.set(window.innerWidth > window.innerHeight); + this.checkLandscapeZoom(); + this.checkTitleWrap(); + } + + private isLandscape(): boolean { + return this.isLandscapeActive(); + } + + private checkAndLimitFontSize(targetFont: number): number { + if (!this.isLandscape()) { + return targetFont; + } + const titleMain = this.el.nativeElement.querySelector('.title-main'); + if (!titleMain) return targetFont; + + const originalStyle = titleMain.style.fontSize; + let bestFont = targetFont; + + // We want to find the largest font <= targetFont where the title stays on one line. + // Let's iterate down from targetFont to 0.6 in steps of 0.05. + for (let f = targetFont; f >= 0.6; f -= 0.05) { + titleMain.style.fontSize = `${f * 1.1}rem`; + + // Force layout calculation + const height = titleMain.clientHeight; + // Get computed line height + const computedStyle = window.getComputedStyle(titleMain); + const lineHeightVal = computedStyle.lineHeight; + let lh = parseFloat(lineHeightVal); + + // If line-height is 'normal', fallback to a reasonable estimate based on font-size + if (isNaN(lh) || lineHeightVal === 'normal') { + const fs = parseFloat(computedStyle.fontSize) || (f * 1.1 * 16); + lh = fs * 1.25; + } + + // If the actual height is less than 1.5 * line-height, it fits on one line! + if (height <= lh * 1.5) { + bestFont = f; + break; + } + bestFont = f; // Fallback + } + + // Restore original style + titleMain.style.fontSize = originalStyle; + return Math.max(0.6, parseFloat(bestFont.toFixed(2))); + } + + public checkLandscapeZoom() { + if (this.isLandscape()) { + setTimeout(() => { + const container = this.el.nativeElement.querySelector('.lyrics-container'); + if (!container) return; + const visibleHeight = container.clientHeight; + const lineElems = this.el.nativeElement.querySelectorAll('.lyric-line'); + if (lineElems.length > 0 && visibleHeight > 0) { + let totalHeight = 0; + lineElems.forEach((el: any) => { + totalHeight += el.getBoundingClientRect().height; + }); + const avgLineHeight = totalHeight / lineElems.length; + if (avgLineHeight > 0) { + const currentFont = this.fontSize(); + const margin = 16; // 1rem in pixels + const targetLineHeight = Math.max(10, (visibleHeight / 3.1) - margin); + const avgLineHeightAtFont1 = avgLineHeight / currentFont; + const newFont = targetLineHeight / avgLineHeightAtFont1; + + const targetFont = Math.max(2.0, Math.min(3.0, newFont)); + let limitedFont = this.checkAndLimitFontSize(targetFont); + if (limitedFont < 2.0) { + limitedFont = 2.0; + } + this.fontSize.set(limitedFont); + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() }); + } + } + }, 150); + } else { + this.fontSize.set(this.portraitFontSize); + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.portraitFontSize }); + } + } + + deactivateBlackScreen() { + this.isBlackScreen.set(false); + } + + private async enterFullscreen() { + try { + const docEl = document.documentElement; + if (docEl.requestFullscreen) { + await docEl.requestFullscreen(); + } else if ((docEl as any).webkitRequestFullscreen) { + await (docEl as any).webkitRequestFullscreen(); + } else if ((docEl as any).msRequestFullscreen) { + await (docEl as any).msRequestFullscreen(); + } + } catch (e) { + console.warn('[PlayerPage] Failed to enter fullscreen:', e); + } + } + + private async exitFullscreen() { + try { + if (document.exitFullscreen) { + if (document.fullscreenElement) { + await document.exitFullscreen(); + } + } else if ((document as any).webkitExitFullscreen) { + if ((document as any).webkitFullscreenElement) { + await (document as any).webkitExitFullscreen(); + } + } else if ((document as any).msExitFullscreen) { + if ((document as any).msFullscreenElement) { + await (document as any).msExitFullscreen(); + } + } + } catch (e) { + console.warn('[PlayerPage] Failed to exit fullscreen:', e); + } + } + + + checkTitleWrap() { + const el = document.querySelector('.canto-title') as HTMLElement; + if (!el) return; + + this.isTitleWrapped.set(false); + + setTimeout(() => { + if (el.scrollHeight > 30) { + this.isTitleWrapped.set(true); + } + }, 50); + } + + ngAfterViewInit() { + this.checkLandscapeZoom(); + this.checkTitleWrap(); + if (this.settingsService.cameraNavigationActive()) { + this.initCameraTracking(); + } + const gestureX = this.gestureCtrl.create({ + el: this.el.nativeElement, + direction: 'x', + gestureName: 'swipe-song-x', + canStart: (ev) => { + const target = ev.event.target as HTMLElement; + return !target.closest('ion-footer') && !target.closest('ion-header'); + }, + onEnd: (ev) => { + if (Math.abs(ev.deltaX) > 60) { + if (ev.deltaX > 0) { + // Swipe/trascinamento verso destra -> Brano precedente + this.prevSong(); + } else { + // Swipe/trascinamento verso sinistra -> Brano successivo + this.nextSong(); + } + } + } + }); + gestureX.enable(); + + } + + + private getAllLines(): any[] { + const sections = this.parsedSections(); + const allLines: any[] = []; + for (const s of sections) { + for (const l of s.lines) { + allLines.push(l); + } + } + return allLines; + } + + ngOnInit() { + this.route.queryParams.subscribe(async params => { + let id = params['id']; + if (params['t']) { + this.initialStartTime = parseInt(params['t'], 10); + } + if (!id) { + const checkStorage = async () => { + let storage = this.cantiService.getStorage(); + while (!storage) { + await new Promise(resolve => setTimeout(resolve, 50)); + storage = this.cantiService.getStorage(); + } + const storedId = await storage.get('last_song_id'); + if (storedId && !this.activeSongId()) { + this.activeSongId.set(storedId); + } + }; + checkStorage(); + } else { + this.activeSongId.set(id); + } + }); + } + + + + onTouchStart(event: TouchEvent) { + if (event.touches.length === 2) { + this.initialPinchDistance = this.getDistance(event.touches[0], event.touches[1]); + this.initialFontSize = this.fontSize(); + } + } + + onTouchMove(event: TouchEvent) { + if (event.touches.length === 2 && this.initialPinchDistance !== null) { + event.preventDefault(); + const currentDistance = this.getDistance(event.touches[0], event.touches[1]); + const ratio = currentDistance / this.initialPinchDistance; + let newSize = this.initialFontSize * ratio; + const minZ = this.minZoom(); + const maxZ = this.maxZoom(); + newSize = Math.max(minZ, Math.min(maxZ, newSize)); + let limited = this.checkAndLimitFontSize(newSize); + if (this.isLandscape() && limited < 2.0) { + limited = 2.0; + } + if (Math.abs(limited - this.fontSize()) > 0.01) { + this.fontSize.set(limited); + if (!this.isLandscape()) { + this.portraitFontSize = limited; + this.settingsService.globalZoom.set(limited); + } + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() }); + } + } + } + + onTouchEnd() { + this.initialPinchDistance = null; + this.updatePlaylistSettings(); + } + + + private getDistance(t1: Touch, t2: Touch): number { + return Math.sqrt(Math.pow(t1.clientX - t2.clientX, 2) + Math.pow(t1.clientY - t2.clientY, 2)); + } + + toggleChords() { + this.showChords.update(v => !v); + this.channel.postMessage({ type: 'SYNC_CHORDS', showChords: this.showChords() }); + this.transposeAmount.set(0); + this.checkLandscapeZoom(); + } + + private updatePlaylistSettings() { + const c = this.canto(); + if (c) { + const dbSpeed = this.autoscrollSpeed() * 100; + this.statsService.updateSongSettings(c.id_canti, this.transposeAmount(), dbSpeed); + + const activePlaylistId = this.playlistService.activePlaylistId(); + if (activePlaylistId) { + if (activePlaylistId.startsWith('remote_')) { + return; + } + this.playlistService.updatePlaylistSongSettings( + activePlaylistId, + c.id, + this.transposeAmount(), + this.autoscrollSpeed() + ); + } + } + } + + transposeUp() { + this.transposeAmount.update(v => v + 1); + this.updatePlaylistSettings(); + } + + transposeDown() { + this.transposeAmount.update(v => v - 1); + this.updatePlaylistSettings(); + } + + zoomIn() { + const maxZ = this.maxZoom(); + if (this.fontSize() < maxZ) { + const target = Math.min(this.fontSize() + this.FONT_STEP, maxZ); + let limited = this.checkAndLimitFontSize(target); + if (this.isLandscape() && limited < 2.0) { + limited = 2.0; + } + if (limited !== this.fontSize()) { + this.fontSize.set(limited); + if (!this.isLandscape()) { + this.portraitFontSize = limited; + this.settingsService.globalZoom.set(limited); + } + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() }); + this.updatePlaylistSettings(); + } + } + } + + zoomOut() { + const minZ = this.minZoom(); + if (this.fontSize() > minZ) { + const target = Math.max(this.fontSize() - this.FONT_STEP, minZ); + this.fontSize.set(target); + if (!this.isLandscape()) { + this.portraitFontSize = target; + this.settingsService.globalZoom.set(target); + } + this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() }); + this.updatePlaylistSettings(); + } + } + + toggleAudio() { + if (this.youtubePlayerService.currentCantoId() === this.canto()?.id) { + this.youtubePlayerService.togglePlayPause(); + } else { + const c = this.canto(); + if (c) { + this.playlistService.autoPlayPlaylist.set(true); + this.initPlayer(c.id); + } + } + } + + stopVideo(event?: Event) { + if (event) event.stopPropagation(); + this.youtubePlayerService.stop(); + this.playlistService.autoPlayPlaylist.set(false); + } + + onSeek(event: any) { + this.youtubePlayerService.seekTo(event.detail.value); + } + + goHome() { + this.router.navigate(['/home']); + } + + restart() { + this.currentLineIndex.set(0); + this.youtubePlayerService.seekTo(0); + this.channel.postMessage({ type: 'SYNC_INDEX', index: 0 }); + this.lastScrollBlock.set('start'); + setTimeout(() => { + const scrollEl = this.el.nativeElement.querySelector('.lyrics-container'); + if (scrollEl) { + scrollEl.scrollTop = 0; + } + }, 100); + } + + public calculatePageStepSize(): number { + try { + const container = document.querySelector('.lyrics-container') as HTMLElement; + if (!container) return 3; // Ritorno generico se il contenitore non è pronto + + const containerRect = container.getBoundingClientRect(); + const visibleTop = Math.max(containerRect.top, 0); + let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight); + + const footer = document.querySelector('ion-footer') as HTMLElement; + if (footer) { + const footerRect = footer.getBoundingClientRect(); + if (footerRect.height > 0 && window.getComputedStyle(footer).display !== 'none') { + visibleBottom = Math.min(visibleBottom, footerRect.top); + } + } + + const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement; + if (floatingBar) { + const barRect = floatingBar.getBoundingClientRect(); + if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') { + visibleBottom = Math.min(visibleBottom, barRect.top); + } + } + + // Calcoliamo la reale altezza visibile + const visibleHeight = Math.max(0, visibleBottom - visibleTop); + + const lineElems = document.querySelectorAll('.lyric-line'); + + if (lineElems.length === 0) return 3; + + let totalHeight = 0; + lineElems.forEach((el: any) => { + totalHeight += el.clientHeight; + }); + const avgLineHeight = totalHeight / lineElems.length; + + if (avgLineHeight <= 0) return 3; + + // Quante righe entrano effettivamente nella vista REALE non oscurata dello schermo + const linesPerPage = Math.floor(visibleHeight / avgLineHeight); + + // Passo di scorrimento: una pagina intera pulita (zero sovrapposizione) per far sparire il testo precedente + const pageStep = Math.max(1, linesPerPage); + + console.log('[PageScroll] Calcolo dinamico dello scorrimento a pagina (Area visibile depurata):', { + visibleHeight, + avgLineHeight, + linesPerPage, + pageStep + }); + + return pageStep; + } catch (e) { + console.warn('[PageScroll] Impossibile calcolare dinamicamente lo step di pagina:', e); + return 3; // Fallback di emergenza + } + } + + public getVisibleLineIndices(): number[] { + try { + const container = document.querySelector('.lyrics-container') as HTMLElement; + if (!container) return []; + + const containerRect = container.getBoundingClientRect(); + const visibleTop = Math.max(containerRect.top, 0); + let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight); + + // Sottrai l'altezza dell'eventuale footer o barra sovrapposti ad alto z-index + const footer = document.querySelector('ion-footer') as HTMLElement; + if (footer) { + const footerRect = footer.getBoundingClientRect(); + if (footerRect.height > 0 && window.getComputedStyle(footer).display !== 'none') { + visibleBottom = Math.min(visibleBottom, footerRect.top); + } + } + + const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement; + if (floatingBar) { + const barRect = floatingBar.getBoundingClientRect(); + if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') { + visibleBottom = Math.min(visibleBottom, barRect.top); + } + } + + const lineElems = document.querySelectorAll('.lyric-line'); + const visibleIndices: number[] = []; + + for (let i = 0; i < lineElems.length; i++) { + const el = lineElems[i] as HTMLElement; + const rect = el.getBoundingClientRect(); + + // Consideriamo la riga visibile se la sua metà verticale è all'interno dei limiti visibili reali + const lineMiddle = (rect.top + rect.bottom) / 2; + if (lineMiddle >= visibleTop && lineMiddle <= visibleBottom) { + visibleIndices.push(i); + } + } + return visibleIndices; + } catch (e) { + console.warn('[PageScroll] Errore nel recupero degli indici delle righe visibili:', e); + return []; + } + } + + private calculateNextPageStartIndex(): number { + try { + const container = document.querySelector('.lyrics-container') as HTMLElement; + if (!container) return this.currentLineIndex() + 1; + + const containerRect = container.getBoundingClientRect(); + // Assicuriamoci che il limite inferiore non superi l'altezza reale della finestra + let visibleBottom = Math.min(containerRect.bottom, window.innerHeight || document.documentElement.clientHeight); + + // Trova la posizione del footer o di qualunque elemento sovrapposto in fondo + const footer = document.querySelector('ion-footer') as HTMLElement; + if (footer) { + const footerRect = footer.getBoundingClientRect(); + if (footerRect.height > 0 && window.getComputedStyle(footer).display !== 'none') { + visibleBottom = Math.min(visibleBottom, footerRect.top); + } + } + + const floatingBar = document.querySelector('.floating-autoscroll-bar') as HTMLElement; + if (floatingBar) { + const barRect = floatingBar.getBoundingClientRect(); + if (barRect.height > 0 && window.getComputedStyle(floatingBar).display !== 'none') { + visibleBottom = Math.min(visibleBottom, barRect.top); + } + } + + // Aumentiamo il margine di tolleranza a 24px (o più) per essere sicuri + // di non perdere mai una riga parzialmente coperta. Meglio rileggere una riga + // in cima alla pagina successiva che perderla completamente a causa dello zoom. + const visibleLimitY = visibleBottom - 24; + const lineElems = document.querySelectorAll('.lyric-line'); + + const totalLines = this.getTotalLines(); + const currentIdx = this.currentLineIndex(); + + // Scansiona le righe successive a quella attiva e trova la prima riga che non era COMPLETAMENTE visibile + let foundNextIdx = -1; + for (let i = currentIdx + 1; i < lineElems.length; i++) { + const el = lineElems[i] as HTMLElement; + const rect = el.getBoundingClientRect(); + + // Se la parte inferiore della riga ricade sotto l'area di visualizzazione utile (coperta da footer/log) + if (rect.bottom > visibleLimitY) { + foundNextIdx = i; + break; + } + } + + if (foundNextIdx !== -1) { + // Overlap by 1 line to ensure the last visible line is repeated at the top of the next page + const targetIdx = Math.max(currentIdx + 1, foundNextIdx - 1); + console.log('[PageScroll] Riga coperta/tagliata in fondo rilevata. Nuova pagina inizierà con overlap a:', targetIdx); + return targetIdx; + } + + // Se tutto era perfettamente visibile, avanza dello step di pagina calcolato standard con 1 riga di overlap + const step = this.calculatePageStepSize(); + const targetIdx = Math.max(currentIdx + 1, currentIdx + step - 1); + return Math.min(totalLines - 1, targetIdx); + } catch (e) { + console.warn('[PageScroll] Errore nel calcolo dinamico dell\'indice della pagina successiva:', e); + return this.currentLineIndex() + 1; + } + } + + next(isAutomatic: boolean = false, isVisual: boolean = false) { + if (this.isBlackScreen()) { + this.deactivateBlackScreen(); + return; + } + this.lastAdvanceTimestamp = Date.now(); + + const totalLines = this.getTotalLines(); + const prevIdx = this.currentLineIndex(); + + if (prevIdx < totalLines - 1) { + let nextIdx: number; + if (isAutomatic) { + if (prevIdx === 0) { + // Sulla prima pagina, avanziamo alla metà della pagina (inizio della seconda metà) + const visibleIndices = this.getVisibleLineIndices(); + if (visibleIndices.length > 0) { + const halfLength = Math.max(1, Math.ceil(visibleIndices.length / 2)); + nextIdx = Math.min(totalLines - 1, visibleIndices[halfLength] !== undefined ? visibleIndices[halfLength] : halfLength); + } else { + const pageSize = this.calculatePageStepSize(); + const halfPageSize = Math.max(1, Math.ceil(pageSize / 2)); + nextIdx = Math.min(totalLines - 1, prevIdx + halfPageSize); + } + } else { + // Avanzamento acustico automatico: avanza l'intera pagina lasciando centrale la riga di riferimento + nextIdx = this.calculateNextPageStartIndex(); + } + this.lastScrollBlock.set('center'); + } else if ((this.settingsService.karaokePageScrollMode() || isVisual) && !this.isLandscapeActive()) { + // Modalità manuale a pagine (o trigger visuale): calcolo analitico preciso per non perdere righe coperte + nextIdx = this.calculateNextPageStartIndex(); + this.lastScrollBlock.set('start'); + } else { + // Avanzamento riga per riga standard manuale + nextIdx = prevIdx + 1; + this.lastScrollBlock.set('center'); + } + + this.currentLineIndex.set(nextIdx); + this.channel.postMessage({ type: 'SYNC_INDEX', index: nextIdx }); + } + } + + // Metodi di validazione e freeze rimossi per migliorare affidabilità e prevenire blocchi permanenti + + prev(isVisual: boolean = false) { + if (this.isBlackScreen()) { + this.deactivateBlackScreen(); + return; + } + this.lastAdvanceTimestamp = Date.now(); + + const prevIdx = this.currentLineIndex(); + if (prevIdx > 0) { + const isPageMode = (this.settingsService.karaokePageScrollMode() || isVisual) && !this.isLandscapeActive(); + const stepSize = isPageMode ? this.calculatePageStepSize() : 1; + const nextIdx = Math.max(0, prevIdx - stepSize); + + if (nextIdx === 0) { + // Se torniamo all'inizio, allineiamo in alto + this.lastScrollBlock.set('start'); + } else if (isPageMode) { + this.lastScrollBlock.set('start'); + } else { + this.lastScrollBlock.set('center'); + } + + this.currentLineIndex.set(nextIdx); + this.channel.postMessage({ type: 'SYNC_INDEX', index: nextIdx }); + } + } + + private getSequenceList(): string[] { + const currentId = this.canto()?.id; + + // 1. Homepage filtered list (includes current sorting like Top Ten, Suggeriti, and any active playlist + additional filters) + const filtered = this.playlistService.filteredListIds(); + if (filtered.length > 0) { + if (!currentId || filtered.includes(currentId)) { + return filtered; + } + } + + // 2. Active playlist raw list if present and contains current song + const active = this.playlistService.activeListIds(); + if (active.length > 0) { + if (!currentId || active.includes(currentId)) { + return active; + } + } + + // 3. Default fallback: all canti + return this.cantiService.canti().map(c => c.id); + } + + nextSong() { + const list = this.getSequenceList(); + + const currentId = this.canto()?.id; + if (!currentId) return; + + const index = list.indexOf(currentId); + if (index >= 0 && index < list.length - 1) { + const nextId = list[index + 1]; + if (this.isLandscapeActive()) { + this.isBlackScreen.set(true); + } + this.router.navigate(['/player'], { queryParams: { id: nextId }, replaceUrl: true }); + } else { + this.playlistService.autoPlayPlaylist.set(false); + } + } + + prevSong() { + const list = this.getSequenceList(); + + const currentId = this.canto()?.id; + if (!currentId) return; + + const index = list.indexOf(currentId); + if (index > 0) { + const prevId = list[index - 1]; + if (this.isLandscapeActive()) { + this.isBlackScreen.set(true); + } + this.router.navigate(['/player'], { queryParams: { id: prevId }, replaceUrl: true }); + } + } + + private goToSong(id: string) { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { id }, + queryParamsHandling: 'merge', + replaceUrl: true + }); + this.restart(); + } + + getTotalLines(): number { + return this.parsedSections().reduce((acc, s) => acc + s.lines.length, 0); + } + + isActiveLine(sectionIdx: number, lineIdx: number): boolean { + let flatIdx = 0; + for (let s = 0; s < this.parsedSections().length; s++) { + for (let l = 0; l < this.parsedSections()[s].lines.length; l++) { + if (s === sectionIdx && l === lineIdx) { + return flatIdx === this.currentLineIndex(); + } + flatIdx++; + } + } + return false; + } + + async openDisplay() { + const url = this.router.serializeUrl( + this.router.createUrlTree(['/display'], { queryParams: { id: this.canto()?.id } }) + ); + const absoluteUrl = window.location.origin + window.location.pathname + url; + const win = window.open(absoluteUrl, '_blank', 'width=1024,height=768'); + if (!win) { + const alert = await this.alertCtrl.create({ + header: 'Proiezione TV', + message: 'Il browser ha bloccato l\'apertura della finestra. Vuoi copiare il link da inviare alla TV?', + buttons: [ + { text: 'Annulla', role: 'cancel' }, + { text: 'Copia Link', handler: () => { this.copyToClipboard(absoluteUrl); } } + ] + }); + await alert.present(); + } + } + + async copyToClipboard(text: string) { + try { + await navigator.clipboard.writeText(text); + const toast = await this.toastCtrl.create({ + message: 'Link copiato negli appunti!', + duration: 2000, + position: 'top', + color: 'secondary' + }); + await toast.present(); + } catch (err) {} + } + + openYoutube() { + const videoId = this.cantiService.getYoutubeId(this.canto()?.link_youtube); + if (videoId) { + window.open(`https://www.youtube.com/watch?v=${videoId}`, '_blank'); + } + } + + async editOrCloneCanto() { + const c = this.canto(); + if (!c) return; + + if ( + this.settingsService.comunitaEnabled() && + this.settingsService.showEditor() && + this.comunitaService.comunitaCode() && + !c.id.startsWith('my_') + ) { + // Clone the song: Title: + const clonedTitle = c.titolo; + + const clonedCanto = await this.myCantiService.saveCanto({ + titolo: clonedTitle, + autore: c.autore, + link_youtube: c.link_youtube, + testo: c.testo || c.accordi || '', + accordi: c.accordi || c.testo || '', + id_momenti: c.id_momenti || [] + }); + + // Redirect to the edit page for the newly cloned song + this.router.navigate(['/propose-canto'], { queryParams: { editId: clonedCanto.id } }); + } else { + // Standard edit path + this.router.navigate(['/propose-canto'], { queryParams: { editId: c.id } }); + } + } + + async deleteMyCanto() { + const c = this.canto(); + if (!c || !c.id.startsWith('my_')) return; + const alert = await this.alertCtrl.create({ + header: 'Elimina Canto', + message: 'Sei sicuro di voler eliminare questo canto dai tuoi brani personali?', + buttons: [ + { text: 'Annulla', role: 'cancel' }, + { + text: 'Elimina', + role: 'destructive', + handler: () => { + this.myCantiService.deleteCanto(c.id); + this.router.navigate(['/home']); + } + } + ] + }); + await alert.present(); + } + + async shareCanto() { + const c = this.canto(); + if (!c) return; + + const isStandard = !c.id.startsWith('my_') && !c.id.startsWith('remote_share_') && !c.nonValidato; + + try { + let shareLink = ''; + if (isStandard) { + shareLink = `https://www.canticristiani.it/?id=${c.id}`; + } else { + await this.playlistService.syncLocalDataToServer(); + const uid = this.settingsService.userUuid(); + shareLink = `https://www.canticristiani.it/?song-uid=${uid}&song-id=${c.id_canti}`; + } + + let fileToShare: File | null = null; + const thumbUrl = this.cantiService.getYoutubeThumb(c.link_youtube); + + // Try to fetch YouTube thumbnail first if available + if (thumbUrl) { + try { + // Use images.weserv.nl as a CORS proxy to bypass YouTube's CORS policy + const proxiedUrl = `https://images.weserv.nl/?url=${encodeURIComponent(thumbUrl)}`; + const response = await Promise.race([ + fetch(proxiedUrl), + new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 3000)) + ]); + if (response.ok) { + const blob = await response.blob(); + fileToShare = new File([blob], 'song_thumbnail.jpg', { type: 'image/jpeg' }); + } + } catch (e) { + console.warn('[Share] Failed to fetch YouTube thumbnail due to CORS or timeout:', e); + } + } else { + // If no YouTube thumb is available, fallback to local canticristiani logo (favicon) + try { + const response = await fetch('assets/icon/favicon.png'); + if (response.ok) { + const blob = await response.blob(); + fileToShare = new File([blob], 'canticristiani_logo.png', { type: 'image/png' }); + } + } catch (e) { + console.warn('[Share] Failed to fetch local logo:', e); + } + } + + const shareDataObj: any = { + title: `Condividi Canto: ${c.titolo}`, + text: isStandard + ? `Ecco il canto "${c.titolo}" dall'app Canti Cristiani. Clicca sul link per aprirlo:\n\n` + : `Ecco il canto "${c.titolo}" per l'app Canti Cristiani. Clicca sul link per aggiungerlo:\n\n`, + url: shareLink + }; + + const isMac = /Macintosh|MacIntel|MacPPC|Mac68K/.test(navigator.userAgent) || + (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); + + if (!isMac && fileToShare && navigator.canShare && navigator.canShare({ files: [fileToShare] })) { + shareDataObj.files = [fileToShare]; + } + + if (navigator.share) { + await navigator.share(shareDataObj); + } else { + if (navigator.clipboard) { + await navigator.clipboard.writeText(shareLink); + const toast = await this.toastCtrl.create({ + message: 'Link di condivisione copiato negli appunti!', + duration: 2500, + color: 'success' + }); + await toast.present(); + } + } + } catch (err) { + console.error('Failed to share song', err); + } + } + + async printCanto() { + const c = this.canto(); + if (!c) return; + + const alert = await this.alertCtrl.create({ + header: 'Esporta in PDF', + message: 'Vuoi includere gli accordi nel PDF o esportare solo il testo?', + buttons: [ + { + text: 'Solo Testo', + handler: () => { + this.playlistService.printPlaylist(c.titolo, [c], false, { [c.id || c.id_canti]: this.transposeAmount() }); + } + }, + { + text: 'Testo e Accordi', + handler: () => { + this.playlistService.printPlaylist(c.titolo, [c], true, { [c.id || c.id_canti]: this.transposeAmount() }); + } + }, + { + text: 'Annulla', + role: 'cancel' + } + ] + }); + await alert.present(); + } + + private initPlayer(id: string) { + if (!this.youtubePlayerService.isPlayerSupported()) { + return; + } + const startT = this.initialStartTime; + this.initialStartTime = 0; // Reset + + this.youtubePlayerService.setMediaSessionCallbacks( + () => this.nextSong(), + () => this.prevSong() + ); + + this.youtubePlayerService.initPlayer( + id, + startT, + () => { + if (this.playlistService.autoPlayPlaylist() && this.settingsService.autoAdvance()) { + this.nextSong(); + } else { + this.playlistService.autoPlayPlaylist.set(false); + } + }, + () => { + if (this.playlistService.autoPlayPlaylist() && this.settingsService.autoAdvance()) { + setTimeout(() => this.nextSong(), 1000); + } else { + this.playlistService.autoPlayPlaylist.set(false); + } + } + ); + } + + togglePlaylistSelection() { + const c = this.canto(); + if (c) { + this.playlistService.toggleSongSelection(c.id); + } + } + + getCommunitySongNumber(canto: any): string | null { + if (!canto) return null; + if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) return null; + const cantiInfo = this.comunitaService.comunitaCantiInfo(); + const info = cantiInfo.find(x => x.id_canti === canto.id_canti || x.id_canti === Number(canto.id)); + return info && info.num_canto ? info.num_canto.toString() : null; + } + + getMySongNumber(canto: any): number { + if (!canto || !canto.id) return 0; + const index = this.myCantiService.myCanti().findIndex(c => c.id === canto.id); + return index !== -1 ? index + 1 : 0; + } + + toggleAutoscroll() { + if (this.isAutoscrolling()) { + this.stopAutoscroll(); + } else { + this.startAutoscroll(); + } + } + + startAutoscroll() { + this.isAutoscrolling.set(true); + if (this.autoscrollTimer) clearInterval(this.autoscrollTimer); + + const scrollEl = this.el.nativeElement.querySelector('.lyrics-container'); + if (!scrollEl) return; + + this.autoscrollTimer = setInterval(() => { + if (!this.isAutoscrolling()) { + clearInterval(this.autoscrollTimer); + return; + } + const step = this.autoscrollSpeed() * 0.25; + scrollEl.scrollTop += step; + }, 40); + } + + stopAutoscroll() { + this.isAutoscrolling.set(false); + if (this.autoscrollTimer) { + clearInterval(this.autoscrollTimer); + this.autoscrollTimer = null; + } + } + + increaseAutoscrollSpeed() { + this.autoscrollSpeed.update(s => Math.min(10, s + 1)); + this.updatePlaylistSettings(); + } + + decreaseAutoscrollSpeed() { + this.autoscrollSpeed.update(s => Math.max(1, s - 1)); + this.updatePlaylistSettings(); + } + + private logPreviousSongTime() { + const c = this.canto(); + if (c && this.songStartTime > 0) { + const timeSpent = (Date.now() - this.songStartTime) / 1000; + this.statsService.logSongView(c.id_canti, timeSpent); + this.songStartTime = 0; + } + } + + async recalibrateDistance(event?: Event) { + if (event) event.stopPropagation(); + this.faceDetector.resetDistanceBaseline(); + const toast = await this.toastCtrl.create({ + message: 'Distanza ricalibrata al 100%', + duration: 1500, + position: 'bottom', + color: 'secondary' + }); + await toast.present(); + } + + toggleCameraNavigation() { + if (this.settingsService.cameraNavigationActive()) { + this.stopCameraNavigation(); + } else { + this.startCameraNavigation(); + } + } + + startCameraNavigation() { + this.settingsService.cameraNavigationActive.set(true); + this.initCameraTracking(); + } + + async initCameraTracking() { + if (!this.settingsService.cameraNavigationActive()) return; + + // Usa ViewChild per trovare il video element in modo sicuro + const videoEl = this.faceVideoRef?.nativeElement || document.querySelector('#face-preview-video') as HTMLVideoElement; + if (!videoEl) { + console.error('[PlayerPage] Video element #face-preview-video not found in DOM'); + this.settingsService.cameraNavigationActive.set(false); + return; + } + + try { + await this.faceDetector.start(videoEl, (direction) => { + console.log(`[PlayerPage] Head tilt trigger received: ${direction}`); + if (direction === 'next') { + this.next(false, true); + } else { + this.prev(true); + } + }); + } catch (e: any) { + this.settingsService.cameraNavigationActive.set(false); + const errorMsg = e?.message || e?.name || (typeof e === 'object' ? JSON.stringify(e) : String(e)) || 'Errore sconosciuto'; + alert(`Impossibile accedere alla fotocamera. Assicurati di aver concesso i permessi e di usare HTTPS.\n\nDettagli errore: ${errorMsg}`); + } + } + + stopCameraNavigation() { + this.settingsService.cameraNavigationActive.set(false); + this.faceDetector.stop(); + } + + ngOnDestroy() { + if (this.clickTimeout) { + clearTimeout(this.clickTimeout); + this.clickTimeout = null; + } + this.exitFullscreen(); + this.stopAutoscroll(); + this.logPreviousSongTime(); + if (this.settingsService.cameraNavigationActive()) { + this.faceDetector.pause(); + } else { + this.faceDetector.stop(); + } + this.channel.close(); + } + + formatSeconds(seconds: number | undefined | null): string { + if (seconds === undefined || seconds === null || isNaN(seconds)) { + return '0:00'; + } + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins}:${secs < 10 ? '0' : ''}${secs}`; + } +} diff --git a/src/app/pages/playlist/playlist.module.ts b/src/app/pages/playlist/playlist.module.ts new file mode 100644 index 0000000..431f1db --- /dev/null +++ b/src/app/pages/playlist/playlist.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { PlaylistPage } from './playlist.page'; +import { RouterModule, Routes } from '@angular/router'; + +const routes: Routes = [ + { + path: '', + component: PlaylistPage + } +]; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + DragDropModule, + RouterModule.forChild(routes) + ], + declarations: [PlaylistPage] +}) +export class PlaylistPageModule {} diff --git a/src/app/pages/playlist/playlist.page.html b/src/app/pages/playlist/playlist.page.html new file mode 100644 index 0000000..94a92fa --- /dev/null +++ b/src/app/pages/playlist/playlist.page.html @@ -0,0 +1,52 @@ + + + + + + Gestione Playlist + + + + + + + + + + + + +
+
+

Trascina i canti per riordinarli. Una volta finito puoi salvare la playlist.

+
+ + {{ totalDuration }} +
+
+ +
+
+
+ +
+
+ {{ song.id.startsWith('my_') ? getMySongNumber(song) : song.id_canti }} + + {{ getCommunitySongNumber(song) }}{{ song.titolo }} + +
+
+
+
+ +
+ +

Nessun canto selezionato.

+ + Torna alla Home + +
+
+ +
diff --git a/src/app/pages/playlist/playlist.page.scss b/src/app/pages/playlist/playlist.page.scss new file mode 100644 index 0000000..0f29475 --- /dev/null +++ b/src/app/pages/playlist/playlist.page.scss @@ -0,0 +1,179 @@ +.song-list { + display: block; +} + +.song-item { + display: flex; + align-items: center; + padding: 12px; + border-radius: 12px; + cursor: move; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + + .drag-handle { + margin-right: 12px; + color: rgba(255, 255, 255, 0.3); + font-size: 1.5rem; + display: flex; + align-items: center; + } + + .song-info { + display: flex; + align-items: center; + gap: 8px; + + .canto-number { + background: rgba(var(--ion-color-secondary-rgb), 0.1); + color: var(--ion-color-secondary); + padding: 2px 6px; + border-radius: 4px; + font-size: 0.8rem; + font-weight: 700; + } + + .song-title { + font-weight: 500; + color: white; + } + } +} + +.cdk-drag-preview { + box-sizing: border-box; + border-radius: 4px; + box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), + 0 8px 10px 1px rgba(0, 0, 0, 0.14), + 0 3px 14px 2px rgba(0, 0, 0, 0.12); + background: #1e1e1e; + padding: 12px; + display: flex; + align-items: center; + color: white; +} + +.cdk-drag-placeholder { + opacity: 0; +} + +.cdk-drag-animating { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.song-list.cdk-drop-list-dragging .song-item:not(.cdk-drag-placeholder) { + transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); +} + +.header-info { + padding: 12px; + border-radius: 12px; + p { + margin: 0; + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.7); + line-height: 1.4; + } +} + +.empty-state { + margin-top: 100px; + .large-icon { + font-size: 5rem; + color: rgba(255, 255, 255, 0.1); + } + p { + color: rgba(255, 255, 255, 0.5); + margin-top: 16px; + } +} + +.qr-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.8); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + backdrop-filter: blur(5px); + + .qr-card { + background: #ffffff; + padding: 24px; + border-radius: 20px; + width: 90%; + max-width: 350px; + text-align: center; + color: #000; + + .qr-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; + h3 { margin: 0; text-align: left; } + } + + p { + font-size: 0.9rem; + color: #666; + margin-bottom: 24px; + text-align: left; + } + + .qr-img-container { + background: #f8f8f8; + padding: 16px; + border-radius: 16px; + margin-bottom: 24px; + img { + width: 100%; + height: auto; + display: block; + } + } + + .qr-actions { + display: flex; + flex-direction: column; + gap: 8px; + } + } +} + +.save-export-fab { + --border-radius: 30px; + width: auto; + min-width: 160px; + + .fab-content { + display: flex; + align-items: center; + padding: 0 16px; + gap: 8px; + + ion-icon { + font-size: 1.4rem; + } + + .fab-label { + font-size: 0.9rem; + font-weight: 600; + text-transform: none; + } + } +} + +:host-context(body.high-contrast) { + .song-item { + background: #ffffff !important; + border-color: #000000 !important; + .song-title { color: #000000 !important; } + .drag-handle { color: #000000 !important; } + } + .header-info p { color: #000000 !important; } +} diff --git a/src/app/pages/playlist/playlist.page.ts b/src/app/pages/playlist/playlist.page.ts new file mode 100644 index 0000000..8b6053a --- /dev/null +++ b/src/app/pages/playlist/playlist.page.ts @@ -0,0 +1,313 @@ +import { Component, inject, computed } from '@angular/core'; +import { PlaylistService } from '../../services/playlist.service'; +import { CantiService } from '../../services/canti.service'; +import { ComunitaService } from '../../services/comunita.service'; +import { MyCantiService } from '../../services/my-canti.service'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { AlertController, ToastController, ModalController } from '@ionic/angular'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-playlist', + templateUrl: './playlist.page.html', + styleUrls: ['./playlist.page.scss'], + standalone: false +}) +export class PlaylistPage { + public playlistService = inject(PlaylistService); + public cantiService = inject(CantiService); + public comunitaService = inject(ComunitaService); + public myCantiService = inject(MyCantiService); + private alertCtrl = inject(AlertController); + private toastCtrl = inject(ToastController); + private router = inject(Router); + + public selectedSongs = computed(() => { + const ids = Array.from(this.playlistService.selectedIds()); + const allCanti = this.cantiService.canti(); + const myCantiList = this.myCantiService.myCanti(); + const comunitaCantiPers = this.comunitaService.comunitaCantiPersonali(); + const communityActive = this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive(); + + return ids.map(id => { + let found: any = null; + if (communityActive) { + found = comunitaCantiPers.find(c => c.id === id); + } + if (!found) { + found = allCanti.find(c => c.id === id); + } + if (!found) { + found = myCantiList.find(c => c.id === id); + } + if (!found) { + found = comunitaCantiPers.find(c => c.id === id); + } + return found; + }).filter(c => !!c); + }); + + public localSongs: any[] = []; + public qrCodeImage: string | null = null; + public savedPlaylistName: string | null = null; + + get totalDuration(): string { + const songs = this.localSongs; + if (songs.length === 0) return ''; + let totalSeconds = 0; + for (const song of songs) { + if (song && song.durata) { + totalSeconds += this.parseDuration(song.durata); + } + } + if (totalSeconds === 0) return ''; + return this.formatTotalDuration(totalSeconds); + } + + private parseDuration(dur: string): number { + if (!dur) return 0; + const parts = dur.split(':').map(Number); + if (parts.some(isNaN)) return 0; + if (parts.length === 2) { + return parts[0] * 60 + parts[1]; + } else if (parts.length === 3) { + return parts[0] * 3600 + parts[1] * 60 + parts[2]; + } + return 0; + } + + private formatTotalDuration(seconds: number): string { + const hh = Math.floor(seconds / 3600); + const mm = Math.floor((seconds % 3600) / 60); + const ss = seconds % 60; + const pad = (n: number) => n.toString().padStart(2, '0'); + if (hh > 0) { + return `${pad(hh)}:${pad(mm)}:${pad(ss)}`; + } + return `${pad(mm)}:${pad(ss)}`; + } + + constructor() { + // Initial copy to allow local reordering + this.localSongs = [...this.selectedSongs()]; + } + + drop(event: CdkDragDrop) { + moveItemInArray(this.localSongs, event.previousIndex, event.currentIndex); + } + + getPlaylistSongSettings(): any { + const activeId = this.playlistService.activePlaylistId(); + if (activeId) { + const pl = this.playlistService.playlists().find(p => p.id === activeId); + return pl ? pl.songSettings : undefined; + } + return undefined; + } + + async savePlaylist() { + const alert = await this.alertCtrl.create({ + header: 'Salva Playlist', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'Nome della playlist', + value: this.savedPlaylistName || '' + } + ], + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Salva', + handler: (data) => { + if (data.name) { + this.savedPlaylistName = data.name; + this.playlistService.savePlaylist(data.name, this.localSongs.map(s => s.id), this.getPlaylistSongSettings()); + this.showToast('Playlist salvata!'); + this.router.navigate(['/settings']); + return true; + } + return false; + } + } + ] + }); + await alert.present(); + } + + async saveAndExport() { + const alert = await this.alertCtrl.create({ + header: 'Salva ed Esporta QR', + message: 'Inserisci un nome per la playlist. Verrà salvata e generato il QR Code.', + inputs: [ + { + name: 'name', + type: 'text', + placeholder: 'Nome della playlist', + value: this.savedPlaylistName || '' + } + ], + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Salva ed Esporta', + handler: async (data) => { + if (data.name) { + this.savedPlaylistName = data.name; + const ids = this.localSongs.map(s => s.id); + const songSettings = this.getPlaylistSongSettings(); + await this.playlistService.savePlaylist(data.name, ids, songSettings); + this.qrCodeImage = await this.playlistService.generateQR(ids, data.name, songSettings); + this.showToast('Playlist salvata!'); + return true; + } + return false; + } + } + ] + }); + await alert.present(); + } + + async sharePlaylist() { + if (this.localSongs.length === 0) return; + + const ids = this.localSongs.map(s => s.id); + const name = this.savedPlaylistName || 'Playlist Condivisa'; + const songSettings = this.getPlaylistSongSettings(); + this.qrCodeImage = await this.playlistService.generateQR(ids, name, songSettings); + } + + downloadQR() { + if (!this.qrCodeImage) return; + + const name = this.savedPlaylistName || 'playlist'; + const fileName = `${name.toLowerCase().replace(/\s+/g, '_')}_qr.png`; + + const link = document.createElement('a'); + link.href = this.qrCodeImage; + link.download = fileName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + this.showToast('Immagine scaricata!'); + } + + async shareQR() { + if (!this.qrCodeImage) return; + const name = this.savedPlaylistName || 'playlist'; + const songSettings = this.getPlaylistSongSettings(); + const shareLink = this.playlistService.getShareLink(this.localSongs.map(s => s.id), name, songSettings); + const fileName = `${name.toLowerCase().replace(/\s+/g, '_')}_qr.png`; + + try { + // Convert base64 to blob/file for sharing + const res = await fetch(this.qrCodeImage); + const blob = await res.blob(); + const file = new File([blob], fileName, { type: 'image/png' }); + + const isMac = /Macintosh|MacIntel|MacPPC|Mac68K/.test(navigator.userAgent) || + (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1); + + if (!isMac && navigator.share && navigator.canShare && navigator.canShare({ files: [file] })) { + await navigator.share({ + files: [file], + title: 'Playlist CantiCristiani', + text: `Ecco la playlist: ${name}\n\nClicca qui per aprirla subito: ${shareLink}` + }); + } else { + // Fallback to simple share text or download + if (navigator.share) { + await navigator.share({ + title: 'Playlist CantiCristiani', + text: `Ecco la playlist: ${name}\n\nClicca qui per aprirla: ${shareLink}` + }); + } else { + // Copy to clipboard AND download QR! + try { + if (navigator.clipboard) { + await navigator.clipboard.writeText(shareLink); + this.showToast('Link copiato negli appunti! QR scaricato.'); + } + } catch(e) {} + this.downloadQR(); + } + } + } catch (err) { + console.error('Share failed', err); + this.downloadQR(); + } + } + + closeQR() { + this.qrCodeImage = null; + } + + async showToast(message: string) { + const toast = await this.toastCtrl.create({ + message, + duration: 2000, + color: 'success' + }); + await toast.present(); + } + + getCommunitySongNumber(song: any): string | null { + if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) return null; + const cantiInfo = this.comunitaService.comunitaCantiInfo(); + const info = cantiInfo.find(x => x.id_canti === song.id_canti || x.id_canti === Number(song.id)); + return info && info.num_canto ? info.num_canto.toString() : null; + } + + getMySongNumber(song: any): number { + if (!song || !song.id) return 0; + const index = this.myCantiService.myCanti().findIndex(c => c.id === song.id); + return index !== -1 ? index + 1 : 0; + } + + async exportPlaylistPdf() { + if (this.localSongs.length === 0) return; + + const songSettings = this.getPlaylistSongSettings() || {}; + const transpositions: { [songId: string]: number } = {}; + for (const key of Object.keys(songSettings)) { + if (songSettings[key] && songSettings[key].tonalita !== undefined) { + transpositions[key] = songSettings[key].tonalita; + } + } + + const alert = await this.alertCtrl.create({ + header: 'Esporta in PDF', + message: 'Vuoi includere gli accordi nel PDF o esportare solo il testo?', + buttons: [ + { + text: 'Solo Testo', + handler: () => { + const name = this.savedPlaylistName || 'Playlist'; + this.playlistService.printPlaylist(name, this.localSongs, false, transpositions); + } + }, + { + text: 'Testo e Accordi', + handler: () => { + const name = this.savedPlaylistName || 'Playlist'; + this.playlistService.printPlaylist(name, this.localSongs, true, transpositions); + } + }, + { + text: 'Annulla', + role: 'cancel' + } + ] + }); + await alert.present(); + } +} diff --git a/src/app/pages/propose-canto/propose-canto.page.html b/src/app/pages/propose-canto/propose-canto.page.html new file mode 100644 index 0000000..1f173b9 --- /dev/null +++ b/src/app/pages/propose-canto/propose-canto.page.html @@ -0,0 +1,278 @@ + + + + + + Mio Canto + + + + + +
+
+ +

Rilascia l'immagine o il PDF qui per estrarre il testo

+
+
+ +
+ +
+ +
+

Elaborazione in corso...

+ +
+
+ + + + + Editor + + + Anteprima + + + +
+ +
+ + + Titolo del Canto + + + +
+ + Durata (mm:ss) + + + + + BPM (Tempo) + + +
+ +
+ + Momento Liturgico + + + {{ lit.tag_name }} + + + + + + Periodo / Tema + + + {{ tem.tag_name }} + + + +
+ + +
+
+ + + {{ tag.label }} + + + Fine {{ tag.label }} + + +
+
+ + +
+
+ + {{ group.root }} + +
+
+ + +
+
+ Variazioni {{ selectedRootChord }}: + + {{ chord }} + +
+
+ + +
+
+
+ Editor Testo + + +
+ + + + T:{{ transposeAmount > 0 ? '+' : '' }}{{ transposeAmount }} + + + +
+ + + + Imposta tonalità di default + +
+
+ + + + + + + + + + + + + + RAW + +
+
+
+ + +
+
+ + Autore + + + + +
+ Link YouTube & Audio Player +
+ + + Carica + +
+ + +
+ + + + + {{ formatSeconds(youtubePlayerService.videoProgress()) }} + + + {{ formatSeconds(youtubePlayerService.videoDuration()) }} +
+
+
+ +
+ + + Salva nei Miei Canti + +
+
+ + +
+
+
+ Anteprima Attiva + + + + {{ showChordsPreview ? 'Con Accordi' : 'Solo Testo' }} + +
+
+
+

{{ title || 'Titolo del Canto' }}

+

{{ author }}

+
+
+
+
+ + + + +
+ + + + {{ seg.chord }} + {{ seg.text }} + + + + + {{ line.text }} + +
+
+
+ +
+ Il testo formattato apparirà qui mentre scrivi... +
+
+
+
+
+
+
+ + + + +
diff --git a/src/app/pages/propose-canto/propose-canto.page.scss b/src/app/pages/propose-canto/propose-canto.page.scss new file mode 100644 index 0000000..09ccf10 --- /dev/null +++ b/src/app/pages/propose-canto/propose-canto.page.scss @@ -0,0 +1,845 @@ +:host { + --ion-background-color: #1a1a2e !important; + --ion-text-color: #ffffff !important; + --ion-item-background: transparent !important; + + ion-input, ion-textarea, ion-select { + --color: #ffffff !important; + color: #ffffff !important; + --placeholder-color: rgba(255, 255, 255, 0.5) !important; + } +} + +body.high-contrast :host { + --ion-background-color: #ffffff !important; + --ion-text-color: #000000 !important; + --ion-item-background: #ffffff !important; + + ion-input, ion-textarea, ion-select { + --color: #000000 !important; + color: #000000 !important; + --placeholder-color: rgba(0, 0, 0, 0.6) !important; + } + + /* Labels must be black, not teal */ + ion-label { + color: #000000 !important; + } + + /* Variations container layout in high contrast */ + .variations-container { + background: #f5f5f5 !important; + border: 1px solid #555555 !important; + } +} + +body.high-contrast :host ::ng-deep { + /* Default styles for high contrast buttons (no border by default, e.g. for fill="clear") */ + ion-button { + --background: transparent !important; + --color: #000000 !important; + --color-activated: #000000 !important; + --color-focused: #000000 !important; + --color-hover: #000000 !important; + --border-color: transparent !important; + --border-width: 0px !important; + border: none !important; + font-weight: 700 !important; + } + + /* Outlined buttons (tags, chords, action buttons) in high contrast get single gray border */ + ion-button[fill="outline"], + .main-chords-toolbar ion-button, + .variations-toolbar ion-button { + --background: #ffffff !important; + --border-color: #555555 !important; + --border-width: 1px !important; + --border-style: solid !important; + } + + /* Target specific Light-colored outlined buttons (inactive main chords) to overpower Ionic classes */ + ion-button.ion-color-light, + .main-chords-toolbar ion-button.ion-color-light, + .variations-toolbar ion-button.ion-color-light { + --background: #ffffff !important; + --color: #000000 !important; + --color-activated: #000000 !important; + --color-focused: #000000 !important; + --color-hover: #000000 !important; + --border-color: #555555 !important; + --border-width: 1px !important; + --border-style: solid !important; + color: #000000 !important; + border: none !important; + + /* OVERRIDE IONIC COLOR BASE FOR COLOR="LIGHT" OUTLINE BUTTONS */ + --ion-color-base: #000000 !important; + --ion-color-base-rgb: 0, 0, 0 !important; + } + + /* Solid buttons (active chords, save button) in high contrast */ + ion-button.button-solid, + ion-button[fill="solid"], + .send-btn { + --background: var(--ion-color-secondary) !important; + --color: #ffffff !important; + --color-activated: #ffffff !important; + --color-focused: #ffffff !important; + --color-hover: #ffffff !important; + --border-color: #555555 !important; + --border-width: 1px !important; + --border-style: solid !important; + border: none !important; + font-weight: 700 !important; + } + + /* Textarea inside high contrast must have white background and black text */ + .editor-textarea-container { + background: #ffffff !important; + border: 2px solid #000000 !important; + + textarea { + color: #000000 !important; + caret-color: #000000 !important; + } + } + + /* Force background of inputs and items to be white with single dark gray border in high contrast */ + .custom-input-item, .select-item { + --background: #ffffff !important; + border: 1px solid #555555 !important; + } +} + +.bg-gradient { + --background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); +} + +.propose-container { + max-width: 1400px; + width: 100%; + margin: 0 auto; +} + +.ocr-progress-card { + background: rgba(var(--ion-color-secondary-rgb), 0.15); + border: 1px solid var(--ion-color-secondary); + border-radius: 16px; + padding: 20px; + display: flex; + align-items: center; + gap: 16px; + margin-bottom: 20px; + box-shadow: 0 4px 15px rgba(0,0,0,0.3); + + ion-spinner { + color: var(--ion-color-secondary); + width: 32px; + height: 32px; + } + + .progress-info { + flex: 1; + p { + margin: 0; + font-size: 15px; + font-weight: 600; + color: white; + &.small { + font-size: 11px; + color: rgba(255,255,255,0.6); + margin-top: 2px; + } + } + ion-progress-bar { + margin-top: 12px; + height: 6px; + border-radius: 3px; + } + } +} + +.toolbar-section { + margin-bottom: 12px; + + .toolbar-label { + font-size: 10px; + text-transform: uppercase; + letter-spacing: 1.5px; + color: rgba(255, 255, 255, 0.5); + margin-bottom: 6px; + padding-left: 4px; + font-weight: 700; + } +} + +.horizontal-toolbar { + display: flex; + gap: 6px; + overflow-x: auto; + padding-bottom: 10px; + scrollbar-width: thin; + + &::-webkit-scrollbar { + height: 3px; + } + &::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.15); + border-radius: 2px; + } + + ion-button { + --border-radius: 10px; + margin: 0; + flex-shrink: 0; + font-size: 11px; + font-weight: 600; + } +} + +.chords-toolbar { + ion-button { + --background: rgba(255, 255, 255, 0.1); + --color: #ffffff; + border: 1px solid rgba(255,255,255,0.1); + + &:active { + --background: var(--ion-color-secondary); + } + } +} + +.editor-wrapper { + margin-bottom: 20px; + background: #000000; + border-radius: 14px; + overflow: hidden; + border: 1px solid rgba(255,255,255,0.1); + box-shadow: inset 0 2px 10px rgba(0,0,0,0.5); + + .editor-header { + background: rgba(255,255,255,0.05); + padding: 4px 8px 4px 16px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid rgba(255,255,255,0.1); + + .editor-title-group { + span { + font-size: 11px; + font-weight: 800; + color: var(--ion-color-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + } + } + + .editor-actions { + display: flex; + gap: 0; + + ion-button { + --color: rgba(255,255,255,0.6); + margin: 0; + height: 36px; + + &[disabled] { + opacity: 0.3; + } + + ion-icon { + font-size: 18px; + } + } + } + } + + &.hc { + border: 2px solid #000000; + background: #ffffff; + + .editor-header { + background: #f0f0f0; + border-bottom: 2px solid #000000; + span { color: #000000; } + small { color: #333; font-weight: 600; } + + ion-button { + --color: #000000 !important; + } + } + + .editor-textarea-container { + background: #ffffff; + + textarea { + color: #000000; + caret-color: #000000; + } + } + } +} + +:host ::ng-deep { + .editor-textarea-container { + position: relative; + width: 100%; + height: 450px; + background: #111111; + border-radius: 0 0 14px 14px; + overflow: hidden; + box-sizing: border-box; + + textarea { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: 0 !important; + padding: 16px !important; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important; + font-size: 1.05rem !important; + line-height: 1.6 !important; + color: #ffffff !important; + background: transparent !important; + width: 100%; + height: 100%; + box-sizing: border-box !important; + resize: none; + overflow-y: auto !important; + caret-color: #64ffda !important; + border: none !important; + outline: none !important; + } + } + + .category-selectors { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-bottom: 12px; + } + + .select-item { + --background: rgba(255, 255, 255, 0.08) !important; + --border-radius: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + + ion-select { + width: 100%; + --padding-start: 0; + --color: #ffffff !important; + color: #ffffff !important; + font-size: 14px; + } + } + + .custom-input-item { + --background: rgba(255, 255, 255, 0.08) !important; + --border-radius: 12px; + margin-bottom: 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + + ion-label { + color: #64ffda !important; /* High-contrast teal label */ + font-family: 'Outfit', sans-serif; + font-weight: 700; + margin-bottom: 6px !important; + font-size: 12px !important; + text-transform: uppercase; + letter-spacing: 1px; + } + + ion-input { + --color: #ffffff !important; + color: #ffffff !important; + font-weight: 500; + } + } + + .textarea-item { + --background: transparent; + --padding-start: 0; + --padding-end: 0; + } +} + +.action-buttons { + margin-top: 24px; + margin-bottom: 50px; +} + +.send-btn { + --border-radius: 16px; + --background: var(--ion-color-secondary); + font-weight: 700; + height: 60px; + font-size: 16px; + box-shadow: 0 8px 20px rgba(var(--ion-color-secondary-rgb), 0.3); +} + +/* INTERACTIVE CHORDS TOOLBAR */ +.main-chords-toolbar { + ion-button { + --border-radius: 8px; + font-weight: 700; + font-size: 13px; + min-width: 44px; + margin: 0; + } +} + +.variations-container { + background: rgba(var(--ion-color-secondary-rgb), 0.08); + border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.25); + border-radius: 12px; + padding: 8px 12px; + margin-top: 8px; + margin-bottom: 12px; + animation: fadeIn 0.2s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } +} + +.variations-toolbar { + display: flex; + align-items: center; + gap: 8px; + overflow-x: auto; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + .variations-label { + font-size: 11px; + font-weight: 700; + color: var(--ion-color-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + flex-shrink: 0; + } + + ion-button { + --background: rgba(255, 255, 255, 0.12); + --color: #ffffff; + --border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.08); + margin: 0; + font-size: 11px; + font-weight: 700; + flex-shrink: 0; + height: 28px; + + &:active { + --background: var(--ion-color-secondary); + } + } +} + +/* DRAG AND DROP OVERLAY */ +.drag-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.8); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(4px); + animation: fadeIn 0.2s ease-out; + + .drag-message { + text-align: center; + color: var(--ion-color-secondary); + background: rgba(255, 255, 255, 0.1); + border: 3px dashed var(--ion-color-secondary); + border-radius: 20px; + padding: 40px; + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + box-shadow: 0 10px 30px rgba(0,0,0,0.5); + + ion-icon { + font-size: 64px; + } + + p { + font-size: 20px; + font-weight: 700; + margin: 0; + } + } +} + +body.high-contrast :host ::ng-deep { + .drag-overlay { + background: rgba(255, 255, 255, 0.9); + .drag-message { + color: #000000; + background: #ffffff; + border: 3px dashed #000000; + } + } +} + +/* RESPONSIVE LAYOUT & ACTIVE PREVIEW PANE */ +.editor-preview-split { + display: grid; + grid-template-columns: 1fr; + gap: 24px; + align-items: flex-start; + + @media (min-width: 992px) { + grid-template-columns: 1fr 1fr; + } +} + +.preview-column { + @media (min-width: 992px) { + position: sticky; + top: 16px; + } +} + +.preview-card { + background: rgba(255, 255, 255, 0.03); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 16px; + overflow: hidden; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35); + backdrop-filter: blur(10px); + + .preview-header { + background: rgba(255, 255, 255, 0.04); + padding: 10px 16px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + + .preview-title { + font-size: 11px; + font-weight: 800; + color: var(--ion-color-secondary); + text-transform: uppercase; + letter-spacing: 0.5px; + } + + .preview-toggle-btn { + --color: rgba(255, 255, 255, 0.7); + margin: 0; + font-size: 11px; + font-weight: 600; + + ion-icon { + font-size: 14px; + } + } + } + + .preview-body { + padding: 24px; + min-height: 400px; + background: rgba(0, 0, 0, 0.2); + + .preview-song-header { + margin-bottom: 24px; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + padding-bottom: 14px; + + .preview-song-title { + font-size: 1.6rem; + font-weight: 700; + color: #ffffff; + margin: 0 0 6px 0; + font-family: 'Outfit', sans-serif; + } + + .preview-song-author { + font-size: 0.95rem; + color: rgba(255, 255, 255, 0.5); + margin: 0; + font-weight: 500; + } + } + + .preview-lyrics-container { + font-size: 1.1rem; + font-family: 'Outfit', sans-serif; + overflow-y: auto; + max-height: 60vh; + padding-right: 8px; + scrollbar-width: thin; + + &::-webkit-scrollbar { + width: 4px; + } + &::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + border-radius: 2px; + } + + .lyrics-view { + max-width: 900px; + margin-left: 0; + text-align: left; + } + + .section { + margin-bottom: 2rem; + position: relative; + + &.chorus { + background: rgba(var(--ion-color-secondary-rgb), 0.03); + border-left: 3px solid var(--ion-color-secondary); + padding-left: 1rem; + margin-left: -1rem; + border-radius: 0 8px 8px 0; + } + + .section-label { + font-size: 0.7rem; + text-transform: uppercase; + font-weight: 700; + color: var(--ion-color-secondary); + margin-bottom: 0.5rem; + opacity: 0.7; + letter-spacing: 1px; + } + } + + .lyric-line { + margin-bottom: 1rem; + line-height: 1.6; + color: rgba(255, 255, 255, 0.9); + transition: all 0.3s ease; + min-height: 1.5em; + white-space: normal; + overflow-wrap: break-word; + word-break: break-word; + letter-spacing: 3px; + } + + .chord-segment { + display: inline-flex; + flex-direction: column; + vertical-align: bottom; + margin-right: 0.25em; + + &.contiguous-next { + margin-right: 0 !important; + } + + .chord { + font-size: 0.75em; + font-weight: 700; + color: var(--ion-color-secondary); + height: 1.2em; + margin-bottom: -0.2em; + padding-right: 0.25em; + } + + .seg-text { + white-space: pre; + &::after { + content: '\200b'; + } + } + } + + .preview-empty { + color: rgba(255, 255, 255, 0.3); + text-align: center; + padding-top: 80px; + font-style: italic; + font-size: 0.95rem; + } + } + } + + /* High Contrast mode overrides */ + &.hc { + background: #ffffff; + border: 2px solid #000000; + box-shadow: none; + + .preview-header { + background: #f0f0f0; + border-bottom: 2px solid #000000; + + .preview-title { + color: #000000; + } + + .preview-toggle-btn { + --color: #000000; + font-weight: 700; + } + + .preview-transpose-group { + border-color: #000000 !important; + span { + color: #000000 !important; + } + ion-button { + --color: #000000 !important; + } + } + } + + .preview-body { + background: #ffffff; + + .preview-song-header { + border-bottom: 2px solid #000000; + + .preview-song-title { + color: #000000; + } + + .preview-song-author { + color: #333333; + } + } + + .preview-lyrics-container { + .section { + &.chorus { + background: #f5f5f5; + border-left: 3px solid #000000; + } + + .section-label { + color: #000000; + } + } + + .lyric-line { + color: #000000; + } + + .chord-segment { + .chord { + color: #000000; + text-decoration: underline; + font-weight: 800; + } + } + + .preview-empty { + color: #666666; + } + } + } + } +} + +.youtube-section { + display: flex; + flex-direction: column; + + .youtube-input-row { + ion-button { + height: 38px; + } + } +} + +/* CUSTOM STYLES FOR INTUITIVE MOBILE RESPONSIVENESS */ +.custom-mobile-segment { + display: none; + --background: rgba(255, 255, 255, 0.05); + background: rgba(255, 255, 255, 0.05); + border-radius: 12px; + padding: 4px; + border: 1px solid rgba(255, 255, 255, 0.08); + margin-bottom: 16px; + + ion-segment-button { + --color: rgba(255, 255, 255, 0.6); + --color-checked: #ffffff; + --indicator-color: var(--ion-color-secondary); + --border-radius: 8px; + font-weight: 700; + font-family: 'Outfit', sans-serif; + } +} + +body.high-contrast :host ::ng-deep { + .custom-mobile-segment { + --background: #f0f0f0 !important; + background: #f0f0f0 !important; + border: 2px solid #000000 !important; + + ion-segment-button { + --color: #333333 !important; + --color-checked: #000000 !important; + --indicator-color: #000000 !important; + } + } +} + +@media (max-width: 991px) { + .custom-mobile-segment { + display: flex; + } + + .hide-on-mobile { + display: none !important; + } + + .horizontal-toolbar { + flex-wrap: wrap; + overflow-x: visible; + padding-bottom: 0; + + ion-button { + flex-shrink: 1; + } + } +} + +@media (max-width: 576px) { + :host ::ng-deep .category-selectors { + grid-template-columns: 1fr; + gap: 8px; + } + + .editor-wrapper { + .editor-header { + padding: 6px 8px; + flex-wrap: wrap; + + .editor-title-group { + width: 100%; + margin-bottom: 6px; + padding-left: 8px; + } + + .editor-actions { + width: 100%; + display: flex; + justify-content: space-between; + + ion-button { + flex: 1; + height: 40px; + margin: 0; + } + } + } + } +} + diff --git a/src/app/pages/propose-canto/propose-canto.page.spec.ts b/src/app/pages/propose-canto/propose-canto.page.spec.ts new file mode 100644 index 0000000..afe23d8 --- /dev/null +++ b/src/app/pages/propose-canto/propose-canto.page.spec.ts @@ -0,0 +1,151 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ProposeCantoPage } from './propose-canto.page'; +import { ToastController, PopoverController, NavController, AngularDelegate, AlertController } from '@ionic/angular'; +import { CantiService } from '../../services/canti.service'; +import { MyCantiService } from '../../services/my-canti.service'; +import { PlaylistService } from '../../services/playlist.service'; +import { ThemeService } from '../../services/theme.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { LyricsParserService } from '../../services/lyrics-parser.service'; +import { of } from 'rxjs'; + +describe('ProposeCantoPage', () => { + let component: ProposeCantoPage; + let fixture: ComponentFixture; + + beforeEach(() => { + const cantiServiceMock = { + indiceLiturgico: () => [], + indiceTematico: () => [], + canti: () => [] + }; + const myCantiServiceMock = { + myCanti: () => [] + }; + const playlistServiceMock = { + remoteCustomSongs: () => [], + activePlaylistId: () => null + }; + const themeServiceMock = { + highContrast: () => false + }; + const activatedRouteMock = { + queryParams: of({}) + }; + const routerMock = { + navigate: jasmine.createSpy('navigate') + }; + const lyricsParserMock = { + parseAccordi: () => [] + }; + const navCtrlMock = {}; + const toastControllerMock = {}; + const popoverControllerMock = {}; + const alertControllerMock = {}; + const angularDelegateMock = {}; + + TestBed.configureTestingModule({ + providers: [ + { provide: CantiService, useValue: cantiServiceMock }, + { provide: MyCantiService, useValue: myCantiServiceMock }, + { provide: PlaylistService, useValue: playlistServiceMock }, + { provide: ThemeService, useValue: themeServiceMock }, + { provide: ActivatedRoute, useValue: activatedRouteMock }, + { provide: Router, useValue: routerMock }, + { provide: LyricsParserService, useValue: lyricsParserMock }, + { provide: NavController, useValue: navCtrlMock }, + { provide: ToastController, useValue: toastControllerMock }, + { provide: PopoverController, useValue: popoverControllerMock }, + { provide: AngularDelegate, useValue: angularDelegateMock }, + { provide: AlertController, useValue: alertControllerMock } + ] + }); + + fixture = TestBed.createComponent(ProposeCantoPage); + component = fixture.componentInstance; + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('convertEnglishChordToItalian', () => { + it('should convert simple English chords to Italian', () => { + expect(component.convertEnglishChordToItalian('C')).toBe('DO'); + expect(component.convertEnglishChordToItalian('D')).toBe('RE'); + expect(component.convertEnglishChordToItalian('E')).toBe('MI'); + expect(component.convertEnglishChordToItalian('F')).toBe('FA'); + expect(component.convertEnglishChordToItalian('G')).toBe('SOL'); + expect(component.convertEnglishChordToItalian('A')).toBe('LA'); + expect(component.convertEnglishChordToItalian('B')).toBe('SI'); + }); + + it('should convert English chords with accidentals and modifiers', () => { + expect(component.convertEnglishChordToItalian('C#m7')).toBe('DO#m7'); + expect(component.convertEnglishChordToItalian('Bb')).toBe('SIb'); + expect(component.convertEnglishChordToItalian('F#m')).toBe('FA#m'); + expect(component.convertEnglishChordToItalian('Faug')).toBe('FAaug'); + expect(component.convertEnglishChordToItalian('Fadd9')).toBe('FAadd9'); + }); + + it('should keep Italian chords unchanged', () => { + expect(component.convertEnglishChordToItalian('DO')).toBe('DO'); + expect(component.convertEnglishChordToItalian('RE#m7')).toBe('RE#m7'); + expect(component.convertEnglishChordToItalian('FA#')).toBe('FA#'); + expect(component.convertEnglishChordToItalian('SIb')).toBe('SIb'); + }); + + it('should handle slash chords correctly', () => { + expect(component.convertEnglishChordToItalian('C/E')).toBe('DO/MI'); + expect(component.convertEnglishChordToItalian('D/F#')).toBe('RE/FA#'); + expect(component.convertEnglishChordToItalian('F#m7/A#')).toBe('FA#m7/LA#'); + }); + }); + + describe('sanitizeOcrChord', () => { + it('should convert H to # when following a chord root', () => { + expect(component.sanitizeOcrChord('CH')).toBe('C#'); + expect(component.sanitizeOcrChord('DHm7')).toBe('D#m7'); + expect(component.sanitizeOcrChord('FH#')).toBe('F#'); + expect(component.sanitizeOcrChord('FAH')).toBe('FA#'); + expect(component.sanitizeOcrChord('SOLH7')).toBe('SOL#7'); + expect(component.sanitizeOcrChord('FH#H')).toBe('F#'); + expect(component.sanitizeOcrChord('FH#H/AH#')).toBe('F#/A#'); + expect(component.sanitizeOcrChord('C#H-')).toBe('C#-'); + expect(component.sanitizeOcrChord('G#H#')).toBe('G#'); + }); + + it('should convert 0 to O for DO and SOL roots', () => { + expect(component.sanitizeOcrChord('D0')).toBe('DO'); + expect(component.sanitizeOcrChord('D0#')).toBe('DO#'); + expect(component.sanitizeOcrChord('S0L')).toBe('SOL'); + }); + + it('should handle slash chords with sanitization', () => { + expect(component.sanitizeOcrChord('CH/EH')).toBe('C#/E#'); + expect(component.sanitizeOcrChord('D0/FH#')).toBe('DO/F#'); + }); + }); + + describe('isChordWord', () => { + it('should identify Italian and English chords correctly based on mode', () => { + expect(component.isChordWord('DO', true)).toBe(true); + expect(component.isChordWord('DO', false)).toBe(true); + expect(component.isChordWord('C', true)).toBe(false); // English chord in Italian notation -> false + expect(component.isChordWord('C', false)).toBe(true); // English chord in English notation -> true + expect(component.isChordWord('Lan', true)).toBe(true); + expect(component.isChordWord('Lan', false)).toBe(true); + }); + }); + + describe('isItalianNotation', () => { + it('should detect Italian notation if DO/RE/MI/SOL/SI are present', () => { + const words = [{ text: 'Lan' }, { text: 'FA' }, { text: 'DO' }, { text: 'SOL' }]; + expect(component.isItalianNotation(words)).toBe(true); + }); + it('should return false if only English-like or non-italian chords are present', () => { + const words = [{ text: 'C' }, { text: 'G' }, { text: 'D' }]; + expect(component.isItalianNotation(words)).toBe(false); + }); + }); +}); diff --git a/src/app/pages/propose-canto/propose-canto.page.ts b/src/app/pages/propose-canto/propose-canto.page.ts new file mode 100644 index 0000000..523a24d --- /dev/null +++ b/src/app/pages/propose-canto/propose-canto.page.ts @@ -0,0 +1,1782 @@ +import { Component, OnInit, OnDestroy, ViewChild, ElementRef, inject } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule, ToastController, IonTextarea, PopoverController, NavController, AlertController } from '@ionic/angular'; +import { createWorker } from 'tesseract.js'; +import { CantiService } from '../../services/canti.service'; +import { MyCantiService } from '../../services/my-canti.service'; +import { PlaylistService } from '../../services/playlist.service'; +import { ThemeService } from '../../services/theme.service'; +import { ActivatedRoute, RouterModule, Router } from '@angular/router'; +import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser.service'; +import { YoutubePlayerService } from '../../services/youtube-player.service'; + +@Component({ + selector: 'app-propose-canto', + templateUrl: './propose-canto.page.html', + styleUrls: ['./propose-canto.page.scss'], + standalone: true, + imports: [CommonModule, FormsModule, IonicModule, RouterModule] +}) +export class ProposeCantoPage implements OnInit, OnDestroy { + @ViewChild('nativeTextarea', { static: false }) nativeTextarea!: ElementRef; + + @ViewChild('cameraInput', { static: false }) cameraInput!: ElementRef; + @ViewChild('fileInput', { static: false }) fileInput!: ElementRef; + + public cantiService = inject(CantiService); + private myCantiService = inject(MyCantiService); + private playlistService = inject(PlaylistService); + private navCtrl = inject(NavController); + public themeService = inject(ThemeService); + private route = inject(ActivatedRoute); + private router = inject(Router); + public lyricsParser = inject(LyricsParserService); + private alertCtrl = inject(AlertController); + public youtubePlayerService = inject(YoutubePlayerService); + + showChordsPreview: boolean = true; + activeTab: string = 'editor'; + transposeAmount: number = 0; + isRawPasteModeActive: boolean = false; + + get highlightedHtml(): string { + if (!this.content) return ''; + + let escaped = this.content + .replace(/&/g, '&') + .replace(//g, '>'); + + escaped = escaped.replace(/\[([^\]]+)\]/g, (match, chord) => { + const transposed = this.transposeAmount !== 0 + ? this.lyricsParser.transposeChord(chord, this.transposeAmount) + : chord; + return `[${transposed}]`; + }); + + const lines = escaped.split('\n'); + let htmlLines: string[] = []; + let inChorus = false; + let inVerse = false; + let inVerseNum = false; + + for (const line of lines) { + const trimmed = line.trim(); + + let currentInChorus = inChorus; + let currentInVerse = inVerse; + let currentInVerseNum = inVerseNum; + + let isTagLine = false; + let processedContent = line; + + if (trimmed === '{start_chorus}' || trimmed === '{soc}') { + inChorus = true; + currentInChorus = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed === '{end_chorus}' || trimmed === '{eoc}') { + inChorus = false; + currentInChorus = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed === '{start_verse}' || trimmed === '{sov}') { + inVerse = true; + currentInVerse = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed === '{end_verse}' || trimmed === '{eov}') { + inVerse = false; + currentInVerse = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed === '{start_verse_num}') { + inVerseNum = true; + currentInVerseNum = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed === '{end_verse_num}') { + inVerseNum = false; + currentInVerseNum = true; + isTagLine = true; + processedContent = `${line}`; + } else if (trimmed.startsWith('{') && trimmed.endsWith('}')) { + isTagLine = true; + processedContent = `${line}`; + } + + let classes = ['editor-line']; + if (currentInChorus) classes.push('chorus'); + if (currentInVerse) classes.push('verse'); + if (currentInVerseNum) classes.push('verse-num'); + if (isTagLine) classes.push('tag-line'); + + const finalContent = processedContent || '​'; + htmlLines.push(`
${finalContent}
`); + } + + return htmlLines.join('\n'); + } + + + + get parsedSections(): ParsedSection[] { + const sections = this.lyricsParser.parseAccordi(this.content); + if (this.showChordsPreview && this.transposeAmount !== 0) { + return this.lyricsParser.transposeSections(sections, this.transposeAmount); + } + return sections; + } + + transposeUp() { + this.transposeAmount = (this.transposeAmount + 1) > 12 ? -11 : this.transposeAmount + 1; + } + + transposeDown() { + this.transposeAmount = (this.transposeAmount - 1) < -12 ? 11 : this.transposeAmount - 1; + } + + setDefaultTonalita() { + if (this.transposeAmount === 0 || !this.content) return; + const chordRegex = /\[([^\]]+)\]/g; + this.content = this.content.replace(chordRegex, (match, chord) => { + const transposed = this.lyricsParser.transposeChord(chord, this.transposeAmount); + return `[${transposed}]`; + }); + this.transposeAmount = 0; + } + + isAudioLoaded(): boolean { + return !!this.youtubeLink && this.cantiService.getYoutubeId(this.youtubeLink) !== null; + } + + loadedYoutubeLink: string = ''; + + loadEditorAudio() { + if (!this.youtubeLink) return; + const videoId = this.cantiService.getYoutubeId(this.youtubeLink); + if (videoId) { + this.youtubePlayerService.initPlayer(this.editId || 'editing_song', 0, undefined, undefined, this.youtubeLink); + this.loadedYoutubeLink = this.youtubeLink; + } + } + + togglePlayPause() { + const currentId = this.editId || 'editing_song'; + const isLoaded = this.youtubePlayerService.currentCantoId() === currentId && this.loadedYoutubeLink === this.youtubeLink; + if (!isLoaded && this.youtubeLink) { + this.loadEditorAudio(); + } else { + this.youtubePlayerService.togglePlayPause(); + } + } + + onSeek(event: any) { + const value = event.detail.value; + this.youtubePlayerService.seekTo(value); + } + + formatSeconds(seconds: number): string { + if (isNaN(seconds)) return '0:00'; + const mins = Math.floor(seconds / 60); + const secs = Math.floor(seconds % 60); + return `${mins}:${secs < 10 ? '0' : ''}${secs}`; + } + + toggleChordsPreview() { + this.showChordsPreview = !this.showChordsPreview; + } + + title: string = ''; + author: string = ''; + youtubeLink: string = ''; + selectedLiturgico: number[] = []; + selectedTematico: number[] = []; + durata: string = ''; + bpm: number | null = null; + + get sortedLiturgico() { + return [...this.cantiService.indiceLiturgico()].sort((a, b) => a.tag_name.localeCompare(b.tag_name)); + } + + get sortedTematico() { + return [...this.cantiService.indiceTematico()].sort((a, b) => a.tag_name.localeCompare(b.tag_name)); + } + + editId: string | null = null; + + private _content: string = ''; + get content(): string { return this._content; } + set content(val: string) { + if (this._content !== val) { + this.saveToUndoStack(this._content); + this._content = val; + } + } + + undoStack: string[] = []; + isProcessingOCR: boolean = false; + ocrProgress: number = 0; + isDraggingOver: boolean = false; + get isHighContrast(): boolean { return this.themeService.highContrast(); } + + groupedChords = [ + { + root: 'DO', + chords: ['DO', 'DO-', 'DO#', 'DO#-', 'DO7', 'DO-7', 'DO4'] + }, + { + root: 'RE', + chords: ['RE', 'RE-', 'RE#', 'RE#-', 'RE7', 'RE-7', 'RE4'] + }, + { + root: 'MI', + chords: ['MI', 'MI-', 'MI7', 'MI-7', 'MI4'] + }, + { + root: 'FA', + chords: ['FA', 'FA-', 'FA#', 'FA#-', 'FA7', 'FA-7', 'FA4'] + }, + { + root: 'SOL', + chords: ['SOL', 'SOL-', 'SOL#', 'SOL#-', 'SOL7', 'SOL-7', 'SOL4'] + }, + { + root: 'LA', + chords: ['LA', 'LA-', 'LA#', 'LA#-', 'LA7', 'LA-7', 'LA4'] + }, + { + root: 'SI', + chords: ['SI', 'SI-', 'SI7', 'SI-7', 'SI4'] + } + ]; + + selectedRootChord: string | null = null; + + selectRoot(root: string) { + if (this.selectedRootChord === root) { + this.selectedRootChord = null; + } else { + this.selectedRootChord = root; + } + } + + getVariations(): string[] { + if (!this.selectedRootChord) return []; + const group = this.groupedChords.find(g => g.root === this.selectedRootChord); + return group ? group.chords : []; + } + + commonTags = [ + { label: 'Ritornello', start: '{start_chorus}', end: '{end_chorus}' }, + { label: 'Strofa', start: '{start_verse}', end: '{end_verse}' }, + { label: 'Strofa Num.', start: '{start_verse_num}', end: '{end_verse_num}' }, + { label: 'Inciso', start: '{start_bridge}', end: '{end_bridge}' }, + { label: 'Intro Accordi', start: '{start_chord}', end: '{end_chord}' }, + { label: 'Commento', start: '{c: ', end: '}' }, + { label: 'ChordPro Strofa', start: '{sov}', end: '{eov}' }, + { label: 'ChordPro Rit.', start: '{soc}', end: '{eoc}' } + ]; + + constructor(private toastController: ToastController, private popoverController: PopoverController) { } + + ngOnInit() { + this.route.queryParams.subscribe(params => { + const editId = params['editId']; + if (editId) { + this.editId = editId; + // Find the song in standard canti, personal canti, or remote custom canti list + const song = [ + ...this.cantiService.canti(), + ...this.myCantiService.myCanti(), + ...this.playlistService.remoteCustomSongs(), + ...this.playlistService.remoteShareCanti() + ].find(c => c.id === editId); + + if (song) { + this.title = song.titolo; + this.author = song.autore || ''; + this.youtubeLink = song.link_youtube || ''; + this.content = song.accordi || song.testo || ''; + this.durata = song.durata || ''; + this.bpm = song.bpm !== undefined ? song.bpm : null; + + // Pre-populate liturgico and tematico lists + const litIds = this.cantiService.indiceLiturgico().map(m => m.id); + const temIds = this.cantiService.indiceTematico().map(m => m.id); + + this.selectedLiturgico = song.id_momenti?.filter((id: number) => litIds.includes(id)) || []; + this.selectedTematico = song.id_momenti?.filter((id: number) => temIds.includes(id)) || []; + } + } + }); + } + + ngOnDestroy() { + this.youtubePlayerService.stop(); + } + + async insertText(tag: string) { + const input = this.nativeTextarea.nativeElement; + const start = input.selectionStart || 0; + const end = input.selectionEnd || 0; + + this.content = this.content.substring(0, start) + tag + this.content.substring(end); + + setTimeout(() => { + input.focus(); + input.setSelectionRange(start + tag.length, start + tag.length); + }, 10); + } + + insertChord(chord: string) { + this.insertText(`[${chord}]`); + } + + toggleRawPasteMode() { + this.isRawPasteModeActive = !this.isRawPasteModeActive; + + // Show a toast indicating whether the Raw Paste mode has been activated or deactivated + this.toastController.create({ + message: this.isRawPasteModeActive + ? 'Modalità Incolla Raw ATTIVA: incolla liberamente senza filtri' + : 'Modalità Incolla Raw DISATTIVA: i filtri automatici sono attivi', + duration: 2500, + color: this.isRawPasteModeActive ? 'warning' : 'primary' + }).then(toast => toast.present()); + } + + undo() { + if (this.undoStack.length > 0) { + const previous = this.undoStack.pop(); + if (previous !== undefined) { + this._content = previous; + } + } + } + + private saveToUndoStack(val: string) { + if (this.undoStack.length >= 30) { + this.undoStack.shift(); + } + this.undoStack.push(val); + } + + takePhoto() { + this.cameraInput.nativeElement.click(); + } + + chooseFile() { + this.fileInput.nativeElement.click(); + } + + async deduceChords() { + if (!this.content) return; + + // Salva nello stack degli undo + this.saveToUndoStack(this.content); + + const lines = this.content.split('\n'); + + interface SectionLine { + originalIndex: number; + text: string; + } + + interface Section { + type: 'verse' | 'chorus' | 'other'; + startTag: string | null; + endTag: string | null; + lines: SectionLine[]; + hasChords: boolean; + } + + const sections: Section[] = []; + let currentSection: Section = { type: 'other', startTag: null, endTag: null, lines: [], hasChords: false }; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const trimmed = line.trim(); + + const startMatch = trimmed.match(/^\{(start_verse|start_chorus|start_verse_num|sov|soc)\}/); + const endMatch = trimmed === '{end_verse}' || trimmed === '{eov}' || trimmed === '{end_chorus}' || trimmed === '{eoc}' || trimmed === '{end_verse_num}'; + + if (startMatch) { + if (currentSection.lines.length > 0 || currentSection.startTag) { + sections.push(currentSection); + } + let type: 'verse' | 'chorus' | 'other' = 'other'; + const tag = startMatch[1]; + if (tag === 'start_verse' || tag === 'start_verse_num' || tag === 'sov') { + type = 'verse'; + } else if (tag === 'start_chorus' || tag === 'soc') { + type = 'chorus'; + } + currentSection = { type, startTag: line, endTag: null, lines: [], hasChords: false }; + } else if (endMatch) { + currentSection.endTag = line; + sections.push(currentSection); + currentSection = { type: 'other', startTag: null, endTag: null, lines: [], hasChords: false }; + } else { + if (trimmed === '' && !currentSection.startTag) { + if (currentSection.lines.length > 0) { + sections.push(currentSection); + } + sections.push({ type: 'other', startTag: null, endTag: null, lines: [{ originalIndex: i, text: '' }], hasChords: false }); + currentSection = { type: 'other', startTag: null, endTag: null, lines: [], hasChords: false }; + } else { + const hasChords = /\[[^\]]+\]/.test(line); + if (hasChords) { + currentSection.hasChords = true; + } + if (currentSection.lines.length === 0 && !currentSection.startTag && trimmed !== '') { + currentSection.type = 'verse'; + } + const isComment = trimmed.startsWith('{c:') || trimmed.startsWith('{comment:'); + if (!isComment) { + currentSection.lines.push({ originalIndex: i, text: line }); + } + } + } + } + if (currentSection.lines.length > 0 || currentSection.startTag) { + sections.push(currentSection); + } + + const templateVerse = sections.find(s => s.type === 'verse' && s.hasChords); + const templateChorus = sections.find(s => s.type === 'chorus' && s.hasChords); + + let deducedCount = 0; + + const getWords = (text: string) => { + const words: { text: string; start: number; end: number }[] = []; + const regex = /\S+/g; + let match; + while ((match = regex.exec(text)) !== null) { + words.push({ + text: match[0], + start: match.index, + end: match.index + match[0].length + }); + } + return words; + }; + + const alignChords = (templateLine: string, targetLine: string): string => { + if (/\[[^\]]+\]/.test(targetLine)) { + return targetLine; + } + + const parsedTemplate = this.lyricsParser.parseChordLine(templateLine); + const templateClean = parsedTemplate.text; + const targetClean = targetLine.replace(/\[[^\]]*\]/g, ''); + + if (!templateClean.trim() || !targetClean.trim()) { + return targetLine; + } + + const chords: { chord: string; charIndex: number }[] = []; + let charAcc = 0; + parsedTemplate.segments.forEach(seg => { + if (seg.chord) { + chords.push({ chord: seg.chord, charIndex: charAcc }); + } + charAcc += seg.text.length; + }); + + if (chords.length === 0) { + return targetLine; + } + + const templateWords = getWords(templateClean); + const targetWords = getWords(targetClean); + + const insertions: { chord: string; index: number }[] = []; + + chords.forEach(c => { + const ratio = c.charIndex / Math.max(1, templateClean.length); + const wordIdx = templateWords.findIndex(w => Math.abs(w.start - c.charIndex) <= 1); + + let targetIndex = 0; + if (wordIdx !== -1 && templateWords.length > 1 && targetWords.length > 1) { + const wRatio = wordIdx / (templateWords.length - 1); + const targetWIdx = Math.round(wRatio * (targetWords.length - 1)); + targetIndex = targetWords[targetWIdx].start; + } else { + targetIndex = Math.round(ratio * targetClean.length); + } + + insertions.push({ chord: c.chord, index: targetIndex }); + }); + + insertions.sort((a, b) => b.index - a.index); + + let result = targetClean; + insertions.forEach(ins => { + result = result.substring(0, ins.index) + `[${ins.chord}]` + result.substring(ins.index); + }); + + return result; + }; + + const newLines = [...lines]; + + sections.forEach(sec => { + if (!sec.hasChords && sec.type !== 'other') { + const template = sec.type === 'verse' ? templateVerse : templateChorus; + if (template) { + for (let j = 0; j < sec.lines.length; j++) { + const targetSecLine = sec.lines[j]; + if (j < template.lines.length) { + const templateSecLine = template.lines[j]; + const aligned = alignChords(templateSecLine.text, targetSecLine.text); + if (aligned !== targetSecLine.text) { + newLines[targetSecLine.originalIndex] = aligned; + deducedCount++; + } + } + } + } + } + }); + + if (deducedCount > 0) { + this.content = newLines.join('\n'); + const toast = await this.toastController.create({ + message: `Accordi dedotti con successo in ${deducedCount} righe!`, + duration: 3000, + color: 'success' + }); + toast.present(); + } else { + const toast = await this.toastController.create({ + message: 'Nessuna strofa compatibile trovata o accordi già presenti.', + duration: 3000, + color: 'warning' + }); + toast.present(); + } + } + + onDragOver(event: DragEvent) { + event.preventDefault(); + event.stopPropagation(); + + // Mostra l'overlay solo se si sta trascinando un file + if (event.dataTransfer?.types.includes('Files')) { + this.isDraggingOver = true; + } + } + + onDragLeave(event: DragEvent) { + event.preventDefault(); + event.stopPropagation(); + this.isDraggingOver = false; + } + + async onDrop(event: DragEvent) { + event.preventDefault(); + event.stopPropagation(); + this.isDraggingOver = false; + + if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) { + const file = event.dataTransfer.files[0]; + const isPdf = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf'); + if (file.type.indexOf('image') !== -1 || isPdf) { + await this.processFile(file); + } else { + const toast = await this.toastController.create({ + message: 'Per favore, trascina un file immagine o PDF valido.', + duration: 3000, + color: 'warning' + }); + toast.present(); + } + } + } + + async onFileSelected(event: any, isCamera: boolean) { + const file = event.target.files[0]; + if (!file) { + console.log('[OCR-Capture] Nessun file selezionato.'); + return; + } + await this.processFile(file); + event.target.value = ''; + } + + async onPaste(event: ClipboardEvent) { + if (this.isRawPasteModeActive) { + // In raw paste mode, we let the browser handle paste natively with no processing + return; + } + const items = event.clipboardData?.items; + if (!items) return; + + let hasImage = false; + for (let i = 0; i < items.length; i++) { + if (items[i].type.indexOf('image') !== -1) { + hasImage = true; + event.preventDefault(); // Prevent pasting the image representation as text + const blob = items[i].getAsFile(); + if (blob) { + const file = new File([blob], 'pasted-image.png', { type: blob.type }); + await this.processFile(file); + } + break; + } + } + + if (!hasImage) { + const pastedText = event.clipboardData?.getData('text'); + if (pastedText && this.looksLikeChordSheetOrSong(pastedText)) { + event.preventDefault(); + const parsed = this.parsePastedChordSheet(pastedText); + this.insertText(parsed); + } + } + } + + isTextLineChords(line: string, isItalian: boolean): boolean { + const trimmed = line.trim(); + if (!trimmed) return false; + const tokens = trimmed.split(/\s+/); + let chordCount = 0; + let nonChordWordCount = 0; + + for (const token of tokens) { + let clean = token.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + if (this.isChordWord(clean, isItalian)) { + chordCount++; + } else { + if (clean.length > 4) { + nonChordWordCount++; + } + } + } + + if (tokens.length === 0) return false; + const ratio = chordCount / tokens.length; + return ratio >= 0.6 && nonChordWordCount === 0; + } + + getSectionType(line: string): 'chorus' | 'verse' | 'intro' | 'none' { + const trimmed = line.trim(); + if (/^(ritornello|rit|chorus|refrain|coro)/i.test(trimmed)) { + return 'chorus'; + } + if (/^(verso|strofa|verse|strophe|\d+(\.)?)/i.test(trimmed)) { + return 'verse'; + } + if (/^(intro|introduzione|bridge|special|outro|strum)/i.test(trimmed)) { + return 'intro'; + } + return 'none'; + } + + looksLikeChordSheetOrSong(text: string): boolean { + const lines = text.split('\n'); + if (lines.length < 2) return false; + + const words = text.split(/\s+/).map(t => ({ text: t })); + const isItalian = this.isItalianNotation(words); + + let chordLinesCount = 0; + let sectionMarkersCount = 0; + + for (const line of lines) { + if (this.getSectionType(line) !== 'none') { + sectionMarkersCount++; + } + if (this.isTextLineChords(line, isItalian)) { + chordLinesCount++; + } + } + + return chordLinesCount > 0 || sectionMarkersCount > 0; + } + + convertPureChordLine(line: string, isItalian: boolean): string { + return line.replace(/\S+/g, (match) => { + let clean = match.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + if (this.isChordWord(clean, isItalian)) { + return `[${this.convertEnglishChordToItalian(clean, isItalian)}]`; + } + return match; + }); + } + + parsePastedChordSheet(text: string): string { + const lines = text.split('\n'); + const processedLines: string[] = []; + + const words = text.split(/\s+/).map(t => ({ text: t })); + const isItalian = this.isItalianNotation(words); + + let inVerse = false; + let inChorus = false; + let hasAccumulatedLines = false; + + const closeSection = () => { + if (inChorus) { + processedLines.push('{end_chorus}'); + inChorus = false; + } + if (inVerse) { + processedLines.push('{end_verse}'); + inVerse = false; + } + hasAccumulatedLines = false; + }; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const trimmed = line.trim(); + + if (!trimmed) { + if (hasAccumulatedLines) { + closeSection(); + processedLines.push(''); + } + continue; + } + + const sectionType = this.getSectionType(line); + if (sectionType !== 'none') { + closeSection(); + if (sectionType === 'chorus') { + processedLines.push('{start_chorus}'); + inChorus = true; + } else { + processedLines.push('{start_verse}'); + inVerse = true; + } + continue; + } + + // If no section is open, open a default one (verse) + if (!inChorus && !inVerse) { + processedLines.push('{start_verse}'); + inVerse = true; + } + + // Check if this line is chords + const isChords = this.isTextLineChords(line, isItalian); + + if (isChords) { + // Look ahead to see if the next line is lyrics (not empty, not chords, not section marker) + let nextLine = ''; + let nextLineIndex = i + 1; + while (nextLineIndex < lines.length) { + const nextTrimmed = lines[nextLineIndex].trim(); + if (nextTrimmed) { + if (this.getSectionType(lines[nextLineIndex]) === 'none' && !this.isTextLineChords(lines[nextLineIndex], isItalian)) { + nextLine = lines[nextLineIndex]; + } + break; + } + nextLineIndex++; + } + + if (nextLine) { + // Merge spatially! + const chords: { text: string; index: number }[] = []; + const regex = /\S+/g; + let match: RegExpExecArray | null; + while ((match = regex.exec(line)) !== null) { + let clean = match[0].toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + if (this.isChordWord(clean, isItalian)) { + chords.push({ + text: `[${this.convertEnglishChordToItalian(clean, isItalian)}]`, + index: match.index + }); + } else { + chords.push({ + text: match[0], + index: match.index + }); + } + } + + // Merge chords with the next line (lyrics) + let merged = ''; + let lyricIdx = 0; + let chordIdx = 0; + while (lyricIdx < nextLine.length || chordIdx < chords.length) { + if (chordIdx < chords.length && (lyricIdx === chords[chordIdx].index || lyricIdx >= nextLine.length)) { + merged += chords[chordIdx].text; + chordIdx++; + } else { + merged += nextLine[lyricIdx]; + lyricIdx++; + } + } + + processedLines.push(merged); + hasAccumulatedLines = true; + + // Skip the next line since we consumed it + i = nextLineIndex; + } else { + // No lyrics line follows, just convert chords in place + processedLines.push(this.convertPureChordLine(line, isItalian)); + hasAccumulatedLines = true; + } + } else { + // Plain text line + processedLines.push(this.wrapChords(line, this.getChordRegex(isItalian), isItalian)); + hasAccumulatedLines = true; + } + } + + closeSection(); + + return processedLines.join('\n'); + } + + async convertPdfToImages(file: File): Promise { + console.log('[OCR-Capture] Caricamento PDF per conversione in immagini...'); + const pdfjsLib = await import('pdfjs-dist'); + pdfjsLib.GlobalWorkerOptions.workerSrc = 'assets/pdf.worker.min.js'; + + const arrayBuffer = await file.arrayBuffer(); + const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer }); + const pdf = await loadingTask.promise; + + console.log(`[OCR-Capture] PDF caricato con successo. Numero di pagine: ${pdf.numPages}`); + const blobs: Blob[] = []; + + // Limit to maximum 5 pages to avoid extreme memory consumption or timeouts + const pagesToRender = Math.min(pdf.numPages, 5); + for (let i = 1; i <= pagesToRender; i++) { + console.log(`[OCR-Capture] Rendering pagina ${i}/${pagesToRender}...`); + const page = await pdf.getPage(i); + const viewport = page.getViewport({ scale: 2.0 }); // High resolution scale for OCR + + const canvas = document.createElement('canvas'); + canvas.width = viewport.width; + canvas.height = viewport.height; + + const ctx = canvas.getContext('2d'); + if (!ctx) { + throw new Error('Impossibile ottenere il context 2D per il canvas.'); + } + + await page.render({ + canvasContext: ctx, + viewport: viewport, + canvas: canvas + }).promise; + + const blob = await new Promise((resolve) => { + canvas.toBlob(b => resolve(b), 'image/jpeg', 0.95); + }); + + if (blob) { + blobs.push(blob); + } + } + + return blobs; + } + + async processFile(file: File) { + const isPdf = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf'); + console.log(`[OCR-Capture] File selezionato: nome="${file.name}", tipo="${file.type}", dimensione=${(file.size / (1024 * 1024)).toFixed(2)} MB, è PDF: ${isPdf}`); + + this.isProcessingOCR = true; + this.ocrProgress = 0; + + try { + if (isPdf) { + const pageBlobs = await this.convertPdfToImages(file); + console.log(`[OCR-Capture] PDF convertito in ${pageBlobs.length} immagini.`); + + for (let idx = 0; idx < pageBlobs.length; idx++) { + const pageBlob = pageBlobs[idx]; + const pageFile = new File([pageBlob], `page_${idx + 1}.jpg`, { type: 'image/jpeg' }); + console.log(`[OCR-Capture] Elaborazione pagina ${idx + 1}/${pageBlobs.length} via OCR...`); + + this.ocrProgress = (idx / pageBlobs.length); + const extractedText = await this.processImageOCR(pageFile); + + if (extractedText) { + console.log(`[OCR-Capture] Pagina ${idx + 1} estratta con successo.`); + this.content += (this.content ? '\n\n' : '') + extractedText; + } + } + + const toast = await this.toastController.create({ + message: 'Scansione PDF completata!', + duration: 2000, + color: 'success' + }); + toast.present(); + + } else { + console.log('[OCR-Capture] Immagine/Fotocamera rilevata. Avvio ridimensionamento...'); + const compressedBlob = await this.resizeImage(file); + const compressedFile = new File([compressedBlob], file.name, { type: 'image/jpeg' }); + console.log(`[OCR-Capture] Dimensioni dopo compressione: ${(compressedFile.size / 1024).toFixed(1)} KB`); + + console.log('[OCR-Capture] Avvio motore Tesseract OCR local...'); + const extractedText = await this.processImageOCR(compressedFile); + + if (extractedText) { + console.log('[OCR-Capture] Testo estratto con successo! Inserimento nell\'editor...'); + this.content += (this.content ? '\n\n' : '') + extractedText; + const toast = await this.toastController.create({ + message: 'Scansione completata!', + duration: 2000, + color: 'success' + }); + toast.present(); + } else { + console.warn('[OCR-Capture] Nessun testo estratto dal file.'); + } + } + } catch (error) { + console.error('[OCR-Capture] Errore durante l\'elaborazione del file:', error); + const errorToast = await this.toastController.create({ + message: 'Errore durante la scansione del file.', + duration: 3000, + color: 'danger' + }); + errorToast.present(); + } finally { + this.isProcessingOCR = false; + this.ocrProgress = 0; + } + } + + async resizeImage(file: File): Promise { + console.log('[OCR-Capture] Caricamento immagine in memoria...'); + return new Promise((resolve, reject) => { + const img = new Image(); + img.onload = () => { + console.log(`[OCR-Capture] Immagine caricata in memoria. Dimensioni originali: ${img.width}x${img.height}`); + const canvas = document.createElement('canvas'); + const maxDim = 1200; + let width = img.width; + let height = img.height; + + if (width > maxDim || height > maxDim) { + if (width > height) { + height = Math.round((height * maxDim) / width); + width = maxDim; + } else { + width = Math.round((width * maxDim) / height); + height = maxDim; + } + } + + console.log(`[OCR-Capture] Ridimensionamento a: ${width}x${height}`); + canvas.width = width; + canvas.height = height; + const ctx = canvas.getContext('2d'); + if (ctx) { + ctx.drawImage(img, 0, 0, width, height); + canvas.toBlob(blob => { + if (blob) { + console.log('[OCR-Capture] Compressione in JPEG completata con successo.'); + resolve(blob); + } else { + reject(new Error('Canvas toBlob failed')); + } + }, 'image/jpeg', 0.85); + } else { + reject(new Error('Canvas getContext 2d failed')); + } + }; + img.onerror = (err) => { + console.error('[OCR-Capture] Impossibile caricare l\'immagine in memoria:', err); + reject(err); + }; + img.src = URL.createObjectURL(file); + }); + } + + async processImageOCR(file: File): Promise { + console.log('[OCR-Capture] Inizializzazione Worker Tesseract.js...'); + const worker = await createWorker('ita', 1, { + logger: m => { + if (m.status === 'recognizing text') { + this.ocrProgress = m.progress; + console.log(`[OCR-Capture] Progresso OCR: ${(m.progress * 100).toFixed(0)}%`); + } + } + }); + console.log('[OCR-Capture] Avvio riconoscimento caratteri (OCR) con blocks abilitato...'); + const { data } = await worker.recognize(file, {}, { blocks: true }); + console.log('[OCR-Capture] Riconoscimento caratteri terminato. Spegnimento worker...'); + await worker.terminate(); + console.log('[OCR-Capture] Spegnimento worker completato. Estrazione parole...'); + + // Flatten blocks hierarchy to get a flat words list + const words: any[] = []; + if (data && (data as any).blocks) { + const blocks = (data as any).blocks; + blocks.forEach((block: any) => { + if (block.paragraphs) { + block.paragraphs.forEach((paragraph: any) => { + if (paragraph.lines) { + paragraph.lines.forEach((line: any) => { + if (line.words) { + line.words.forEach((word: any) => { + words.push(word); + }); + } + }); + } + }); + } + }); + } + + console.log(`[OCR-Capture] Parole estratte dal blocco gerarchico: ${words.length}`); + return this.parseSongSpatially(words); + } + + sanitizeOcrChord(text: string): string { + if (!text) return text; + + // First, heal separators like I, 1, l, |, \ between chords/notes to '/' + const separatorRegex = /\b([A-G]|DO|RE|MI|FA|SOL|LA|SI)(#|b|♭)?(m|min|maj|dim|aug|sus)?(\d*)([I1l|\\\/])([A-G]|DO|RE|MI|FA|SOL|LA|SI|\d+)(#|b|♭)?\b/gi; + text = text.replace(separatorRegex, (match, p1, p2, p3, p4, sep, p5, p6) => { + return `${p1}${p2 || ''}${p3 || ''}${p4 || ''}/${p5}${p6 || ''}`; + }); + + if (text.includes('/')) { + return text.split('/').map(part => this.sanitizeOcrChord(part.trim())).join('/'); + } + let cleaned = text; + // Replace D0/d0 with DO/do + cleaned = cleaned.replace(/^D0/gi, 'DO'); + // Replace S0L/s0l with SOL/sol + cleaned = cleaned.replace(/^S0L/gi, 'SOL'); + // Clean H/sharp mismatches: + cleaned = cleaned.replace(/H#/gi, '#'); + cleaned = cleaned.replace(/#H/gi, '#'); + cleaned = cleaned.replace(/([CDEFGAB]|DO|RE|MI|FA|SOL|LA|SI)H/gi, '$1#'); + // Clean duplicate sharps (e.g. ## -> #) + cleaned = cleaned.replace(/##+/g, '#'); + + // Clean duplicate chord letters at start (e.g. Ff#m -> F#m) + cleaned = cleaned.replace(/^([CDEFGAB])\1/gi, '$1'); + + // Convert Italian chords ending in 'M' or 'N' (e.g. LAM -> LAm, LAN -> LAm, LAN7 -> LAm7) to lowercase 'm' + cleaned = cleaned.replace(/\b(DO|RE|MI|FA|SOL|LA|SI)(#|b|♭)?[mMnN](\d*)\b/g, (match, p1, p2, p3) => { + return p1 + (p2 || '') + 'm' + (p3 || ''); + }); + + return cleaned; + } + + getChordRegex(isItalian: boolean): RegExp { + if (isItalian) { + return /^(DO|RE|MI|FA|SOL|LA|SI)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(DO|RE|MI|FA|SOL|LA|SI|\d+)(#|B|b)?)?$/i; + } else { + return /^(DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B|\d+)(#|B|b)?)?$/i; + } + } + + getMultiChordRegex(isItalian: boolean): RegExp { + if (isItalian) { + return /((?:DO|RE|MI|FA|SOL|LA|SI)(?:#|B)?(?:MIN|MAJ|AUG|DIM|M|-|4|5|6)?(?:7|9|11|13)?(?:\/(?:DO|RE|MI|FA|SOL|LA|SI|\d+)(?:#|B|b)?)?)/gi; + } else { + return /((?:DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B)(?:#|B)?(?:MIN|MAJ|AUG|DIM|M|-|4|5|6)?(?:7|9|11|13)?(?:\/(?:DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B|\d+)(?:#|B|b)?)?)/gi; + } + } + + isItalianNotation(words: any[]): boolean { + if (!words || words.length === 0) return false; + + // 1. Group words into horizontal lines + const heights = words.map(w => w.bbox ? (w.bbox.y1 - w.bbox.y0) : 10); + const avgHeight = heights.reduce((sum, h) => sum + h, 0) / heights.length; + const verticalTolerance = avgHeight * 1.0; + + const lines: any[][] = []; + words.forEach(word => { + if (!word.text) return; + const wordYCenter = word.bbox ? ((word.bbox.y0 + word.bbox.y1) / 2) : 0; + let added = false; + for (const line of lines) { + const avgLineYCenter = line.reduce((sum, w) => sum + (w.bbox ? ((w.bbox.y0 + w.bbox.y1) / 2) : 0), 0) / line.length; + if (Math.abs(wordYCenter - avgLineYCenter) < verticalTolerance) { + line.push(word); + added = true; + break; + } + } + if (!added) { + lines.push([word]); + } + }); + + const genericChordRegex = /^(DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B|\d+)(#|B|b)?)?$/i; + let englishChordsCount = 0; + let italianChordsCount = 0; + + lines.forEach(line => { + let chordCount = 0; + line.forEach(w => { + let clean = w.text.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + if (genericChordRegex.test(clean)) { + chordCount++; + } + }); + + const ratio = line.length > 0 ? chordCount / line.length : 0; + if (ratio >= 0.5) { + line.forEach(w => { + let clean = w.text.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + + const isEnglish = /^(C|D|E|F|G|A|B)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(C|D|E|F|G|A|B|\d+)(#|B|b)?)?$/i.test(clean); + const isItalian = /^(DO|RE|MI|FA|SOL|LA|SI)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(DO|RE|MI|FA|SOL|LA|SI|\d+)(#|B|b)?)?$/i.test(clean); + + if (isEnglish && !isItalian) { + englishChordsCount++; + } else if (isItalian && !isEnglish) { + italianChordsCount++; + } + }); + } + }); + + if (englishChordsCount === 0 && italianChordsCount === 0) { + // Fallback: search the entire words list for unambiguous chords + words.forEach(w => { + if (!w.text) return; + let clean = w.text.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + + const isUnambiguousEnglish = + /^(C|D|G|B)(#|B)?(M|-|MIN|MAJ|AUG|DIM|4|5|6)?(7|9|11|13)?(\/(C|D|E|F|G|A|B|\d+)(#|B|b)?)?$/i.test(clean) || + /^(A|E|F)(#|B|M|-|MIN|MAJ|AUG|DIM|4|5|6|7|9|11|13)/i.test(clean); + const isUnambiguousItalian = + /^(DO|RE|MI|FA|SOL|LA|SI)(#|B|M|-|MIN|MAJ|AUG|DIM|4|5|6|7|9|11|13)/i.test(clean); + + if (isUnambiguousEnglish) englishChordsCount++; + if (isUnambiguousItalian) italianChordsCount++; + }); + } + + console.log(`[OCR-Capture] Chord line analysis - English chords: ${englishChordsCount}, Italian chords: ${italianChordsCount}`); + return italianChordsCount > englishChordsCount; + } + + isChordWord(text: string, isItalian: boolean, allowLowercase: boolean = false): boolean { + if (!text || text.length === 0) return false; + const lower = text.toLowerCase(); + // Skip common valid words written purely in lowercase unless allowLowercase is true + if (!allowLowercase && text[0] === lower[0] && ['la', 'mi', 're', 'do', 'si', 'fa', 'e'].includes(lower)) { + return false; + } + let clean = text.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + const chordRegex = this.getChordRegex(isItalian); + if (clean.includes('_')) { + const parts = clean.split('_').filter(p => p.length > 0); + if (parts.length === 0) return false; + return parts.every(p => chordRegex.test(p)); + } + return chordRegex.test(clean); + } + + convertEnglishChordToItalian(chord: string, isItalian: boolean = false): string { + if (isItalian) return chord; + if (!chord) return chord; + if (chord.includes('/')) { + return chord.split('/').map(part => this.convertEnglishChordToItalian(part.trim(), isItalian)).join('/'); + } + const upper = chord.toUpperCase(); + if (upper.startsWith('DO')) { + return chord; + } + if (upper.startsWith('FA')) { + if (upper.startsWith('FAUG') || upper.startsWith('FADD') || upper.startsWith('FALT')) { + return 'FA' + chord.slice(1); + } + return chord; + } + if (upper.startsWith('C')) { + return 'DO' + chord.slice(1); + } + if (upper.startsWith('D')) { + return 'RE' + chord.slice(1); + } + if (upper.startsWith('E')) { + return 'MI' + chord.slice(1); + } + if (upper.startsWith('F')) { + return 'FA' + chord.slice(1); + } + if (upper.startsWith('G')) { + return 'SOL' + chord.slice(1); + } + if (upper.startsWith('A')) { + return 'LA' + chord.slice(1); + } + if (upper.startsWith('B')) { + return 'SI' + chord.slice(1); + } + return chord; + } + + isLabelLine(text: string): boolean { + return /^(Intro|Strofa|Rit|Special|Coro|Bridge|RIT|CHORUS|VERSE)/i.test(text.trim()); + } + + parseSongSpatially(words: any[]): string { + if (!words || words.length === 0) { + console.warn('[OCR-Capture] Nessuna parola ricevuta dall\'OCR.'); + return ''; + } + + const isItalian = this.isItalianNotation(words); + console.log(`[OCR-Capture] Rilevata notazione italiana: ${isItalian}`); + + // Preprocess words to split run-together chords like BA + const preprocessedWords: any[] = []; + words.forEach(w => { + if (!w.text) return; + const match = w.text.match(/^([ABCDEFG])([ABCDEFG])$/i); + if (match && !(match[1].toUpperCase() === 'F' && match[2].toUpperCase() === 'A')) { + const charWidth = (w.bbox.x1 - w.bbox.x0) / 2; + preprocessedWords.push({ + text: match[1], + bbox: { ...w.bbox, x1: w.bbox.x0 + charWidth } + }); + preprocessedWords.push({ + text: match[2], + bbox: { ...w.bbox, x0: w.bbox.x0 + charWidth } + }); + } else { + preprocessedWords.push(w); + } + }); + words = preprocessedWords; + + console.log(`[OCR-Capture] Parole totali ricevute dall'OCR: ${words.length}`); + const validWords = words.filter(w => w.text && w.text.trim().length > 0); + console.log(`[OCR-Capture] Parole valide dopo filtraggio: ${validWords.length}`); + if (validWords.length === 0) return ''; + + // Calculate average word height to set vertical tolerance + const heights = validWords.map(w => w.bbox.y1 - w.bbox.y0); + const avgHeight = heights.reduce((sum, h) => sum + h, 0) / heights.length; + const verticalTolerance = avgHeight * 1.0; + console.log(`[OCR-Capture] Altezza media carattere: ${avgHeight.toFixed(1)}px, tolleranza verticale: ${verticalTolerance.toFixed(1)}px`); + + // 2. Group words into horizontal lines + const lines: any[][] = []; + validWords.forEach(word => { + const wordYCenter = (word.bbox.y0 + word.bbox.y1) / 2; + let added = false; + for (const line of lines) { + const avgLineYCenter = line.reduce((sum, w) => sum + (w.bbox.y0 + w.bbox.y1) / 2, 0) / line.length; + if (Math.abs(wordYCenter - avgLineYCenter) < verticalTolerance) { + line.push(word); + added = true; + break; + } + } + if (!added) { + lines.push([word]); + } + }); + + // Sort words horizontally in each line + lines.forEach(line => line.sort((a, b) => a.bbox.x0 - b.bbox.x0)); + + // Sort all lines vertically by average y0 + lines.sort((a, b) => { + const avgA = a.reduce((sum, w) => sum + w.bbox.y0, 0) / a.length; + const avgB = b.reduce((sum, w) => sum + w.bbox.y0, 0) / b.length; + return avgA - avgB; + }); + + // 3. Classify lines as Chords vs. Text + const chordRegex = this.getChordRegex(isItalian); + + const classifiedLines = lines.map(line => { + let chordCount = 0; + let hasLongNonChord = false; + + line.forEach(w => { + if (this.isChordWord(w.text, isItalian, true)) { + chordCount++; + } else { + const clean = w.text.replace(/[.,:;!\?]/g, '').trim(); + if (clean.length > 5) { + hasLongNonChord = true; + } + } + }); + + const ratio = line.length > 0 ? chordCount / line.length : 0; + let isChords = false; + + if (ratio >= 0.4 && line.length <= 10) { + if (!hasLongNonChord || ratio >= 0.75) { + isChords = true; + } + } + + return { + words: line, + isChords: isChords, + yCenter: line.reduce((sum, w) => sum + (w.bbox.y0 + w.bbox.y1)/2, 0) / line.length + }; + }); + + // 4. Merge chords and text lines + const processedLines: string[] = []; + let inChorus = false; + let inVerse = false; + const chorusStartRegex = /^(R:|Rit\.|Rit|Ritornello|Coro)/i; + + for (let i = 0; i < classifiedLines.length; i++) { + const current = classifiedLines[i]; + + if (current.isChords) { + const next = (i + 1 < classifiedLines.length) ? classifiedLines[i + 1] : null; + const nextText = next ? next.words.map(w => w.text).join(' ') : ''; + if (next && !next.isChords && !this.isLabelLine(nextText)) { + // Merge spatially! + const merged = this.mergeChordsAndLyrics(current.words, next.words, isItalian); + const lineText = next.words.map(w => w.text).join(' '); + const isChorus = chorusStartRegex.test(lineText); + + if (isChorus) { + if (inVerse) { processedLines.push('{end_verse}'); inVerse = false; } + if (!inChorus) { processedLines.push('{start_chorus}'); inChorus = true; } + } else if (!inChorus && !inVerse && lineText.length > 5) { + processedLines.push('{start_verse}'); + inVerse = true; + } + + processedLines.push(merged); + i++; // Skip next line because we consumed it! + } else { + // Chord line but no text below it: just wrap and print + const multiChordRegex = this.getMultiChordRegex(isItalian); + const expandedChords: string[] = []; + current.words.forEach(w => { + const parts = w.text.split(/(_)/); + const processedParts = parts.map((part: string) => { + if (part === '_') return ' _ '; + if (!part.trim()) return part; + + let cleanText = part.toUpperCase().replace(/\s+/g, ''); + cleanText = cleanText.replace(/\((.*?)\)/g, '/$1'); + cleanText = cleanText.replace(/[\.\,]$/g, ''); + cleanText = this.sanitizeOcrChord(cleanText); + + if (this.isChordWord(cleanText, isItalian)) { + return `[${this.convertEnglishChordToItalian(cleanText, isItalian)}]`; + } else { + const matches = [...cleanText.matchAll(multiChordRegex)]; + const fullMatchStr = matches.map(m => m[0]).join(''); + if (matches.length > 0 && fullMatchStr === cleanText) { + return matches.map((m: any) => `[${this.convertEnglishChordToItalian(m[0].toUpperCase(), isItalian)}]`).join(' '); + } else { + return part; + } + } + }); + expandedChords.push(processedParts.join('')); + }); + const wrapped = expandedChords.join(' '); + if (wrapped) { + processedLines.push(wrapped); + } + } + } else { + const lineText = current.words.map(w => w.text).join(' '); + const isChorus = chorusStartRegex.test(lineText); + + if (isChorus) { + if (inVerse) { processedLines.push('{end_verse}'); inVerse = false; } + if (!inChorus) { processedLines.push('{start_chorus}'); inChorus = true; } + } else if (!inChorus && !inVerse && lineText.length > 5) { + processedLines.push('{start_verse}'); + inVerse = true; + } + + processedLines.push(this.wrapChords(lineText, chordRegex, isItalian)); + } + + // If we see a large vertical gap, close open blocks + const lastProcessedLine = classifiedLines[i]; + const currentNext = (i + 1 < classifiedLines.length) ? classifiedLines[i + 1] : null; + if (currentNext && lastProcessedLine) { + const gap = currentNext.yCenter - lastProcessedLine.yCenter; + if (gap > avgHeight * 3.5) { + if (inChorus) { processedLines.push('{end_chorus}'); inChorus = false; } + if (inVerse) { processedLines.push('{end_verse}'); inVerse = false; } + processedLines.push(''); + } + } + } + + if (inChorus) processedLines.push('{end_chorus}'); + if (inVerse) processedLines.push('{end_verse}'); + + return processedLines.join('\n'); + } + + mergeChordsAndLyrics(chordWords: any[], textWords: any[], isItalian: boolean = false): string { + // Pre-process chordWords to merge fragmented bass notes like 'Re', '(f', 'fa#)' + let mergedChordWords: any[] = []; + for (let i = 0; i < chordWords.length; i++) { + let cw = chordWords[i]; + if (cw.text.startsWith('(') && mergedChordWords.length > 0) { + let prev = mergedChordWords[mergedChordWords.length - 1]; + prev.text += cw.text; + prev.bbox.x1 = Math.max(prev.bbox.x1, cw.bbox.x1); + if (!prev.text.includes(')')) { + let j = i + 1; + while (j < chordWords.length) { + prev.text += chordWords[j].text; + prev.bbox.x1 = Math.max(prev.bbox.x1, chordWords[j].bbox.x1); + if (chordWords[j].text.includes(')')) { + i = j; + break; + } + j++; + } + } + } else { + let text = cw.text; + let bbox = { ...cw.bbox }; + if (text.includes('(') && !text.includes(')')) { + let j = i + 1; + while (j < chordWords.length) { + text += chordWords[j].text; + bbox.x1 = Math.max(bbox.x1, chordWords[j].bbox.x1); + if (chordWords[j].text.includes(')')) { + i = j; + break; + } + j++; + } + } + mergedChordWords.push({ text, bbox }); + } + } + + // Sanitize common OCR errors in chords (e.g., 'Re(f fa#)' -> 'Re(fa#)') + mergedChordWords.forEach(cw => { + cw.text = cw.text.replace(/f\s*fa#/gi, 'fa#'); + cw.text = cw.text.replace(/ff/gi, 'f'); + cw.text = cw.text.replace(/m\s*mi/gi, 'mi'); + cw.text = cw.text.replace(/mm/gi, 'm'); + }); + + if (!textWords || textWords.length === 0) { + return mergedChordWords.map(c => { + const parts = c.text.split(/(_)/); + return parts.map((part: string) => { + if (part === '_') return ' _ '; + if (!part.trim()) return part; + let clean = part.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + clean = this.sanitizeOcrChord(clean); + if (this.isChordWord(part, isItalian, true)) { + return `[${this.convertEnglishChordToItalian(clean, isItalian)}]`; + } else { + return part; + } + }).join(''); + }).join(' '); + } + + const multiChordRegex = this.getMultiChordRegex(isItalian); + + const expandedChordWords: any[] = []; + mergedChordWords.forEach(chord => { + const parts = chord.text.split(/(_)/); + let currentX = chord.bbox.x0; + const totalLen = chord.text.length || 1; + const widthPerChar = (chord.bbox.x1 - chord.bbox.x0) / totalLen; + + parts.forEach((part: string) => { + const partLen = part.length; + const partWidth = partLen * widthPerChar; + const partX0 = currentX; + const partX1 = currentX + partWidth; + currentX = partX1; + + if (part === '_' || !part.trim()) { + return; + } + + let originalText = part.toUpperCase().replace(/\s+/g, '').replace(/\((.*?)\)/g, '/$1').replace(/[\.\,\[\]]/g, ''); + originalText = this.sanitizeOcrChord(originalText); + const matches = [...originalText.matchAll(multiChordRegex)]; + + if (matches.length === 0) { + expandedChordWords.push({ + text: originalText, + bbox: { ...chord.bbox, x0: partX0, x1: partX1 } + }); + } else { + const fullMatchStr = matches.map(m => m[0]).join(''); + if (fullMatchStr === originalText) { + const matchCharWidth = (partX1 - partX0) / Math.max(1, originalText.length); + matches.forEach(match => { + const matchIndex = match.index!; + const matchLength = match[0].length; + const newX0 = partX0 + matchIndex * matchCharWidth; + const newX1 = partX0 + (matchIndex + matchLength) * matchCharWidth; + + expandedChordWords.push({ + text: match[0], + bbox: { ...chord.bbox, x0: newX0, x1: newX1 } + }); + }); + } else { + expandedChordWords.push({ + text: originalText, + bbox: { ...chord.bbox, x0: partX0, x1: partX1 } + }); + } + } + }); + }); + + const chordAssignments = new Map(); + + expandedChordWords.forEach(chord => { + const chordX = (chord.bbox.x0 + chord.bbox.x1) / 2; + let closestWord: any = null; + let minDistance = Infinity; + + textWords.forEach(textWord => { + let dist = 0; + if (chordX < textWord.bbox.x0) { + dist = textWord.bbox.x0 - chordX; + } else if (chordX > textWord.bbox.x1) { + dist = chordX - textWord.bbox.x1; + } + + if (dist < minDistance) { + minDistance = dist; + closestWord = textWord; + } + }); + + if (closestWord) { + if (!chordAssignments.has(closestWord)) { + chordAssignments.set(closestWord, []); + } + chordAssignments.get(closestWord)!.push(chord); + } + }); + + let result = ''; + + textWords.forEach((textWord, index) => { + const assignedChords = chordAssignments.get(textWord) || []; + assignedChords.sort((a, b) => a.bbox.x0 - b.bbox.x0); + + const wordText = textWord.text; + let charWidth = (textWord.bbox.x1 - textWord.bbox.x0) / Math.max(1, wordText.length); + if (charWidth <= 0) charWidth = 6; // safe fallback + + let lastCharIndex = 0; + let wordResult = ''; + + assignedChords.forEach(chord => { + const chordX = (chord.bbox.x0 + chord.bbox.x1) / 2; + let charIndex = Math.round((chordX - textWord.bbox.x0) / charWidth); + + if (charIndex < 0) charIndex = 0; + if (charIndex > wordText.length) charIndex = wordText.length; + + let cleanChord = chord.text.replace(/[\(\)\[\]]/g, '').toUpperCase(); + cleanChord = this.sanitizeOcrChord(cleanChord); + if (this.isChordWord(chord.text, isItalian, true)) { + wordResult += wordText.substring(lastCharIndex, charIndex) + `[${this.convertEnglishChordToItalian(cleanChord, isItalian)}]`; + } else { + wordResult += wordText.substring(lastCharIndex, charIndex); + } + lastCharIndex = charIndex; + }); + + wordResult += wordText.substring(lastCharIndex); + result += wordResult; + + if (index < textWords.length - 1) { + result += ' '; + } + }); + + let finalResult = result.replace(/\]\[/g, '] ['); + finalResult = finalResult.replace(/\]_\[/g, '] _ ['); + finalResult = finalResult.replace(/\]_/g, '] _ '); + finalResult = finalResult.replace(/_\[/g, ' _ ['); + // Normalize any duplicate spaces around underscores: + finalResult = finalResult.replace(/\s*_\s*/g, ' _ '); + + console.log(`[OCR-Debug] Linea generata: ${finalResult}`); + + return finalResult; + } + + + + smartProcessOCR(text: string): string { + let lines = text.split('\n'); + let processedLines: string[] = []; + + const words = text.split(/\s+/).map(t => ({ text: t })); + const isItalian = this.isItalianNotation(words); + const chordRegex = isItalian + ? /(DO|RE|MI|FA|SOL|LA|SI)(#|b)?(m|-|min|maj|aug|dim)?(7|9|11|13)?/i + : /(DO|RE|MI|FA|SOL|LA|SI|C|D|E|F|G|A|B)(#|b)?(m|-|min|maj|aug|dim)?(7|9|11|13)?/i; + let inChorus = false; + let inVerse = false; + + lines.forEach((line) => { + let trimmed = line.trim(); + if (!trimmed) { + if (inChorus) { processedLines.push('{end_chorus}'); inChorus = false; } + if (inVerse) { processedLines.push('{end_verse}'); inVerse = false; } + processedLines.push(''); + return; + } + + const isChorusMarker = /^(Rit|Ritornello|Chorus|CORO)/i.test(trimmed); + if (isChorusMarker && !inChorus) { + if (inVerse) { processedLines.push('{end_verse}'); inVerse = false; } + processedLines.push('{start_chorus}'); + inChorus = true; + if (trimmed.length > 12) processedLines.push(this.wrapChords(trimmed, chordRegex, isItalian)); + } else { + if (!inVerse && !inChorus && trimmed.length > 5) { + processedLines.push('{start_verse}'); + inVerse = true; + } + processedLines.push(this.wrapChords(trimmed, chordRegex, isItalian)); + } + }); + + if (inChorus) processedLines.push('{end_chorus}'); + if (inVerse) processedLines.push('{end_verse}'); + return processedLines.join('\n'); + } + + private wrapChords(line: string, regex: RegExp, isItalian: boolean): string { + let source = regex.source.replace(/^\^/, '').replace(/\$$/, ''); + if (!source.startsWith('\\b')) source = '\\b' + source; + if (!source.endsWith('\\b')) source = source + '\\b'; + const globalRegex = new RegExp(source, 'gi'); + const parts = line.split(/(_)/); + return parts.map((part: string) => { + if (part === '_') return ' _ '; + return part.replace(globalRegex, (match) => { + const lower = match.toLowerCase(); + if (['a', 'e', 'o', 'i'].includes(lower)) { + return match; + } + if (['la', 'mi', 're', 'do', 'si', 'fa', 'sol'].includes(lower)) { + return match; + } + const sanitized = this.sanitizeOcrChord(match.toUpperCase()); + return `[${this.convertEnglishChordToItalian(sanitized, isItalian)}]`; + }); + }).join(''); + } + + + + async saveToMyCanti() { + if (!this.title || !this.content) return; + + // Automatically convert any [LAM]/[LAN], [REM]/[REN] etc. to [LAm], [REm] in content before saving + this.content = this.content.replace(/\[(DO|RE|MI|FA|SOL|LA|SI)(#|b|♭)?[mMnN](\d*)\]/g, (match, p1, p2, p3) => { + return `[${p1}${p2 || ''}m${p3 || ''}]`; + }); + + await this.proceedSaveToMyCanti(); + } + + private async proceedSaveToMyCanti() { + // Combine lit and tematico for id_momenti + const id_momenti = [...this.selectedLiturgico, ...this.selectedTematico]; + + const activePlaylistId = this.playlistService.activePlaylistId(); + const isRemotePlaylist = activePlaylistId && activePlaylistId.startsWith('remote_'); + + if (isRemotePlaylist) { + // 1. Clone the song (generate a brand new my_... ID) + const savedCanto = await this.myCantiService.saveCanto({ + titolo: this.title, + autore: this.author, + link_youtube: this.youtubeLink, + testo: this.content, + accordi: this.content, + id_momenti: id_momenti, + durata: this.durata || undefined, + bpm: this.bpm !== null && this.bpm !== undefined && !isNaN(Number(this.bpm)) ? Number(this.bpm) : undefined + }); + + // 2. Clone/convert remote playlist to local personal playlist + const remotePl = this.playlistService.remotePlaylist(); + if (remotePl) { + const originalIds = remotePl.ids || []; + const updatedIds = originalIds.map((id: string) => id === this.editId ? savedCanto.id : id); + + const songSettings = { ...(remotePl.songSettings || {}) }; + if (this.editId && songSettings[this.editId]) { + songSettings[savedCanto.id] = { ...songSettings[this.editId] }; + delete songSettings[this.editId]; + } + + const localName = remotePl.name.replace('[Remote] ', ''); + + // Force save as a new local playlist + this.playlistService.activePlaylistId.set(null); + await this.playlistService.savePlaylist(localName, updatedIds, songSettings); + } + + // Navigate to the player with the new cloned song ID immediately + this.router.navigate(['/player'], { queryParams: { id: savedCanto.id }, replaceUrl: true }); + } else { + // Standard path + const savedCanto = await this.myCantiService.saveCanto({ + id: this.editId || undefined, + titolo: this.title, + autore: this.author, + link_youtube: this.youtubeLink, + testo: this.content, + accordi: this.content, // Save to both fields for compatibility + id_momenti: id_momenti, + durata: this.durata || undefined, + bpm: this.bpm !== null && this.bpm !== undefined && !isNaN(Number(this.bpm)) ? Number(this.bpm) : undefined + }); + + if (this.editId && !this.editId.startsWith('my_') && savedCanto && savedCanto.id) { + await this.playlistService.replaceSongIdInPlaylists(this.editId, savedCanto.id); + } + + if (this.editId && this.editId.startsWith('remote_share_')) { + await this.playlistService.deleteRemoteShareCanto(this.editId); + } + + if (this.editId && savedCanto && savedCanto.id && this.editId !== savedCanto.id) { + this.router.navigate(['/player'], { queryParams: { id: savedCanto.id }, replaceUrl: true }); + } else { + this.navCtrl.back(); + } + } + } +} diff --git a/src/app/pages/settings/settings-routing.module.ts b/src/app/pages/settings/settings-routing.module.ts new file mode 100644 index 0000000..c91d0d3 --- /dev/null +++ b/src/app/pages/settings/settings-routing.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { SettingsPage } from './settings.page'; + +const routes: Routes = [ + { + path: '', + component: SettingsPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class SettingsPageRoutingModule {} diff --git a/src/app/pages/settings/settings.module.ts b/src/app/pages/settings/settings.module.ts new file mode 100644 index 0000000..955bab3 --- /dev/null +++ b/src/app/pages/settings/settings.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; +import { SettingsPageRoutingModule } from './settings-routing.module'; +import { SettingsPage } from './settings.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + SettingsPageRoutingModule + ], + declarations: [SettingsPage] +}) +export class SettingsPageModule {} diff --git a/src/app/pages/settings/settings.page.html b/src/app/pages/settings/settings.page.html new file mode 100644 index 0000000..c68bb0e --- /dev/null +++ b/src/app/pages/settings/settings.page.html @@ -0,0 +1,507 @@ + + + + + + Impostazioni + + + + +
+ + +
+ + + +

Installa Applicazione

+

Aggiungi {{ appName }} alla schermata home

+
+ + Installa + +
+
+ + +
+ + + +

Installazione su iPhone / iPad

+

Scopri come aggiungere l'app sulla home

+
+ +
+ +
+

+ Apple non consente l'installazione automatica dei siti web. Segui questi semplici passi da Safari: +

+
    +
  1. + Tocca il pulsante di Condivisione nella barra di navigazione inferiore di Safari. +
  2. +
  3. + Scorri il menu verso il basso e seleziona Aggiungi alla schermata Home . +
  4. +
  5. + Conferma toccando Aggiungi in alto a destra. L'icona dell'app apparirà sul tuo schermo! +
  6. +
+
+
+ + +
+ + + +

Come installare l'applicazione

+

+ Se usi Chrome / Edge / Brave: puoi installarla cliccando sull'icona di installazione ⊕ o 📥 che appare a destra nella barra degli indirizzi del browser.

+ Se usi Safari (su Mac): clicca sul menu File in alto e seleziona Aggiungi al Dock.... +

+
+
+
+ +
+ + + +

Schermo Intero Browser

+

Espande l'app a tutto schermo

+
+ +
+ + + + +

Alto Contrasto

+

Colori più netti per il sole

+
+ +
+ + + +

Avanzamento Automatico

+

Passa al canto successivo

+
+ +
+ + + + +

Editor e Canti Personali

+

Abilita aggiunta e gestione "Miei"

+
+ +
+ + + +

Visualizza tag

+

Mostra filtri sotto autore nella lista canti

+
+ +
+ + + +

Visualizza data update

+

Mostra data aggiornamento nella lista canti

+
+ +
+ + + +

Visualizza durata, bpm e tonalità

+

Mostra queste info sotto autore / titolo

+
+ +
+ + + +

Autoscroll standard

+

Abilita 3 tasti di autoscroll nel canto

+
+ +
+ + + +

Autoscroll visuale

+

Mostra fotocamera per scorrimento visuale

+
+ +
+ + + +

Avanzamento manuale a pagine

+

I tasti Avanti/Indietro (Karaoke) voltano la pagina intera anziché riga per riga

+
+ +
+ + + +

Vista orizzontale per proiezione

+

Adatta il layout in landscape per la proiezione (testo più grande, controlli dedicati)

+
+ +
+ + + +

Schermo nero durante l'ascolto

+

Se attiva la riproduzione in home, mostra uno schermo nero per risparmiare batteria. Tocca per disattivare.

+
+ +
+
+ + +
+ + + +

Comunità

+

Mostra il filtro Comunità nella home

+
+ +
+ + +
+
+
+
Comunità Attiva
+
{{ comunitaService.comunitaNome() }}
+
Codice: {{ comunitaService.comunitaCode() }}
+
+
+ + + + + + +
+
+ +
+

+ Inserisci il codice parrocchiale/comunità per scaricare i canti e le scalette dedicate: +

+
+
+ +
+ + Attiva + +
+
+
+
+ + +
+
+

+ Identità Utente e Ripristino +

+
+ +
+

+ Questo codice univoco identifica in modo anonimo il tuo dispositivo e ti consente di gestire comunità e canti. Salva il codice o il QR code per ripristinare il tuo profilo su un nuovo dispositivo. +

+ + +
+
Nome
+ +
+ +
+
+
Codice ID
+
{{ settingsService.userUuid() }}
+
+ + + +
+ +
+ + + Scansiona QR + + + + Inserisci Codice + +
+ + + + Ripristina ID Originario + + + + + Salva Backup sul Server + + + + + Ripristina Backup dal Server + +
+
+ + +
+ + + +

Importa Playlist via QR

+

Inquadra il QR di una playlist condivisa per importarla

+
+ +
+
+ + +
+ + + +

Invio dati statistici

+

Invia statistiche di utilizzo e tonalità

+
+ +
+
+ + + +
+
+

+ Modalità Visualizzazione +

+
+ +
+
+
+ Solo Testo +
+
+ Accordi +
+
+
+
+ + +
+
+

+ Notazione Accordi Preferita +

+
+ +
+
+
+ Diesis (#) +
+
+ Bemolle (b) +
+
+
+
+ + +
+
+

+ Modalità Tracciamento Fotocamera (Karaoke) +

+
+ +
+
+
+ Distanza Viso (Avanti / Dietro) +
+
+ Inclinazione Testa +
+
+

+ + 💡 Distanza Viso: avvicinati allo schermo per avanzare nel testo, allontanati per tornare indietro. Tocca la percentuale nel player per calibrare all'istante la tua distanza attuale al 100%. + + + 💡 Inclinazione: piega la testa a destra o a sinistra per avanzare o tornare indietro. + +

+
+
+ + +
+
+

+ Legenda Pulsanti del Canto +

+
+ +
+

+ All'interno della schermata di lettura del canto trovi vari pulsanti per controllare la visualizzazione e lo scorrimento: +

+ +
+
+
+ +
+
+

Scroll Visuale (Karaoke)

+

+ Attiva lo scorrimento visuale intelligente tramite fotocamera frontale (avvicinandoti/allontanandoti o inclinando il capo in base alla modalità selezionata). +

+
+
+ +
+
+ +
+
+

Trasposizione Tonalità (+ / -)

+

+ Disponibile in modalità "Accordi". Alza o abbassa la tonalità del canto di semitono in semitono, ricalcolando gli accordi all'istante. +

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

Testo / Accordi (icona in alto a destra)

+

+ Alterna la visualizzazione tra solo testo e testo con accordi. L'icona con la T (grigia) indica la modalità testo; l'icona con le note musicali (arancione) indica la modalità accordi. Un tocco cambia modalità all'istante. +

+
+
+ +
+
+ +
+
+

Riavvia Canto

+

+ Riporta la visualizzazione all'inizio del testo e azzera il tracciamento dello scroll visuale. +

+
+
+ +
+
+ +
+
+

Navigazione Righe

+

+ Permette di avanzare o tornare indietro manualmente tra le righe del testo del canto. +

+
+
+ +
+
+ +
+
+

Zoom Caratteri

+

+ Ingrandisce o rimpicciolisce il testo e gli accordi (puoi usare anche il gesto "pinch-to-zoom" sullo schermo). +

+
+
+ +
+
+ +
+
+

YouTube Esterno

+

+ Apre la traccia o il video ufficiale del canto direttamente sull'applicazione esterna di YouTube (quando online). +

+
+
+
+
+
+ + + +
+ +
+
+
diff --git a/src/app/pages/settings/settings.page.scss b/src/app/pages/settings/settings.page.scss new file mode 100644 index 0000000..ab573f5 --- /dev/null +++ b/src/app/pages/settings/settings.page.scss @@ -0,0 +1,326 @@ +.bg-gradient { + --background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); + background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); +} + +.outfit-font { + font-family: 'Outfit', sans-serif; +} + +.settings-container { + max-width: 600px; + margin: 0 auto; +} + +.settings-group { + border-radius: 20px; + overflow: hidden; + border: 1px solid rgba(255, 255, 255, 0.1); +} + + + +.transparent-item { + --background: transparent; + --color: white; + --padding-start: 16px; + --inner-padding-end: 16px; +} + +.settings-item-title { + color: white; + font-weight: 600; + margin: 0; +} + +.settings-item-subtitle { + color: rgba(255, 255, 255, 0.6); + margin: 0; +} + +.settings-group-title { + font-size: 1.1rem; + font-weight: 700; + color: var(--ion-color-secondary); + margin: 0; +} + +.sub-group-title { + font-size: 0.75rem; + font-weight: 700; + color: rgba(255, 255, 255, 0.4); + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 4px; +} + +.playlist-item { + --min-height: 44px; + background: rgba(255, 255, 255, 0.03) !important; + margin: 4px 8px; + border-radius: 8px; + + .settings-item-title { + font-size: 0.9rem; + } +} + +ion-radio { + --color: rgba(255, 255, 255, 0.4); + --color-checked: var(--ion-color-secondary); + font-size: 1rem; + width: 100%; + + ion-label { + color: white; + } +} + +.compact-mode { + .filter-btn { + flex: 1; + justify-content: center; + } +} + +.group-header { + margin-bottom: 8px; +} + +.sync-info { + margin-top: 4px; + padding-left: 56px; + p { + font-size: 0.75rem; + color: rgba(255, 255, 255, 0.4); + strong { + color: var(--ion-color-secondary); + } + } +} + +.sync-progress { + height: 4px; + background: rgba(255, 255, 255, 0.1); + width: 100%; + + .progress-bar { + height: 100%; + background: var(--ion-color-secondary); + transition: width 0.3s ease; + } +} + +.settings-footer-text { + color: rgba(255, 255, 255, 0.3); + font-size: 0.8rem; +} + +// High contrast overrides +:host-context(body.high-contrast) { + .settings-item-title { + color: black !important; + } + .settings-item-subtitle { + color: rgba(0, 0, 0, 0.6) !important; + } + .settings-footer-text { + color: rgba(0, 0, 0, 0.4) !important; + } + .sub-group-title { + color: rgba(0, 0, 0, 0.7) !important; + } + .sync-info p { + color: rgba(0, 0, 0, 0.7) !important; + } + ion-label { + color: black !important; + } + ion-radio { + --color: rgba(0, 0, 0, 0.3); + color: black !important; + + ion-label { + color: black !important; + } + } +} + +.credits-footer { + margin-top: 24px; + border-top: 1px solid rgba(255, 255, 255, 0.1); + padding-top: 24px; + + .credits-text { + font-size: 1rem; + font-weight: 600; + color: var(--ion-color-secondary); + line-height: 1.6; + } + + .email-text { + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.5); + margin-top: 8px; + } +} + +:host-context(body.high-contrast) { + .credits-footer { + border-top-color: rgba(0, 0, 0, 0.2); + .credits-text { + color: black !important; + } + .email-text { + color: rgba(0, 0, 0, 0.6) !important; + } + } +} + +.select-item-container { + display: flex; + flex-direction: column; + gap: 12px; +} + +.select-label-row { + display: flex; + align-items: center; + gap: 12px; +} + +.select-icon { + font-size: 1.5rem; + flex-shrink: 0; +} + +.select-text-group { + display: flex; + flex-direction: column; + + .settings-item-title { + font-size: 1rem !important; + font-weight: 600 !important; + line-height: 1.2; + margin: 0; + } + + .settings-item-subtitle { + font-size: 0.85rem !important; + margin-top: 2px !important; + } +} + +.select-box-wrapper { + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + padding: 4px 12px; + transition: background 0.2s ease, border-color 0.2s ease; + + &:active { + background: rgba(255, 255, 255, 0.1); + border-color: rgba(255, 255, 255, 0.2); + } +} + +.custom-select-block { + --placeholder-color: rgba(255, 255, 255, 0.4); + --placeholder-opacity: 1; + --color: var(--ion-color-secondary); + color: var(--ion-color-secondary); + font-family: 'Outfit', sans-serif; + font-weight: 500; + width: 100%; + font-size: 0.95rem; + + &::part(placeholder), &::part(text) { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + +:host-context(body.high-contrast) { + .select-box-wrapper { + background: rgba(0, 0, 0, 0.05) !important; + border-color: rgba(0, 0, 0, 0.3) !important; + } + .custom-select-block { + --color: black !important; + color: black !important; + } + .legend-content { + .legend-intro { + color: #333333 !important; + } + .legend-item { + .legend-icon-wrapper { + background: rgba(0, 0, 0, 0.05) !important; + border: 1px solid #cccccc; + } + .legend-text { + h4 { + color: #000000 !important; + } + p { + color: #222222 !important; + } + } + } + } +} + +.legend-content { + .legend-intro { + font-size: 0.9rem; + color: rgba(255, 255, 255, 0.7); + margin-bottom: 16px; + line-height: 1.4; + } + + .legend-list { + display: flex; + flex-direction: column; + gap: 16px; + } + + .legend-item { + display: flex; + align-items: flex-start; + gap: 12px; + + .legend-icon-wrapper { + width: 32px; + height: 32px; + border-radius: 8px; + background: rgba(255, 255, 255, 0.05); + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + + ion-icon { + font-size: 1.2rem; + } + } + + .legend-text { + flex: 1; + + h4 { + margin: 0 0 4px 0; + font-size: 0.95rem; + font-weight: 600; + color: var(--ion-color-secondary); + } + + p { + margin: 0; + font-size: 0.82rem; + color: rgba(255, 255, 255, 0.6); + line-height: 1.4; + } + } + } +} diff --git a/src/app/pages/settings/settings.page.ts b/src/app/pages/settings/settings.page.ts new file mode 100644 index 0000000..999500b --- /dev/null +++ b/src/app/pages/settings/settings.page.ts @@ -0,0 +1,516 @@ +import { Component, inject } from '@angular/core'; +import { ThemeService } from '../../services/theme.service'; +import { SettingsService } from '../../services/settings.service'; +import { CantiService } from '../../services/canti.service'; +import { ConnectivityService } from '../../services/connectivity.service'; +import { SwUpdate, VersionReadyEvent } from '@angular/service-worker'; +import { ToastController, ModalController, AlertController, LoadingController } from '@ionic/angular'; +import { VERSION } from '../../version'; +import { PlaylistService } from '../../services/playlist.service'; +import { Router } from '@angular/router'; +import { filter, first } from 'rxjs/operators'; + +import { MyCantiService } from '../../services/my-canti.service'; +import { CantiLettureService } from '../../services/canti-letture.service'; +import { ComunitaService } from '../../services/comunita.service'; +import { environment } from '../../../environments/environment'; +import { showFullscreenUpdateOverlay } from '../../app.component'; +import { QrScannerComponent } from '../../components/qr-scanner/qr-scanner.component'; +import { IdentityQrModalComponent } from '../../components/identity-qr-modal/identity-qr-modal.component'; + +@Component({ + selector: 'app-settings', + templateUrl: './settings.page.html', + styleUrls: ['./settings.page.scss'], + standalone: false +}) +export class SettingsPage { + public myCantiService = inject(MyCantiService); + public themeService = inject(ThemeService); + public settingsService = inject(SettingsService); + public cantiService = inject(CantiService); + public connectivityService = inject(ConnectivityService); + public playlistService = inject(PlaylistService); + public cantiLettureService = inject(CantiLettureService); + public comunitaService = inject(ComunitaService); + private swUpdate = inject(SwUpdate); + private toastCtrl = inject(ToastController); + private modalCtrl = inject(ModalController); + private alertCtrl = inject(AlertController); + private loadingCtrl = inject(LoadingController); + private router = inject(Router); + + public version = VERSION; + public contactEmail = environment.contactEmail; + public appName = environment.appName; + public showIosInstructions = false; + + constructor() {} + + async installApp() { + await this.settingsService.installPwa(); + } + + toggleIosInstructions() { + this.showIosInstructions = !this.showIosInstructions; + } + + async showBackupQrCode() { + const modal = await this.modalCtrl.create({ + component: IdentityQrModalComponent, + componentProps: { + userUuid: this.settingsService.userUuid() + } + }); + return await modal.present(); + } + + async scanRestoreQrCode() { + const modal = await this.modalCtrl.create({ + component: QrScannerComponent + }); + await modal.present(); + + const { data } = await modal.onWillDismiss(); + if (data) { + this.confirmRestore(data); + } + } + + async importPlaylistViaQr() { + const modal = await this.modalCtrl.create({ + component: QrScannerComponent + }); + await modal.present(); + + const { data } = await modal.onWillDismiss(); + if (data) { + // Naviga alla home passando il dato via state per il processing multi-scopo + this.router.navigate(['/home'], { state: { scannedQrData: data } }); + } + } + + async manualRestore() { + const alert = await this.alertCtrl.create({ + header: 'Ripristina con Codice', + message: 'Digita o incolla il tuo codice identificativo univoco.', + inputs: [ + { + name: 'code', + type: 'text', + placeholder: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', + value: '' + } + ], + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Conferma', + handler: (data) => { + if (data.code && data.code.trim()) { + this.confirmRestore(data.code.trim()); + } + } + } + ] + }); + await alert.present(); + } + + private async confirmRestore(code: string) { + // Basic validation for UUID + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + if (!uuidRegex.test(code)) { + const errorAlert = await this.alertCtrl.create({ + header: 'Codice Non Valido', + message: 'Il codice inserito non sembra essere un identificativo univoco valido. Riprova.', + buttons: ['OK'] + }); + await errorAlert.present(); + return; + } + + const alert = await this.alertCtrl.create({ + header: 'Ripristina Identità', + message: 'Sei sicuro di voler ripristinare questa identità? L\'ID attuale del dispositivo verrà sovrascritto permanentemente ed eventuali canti e playlist remoti associati al nuovo ID verranno scaricati.', + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Ripristina', + role: 'destructive', + handler: async () => { + const loading = await this.loadingCtrl.create({ + message: 'Scaricamento dati da remoto...' + }); + await loading.present(); + + try { + const response = await fetch(`https://api.canticristiani.it/${code}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (response.ok) { + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + // Reconstruct user name/metadata + const userMetadata = remoteJson.find((item: any) => item.momenti && item.momenti.includes('UserMetadata')); + if (userMetadata && userMetadata.titolo) { + this.settingsService.setUserName(userMetadata.titolo); + } + + // Reconstruct custom songs + const customSongs = remoteJson + .filter((item: any) => (!item.momenti || !item.momenti.includes('Playlist')) && (!item.momenti || !item.momenti.includes('UserMetadata'))) + .map((item: any) => ({ + id: `my_${item.id_canti}`, + id_canti: Number(item.id_canti), + titolo: item.titolo || 'Senza Titolo', + testo: item.testo || '', + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + autore: item.autore || '', + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + })); + + if (customSongs.length > 0) { + this.myCantiService.myCanti.set(customSongs); + const storage = this.cantiService.getStorage(); + if (storage) { + await storage.set('my-canti', customSongs); + } + } + + // Reconstruct playlists + const playlists = remoteJson + .filter((item: any) => item.momenti && item.momenti.includes('Playlist')) + .map((item: any) => { + let songSettings = {}; + if (item.periodi && item.periodi.length > 0) { + try { + songSettings = JSON.parse(item.periodi[0]); + } catch (e) {} + } + return { + id: String(item.id_canti), + name: item.titolo, + ids: item.testo ? item.testo.split(',') : [], + songSettings: songSettings, + createdAt: new Date() + }; + }); + + if (playlists.length > 0) { + this.playlistService.playlists.set(playlists); + if (this.playlistService['_storage']) { + const key = this.playlistService.getPlaylistsStorageKey(); + await this.playlistService['_storage'].set(key, playlists); + } + } + } + } + } catch (err) { + console.error('Failed to restore backup data:', err); + } finally { + await loading.dismiss(); + } + + this.settingsService.setUserUuid(code); + const toast = await this.toastCtrl.create({ + message: 'Identità e dati ripristinati con successo! Ricaricamento...', + duration: 2000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + + setTimeout(() => { + window.location.replace(window.location.origin + window.location.pathname); + }, 1500); + } + } + ] + }); + await alert.present(); + } + + async restoreOriginalIdentity() { + const original = this.settingsService.originalUserUuid(); + if (!original) { + const alert = await this.alertCtrl.create({ + header: 'Errore', + message: 'Nessun identificativo originario trovato.', + buttons: ['OK'] + }); + await alert.present(); + return; + } + + const alert = await this.alertCtrl.create({ + header: 'Ripristina ID Originario', + message: `Sei sicuro di voler ripristinare il codice ID originario assegnato alla prima installazione? L'ID attuale del dispositivo verrà sovrascritto e verranno scaricati eventuali canti e playlist associati all'ID originario.`, + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Ripristina', + handler: () => { + this.confirmRestore(original); + } + } + ] + }); + await alert.present(); + } + + async syncLocalDataToServer() { + const uid = this.settingsService.userUuid(); + if (!uid) { + const alert = await this.alertCtrl.create({ + header: 'Errore', + message: 'Nessun identificativo utente (UID) trovato.', + buttons: ['OK'] + }); + await alert.present(); + return; + } + + const toastLoading = await this.toastCtrl.create({ + message: 'Invio backup in corso...', + duration: 1500, + color: 'secondary' + }); + await toastLoading.present(); + + try { + await this.playlistService.syncLocalDataToServer(); + await toastLoading.dismiss(); + + const toastSuccess = await this.toastCtrl.create({ + message: 'Backup sincronizzato con successo!', + duration: 3000, + color: 'success' + }); + await toastSuccess.present(); + } catch (err: any) { + try { + await toastLoading.dismiss(); + } catch (e) {} + console.error('Failed to backup to server:', err); + const alertError = await this.alertCtrl.create({ + header: 'Errore di sincronizzazione', + message: 'Impossibile inviare il backup al server. Controlla la connessione e riprova.', + buttons: ['OK'] + }); + await alertError.present(); + } + } + + async restoreBackupFromServer() { + const code = this.settingsService.userUuid(); + if (!code) { + const alert = await this.alertCtrl.create({ + header: 'Errore', + message: 'Nessun identificativo utente (UID) trovato.', + buttons: ['OK'] + }); + await alert.present(); + return; + } + + const alert = await this.alertCtrl.create({ + header: 'Ripristina Backup', + message: 'Sei sicuro di voler ripristinare i dati dal server? I tuoi canti personali e le tue scalette locali verranno allineati con l\'ultimo backup presente sul server.', + buttons: [ + { + text: 'Annulla', + role: 'cancel' + }, + { + text: 'Ripristina', + handler: async () => { + const loading = await this.loadingCtrl.create({ + message: 'Scaricamento dati da remoto...' + }); + await loading.present(); + + try { + const response = await fetch(`https://api.canticristiani.it/${code}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (response.ok) { + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + // Reconstruct user name/metadata + const userMetadata = remoteJson.find((item: any) => item.momenti && item.momenti.includes('UserMetadata')); + if (userMetadata && userMetadata.titolo) { + this.settingsService.setUserName(userMetadata.titolo); + } + + // Reconstruct custom songs + const customSongs = remoteJson + .filter((item: any) => (!item.momenti || !item.momenti.includes('Playlist')) && (!item.momenti || !item.momenti.includes('UserMetadata'))) + .map((item: any) => ({ + id: `my_${item.id_canti}`, + id_canti: Number(item.id_canti), + titolo: item.titolo || 'Senza Titolo', + testo: item.testo || '', + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + autore: item.autore || '', + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + })); + + this.myCantiService.myCanti.set(customSongs); + const storage = this.cantiService.getStorage(); + if (storage) { + await storage.set('my-canti', customSongs); + } + + // Reconstruct playlists + const playlists = remoteJson + .filter((item: any) => item.momenti && item.momenti.includes('Playlist')) + .map((item: any) => { + let songSettings = {}; + if (item.periodi && item.periodi.length > 0) { + try { + songSettings = JSON.parse(item.periodi[0]); + } catch (e) {} + } + return { + id: String(item.id_canti), + name: item.titolo, + ids: item.testo ? item.testo.split(',') : [], + songSettings: songSettings, + createdAt: new Date() + }; + }); + + this.playlistService.playlists.set(playlists); + if (this.playlistService['_storage']) { + const key = this.playlistService.getPlaylistsStorageKey(); + await this.playlistService['_storage'].set(key, playlists); + } + + const toast = await this.toastCtrl.create({ + message: 'Dati ripristinati con successo! Ricaricamento...', + duration: 2000, + color: 'success', + position: 'bottom' + }); + await toast.present(); + + setTimeout(() => { + window.location.replace(window.location.origin + window.location.pathname); + }, 1500); + } else { + throw new Error('Formato dati del backup non valido.'); + } + } else { + throw new Error('Nessun backup trovato sul server per questo ID.'); + } + } catch (err: any) { + console.error('Failed to restore backup data:', err); + const errorAlert = await this.alertCtrl.create({ + header: 'Errore Ripristino', + message: err.message || 'Impossibile scaricare il backup dal server. Verifica la connessione.', + buttons: ['OK'] + }); + await errorAlert.present(); + } finally { + await loading.dismiss(); + } + } + } + ] + }); + await alert.present(); + } + + onModeChange(event: any) { + this.settingsService.setShowChordsDefault(event.detail.value === 'chords'); + } + + onNameChange(event: any) { + this.settingsService.setUserName(event.target.value); + } + + onMassChange(event: any) { + this.cantiLettureService.setSelectedMass(event.detail.value); + } + + + + async onComunitaToggleChange(event: any) { + const checked = event.detail.checked; + if (checked) { + this.settingsService.comunitaEnabled.set(true); + localStorage.setItem('comunita-enabled', 'true'); + } else { + this.settingsService.comunitaEnabled.set(false); + localStorage.setItem('comunita-enabled', 'false'); + } + } + + async editComunita() { + await this.comunitaService.setComunitaCode(''); + } + + async saveComunitaCode(code: string) { + const trimmed = (code || '').trim(); + if (!trimmed) return; + + const loading = await this.loadingCtrl.create({ + message: 'Caricamento 0%', + cssClass: 'premium-loading', + spinner: 'crescent' + }); + await loading.present(); + + let progressInterval = setInterval(() => { + const pct = this.comunitaService.loadingProgress(); + loading.message = `Caricamento ${pct}%`; + if (pct >= 100) { + clearInterval(progressInterval); + } + }, 100); + + const success = await this.comunitaService.setComunitaCode(trimmed); + clearInterval(progressInterval); + await loading.dismiss(); + + if (success) { + const toast = await this.toastCtrl.create({ + message: `Comunità attivata: ${this.comunitaService.comunitaNome()}`, + duration: 2000, + color: 'success' + }); + await toast.present(); + } else { + const toast = await this.toastCtrl.create({ + message: 'Codice non trovato o errore di connessione.', + duration: 2000, + color: 'danger' + }); + await toast.present(); + } + } + + async removeComunita() { + await this.comunitaService.setComunitaCode(''); + this.settingsService.comunitaEnabled.set(false); + localStorage.setItem('comunita-enabled', 'false'); + const toast = await this.toastCtrl.create({ + message: 'Comunità disattivata.', + duration: 2000, + color: 'secondary' + }); + await toast.present(); + } +} diff --git a/src/app/services/audio-engine.service.ts b/src/app/services/audio-engine.service.ts new file mode 100644 index 0000000..aa7c4b6 --- /dev/null +++ b/src/app/services/audio-engine.service.ts @@ -0,0 +1,612 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class AudioEngineService { + public isListening = signal(false); + public wordsDetected = signal(0); + public linesDetected = signal(0); + public energyLevel = signal(0); // For visual feedback + public searchTranscript = signal(''); + public isSearching = signal(false); + public sensitivity = signal(75); // Default sensitivity (50-100) + public speechRecognitionActive = signal(false); + + // Voice/Guitar detection signals + public voiceDetected = signal(false); + public guitarDetected = signal(false); + + /** Soglia del punteggio voce: valori più bassi = più sensibile alla voce (range 0.05 – 0.50) */ + public voiceThreshold = signal(0.15); + + /** Debug: punteggio voce corrente (0-1) per feedback visivo */ + public voiceScore = signal(0); + + // Real-time background continuous transcript and word buffer for reliability checks + public backgroundTranscript = signal(''); + private backgroundRecognition: any = null; + private recentWordsBuffer: { word: string, timestamp: number }[] = []; + + public clearSearchTranscript() { + this.searchTranscript.set(''); + } + + private audioContext: AudioContext | null = null; + private analyser: AnalyserNode | null = null; + private stream: MediaStream | null = null; + private animationFrame: number | null = null; + private recognition: any = null; + + // Detection logic state + private isSpeaking: boolean = false; + private lastSilenceTime: number = Date.now(); + private lastWordTime: number = 0; + private speakingStartTime: number = 0; + + // Constants for tuning - Optimized for close proximity (singer/guitarist) + private readonly SILENCE_GAP = 100; // ms + private readonly LINE_SILENCE_GAP = 600; // ms + private readonly COOLDOWN = 1000; // ms + private peakEnergy: number = 0; + private lineStarted: boolean = false; + private noiseFloor: number = 30; // Adaptive noise floor starting point + + // --- Advanced Voice Detection State --- + + // Smoothing buffer (16 frames ~260ms a 60fps) + private readonly SMOOTHING_FRAMES = 16; + private voiceScoreBuffer: number[] = []; + + // Spectral flux: previous frame spectrum for change detection + private previousSpectrum: Float32Array | null = null; + + // Hysteresis: once voice is detected, it stays on for at least this many frames + private readonly VOICE_HOLD_FRAMES = 12; // ~200ms + private voiceHoldCounter: number = 0; + + // Sub-band definitions (Hz) - 8 fine-grained bands + private readonly BANDS = [ + { name: 'sub_bass', start: 80, end: 150 }, // Fondamentali basse chitarra (Mi2=82, La2=110) + { name: 'bass', start: 150, end: 300 }, // Fondamentali voce maschile/femminile + chitarra + { name: 'low_mid', start: 300, end: 600 }, // Armoniche chitarra dominanti + { name: 'mid', start: 600, end: 1000 }, // Zona transizione + { name: 'formant_f1', start: 1000, end: 1500 }, // Formante F1 voce (vocali aperte) + { name: 'formant_f2', start: 1500, end: 2500 }, // Formante F2 voce (KEY: quasi assente in chitarra) + { name: 'formant_f3', start: 2500, end: 3500 }, // Formante F3 voce (sibilanti morbide) + { name: 'sibilants', start: 3500, end: 6000 }, // Consonanti sibilanti (s, t, f, sh) - SOLO voce + ]; + + constructor() { + this.initSpeechRecognition(); + } + + private initBackgroundRecognition() { + // Disattivato per utilizzare esclusivamente l'analizzatore FFT acustico locale + } + + private startBackgroundRecognition() { + // Disattivato + } + + private stopBackgroundRecognition() { + // Disattivato + } + + private updateRecentWords(transcript: string) { + // Disattivato + } + + public getRecentWords(): string[] { + return []; + } + + public getRecentWordsSince(timestamp: number): string[] { + return []; + } + + public clearRecentWords() { + this.recentWordsBuffer = []; + this.backgroundTranscript.set(''); + } + + private initSpeechRecognition() { + const SpeechRecognition = (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition; + if (SpeechRecognition) { + this.recognition = new SpeechRecognition(); + this.recognition.continuous = false; // Stop after one phrase for search + this.recognition.interimResults = true; + this.recognition.lang = 'it-IT'; + + this.recognition.onresult = (event: any) => { + const text = event.results[0][0].transcript; + this.searchTranscript.set(text); + }; + + this.recognition.onend = () => { + this.isSearching.set(false); + }; + + this.recognition.onerror = (err: any) => { + console.error('Search recognition error:', err); + this.isSearching.set(false); + }; + } + } + + startSearchRecognition() { + if (!this.recognition) { + alert('Il riconoscimento vocale non è supportato in questo browser.'); + return; + } + this.searchTranscript.set(''); + this.isSearching.set(true); + try { + this.recognition.start(); + } catch (e) { + console.warn('Recognition already started', e); + } + } + + stopSearchRecognition() { + this.recognition?.stop(); + this.isSearching.set(false); + } + + async startListening() { + if (this.isListening()) return; + + this.isListening.set(true); + this.voiceDetected.set(false); + this.guitarDetected.set(false); + this.voiceScoreBuffer = []; + this.previousSpectrum = null; + this.voiceHoldCounter = 0; + this.clearRecentWords(); + + console.log('[AudioEngine] Starting local FFT Audio Analyser'); + await this.startOfflineAnalyser(); + } + + public async startOfflineAnalyser() { + if (this.analyser) return; // Già attivo + try { + this.stream = await navigator.mediaDevices.getUserMedia({ + audio: { + echoCancellation: true, + noiseSuppression: true, + autoGainControl: false // Impedisce il boost automatico del rumore di fondo nel silenzio + } + }); + this.audioContext = new AudioContext(); + const source = this.audioContext.createMediaStreamSource(this.stream); + + // FFT a 4096 punti per risoluzione ~10.7 Hz/bin (a 44100 Hz) + this.analyser = this.audioContext.createAnalyser(); + this.analyser.fftSize = 4096; + this.analyser.smoothingTimeConstant = 0.4; // Smoothing moderato per stabilità spettrale + + source.connect(this.analyser); + this.processAudio(); + } catch (err) { + console.error('[AudioEngine] Error accessing microphone for offline analyser:', err); + // Se fallisce anche il mic locale, proviamo a ripristinare lo stato + this.stopListening(); + alert('Errore microfono: assicurati di usare HTTPS e di aver dato i permessi.'); + } + } + + stopListening() { + if (this.animationFrame) cancelAnimationFrame(this.animationFrame); + + // Rilascia le risorse del microfono locale + this.stream?.getTracks().forEach(track => track.stop()); + this.audioContext?.close(); + this.stream = null; + this.audioContext = null; + this.analyser = null; + + this.isListening.set(false); + this.energyLevel.set(0); + this.voiceDetected.set(false); + this.guitarDetected.set(false); + this.voiceScore.set(0); + this.voiceScoreBuffer = []; + this.previousSpectrum = null; + this.voiceHoldCounter = 0; + this.stopBackgroundRecognition(); + this.clearRecentWords(); + this.speechRecognitionActive.set(false); + } + + // ===================================================================== + // ANALISI SPETTRALE AVANZATA MULTI-FEATURE + // ===================================================================== + + /** + * Calcola l'energia media in una sotto-banda dello spettro. + */ + private getBandEnergy(dataArray: Uint8Array, binWidth: number, startHz: number, endHz: number): number { + const startBin = Math.max(0, Math.floor(startHz / binWidth)); + const endBin = Math.min(dataArray.length - 1, Math.floor(endHz / binWidth)); + if (endBin <= startBin) return 0; + let sum = 0; + for (let i = startBin; i <= endBin; i++) { + sum += dataArray[i]; + } + return sum / (endBin - startBin + 1); + } + + /** + * FEATURE 1: Rapporto formanti vocali F2+F3 vs bande strumentali (low+mid) + * + * La voce umana ha formanti F2 (1500-2500 Hz) e F3 (2500-3500 Hz) molto prominenti. + * La chitarra acustica ha pochissima energia in queste bande. + * Rapporto alto = voce, basso = strumento. + */ + private calcFormantRatio(bandEnergies: number[]): number { + const instrumentEnergy = bandEnergies[0] + bandEnergies[1] + bandEnergies[2] + bandEnergies[3]; // 80-1000 Hz + const formantEnergy = bandEnergies[5] + bandEnergies[6]; // F2 (1500-2500) + F3 (2500-3500) + return formantEnergy / (instrumentEnergy + 0.001); + } + + /** + * FEATURE 2: Energia sibilanti (3500-6000 Hz) + * + * Solo la voce umana produce consonanti sibilanti come "s", "t", "f", "sh", "z" + * che hanno energia significativa sopra 3500 Hz. Gli strumenti acustici (chitarra, + * pianoforte, etc.) hanno energia trascurabile in questa banda. + * + * Ritorna un valore normalizzato 0-1. + */ + private calcSibilantScore(bandEnergies: number[], totalEnergy: number): number { + if (totalEnergy < 1) return 0; + const sibilantEnergy = bandEnergies[7]; // 3500-6000 Hz + // Normalizza: una sibilante tipica ha 15-40% dell'energia totale + return Math.min(1, sibilantEnergy / (totalEnergy * 0.15 + 0.001)); + } + + /** + * FEATURE 3: Spectral Flatness (entropia di Wiener) + * + * Misura quanto lo spettro è "piatto" (rumoroso) vs "piccato" (tonale). + * - Chitarra: spettro molto tonale con picchi armonici netti → flatness BASSA + * - Voce (consonanti): spettro più rumoroso → flatness ALTA + * - Voce (vocali): moderatamente tonale ma con formanti larghe → flatness MEDIA + * + * Formula: media_geometrica / media_aritmetica (0=tono puro, 1=rumore bianco) + */ + private calcSpectralFlatness(dataArray: Uint8Array, binWidth: number): number { + // Calcola nella regione 300-6000 Hz (dove la discriminazione è più utile) + const startBin = Math.max(1, Math.floor(300 / binWidth)); + const endBin = Math.min(dataArray.length - 1, Math.floor(6000 / binWidth)); + const n = endBin - startBin + 1; + if (n <= 0) return 0; + + let logSum = 0; + let arithmeticSum = 0; + let zeroCount = 0; + + for (let i = startBin; i <= endBin; i++) { + const val = Math.max(dataArray[i], 0.001); // Avoid log(0) + logSum += Math.log(val); + arithmeticSum += val; + if (dataArray[i] === 0) zeroCount++; + } + + if (zeroCount > n * 0.5) return 0; // Troppi zeri = silenzio + + const geometricMean = Math.exp(logSum / n); + const arithmeticMean = arithmeticSum / n; + + if (arithmeticMean < 0.001) return 0; + return Math.min(1, geometricMean / arithmeticMean); + } + + /** + * FEATURE 4: Spectral Flux (velocità di cambiamento spettrale) + * + * Misura quanto rapidamente cambia la forma dello spettro tra frame successivi. + * - Voce: alta flux (alternanza vocali/consonanti, prosodia) + * - Chitarra: bassa flux (note sostenute, spettro stabile) + * + * Ritorna un valore normalizzato 0-1. + */ + private calcSpectralFlux(dataArray: Uint8Array, binWidth: number): number { + const startBin = Math.max(0, Math.floor(200 / binWidth)); + const endBin = Math.min(dataArray.length - 1, Math.floor(5000 / binWidth)); + + if (!this.previousSpectrum) { + this.previousSpectrum = new Float32Array(dataArray.length); + for (let i = 0; i < dataArray.length; i++) { + this.previousSpectrum[i] = dataArray[i]; + } + return 0; + } + + let flux = 0; + let maxFlux = 0; + for (let i = startBin; i <= endBin; i++) { + const diff = dataArray[i] - this.previousSpectrum[i]; + // Solo variazioni positive (onset) per evitare il decadimento naturale + if (diff > 0) { + flux += diff * diff; + } + maxFlux += 255 * 255; // Massimo teorico + } + + // Aggiorna il buffer dello spettro precedente + for (let i = 0; i < dataArray.length; i++) { + this.previousSpectrum[i] = dataArray[i]; + } + + if (maxFlux === 0) return 0; + // Normalizza e scala logaritmicamente per sensibilità + const normalizedFlux = flux / maxFlux; + return Math.min(1, Math.sqrt(normalizedFlux) * 10); // Amplifica le piccole variazioni + } + + /** + * FEATURE 5: Formant Peak Detection + * + * Cerca picchi spettrali caratteristici nella regione delle formanti vocali (800-3500 Hz). + * La voce umana produce 2-4 picchi prominenti (formanti F1-F4). + * La chitarra ha uno spettro armonico regolare senza picchi formantici. + * + * Ritorna il numero di picchi formantici rilevati (0-4), normalizzato 0-1. + */ + private calcFormantPeaks(dataArray: Uint8Array, binWidth: number): number { + const startBin = Math.max(0, Math.floor(800 / binWidth)); + const endBin = Math.min(dataArray.length - 1, Math.floor(3500 / binWidth)); + + // Calcola la media locale per determinare la soglia di prominenza + let sum = 0; + for (let i = startBin; i <= endBin; i++) { + sum += dataArray[i]; + } + const avgEnergy = sum / Math.max(1, endBin - startBin + 1); + + if (avgEnergy < 5) return 0; // Silenzio + + // Cerca picchi: un bin è un picco se è maggiore dei 5 bin a sinistra e 5 a destra + // e supera la media di almeno 30% + const peakThreshold = avgEnergy * 1.3; + const windowSize = Math.max(3, Math.floor(100 / binWidth)); // ~100 Hz di finestra + let peakCount = 0; + let lastPeakBin = -windowSize * 2; // Evita di contare picchi troppo vicini + + for (let i = startBin + windowSize; i <= endBin - windowSize; i++) { + if (dataArray[i] < peakThreshold) continue; + + let isPeak = true; + for (let j = 1; j <= windowSize; j++) { + if (dataArray[i] < dataArray[i - j] || dataArray[i] < dataArray[i + j]) { + isPeak = false; + break; + } + } + + if (isPeak && (i - lastPeakBin) > windowSize) { + peakCount++; + lastPeakBin = i; + if (peakCount >= 4) break; // Max 4 formanti + } + } + + return Math.min(1, peakCount / 3); // 3 formanti = punteggio pieno + } + + /** + * FEATURE 6: Rapporto energia alta/bassa (spectral tilt) + * + * La voce umana (soprattutto da vicino al microfono) ha uno spettro più "piatto" + * con energia significativa anche nelle alte frequenze. + * La chitarra ha una forte caduta sopra 1-2 kHz. + */ + private calcSpectralTilt(bandEnergies: number[]): number { + const lowEnergy = bandEnergies[0] + bandEnergies[1] + bandEnergies[2]; // 80-600 Hz + const highEnergy = bandEnergies[5] + bandEnergies[6] + bandEnergies[7]; // 1500-6000 Hz + if (lowEnergy < 0.001) return 0; + // Un rapporto alto indica più energia nelle alte frequenze (voce) + return Math.min(1, highEnergy / (lowEnergy + 0.001)); + } + + /** + * Calcola il punteggio voce combinato da tutte le feature. + * + * Pesi delle feature (calibrati per massimizzare la discriminazione): + * - Formant ratio: 25% (molto discriminante) + * - Sibilant score: 20% (quasi esclusivo della voce) + * - Spectral flatness: 15% (voce più rumorosa di chitarra) + * - Spectral flux: 15% (voce cambia più rapidamente) + * - Formant peaks: 15% (struttura formanti unica della voce) + * - Spectral tilt: 10% (distribuzione energia) + */ + private calcVoiceScore( + dataArray: Uint8Array, + bandEnergies: number[], + totalEnergy: number, + binWidth: number + ): number { + const formantRatio = this.calcFormantRatio(bandEnergies); + const sibilantScore = this.calcSibilantScore(bandEnergies, totalEnergy); + const flatness = this.calcSpectralFlatness(dataArray, binWidth); + const flux = this.calcSpectralFlux(dataArray, binWidth); + const formantPeaks = this.calcFormantPeaks(dataArray, binWidth); + const spectralTilt = this.calcSpectralTilt(bandEnergies); + + // Normalizza formantRatio: tipicamente 0.05-0.5 per voce, 0-0.05 per chitarra + const normalizedFormantRatio = Math.min(1, formantRatio / 0.4); + + // Punteggio pesato + const score = + normalizedFormantRatio * 0.25 + + sibilantScore * 0.20 + + flatness * 0.15 + + flux * 0.15 + + formantPeaks * 0.15 + + spectralTilt * 0.10; + + return Math.min(1, Math.max(0, score)); + } + + // ===================================================================== + // MAIN AUDIO PROCESSING LOOP + // ===================================================================== + + private processAudio() { + if (!this.analyser) return; + + const bufferLength = this.analyser.frequencyBinCount; // 2048 con fftSize=4096 + const dataArray = new Uint8Array(bufferLength); + const sampleRate = this.audioContext ? this.audioContext.sampleRate : 44100; + const binWidth = sampleRate / 4096; // ~10.7 Hz/bin + + // Energia minima per considerare che c'è suono (evita falsi positivi nel silenzio) + const MIN_ENERGY = 5; + + const analyze = () => { + if (!this.analyser) return; + this.analyser.getByteFrequencyData(dataArray); + + // Calcola energia in ciascuna delle 8 sotto-bande + const bandEnergies: number[] = this.BANDS.map(band => + this.getBandEnergy(dataArray, binWidth, band.start, band.end) + ); + + // Energia totale media + const totalEnergy = bandEnergies.reduce((a, b) => a + b, 0) / bandEnergies.length; + + // Feedback visuale (barra energia) — usa la media delle bande vocali per coerenza + const vocalDisplayEnergy = (bandEnergies[4] + bandEnergies[5] + bandEnergies[6]) / 3; + this.energyLevel.set(vocalDisplayEnergy); + + const now = Date.now(); + const hasSound = totalEnergy > MIN_ENERGY; + + if (hasSound) { + // Calcola il punteggio voce multi-feature + const rawScore = this.calcVoiceScore(dataArray, bandEnergies, totalEnergy, binWidth); + + // Aggiungi al buffer di smoothing + this.voiceScoreBuffer.push(rawScore); + if (this.voiceScoreBuffer.length > this.SMOOTHING_FRAMES) { + this.voiceScoreBuffer.shift(); + } + + // Media pesata: i frame più recenti contano di più + let weightedSum = 0; + let weightTotal = 0; + for (let i = 0; i < this.voiceScoreBuffer.length; i++) { + const weight = (i + 1); // Peso crescente + weightedSum += this.voiceScoreBuffer[i] * weight; + weightTotal += weight; + } + const smoothedScore = weightedSum / weightTotal; + + this.voiceScore.set(smoothedScore); + + // Determinazione con isteresi + const threshold = this.voiceThreshold(); + + if (smoothedScore > threshold) { + // Voce rilevata + this.voiceDetected.set(true); + this.guitarDetected.set(false); + this.voiceHoldCounter = this.VOICE_HOLD_FRAMES; + } else if (this.voiceHoldCounter > 0) { + // Isteresi: mantieni lo stato "voce" per evitare oscillazioni + this.voiceHoldCounter--; + // Lo stato resta quello precedente (voce) + } else { + // Strumento/rumore ambientale + this.voiceDetected.set(false); + this.guitarDetected.set(true); + } + } else { + // Silenzio + this.voiceDetected.set(false); + this.guitarDetected.set(false); + this.voiceScore.set(0); + this.voiceHoldCounter = 0; + } + + // --- Logica conteggio parole (solo se voce rilevata) --- + + // Tracciamento adattivo del rumore di fondo + if (totalEnergy < this.noiseFloor) { + this.noiseFloor = this.noiseFloor * 0.95 + totalEnergy * 0.05; + } else { + this.noiseFloor = this.noiseFloor * 0.998 + totalEnergy * 0.002; + } + + // Soglia di sensibilità definita dall'utente + const userThreshold = 220 - (this.sensitivity() * 2.0); + const currentThreshold = Math.max(userThreshold, this.noiseFloor + 12); + + // *** CONTEGGIO PAROLE SOLO QUANDO LA VOCE UMANA È DOMINANTE *** + const isVoice = this.voiceDetected(); + + if (isVoice && totalEnergy > currentThreshold) { + if (totalEnergy > this.peakEnergy) { + this.peakEnergy = totalEnergy; + } + + if (!this.isSpeaking) { + this.isSpeaking = true; + this.speakingStartTime = now; + this.peakEnergy = totalEnergy; + this.lastSilenceTime = now; + } + + // Rilevamento della caduta di energia relativa per stacchi sillabici + const dropRatio = (this.peakEnergy - totalEnergy) / this.peakEnergy; + if (this.isSpeaking && dropRatio > 0.20 && this.peakEnergy > currentThreshold * 1.1) { + const speakDuration = now - this.speakingStartTime; + if (now - this.lastWordTime > this.COOLDOWN && speakDuration > 120) { + this.linesDetected.update(v => v + 1); + this.lastWordTime = now; + this.peakEnergy = totalEnergy; + this.isSpeaking = false; + console.log('[VoiceDetect] Word counted - voice energy drop', { + score: this.voiceScore().toFixed(3), + dropRatio: dropRatio.toFixed(2), + duration: speakDuration + }); + } + } + + this.lastSilenceTime = now; + } else { + // Sotto soglia, chitarra, o silenzio + if (this.isSpeaking && (now - this.lastSilenceTime > 180)) { + // Calcola la durata reale del segnale vocale escludendo la finestra di silenzio (180ms) + const actualSoundDuration = this.lastSilenceTime - this.speakingStartTime; + if (isVoice && now - this.lastWordTime > this.COOLDOWN && actualSoundDuration > 100) { + this.linesDetected.update(v => v + 1); + this.lastWordTime = now; + console.log('[VoiceDetect] Word counted - voice silence gap', { duration: actualSoundDuration }); + } + this.isSpeaking = false; + this.peakEnergy = 0; + } + + // Se la chitarra è dominante, resetta lo stato di parlato + if (!isVoice && this.isSpeaking) { + this.isSpeaking = false; + this.peakEnergy = 0; + } + } + + this.animationFrame = requestAnimationFrame(analyze); + }; + + analyze(); + } + + resetWordCount() { + this.wordsDetected.set(0); + this.linesDetected.set(0); + this.lineStarted = false; + } +} diff --git a/src/app/services/canti-letture.service.ts b/src/app/services/canti-letture.service.ts new file mode 100644 index 0000000..a13311e --- /dev/null +++ b/src/app/services/canti-letture.service.ts @@ -0,0 +1,261 @@ +import { Injectable, signal, inject, effect } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Storage } from '@ionic/storage-angular'; +import { firstValueFrom } from 'rxjs'; +import { environment } from '../../environments/environment'; + +export interface Suggestion { + id_canto?: number; + id_canti?: number; + peso?: number; + score?: number; +} + +export interface MassDetails { + title: string; + day: string; + summary?: string; + suggestions: { [moment: string]: Suggestion[] } | Suggestion[]; +} + +export interface CantiLettureData { + generated_at: string; + week_start: string; + week_end: string; + masses: { [date: string]: MassDetails }; +} + +export interface AvailableMass { + date: string; + title: string; + day: string; + formattedLabel: string; +} + +@Injectable({ + providedIn: 'root' +}) +export class CantiLettureService { + private http = inject(HttpClient); + private storage = inject(Storage); + + private _storage: Storage | null = null; + public data = signal(null); + public selectedMassDate = signal(null); + public availableMasses = signal([]); + public suggestionsMap = signal>(new Map()); // id_canto -> peso + public suggestionsMomentsMap = signal>(new Map()); // id_canto -> moments[] + + private JSON_URL = 'https://api.canticristiani.it/cantiletture.json'; + private SECURE_JSON_URL = '/api/cantiletture.json'; + + constructor() { + this.init(); + + // Effect to auto-update suggestions maps when selectedMassDate or data changes + effect(() => { + const activeDate = this.selectedMassDate(); + const currentData = this.data(); + const newMap = new Map(); + const newMomentsMap = new Map(); + + if (activeDate && currentData && currentData.masses[activeDate]) { + const mass = currentData.masses[activeDate]; + if (mass.suggestions) { + if (Array.isArray(mass.suggestions)) { + // Legacy flat suggestions format + mass.suggestions.forEach(s => { + if (s) { + const id = s.id_canto || (s as any).id_canti; + const weight = s.peso !== undefined ? s.peso : (s as any).score; + if (id) { + newMap.set(id, weight); + newMomentsMap.set(id, ['Generale']); + } + } + }); + } else { + // New moment-grouped suggestions format + Object.keys(mass.suggestions).forEach(moment => { + const momentSuggestions = (mass.suggestions as any)[moment]; + if (Array.isArray(momentSuggestions)) { + momentSuggestions.forEach(s => { + if (s) { + const id = s.id_canto || (s as any).id_canti; + const weight = s.peso !== undefined ? s.peso : (s as any).score; + if (id) { + // Save max weight + const existingWeight = newMap.get(id) || 0; + if (weight > existingWeight) { + newMap.set(id, weight); + } + + // Save liturgical moment + const existingMoments = newMomentsMap.get(id) || []; + if (!existingMoments.includes(moment)) { + newMomentsMap.set(id, [...existingMoments, moment]); + } + } + } + }); + } + }); + } + } + } + this.suggestionsMap.set(newMap); + this.suggestionsMomentsMap.set(newMomentsMap); + }); + + // Effect to persist selectedMassDate to local storage + effect(() => { + const activeDate = this.selectedMassDate(); + if (activeDate) { + localStorage.setItem('selected-mass-date', activeDate); + } + }); + } + + async init() { + // We assume CantiService has already created the storage, but to be safe: + this._storage = await this.storage.create(); + + // Load cached values + const cachedData = await this._storage?.get('cantiletture_data'); + if (cachedData) { + this.processData(cachedData); + } + + const savedDate = localStorage.getItem('selected-mass-date'); + if (savedDate) { + const masses = this.availableMasses(); + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const todayStr = `${year}-${month}-${day}`; + + // Only restore savedDate if it exists in available masses and is not outdated + const isValidAndNotPast = masses.some(m => m.date === savedDate && m.date >= todayStr); + if (isValidAndNotPast) { + this.selectedMassDate.set(savedDate); + } + } + + // Fetch fresh data + await this.fetchData(); + } + + async fetchData() { + try { + let fetchedData: CantiLettureData | null = null; + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const todayStr = `${year}-${month}-${day}`; + + const isProduction = window.location.hostname.includes('canticristiani.it'); + const primaryUrl = isProduction + ? `${window.location.origin}${this.SECURE_JSON_URL}` + : 'https://www.canticristiani.it/api/cantiletture.json'; + + // 1. Try static JSON endpoint first + try { + console.log('Fetching mass data from primary URL:', primaryUrl); + const res = await firstValueFrom(this.http.get(`${primaryUrl}?t=${Date.now()}`)); + if (res && res.masses && res.week_end && res.week_end >= todayStr) { + fetchedData = res; + } else { + console.warn('Primary JSON data is missing or out of date:', res?.week_end); + } + } catch (err) { + console.warn('Primary fetch failed:', err); + } + + // 2. Fallback to direct API endpoint using Basic Auth credentials + if (!fetchedData) { + try { + console.log('Fetching mass data from direct API:', this.JSON_URL); + const authUser = environment.apiAuthUser || 'canti'; + const authPass = environment.apiAuthPass || 'antani2026'; + const headers = new HttpHeaders({ + 'Authorization': 'Basic ' + btoa(`${authUser}:${authPass}`) + }); + const res = await firstValueFrom(this.http.get(`${this.JSON_URL}?t=${Date.now()}`, { headers })); + if (res && res.masses) { + fetchedData = res; + } + } catch (authErr) { + console.error('Direct API fetch failed:', authErr); + } + } + + if (fetchedData && fetchedData.masses) { + this.processData(fetchedData); + await this._storage?.set('cantiletture_data', fetchedData); + } + } catch (err) { + console.error('Failed to fetch cantiletture.json from both primary and fallback URLs', err); + } + } + + private processData(json: CantiLettureData) { + this.data.set(json); + + // Build available masses array + const massesList: AvailableMass[] = []; + const keys = Object.keys(json.masses).sort(); // Sort chronological + + keys.forEach(key => { + const mass = json.masses[key]; + const parts = key.split('-'); + let formattedLabel = key; + if (parts.length === 3) { + formattedLabel = `${parts[2]}/${parts[1]}`; + } + const day = mass.day || ''; + const title = mass.title || ''; + + massesList.push({ + date: key, + title: title, + day: day, + formattedLabel: `${day} ${formattedLabel}` + }); + }); + + this.availableMasses.set(massesList); + + if (massesList.length > 0) { + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const todayStr = `${year}-${month}-${day}`; + + const currentSelected = this.selectedMassDate(); + const isCurrentValid = currentSelected && massesList.some(m => m.date === currentSelected && m.date >= todayStr); + + if (!isCurrentValid) { + const match = massesList.find(m => m.date === todayStr); + if (match) { + this.selectedMassDate.set(match.date); + } else { + // If today is not present, find the first date that is in the future + const futureMatch = massesList.find(m => m.date >= todayStr); + if (futureMatch) { + this.selectedMassDate.set(futureMatch.date); + } else { + // Otherwise fall back to the last available mass date (closest to today) + this.selectedMassDate.set(massesList[massesList.length - 1].date); + } + } + } + } + } + + setSelectedMass(date: string) { + this.selectedMassDate.set(date); + } +} diff --git a/src/app/services/canti.service.ts b/src/app/services/canti.service.ts new file mode 100644 index 0000000..7c88b36 --- /dev/null +++ b/src/app/services/canti.service.ts @@ -0,0 +1,228 @@ +import { Injectable, signal, inject } from '@angular/core'; +import { HttpClient, HttpEventType } from '@angular/common/http'; +import { Storage } from '@ionic/storage-angular'; +import { SettingsService } from './settings.service'; + +export interface Canto { + id: string; + id_canti: number; + titolo: string; + testo: string; + accordi?: string; + autore?: string; + link_youtube?: string; + id_momenti?: number[]; + data_update?: string; + nonValidato?: boolean; + isPersonal?: boolean; + durata?: string; + bpm?: number; +} + +export interface Indice { + id: number; + tag_name: string; + slug: string; + type: 'liturgico' | 'tematico'; +} + +export interface CantoEseguito { + id_canti: number; + num: number; +} + +@Injectable({ + providedIn: 'root' +}) +export class CantiService { + private http = inject(HttpClient); + private storage = inject(Storage); + private settingsService = inject(SettingsService); + + private _storage: Storage | null = null; + public canti = signal([]); + public indiceLiturgico = signal([]); + public indiceTematico = signal([]); + public cantiEseguiti = signal([]); + // Keep momenti for backward compatibility or temporary usage + public momenti = signal([]); + public loading = signal(false); + public progress = signal(0); + public firstLoadCompleted = signal(false); + + private getApiUrl(): string { + const isProduction = window.location.hostname.includes('canticristiani.it'); + return isProduction + ? `${window.location.origin}/api/canti.json` + : 'https://www.canticristiani.it/api/canti.json'; + } + + constructor() { + this.init(); + } + + async init() { + const storage = await this.storage.create(); + this._storage = storage; + await this.loadFromStorage(); + if (this.canti() && this.canti().length > 0) { + this.firstLoadCompleted.set(true); + } else { + // First boot or data cleared: show setup loader immediately + if ((window as any).PwaLoader) { + (window as any).PwaLoader.show(); + (window as any).PwaLoader.update({ + title: 'Setup in corso', + phase: 'Fase: Setup', + desc: 'Configurazione iniziale e caricamento canti...', + percent: 0 + }); + } + } + this.refresh(); + } + + async loadFromStorage() { + const cachedCanti = await this._storage?.get('canti'); + const cachedLit = await this._storage?.get('indiceLiturgico'); + const cachedTem = await this._storage?.get('indiceTematico'); + const cachedEseguiti = await this._storage?.get('cantiEseguiti'); + if (cachedCanti) this.canti.set(cachedCanti); + if (cachedLit) this.indiceLiturgico.set(cachedLit); + if (cachedTem) this.indiceTematico.set(cachedTem); + if (cachedEseguiti) this.cantiEseguiti.set(cachedEseguiti); + // Sync momenti + if (cachedLit) this.momenti.set(cachedLit); + } + + refresh() { + this.loading.set(true); + this.progress.set(0); + + this.http.get(`${this.getApiUrl()}?t=${Date.now()}`, { + reportProgress: true, + observe: 'events' + }).subscribe({ + next: async (event: any) => { + if (event.type === HttpEventType.DownloadProgress) { + let pct = 0; + if (event.total) { + pct = Math.round((event.loaded / event.total) * 100); + this.progress.set(pct); + } else { + this.progress.update(p => p < 90 ? p + 5 : p); + pct = this.progress(); + } + if (!this.firstLoadCompleted() && (window as any).PwaLoader) { + (window as any).PwaLoader.update({ percent: pct }); + } + } else if (event.type === HttpEventType.Response) { + const response = event.body; + if (response?.canti?.data) { + const cantiData = response.canti.data; + const litData = (response.indice_liturgico?.data || []).map((x: any) => ({ + id: x.id_indice_liturgico, + tag_name: x.tag_name, + slug: x.slug, + type: 'liturgico' + })); + const temData = (response.indice_tematico?.data || []).map((x: any) => ({ + id: x.id_indice_tematico, + tag_name: x.tag_name, + slug: x.slug, + type: 'tematico' + })); + const pivotData = response.tema?.data || []; + + // Optimize linking: O(N+M) instead of O(N*M) + const pivotMap = new Map(); + pivotData.forEach((p: any) => { + if (!pivotMap.has(p.id_canti)) pivotMap.set(p.id_canti, []); + pivotMap.get(p.id_canti)!.push(p.id_momento); + }); + + const linkedCanti = cantiData.map((c: any) => ({ + ...c, + id: c.id_canti.toString(), + id_momenti: pivotMap.get(c.id_canti) || [] + })); + + const eseguitiData = response.canti_eseguiti?.data || []; + + this.canti.set(linkedCanti); + this.indiceLiturgico.set(litData); + this.indiceTematico.set(temData); + this.momenti.set(litData); // Fallback + this.cantiEseguiti.set(eseguitiData); + + await this._storage?.set('canti', linkedCanti); + await this._storage?.set('indiceLiturgico', litData); + await this._storage?.set('indiceTematico', temData); + await this._storage?.set('cantiEseguiti', eseguitiData); + } + this.progress.set(100); + this.loading.set(false); + this.firstLoadCompleted.set(true); + } + }, + error: (error) => { + console.error('Failed to fetch canti', error); + this.loading.set(false); + this.firstLoadCompleted.set(true); + } + }); + } + + getCantoById(id: string) { + return this.canti().find(c => c.id === id); + } + + getSongTags(canto: Canto): string[] { + if (!canto.id_momenti || canto.id_momenti.length === 0) return []; + const tags: string[] = []; + const lit = this.indiceLiturgico(); + const tem = this.indiceTematico(); + + canto.id_momenti.forEach(id => { + const matchLit = lit.find(x => x.id === id); + if (matchLit) { + tags.push(matchLit.tag_name); + } else { + const matchTem = tem.find(x => x.id === id); + if (matchTem) { + tags.push(matchTem.tag_name); + } + } + }); + return tags; + } + + formatUpdateDate(dateStr: string | undefined): string { + if (!dateStr) return ''; + try { + const parts = dateStr.split(' ')[0].split('-'); + if (parts.length === 3) { + return `${parts[2]}/${parts[1]}/${parts[0]}`; + } + } catch (e) {} + return dateStr; + } + + getYoutubeId(urlOrId: string | undefined): string | null { + if (!urlOrId) return null; + if (urlOrId.length === 11) return urlOrId; + + const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; + const match = urlOrId.match(regExp); + return (match && match[7].length === 11) ? match[7] : null; + } + + getYoutubeThumb(urlOrId: string | undefined): string | null { + const id = this.getYoutubeId(urlOrId); + return id ? `https://img.youtube.com/vi/${id}/mqdefault.jpg` : null; + } + + getStorage() { + return this._storage; + } +} diff --git a/src/app/services/comunita.service.ts b/src/app/services/comunita.service.ts new file mode 100644 index 0000000..6bf9ddb --- /dev/null +++ b/src/app/services/comunita.service.ts @@ -0,0 +1,283 @@ +import { Injectable, signal, inject, effect } from '@angular/core'; +import { HttpClient, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http'; +import { SettingsService } from './settings.service'; +import { Canto } from './canti.service'; + +export interface ParrocchiaItem { + id_parrocchia: number; + nome: string; + codice: string; + mail: string; + guid_parrocchia: string; +} + +export interface ParrocchiaCantiItem { + id_parrocchia: number; + id_canti: number; + num_canto: number; +} + +export interface CantiSettingsItem { + id_canti: number; + speed: number; + tonalita: number; +} + +export interface ComunitaScaletta { + id: string; + name: string; + date: string; + ids: string[]; +} + +export interface GetAllAppTablesResponse { + parrocchia?: { data: ParrocchiaItem[] }; + parrocchia_canti?: { data: ParrocchiaCantiItem[] }; + canti_settings?: { data: CantiSettingsItem[] }; +} + +@Injectable({ + providedIn: 'root' +}) +export class ComunitaService { + private http = inject(HttpClient); + private settingsService = inject(SettingsService); + + public comunitaCode = signal(''); + public comunitaNome = signal(''); + public comunitaMail = signal(''); + public comunitaCantiIds = signal<(number | string)[]>([]); + public comunitaCantiInfo = signal([]); + public comunitaCantiSettings = signal([]); + public comunitaCantiPersonali = signal([]); + public comunitaScalette = signal([]); + public isFilterActive = signal(false); + public loading = signal(false); + public loadingProgress = signal(0); + + constructor() { + const savedCode = localStorage.getItem('comunita-code'); + const savedNome = localStorage.getItem('comunita-nome'); + const savedMail = localStorage.getItem('comunita-mail'); + const savedCanti = localStorage.getItem('comunita-canti-ids'); + const savedInfo = localStorage.getItem('comunita-canti-info'); + const savedSettings = localStorage.getItem('comunita-canti-settings'); + const savedCantiPersonali = localStorage.getItem('comunita-canti-personali'); + const savedScalette = localStorage.getItem('comunita-scalette'); + const savedFilterActive = localStorage.getItem('comunita-filter-active') === 'true'; + + if (savedCode) { + this.comunitaCode.set(savedCode); + // Run background refresh 1 second after startup to fetch any new custom canti or updates + // but only if the community feature is enabled in settings + setTimeout(() => { + if (!this.settingsService.comunitaEnabled()) { + // Community is disabled: skip refresh to avoid re-enabling the filter + return; + } + this.setComunitaCode(savedCode).catch(err => { + console.warn('Failed background community refresh at startup:', err); + }); + }, 1000); + } + if (savedNome) this.comunitaNome.set(savedNome); + if (savedMail) this.comunitaMail.set(savedMail); + if (savedCanti) { + try { this.comunitaCantiIds.set(JSON.parse(savedCanti)); } catch (e) {} + } + if (savedInfo) { + try { this.comunitaCantiInfo.set(JSON.parse(savedInfo)); } catch (e) {} + } + if (savedSettings) { + try { this.comunitaCantiSettings.set(JSON.parse(savedSettings)); } catch (e) {} + } + if (savedCantiPersonali) { + try { this.comunitaCantiPersonali.set(JSON.parse(savedCantiPersonali)); } catch (e) {} + } + if (savedScalette) { + try { this.comunitaScalette.set(JSON.parse(savedScalette)); } catch (e) {} + } + this.isFilterActive.set(savedFilterActive); + + effect(() => { + localStorage.setItem('comunita-code', this.comunitaCode()); + localStorage.setItem('comunita-nome', this.comunitaNome()); + localStorage.setItem('comunita-mail', this.comunitaMail()); + localStorage.setItem('comunita-canti-ids', JSON.stringify(this.comunitaCantiIds())); + localStorage.setItem('comunita-canti-info', JSON.stringify(this.comunitaCantiInfo())); + localStorage.setItem('comunita-canti-settings', JSON.stringify(this.comunitaCantiSettings())); + localStorage.setItem('comunita-canti-personali', JSON.stringify(this.comunitaCantiPersonali())); + localStorage.setItem('comunita-scalette', JSON.stringify(this.comunitaScalette())); + localStorage.setItem('comunita-filter-active', this.isFilterActive().toString()); + }); + + effect(() => { + if (!this.settingsService.comunitaEnabled()) { + this.isFilterActive.set(false); + } + }); + } + + private fetchWithProgress(url: string): Promise { + return new Promise((resolve, reject) => { + const req = new HttpRequest('GET', url, { + reportProgress: true, + responseType: 'json' + }); + + this.http.request(req).subscribe({ + next: (event) => { + if (event.type === HttpEventType.DownloadProgress) { + if (event.total && event.total > 0) { + const pct = Math.round((event.loaded / event.total) * 100); + this.loadingProgress.set(pct); + } else { + // No Content-Length header — simulate gradual progress up to 85% + const simulated = Math.min(85, this.loadingProgress() + 12); + this.loadingProgress.set(simulated); + } + } else if (event instanceof HttpResponse) { + this.loadingProgress.set(100); + resolve(event.body as T); + } + }, + error: (err) => reject(err) + }); + }); + } + + async setComunitaCode(code: string): Promise { + const trimmedCode = code.trim(); + if (!trimmedCode) { + this.comunitaCode.set(''); + this.comunitaNome.set(''); + this.comunitaMail.set(''); + this.comunitaCantiIds.set([]); + this.comunitaCantiInfo.set([]); + this.comunitaCantiSettings.set([]); + this.comunitaCantiPersonali.set([]); + this.comunitaScalette.set([]); + this.isFilterActive.set(false); + return true; + } + + this.loading.set(true); + this.loadingProgress.set(0); + + // 1. Try to fetch from the actual production API + try { + const url = `https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables?uuid=pwa-cc-uuid&email=&platform=browser&version=1.0&gruppo=${trimmedCode}&all_song=false&t=${Date.now()}`; + const data = await this.fetchWithProgress(url); + + if (data && data.parrocchia?.data && data.parrocchia.data.length > 0) { + const parrocchia = data.parrocchia.data[0]; + const cantiList = data.parrocchia_canti?.data || []; + const settingsList = data.canti_settings?.data || []; + + // Parse canti_personali (custom unvalidated community canti) + const cantiPersonaliList = (data as any).canti_personali?.data || []; + const mappedCantiPersonali = cantiPersonaliList.map((cp: any) => ({ + id: cp.id_canti.toString(), + id_canti: cp.id_canti, + titolo: cp.titolo, + testo: cp.accordi || '', + accordi: cp.accordi || '', + autore: cp.autore || '', + link_youtube: cp.link_youtube || '', + id_momenti: [], + data_update: cp.data_update || '', + nonValidato: Number(cp.stato) === 10, + isPersonal: true, + durata: cp.durata || '', + bpm: cp.bpm !== undefined && cp.bpm !== null ? Number(cp.bpm) : undefined + })); + + this.comunitaCode.set(trimmedCode); + this.comunitaNome.set(parrocchia.nome || `Comunità ${trimmedCode}`); + this.comunitaMail.set(parrocchia.mail || ''); + this.comunitaCantiInfo.set(cantiList); + this.comunitaCantiIds.set(cantiList.map(c => c.id_canti)); + this.comunitaCantiSettings.set(settingsList); + this.comunitaCantiPersonali.set(mappedCantiPersonali); + + // Parse scalette (setlists) from lista_nome + lista_esecuzione + const listaNomelList = (data as any).lista_nome?.data || []; + const listaEsecuzioneList = (data as any).lista_esecuzione?.data || []; + + // Group lista_esecuzione by id_lista and keep order by progr + const esecuzioniByLista = new Map(); + for (const item of listaEsecuzioneList) { + if (!esecuzioniByLista.has(item.id_lista)) { + esecuzioniByLista.set(item.id_lista, []); + } + esecuzioniByLista.get(item.id_lista)!.push({ + id_canti: String(item.id_canti), + progr: Number(item.progr) || 0 + }); + } + + // Build scalette array sorted by date (most recent first) + const scalette: ComunitaScaletta[] = listaNomelList + .map((ln: any) => { + const songs = esecuzioniByLista.get(ln.id_lista) || []; + songs.sort((a: any, b: any) => a.progr - b.progr); + return { + id: `comunita_${ln.id_lista}`, + name: ln.nome || 'Scaletta', + date: ln.progr || '', + ids: songs.map((s: any) => s.id_canti) + }; + }) + .filter((s: ComunitaScaletta) => s.ids.length > 0) + .sort((a: ComunitaScaletta, b: ComunitaScaletta) => b.date.localeCompare(a.date)); + + this.comunitaScalette.set(scalette); + this.isFilterActive.set(true); + this.loading.set(false); + return true; + } + } catch (err) { + console.warn('Failed to fetch from production API, trying fallback...', err); + this.loadingProgress.set(0); + } + + // 2. Fallback to static community JSON + try { + const isProduction = window.location.hostname.includes('canticristiani.it'); + const origin = isProduction ? window.location.origin : 'https://www.canticristiani.it'; + const fallbackUrl = `${origin}/api/comunita_${trimmedCode}.json?t=${Date.now()}`; + + interface StaticComunitaData { + id_comunita: string; + nome_comunita: string; + canti: (number | string)[]; + } + + const staticData = await this.fetchWithProgress(fallbackUrl); + if (staticData && staticData.canti) { + this.comunitaCode.set(trimmedCode); + this.comunitaNome.set(staticData.nome_comunita || `Comunità ${trimmedCode}`); + this.comunitaCantiIds.set(staticData.canti); + + const mockInfo = staticData.canti.map((id, index) => ({ + id_parrocchia: 1, + id_canti: Number(id), + num_canto: index + 1 + })); + + this.comunitaCantiInfo.set(mockInfo); + this.comunitaCantiSettings.set([]); + this.comunitaCantiPersonali.set([]); + this.comunitaScalette.set([]); + this.isFilterActive.set(true); + this.loading.set(false); + return true; + } + } catch (err) { + console.error('All community fetch strategies failed:', err); + } + + this.loading.set(false); + return false; + } +} diff --git a/src/app/services/connectivity.service.ts b/src/app/services/connectivity.service.ts new file mode 100644 index 0000000..16c683b --- /dev/null +++ b/src/app/services/connectivity.service.ts @@ -0,0 +1,13 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ConnectivityService { + public isOnline = signal(navigator.onLine); + + constructor() { + window.addEventListener('online', () => this.isOnline.set(true)); + window.addEventListener('offline', () => this.isOnline.set(false)); + } +} diff --git a/src/app/services/face-detector.service.ts b/src/app/services/face-detector.service.ts new file mode 100644 index 0000000..61e64ee --- /dev/null +++ b/src/app/services/face-detector.service.ts @@ -0,0 +1,387 @@ +import { Injectable, inject, signal } from '@angular/core'; +import { SettingsService } from './settings.service'; + +@Injectable({ + providedIn: 'root' +}) +export class FaceDetectorService { + private settingsService = inject(SettingsService); + + public isCameraActive = signal(false); + public currentTiltAngle = signal(0); + public isTilted = signal(false); + + // Segnali di stato per la modalità distanza viso + public currentDistanceRatio = signal(1.0); // Rapporto rispetto alla distanza di riposo (es. 1.25 = 25% più vicino, 0.75 = 25% più lontano) + public distanceState = signal<'idle' | 'approaching' | 'receding'>('idle'); // Stato dinamico rilevato + + private stream: MediaStream | null = null; + private camera: any = null; + private faceMesh: any = null; + private onTriggerCallback: ((direction: 'next' | 'prev') => void) | null = null; + private isProcessingFrame: boolean = false; + + // Gesture state machine - Tilt (inclinazione testa) + private tiltStartTime: number = 0; + private tiltInCooldown: boolean = false; + private lastTiltTriggerTime: number = 0; + private readonly TILT_THRESHOLD = 15; // Gradi per scattare avanti/dietro (originale: 15°) + private readonly TILT_HOLD_MS = 250; // Durata mantenimento inclinazione (ms) + private readonly RETURN_THRESHOLD = 6; // Gradi per reimpostare il cooldown (originale: 6°) + private readonly TRIGGER_COOLDOWN_MS = 2000; // Tempo minimo tra due scatti consecutivi (ms) + + // Gesture state machine - Distance (avvicinamento / allontanamento viso) + // Utilizziamo la distanza geometrica normalizzata tra gli angoli esterni degli occhi (33 e 263) e tra fronte (10) e mento (152) + private baselineFaceSize: number = 0; // Dimensione di riferimento del viso in posizione neutra + private smoothedFaceSize: number = 0; // Media mobile per evitare jitter/rumore + private distanceStartTime: number = 0; // Timestamp di inizio superamento soglia + private distanceInCooldown: boolean = false; // Flag di attesa ritorno a neutro + private lastDistanceTriggerTime: number = 0; // Timestamp ultimo scatto + private activeDistanceDirection: 'next' | 'prev' | null = null; + + constructor() {} + + /** + * Loads MediaPipe scripts dynamically if not already loaded. + */ + private loadScripts(): Promise { + return new Promise((resolve, reject) => { + if ((window as any).FaceMesh && (window as any).Camera) { + resolve(); + return; + } + + const cameraScript = document.createElement('script'); + cameraScript.src = 'assets/mediapipe/camera_utils.js'; + + const faceMeshScript = document.createElement('script'); + faceMeshScript.src = 'assets/mediapipe/face_mesh.js'; + + cameraScript.onload = () => { + document.head.appendChild(faceMeshScript); + }; + + faceMeshScript.onload = () => { + resolve(); + }; + + cameraScript.onerror = (err) => reject(err); + faceMeshScript.onerror = (err) => reject(err); + + document.head.appendChild(cameraScript); + }); + } + + /** + * Starts camera capture and face mesh tracking. + */ + async start(videoElement: HTMLVideoElement, onTrigger: (direction: 'next' | 'prev') => void): Promise { + this.onTriggerCallback = onTrigger; + + if (this.isCameraActive()) { + return; + } + + try { + await this.loadScripts(); + + const FaceMeshLib = (window as any).FaceMesh; + const CameraLib = (window as any).Camera; + + if (!FaceMeshLib || !CameraLib) { + throw new Error('MediaPipe libraries failed to initialize.'); + } + + if (!this.faceMesh) { + this.faceMesh = new FaceMeshLib({ + locateFile: (file: string) => `assets/mediapipe/${file}` + }); + + this.faceMesh.setOptions({ + maxNumFaces: 1, + refineLandmarks: false, + minDetectionConfidence: 0.5, + minTrackingConfidence: 0.5 + }); + + this.faceMesh.onResults((results: any) => { + this.processLandmarks(results); + }); + } + + // Reset immediato per calibrazione istantanea al primo frame utile + this.resetDistanceBaseline(); + + this.isCameraActive.set(true); + + // Usiamo CameraLib direttamente per gestire lo stream ed evitare doppi stream / loop + this.isProcessingFrame = false; + this.camera = new CameraLib(videoElement, { + onFrame: async () => { + if (!this.isCameraActive() || !this.faceMesh) return; + if (this.isProcessingFrame) return; // Salta il frame se il precedente è ancora in elaborazione (anti-lag & memory leak) + + this.isProcessingFrame = true; + try { + await this.faceMesh.send({ image: videoElement }); + } catch (e) { + console.warn('[FaceDetector] Error sending frame to FaceMesh:', e); + } finally { + this.isProcessingFrame = false; + } + }, + width: 320, + height: 240, + facingMode: 'user' + }); + + await this.camera.start(); + console.log('[FaceDetector] Face tracking started successfully.'); + } catch (err) { + console.error('[FaceDetector] Failed to start face tracking:', err); + this.stop(); + throw err; + } + } + + /** + * Resetta la dimensione di riferimento (baseline) della distanza del viso + */ + /** + * Resetta la dimensione di riferimento (baseline) della distanza del viso per calibrazione istantanea + */ + public resetDistanceBaseline() { + this.baselineFaceSize = 0; + this.smoothedFaceSize = 0; + this.currentDistanceRatio.set(1.0); + this.distanceState.set('idle'); + this.distanceStartTime = 0; + this.distanceInCooldown = false; + this.activeDistanceDirection = null; + this.lastDistanceTriggerTime = 0; + } + + /** + * Processes landmarks to calculate head tilt angle or face distance. + */ + private processLandmarks(results: any) { + if (!results.multiFaceLandmarks || results.multiFaceLandmarks.length === 0) { + this.currentTiltAngle.set(0); + this.isTilted.set(false); + this.distanceState.set('idle'); + return; + } + + const landmarks = results.multiFaceLandmarks[0]; + + // Landmark essenziali: + // 33: occhio sinistro esterno, 263: occhio destro esterno + // 10: fronte / attaccatura capelli superiore, 152: mento inferiore + const leftEye = landmarks[33]; + const rightEye = landmarks[263]; + const topForehead = landmarks[10]; + const chin = landmarks[152]; + + if (!leftEye || !rightEye) return; + + // Calcolo roll/inclinazione testa (sempre aggiornato per visualizzazione e modalità tilt) + const dy = rightEye.y - leftEye.y; + const dx = rightEye.x - leftEye.x; + const angle = Math.atan2(dy, dx) * (180 / Math.PI); + this.currentTiltAngle.set(Math.round(angle)); + + const trackingMode = this.settingsService.cameraTrackingMode(); + + if (trackingMode === 'distance') { + this.processDistanceGesture(leftEye, rightEye, topForehead, chin); + } else { + this.processTiltGesture(angle); + } + } + + /** + * Gestione del gesto basato sulla distanza del viso dalla fotocamera + */ + private processDistanceGesture(leftEye: any, rightEye: any, topForehead: any, chin: any) { + // Calcoliamo la larghezza occhi (inter-ocular distance) e l'altezza del viso + const eyeDistX = rightEye.x - leftEye.x; + const eyeDistY = rightEye.y - leftEye.y; + const eyeDist = Math.sqrt(eyeDistX * eyeDistX + eyeDistY * eyeDistY); + + let faceHeight = eyeDist; + if (topForehead && chin) { + const faceHeightX = chin.x - topForehead.x; + const faceHeightY = chin.y - topForehead.y; + faceHeight = Math.sqrt(faceHeightX * faceHeightX + faceHeightY * faceHeightY); + } + + // Media armonica combinata di larghezza occhi e altezza viso per massima accuratezza invariante da rotazioni + const currentMeasuredSize = (eyeDist * 1.5 + faceHeight) / 2.5; + + // Calibrazione ISTANTANEA al primo frame utile (funziona subito senza attendere) + if (this.smoothedFaceSize === 0 || this.baselineFaceSize === 0) { + this.smoothedFaceSize = currentMeasuredSize; + this.baselineFaceSize = currentMeasuredSize; + this.currentDistanceRatio.set(1.0); + this.distanceState.set('idle'); + return; + } + + // Filtro a media mobile esponenziale (EMA) rapido per evitare jitter + this.smoothedFaceSize = this.smoothedFaceSize * 0.65 + currentMeasuredSize * 0.35; + + const ratio = this.baselineFaceSize > 0 ? (this.smoothedFaceSize / this.baselineFaceSize) : 1.0; + this.currentDistanceRatio.set(Math.round(ratio * 100) / 100); + + const now = Date.now(); + + // Soglie per scatto immediato ed ergonomico: + // +12% per avanzare, -12% per retrocedere + const approachThreshold = 1.12; + const recedeThreshold = 0.88; + const returnHigh = 1.05; + const returnLow = 0.95; + const holdMs = 120; // Reattività immediata (120ms) + const distanceCooldownMs = 900; // Cooldown fluido tra scatti consecutivi (0.9s) + + // Adattamento graduale della baseline SOLO quando l'utente è stabile e rilassato al centro + if (!this.distanceInCooldown && ratio >= returnLow && ratio <= returnHigh && this.activeDistanceDirection === null) { + this.baselineFaceSize = this.baselineFaceSize * 0.985 + this.smoothedFaceSize * 0.015; + } + + // Riconoscimento avvicinamento (Next) + if (ratio >= approachThreshold) { + this.distanceState.set('approaching'); + + if (!this.distanceInCooldown && (now - this.lastDistanceTriggerTime > distanceCooldownMs)) { + if (this.activeDistanceDirection !== 'next') { + this.activeDistanceDirection = 'next'; + this.distanceStartTime = now; + } else if (now - this.distanceStartTime >= holdMs) { + // Trigger avvicinamento -> AVANTI + console.log(`[FaceDetector] Face approach gesture detected! Ratio: ${ratio.toFixed(2)} -> NEXT`); + if (this.onTriggerCallback) { + this.onTriggerCallback('next'); + } + this.distanceInCooldown = true; + this.activeDistanceDirection = null; + this.distanceStartTime = 0; + this.lastDistanceTriggerTime = now; + } + } + } + // Riconoscimento allontanamento (Prev) + else if (ratio <= recedeThreshold) { + this.distanceState.set('receding'); + + if (!this.distanceInCooldown && (now - this.lastDistanceTriggerTime > distanceCooldownMs)) { + if (this.activeDistanceDirection !== 'prev') { + this.activeDistanceDirection = 'prev'; + this.distanceStartTime = now; + } else if (now - this.distanceStartTime >= holdMs) { + // Trigger allontanamento -> INDIETRO + console.log(`[FaceDetector] Face recede gesture detected! Ratio: ${ratio.toFixed(2)} -> PREV`); + if (this.onTriggerCallback) { + this.onTriggerCallback('prev'); + } + this.distanceInCooldown = true; + this.activeDistanceDirection = null; + this.distanceStartTime = 0; + this.lastDistanceTriggerTime = now; + } + } + } + // Posizione neutra + else { + this.distanceState.set('idle'); + this.activeDistanceDirection = null; + this.distanceStartTime = 0; + + // Reset cooldown quando l'utente torna alla distanza neutra + if (ratio < returnHigh && ratio > returnLow) { + this.distanceInCooldown = false; + } + } + } + + /** + * Gestione del gesto basato sull'inclinazione del collo (modalità tilt) + */ + private processTiltGesture(angle: number) { + const absAngle = Math.abs(angle); + const now = Date.now(); + + if (absAngle > this.TILT_THRESHOLD) { + this.isTilted.set(true); + + if (!this.tiltInCooldown && (now - this.lastTiltTriggerTime > this.TRIGGER_COOLDOWN_MS)) { + if (this.tiltStartTime === 0) { + this.tiltStartTime = now; + } else if (now - this.tiltStartTime >= this.TILT_HOLD_MS) { + // Trigger the tilt gesture! + const direction = angle > 0 ? 'prev' : 'next'; + console.log(`[FaceDetector] Head tilt gesture detected! Angle: ${angle.toFixed(1)}°, Direction: ${direction}`); + if (this.onTriggerCallback) { + this.onTriggerCallback(direction); + } + this.tiltInCooldown = true; + this.tiltStartTime = 0; + this.lastTiltTriggerTime = now; + } + } + } else { + this.isTilted.set(false); + this.tiltStartTime = 0; + + // Reset cooldown when the head returns near the center + if (absAngle < this.RETURN_THRESHOLD) { + this.tiltInCooldown = false; + } + } + } + + /** + * Pauses the frame tracking loop without killing the underlying media stream hardware. + */ + pause() { + this.isCameraActive.set(false); + this.isProcessingFrame = false; + if (this.camera) { + try { + this.camera.stop(); + } catch (e) {} + this.camera = null; + } + } + + /** + * Stops camera capture and releases face mesh & hardware stream resources. + */ + stop() { + this.pause(); + this.currentTiltAngle.set(0); + this.isTilted.set(false); + this.tiltInCooldown = false; + this.tiltStartTime = 0; + this.lastTiltTriggerTime = 0; + this.resetDistanceBaseline(); + + if (this.stream) { + try { + this.stream.getTracks().forEach(track => track.stop()); + } catch (e) {} + this.stream = null; + } + + if (this.faceMesh) { + try { + this.faceMesh.close(); + } catch (e) {} + this.faceMesh = null; + } + + this.onTriggerCallback = null; + console.log('[FaceDetector] Face tracking fully stopped.'); + } +} + diff --git a/src/app/services/lyrics-parser.service.spec.ts b/src/app/services/lyrics-parser.service.spec.ts new file mode 100644 index 0000000..05f8161 --- /dev/null +++ b/src/app/services/lyrics-parser.service.spec.ts @@ -0,0 +1,148 @@ +import { TestBed } from '@angular/core/testing'; +import { LyricsParserService } from './lyrics-parser.service'; +import { SettingsService } from './settings.service'; + +describe('LyricsParserService - Hybrid Notation', () => { + let service: LyricsParserService; + let mockSettingsService: any; + + beforeEach(() => { + mockSettingsService = { + chordNotationPreference: jasmine.createSpy('chordNotationPreference').and.returnValue('diesis') + }; + + TestBed.configureTestingModule({ + providers: [ + LyricsParserService, + { provide: SettingsService, useValue: mockSettingsService } + ] + }); + service = TestBed.inject(LyricsParserService); + }); + + it('should parse simple text with memorize, replay, copy, paste', () => { + const rawSong = ` +{start_verse}{memorize/m1} +Ralle[RE]griamoci, [LA] +non [SOL]c’è spazio alla tri[RE]stezza in questo gior[LA]no [SOL] +{end_verse} + +{start_chorus}{copy/rit} +Gloria a [RE]Te Emma[SOL]nue-[LA]le +{end_chorus} + +{start_verse}{replay/m1} +Rallegri*amoci,* +Egli *viene a libe*rarci da ogni *male.* +{end_verse} + +{start_chorus}{paste/rit} +{end_chorus} +`; + + // 1. Test parsing with chords enabled + const sections = service.parseAccordi(rawSong); + expect(sections.length).toBe(4); + + // Verse 1 (memorize) + expect(sections[0].type).toBe('verse'); + expect(sections[0].lines[0].text).toBe('Rallegriamoci, '); + expect(sections[0].lines[0].segments[0].chord).toBeUndefined(); + expect(sections[0].lines[0].segments[1].chord).toBe('RE'); + expect(sections[0].lines[0].segments[2].chord).toBe('LA'); + + // Chorus 1 (copy) + expect(sections[1].type).toBe('chorus'); + expect(sections[1].lines[0].text).toBe('Gloria a Te Emmanue-le'); + expect(sections[1].lines[0].segments[0].chord).toBeUndefined(); + expect(sections[1].lines[0].segments[1].chord).toBe('RE'); + expect(sections[1].lines[0].segments[2].chord).toBe('SOL'); + expect(sections[1].lines[0].segments[3].chord).toBe('LA'); + + // Verse 2 (replay) + expect(sections[2].type).toBe('verse'); + expect(sections[2].lines[0].text).toBe('Rallegriamoci,'); + expect(sections[2].lines[0].segments[0].chord).toBeUndefined(); + expect(sections[2].lines[0].segments[1].chord).toBe('RE'); + expect(sections[2].lines[0].segments[2].chord).toBe('LA'); + + expect(sections[2].lines[1].text).toBe('Egli viene a liberarci da ogni male.'); + expect(sections[2].lines[1].segments[0].chord).toBeUndefined(); + expect(sections[2].lines[1].segments[1].chord).toBe('SOL'); + expect(sections[2].lines[1].segments[2].chord).toBe('RE'); + expect(sections[2].lines[1].segments[3].chord).toBe('LA'); + expect(sections[2].lines[1].segments[4].chord).toBe('SOL'); + + // Chorus 2 (paste) + expect(sections[3].type).toBe('chorus'); + expect(sections[3].lines[0].text).toBe('Gloria a Te Emmanue-le'); + expect(sections[3].lines[0].segments[0].chord).toBeUndefined(); + expect(sections[3].lines[0].segments[1].chord).toBe('RE'); + expect(sections[3].lines[0].segments[2].chord).toBe('SOL'); + expect(sections[3].lines[0].segments[3].chord).toBe('LA'); + }); + + it('should strip chords in text-only mode and remove asterisks', () => { + const rawSong = ` +{start_verse}{memorize/m1} +Ralle[RE]griamoci, [LA] +{end_verse} + +{start_verse}{replay/m1} +Rallegri*amoci,* +{end_verse} +`; + const sections = service.parseText(rawSong); + expect(sections.length).toBe(2); + + expect(sections[0].lines[0].text).toBe('Rallegriamoci,'); + expect(sections[0].lines[0].segments[0].chord).toBeUndefined(); + + expect(sections[1].lines[0].text).toBe('Rallegriamoci,'); + expect(sections[1].lines[0].segments[0].chord).toBeUndefined(); + }); + it('should format sections outside of soc/eoc tags as verses', () => { + const rawSong = ` +{c:Intro:} [RE] + +[RE]Guardami Signor +{soc} +Abba Padre! +{eoc} +[RE]Più solo non sarò +`; + const sections = service.parseAccordi(rawSong); + // There should be three sections: + // 1. Verse (Intro & Guardami Signor) + // 2. Chorus (Abba Padre) + // 3. Verse (Più solo non sarò) + expect(sections.length).toBe(3); + expect(sections[0].type).toBe('verse'); + expect(sections[0].lines[0].text).toBe('Intro '); + expect(sections[0].lines[0].segments[0].text).toBe('Intro '); + expect(sections[0].lines[0].segments[0].chord).toBeUndefined(); + expect(sections[0].lines[0].segments[1].chord).toBe('RE'); + expect(sections[0].lines[1].text).toBe('Guardami Signor'); + expect(sections[1].type).toBe('chorus'); + expect(sections[2].type).toBe('verse'); + }); + + it('should parse vertical bars | as chords', () => { + const rawSong = ` +[SOL] | [RE] | [DO] | [RE] +| | | | +`; + const sections = service.parseAccordi(rawSong); + expect(sections.length).toBe(1); + const line1 = sections[0].lines[0]; + const line2 = sections[0].lines[1]; + + // Check first line: SOL | RE | DO | RE + // All components should be parsed as chords + expect(line1.segments.map(s => s.chord)).toEqual(['SOL', '|', 'RE', '|', 'DO', '|', 'RE']); + expect(line1.segments.map(s => s.text.trim())).toEqual(['', '', '', '', '', '', '']); + + // Check second line: | | | | + expect(line2.segments.map(s => s.chord)).toEqual(['|', '|', '|', '|']); + }); +}); diff --git a/src/app/services/lyrics-parser.service.ts b/src/app/services/lyrics-parser.service.ts new file mode 100644 index 0000000..e45043f --- /dev/null +++ b/src/app/services/lyrics-parser.service.ts @@ -0,0 +1,413 @@ +import { Injectable, inject } from '@angular/core'; +import { SettingsService } from './settings.service'; + +export interface ChordSegment { + text: string; + chord?: string; +} + +export interface ParsedLine { + segments: ChordSegment[]; + text: string; +} + +export interface ParsedSection { + type: 'verse' | 'chorus' | 'verse_num'; + lines: ParsedLine[]; + verseNumber?: number; +} + +@Injectable({ + providedIn: 'root' +}) +export class LyricsParserService { + private settingsService = inject(SettingsService); + + /** + * Parse plain text (campo 'testo') into structured sections. + */ + parseText(raw: string): ParsedSection[] { + if (!raw) return []; + return this.parseSections(raw, false); + } + + /** + * Parse text with inline chords (campo 'accordi') into structured sections. + */ + parseAccordi(raw: string): ParsedSection[] { + if (!raw) return []; + return this.parseSections(raw, true); + } + + private parseSections(raw: string, withChords: boolean): ParsedSection[] { + const sections: ParsedSection[] = []; + let currentType: 'verse' | 'chorus' | 'verse_num' = 'verse'; + let currentLines: ParsedLine[] = []; + let verseNumCounter = 0; + + const memories = new Map(); + const copies = new Map(); + + let currentAction: { type: 'memorize' | 'replay' | 'copy' | 'paste'; key: string } | null = null; + let currentRawLines: string[] = []; + + const lines = raw.split('\n'); + const startTagRegex = /^\{(start_verse|start_chorus|start_verse_num|sov|soc)\}(?:\{([a-z]+)\/([a-zA-Z0-9_-]+)\})?$/; + + for (const line of lines) { + const trimmed = line.trim(); + + const startMatch = trimmed.match(startTagRegex); + if (startMatch) { + this.pushSection(sections, currentType, currentLines); + + const tag = startMatch[1]; + if (tag === 'start_verse' || tag === 'sov') { + currentType = 'verse'; + } else if (tag === 'start_chorus' || tag === 'soc') { + currentType = 'chorus'; + } else if (tag === 'start_verse_num') { + currentType = 'verse_num'; + verseNumCounter++; + } + + currentLines = []; + currentRawLines = []; + + if (startMatch[2] && startMatch[3]) { + currentAction = { + type: startMatch[2] as any, + key: startMatch[3] + }; + + if (currentAction.type === 'paste') { + const pastedRawLines = copies.get(currentAction.key) || []; + for (const pLine of pastedRawLines) { + if (withChords) { + currentLines.push(this.parseChordLine(pLine)); + } else { + const cleanLine = pLine.replace(/\[[^\]]*\]/g, '').trim(); + if (cleanLine.length > 0) { + currentLines.push({ + text: cleanLine, + segments: [{ text: cleanLine }] + }); + } + } + } + } + } else { + currentAction = null; + } + continue; + } + + // Detect section end tags + if (trimmed === '{end_verse}' || trimmed === '{eov}' || trimmed === '{end_chorus}' || trimmed === '{eoc}' || trimmed === '{end_verse_num}') { + if (currentAction) { + if (currentAction.type === 'memorize') { + memories.set(currentAction.key, [...currentRawLines]); + } else if (currentAction.type === 'copy') { + copies.set(currentAction.key, [...currentRawLines]); + } + } + + this.pushSection(sections, currentType, currentLines, currentType === 'verse_num' ? verseNumCounter : undefined); + currentLines = []; + currentRawLines = []; + currentAction = null; + currentType = 'verse'; + continue; + } + + // Skip structural tags (already handled above) + if (trimmed.startsWith('{') && trimmed.endsWith('}') && !trimmed.startsWith('{c:') && !trimmed.startsWith('{comment:')) { + continue; + } + + // Skip empty lines + if (trimmed.length === 0) { + continue; + } + + let resolvedLine = line; + if (currentAction && currentAction.type === 'replay') { + const memLines = memories.get(currentAction.key) || []; + const lineIndex = currentRawLines.length; + if (lineIndex < memLines.length) { + const memLine = memLines[lineIndex]; + const chordMatches = [...memLine.matchAll(/\[([^\]]+)\]/g)].map(m => m[0]); + let chordIdx = 0; + resolvedLine = line.replace(/\*/g, () => { + if (chordIdx < chordMatches.length) { + return chordMatches[chordIdx++]; + } + return ''; + }); + } else { + resolvedLine = line.replace(/\*/g, ''); + } + } + + // Clean comment tags: {c:Text} or {comment:Text} -> Text (removing trailing colon if any) + resolvedLine = resolvedLine.replace(/\{(?:c|comment):([^}]+)\}/g, (match, p1) => { + return p1.trim().replace(/:$/, ''); + }); + + currentRawLines.push(line); + + // Parse line + if (withChords) { + currentLines.push(this.parseChordLine(resolvedLine)); + } else { + // CLEAN CHORDS in text-only mode: remove [anything] + const cleanLine = resolvedLine.replace(/\[[^\]]*\]/g, '').trim(); + if (cleanLine.length > 0) { + currentLines.push({ + text: cleanLine, + segments: [{ text: cleanLine }] + }); + } + } + } + + // Push any remaining lines + this.pushSection(sections, currentType, currentLines); + + return sections; + } + + private pushSection(sections: ParsedSection[], type: 'verse' | 'chorus' | 'verse_num', lines: ParsedLine[], verseNumber?: number): void { + if (lines.length > 0) { + sections.push({ type, lines, verseNumber }); + } + } + + /** + * Parse a single line containing inline chord tags. + * Format: "[RE]Tu sei Re[LA]" → segments with chords positioned above text + * + * The chord tag appears BEFORE the text it belongs to: + * [RE]Tu sei Re → chord "RE" above "Tu sei Re" + * + * But a chord can also appear at the END of text: + * sei Re Gesù[SOL] → text "sei Re Gesù" then chord "SOL" with empty text + */ + parseChordLine(line: string): ParsedLine { + // Treat vertical bars (|) as chords instead of text + let prepared = line.replace(/\[\|\]/g, '|'); + prepared = prepared.replace(/\|/g, '[|]'); + + const segments: ChordSegment[] = []; + // Clean up non-breaking spaces + const cleaned = prepared.replace(/\u00a0/g, ' ').trim(); + + // Regex to match [CHORD] tags and text between them + const chordRegex = /\[([^\]]+)\]/g; + let lastIndex = 0; + let match: RegExpExecArray | null; + + while ((match = chordRegex.exec(cleaned)) !== null) { + // Text before this chord tag + const textBefore = cleaned.substring(lastIndex, match.index); + if (textBefore.length > 0) { + // This text has no chord above it (or belongs to previous chord) + if (segments.length > 0 && segments[segments.length - 1].text === '') { + // Previous segment had a chord but no text — attach this text to it + segments[segments.length - 1].text = textBefore; + } else { + segments.push({ text: textBefore }); + } + } + + // Add the chord as a new segment (text will be filled by next text chunk) + segments.push({ chord: this.transposeChord(match[1], 0), text: '' }); + lastIndex = match.index + match[0].length; + } + + // Remaining text after the last chord + const remaining = cleaned.substring(lastIndex); + if (remaining.length > 0) { + if (segments.length > 0 && segments[segments.length - 1].text === '') { + segments[segments.length - 1].text = remaining; + } else { + segments.push({ text: remaining }); + } + } + + // If no chords found, just return plain text + if (segments.length === 0) { + segments.push({ text: cleaned }); + } + + // Build plain text + const plainText = segments.map(s => s.text).join(''); + + return { segments, text: plainText }; + } + + private readonly scale = ['DO', 'DO#', 'RE', 'RE#', 'MI', 'FA', 'FA#', 'SOL', 'SOL#', 'LA', 'LA#', 'SI']; + private readonly flatScale = ['DO', 'REb', 'RE', 'MIb', 'MI', 'FA', 'SOLb', 'SOL', 'LAb', 'LA', 'SIb', 'SI']; + + /** + * Transpose a single chord by a given number of semitones. + * Handles Italian notation. + */ + transposeChord(chord: string, semitones: number): string { + if (!chord) return chord; + if (chord === '|') return '|'; + + // Convert Italian chords ending in 'M' or 'N' (e.g. LAM -> LAm, LAN -> LAm, LAN7 -> LAm7) to lowercase 'm' + chord = chord.replace(/\b(DO|RE|MI|FA|SOL|LA|SI)(#|b|♭)?[mMnN](\d*)\b/g, (match, p1, p2, p3) => { + return p1 + (p2 || '') + 'm' + (p3 || ''); + }); + + // Handle slash chords (e.g., DO/SOL) + if (chord.includes('/')) { + return chord.split('/') + .map(part => this.transposeChord(part.trim(), semitones)) + .join('/'); + } + + const possibleRoots = [...this.scale, ...this.flatScale].sort((a, b) => b.length - a.length); + let root = ''; + let suffix = ''; + + const upperChord = chord.toUpperCase(); + for (const r of possibleRoots) { + if (upperChord.startsWith(r.toUpperCase())) { + root = r; + suffix = chord.substring(r.length); + break; + } + } + + if (!root) return chord; + + const upperRoot = root.toUpperCase(); + let index = this.scale.indexOf(upperRoot); + if (index === -1) { + index = this.flatScale.findIndex(n => n.toUpperCase() === upperRoot); + } + if (index === -1) return chord; + + let newIndex = (index + semitones) % 12; + if (newIndex < 0) newIndex += 12; + + // Decide flat vs sharp notation based on SettingsService preference: + const pref = this.settingsService.chordNotationPreference(); + let useFlat = false; + if (pref === 'diesis') { + useFlat = false; + } else if (pref === 'bemolle') { + useFlat = true; + } else { + // Fallback/Default logic + if (root.includes('#')) { + useFlat = false; + } else if (root.toLowerCase().includes('b')) { + useFlat = true; + } else { + useFlat = semitones < 0; + } + } + + let newRoot = useFlat ? this.flatScale[newIndex] : this.scale[newIndex]; + if (newRoot === 'LA#') { + newRoot = 'SIb'; + } else if (newRoot === 'RE#') { + newRoot = 'MIb'; + } + + return newRoot + suffix; + } + + /** + * Transpose all chords in a parsed structure. + */ + transposeSections(sections: ParsedSection[], semitones: number): ParsedSection[] { + return sections.map(section => ({ + ...section, + lines: section.lines.map(line => ({ + ...line, + segments: line.segments.map(segment => ({ + ...segment, + chord: segment.chord ? this.transposeChord(segment.chord, semitones) : undefined + })) + })) + })); + } + + /** + * Helper to check if the segment at the given index is contiguous with the next segment. + * This means the text is split within a word (e.g. by a chord tag like "rima[RE]ne"). + */ + isContiguousNext(segments: ChordSegment[], index: number): boolean { + if (!segments || index >= segments.length - 1) return false; + + // Se sia il segmento corrente che il successivo hanno un accordo, non sono contigui (vogliamo dello spazio tra loro) + if (segments[index].chord && segments[index + 1].chord) { + return false; + } + + // Find the next segment with non-empty text + let nextWithText: ChordSegment | null = null; + for (let i = index + 1; i < segments.length; i++) { + if (segments[i].text && segments[i].text.length > 0) { + nextWithText = segments[i]; + break; + } + } + + const currentText = segments[index].text || ''; + if (!currentText) { + // If current segment has no text, it should have no margin-right to not add extra spacing + return true; + } + + if (!nextWithText) return false; + + const endsWithNonSpace = !/\s$/.test(currentText); + const startsWithNonSpace = !/^\s/.test(nextWithText.text); + + return endsWithNonSpace && startsWithNonSpace; + } + + /** + * Deduce the musical key (tonality) of the song by looking at the first chord. + */ + deduceTonality(raw: string): string | null { + if (!raw) return null; + const matches = [...raw.matchAll(/\[([^\]]+)\]/g)]; + if (matches.length === 0) return null; + + // Get the first chord + let firstChord = matches[0][1].trim(); + if (firstChord.includes('/')) { + firstChord = firstChord.split('/')[0].trim(); + } + + // Normalize minor indicators (uppercase M/N to m) + firstChord = firstChord.replace(/\b(DO|RE|MI|FA|SOL|LA|SI)(#|b|♭)?[mMnN](\d*)\b/g, (match, p1, p2, p3) => { + return p1 + (p2 || '') + 'm'; + }); + + // Find the root chord name matching the scales + const possibleRoots = [...this.scale, ...this.flatScale].sort((a, b) => b.length - a.length); + let root = ''; + const upperChord = firstChord.toUpperCase(); + for (const r of possibleRoots) { + if (upperChord.startsWith(r.toUpperCase())) { + root = r; + break; + } + } + + if (!root) return null; + + // Check if it is a minor chord + const isMinor = firstChord.toLowerCase().includes('m') || firstChord.includes('-'); + return root + (isMinor ? 'm' : ''); + } +} + diff --git a/src/app/services/media-session.service.ts b/src/app/services/media-session.service.ts new file mode 100644 index 0000000..6db3dac --- /dev/null +++ b/src/app/services/media-session.service.ts @@ -0,0 +1,93 @@ +import { Injectable, inject } from '@angular/core'; +import { CantiService } from './canti.service'; +import { MyCantiService } from './my-canti.service'; +import { ComunitaService } from './comunita.service'; +import { PlaylistService } from './playlist.service'; + +@Injectable({ + providedIn: 'root' +}) +export class MediaSessionService { + private cantiService = inject(CantiService); + private myCantiService = inject(MyCantiService); + private comunitaService = inject(ComunitaService); + private playlistService = inject(PlaylistService); + + public updateMetadata(cantoId: string) { + if (!('mediaSession' in navigator)) return; + + let canto = this.cantiService.getCantoById(cantoId); + if (!canto) { + canto = this.myCantiService.myCanti().find(c => c.id === cantoId); + } + if (!canto) { + canto = this.comunitaService.comunitaCantiPersonali().find(c => c.id === cantoId); + } + if (!canto) { + canto = this.playlistService.remoteCustomSongs().find(c => c.id === cantoId || String(c.id_canti) === cantoId); + } + if (!canto) { + canto = this.playlistService.remoteShareCanti().find(c => c.id === cantoId || String(c.id_canti) === cantoId); + } + if (!canto) return; + + const thumb = this.cantiService.getYoutubeThumb(canto.link_youtube) || 'assets/icons/icon-512x512.png'; + + if (!('MediaMetadata' in window)) return; + + try { + (navigator as any).mediaSession.metadata = new (window as any).MediaMetadata({ + title: canto.titolo, + artist: canto.autore || 'Canti Cristiani', + album: 'Canti Cristiani', + artwork: [ + { src: thumb, sizes: '96x96', type: 'image/jpeg' }, + { src: thumb, sizes: '128x128', type: 'image/jpeg' }, + { src: thumb, sizes: '192x192', type: 'image/jpeg' }, + { src: thumb, sizes: '256x256', type: 'image/jpeg' }, + { src: thumb, sizes: '384x384', type: 'image/jpeg' }, + { src: thumb, sizes: '512x512', type: 'image/jpeg' }, + ] + }); + } catch (e) { + console.error('Error updating Media Session metadata', e); + } + } + + public setPlaybackState(state: 'playing' | 'paused' | 'none') { + if (!('mediaSession' in navigator)) return; + (navigator as any).mediaSession.playbackState = state; + } + + public initActionHandlers(callbacks: { + play: () => void, + pause: () => void, + next?: () => void, + prev?: () => void, + seekto?: (time: number) => void + }) { + if (!('mediaSession' in navigator)) return; + + const ms = (navigator as any).mediaSession; + + ms.setActionHandler('play', callbacks.play); + ms.setActionHandler('pause', callbacks.pause); + + if (callbacks.next) { + ms.setActionHandler('nexttrack', callbacks.next); + } + if (callbacks.prev) { + ms.setActionHandler('previoustrack', callbacks.prev); + } + + try { + if (callbacks.seekto) { + ms.setActionHandler('seekto', (details: any) => { + if (details.seekTime !== undefined && callbacks.seekto) { + callbacks.seekto(details.seekTime); + } + }); + } + } catch (e) {} + } +} diff --git a/src/app/services/my-canti.service.ts b/src/app/services/my-canti.service.ts new file mode 100644 index 0000000..6feb121 --- /dev/null +++ b/src/app/services/my-canti.service.ts @@ -0,0 +1,153 @@ +import { Injectable, signal, inject, Injector } from '@angular/core'; +import { Storage } from '@ionic/storage-angular'; +import { Canto, CantiService } from './canti.service'; +import { ToastController } from '@ionic/angular'; +import { environment } from '../../environments/environment'; +import { PlaylistService } from './playlist.service'; + +@Injectable({ + providedIn: 'root' +}) +export class MyCantiService { + private storage = inject(Storage); + private cantiService = inject(CantiService); + private toastController = inject(ToastController); + private injector = inject(Injector); + private playlistService!: PlaylistService; + + private _storage: Storage | null = null; + public myCanti = signal([]); + private initPromise!: Promise; + + constructor() { + this.initPromise = this.init(); + } + + async init(): Promise { + this._storage = this.cantiService.getStorage(); + if (!this._storage) { + return new Promise((resolve) => { + setTimeout(async () => { + await this.init(); + resolve(); + }, 500); + }); + } + const saved = await this._storage.get('my-canti'); + if (saved) { + this.myCanti.set(saved); + } + } + + async saveCanto(canto: Partial): Promise { + await this.initPromise; + const current = this.myCanti(); + let updated: Canto[]; + let targetCanto: Canto; + + if (canto.id && canto.id.startsWith('my_')) { + // Update existing song + updated = current.map(c => { + if (c.id === canto.id) { + targetCanto = { + ...c, + titolo: canto.titolo || c.titolo, + testo: canto.testo || c.testo, + accordi: canto.accordi !== undefined ? canto.accordi : c.accordi, + autore: canto.autore !== undefined ? canto.autore : c.autore, + link_youtube: canto.link_youtube !== undefined ? canto.link_youtube : c.link_youtube, + id_momenti: canto.id_momenti || c.id_momenti, + durata: canto.durata !== undefined ? canto.durata : c.durata, + bpm: canto.bpm !== undefined ? canto.bpm : c.bpm + }; + return targetCanto; + } + return c; + }); + // Fallback if not found in list (should not happen normally) + if (!updated.some(c => c.id === canto.id)) { + const numericId = canto.id ? Number(canto.id.replace('my_', '')) : NaN; + const idCanti = isNaN(numericId) ? Date.now() : numericId; + targetCanto = { + id: canto.id, + id_canti: canto.id_canti || idCanti, + titolo: canto.titolo || 'Senza Titolo', + testo: canto.testo || '', + accordi: canto.accordi, + autore: canto.autore, + link_youtube: canto.link_youtube, + id_momenti: canto.id_momenti || [], + durata: canto.durata, + bpm: canto.bpm + }; + updated.push(targetCanto); + } + } else { + // Create new song + targetCanto = { + id: `my_${Date.now()}`, + id_canti: Date.now(), // Fake ID for internal logic + titolo: canto.titolo || 'Senza Titolo', + testo: canto.testo || '', + accordi: canto.accordi, + autore: canto.autore, + link_youtube: canto.link_youtube, + id_momenti: canto.id_momenti || [], + durata: canto.durata, + bpm: canto.bpm + }; + updated = [...current, targetCanto]; + } + + this.myCanti.set(updated); + await this._storage?.set('my-canti', updated); + + // Sincronizza automaticamente in background + if (!this.playlistService) { + this.playlistService = this.injector.get(PlaylistService); + } + this.playlistService.syncLocalDataToServer(); + + const toast = await this.toastController.create({ + message: 'Canto salvato nei "Miei Canti"!', + duration: 2000, + color: 'success' + }); + toast.present(); + + return targetCanto!; + } + + async deleteCanto(id: string) { + await this.initPromise; + const updated = this.myCanti().filter(c => c.id !== id); + this.myCanti.set(updated); + await this._storage?.set('my-canti', updated); + + // Sincronizza automaticamente in background + if (!this.playlistService) { + this.playlistService = this.injector.get(PlaylistService); + } + this.playlistService.syncLocalDataToServer(); + } + + async sendAllMyCanti() { + const data = { + version: new Date().toISOString(), + canti: this.myCanti() + }; + + const body = JSON.stringify(data, null, 2); + const subject = `Proposta Collection Canti: ${this.myCanti().length} brani`; + const mailtoUrl = `mailto:${environment.contactEmail}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`; + + window.location.href = mailtoUrl; + + const toast = await this.toastController.create({ + message: 'Email generata con il JSON dei tuoi canti.', + duration: 3000, + color: 'secondary' + }); + toast.present(); + } +} diff --git a/src/app/services/my-canti.spec.ts b/src/app/services/my-canti.spec.ts new file mode 100644 index 0000000..1c790a7 --- /dev/null +++ b/src/app/services/my-canti.spec.ts @@ -0,0 +1,40 @@ +import { TestBed } from '@angular/core/testing'; +import { MyCantiService } from './my-canti.service'; +import { Storage } from '@ionic/storage-angular'; +import { CantiService } from './canti.service'; +import { ToastController } from '@ionic/angular'; + +describe('MyCantiService', () => { + let service: MyCantiService; + let mockStorage: any; + let mockCantiService: any; + let mockToastCtrl: any; + + beforeEach(() => { + mockStorage = jasmine.createSpyObj('Storage', ['create', 'get', 'set']); + mockStorage.get.and.returnValue(Promise.resolve([])); + mockStorage.set.and.returnValue(Promise.resolve()); + + mockCantiService = jasmine.createSpyObj('CantiService', ['getStorage']); + mockCantiService.getStorage.and.returnValue(mockStorage); + + mockToastCtrl = jasmine.createSpyObj('ToastController', ['create']); + mockToastCtrl.create.and.returnValue(Promise.resolve({ + present: jasmine.createSpy('present').and.returnValue(Promise.resolve()) + })); + + TestBed.configureTestingModule({ + providers: [ + MyCantiService, + { provide: Storage, useValue: mockStorage }, + { provide: CantiService, useValue: mockCantiService }, + { provide: ToastController, useValue: mockToastCtrl } + ] + }); + service = TestBed.inject(MyCantiService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/playlist.service.spec.ts b/src/app/services/playlist.service.spec.ts new file mode 100644 index 0000000..7059658 --- /dev/null +++ b/src/app/services/playlist.service.spec.ts @@ -0,0 +1,74 @@ +import { TestBed } from '@angular/core/testing'; +import { PlaylistService } from './playlist.service'; +import { Storage } from '@ionic/storage-angular'; +import { CantiService } from './canti.service'; +import { ComunitaService } from './comunita.service'; +import { signal } from '@angular/core'; + +describe('PlaylistService', () => { + let service: PlaylistService; + let mockStorage: any; + let mockCantiService: any; + let mockComunitaService: any; + + beforeEach(async () => { + mockStorage = jasmine.createSpyObj('Storage', ['create', 'get', 'set']); + mockStorage.create.and.returnValue(Promise.resolve(mockStorage)); + mockStorage.get.and.callFake((key: string) => { + if (key === 'playlists') { + return Promise.resolve([{ id: '1', name: 'Playlist Generale', ids: ['101', '102'] }]); + } + if (key === 'playlists_comunita_123456') { + return Promise.resolve([{ id: '2', name: 'Playlist Comunita 123', ids: ['103'] }]); + } + return Promise.resolve(null); + }); + mockStorage.set.and.returnValue(Promise.resolve()); + + mockCantiService = jasmine.createSpyObj('CantiService', ['canti']); + mockCantiService.canti.and.returnValue([]); + + mockComunitaService = { + comunitaCode: signal(''), + isFilterActive: signal(false), + comunitaScalette: signal([]), + }; + + TestBed.configureTestingModule({ + providers: [ + PlaylistService, + { provide: Storage, useValue: mockStorage }, + { provide: CantiService, useValue: mockCantiService }, + { provide: ComunitaService, useValue: mockComunitaService } + ] + }); + + service = TestBed.inject(PlaylistService); + // Simulate init() completion + await service.init(); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should load general playlists when community is not active', async () => { + mockComunitaService.isFilterActive.set(false); + mockComunitaService.comunitaCode.set(''); + + await service.loadPlaylistsForCurrentContext(); + + expect(service.playlists().length).toBe(1); + expect(service.playlists()[0].name).toBe('Playlist Generale'); + }); + + it('should load community-specific playlists when community is active', async () => { + mockComunitaService.comunitaCode.set('123456'); + mockComunitaService.isFilterActive.set(true); + + await service.loadPlaylistsForCurrentContext(); + + expect(service.playlists().length).toBe(1); + expect(service.playlists()[0].name).toBe('Playlist Comunita 123'); + }); +}); diff --git a/src/app/services/playlist.service.ts b/src/app/services/playlist.service.ts new file mode 100644 index 0000000..9be3971 --- /dev/null +++ b/src/app/services/playlist.service.ts @@ -0,0 +1,1274 @@ +import { Injectable, signal, inject, computed, effect, Injector } from '@angular/core'; +import { Storage } from '@ionic/storage-angular'; +import { Canto, CantiService } from './canti.service'; +import { ComunitaService } from './comunita.service'; +import * as QRCode from 'qrcode'; +import { ToastController, AlertController, ModalController } from '@ionic/angular'; +import { SettingsService } from './settings.service'; +import { SharePlaylistQrModalComponent } from '../components/share-playlist-qr-modal/share-playlist-qr-modal.component'; +import { MyCantiService } from './my-canti.service'; +import { LyricsParserService } from './lyrics-parser.service'; + +@Injectable({ + providedIn: 'root' +}) +export class PlaylistService { + private storage = inject(Storage); + private cantiService = inject(CantiService); + private lyricsParser = inject(LyricsParserService); + private comunitaService = inject(ComunitaService); + private toastCtrl = inject(ToastController); + private alertCtrl = inject(AlertController); + private modalCtrl = inject(ModalController); + private settingsService = inject(SettingsService); + private injector = inject(Injector); + private myCantiService!: MyCantiService; + + public selectionMode = signal(false); + public selectedIds = signal>(new Set()); + public playlists = signal([]); + public lastPlaylist = signal(null); + public autoPlayPlaylist = signal(false); + + public activeListIds = signal([]); + public activeListName = signal(null); + public activePlaylistId = signal(null); + public filteredListIds = signal([]); + + public remotePlaylist = signal(null); + public remoteCustomSongs = signal([]); + public remoteShareCanti = signal([]); + public hasRemotePlaylistUpdate = signal(false); + + private _storage: Storage | null = null; + private initPromise!: Promise; + + // Community scalette exposed as playlists (only when community filter is active) + public comunitaPlaylists = computed(() => { + if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) { + return []; + } + return this.comunitaService.comunitaScalette().map(s => ({ + ...s, + isComunita: true + })); + }); + + // Merged list: personal playlists + community scalette + remote playlist + public allPlaylists = computed(() => { + const community = this.comunitaPlaylists(); + const personal = this.playlists(); + const remote = this.remotePlaylist(); + + let list = [...personal.map(p => ({ ...p, isComunita: false, isRemote: false }))]; + if (community.length > 0) { + list = [...community, ...list]; + } + if (remote) { + list = [{ ...remote, isComunita: false, isRemote: true }, ...list]; + } + return list; + }); + + constructor() { + this.initPromise = this.init(); + + // Watch for context changes to dynamically reload the correct playlists + effect(() => { + // Trigger effect on changes to these signals + this.comunitaService.comunitaCode(); + this.comunitaService.isFilterActive(); + + // Load the playlists + this.loadPlaylistsForCurrentContext(); + }, { allowSignalWrites: true }); + } + + getPlaylistsStorageKey(): string { + const code = this.comunitaService.comunitaCode(); + const active = this.comunitaService.isFilterActive(); + if (code && active) { + return `playlists_${code}`; + } + return 'playlists'; + } + + async init(): Promise { + this._storage = this.cantiService.getStorage(); + if (!this._storage) { + return new Promise((resolve) => { + setTimeout(async () => { + await this.init(); + resolve(); + }, 500); + }); + } + const key = this.getPlaylistsStorageKey(); + const saved = await this._storage.get(key); + this.playlists.set(saved || []); + + const lastKey = `lastPlaylist_${key}`; + const last = await this._storage.get(lastKey); + this.lastPlaylist.set(last || null); + + // Carica la playlist remota persistita e i relativi canti personalizzati + const remotePl = await this._storage.get('remote_playlist'); + if (remotePl) { + this.remotePlaylist.set(remotePl); + } + const remoteSongs = await this._storage.get('remote_custom_songs'); + if (remoteSongs) { + this.remoteCustomSongs.set(remoteSongs); + } + const remoteShareSongs = await this._storage.get('remote_share_canti'); + if (remoteShareSongs) { + this.remoteShareCanti.set(remoteShareSongs); + } + + // Aggiorna in background la playlist remota per sincronizzare eventuali modifiche + if (remotePl) { + this.refreshRemotePlaylist(); + } + } + + async loadPlaylistsForCurrentContext() { + await this.initPromise; + const key = this.getPlaylistsStorageKey(); + const saved = await this._storage?.get(key); + this.playlists.set(saved || []); + + const lastKey = `lastPlaylist_${key}`; + const last = await this._storage?.get(lastKey); + this.lastPlaylist.set(last || null); + + // Carica la playlist remota persistita e i relativi canti personalizzati + const remotePl = await this._storage?.get('remote_playlist'); + if (remotePl) { + this.remotePlaylist.set(remotePl); + } + const remoteSongs = await this._storage?.get('remote_custom_songs'); + if (remoteSongs) { + this.remoteCustomSongs.set(remoteSongs); + } + const remoteShareSongs = await this._storage?.get('remote_share_canti'); + if (remoteShareSongs) { + this.remoteShareCanti.set(remoteShareSongs); + } + + // Aggiorna in background la playlist remota per sincronizzare eventuali modifiche + if (remotePl) { + this.refreshRemotePlaylist(); + } + } + + async checkForRemotePlaylistUpdates() { + const remotePl = this.remotePlaylist(); + if (!remotePl) { + this.hasRemotePlaylistUpdate.set(false); + return; + } + + const parts = remotePl.id.split('_'); + if (parts.length < 3) return; + const uid = parts[1]; + + try { + const response = await fetch(`https://api.canticristiani.it/${uid}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (!response.ok) return; + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + const playlists = remoteJson.filter((item: any) => item.momenti && item.momenti.includes('Playlist')); + const updatedPl = playlists.find((p: any) => `remote_${uid}_${p.id_canti}` === remotePl.id); + if (updatedPl) { + const serverIds = updatedPl.testo ? updatedPl.testo.split(',') : []; + const localIds = remotePl.ids || []; + + const idsMatch = serverIds.length === localIds.length && serverIds.every((id: string, idx: number) => id === localIds[idx]); + const nameMatch = `[Remote] ${updatedPl.titolo}` === remotePl.name; + + if (!idsMatch || !nameMatch) { + this.hasRemotePlaylistUpdate.set(true); + return; + } + } + } + this.hasRemotePlaylistUpdate.set(false); + } catch (e) { + console.warn('Failed to check for remote playlist updates:', e); + } + } + + async refreshRemotePlaylist() { + const remotePl = this.remotePlaylist(); + if (!remotePl) return; + + const parts = remotePl.id.split('_'); + if (parts.length < 3) return; + const uid = parts[1]; + + try { + const response = await fetch(`https://api.canticristiani.it/${uid}.json?cb=${Date.now()}`, { cache: 'no-store' }); + if (!response.ok) return; + const remoteJson = await response.json(); + if (Array.isArray(remoteJson)) { + const customSongs = remoteJson + .filter((item: any) => !item.momenti || !item.momenti.includes('Playlist')) + .map((item: any) => ({ + id: `my_${item.id_canti}`, + id_canti: Number(item.id_canti), + titolo: item.titolo || 'Senza Titolo', + testo: item.testo || '', + accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined), + autore: item.autore || '', + link_youtube: item.link_youtube || '', + id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || [], + durata: item.durata || '', + bpm: item.bpm !== undefined && item.bpm !== null ? Number(item.bpm) : undefined + })); + + const playlists = remoteJson + .filter((item: any) => item.momenti && item.momenti.includes('Playlist')) + .map((item: any) => { + let songSettings = {}; + if (item.periodi && item.periodi.length > 0) { + try { + songSettings = JSON.parse(item.periodi[0]); + } catch (e) {} + } + return { + id: `remote_${uid}_${item.id_canti}`, + name: `[Remote] ${item.titolo}`, + ids: item.testo ? item.testo.split(',') : [], + songSettings: songSettings, + createdAt: new Date(), + isRemote: true + }; + }); + + const updatedPl = playlists.find(p => p.id === remotePl.id); + if (updatedPl) { + this.remotePlaylist.set(updatedPl); + this.remoteCustomSongs.set(customSongs); + await this._storage?.set('remote_playlist', updatedPl); + await this._storage?.set('remote_custom_songs', customSongs); + this.hasRemotePlaylistUpdate.set(false); + + if (this.activePlaylistId() === remotePl.id) { + this.activeListIds.set(updatedPl.ids); + this.activeListName.set(updatedPl.name); + } + console.log('[Remote-Sync] Remote playlist and custom songs updated successfully.'); + } + } + } catch (err) { + console.warn('[Remote-Sync] Failed to refresh remote playlist:', err); + } + } + + toggleSelectionMode() { + this.selectionMode.update(v => !v); + if (!this.selectionMode()) { + this.selectedIds.set(new Set()); + } + } + + toggleSongSelection(id: string) { + if (!this.selectionMode()) { + const active = this.activeListIds(); + if (active.length > 0) { + this.selectedIds.set(new Set(active)); + } + this.selectionMode.set(true); + } + this.selectedIds.update(set => { + const newSet = new Set(set); + if (newSet.has(id)) { + newSet.delete(id); + } else { + newSet.add(id); + } + return newSet; + }); + } + + async savePlaylist(name: string, ids: string[], songSettings?: any, setAsLast = true) { + await this.initPromise; + const key = this.getPlaylistsStorageKey(); + const lastKey = `lastPlaylist_${key}`; + const editId = this.activePlaylistId(); + let newPlaylist: any; + + if (editId) { + this.playlists.update(p => p.map(pl => { + if (pl.id === editId) { + const mergedSettings = songSettings || pl.songSettings || {}; + return { ...pl, name, ids, songSettings: mergedSettings }; + } + return pl; + })); + newPlaylist = this.playlists().find(pl => pl.id === editId); + } else { + newPlaylist = { + id: Date.now().toString(), + name, + ids, + songSettings: songSettings || {}, + createdAt: new Date() + }; + this.playlists.update(p => [newPlaylist, ...p]); + } + + if (setAsLast) { + this.lastPlaylist.set(newPlaylist); + } + this.activeListIds.set(ids); + this.activeListName.set(name); + await this._storage?.set(key, this.playlists()); + if (setAsLast) { + await this._storage?.set(lastKey, newPlaylist); + } + + // Reset selection mode, IDs and editing state after saving + this.selectedIds.set(new Set()); + this.selectionMode.set(false); + this.activePlaylistId.set(newPlaylist.id); + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + } + + async clonePlaylist(name: string, ids: string[], songSettings?: any) { + await this.initPromise; + const isCommunityActive = this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive(); + const key = 'playlists'; + const lastKey = `lastPlaylist_${key}`; + + // Create the cloned playlist + const newPlaylist = { + id: Date.now().toString(), + name, + ids, + songSettings: songSettings || {}, + createdAt: new Date() + }; + + let personalPlaylists: any[] = []; + if (isCommunityActive) { + // If community is active, read the personal playlists from storage + const saved = await this._storage?.get(key); + personalPlaylists = saved || []; + } else { + // If personal context is active, we can use the current signal + personalPlaylists = this.playlists(); + } + + const updated = [newPlaylist, ...personalPlaylists]; + + if (isCommunityActive) { + // Save directly to storage for personal context + await this._storage?.set(key, updated); + await this._storage?.set(`lastPlaylist_playlists`, newPlaylist); + } else { + // Update signal and save to storage + this.playlists.set(updated); + this.lastPlaylist.set(newPlaylist); + this.activeListIds.set(ids); + this.activeListName.set(name); + this.activePlaylistId.set(newPlaylist.id); + await this._storage?.set(key, updated); + await this._storage?.set(lastKey, newPlaylist); + } + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + } + + async replaceSongIdInPlaylists(oldId: string, newId: string) { + await this.initPromise; + this.playlists.update(p => p.map(pl => { + if (pl.ids && pl.ids.includes(oldId)) { + const updatedIds = pl.ids.map((id: string) => id === oldId ? newId : id); + + // Copia anche i parametri di tonalità/zoom/velocità della canzone se presenti + const songSettings = { ...(pl.songSettings || {}) }; + if (songSettings[oldId]) { + songSettings[newId] = { ...songSettings[oldId] }; + delete songSettings[oldId]; + } + + return { ...pl, ids: updatedIds, songSettings }; + } + return pl; + })); + + const key = this.getPlaylistsStorageKey(); + await this._storage?.set(key, this.playlists()); + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + } + + async updatePlaylistSongSettings(playlistId: string, songId: string, tonalita: number, speed: number) { + await this.initPromise; + this.playlists.update(p => p.map(pl => { + if (pl.id === playlistId) { + const songSettings = { ...(pl.songSettings || {}) }; + songSettings[songId] = { + tonalita, + speed + }; + return { ...pl, songSettings }; + } + return pl; + })); + + const key = this.getPlaylistsStorageKey(); + await this._storage?.set(key, this.playlists()); + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + + // Also update lastPlaylist if it is the current one + const lastKey = `lastPlaylist_${key}`; + const last = this.lastPlaylist(); + if (last && last.id === playlistId) { + const updatedLast = this.playlists().find(pl => pl.id === playlistId); + this.lastPlaylist.set(updatedLast || null); + await this._storage?.set(lastKey, updatedLast); + } + } + + async deletePlaylist(id: string) { + await this.initPromise; + if (id.startsWith('remote_')) { + await this.clearRemotePlaylist(); + return; + } + const key = this.getPlaylistsStorageKey(); + this.playlists.update(p => p.filter(pl => pl.id !== id)); + await this._storage?.set(key, this.playlists()); + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + } + + async saveRemotePlaylist(pl: any, customSongs: any[]) { + await this.initPromise; + this.remotePlaylist.set(pl); + this.remoteCustomSongs.set(customSongs); + await this._storage?.set('remote_playlist', pl); + await this._storage?.set('remote_custom_songs', customSongs); + } + + async clearRemotePlaylist() { + await this.initPromise; + this.remotePlaylist.set(null); + this.remoteCustomSongs.set([]); + await this._storage?.remove('remote_playlist'); + await this._storage?.remove('remote_custom_songs'); + + // Sincronizza automaticamente in background + this.syncLocalDataToServer(); + } + + async syncLocalDataToServer() { + await this.initPromise; + const uid = this.settingsService.userUuid(); + if (!uid) return; + + if (!this.myCantiService) { + this.myCantiService = this.injector.get(MyCantiService); + } + + try { + const mergedSongsMap = new Map(); + + this.remoteShareCanti().forEach(c => { + const id_canti = c.id_canti || Date.now(); + mergedSongsMap.set(id_canti, { + id_canti, + titolo: c.titolo || 'Senza Titolo', + autore: c.autore || '', + link_youtube: c.link_youtube || '', + accordi: c.accordi || '', + momenti: c.id_momenti?.map(id => String(id)) || [], + periodi: [] as string[], + testo: c.testo || '', + durata: c.durata || '', + bpm: c.bpm !== undefined ? c.bpm : null + }); + }); + + this.myCantiService.myCanti().forEach(c => { + const id_canti = c.id_canti || Date.now(); + mergedSongsMap.set(id_canti, { + id_canti, + titolo: c.titolo || 'Senza Titolo', + autore: c.autore || '', + link_youtube: c.link_youtube || '', + accordi: c.accordi || '', + momenti: c.id_momenti?.map(id => String(id)) || [], + periodi: [] as string[], + testo: c.testo || '', + durata: c.durata || '', + bpm: c.bpm !== undefined ? c.bpm : null + }); + }); + + this.remoteCustomSongs().forEach(c => { + const id_canti = c.id_canti || Date.now(); + mergedSongsMap.set(id_canti, { + id_canti, + titolo: c.titolo || 'Senza Titolo', + autore: c.autore || '', + link_youtube: c.link_youtube || '', + accordi: c.accordi || '', + momenti: c.id_momenti?.map((id: any) => String(id)) || [], + periodi: [] as string[], + testo: c.testo || '', + durata: c.durata || '', + bpm: c.bpm !== undefined ? c.bpm : null + }); + }); + + this.comunitaService.comunitaCantiPersonali().forEach(c => { + const id_canti = c.id_canti || Date.now(); + mergedSongsMap.set(id_canti, { + id_canti, + titolo: c.titolo || 'Senza Titolo', + autore: c.autore || '', + link_youtube: c.link_youtube || '', + accordi: c.accordi || '', + momenti: c.id_momenti?.map((id: any) => String(id)) || [], + periodi: [] as string[], + testo: c.testo || '', + durata: c.durata || '', + bpm: c.bpm !== undefined ? c.bpm : null + }); + }); + + const customSongs = Array.from(mergedSongsMap.values()); + + const playlistSongs = this.playlists().map(pl => ({ + id_canti: Number(pl.id) || Date.now(), + titolo: pl.name, + momenti: ['Playlist'], + periodi: pl.songSettings ? [JSON.stringify(pl.songSettings)] : [], + testo: pl.ids.join(',') + })); + + const payload = [...customSongs, ...playlistSongs]; + + if (this.settingsService.userName()) { + payload.push({ + id_canti: 999999, + titolo: this.settingsService.userName(), + momenti: ['UserMetadata'], + periodi: [], + testo: '' + }); + } + + const response = await fetch('https://api.canticristiani.it/miei', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-user-uid': uid + }, + body: JSON.stringify(payload) + }); + + if (!response.ok) { + console.warn(`[Auto-Sync] Server returned code: ${response.status}`); + } else { + console.log('[Auto-Sync] Local playlists and canti backed up successfully.'); + } + } catch (err) { + console.error('[Auto-Sync] Auto-synchronization failed:', err); + } + } + + async generateQR(ids: string[], name: string, songSettings?: any): Promise { + const data = this.getShareLink(ids, name, songSettings); + return await QRCode.toDataURL(data, { + width: 400, + margin: 2, + color: { + dark: '#2d3436', + light: '#ffffff' + } + }); + } + + getShareLink(ids: string[], name: string, songSettings?: any): string { + const mergedSettings = { ...(songSettings || {}) }; + const cc = this.comunitaService.comunitaCode(); + const isCommunityActive = this.comunitaService.isFilterActive(); + + if (cc && isCommunityActive) { + const communitySettings = this.comunitaService.comunitaCantiSettings(); + for (const id of ids) { + if (mergedSettings[id] === undefined) { + const cSettings = communitySettings.find(s => + s.id_canti === Number(id) || String(s.id_canti) === id + ); + if (cSettings) { + const tonalita = cSettings.tonalita !== undefined ? cSettings.tonalita : 0; + let speed = 2; + if (cSettings.speed !== undefined && cSettings.speed > 0) { + speed = Math.max(1, Math.min(10, Math.round(cSettings.speed / 100))); + } + mergedSettings[id] = { tonalita, speed }; + } + } + } + } + + const shareObj: any = { name, ids, songSettings: mergedSettings }; + + if (cc && isCommunityActive) { + const communityCantiIds = this.comunitaService.comunitaCantiIds(); + const communityCantiPersonali = this.comunitaService.comunitaCantiPersonali(); + + const containsCommunitySong = ids.some(id => { + const isStandard = communityCantiIds.includes(id) || communityCantiIds.includes(Number(id)); + const isPersonal = communityCantiPersonali.some(cp => cp.id === id); + return isStandard || isPersonal; + }); + + if (containsCommunitySong) { + shareObj.comunitaCode = cc; + } + } + + const data = JSON.stringify(shareObj); + // Use btoa safely for UTF-8 strings + const base64 = btoa(unescape(encodeURIComponent(data))); + + // Always use the production URL for sharing links as requested + const productionUrl = 'https://www.canticristiani.it'; + return `${productionUrl}/?import=${base64}&openFirst=1`; + } + + processImportJson(json: any): boolean { + if (json && json.name && json.ids) { + this.activePlaylistId.set(null); // Forza il salvataggio come nuova playlist indipendente ed editabile + this.activeListIds.set(json.ids); + this.activeListName.set(json.name); + // Automatically save to the device! + this.savePlaylist(json.name, json.ids, json.songSettings, false); + return true; + } + return false; + } + + async sharePlaylistQR(ids: string[], name: string, songSettings?: any) { + // Sincronizza istantaneamente sul server prima di generare/condividere la playlist + await this.syncLocalDataToServer(); + + const uid = this.settingsService.userUuid(); + const activeId = this.activePlaylistId() || Date.now().toString(); + const isRemote = activeId.startsWith('remote_'); + + let shareLink = `https://www.canticristiani.it/?playlist-uid=${uid}&playlist-id=${activeId}&openFirst=1`; + if (isRemote) { + let remoteUid = uid; + let remotePid = activeId; + const parts = activeId.split('_'); + if (parts.length >= 3) { + remoteUid = parts[1]; + remotePid = parts[2]; + } + shareLink = `https://www.canticristiani.it/?playlist-uid=${remoteUid}&playlist-id=${remotePid}&openFirst=1`; + } + + const modal = await this.modalCtrl.create({ + component: SharePlaylistQrModalComponent, + componentProps: { + playlistName: name, + shareLink: shareLink + } + }); + await modal.present(); + } + + async loadPlaylists() { + } + + async saveRemoteShareCanto(canto: Canto) { + await this.initPromise; + const current = this.remoteShareCanti(); + const index = current.findIndex(c => c.id === canto.id); + let updated: Canto[]; + if (index > -1) { + updated = current.map(c => c.id === canto.id ? canto : c); + } else { + updated = [...current, canto]; + } + this.remoteShareCanti.set(updated); + await this._storage?.set('remote_share_canti', updated); + } + + async deleteRemoteShareCanto(id: string) { + await this.initPromise; + const updated = this.remoteShareCanti().filter(c => c.id !== id); + this.remoteShareCanti.set(updated); + await this._storage?.set('remote_share_canti', updated); + } + + public printPlaylist(playlistName: string, songs: any[], showChords: boolean, transpositions?: { [songId: string]: number }) { + const printWindow = window.open('', '_blank'); + if (!printWindow) { + alert('Impossibile aprire la finestra di stampa. Abilita i popup nel browser.'); + return; + } + + if (!this.myCantiService) { + this.myCantiService = this.injector.get(MyCantiService); + } + + const titleHtml = playlistName ? ` +
+
+

Playlist: ${playlistName}

+

Data: ${new Date().toLocaleDateString('it-IT')}  •  N. Canti: ${songs.length}

+
+
+ ` : ''; + + let contentHtml = ''; + + for (const song of songs) { + if (!song) continue; + const isPersonal = song.id && song.id.startsWith('my_'); + let songNum = ''; + if (isPersonal) { + const myIndex = this.myCantiService ? this.myCantiService.myCanti().findIndex((c: any) => c.id === song.id) : -1; + songNum = myIndex !== -1 ? `Pers. ${myIndex + 1}` : 'Pers.'; + } else { + songNum = song.id_canti || ''; + } + + // Check if there is a community number + const commCode = this.comunitaService.comunitaCode(); + const commActive = this.comunitaService.isFilterActive(); + let commNum = ''; + if (commCode && commActive) { + const cantiInfo = this.comunitaService.comunitaCantiInfo(); + const info = cantiInfo.find((x: any) => x.id_canti === song.id_canti || x.id_canti === Number(song.id)); + if (info && info.num_canto) { + commNum = info.num_canto.toString(); + } + } + + const displayNum = commNum ? `${commNum} (${songNum})` : songNum; + + // Determine the transposition amount (semitones) + let semitones = 0; + if (transpositions && transpositions[song.id] !== undefined) { + semitones = transpositions[song.id]; + } else if (transpositions && transpositions[song.id_canti] !== undefined) { + semitones = transpositions[song.id_canti]; + } else { + // Fallback to active playlist settings or community settings + const activePlaylistId = this.activePlaylistId(); + let playlistSongSetting: any = null; + if (activePlaylistId) { + if (activePlaylistId.startsWith('remote_')) { + const pl = this.remotePlaylist(); + if (pl && pl.songSettings && pl.songSettings[song.id]) { + playlistSongSetting = pl.songSettings[song.id]; + } + } else { + const pl = this.playlists().find(p => p.id === activePlaylistId); + if (pl && pl.songSettings && pl.songSettings[song.id]) { + playlistSongSetting = pl.songSettings[song.id]; + } + } + } + + if (playlistSongSetting && playlistSongSetting.tonalita !== undefined) { + semitones = playlistSongSetting.tonalita; + } else if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) { + const settings = this.comunitaService.comunitaCantiSettings(); + const songSetting = settings.find(s => s.id_canti === song.id_canti || s.id_canti === Number(song.id)); + if (songSetting && songSetting.tonalita !== undefined) { + semitones = songSetting.tonalita; + } + } + } + + const rawText = showChords ? (song.accordi || song.testo) : song.testo; + let parsedSections = showChords ? this.lyricsParser.parseAccordi(rawText) : this.lyricsParser.parseText(rawText); + if (showChords && semitones !== 0) { + parsedSections = this.lyricsParser.transposeSections(parsedSections, semitones); + } + + let songBodyHtml = ''; + for (const section of parsedSections) { + const sectionClass = section.type === 'chorus' ? 'section-chorus' : 'section-verse'; + let sectionHeader = ''; + if (section.type === 'verse_num' && section.verseNumber) { + sectionHeader = `${section.verseNumber}.`; + } + + let linesHtml = ''; + for (const line of section.lines) { + let lineContentHtml = ''; + if (showChords) { + for (let i = 0; i < line.segments.length; i++) { + const seg = line.segments[i]; + const isCont = this.lyricsParser.isContiguousNext(line.segments, i); + const chordHtml = seg.chord ? `${seg.chord}` : ''; + lineContentHtml += `${chordHtml}${seg.text || ''}`; + } + } else { + lineContentHtml = line.text; + } + linesHtml += `
${lineContentHtml}
`; + } + + songBodyHtml += `
${sectionHeader}${linesHtml}
`; + } + + contentHtml += ` +
+
+
+ ${displayNum} + ${song.titolo} +
+
+ ${song.autore ? `Autore: ${song.autore}` : ''} + ${song.durata ? `Durata: ${song.durata}` : ''} + ${song.bpm ? `BPM: ${song.bpm}` : ''} +
+
+
+ ${songBodyHtml} +
+
+ `; + } + + const html = ` + + + + + ${playlistName || 'Playlist'} + + + + + + + + ${titleHtml} + ${contentHtml} + + + + `; + + printWindow.document.open(); + printWindow.document.write(html); + printWindow.document.close(); + } +} diff --git a/src/app/services/settings.service.ts b/src/app/services/settings.service.ts new file mode 100644 index 0000000..e533d1b --- /dev/null +++ b/src/app/services/settings.service.ts @@ -0,0 +1,586 @@ +import { Injectable, signal, effect } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class SettingsService { + /** Default mode for viewing songs: true = chords, false = text only */ + public showChordsDefault = signal(true); + + /** UI Fullscreen mode (lyrics only): true = active */ + public fullscreenMode = signal(false); + + /** Browser Fullscreen state: true = fullscreen active */ + public browserFullscreen = signal( + typeof document !== 'undefined' && !!( + document.fullscreenElement || + (document as any).webkitFullscreenElement || + (document as any).mozFullScreenElement || + (document as any).msFullscreenElement + ) + ); + + /** Avanzamento automatico: true = passa al brano successivo automaticamente */ + public autoAdvance = signal(true); + + /** Editor e Canti Personali: true = mostra funzioni aggiunta e lista "Miei" */ + public showEditor = signal(false); + + /** Schermo sempre acceso: true = attiva Screen Wake Lock */ + public keepScreenOn = signal(true); + + /** Funzionalità Comunità: true = il chip comunità è visibile nella home */ + public comunitaEnabled = signal(false); + + /** Invio dati statistici: true = invia pacchetto dati statistici */ + public invioDatiStatistici = signal(false); + + /** Visualizza tag sotto autore nella lista canti: true = attivo */ + public showTagsInList = signal(true); + + /** Visualizza data update sotto autore nella lista canti: true = attivo */ + public showUpdateDate = signal(true); + + /** Visualizza durata, bpm e tonalità sotto autore / titolo: true = attivo */ + public showDurationBpmTonality = signal(true); + + /** Attiva autoscroll standard nel dettaglio canto: true = attivo */ + public enableStandardAutoscroll = signal(false); + + /** Attiva autoscroll visuale nel dettaglio canto: true = attivo */ + public enableVisualAutoscroll = signal(true); + + /** Navigazione con fotocamera (tracciamento testa) attiva nel player: true = attivo */ + public cameraNavigationActive = signal(false); + + /** Modalità tracciamento fotocamera: 'tilt' (inclinazione collo) o 'distance' (avvicinamento/allontanamento viso) */ + public cameraTrackingMode = signal<'tilt' | 'distance'>('tilt'); + + /** Fascia di distanza utente-fotocamera per taratura sensibilità: 'close' (0-30 cm), 'medium' (30-60 cm), 'far' (1m e oltre) */ + public cameraDistanceRange = signal<'close' | 'medium' | 'far'>('medium'); + + /** Preferenza notazione accordi: diesis o bemolle */ + public chordNotationPreference = signal<'diesis' | 'bemolle'>('diesis'); + + /** Avanzamento a pagine del karaoke manuale: true = i tasti next/prev voltano la pagina */ + public karaokePageScrollMode = signal(false); + + /** Vista orizzontale per proiezione: true = attiva layout landscape per proiezione */ + public landscapeProjectionEnabled = signal(false); + + /** Schermo nero per l'ascolto delle playlist in macchina: true = attivo */ + public carModeBlackScreen = signal(false); + + /** Global zoom/font size factor for song presentation */ + public globalZoom = signal(1.0); + + /** Identificativo utente univoco per la gestione delle comunità */ + public userUuid = signal(''); + + /** Identificativo originario assegnato alla prima installazione */ + public originalUserUuid = signal(''); + + /** Nome associato all'identità utente */ + public userName = signal(''); + + private wakeLock: any = null; + + // PWA installation signals + public deferredPrompt = signal(null); + public showInstallButton = signal(false); + public isStandalone = signal(false); + public isIos = signal(false); + public isAndroid = signal(false); + public isVersionCheckComplete = signal(false); + + constructor() { + // Gestione/Generazione ID utente univoco + let savedUuid = localStorage.getItem('user-uuid'); + if (!savedUuid) { + if (typeof crypto !== 'undefined' && crypto.randomUUID) { + savedUuid = crypto.randomUUID(); + } else { + savedUuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = Math.random() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + localStorage.setItem('user-uuid', savedUuid); + } + this.userUuid.set(savedUuid); + + // Salvataggio dell'ID originario (alla prima installazione) se non è già presente + let originalUuid = localStorage.getItem('original-user-uuid'); + if (!originalUuid) { + originalUuid = savedUuid; + localStorage.setItem('original-user-uuid', originalUuid); + } + this.originalUserUuid.set(originalUuid); + + const savedName = localStorage.getItem('user-name'); + if (savedName) { + this.userName.set(savedName); + } + + // Detect PWA status + try { + this.isStandalone.set( + window.matchMedia('(display-mode: standalone)').matches || + (window.navigator as any).standalone === true + ); + this.isIos.set( + /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream + ); + this.isAndroid.set( + /Android/i.test(navigator.userAgent) + ); + } catch (e) { + console.warn('Browser environment does not support display-mode media query'); + } + + window.addEventListener('beforeinstallprompt', (e: any) => { + // Prevent the mini-infobar from appearing on mobile + e.preventDefault(); + // Stash the event so it can be triggered later. + this.deferredPrompt.set(e); + // Update UI notify the user they can install the PWA + this.showInstallButton.set(true); + // Se scatta l'evento di installazione, l'app NON è attualmente installata + localStorage.setItem('pwa-installed', 'false'); + }); + + window.addEventListener('appinstalled', () => { + this.deferredPrompt.set(null); + this.showInstallButton.set(false); + this.isStandalone.set(true); + console.log('PWA was installed'); + }); + + // Migration: force settings defaults once for existing users to match the new rules + const migrationKey = 'defaults-migrated-20260605'; + if (localStorage.getItem(migrationKey) !== 'true') { + localStorage.setItem('show-chords-default', 'true'); + localStorage.setItem('fullscreen-mode', this.isIos().toString()); + localStorage.setItem('show-editor', 'false'); + localStorage.setItem('auto-advance', 'true'); + localStorage.setItem('keep-screen-on', 'true'); + localStorage.setItem('comunita-enabled', 'false'); + localStorage.setItem('invio-dati-statistici', 'false'); + localStorage.setItem('show-tags-in-list', 'true'); + localStorage.setItem('show-update-date', 'true'); + localStorage.setItem('show-duration-bpm-tonality', 'true'); + localStorage.setItem('enable-standard-autoscroll', 'false'); + localStorage.setItem('enable-visual-autoscroll', 'true'); + localStorage.setItem('chord-notation-preference', 'diesis'); + + // ThemeService high contrast default + localStorage.setItem('high-contrast', 'true'); + + localStorage.setItem(migrationKey, 'true'); + } + + + const savedChords = localStorage.getItem('show-chords-default'); + if (savedChords !== null) { + this.showChordsDefault.set(savedChords === 'true'); + } else { + this.showChordsDefault.set(true); + } + + const savedFullscreen = localStorage.getItem('fullscreen-mode'); + if (savedFullscreen !== null) { + this.fullscreenMode.set(savedFullscreen === 'true'); + } else { + this.fullscreenMode.set(this.isIos()); + } + + const savedEditor = localStorage.getItem('show-editor'); + if (savedEditor !== null) { + this.showEditor.set(savedEditor === 'true'); + } else { + this.showEditor.set(false); + } + + const savedAutoAdvance = localStorage.getItem('auto-advance'); + if (savedAutoAdvance !== null) { + this.autoAdvance.set(savedAutoAdvance === 'true'); + } else { + this.autoAdvance.set(true); + } + + // Keep screen always on by default and always active + this.keepScreenOn.set(true); + + const savedComunitaEnabled = localStorage.getItem('comunita-enabled'); + if (savedComunitaEnabled !== null) { + this.comunitaEnabled.set(savedComunitaEnabled === 'true'); + } else { + this.comunitaEnabled.set(false); + } + + const savedStats = localStorage.getItem('invio-dati-statistici'); + if (savedStats !== null) { + this.invioDatiStatistici.set(savedStats === 'true'); + } else { + this.invioDatiStatistici.set(false); + } + + const savedShowTags = localStorage.getItem('show-tags-in-list'); + if (savedShowTags !== null) { + this.showTagsInList.set(savedShowTags === 'true'); + } else { + this.showTagsInList.set(true); + } + + const savedShowUpdateDate = localStorage.getItem('show-update-date'); + if (savedShowUpdateDate !== null) { + this.showUpdateDate.set(savedShowUpdateDate === 'true'); + } else { + this.showUpdateDate.set(true); + } + + const savedShowDurBpmTon = localStorage.getItem('show-duration-bpm-tonality'); + if (savedShowDurBpmTon !== null) { + this.showDurationBpmTonality.set(savedShowDurBpmTon === 'true'); + } else { + this.showDurationBpmTonality.set(true); + } + + const savedStandardAutoscroll = localStorage.getItem('enable-standard-autoscroll'); + if (savedStandardAutoscroll !== null) { + this.enableStandardAutoscroll.set(savedStandardAutoscroll === 'true'); + } else { + this.enableStandardAutoscroll.set(false); + } + + const savedVisualAutoscroll = localStorage.getItem('enable-visual-autoscroll'); + if (savedVisualAutoscroll !== null) { + this.enableVisualAutoscroll.set(savedVisualAutoscroll === 'true'); + } else { + this.enableVisualAutoscroll.set(true); + } + + const savedNotation = localStorage.getItem('chord-notation-preference'); + if (savedNotation !== null) { + this.chordNotationPreference.set(savedNotation === 'bemolle' ? 'bemolle' : 'diesis'); + } else { + this.chordNotationPreference.set('diesis'); + } + + const savedKaraokePageScrollMode = localStorage.getItem('karaoke-page-scroll-mode'); + if (savedKaraokePageScrollMode !== null) { + this.karaokePageScrollMode.set(savedKaraokePageScrollMode === 'true'); + } else { + this.karaokePageScrollMode.set(false); + } + + const savedLandscapeProjectionEnabled = localStorage.getItem('landscape-projection-enabled'); + if (savedLandscapeProjectionEnabled !== null) { + this.landscapeProjectionEnabled.set(savedLandscapeProjectionEnabled === 'true'); + } else { + this.landscapeProjectionEnabled.set(false); + } + + const savedCarModeBlackScreen = localStorage.getItem('car-mode-black-screen'); + if (savedCarModeBlackScreen !== null) { + this.carModeBlackScreen.set(savedCarModeBlackScreen === 'true'); + } else { + this.carModeBlackScreen.set(false); + } + + const savedGlobalZoom = localStorage.getItem('global-zoom'); + if (savedGlobalZoom !== null) { + const parsed = parseFloat(savedGlobalZoom); + this.globalZoom.set(isNaN(parsed) ? 1.0 : parsed); + } else { + this.globalZoom.set(1.0); + } + + // Sync browser fullscreen state with listeners (supporting vendor prefixes) + const updateFullscreenState = () => { + const isFs = !!( + document.fullscreenElement || + (document as any).webkitFullscreenElement || + (document as any).mozFullScreenElement || + (document as any).msFullscreenElement + ); + this.browserFullscreen.set(isFs); + }; + + document.addEventListener('fullscreenchange', updateFullscreenState); + document.addEventListener('webkitfullscreenchange', updateFullscreenState); + document.addEventListener('mozfullscreenchange', updateFullscreenState); + document.addEventListener('MSFullscreenChange', updateFullscreenState); + + effect(() => { + localStorage.setItem('show-chords-default', this.showChordsDefault().toString()); + }); + + effect(() => { + const mode = this.fullscreenMode(); + localStorage.setItem('fullscreen-mode', mode.toString()); + }); + + effect(() => { + localStorage.setItem('auto-advance', this.autoAdvance().toString()); + }); + + effect(() => { + localStorage.setItem('show-tags-in-list', this.showTagsInList().toString()); + }); + + effect(() => { + localStorage.setItem('show-update-date', this.showUpdateDate().toString()); + }); + + effect(() => { + localStorage.setItem('show-duration-bpm-tonality', this.showDurationBpmTonality().toString()); + }); + + effect(() => { + localStorage.setItem('enable-standard-autoscroll', this.enableStandardAutoscroll().toString()); + }); + + effect(() => { + localStorage.setItem('enable-visual-autoscroll', this.enableVisualAutoscroll().toString()); + }); + + effect(() => { + localStorage.setItem('chord-notation-preference', this.chordNotationPreference()); + }); + + effect(() => { + localStorage.setItem('karaoke-page-scroll-mode', this.karaokePageScrollMode().toString()); + }); + + effect(() => { + localStorage.setItem('landscape-projection-enabled', this.landscapeProjectionEnabled().toString()); + }); + + effect(() => { + localStorage.setItem('car-mode-black-screen', this.carModeBlackScreen().toString()); + }); + + effect(() => { + localStorage.setItem('global-zoom', this.globalZoom().toString()); + }); + + // La navigazione con fotocamera deve SEMPRE partire disattivata all'avvio dell'app + this.cameraNavigationActive.set(false); + + const savedCameraTrackingMode = localStorage.getItem('camera-tracking-mode'); + if (savedCameraTrackingMode === 'tilt' || savedCameraTrackingMode === 'distance') { + this.cameraTrackingMode.set(savedCameraTrackingMode); + } else { + this.cameraTrackingMode.set('tilt'); + } + + const savedCameraDistanceRange = localStorage.getItem('camera-distance-range'); + if (savedCameraDistanceRange === 'close' || savedCameraDistanceRange === 'medium' || savedCameraDistanceRange === 'far') { + this.cameraDistanceRange.set(savedCameraDistanceRange); + } else { + this.cameraDistanceRange.set('medium'); + } + + effect(() => { + localStorage.setItem('camera-navigation-active', this.cameraNavigationActive().toString()); + }); + + effect(() => { + localStorage.setItem('camera-tracking-mode', this.cameraTrackingMode()); + }); + + effect(() => { + localStorage.setItem('camera-distance-range', this.cameraDistanceRange()); + }); + + effect(() => { + const active = this.keepScreenOn(); + localStorage.setItem('keep-screen-on', active.toString()); + if (active) { + this.requestWakeLock(); + } else { + this.releaseWakeLock(); + } + }); + + // Re-request on visibility change + document.addEventListener('visibilitychange', () => { + if (this.keepScreenOn() && document.visibilityState === 'visible') { + this.requestWakeLock(); + } + }); + } + + setShowChordsDefault(val: boolean) { + this.showChordsDefault.set(val); + } + + toggleFullscreenMode() { + this.fullscreenMode.update(v => !v); + } + + toggleAutoAdvance() { + this.autoAdvance.update(v => !v); + } + + toggleEditor() { + const newValue = !this.showEditor(); + this.showEditor.set(newValue); + localStorage.setItem('show-editor', newValue.toString()); + } + + + toggleComunitaEnabled() { + const newValue = !this.comunitaEnabled(); + this.comunitaEnabled.set(newValue); + localStorage.setItem('comunita-enabled', newValue.toString()); + } + + private async requestWakeLock() { + if ('wakeLock' in navigator) { + try { + this.wakeLock = await (navigator as any).wakeLock.request('screen'); + } catch (err: any) { + console.error(`Wake Lock error: ${err.name}, ${err.message}`); + } + } + } + + private releaseWakeLock() { + if (this.wakeLock) { + this.wakeLock.release(); + this.wakeLock = null; + } + } + + toggleBrowserFullscreen() { + const isFs = !!( + document.fullscreenElement || + (document as any).webkitFullscreenElement || + (document as any).mozFullScreenElement || + (document as any).msFullscreenElement + ); + + if (!isFs) { + const docEl = document.documentElement as any; + if (docEl.requestFullscreen) { + docEl.requestFullscreen().catch((err: any) => console.error(err)); + } else if (docEl.webkitRequestFullscreen) { + docEl.webkitRequestFullscreen(); + } else if (docEl.mozRequestFullScreen) { + docEl.mozRequestFullScreen(); + } else if (docEl.msRequestFullscreen) { + docEl.msRequestFullscreen(); + } + } else { + const doc = document as any; + if (doc.exitFullscreen) { + doc.exitFullscreen().catch((err: any) => console.error(err)); + } else if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } else if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } + } + } + + toggleInvioDatiStatistici() { + const newValue = !this.invioDatiStatistici(); + this.invioDatiStatistici.set(newValue); + localStorage.setItem('invio-dati-statistici', newValue.toString()); + } + + toggleShowTagsInList() { + const newValue = !this.showTagsInList(); + this.showTagsInList.set(newValue); + localStorage.setItem('show-tags-in-list', newValue.toString()); + } + + toggleShowUpdateDate() { + const newValue = !this.showUpdateDate(); + this.showUpdateDate.set(newValue); + localStorage.setItem('show-update-date', newValue.toString()); + } + + toggleShowDurationBpmTonality() { + const newValue = !this.showDurationBpmTonality(); + this.showDurationBpmTonality.set(newValue); + localStorage.setItem('show-duration-bpm-tonality', newValue.toString()); + } + + toggleStandardAutoscroll() { + const newValue = !this.enableStandardAutoscroll(); + this.enableStandardAutoscroll.set(newValue); + localStorage.setItem('enable-standard-autoscroll', newValue.toString()); + } + + toggleVisualAutoscroll() { + const newValue = !this.enableVisualAutoscroll(); + this.enableVisualAutoscroll.set(newValue); + localStorage.setItem('enable-visual-autoscroll', newValue.toString()); + } + + toggleKaraokePageScrollMode() { + const newValue = !this.karaokePageScrollMode(); + this.karaokePageScrollMode.set(newValue); + localStorage.setItem('karaoke-page-scroll-mode', newValue.toString()); + } + + toggleLandscapeProjectionEnabled() { + const newValue = !this.landscapeProjectionEnabled(); + this.landscapeProjectionEnabled.set(newValue); + localStorage.setItem('landscape-projection-enabled', newValue.toString()); + } + + toggleCarModeBlackScreen() { + const newValue = !this.carModeBlackScreen(); + this.carModeBlackScreen.set(newValue); + localStorage.setItem('car-mode-black-screen', newValue.toString()); + } + + setChordNotationPreference(val: 'diesis' | 'bemolle') { + this.chordNotationPreference.set(val); + } + + setCameraTrackingMode(val: 'tilt' | 'distance') { + this.cameraTrackingMode.set(val); + } + + setCameraDistanceRange(val: 'close' | 'medium' | 'far') { + this.cameraDistanceRange.set(val); + } + + setUserUuid(uuid: string) { + const trimmed = uuid.trim(); + if (trimmed) { + this.userUuid.set(trimmed); + localStorage.setItem('user-uuid', trimmed); + } + } + + setUserName(name: string) { + const trimmed = name.trim(); + this.userName.set(trimmed); + localStorage.setItem('user-name', trimmed); + } + + async installPwa(): Promise { + const promptEvent = this.deferredPrompt(); + if (!promptEvent) { + return undefined; + } + // Show the install prompt + promptEvent.prompt(); + // Wait for the user to respond to the prompt + const { outcome } = await promptEvent.userChoice; + console.log(`User response to the install prompt: ${outcome}`); + // We've used the prompt, and can't use it again, discard it + this.deferredPrompt.set(null); + this.showInstallButton.set(false); + return outcome; + } +} diff --git a/src/app/services/stats.service.ts b/src/app/services/stats.service.ts new file mode 100644 index 0000000..77fb3f7 --- /dev/null +++ b/src/app/services/stats.service.ts @@ -0,0 +1,192 @@ +import { Injectable, inject, effect } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { SettingsService } from './settings.service'; +import { ConnectivityService } from './connectivity.service'; +import { ComunitaService } from './comunita.service'; +import { VERSION } from '../version'; + +@Injectable({ + providedIn: 'root' +}) +export class StatsService { + private http = inject(HttpClient); + private settingsService = inject(SettingsService); + private connectivityService = inject(ConnectivityService); + private comunitaService = inject(ComunitaService); + + constructor() { + // Automatically trigger sync when the device becomes online + effect(() => { + if (this.connectivityService.isOnline()) { + this.syncStats(); + } + }); + } + + private getOrCreateUUID(): string { + let uuid = localStorage.getItem('stats-uuid'); + if (!uuid) { + uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = Math.random() * 16 | 0; + const v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + localStorage.setItem('stats-uuid', uuid); + } + return uuid; + } + + private formatDateTime(date: Date): string { + const pad = (n: number) => n.toString().padStart(2, '0'); + const y = date.getFullYear(); + const m = pad(date.getMonth() + 1); + const d = pad(date.getDate()); + const h = date.getHours(); + const min = pad(date.getMinutes()); + const s = pad(date.getSeconds()); + return `${y}-${m}-${d} ${h}:${min}:${s}`; + } + + private getBrowserModel(): string { + const ua = navigator.userAgent; + if (ua.includes('Chrome')) return 'Chrome'; + if (ua.includes('Safari') && !ua.includes('Chrome')) return 'Safari'; + if (ua.includes('Firefox')) return 'Firefox'; + return 'Browser'; + } + + private getLocalLogs(): any[] { + const data = localStorage.getItem('stats-logs-queue'); + return data ? JSON.parse(data) : []; + } + + private saveLocalLogs(logs: any[]) { + localStorage.setItem('stats-logs-queue', JSON.stringify(logs)); + } + + private clearLocalLogs() { + localStorage.removeItem('stats-logs-queue'); + } + + private getLocalSongSettings(): any[] { + const data = localStorage.getItem('stats-settings-queue'); + return data ? JSON.parse(data) : []; + } + + private saveLocalSongSettings(settings: any[]) { + localStorage.setItem('stats-settings-queue', JSON.stringify(settings)); + } + + logSongView(idCanti: number, timeSpentSeconds: number) { + if (!this.settingsService.invioDatiStatistici()) return; + if (timeSpentSeconds < 1) return; // Ignore very short views + + console.log('📊 StatsService: logSongView called for song', idCanti, 'timespent:', timeSpentSeconds); + + const logEntry = { + uuid: this.getOrCreateUUID(), + id_canti: idCanti.toString(), + data_log: this.formatDateTime(new Date()), + version: VERSION, + tempo: Math.round(timeSpentSeconds), + lat: null, + lon: null, + json: JSON.stringify({ + model: this.getBrowserModel(), + height: window.innerHeight, + width: window.innerWidth + }), + stato: 0, + id: Math.floor(Math.random() * 100000) + }; + + const logs = this.getLocalLogs(); + logs.push(logEntry); + this.saveLocalLogs(logs); + + this.syncStats(); + } + + updateSongSettings(idCanti: number, tonalita: number, speed: number = 0) { + if (!this.settingsService.invioDatiStatistici()) return; + + console.log('📊 StatsService: updateSongSettings called for song', idCanti, 'tonalita:', tonalita); + + const settingsList = this.getLocalSongSettings(); + const idx = settingsList.findIndex(s => s.id_canti === idCanti); + + if (idx !== -1) { + settingsList[idx].tonalita = tonalita; + settingsList[idx].speed = speed; + } else { + settingsList.push({ + id_canti: idCanti, + speed: speed, + tonalita: tonalita, + id: Math.floor(Math.random() * 100000) + }); + } + + this.saveLocalSongSettings(settingsList); + this.syncStats(); + } + + private clearLocalStats() { + localStorage.removeItem('stats-logs-queue'); + localStorage.removeItem('stats-settings-queue'); + } + + syncStats() { + if (!this.settingsService.invioDatiStatistici()) { + console.log('📊 StatsService: Sync ignored (settings disabled)'); + return; + } + if (!this.connectivityService.isOnline()) { + console.log('📊 StatsService: Sync postponed (offline)'); + return; + } + + const logs = this.getLocalLogs(); + const settings = this.getLocalSongSettings(); + + console.log('📊 StatsService: syncStats checking queues. Logs:', logs.length, 'Settings:', settings.length); + + if (logs.length === 0 && settings.length === 0) { + return; + } + + const uuid = this.getOrCreateUUID(); + const email = this.comunitaService.comunitaMail() || `pwa-${uuid.substring(0,8)}@librettocanti.it`; + + const payload = { + uuid: uuid, + log: logs, + pref: [], + canti_settings: settings, + user_devices: { + uuid: uuid, + email: email, + platform: 'browser', + version: VERSION, + gruppo: (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) ? this.comunitaService.comunitaCode() : '', + all_song: false, + deleteList: false, + deletePref: false, + data_app_sync: this.formatDateTime(new Date()) + } + }; + + const url = `https://api.librettocanti.it/canti/api/v1/updateOnlineDB?uuid=${uuid}&email=${email}`; + console.log('📊 StatsService: Sending POST request to:', url, 'with payload:', payload); + + this.http.post(url, payload).subscribe({ + next: (res) => { + this.clearLocalStats(); + console.log('📊 StatsService: Sync successful!', res); + }, + error: (err) => { + console.error('📊 StatsService: Sync failed, keeping in local buffer...', err); + } + }); + } +} diff --git a/src/app/services/theme.service.ts b/src/app/services/theme.service.ts new file mode 100644 index 0000000..b5356f7 --- /dev/null +++ b/src/app/services/theme.service.ts @@ -0,0 +1,69 @@ +import { Injectable, signal, effect } from '@angular/core'; + +@Injectable({ + providedIn: 'root' +}) +export class ThemeService { + public highContrast = signal(true); + + /** Whether the system prefers dark mode */ + private systemPrefersDark = signal(false); + + constructor() { + // Load from localStorage + const saved = localStorage.getItem('high-contrast'); + if (saved !== null) { + this.highContrast.set(saved === 'true'); + } else { + this.highContrast.set(true); + } + + // Detect system dark mode preference + if (typeof window !== 'undefined') { + const darkMq = window.matchMedia('(prefers-color-scheme: dark)'); + this.systemPrefersDark.set(darkMq.matches); + darkMq.addEventListener('change', (e) => { + this.systemPrefersDark.set(e.matches); + }); + } + + // Effect to apply high-contrast class to body and html + effect(() => { + const isHigh = this.highContrast(); + if (typeof document !== 'undefined') { + const root = document.documentElement; + if (isHigh) { + root.classList.add('high-contrast'); + if (document.body) document.body.classList.add('high-contrast'); + } else { + root.classList.remove('high-contrast'); + if (document.body) document.body.classList.remove('high-contrast'); + } + } + localStorage.setItem('high-contrast', isHigh.toString()); + }); + + // Effect to manage Ionic dark palette class + // When high contrast is ON → NEVER apply dark palette (force light mode) + // When high contrast is OFF and system prefers dark → apply dark palette + effect(() => { + const isHigh = this.highContrast(); + const systemDark = this.systemPrefersDark(); + + if (typeof document !== 'undefined') { + const root = document.documentElement; + if (!isHigh && systemDark) { + root.classList.add('ion-palette-dark'); + if (document.body) document.body.classList.add('ion-palette-dark'); + } else { + root.classList.remove('ion-palette-dark'); + if (document.body) document.body.classList.remove('ion-palette-dark'); + } + } + }); + } + + toggleContrast() { + this.highContrast.update(v => !v); + } +} diff --git a/src/app/services/youtube-player.service.ts b/src/app/services/youtube-player.service.ts new file mode 100644 index 0000000..585d6c3 --- /dev/null +++ b/src/app/services/youtube-player.service.ts @@ -0,0 +1,311 @@ +import { Injectable, signal, effect, inject, computed } from '@angular/core'; +import { CantiService } from './canti.service'; +import { SettingsService } from './settings.service'; +import { MediaSessionService } from './media-session.service'; +import { MyCantiService } from './my-canti.service'; +import { ConnectivityService } from './connectivity.service'; +import { ComunitaService } from './comunita.service'; +import { PlaylistService } from './playlist.service'; + +@Injectable({ + providedIn: 'root' +}) +export class YoutubePlayerService { + private cantiService = inject(CantiService); + private settingsService = inject(SettingsService); + private mediaSessionService = inject(MediaSessionService); + private myCantiService = inject(MyCantiService); + private connectivityService = inject(ConnectivityService); + private comunitaService = inject(ComunitaService); + private playlistService = inject(PlaylistService); + + public isPlayerSupported = computed(() => { + // Check if offline + if (!this.connectivityService.isOnline()) { + return false; + } + return true; + }); + + public currentCantoId = signal(null); + public isPlaying = signal(false); + public videoProgress = signal(0); + public videoDuration = signal(0); + public isPlayerReady = signal(false); + + private player: any = null; + private progressInterval: any = null; + private onEndedCallback: (() => void) | null = null; + private onErrorCallback: (() => void) | null = null; + private silentAudio: HTMLAudioElement | null = null; + private lastNextCallback: (() => void) | null = null; + private lastPrevCallback: (() => void) | null = null; + + constructor() { + this.loadYoutubeAPI(); + this.setupMediaSession(); + this.initSilentAudio(); + this.setupBackgroundPersistence(); + + // Auto-stop player when not supported (e.g. going offline) + effect(() => { + const supported = this.isPlayerSupported(); + if (!supported) { + this.isPlaying.set(false); + this.destroyPlayer(); + } + }); + } + + private initSilentAudio() { + // 1-second silent MP3 base64 + const silentSrc = 'data:audio/mpeg;base64,SUQzBAAAAAABAFRYWFhYAAAADAAAY29udGVudAB0eXBlAGF1ZGlvL21wZWdB///+8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + this.silentAudio = new Audio(silentSrc); + this.silentAudio.loop = true; + } + + private setupBackgroundPersistence() { + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible' && this.isPlaying() && this.player) { + // Ensure player is actually playing when returning to the app + try { + if (this.player.getPlayerState() !== (window as any).YT.PlayerState.PLAYING) { + this.player.playVideo(); + } + } catch (e) {} + } + }); + } + + public setMediaSessionCallbacks(next?: () => void, prev?: () => void) { + if (next) this.lastNextCallback = next; + if (prev) this.lastPrevCallback = prev; + + this.mediaSessionService.initActionHandlers({ + play: () => this.resume(), + pause: () => this.pause(), + seekto: (time) => this.seekTo(time), + next: this.lastNextCallback || undefined, + prev: this.lastPrevCallback || undefined + }); + } + + private setupMediaSession() { + this.setMediaSessionCallbacks(); + } + + private loadYoutubeAPI() { + if ((window as any).YT) return; + const tag = document.createElement('script'); + tag.src = "https://www.youtube.com/iframe_api"; + const firstScriptTag = document.getElementsByTagName('script')[0]; + firstScriptTag.parentNode?.insertBefore(tag, firstScriptTag); + + (window as any).onYouTubeIframeAPIReady = () => { + this.isPlayerReady.set(true); + }; + } + + public initPlayer(cantoId: string, startTime: number = 0, onEnded?: () => void, onError?: () => void, customYoutubeLink?: string) { + if (this.currentCantoId() === cantoId && this.player && !customYoutubeLink) { + this.onEndedCallback = onEnded || null; + this.onErrorCallback = onError || null; + + const currentTime = this.player.getCurrentTime(); + // Only seek if the difference is significant (more than 2 seconds) + if (startTime > 0 && Math.abs(currentTime - startTime) > 2) { + this.player.seekTo(startTime, true); + } + this.resume(); + return; + } + + this.onEndedCallback = onEnded || null; + this.onErrorCallback = onError || null; + + let videoId: string | null = null; + if (customYoutubeLink) { + videoId = this.cantiService.getYoutubeId(customYoutubeLink); + } else { + let canto = this.cantiService.getCantoById(cantoId); + if (!canto) { + canto = this.myCantiService.myCanti().find(c => c.id === cantoId); + } + if (!canto) { + canto = this.comunitaService.comunitaCantiPersonali().find(c => c.id === cantoId); + } + if (!canto) { + canto = this.playlistService.remoteCustomSongs().find(c => c.id === cantoId || String(c.id_canti) === cantoId); + } + if (!canto) { + canto = this.playlistService.remoteShareCanti().find(c => c.id === cantoId || String(c.id_canti) === cantoId); + } + if (canto) { + videoId = this.cantiService.getYoutubeId(canto.link_youtube); + } + } + + if (!videoId) { + if (onError) onError(); + return; + } + + if (!(window as any).YT || !(window as any).YT.Player) { + setTimeout(() => this.initPlayer(cantoId, startTime, onEnded, onError, customYoutubeLink), 200); + return; + } + + // Reuse existing player if possible + if (this.player && this.player.loadVideoById) { + this.currentCantoId.set(cantoId); + if (customYoutubeLink) { + if ('mediaSession' in navigator && 'MediaMetadata' in window) { + try { + (navigator as any).mediaSession.metadata = new (window as any).MediaMetadata({ + title: 'Anteprima Canto', + artist: 'Canti Cristiani', + album: 'Canti Cristiani', + artwork: [{ src: 'assets/icon/favicon.png', sizes: '512x512', type: 'image/png' }] + }); + } catch (e) {} + } + } else { + this.mediaSessionService.updateMetadata(cantoId); + } + this.player.loadVideoById({ + videoId: videoId, + startSeconds: startTime + }); + if (this.silentAudio) this.silentAudio.play().catch(() => {}); + return; + } + + this.destroyPlayer(); + this.currentCantoId.set(cantoId); + if (customYoutubeLink) { + if ('mediaSession' in navigator && 'MediaMetadata' in window) { + try { + (navigator as any).mediaSession.metadata = new (window as any).MediaMetadata({ + title: 'Anteprima Canto', + artist: 'Canti Cristiani', + album: 'Canti Cristiani', + artwork: [{ src: 'assets/icon/favicon.png', sizes: '512x512', type: 'image/png' }] + }); + } catch (e) {} + } + } else { + this.mediaSessionService.updateMetadata(cantoId); + } + + this.player = new (window as any).YT.Player('global-yt-player-container', { + height: '1', + width: '1', + videoId: videoId, + playerVars: { + autoplay: 1, + playsinline: 1, + mute: 0, + modestbranding: 1, + rel: 0, + controls: 0, + disablekb: 1, + start: startTime + }, + events: { + onReady: (event: any) => { + event.target.unMute(); + event.target.setVolume(100); + this.videoDuration.set(event.target.getDuration()); + this.startPolling(); + if (startTime > 0) { + event.target.seekTo(startTime, true); + } + event.target.playVideo(); + this.isPlaying.set(true); + if (this.silentAudio) this.silentAudio.play().catch(() => {}); + }, + onStateChange: (event: any) => { + const state = event.data; + if (state === (window as any).YT.PlayerState.PLAYING) { + this.isPlaying.set(true); + this.videoDuration.set(this.player.getDuration()); + this.mediaSessionService.setPlaybackState('playing'); + // Re-apply handlers to prevent YT from overriding them + this.setMediaSessionCallbacks(); + } else if (state === (window as any).YT.PlayerState.PAUSED) { + this.isPlaying.set(false); + this.mediaSessionService.setPlaybackState('paused'); + // Re-apply handlers even when paused + this.setMediaSessionCallbacks(); + } else if (state === (window as any).YT.PlayerState.ENDED) { + this.isPlaying.set(false); + this.mediaSessionService.setPlaybackState('none'); + if (this.onEndedCallback) this.onEndedCallback(); + } + }, + onError: (event: any) => { + console.error('Global YT Player Error:', event.data); + if (this.onErrorCallback) this.onErrorCallback(); + } + } + }); + } + + public pause() { + if (this.player) { + this.player.pauseVideo(); + this.isPlaying.set(false); + if (this.silentAudio) this.silentAudio.pause(); + } + } + + public resume() { + if (this.player) { + this.player.playVideo(); + this.isPlaying.set(true); + if (this.silentAudio) this.silentAudio.play().catch(() => {}); + } + } + + public togglePlayPause() { + if (this.isPlaying()) { + this.pause(); + } else { + this.resume(); + } + } + + public seekTo(seconds: number) { + if (this.player) { + this.player.seekTo(seconds, true); + } + } + + public stop() { + this.destroyPlayer(); + this.currentCantoId.set(null); + this.isPlaying.set(false); + } + + private startPolling() { + if (this.progressInterval) clearInterval(this.progressInterval); + this.progressInterval = setInterval(() => { + if (this.player && this.player.getCurrentTime) { + this.videoProgress.set(this.player.getCurrentTime()); + } + }, 500); + } + + private destroyPlayer() { + if (this.progressInterval) { + clearInterval(this.progressInterval); + this.progressInterval = null; + } + if (this.player) { + try { + this.player.destroy(); + } catch (e) {} + this.player = null; + } + } +} diff --git a/src/app/version.ts b/src/app/version.ts new file mode 100644 index 0000000..f9b9e9d --- /dev/null +++ b/src/app/version.ts @@ -0,0 +1 @@ +export const VERSION = '2026.08.24.0113'; diff --git a/src/assets/icon/favicon.png b/src/assets/icon/favicon.png new file mode 100644 index 0000000..b4f8114 Binary files /dev/null and b/src/assets/icon/favicon.png differ diff --git a/src/assets/icon/icon.png b/src/assets/icon/icon.png new file mode 100644 index 0000000..b4f8114 Binary files /dev/null and b/src/assets/icon/icon.png differ diff --git a/src/assets/icons/icon-128x128.png b/src/assets/icons/icon-128x128.png new file mode 100644 index 0000000..f9375e1 Binary files /dev/null and b/src/assets/icons/icon-128x128.png differ diff --git a/src/assets/icons/icon-144x144.png b/src/assets/icons/icon-144x144.png new file mode 100644 index 0000000..37894af Binary files /dev/null and b/src/assets/icons/icon-144x144.png differ diff --git a/src/assets/icons/icon-152x152.png b/src/assets/icons/icon-152x152.png new file mode 100644 index 0000000..a856095 Binary files /dev/null and b/src/assets/icons/icon-152x152.png differ diff --git a/src/assets/icons/icon-192x192.png b/src/assets/icons/icon-192x192.png new file mode 100644 index 0000000..750473c Binary files /dev/null and b/src/assets/icons/icon-192x192.png differ diff --git a/src/assets/icons/icon-384x384.png b/src/assets/icons/icon-384x384.png new file mode 100644 index 0000000..d05a3d5 Binary files /dev/null and b/src/assets/icons/icon-384x384.png differ diff --git a/src/assets/icons/icon-512x512.png b/src/assets/icons/icon-512x512.png new file mode 100644 index 0000000..f5a59bc Binary files /dev/null and b/src/assets/icons/icon-512x512.png differ diff --git a/src/assets/icons/icon-72x72.png b/src/assets/icons/icon-72x72.png new file mode 100644 index 0000000..61c6986 Binary files /dev/null and b/src/assets/icons/icon-72x72.png differ diff --git a/src/assets/icons/icon-96x96.png b/src/assets/icons/icon-96x96.png new file mode 100644 index 0000000..81dea00 Binary files /dev/null and b/src/assets/icons/icon-96x96.png differ diff --git a/src/assets/imagemenu.png b/src/assets/imagemenu.png new file mode 100644 index 0000000..fb5c07e Binary files /dev/null and b/src/assets/imagemenu.png differ diff --git a/src/assets/logo_ref.png b/src/assets/logo_ref.png new file mode 100644 index 0000000..efd219b Binary files /dev/null and b/src/assets/logo_ref.png differ diff --git a/src/assets/mediapipe/camera_utils.js b/src/assets/mediapipe/camera_utils.js new file mode 100644 index 0000000..8a7df29 --- /dev/null +++ b/src/assets/mediapipe/camera_utils.js @@ -0,0 +1,23 @@ +(function(){/* + + Copyright The Closure Library Authors. + SPDX-License-Identifier: Apache-2.0 +*/ +'use strict';function n(a){var b=0;return function(){return b>>0)+"_",h=0;return b}); +v("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),e=0;e>>0)+"_",e=0;return b}); +J("Symbol.iterator",function(a){if(a)return a;a=Symbol("Symbol.iterator");for(var b="Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array".split(" "),c=0;cc&&(c=Math.max(c+e,0));cg)d[c++]=g;else{if(2048>g)d[c++]=g>>6|192;else{if(55296<=g&&57343>=g){if(56319>=g&&e=f){g=1024*(g-55296)+f-56320+65536;d[c++]=g>>18|240;d[c++]=g>>12&63|128;d[c++]=g>>6&63|128;d[c++]=g&63|128;continue}else e--}if(b)throw Error("Found an unpaired surrogate");g=65533}d[c++]= +g>>12|224;d[c++]=g>>6&63|128}d[c++]=g&63|128}}a=d.subarray(0,c)}return a};var Da={},Ea=null;function Fa(a,b){void 0===b&&(b=0);Ga();b=Da[b];for(var c=Array(Math.floor(a.length/3)),d=b[64]||"",e=0,g=0;e>2];f=b[(f&3)<<4|h>>4];h=b[(h&15)<<2|k>>6];k=b[k&63];c[g++]=l+f+h+k}l=0;k=d;switch(a.length-e){case 2:l=a[e+1],k=b[(l&15)<<2]||d;case 1:a=a[e],c[g]=b[a>>2]+b[(a&3)<<4|l>>4]+k+d}return c.join("")} +function Ha(a){var b=a.length,c=3*b/4;c%3?c=Math.floor(c):-1!="=.".indexOf(a[b-1])&&(c=-1!="=.".indexOf(a[b-2])?c-2:c-1);var d=new Uint8Array(c),e=0;Ia(a,function(g){d[e++]=g});return d.subarray(0,e)} +function Ia(a,b){function c(k){for(;d>4);64!=f&&(b(g<<4&240|f>>2),64!=h&&b(f<<6&192|h))}} +function Ga(){if(!Ea){Ea={};for(var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".split(""),b=["+/=","+/","-_=","-_.","-_"],c=0;5>c;c++){var d=a.concat(b[c].split(""));Da[c]=d;for(var e=0;ee&&128<=b;e++)b=a.h[a.g++],c|=(b&127)<<7*e;128<=b&&(b=a.h[a.g++],c|=(b&127)<<28,d|=(b&127)>>4);if(128<=b)for(e=0;5>e&&128<=b;e++)b=a.h[a.g++],d|=(b&127)<<7*e+3;if(128>b){a=c>>>0;b=d>>>0;if(d=b&2147483648)a=~a+1>>>0,b=~b>>>0,0==a&&(b=b+1>>>0);a=4294967296*b+(a>>>0);return d?-a:a}a.m=!0} +Ma.prototype.i=function(){var a=this.h,b=a[this.g],c=b&127;if(128>b)return this.g+=1,c;b=a[this.g+1];c|=(b&127)<<7;if(128>b)return this.g+=2,c;b=a[this.g+2];c|=(b&127)<<14;if(128>b)return this.g+=3,c;b=a[this.g+3];c|=(b&127)<<21;if(128>b)return this.g+=4,c;b=a[this.g+4];c|=(b&15)<<28;if(128>b)return this.g+=5,c>>>0;this.g+=5;128<=a[this.g++]&&128<=a[this.g++]&&128<=a[this.g++]&&128<=a[this.g++]&&this.g++;return c}; +Ma.prototype.o=function(){var a=this.h[this.g],b=this.h[this.g+1];var c=this.h[this.g+2];var d=this.h[this.g+3];this.g+=4;c=(a<<0|b<<8|c<<16|d<<24)>>>0;a=2*(c>>31)+1;b=c>>>23&255;c&=8388607;return 255==b?c?NaN:Infinity*a:0==b?a*Math.pow(2,-149)*c:a*Math.pow(2,b-150)*(c+Math.pow(2,23))};var Pa=[];function Qa(){this.g=new Uint8Array(64);this.h=0}Qa.prototype.push=function(a){if(!(this.h+1>>=7;a.push(b)};function Sa(a){var b={},c=void 0===b.N?!1:b.N;this.o={v:void 0===b.v?!1:b.v};this.N=c;b=this.o;Pa.length?(c=Pa.pop(),b&&(c.v=b.v),a&&Na(c,a),a=c):a=new Ma(a,b);this.g=a;this.m=this.g.g;this.h=this.i=this.l=-1;this.j=!1}Sa.prototype.reset=function(){this.g.reset();this.h=this.l=-1};function S(a){var b=a.g;(b=b.g==b.j)||(b=a.j)||(b=a.g,b=b.m||0>b.g||b.g>b.j);if(b)return!1;a.m=a.g.g;b=a.g.i();var c=b&7;if(0!=c&&5!=c&&1!=c&&2!=c&&3!=c&&4!=c)return a.j=!0,!1;a.i=b;a.l=b>>>3;a.h=c;return!0} +function Ta(a){switch(a.h){case 0:if(0!=a.h)Ta(a);else{for(a=a.g;a.h[a.g]&128;)a.g++;a.g++}break;case 1:1!=a.h?Ta(a):(a=a.g,a.g+=8);break;case 2:if(2!=a.h)Ta(a);else{var b=a.g.i();a=a.g;a.g+=b}break;case 5:5!=a.h?Ta(a):(a=a.g,a.g+=4);break;case 3:b=a.l;do{if(!S(a)){a.j=!0;break}if(4==a.h){a.l!=b&&(a.j=!0);break}Ta(a)}while(1);break;default:a.j=!0}} +function Ua(a,b,c){var d=a.g.j,e=a.g.i(),g=a.g.g+e;a.g.j=g;c(b,a);c=g-a.g.g;if(0!==c)throw Error("Message parsing ended unexpectedly. Expected to read "+e+" bytes, instead read "+(e-c)+" bytes, either the data ended unexpectedly or the message misreported its own length");a.g.g=g;a.g.j=d;return b}function T(a){return a.g.o()} +function Va(a){var b=a.g.i();a=a.g;var c=a.g;a.g+=b;a=a.h;var d;if(za)(d=ya)||(d=ya=new TextDecoder("utf-8",{fatal:!1})),d=d.decode(a.subarray(c,c+b));else{b=c+b;for(var e=[],g=null,f,h,k;cf?e.push(f):224>f?c>=b?e.push(65533):(h=a[c++],194>f||128!==(h&192)?(c--,e.push(65533)):e.push((f&31)<<6|h&63)):240>f?c>=b-1?e.push(65533):(h=a[c++],128!==(h&192)||224===f&&160>h||237===f&&160<=h||128!==((d=a[c++])&192)?(c--,e.push(65533)):e.push((f&15)<<12|(h&63)<<6|d&63)):244>=f?c>=b-2?e.push(65533): +(h=a[c++],128!==(h&192)||0!==(f<<28)+(h-144)>>30||128!==((d=a[c++])&192)||128!==((k=a[c++])&192)?(c--,e.push(65533)):(f=(f&7)<<18|(h&63)<<12|(d&63)<<6|k&63,f-=65536,e.push((f>>10&1023)+55296,(f&1023)+56320))):e.push(65533),8192<=e.length&&(g=xa(g,e),e.length=0);d=xa(g,e)}return d}function Wa(a,b,c){var d=a.g.i();for(d=a.g.g+d;a.g.gd?1:0)?-d:d;0===d?0<1/d?Q=R=0:(R=0,Q=2147483648):isNaN(d)?(R=0,Q=2147483647):3.4028234663852886E38>>0):1.1754943508222875E-38>d?(d=Math.round(d/Math.pow(2,-149)),R=0,Q=(c<<31|d)>>>0):(b=Math.floor(Math.log(d)/Math.LN2),d*=Math.pow(2,-b),d=Math.round(8388608*d),16777216<=d&&++b,R=0,Q=(c<<31|b+127<<23|d&8388607)>>>0);c=Q;a.push(c>>>0&255);a.push(c>>>8&255);a.push(c>>>16&255);a.push(c>>>24&255)}};var ab="function"===typeof Uint8Array;function bb(a,b,c){if(null!=a)return"object"===typeof a?ab&&a instanceof Uint8Array?c(a):cb(a,b,c):b(a)}function cb(a,b,c){if(Array.isArray(a)){for(var d=Array(a.length),e=0;e=a.l?a.i?a.i[b]:void 0:a.h[b+a.j]}function jb(a,b){var c=void 0===c?!1:c;var d=W(a,b,c);null==d&&(d=hb);d===hb&&(d=db([]),X(a,b,d,c));return d}function kb(a){var b=jb(a,3);a.m||(a.m={});if(!a.m[3]){for(var c=0;c=a.l?(ib(a),a.i[b]=c):a.h[b+a.j]=c}function mb(a,b,c){if(-1===c)return null;a.g||(a.g={});if(!a.g[c]){var d=W(a,c,!1);d&&(a.g[c]=new b(d))}return a.g[c]}function nb(a,b){a.g||(a.g={});var c=a.g[1];if(!c){var d=jb(a,1);c=[];for(var e=0;eB;B=Math.abs(B);var D=B>>>0;B=Math.floor((B-D)/4294967296);B>>>=0;C&&(B=~B>>> +0,D=(~D>>>0)+1,4294967295>>7|D<<25)>>>0,D>>>=7;q.push(C)}rb(p,A);H=$a(H);F.call(E,I,H);if(z.O)for(E=0;EB;B++)C.push(D&127|128),D>>=7;C.push(1)}U(q,2,W(A,2));C=W(A,3);null!=C&&(C=Ca(C),Ra(q.g,26),Ra(q.g,C.length),Za(q,q.g.end()),Za(q,C));C=W(A,4);null!=C&&(C=Ca(C),Ra(q.g,34),Ra(q.g,C.length),Za(q,q.g.end()), +Za(q,C));rb(A,q);p=$a(p);I.call(F,H,p)}}m=m.data;break a;default:m={}}}u=m;w=n.stream;switch(n.type){case "video":f.pushTexture2d(Object.assign(Object.assign({},u),{stream:w,timestamp:g}));break;case "detections":r=u;r.stream=w;r.timestamp=g;f.pushDetectionList(r);break;default:throw Error("Unknown input config type: '"+n.type+"'");}}e.i.send(f);return N(y,e.C,4);case 4:f.delete(),y.g=0}})})}; +function dc(a,b,c){return Z(a,function e(){var g,f,h,k,l,n,u=this,w,r,y,m,t,x,z,E;return O(e,function(F){switch(F.g){case 1:if(!c)return F.return(b);g={};f=0;h=K(Object.keys(c));for(k=h.next();!k.done;k=h.next())l=k.value,n=c[l],"string"!==typeof n&&"texture"===n.type&&void 0!==b[n.stream]&&++f;11){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status,toThrow){if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof process==="object"&&typeof require==="function"||typeof window==="object"||typeof importScripts==="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};readAsync=function readAsync(f,onload,onerror){setTimeout(function(){onload(readBinary(f))},0)};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window==="object"||typeof importScripts==="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(!Object.getOwnPropertyDescriptor(Module,"arguments")){Object.defineProperty(Module,"arguments",{configurable:true,get:function(){abort("Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(!Object.getOwnPropertyDescriptor(Module,"thisProgram")){Object.defineProperty(Module,"thisProgram",{configurable:true,get:function(){abort("Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(Module["quit"])quit_=Module["quit"];if(!Object.getOwnPropertyDescriptor(Module,"quit")){Object.defineProperty(Module,"quit",{configurable:true,get:function(){abort("Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(typeof Module["memoryInitializerPrefixURL"]==="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]==="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]==="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]==="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]==="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]==="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]==="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]==="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");assert(typeof Module["TOTAL_MEMORY"]==="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");if(!Object.getOwnPropertyDescriptor(Module,"read")){Object.defineProperty(Module,"read",{configurable:true,get:function(){abort("Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"readAsync")){Object.defineProperty(Module,"readAsync",{configurable:true,get:function(){abort("Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"readBinary")){Object.defineProperty(Module,"readBinary",{configurable:true,get:function(){abort("Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"setWindowTitle")){Object.defineProperty(Module,"setWindowTitle",{configurable:true,get:function(){abort("Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-s ENVIRONMENT` to enable.");function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}function convertJsFunctionToWasm(func,sig){if(typeof WebAssembly.Function==="function"){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>=2097152)warnOnce("Invalid Unicode code point 0x"+u.toString(16)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x1FFFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var TOTAL_STACK=5242880;if(Module["TOTAL_STACK"])assert(TOTAL_STACK===Module["TOTAL_STACK"],"the stack size can no longer be determined at runtime");var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(!Object.getOwnPropertyDescriptor(Module,"INITIAL_MEMORY")){Object.defineProperty(Module,"INITIAL_MEMORY",{configurable:true,get:function(){abort("Module.INITIAL_MEMORY has been replaced with plain INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(INITIAL_MEMORY>=TOTAL_STACK,"INITIAL_MEMORY should be larger than TOTAL_STACK, was "+INITIAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")");assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!==undefined&&Int32Array.prototype.set!==undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -s IMPORTED_MEMORY to define wasmMemory externally");assert(INITIAL_MEMORY==16777216,"Detected runtime INITIAL_MEMORY setting. Use -s IMPORTED_MEMORY to define wasmMemory dynamically");var wasmTable;function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);HEAPU32[(max>>2)+1]=34821223;HEAPU32[(max>>2)+2]=2310721022;HEAP32[0]=1668509029}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();var cookie1=HEAPU32[(max>>2)+1];var cookie2=HEAPU32[(max>>2)+2];if(cookie1!=34821223||cookie2!=2310721022){abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x"+cookie2.toString(16)+" "+cookie1.toString(16))}if(HEAP32[0]!==1668509029)abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -s SUPPORT_BIG_ENDIAN=1 to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){checkStackCookie();assert(!runtimeInitialized);runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function exitRuntime(){checkStackCookie();runtimeExited=true}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!=="undefined"){runDependencyWatcher=setInterval(function(){if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}},1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;var output="abort("+what+") at "+stackTrace();what=output;var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}function createExportWrapper(name,fixedasm){return function(){var displayName=name;var asm=fixedasm;if(!fixedasm){asm=Module["asm"]}assert(runtimeInitialized,"native function `"+displayName+"` called before runtime initialization");assert(!runtimeExited,"native function `"+displayName+"` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)");if(!asm[name]){assert(asm[name],"exported native function `"+displayName+"` not found")}return asm[name].apply(null,arguments)}}var wasmBinaryFile;wasmBinaryFile="face_mesh_solution_simd_wasm_bin.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];assert(wasmMemory,"memory not found in wasm exports");updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){var result=WebAssembly.instantiate(binary,info);return result}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);if(isFileURI(wasmBinaryFile)){err("warning: Loading from a file URI ("+wasmBinaryFile+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing")}abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={547944:function(){let init_once=true;if(init_once){const cachedFindCanvasEventTarget=findCanvasEventTarget;if(typeof cachedFindCanvasEventTarget!=="function"){if(typeof console!=="undefined"){console.error("Expected Emscripten global function "+'"findCanvasEventTarget" not found. WebGL context creation '+"may fail.")}return}findCanvasEventTarget=function(target){if(target==0){if(Module&&Module.canvas){return Module.canvas}else if(Module&&Module.canvasCssSelector){return cachedFindCanvasEventTarget(Module.canvasCssSelector)}if(typeof console!=="undefined"){console.warn("Module properties canvas and canvasCssSelector not "+"found during WebGL context creation.")}}return cachedFindCanvasEventTarget(target)};init_once=false}},548729:function(){return typeof wasmOffsetConverter!=="undefined"}};function HaveOffsetConverter(){return typeof wasmOffsetConverter!=="undefined"}function _emscripten_set_main_loop_timing(mode,value){Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){err("emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.");return 1}if(!Browser.mainLoop.running){Browser.mainLoop.running=true}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setTimeout(){var timeUntilNextTick=Math.max(0,Browser.mainLoop.tickStartTime+value-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,timeUntilNextTick)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_rAF(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}else if(mode==2){if(typeof setImmediate==="undefined"){var setImmediates=[];var emscriptenMainLoopMessageId="setimmediate";var Browser_setImmediate_messageHandler=function(event){if(event.data===emscriptenMainLoopMessageId||event.data.target===emscriptenMainLoopMessageId){event.stopPropagation();setImmediates.shift()()}};addEventListener("message",Browser_setImmediate_messageHandler,true);setImmediate=function Browser_emulated_setImmediate(func){setImmediates.push(func);if(ENVIRONMENT_IS_WORKER){if(Module["setImmediates"]===undefined)Module["setImmediates"]=[];Module["setImmediates"].push(func);postMessage({target:emscriptenMainLoopMessageId})}else postMessage(emscriptenMainLoopMessageId,"*")}}Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setImmediate(){setImmediate(Browser.mainLoop.runner)};Browser.mainLoop.method="immediate"}return 0}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else _emscripten_get_now=function(){return performance.now()};function _emscripten_webgl_do_commit_frame(){if(!GL.currentContext||!GL.currentContext.GLctx){return-3}if(GL.currentContext.defaultFbo){GL.blitOffscreenFramebuffer(GL.currentContext);return 0}if(!GL.currentContext.attributes.explicitSwapControl){return-3}return 0}function _exit(status){exit(status)}function maybeExit(){if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){if(e instanceof ExitStatus){return}throw e}}}function setMainLoop(browserIterationFunc,fps,simulateInfiniteLoop,arg,noSetTiming){assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=browserIterationFunc;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;function checkIsRunning(){if(thisMainLoopId0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}out('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();if(!checkIsRunning())return;setTimeout(Browser.mainLoop.runner,0);return}if(!checkIsRunning())return;Browser.mainLoop.currentFrameNumber=Browser.mainLoop.currentFrameNumber+1|0;if(Browser.mainLoop.timingMode==1&&Browser.mainLoop.timingValue>1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else if(Browser.mainLoop.timingMode==0){Browser.mainLoop.tickStartTime=_emscripten_get_now()}GL.newRenderingFrameStarted();if(typeof GL!=="undefined"&&GL.currentContext&&!GL.currentContextIsProxied&&!GL.currentContext.attributes.explicitSwapControl&&GL.currentContext.GLctx.commit){GL.currentContext.GLctx.commit()}if(Browser.mainLoop.method==="timeout"&&Module.ctx){warnOnce("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");Browser.mainLoop.method=""}Browser.mainLoop.runIter(browserIterationFunc);checkStackCookie();if(!checkIsRunning())return;if(typeof SDL==="object"&&SDL.audio&&SDL.audio.queueNewAudioData)SDL.audio.queueNewAudioData();Browser.mainLoop.scheduler()};if(!noSetTiming){if(fps&&fps>0)_emscripten_set_main_loop_timing(0,1e3/fps);else _emscripten_set_main_loop_timing(1,1);Browser.mainLoop.scheduler()}if(simulateInfiniteLoop){throw"unwind"}}function callUserCallback(func,synchronous){if(ABORT){err("user callback triggered after application aborted. Ignoring.");return}if(synchronous){func();return}try{func()}catch(e){if(e instanceof ExitStatus){return}else if(e!=="unwind"){if(e&&typeof e==="object"&&e.stack)err("exception thrown: "+[e,e.stack]);throw e}}}function safeSetTimeout(func,timeout){return setTimeout(function(){callUserCallback(func)},timeout)}var Browser={mainLoop:{running:false,scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;setMainLoop(func,0,false,Browser.mainLoop.arg,true);_emscripten_set_main_loop_timing(timingMode,timingValue);Browser.mainLoop.scheduler()},updateStatus:function(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;safeSetTimeout(function(){finish(audio)},1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===Module["canvas"]||document["mozPointerLockElement"]===Module["canvas"]||document["webkitPointerLockElement"]===Module["canvas"]||document["msPointerLockElement"]===Module["canvas"]}var canvas=Module["canvas"];if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||function(){};canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||function(){};canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",function(ev){if(!Browser.pointerLock&&Module["canvas"].requestPointerLock){Module["canvas"].requestPointerLock();ev.preventDefault()}},false)}}},createContext:function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false,majorVersion:typeof WebGL2RenderingContext!=="undefined"?2:1};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}if(typeof GL!=="undefined"){contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}}}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach(function(callback){callback()});Browser.init()}return ctx},destroyContext:function(canvas,useWebGL,setInModule){},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullscreenChange(){Browser.isFullscreen=false;var canvasContainer=canvas.parentNode;if((document["fullscreenElement"]||document["mozFullScreenElement"]||document["msFullscreenElement"]||document["webkitFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.exitFullscreen=Browser.exitFullscreen;if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullscreen=true;if(Browser.resizeCanvas){Browser.setFullscreenCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas){Browser.setWindowedCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullscreen);if(Module["onFullscreen"])Module["onFullscreen"](Browser.isFullscreen)}if(!Browser.fullscreenHandlersInstalled){Browser.fullscreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullscreenChange,false);document.addEventListener("mozfullscreenchange",fullscreenChange,false);document.addEventListener("webkitfullscreenchange",fullscreenChange,false);document.addEventListener("MSFullscreenChange",fullscreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullscreen=canvasContainer["requestFullscreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullscreen"]?function(){canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null)||(canvasContainer["webkitRequestFullScreen"]?function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null);canvasContainer.requestFullscreen()},requestFullScreen:function(){abort("Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)")},exitFullscreen:function(){if(!Browser.isFullscreen){return false}var CFS=document["exitFullscreen"]||document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["msExitFullscreen"]||document["webkitCancelFullScreen"]||function(){};CFS.apply(document,[]);return true},nextRAF:0,fakeRequestAnimationFrame:function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)},requestAnimationFrame:function(func){if(typeof requestAnimationFrame==="function"){requestAnimationFrame(func);return}var RAF=Browser.fakeRequestAnimationFrame;RAF(func)},safeSetTimeout:function(func){return safeSetTimeout(func)},safeRequestAnimationFrame:function(func){return Browser.requestAnimationFrame(function(){callUserCallback(func)})},getMimetype:function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]},getUserMedia:function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)},getMovementX:function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0},getMovementY:function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0},getMouseWheelDelta:function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail/3;break;case"mousewheel":delta=event.wheelDelta/120;break;case"wheel":delta=event.deltaY;switch(event.deltaMode){case 0:delta/=100;break;case 1:delta/=3;break;case 2:delta*=80;break;default:throw"unrecognized mouse wheel delta mode: "+event.deltaMode}break;default:throw"unrecognized mouse wheel event: "+event.type}return delta},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;assert(typeof scrollX!=="undefined"&&typeof scrollY!=="undefined","Unable to retrieve scroll position, mouse positions likely broken.");if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){var last=Browser.touches[touch.identifier];if(!last)last=coords;Browser.lastTouches[touch.identifier]=last;Browser.touches[touch.identifier]=coords}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}},resizeListeners:[],updateResizeListeners:function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach(function(listener){listener(canvas.width,canvas.height)})},setCanvasSize:function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags|8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags&~8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},updateCanvasDimensions:function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function ___cxa_allocate_exception(size){return _malloc(size+16)+16}function _atexit(func,arg){}function ___cxa_atexit(a0,a1){return _atexit(a0,a1)}function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-16;this.set_type=function(type){HEAP32[this.ptr+4>>2]=type};this.get_type=function(){return HEAP32[this.ptr+4>>2]};this.set_destructor=function(destructor){HEAP32[this.ptr+8>>2]=destructor};this.get_destructor=function(){return HEAP32[this.ptr+8>>2]};this.set_refcount=function(refcount){HEAP32[this.ptr>>2]=refcount};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_type(type);this.set_destructor(destructor);this.set_refcount(0);this.set_caught(false);this.set_rethrown(false)};this.add_ref=function(){var value=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=value+1};this.release_ref=function(){var prev=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=prev-1;assert(prev>0);return prev===1}}function CatchInfo(ptr){this.free=function(){_free(this.ptr);this.ptr=0};this.set_base_ptr=function(basePtr){HEAP32[this.ptr>>2]=basePtr};this.get_base_ptr=function(){return HEAP32[this.ptr>>2]};this.set_adjusted_ptr=function(adjustedPtr){HEAP32[this.ptr+4>>2]=adjustedPtr};this.get_adjusted_ptr_addr=function(){return this.ptr+4};this.get_adjusted_ptr=function(){return HEAP32[this.ptr+4>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_exception_info().get_type());if(isPointer){return HEAP32[this.get_base_ptr()>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.get_base_ptr()};this.get_exception_info=function(){return new ExceptionInfo(this.get_base_ptr())};if(ptr===undefined){this.ptr=_malloc(8);this.set_adjusted_ptr(0)}else{this.ptr=ptr}}var exceptionCaught=[];function exception_addRef(info){info.add_ref()}var uncaughtExceptionCount=0;function ___cxa_begin_catch(ptr){var catchInfo=new CatchInfo(ptr);var info=catchInfo.get_exception_info();if(!info.get_caught()){info.set_caught(true);uncaughtExceptionCount--}info.set_rethrown(false);exceptionCaught.push(catchInfo);exception_addRef(info);return catchInfo.get_exception_ptr()}var exceptionLast=0;function ___cxa_free_exception(ptr){try{return _free(new ExceptionInfo(ptr).ptr)}catch(e){err("exception during cxa_free_exception: "+e)}}function exception_decRef(info){if(info.release_ref()&&!info.get_rethrown()){var destructor=info.get_destructor();if(destructor){wasmTable.get(destructor)(info.excPtr)}___cxa_free_exception(info.excPtr)}}function ___cxa_end_catch(){_setThrew(0);assert(exceptionCaught.length>0);var catchInfo=exceptionCaught.pop();exception_decRef(catchInfo.get_exception_info());catchInfo.free();exceptionLast=0}function ___resumeException(catchInfoPtr){var catchInfo=new CatchInfo(catchInfoPtr);var ptr=catchInfo.get_base_ptr();if(!exceptionLast){exceptionLast=ptr}catchInfo.free();throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s NO_DISABLE_EXCEPTION_CATCHING or -s EXCEPTION_CATCHING_ALLOWED=[..] to catch."}function ___cxa_find_matching_catch_2(){var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0|0}var info=new ExceptionInfo(thrown);var thrownType=info.get_type();var catchInfo=new CatchInfo;catchInfo.set_base_ptr(thrown);catchInfo.set_adjusted_ptr(thrown);if(!thrownType){setTempRet0(0);return catchInfo.ptr|0}var typeArray=Array.prototype.slice.call(arguments);for(var i=0;i>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function zeroMemory(address,size){HEAPU8.fill(0,address,address+size)}function alignMemory(size,alignment){assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment}function mmapAlloc(size){size=alignMemory(size,65536);var ptr=_memalign(65536,size);if(!ptr)return 0;zeroMemory(ptr,size);return ptr}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){assert(typeof parent==="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){if(typeof type==="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){assert(SYSCALLS.varargs!=undefined);SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){if(low>=0)assert(high===0);else assert(high===-1);return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function syscallMmap2(addr,len,prot,flags,fd,off){off<<=12;var ptr;var allocated=false;if((flags&16)!==0&&addr%65536!==0){return-28}if((flags&32)!==0){ptr=mmapAlloc(len);if(!ptr)return-48;allocated=true}else{var info=FS.getStream(fd);if(!info)return-8;var res=FS.mmap(info,addr,len,off,prot,flags);ptr=res.ptr;allocated=res.allocated}SYSCALLS.mappings[ptr]={malloc:ptr,len:len,allocated:allocated,fd:fd,prot:prot,flags:flags,offset:off};return ptr}function ___sys_mmap2(addr,len,prot,flags,fd,off){try{return syscallMmap2(addr,len,prot,flags,fd,off)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function count_emval_handles(){var count=0;for(var i=5;i>2])}var awaitingDependencies={};var typeDependencies={};var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){assert("dynCall_"+sig in Module,"bad function pointer type - no table for sig '"+sig+"'");if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}function dynCall(sig,ptr,args){if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(wasmTable.get(ptr),"missing table entry in dynCall: "+ptr);return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.includes("j"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function validateThis(this_,classType,humanName){if(!(this_ instanceof Object)){throwBindingError(humanName+' with invalid "this": '+this_)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(humanName+' incompatible with "this" of type '+this_.constructor.name)}if(!this_.$$.ptr){throwBindingError("cannot call emscripten binding method "+humanName+" on deleted object")}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)}function __embind_register_class_property(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],function(classType){classType=classType[0];var humanName=classType.name+"."+fieldName;var desc={get:function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])}}else{desc.set=function(v){throwBindingError(humanName+" is a read-only property")}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],function(types){var getterReturnType=types[0];var desc={get:function(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})}function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv},"toWireType":function(destructors,value){return __emval_register(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.includes("unsigned");registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _dlopen(filename,flag){abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")}function _dlsym(handle,symbol){abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){assert(Array.isArray(readAsmConstArgsArray));assert(buf%16==0);readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){assert(ch===100||ch===102||ch===105);var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);if(!ASM_CONSTS.hasOwnProperty(code))abort("No EM_ASM constant found at address "+code);return ASM_CONSTS[code].apply(null,args)}function _emscripten_get_heap_max(){return 2147483648}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_pc_get_function(pc){abort("Cannot use emscripten_pc_get_function without -s USE_OFFSET_CONVERTER")}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){err("emscripten_realloc_buffer: Attempted to grow heap from "+buffer.byteLength+" bytes to "+size+" bytes, but got error: "+e)}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;assert(requestedSize>oldSize);var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){err("Cannot enlarge memory, asked to go up to "+requestedSize+" bytes, but the limit is "+maxHeapSize+" bytes!");return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}err("Failed to grow the heap from "+oldSize+" bytes to "+newSize+" bytes, not enough memory!");return false}function _emscripten_generate_pc(frame){abort("Cannot use emscripten_generate_pc (needed by __builtin_return_address) without -s USE_OFFSET_CONVERTER")}var UNWIND_CACHE={};function __emscripten_save_in_unwind_cache(callstack){callstack.forEach(function(frame){var pc=_emscripten_generate_pc(frame);if(pc){UNWIND_CACHE[pc]=frame}})}function _emscripten_stack_snapshot(){var callstack=(new Error).stack.split("\n");if(callstack[0]=="Error"){callstack.shift()}__emscripten_save_in_unwind_cache(callstack);UNWIND_CACHE.last_addr=_emscripten_generate_pc(callstack[2]);UNWIND_CACHE.last_stack=callstack;return UNWIND_CACHE.last_addr}function _emscripten_stack_unwind_buffer(addr,buffer,count){var stack;if(UNWIND_CACHE.last_addr==addr){stack=UNWIND_CACHE.last_stack}else{stack=(new Error).stack.split("\n");if(stack[0]=="Error"){stack.shift()}__emscripten_save_in_unwind_cache(stack)}var offset=2;while(stack[offset]&&_emscripten_generate_pc(stack[offset])!=addr){++offset}for(var i=0;i>2]=_emscripten_generate_pc(stack[i+offset])}return i}function _emscripten_thread_sleep(msecs){var start=_emscripten_get_now();while(_emscripten_get_now()-start>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i1?canvas.getContext("webgl2",webGLContextAttributes):canvas.getContext("webgl",webGLContextAttributes);if(!ctx)return 0;var handle=GL.registerContext(ctx,webGLContextAttributes);return handle},enableOffscreenFramebufferAttributes:function(webGLContextAttributes){webGLContextAttributes.renderViaOffscreenBackBuffer=true;webGLContextAttributes.preserveDrawingBuffer=true},createOffscreenFramebuffer:function(context){var gl=context.GLctx;var fbo=gl.createFramebuffer();gl.bindFramebuffer(36160,fbo);context.defaultFbo=fbo;context.defaultFboForbidBlitFramebuffer=false;if(gl.getContextAttributes().antialias){context.defaultFboForbidBlitFramebuffer=true}else{var firefoxMatch=navigator.userAgent.toLowerCase().match(/firefox\/(\d\d)/);if(firefoxMatch!=null){var firefoxVersion=firefoxMatch[1];context.defaultFboForbidBlitFramebuffer=firefoxVersion<67}}context.defaultColorTarget=gl.createTexture();context.defaultDepthTarget=gl.createRenderbuffer();GL.resizeOffscreenFramebuffer(context);gl.bindTexture(3553,context.defaultColorTarget);gl.texParameteri(3553,10241,9728);gl.texParameteri(3553,10240,9728);gl.texParameteri(3553,10242,33071);gl.texParameteri(3553,10243,33071);gl.texImage2D(3553,0,6408,gl.canvas.width,gl.canvas.height,0,6408,5121,null);gl.framebufferTexture2D(36160,36064,3553,context.defaultColorTarget,0);gl.bindTexture(3553,null);var depthTarget=gl.createRenderbuffer();gl.bindRenderbuffer(36161,context.defaultDepthTarget);gl.renderbufferStorage(36161,33189,gl.canvas.width,gl.canvas.height);gl.framebufferRenderbuffer(36160,36096,36161,context.defaultDepthTarget);gl.bindRenderbuffer(36161,null);var vertices=[-1,-1,-1,1,1,-1,1,1];var vb=gl.createBuffer();gl.bindBuffer(34962,vb);gl.bufferData(34962,new Float32Array(vertices),35044);gl.bindBuffer(34962,null);context.blitVB=vb;var vsCode="attribute vec2 pos;"+"varying lowp vec2 tex;"+"void main() { tex = pos * 0.5 + vec2(0.5,0.5); gl_Position = vec4(pos, 0.0, 1.0); }";var vs=gl.createShader(35633);gl.shaderSource(vs,vsCode);gl.compileShader(vs);var fsCode="varying lowp vec2 tex;"+"uniform sampler2D sampler;"+"void main() { gl_FragColor = texture2D(sampler, tex); }";var fs=gl.createShader(35632);gl.shaderSource(fs,fsCode);gl.compileShader(fs);var blitProgram=gl.createProgram();gl.attachShader(blitProgram,vs);gl.attachShader(blitProgram,fs);gl.linkProgram(blitProgram);context.blitProgram=blitProgram;context.blitPosLoc=gl.getAttribLocation(blitProgram,"pos");gl.useProgram(blitProgram);gl.uniform1i(gl.getUniformLocation(blitProgram,"sampler"),0);gl.useProgram(null);context.defaultVao=undefined;if(gl.createVertexArray){context.defaultVao=gl.createVertexArray();gl.bindVertexArray(context.defaultVao);gl.enableVertexAttribArray(context.blitPosLoc);gl.bindVertexArray(null)}},resizeOffscreenFramebuffer:function(context){var gl=context.GLctx;if(context.defaultColorTarget){var prevTextureBinding=gl.getParameter(32873);gl.bindTexture(3553,context.defaultColorTarget);gl.texImage2D(3553,0,6408,gl.drawingBufferWidth,gl.drawingBufferHeight,0,6408,5121,null);gl.bindTexture(3553,prevTextureBinding)}if(context.defaultDepthTarget){var prevRenderBufferBinding=gl.getParameter(36007);gl.bindRenderbuffer(36161,context.defaultDepthTarget);gl.renderbufferStorage(36161,33189,gl.drawingBufferWidth,gl.drawingBufferHeight);gl.bindRenderbuffer(36161,prevRenderBufferBinding)}},blitOffscreenFramebuffer:function(context){var gl=context.GLctx;var prevScissorTest=gl.getParameter(3089);if(prevScissorTest)gl.disable(3089);var prevFbo=gl.getParameter(36006);if(gl.blitFramebuffer&&!context.defaultFboForbidBlitFramebuffer){gl.bindFramebuffer(36008,context.defaultFbo);gl.bindFramebuffer(36009,null);gl.blitFramebuffer(0,0,gl.canvas.width,gl.canvas.height,0,0,gl.canvas.width,gl.canvas.height,16384,9728)}else{gl.bindFramebuffer(36160,null);var prevProgram=gl.getParameter(35725);gl.useProgram(context.blitProgram);var prevVB=gl.getParameter(34964);gl.bindBuffer(34962,context.blitVB);var prevActiveTexture=gl.getParameter(34016);gl.activeTexture(33984);var prevTextureBinding=gl.getParameter(32873);gl.bindTexture(3553,context.defaultColorTarget);var prevBlend=gl.getParameter(3042);if(prevBlend)gl.disable(3042);var prevCullFace=gl.getParameter(2884);if(prevCullFace)gl.disable(2884);var prevDepthTest=gl.getParameter(2929);if(prevDepthTest)gl.disable(2929);var prevStencilTest=gl.getParameter(2960);if(prevStencilTest)gl.disable(2960);function draw(){gl.vertexAttribPointer(context.blitPosLoc,2,5126,false,0,0);gl.drawArrays(5,0,4)}if(context.defaultVao){var prevVAO=gl.getParameter(34229);gl.bindVertexArray(context.defaultVao);draw();gl.bindVertexArray(prevVAO)}else{var prevVertexAttribPointer={buffer:gl.getVertexAttrib(context.blitPosLoc,34975),size:gl.getVertexAttrib(context.blitPosLoc,34339),stride:gl.getVertexAttrib(context.blitPosLoc,34340),type:gl.getVertexAttrib(context.blitPosLoc,34341),normalized:gl.getVertexAttrib(context.blitPosLoc,34922),pointer:gl.getVertexAttribOffset(context.blitPosLoc,34373)};var maxVertexAttribs=gl.getParameter(34921);var prevVertexAttribEnables=[];for(var i=0;i=2){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query_webgl2")}if(context.version<2||!GLctx.disjointTimerQueryExt){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query")}__webgl_enable_WEBGL_multi_draw(GLctx);var exts=GLctx.getSupportedExtensions()||[];exts.forEach(function(ext){if(!ext.includes("lose_context")&&!ext.includes("debug")){GLctx.getExtension(ext)}})}};var JSEvents={inEventHandler:0,removeAllEventListeners:function(){for(var i=JSEvents.eventHandlers.length-1;i>=0;--i){JSEvents._removeHandler(i)}JSEvents.eventHandlers=[];JSEvents.deferredCalls=[]},registerRemoveEventListeners:function(){if(!JSEvents.removeEventListenersRegistered){__ATEXIT__.push(JSEvents.removeAllEventListeners);JSEvents.removeEventListenersRegistered=true}},deferredCalls:[],deferCall:function(targetFunction,precedence,argsList){function arraysHaveEqualContent(arrA,arrB){if(arrA.length!=arrB.length)return false;for(var i in arrA){if(arrA[i]!=arrB[i])return false}return true}for(var i in JSEvents.deferredCalls){var call=JSEvents.deferredCalls[i];if(call.targetFunction==targetFunction&&arraysHaveEqualContent(call.argsList,argsList)){return}}JSEvents.deferredCalls.push({targetFunction:targetFunction,precedence:precedence,argsList:argsList});JSEvents.deferredCalls.sort(function(x,y){return x.precedence>2;var powerPreference=HEAP32[a+(24>>2)];var contextAttributes={"alpha":!!HEAP32[a+(0>>2)],"depth":!!HEAP32[a+(4>>2)],"stencil":!!HEAP32[a+(8>>2)],"antialias":!!HEAP32[a+(12>>2)],"premultipliedAlpha":!!HEAP32[a+(16>>2)],"preserveDrawingBuffer":!!HEAP32[a+(20>>2)],"powerPreference":__emscripten_webgl_power_preferences[powerPreference],"failIfMajorPerformanceCaveat":!!HEAP32[a+(28>>2)],majorVersion:HEAP32[a+(32>>2)],minorVersion:HEAP32[a+(36>>2)],enableExtensionsByDefault:HEAP32[a+(40>>2)],explicitSwapControl:HEAP32[a+(44>>2)],proxyContextToMainThread:HEAP32[a+(48>>2)],renderViaOffscreenBackBuffer:HEAP32[a+(52>>2)]};var canvas=findCanvasEventTarget(target);if(!canvas){return 0}if(canvas.offscreenCanvas)canvas=canvas.offscreenCanvas;if(contextAttributes.explicitSwapControl){var supportsOffscreenCanvas=canvas.transferControlToOffscreen||typeof OffscreenCanvas!=="undefined"&&canvas instanceof OffscreenCanvas;if(!supportsOffscreenCanvas){if(!contextAttributes.renderViaOffscreenBackBuffer){contextAttributes.renderViaOffscreenBackBuffer=true}}if(canvas.transferControlToOffscreen){if(!canvas.controlTransferredOffscreen){GL.offscreenCanvases[canvas.id]={canvas:canvas.transferControlToOffscreen(),canvasSharedPtr:_malloc(12),id:canvas.id};canvas.controlTransferredOffscreen=true}else if(!GL.offscreenCanvases[canvas.id]){return 0}canvas=GL.offscreenCanvases[canvas.id]}}var contextHandle=GL.createContext(canvas,contextAttributes);return contextHandle}function _emscripten_webgl_create_context(a0,a1){return _emscripten_webgl_do_create_context(a0,a1)}function _emscripten_webgl_do_get_current_context(){return GL.currentContext?GL.currentContext.handle:0}function _emscripten_webgl_get_current_context(){return _emscripten_webgl_do_get_current_context()}Module["_emscripten_webgl_get_current_context"]=_emscripten_webgl_get_current_context;function _emscripten_webgl_make_context_current(contextHandle){var success=GL.makeContextCurrent(contextHandle);return success?0:-5}Module["_emscripten_webgl_make_context_current"]=_emscripten_webgl_make_context_current;function _emscripten_webgl_destroy_context(contextHandle){if(GL.currentContext==contextHandle)GL.currentContext=0;GL.deleteContext(contextHandle)}function _emscripten_webgl_get_context_attributes(c,a){if(!a)return-5;c=GL.contexts[c];if(!c)return-3;var t=c.GLctx;if(!t)return-3;t=t.getContextAttributes();HEAP32[a>>2]=t.alpha;HEAP32[a+4>>2]=t.depth;HEAP32[a+8>>2]=t.stencil;HEAP32[a+12>>2]=t.antialias;HEAP32[a+16>>2]=t.premultipliedAlpha;HEAP32[a+20>>2]=t.preserveDrawingBuffer;var power=t["powerPreference"]&&__emscripten_webgl_power_preferences.indexOf(t["powerPreference"]);HEAP32[a+24>>2]=power;HEAP32[a+28>>2]=t.failIfMajorPerformanceCaveat;HEAP32[a+32>>2]=c.version;HEAP32[a+36>>2]=0;HEAP32[a+40>>2]=c.attributes.enableExtensionsByDefault;return 0}function _emscripten_webgl_init_context_attributes(attributes){assert(attributes);var a=attributes>>2;for(var i=0;i<56>>2;++i){HEAP32[a+i]=0}HEAP32[a+(0>>2)]=HEAP32[a+(4>>2)]=HEAP32[a+(12>>2)]=HEAP32[a+(16>>2)]=HEAP32[a+(32>>2)]=HEAP32[a+(40>>2)]=1}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getTempRet0(){return getTempRet0()}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBindAttribLocation(program,index,name){GLctx.bindAttribLocation(GL.programs[program],index,UTF8ToString(name))}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferBase(target,index,buffer){GLctx["bindBufferBase"](target,index,GL.buffers[buffer])}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,framebuffer?GL.framebuffers[framebuffer]:GL.currentContext.defaultFbo)}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBufferData(target,size,data,usage){if(GL.currentContext.version>=2){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function convertI32PairToI53(lo,hi){assert(hi===(hi|0));return(lo>>>0)+hi*4294967296}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;program.maxUniformLength=program.maxAttributeLength=program.maxUniformBlockNameLength=0;program.uniformIdCounter=1;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}var tempFixedLengthArray=[];function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function readI53FromI64(ptr){return HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*4294967296}function readI53FromU64(ptr){return HEAPU32[ptr>>2]+HEAPU32[ptr+4>>2]*4294967296}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296;var deserialized=num>=0?readI53FromU64(ptr):readI53FromI64(ptr);if(deserialized!=num)warnOnce("writeI53ToI64() out of range: serialized JS Number "+num+" to Wasm heap as bytes lo=0x"+HEAPU32[ptr>>2].toString(16)+", hi=0x"+HEAPU32[ptr+4>>2].toString(16)+", which deserializes back to "+deserialized+" instead!")}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){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:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _glGetString(name_){var ret=GL.stringCache[name_];if(!ret){switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=s&&stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(GL.currentContext.version>=2)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280)}GL.stringCache[name_]=ret}return ret}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function jstoi_q(str){return parseInt(str)}function webglGetLeftBracePos(name){return name.slice(-1)=="]"&&name.lastIndexOf("[")}function webglPrepareUniformLocationsBeforeFirstUse(program){var uniformLocsById=program.uniformLocsById,uniformSizeAndIdsByName=program.uniformSizeAndIdsByName,i,j;if(!uniformLocsById){program.uniformLocsById=uniformLocsById={};program.uniformArrayNamesById={};for(i=0;i0?nm.slice(0,lb):nm;var id=program.uniformIdCounter;program.uniformIdCounter+=sz;uniformSizeAndIdsByName[arrayName]=[sz,id];for(j=0;j0){arrayIndex=jstoi_q(name.slice(leftBrace+1))>>>0;uniformBaseName=name.slice(0,leftBrace)}var sizeAndId=program.uniformSizeAndIdsByName[uniformBaseName];if(sizeAndId&&arrayIndex>shift,pixels+bytes>>shift)}function _glReadPixels(x,y,width,height,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function webglGetUniformLocation(location){var p=GLctx.currentProgram;if(p){var webglLoc=p.uniformLocsById[location];if(typeof webglLoc==="number"){p.uniformLocsById[location]=webglLoc=GLctx.getUniformLocation(p,p.uniformArrayNamesById[location]+(webglLoc>0?"["+webglLoc+"]":""))}return webglLoc}else{GL.recordError(1282)}}function _glUniform1f(location,v0){GLctx.uniform1f(webglGetUniformLocation(location),v0)}function _glUniform1i(location,v0){GLctx.uniform1i(webglGetUniformLocation(location),v0)}var miniTempWebGLFloatBuffers=[];function _glUniform2fv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform2fv(webglGetUniformLocation(location),HEAPF32,value>>2,count*2);return}if(count<=144){var view=miniTempWebGLFloatBuffers[2*count-1];for(var i=0;i<2*count;i+=2){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*8>>2)}GLctx.uniform2fv(webglGetUniformLocation(location),view)}function _glUniform4fv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform4fv(webglGetUniformLocation(location),HEAPF32,value>>2,count*4);return}if(count<=72){var view=miniTempWebGLFloatBuffers[4*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<4*count;i+=4){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3]}}else{var view=HEAPF32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4fv(webglGetUniformLocation(location),view)}var __miniTempWebGLIntBuffers=[];function _glUniform4iv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform4iv(webglGetUniformLocation(location),HEAP32,value>>2,count*4);return}if(count<=72){var view=__miniTempWebGLIntBuffers[4*count-1];for(var i=0;i<4*count;i+=4){view[i]=HEAP32[value+4*i>>2];view[i+1]=HEAP32[value+(4*i+4)>>2];view[i+2]=HEAP32[value+(4*i+8)>>2];view[i+3]=HEAP32[value+(4*i+12)>>2]}}else{var view=HEAP32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4iv(webglGetUniformLocation(location),view)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUniformMatrix4fv(location,count,transpose,value){if(GL.currentContext.version>=2){GLctx.uniformMatrix4fv(webglGetUniformLocation(location),!!transpose,HEAPF32,value>>2,count*16);return}if(count<=18){var view=miniTempWebGLFloatBuffers[16*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<16*count;i+=16){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3];view[i+4]=heap[dst+4];view[i+5]=heap[dst+5];view[i+6]=heap[dst+6];view[i+7]=heap[dst+7];view[i+8]=heap[dst+8];view[i+9]=heap[dst+9];view[i+10]=heap[dst+10];view[i+11]=heap[dst+11];view[i+12]=heap[dst+12];view[i+13]=heap[dst+13];view[i+14]=heap[dst+14];view[i+15]=heap[dst+15]}}else{var view=HEAPF32.subarray(value>>2,value+count*64>>2)}GLctx.uniformMatrix4fv(webglGetUniformLocation(location),!!transpose,view)}function _glUseProgram(program){program=GL.programs[program];GLctx.useProgram(program);GLctx.currentProgram=program}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _gmtime_r(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();HEAP32[tmPtr+36>>2]=0;HEAP32[tmPtr+32>>2]=0;var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;if(!_gmtime_r.GMTString)_gmtime_r.GMTString=allocateUTF8("GMT");HEAP32[tmPtr+40>>2]=_gmtime_r.GMTString;return tmPtr}function _llvm_eh_typeid_for(type){return type}function _tzset(){if(_tzset.called)return;_tzset.called=true;var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAP32[__get_timezone()>>2]=stdTimezoneOffset*60;HEAP32[__get_daylight()>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAP32[__get_tzname()+4>>2]=summerNamePtr}else{HEAP32[__get_tzname()>>2]=summerNamePtr;HEAP32[__get_tzname()+4>>2]=winterNamePtr}}function _localtime_r(time,tmPtr){_tzset();var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst;var zonePtr=HEAP32[__get_tzname()+(dst?4:0)>>2];HEAP32[tmPtr+40>>2]=zonePtr;return tmPtr}function _mktime(tmPtr){_tzset();var date=new Date(HEAP32[tmPtr+20>>2]+1900,HEAP32[tmPtr+16>>2],HEAP32[tmPtr+12>>2],HEAP32[tmPtr+8>>2],HEAP32[tmPtr+4>>2],HEAP32[tmPtr>>2],0);var dst=HEAP32[tmPtr+32>>2];var guessedOffset=date.getTimezoneOffset();var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dstOffset=Math.min(winterOffset,summerOffset);if(dst<0){HEAP32[tmPtr+32>>2]=Number(summerOffset!=winterOffset&&dstOffset==guessedOffset)}else if(dst>0!=(dstOffset==guessedOffset)){var nonDstOffset=Math.max(winterOffset,summerOffset);var trueOffset=dst>0?dstOffset:nonDstOffset;date.setTime(date.getTime()+(trueOffset-guessedOffset)*6e4)}HEAP32[tmPtr+24>>2]=date.getDay();var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();return date.getTime()/1e3|0}function _proc_exit(code){procExit(code)}function _setTempRet0(val){setTempRet0(val)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}Module["requestFullscreen"]=function Module_requestFullscreen(lockPointer,resizeCanvas){Browser.requestFullscreen(lockPointer,resizeCanvas)};Module["requestFullScreen"]=function Module_requestFullScreen(){Browser.requestFullScreen()};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};Module["createContext"]=function Module_createContext(canvas,useWebGL,setInModule,webGLContextAttributes){return Browser.createContext(canvas,useWebGL,setInModule,webGLContextAttributes)};var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;init_emval();PureVirtualError=Module["PureVirtualError"]=extendError(Error,"PureVirtualError");embind_init_charCodes();init_embind();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));var miniTempWebGLFloatBuffersStorage=new Float32Array(288);for(var i=0;i<288;++i){miniTempWebGLFloatBuffers[i]=miniTempWebGLFloatBuffersStorage.subarray(0,i+1)}var __miniTempWebGLIntBuffersStorage=new Int32Array(288);for(var i=0;i<288;++i){__miniTempWebGLIntBuffers[i]=__miniTempWebGLIntBuffersStorage.subarray(0,i+1)}var ASSERTIONS=true;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var decodeBase64=typeof atob==="function"?atob:function(input){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}while(i0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}checkStackCookie()}Module["run"]=run;function checkUnflushedContent(){var oldOut=out;var oldErr=err;var has=false;out=err=function(x){has=true};try{var flush=Module["_fflush"];if(flush)flush(0);["stdout","stderr"].forEach(function(name){var info=FS.analyzePath("/dev/"+name);if(!info)return;var stream=info.object;var rdev=stream.rdev;var tty=TTY.ttys[rdev];if(tty&&tty.output&&tty.output.length){has=true}})}catch(e){}out=oldOut;err=oldErr;if(has){warnOnce("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.")}}function exit(status,implicit){EXITSTATUS=status;checkUnflushedContent();if(keepRuntimeAlive()){if(!implicit){var msg="program exited (with status: "+status+"), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)";readyPromiseReject(msg);err(msg)}}else{exitRuntime()}procExit(status)}function procExit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); + + + return createMediapipeSolutionsWasm.ready +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = createMediapipeSolutionsWasm; +else if (typeof define === 'function' && define['amd']) + define([], function() { return createMediapipeSolutionsWasm; }); +else if (typeof exports === 'object') + exports["createMediapipeSolutionsWasm"] = createMediapipeSolutionsWasm; diff --git a/src/assets/mediapipe/face_mesh_solution_simd_wasm_bin.wasm b/src/assets/mediapipe/face_mesh_solution_simd_wasm_bin.wasm new file mode 100644 index 0000000..41f7701 Binary files /dev/null and b/src/assets/mediapipe/face_mesh_solution_simd_wasm_bin.wasm differ diff --git a/src/assets/mediapipe/face_mesh_solution_wasm_bin.js b/src/assets/mediapipe/face_mesh_solution_wasm_bin.js new file mode 100644 index 0000000..e1ec8ba --- /dev/null +++ b/src/assets/mediapipe/face_mesh_solution_wasm_bin.js @@ -0,0 +1,21 @@ + +var createMediapipeSolutionsWasm = (function() { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(createMediapipeSolutionsWasm) { + createMediapipeSolutionsWasm = createMediapipeSolutionsWasm || {}; + +var Module=typeof createMediapipeSolutionsWasm!=="undefined"?createMediapipeSolutionsWasm:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});if(!Object.getOwnPropertyDescriptor(Module["ready"],"_main")){Object.defineProperty(Module["ready"],"_main",{configurable:true,get:function(){abort("You are getting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_main",{configurable:true,set:function(){abort("You are setting _main on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_stack_get_end")){Object.defineProperty(Module["ready"],"_emscripten_stack_get_end",{configurable:true,get:function(){abort("You are getting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_stack_get_end",{configurable:true,set:function(){abort("You are setting _emscripten_stack_get_end on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_stack_get_free")){Object.defineProperty(Module["ready"],"_emscripten_stack_get_free",{configurable:true,get:function(){abort("You are getting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_stack_get_free",{configurable:true,set:function(){abort("You are setting _emscripten_stack_get_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_stack_init")){Object.defineProperty(Module["ready"],"_emscripten_stack_init",{configurable:true,get:function(){abort("You are getting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_stack_init",{configurable:true,set:function(){abort("You are setting _emscripten_stack_init on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_stackSave")){Object.defineProperty(Module["ready"],"_stackSave",{configurable:true,get:function(){abort("You are getting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_stackSave",{configurable:true,set:function(){abort("You are setting _stackSave on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_stackRestore")){Object.defineProperty(Module["ready"],"_stackRestore",{configurable:true,get:function(){abort("You are getting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_stackRestore",{configurable:true,set:function(){abort("You are setting _stackRestore on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_stackAlloc")){Object.defineProperty(Module["ready"],"_stackAlloc",{configurable:true,get:function(){abort("You are getting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_stackAlloc",{configurable:true,set:function(){abort("You are setting _stackAlloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___wasm_call_ctors")){Object.defineProperty(Module["ready"],"___wasm_call_ctors",{configurable:true,get:function(){abort("You are getting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___wasm_call_ctors",{configurable:true,set:function(){abort("You are setting ___wasm_call_ctors on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_fflush")){Object.defineProperty(Module["ready"],"_fflush",{configurable:true,get:function(){abort("You are getting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_fflush",{configurable:true,set:function(){abort("You are setting _fflush on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___errno_location")){Object.defineProperty(Module["ready"],"___errno_location",{configurable:true,get:function(){abort("You are getting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___errno_location",{configurable:true,set:function(){abort("You are setting ___errno_location on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_malloc")){Object.defineProperty(Module["ready"],"_malloc",{configurable:true,get:function(){abort("You are getting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_malloc",{configurable:true,set:function(){abort("You are setting _malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_free")){Object.defineProperty(Module["ready"],"_free",{configurable:true,get:function(){abort("You are getting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_free",{configurable:true,set:function(){abort("You are setting _free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_setThrew")){Object.defineProperty(Module["ready"],"_setThrew",{configurable:true,get:function(){abort("You are getting _setThrew on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_setThrew",{configurable:true,set:function(){abort("You are setting _setThrew on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___cxa_is_pointer_type")){Object.defineProperty(Module["ready"],"___cxa_is_pointer_type",{configurable:true,get:function(){abort("You are getting ___cxa_is_pointer_type on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___cxa_is_pointer_type",{configurable:true,set:function(){abort("You are setting ___cxa_is_pointer_type on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___cxa_can_catch")){Object.defineProperty(Module["ready"],"___cxa_can_catch",{configurable:true,get:function(){abort("You are getting ___cxa_can_catch on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___cxa_can_catch",{configurable:true,set:function(){abort("You are setting ___cxa_can_catch on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_saveSetjmp")){Object.defineProperty(Module["ready"],"_saveSetjmp",{configurable:true,get:function(){abort("You are getting _saveSetjmp on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_saveSetjmp",{configurable:true,set:function(){abort("You are setting _saveSetjmp on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_memalign")){Object.defineProperty(Module["ready"],"_memalign",{configurable:true,get:function(){abort("You are getting _memalign on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_memalign",{configurable:true,set:function(){abort("You are setting _memalign on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_main_thread_process_queued_calls")){Object.defineProperty(Module["ready"],"_emscripten_main_thread_process_queued_calls",{configurable:true,get:function(){abort("You are getting _emscripten_main_thread_process_queued_calls on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_main_thread_process_queued_calls",{configurable:true,set:function(){abort("You are setting _emscripten_main_thread_process_queued_calls on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_webgl_make_context_current")){Object.defineProperty(Module["ready"],"_emscripten_webgl_make_context_current",{configurable:true,get:function(){abort("You are getting _emscripten_webgl_make_context_current on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_webgl_make_context_current",{configurable:true,set:function(){abort("You are setting _emscripten_webgl_make_context_current on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_webgl_get_current_context")){Object.defineProperty(Module["ready"],"_emscripten_webgl_get_current_context",{configurable:true,get:function(){abort("You are getting _emscripten_webgl_get_current_context on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_webgl_get_current_context",{configurable:true,set:function(){abort("You are setting _emscripten_webgl_get_current_context on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"__get_tzname")){Object.defineProperty(Module["ready"],"__get_tzname",{configurable:true,get:function(){abort("You are getting __get_tzname on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"__get_tzname",{configurable:true,set:function(){abort("You are setting __get_tzname on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"__get_daylight")){Object.defineProperty(Module["ready"],"__get_daylight",{configurable:true,get:function(){abort("You are getting __get_daylight on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"__get_daylight",{configurable:true,set:function(){abort("You are setting __get_daylight on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"__get_timezone")){Object.defineProperty(Module["ready"],"__get_timezone",{configurable:true,get:function(){abort("You are getting __get_timezone on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"__get_timezone",{configurable:true,set:function(){abort("You are setting __get_timezone on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_builtin_malloc")){Object.defineProperty(Module["ready"],"_emscripten_builtin_malloc",{configurable:true,get:function(){abort("You are getting _emscripten_builtin_malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_builtin_malloc",{configurable:true,set:function(){abort("You are setting _emscripten_builtin_malloc on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_builtin_free")){Object.defineProperty(Module["ready"],"_emscripten_builtin_free",{configurable:true,get:function(){abort("You are getting _emscripten_builtin_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_builtin_free",{configurable:true,set:function(){abort("You are setting _emscripten_builtin_free on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"_emscripten_builtin_memalign")){Object.defineProperty(Module["ready"],"_emscripten_builtin_memalign",{configurable:true,get:function(){abort("You are getting _emscripten_builtin_memalign on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"_emscripten_builtin_memalign",{configurable:true,set:function(){abort("You are setting _emscripten_builtin_memalign on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___getTypeName")){Object.defineProperty(Module["ready"],"___getTypeName",{configurable:true,get:function(){abort("You are getting ___getTypeName on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___getTypeName",{configurable:true,set:function(){abort("You are setting ___getTypeName on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"___embind_register_native_and_builtin_types")){Object.defineProperty(Module["ready"],"___embind_register_native_and_builtin_types",{configurable:true,get:function(){abort("You are getting ___embind_register_native_and_builtin_types on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"___embind_register_native_and_builtin_types",{configurable:true,set:function(){abort("You are setting ___embind_register_native_and_builtin_types on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}if(!Object.getOwnPropertyDescriptor(Module["ready"],"onRuntimeInitialized")){Object.defineProperty(Module["ready"],"onRuntimeInitialized",{configurable:true,get:function(){abort("You are getting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}});Object.defineProperty(Module["ready"],"onRuntimeInitialized",{configurable:true,set:function(){abort("You are setting onRuntimeInitialized on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js")}})}var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(Module["ENVIRONMENT"]){throw new Error("Module.ENVIRONMENT has been deprecated. To force the environment, use the ENVIRONMENT compile-time option (for example, -s ENVIRONMENT=web or -s ENVIRONMENT=node)")}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(!(typeof process==="object"&&typeof require==="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};readAsync=function readAsync(filename,onload,onerror){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);nodeFS["readFile"](filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status,toThrow){if(keepRuntimeAlive()){process["exitCode"]=status;throw toThrow}process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof process==="object"&&typeof require==="function"||typeof window==="object"||typeof importScripts==="function")throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};readAsync=function readAsync(f,onload,onerror){setTimeout(function(){onload(readBinary(f))},0)};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}if(!(typeof window==="object"||typeof importScripts==="function"))throw new Error("not compiled for this environment (did you build to HTML and try to run it not on the web, or set ENVIRONMENT to something - like node - and run it someplace else - like on the web?)");{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{throw new Error("environment detection error")}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(!Object.getOwnPropertyDescriptor(Module,"arguments")){Object.defineProperty(Module,"arguments",{configurable:true,get:function(){abort("Module.arguments has been replaced with plain arguments_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(!Object.getOwnPropertyDescriptor(Module,"thisProgram")){Object.defineProperty(Module,"thisProgram",{configurable:true,get:function(){abort("Module.thisProgram has been replaced with plain thisProgram (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(Module["quit"])quit_=Module["quit"];if(!Object.getOwnPropertyDescriptor(Module,"quit")){Object.defineProperty(Module,"quit",{configurable:true,get:function(){abort("Module.quit has been replaced with plain quit_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(typeof Module["memoryInitializerPrefixURL"]==="undefined","Module.memoryInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["pthreadMainPrefixURL"]==="undefined","Module.pthreadMainPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["cdInitializerPrefixURL"]==="undefined","Module.cdInitializerPrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["filePackagePrefixURL"]==="undefined","Module.filePackagePrefixURL option was removed, use Module.locateFile instead");assert(typeof Module["read"]==="undefined","Module.read option was removed (modify read_ in JS)");assert(typeof Module["readAsync"]==="undefined","Module.readAsync option was removed (modify readAsync in JS)");assert(typeof Module["readBinary"]==="undefined","Module.readBinary option was removed (modify readBinary in JS)");assert(typeof Module["setWindowTitle"]==="undefined","Module.setWindowTitle option was removed (modify setWindowTitle in JS)");assert(typeof Module["TOTAL_MEMORY"]==="undefined","Module.TOTAL_MEMORY has been renamed Module.INITIAL_MEMORY");if(!Object.getOwnPropertyDescriptor(Module,"read")){Object.defineProperty(Module,"read",{configurable:true,get:function(){abort("Module.read has been replaced with plain read_ (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"readAsync")){Object.defineProperty(Module,"readAsync",{configurable:true,get:function(){abort("Module.readAsync has been replaced with plain readAsync (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"readBinary")){Object.defineProperty(Module,"readBinary",{configurable:true,get:function(){abort("Module.readBinary has been replaced with plain readBinary (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}if(!Object.getOwnPropertyDescriptor(Module,"setWindowTitle")){Object.defineProperty(Module,"setWindowTitle",{configurable:true,get:function(){abort("Module.setWindowTitle has been replaced with plain setWindowTitle (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(!ENVIRONMENT_IS_SHELL,"shell environment detected but not enabled at build time. Add 'shell' to `-s ENVIRONMENT` to enable.");function warnOnce(text){if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;err(text)}}function convertJsFunctionToWasm(func,sig){if(typeof WebAssembly.Function==="function"){var typeNames={"i":"i32","j":"i64","f":"f32","d":"f64"};var type={parameters:[],results:sig[0]=="v"?[]:[typeNames[sig[0]]]};for(var i=1;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;if(u>=2097152)warnOnce("Invalid Unicode code point 0x"+u.toString(16)+" encountered when serializing a JS string to a UTF-8 string in wasm memory! (Valid unicode code points should be in range 0-0x1FFFFF).");heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){assert(typeof maxBytesToWrite=="number","stringToUTF8(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function UTF16ToString(ptr,maxBytesToRead){assert(ptr%2==0,"Pointer passed to UTF16ToString must be aligned to two bytes!");var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&HEAPU16[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder){return UTF16Decoder.decode(HEAPU8.subarray(ptr,endPtr))}else{var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=HEAP16[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str}}function stringToUTF16(str,outPtr,maxBytesToWrite){assert(outPtr%2==0,"Pointer passed to stringToUTF16 must be aligned to two bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF16(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr}function lengthBytesUTF16(str){return str.length*2}function UTF32ToString(ptr,maxBytesToRead){assert(ptr%4==0,"Pointer passed to UTF32ToString must be aligned to four bytes!");var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=HEAP32[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str}function stringToUTF32(str,outPtr,maxBytesToWrite){assert(outPtr%4==0,"Pointer passed to stringToUTF32 must be aligned to four bytes!");assert(typeof maxBytesToWrite=="number","stringToUTF32(str, outPtr, maxBytesToWrite) is missing the third parameter that specifies the length of the output buffer!");if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}HEAP32[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr}function lengthBytesUTF32(str){var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len}function allocateUTF8(str){var size=lengthBytesUTF8(str)+1;var ret=_malloc(size);if(ret)stringToUTF8Array(str,HEAP8,ret,size);return ret}function writeArrayToMemory(array,buffer){assert(array.length>=0,"writeArrayToMemory array must have a length (should be an array or typed array)");HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var TOTAL_STACK=5242880;if(Module["TOTAL_STACK"])assert(TOTAL_STACK===Module["TOTAL_STACK"],"the stack size can no longer be determined at runtime");var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(!Object.getOwnPropertyDescriptor(Module,"INITIAL_MEMORY")){Object.defineProperty(Module,"INITIAL_MEMORY",{configurable:true,get:function(){abort("Module.INITIAL_MEMORY has been replaced with plain INITIAL_MEMORY (the initial value can be provided on Module, but after startup the value is only looked for on a local variable of that name)")}})}assert(INITIAL_MEMORY>=TOTAL_STACK,"INITIAL_MEMORY should be larger than TOTAL_STACK, was "+INITIAL_MEMORY+"! (TOTAL_STACK="+TOTAL_STACK+")");assert(typeof Int32Array!=="undefined"&&typeof Float64Array!=="undefined"&&Int32Array.prototype.subarray!==undefined&&Int32Array.prototype.set!==undefined,"JS engine does not provide full typed array support");assert(!Module["wasmMemory"],"Use of `wasmMemory` detected. Use -s IMPORTED_MEMORY to define wasmMemory externally");assert(INITIAL_MEMORY==16777216,"Detected runtime INITIAL_MEMORY setting. Use -s IMPORTED_MEMORY to define wasmMemory dynamically");var wasmTable;function writeStackCookie(){var max=_emscripten_stack_get_end();assert((max&3)==0);HEAPU32[(max>>2)+1]=34821223;HEAPU32[(max>>2)+2]=2310721022;HEAP32[0]=1668509029}function checkStackCookie(){if(ABORT)return;var max=_emscripten_stack_get_end();var cookie1=HEAPU32[(max>>2)+1];var cookie2=HEAPU32[(max>>2)+2];if(cookie1!=34821223||cookie2!=2310721022){abort("Stack overflow! Stack cookie has been overwritten, expected hex dwords 0x89BACDFE and 0x2135467, but received 0x"+cookie2.toString(16)+" "+cookie1.toString(16))}if(HEAP32[0]!==1668509029)abort("Runtime error: The application has corrupted its heap memory area (address zero)!")}(function(){var h16=new Int16Array(1);var h8=new Int8Array(h16.buffer);h16[0]=25459;if(h8[0]!==115||h8[1]!==99)throw"Runtime error: expected the system to be little-endian! (Run with -s SUPPORT_BIG_ENDIAN=1 to bypass)"})();var __ATPRERUN__=[];var __ATINIT__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){checkStackCookie();assert(!runtimeInitialized);runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function exitRuntime(){checkStackCookie();runtimeExited=true}function postRun(){checkStackCookie();if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}assert(Math.imul,"This browser does not support Math.imul(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.fround,"This browser does not support Math.fround(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.clz32,"This browser does not support Math.clz32(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");assert(Math.trunc,"This browser does not support Math.trunc(), build with LEGACY_VM_SUPPORT or POLYFILL_OLD_MATH_FUNCTIONS to add in a polyfill");var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;var runDependencyTracking={};function getUniqueRunDependency(id){var orig=id;while(1){if(!runDependencyTracking[id])return id;id=orig+Math.random()}}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(!runDependencyTracking[id]);runDependencyTracking[id]=1;if(runDependencyWatcher===null&&typeof setInterval!=="undefined"){runDependencyWatcher=setInterval(function(){if(ABORT){clearInterval(runDependencyWatcher);runDependencyWatcher=null;return}var shown=false;for(var dep in runDependencyTracking){if(!shown){shown=true;err("still waiting on run dependencies:")}err("dependency: "+dep)}if(shown){err("(end of list)")}},1e4)}}else{err("warning: run dependency added without ID")}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(id){assert(runDependencyTracking[id]);delete runDependencyTracking[id]}else{err("warning: run dependency removed without ID")}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;var output="abort("+what+") at "+stackTrace();what=output;var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}function createExportWrapper(name,fixedasm){return function(){var displayName=name;var asm=fixedasm;if(!fixedasm){asm=Module["asm"]}assert(runtimeInitialized,"native function `"+displayName+"` called before runtime initialization");assert(!runtimeExited,"native function `"+displayName+"` called after runtime exit (use NO_EXIT_RUNTIME to keep it alive after main() exits)");if(!asm[name]){assert(asm[name],"exported native function `"+displayName+"` not found")}return asm[name].apply(null,arguments)}}var wasmBinaryFile;wasmBinaryFile="face_mesh_solution_wasm_bin.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["memory"];assert(wasmMemory,"memory not found in wasm exports");updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["__indirect_function_table"];assert(wasmTable,"table not found in wasm exports");addOnInit(Module["asm"]["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");var trueModule=Module;function receiveInstantiationResult(result){assert(Module===trueModule,"the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?");trueModule=null;receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){var result=WebAssembly.instantiate(binary,info);return result}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);if(isFileURI(wasmBinaryFile)){err("warning: Loading from a file URI ("+wasmBinaryFile+") is not supported in most browsers. See https://emscripten.org/docs/getting_started/FAQ.html#how-do-i-run-a-local-webserver-for-testing-why-does-my-program-stall-in-downloading-or-preparing")}abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var tempDouble;var tempI64;var ASM_CONSTS={548264:function(){let init_once=true;if(init_once){const cachedFindCanvasEventTarget=findCanvasEventTarget;if(typeof cachedFindCanvasEventTarget!=="function"){if(typeof console!=="undefined"){console.error("Expected Emscripten global function "+'"findCanvasEventTarget" not found. WebGL context creation '+"may fail.")}return}findCanvasEventTarget=function(target){if(target==0){if(Module&&Module.canvas){return Module.canvas}else if(Module&&Module.canvasCssSelector){return cachedFindCanvasEventTarget(Module.canvasCssSelector)}if(typeof console!=="undefined"){console.warn("Module properties canvas and canvasCssSelector not "+"found during WebGL context creation.")}}return cachedFindCanvasEventTarget(target)};init_once=false}},549049:function(){return typeof wasmOffsetConverter!=="undefined"}};function HaveOffsetConverter(){return typeof wasmOffsetConverter!=="undefined"}function _emscripten_set_main_loop_timing(mode,value){Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){err("emscripten_set_main_loop_timing: Cannot set timing mode for main loop since a main loop does not exist! Call emscripten_set_main_loop first to set one up.");return 1}if(!Browser.mainLoop.running){Browser.mainLoop.running=true}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setTimeout(){var timeUntilNextTick=Math.max(0,Browser.mainLoop.tickStartTime+value-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,timeUntilNextTick)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_rAF(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}else if(mode==2){if(typeof setImmediate==="undefined"){var setImmediates=[];var emscriptenMainLoopMessageId="setimmediate";var Browser_setImmediate_messageHandler=function(event){if(event.data===emscriptenMainLoopMessageId||event.data.target===emscriptenMainLoopMessageId){event.stopPropagation();setImmediates.shift()()}};addEventListener("message",Browser_setImmediate_messageHandler,true);setImmediate=function Browser_emulated_setImmediate(func){setImmediates.push(func);if(ENVIRONMENT_IS_WORKER){if(Module["setImmediates"]===undefined)Module["setImmediates"]=[];Module["setImmediates"].push(func);postMessage({target:emscriptenMainLoopMessageId})}else postMessage(emscriptenMainLoopMessageId,"*")}}Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setImmediate(){setImmediate(Browser.mainLoop.runner)};Browser.mainLoop.method="immediate"}return 0}var _emscripten_get_now;if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else _emscripten_get_now=function(){return performance.now()};function _emscripten_webgl_do_commit_frame(){if(!GL.currentContext||!GL.currentContext.GLctx){return-3}if(GL.currentContext.defaultFbo){GL.blitOffscreenFramebuffer(GL.currentContext);return 0}if(!GL.currentContext.attributes.explicitSwapControl){return-3}return 0}function _exit(status){exit(status)}function maybeExit(){if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){if(e instanceof ExitStatus){return}throw e}}}function setMainLoop(browserIterationFunc,fps,simulateInfiniteLoop,arg,noSetTiming){assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=browserIterationFunc;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;function checkIsRunning(){if(thisMainLoopId0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}out('main loop blocker "'+blocker.name+'" took '+(Date.now()-start)+" ms");Browser.mainLoop.updateStatus();if(!checkIsRunning())return;setTimeout(Browser.mainLoop.runner,0);return}if(!checkIsRunning())return;Browser.mainLoop.currentFrameNumber=Browser.mainLoop.currentFrameNumber+1|0;if(Browser.mainLoop.timingMode==1&&Browser.mainLoop.timingValue>1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else if(Browser.mainLoop.timingMode==0){Browser.mainLoop.tickStartTime=_emscripten_get_now()}GL.newRenderingFrameStarted();if(typeof GL!=="undefined"&&GL.currentContext&&!GL.currentContextIsProxied&&!GL.currentContext.attributes.explicitSwapControl&&GL.currentContext.GLctx.commit){GL.currentContext.GLctx.commit()}if(Browser.mainLoop.method==="timeout"&&Module.ctx){warnOnce("Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!");Browser.mainLoop.method=""}Browser.mainLoop.runIter(browserIterationFunc);checkStackCookie();if(!checkIsRunning())return;if(typeof SDL==="object"&&SDL.audio&&SDL.audio.queueNewAudioData)SDL.audio.queueNewAudioData();Browser.mainLoop.scheduler()};if(!noSetTiming){if(fps&&fps>0)_emscripten_set_main_loop_timing(0,1e3/fps);else _emscripten_set_main_loop_timing(1,1);Browser.mainLoop.scheduler()}if(simulateInfiniteLoop){throw"unwind"}}function callUserCallback(func,synchronous){if(ABORT){err("user callback triggered after application aborted. Ignoring.");return}if(synchronous){func();return}try{func()}catch(e){if(e instanceof ExitStatus){return}else if(e!=="unwind"){if(e&&typeof e==="object"&&e.stack)err("exception thrown: "+[e,e.stack]);throw e}}}function safeSetTimeout(func,timeout){return setTimeout(function(){callUserCallback(func)},timeout)}var Browser={mainLoop:{running:false,scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause:function(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++},resume:function(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;setMainLoop(func,0,false,Browser.mainLoop.arg,true);_emscripten_set_main_loop_timing(timingMode,timingValue);Browser.mainLoop.scheduler()},updateStatus:function(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;safeSetTimeout(function(){finish(audio)},1e4)}else{return fail()}};Module["preloadPlugins"].push(audioPlugin);function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===Module["canvas"]||document["mozPointerLockElement"]===Module["canvas"]||document["webkitPointerLockElement"]===Module["canvas"]||document["msPointerLockElement"]===Module["canvas"]}var canvas=Module["canvas"];if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||function(){};canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||function(){};canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",function(ev){if(!Browser.pointerLock&&Module["canvas"].requestPointerLock){Module["canvas"].requestPointerLock();ev.preventDefault()}},false)}}},createContext:function(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false,majorVersion:typeof WebGL2RenderingContext!=="undefined"?2:1};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}if(typeof GL!=="undefined"){contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}}}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx==="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach(function(callback){callback()});Browser.init()}return ctx},destroyContext:function(canvas,useWebGL,setInModule){},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen:function(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer==="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas==="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullscreenChange(){Browser.isFullscreen=false;var canvasContainer=canvas.parentNode;if((document["fullscreenElement"]||document["mozFullScreenElement"]||document["msFullscreenElement"]||document["webkitFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.exitFullscreen=Browser.exitFullscreen;if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullscreen=true;if(Browser.resizeCanvas){Browser.setFullscreenCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas){Browser.setWindowedCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}if(Module["onFullScreen"])Module["onFullScreen"](Browser.isFullscreen);if(Module["onFullscreen"])Module["onFullscreen"](Browser.isFullscreen)}if(!Browser.fullscreenHandlersInstalled){Browser.fullscreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullscreenChange,false);document.addEventListener("mozfullscreenchange",fullscreenChange,false);document.addEventListener("webkitfullscreenchange",fullscreenChange,false);document.addEventListener("MSFullscreenChange",fullscreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullscreen=canvasContainer["requestFullscreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullscreen"]?function(){canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null)||(canvasContainer["webkitRequestFullScreen"]?function(){canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"])}:null);canvasContainer.requestFullscreen()},requestFullScreen:function(){abort("Module.requestFullScreen has been replaced by Module.requestFullscreen (without a capital S)")},exitFullscreen:function(){if(!Browser.isFullscreen){return false}var CFS=document["exitFullscreen"]||document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["msExitFullscreen"]||document["webkitCancelFullScreen"]||function(){};CFS.apply(document,[]);return true},nextRAF:0,fakeRequestAnimationFrame:function(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)},requestAnimationFrame:function(func){if(typeof requestAnimationFrame==="function"){requestAnimationFrame(func);return}var RAF=Browser.fakeRequestAnimationFrame;RAF(func)},safeSetTimeout:function(func){return safeSetTimeout(func)},safeRequestAnimationFrame:function(func){return Browser.requestAnimationFrame(function(){callUserCallback(func)})},getMimetype:function(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]},getUserMedia:function(func){if(!window.getUserMedia){window.getUserMedia=navigator["getUserMedia"]||navigator["mozGetUserMedia"]}window.getUserMedia(func)},getMovementX:function(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0},getMovementY:function(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0},getMouseWheelDelta:function(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail/3;break;case"mousewheel":delta=event.wheelDelta/120;break;case"wheel":delta=event.deltaY;switch(event.deltaMode){case 0:delta/=100;break;case 1:delta/=3;break;case 2:delta*=80;break;default:throw"unrecognized mouse wheel delta mode: "+event.deltaMode}break;default:throw"unrecognized mouse wheel event: "+event.type}return delta},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseEvent:function(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!=="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!=="undefined"?window.scrollY:window.pageYOffset;assert(typeof scrollX!=="undefined"&&typeof scrollY!=="undefined","Unable to retrieve scroll position, mouse positions likely broken.");if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var adjustedX=touch.pageX-(scrollX+rect.left);var adjustedY=touch.pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);var coords={x:adjustedX,y:adjustedY};if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){var last=Browser.touches[touch.identifier];if(!last)last=coords;Browser.lastTouches[touch.identifier]=last;Browser.touches[touch.identifier]=coords}return}var x=event.pageX-(scrollX+rect.left);var y=event.pageY-(scrollY+rect.top);x=x*(cw/rect.width);y=y*(ch/rect.height);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y}},resizeListeners:[],updateResizeListeners:function(){var canvas=Module["canvas"];Browser.resizeListeners.forEach(function(listener){listener(canvas.width,canvas.height)})},setCanvasSize:function(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags|8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},setWindowedCanvasSize:function(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>2];flags=flags&~8388608;HEAP32[SDL.screen>>2]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},updateCanvasDimensions:function(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function demangle(func){warnOnce("warning: build with -s DEMANGLE_SUPPORT=1 to link in libcxxabi demangling");return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var error=new Error;if(!error.stack){try{throw new Error}catch(e){error=e}if(!error.stack){return"(no stack trace available)"}}return error.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function ___cxa_allocate_exception(size){return _malloc(size+16)+16}function _atexit(func,arg){}function ___cxa_atexit(a0,a1){return _atexit(a0,a1)}function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-16;this.set_type=function(type){HEAP32[this.ptr+4>>2]=type};this.get_type=function(){return HEAP32[this.ptr+4>>2]};this.set_destructor=function(destructor){HEAP32[this.ptr+8>>2]=destructor};this.get_destructor=function(){return HEAP32[this.ptr+8>>2]};this.set_refcount=function(refcount){HEAP32[this.ptr>>2]=refcount};this.set_caught=function(caught){caught=caught?1:0;HEAP8[this.ptr+12>>0]=caught};this.get_caught=function(){return HEAP8[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return HEAP8[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_type(type);this.set_destructor(destructor);this.set_refcount(0);this.set_caught(false);this.set_rethrown(false)};this.add_ref=function(){var value=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=value+1};this.release_ref=function(){var prev=HEAP32[this.ptr>>2];HEAP32[this.ptr>>2]=prev-1;assert(prev>0);return prev===1}}function CatchInfo(ptr){this.free=function(){_free(this.ptr);this.ptr=0};this.set_base_ptr=function(basePtr){HEAP32[this.ptr>>2]=basePtr};this.get_base_ptr=function(){return HEAP32[this.ptr>>2]};this.set_adjusted_ptr=function(adjustedPtr){HEAP32[this.ptr+4>>2]=adjustedPtr};this.get_adjusted_ptr_addr=function(){return this.ptr+4};this.get_adjusted_ptr=function(){return HEAP32[this.ptr+4>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_exception_info().get_type());if(isPointer){return HEAP32[this.get_base_ptr()>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.get_base_ptr()};this.get_exception_info=function(){return new ExceptionInfo(this.get_base_ptr())};if(ptr===undefined){this.ptr=_malloc(8);this.set_adjusted_ptr(0)}else{this.ptr=ptr}}var exceptionCaught=[];function exception_addRef(info){info.add_ref()}var uncaughtExceptionCount=0;function ___cxa_begin_catch(ptr){var catchInfo=new CatchInfo(ptr);var info=catchInfo.get_exception_info();if(!info.get_caught()){info.set_caught(true);uncaughtExceptionCount--}info.set_rethrown(false);exceptionCaught.push(catchInfo);exception_addRef(info);return catchInfo.get_exception_ptr()}var exceptionLast=0;function ___cxa_free_exception(ptr){try{return _free(new ExceptionInfo(ptr).ptr)}catch(e){err("exception during cxa_free_exception: "+e)}}function exception_decRef(info){if(info.release_ref()&&!info.get_rethrown()){var destructor=info.get_destructor();if(destructor){wasmTable.get(destructor)(info.excPtr)}___cxa_free_exception(info.excPtr)}}function ___cxa_end_catch(){_setThrew(0);assert(exceptionCaught.length>0);var catchInfo=exceptionCaught.pop();exception_decRef(catchInfo.get_exception_info());catchInfo.free();exceptionLast=0}function ___resumeException(catchInfoPtr){var catchInfo=new CatchInfo(catchInfoPtr);var ptr=catchInfo.get_base_ptr();if(!exceptionLast){exceptionLast=ptr}catchInfo.free();throw ptr+" - Exception catching is disabled, this exception cannot be caught. Compile with -s NO_DISABLE_EXCEPTION_CATCHING or -s EXCEPTION_CATCHING_ALLOWED=[..] to catch."}function ___cxa_find_matching_catch_2(){var thrown=exceptionLast;if(!thrown){setTempRet0(0);return 0|0}var info=new ExceptionInfo(thrown);var thrownType=info.get_type();var catchInfo=new CatchInfo;catchInfo.set_base_ptr(thrown);catchInfo.set_adjusted_ptr(thrown);if(!thrownType){setTempRet0(0);return catchInfo.ptr|0}var typeArray=Array.prototype.slice.call(arguments);for(var i=0;i>2]=value;return value}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function getRandomDevice(){if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);return function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");return function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}return function(){abort("no cryptographic support found for randomDevice. consider polyfilling it if you want to use something insecure like Math.random(), e.g. put this in a --pre-js: var crypto = { getRandomValues: function(array) { for (var i = 0; i < array.length; i++) array[i] = (Math.random()*256)|0 } };")}}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};function zeroMemory(address,size){HEAPU8.fill(0,address,address+size)}function alignMemory(size,alignment){assert(alignment,"alignment argument is required");return Math.ceil(size/alignment)*alignment}function mmapAlloc(size){size=alignMemory(size,65536);var ptr=_memalign(65536,size);if(!ptr)return 0;zeroMemory(ptr,size);return ptr}var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);assert(size>=0);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){assert(typeof parent==="object");var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"r+":2,"w":577,"w+":578,"a":1089,"a+":1090},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){assert(FS.syncFSRequests>0);FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){if(typeof type==="string"){throw type}var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);assert(idx!==-1);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){FS.forceLoadFile(node);var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);assert(size>=0);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){assert(SYSCALLS.varargs!=undefined);SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){if(low>=0)assert(high===0);else assert(high===-1);return low}};function ___sys_fcntl64(fd,cmd,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_ioctl(fd,op,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function syscallMmap2(addr,len,prot,flags,fd,off){off<<=12;var ptr;var allocated=false;if((flags&16)!==0&&addr%65536!==0){return-28}if((flags&32)!==0){ptr=mmapAlloc(len);if(!ptr)return-48;allocated=true}else{var info=FS.getStream(fd);if(!info)return-8;var res=FS.mmap(info,addr,len,off,prot,flags);ptr=res.ptr;allocated=res.allocated}SYSCALLS.mappings[ptr]={malloc:ptr,len:len,allocated:allocated,fd:fd,prot:prot,flags:flags,offset:off};return ptr}function ___sys_mmap2(addr,len,prot,flags,fd,off){try{return syscallMmap2(addr,len,prot,flags,fd,off)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_open(path,flags,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(path);var mode=varargs?SYSCALLS.get():0;var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___sys_stat64(path,buf){try{path=SYSCALLS.getStr(path);return SYSCALLS.doStat(FS.stat,path,buf)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}var char_0=48;var char_9=57;function makeLegalFunctionName(name){if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return"_"+name}else{return name}}function createNamedFunction(name,body){name=makeLegalFunctionName(name);return new Function("body","return function "+name+"() {\n"+' "use strict";'+" return body.apply(this, arguments);\n"+"};\n")(body)}var emval_free_list=[];var emval_handle_array=[{},{value:undefined},{value:null},{value:true},{value:false}];function count_emval_handles(){var count=0;for(var i=5;i>2])}var awaitingDependencies={};var typeDependencies={};var InternalError=undefined;function throwInternalError(message){throw new InternalError(message)}function whenDependentTypesAreResolved(myTypes,dependentTypes,getTypeConverters){myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i>shift])},destructorFunction:null})}function ClassHandle_isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right}function shallowCopyInternalPointer(o){return{count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType}}function throwInstanceAlreadyDeleted(obj){function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+" instance already deleted")}function ClassHandle_clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}}function ClassHandle_delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}}function ClassHandle_isDeleted(){return!this.$$.ptr}function ClassHandle_deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError("Object already scheduled for deletion")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}function init_ClassHandle(){ClassHandle.prototype["isAliasOf"]=ClassHandle_isAliasOf;ClassHandle.prototype["clone"]=ClassHandle_clone;ClassHandle.prototype["delete"]=ClassHandle_delete;ClassHandle.prototype["isDeleted"]=ClassHandle_isDeleted;ClassHandle.prototype["deleteLater"]=ClassHandle_deleteLater}function ClassHandle(){}var registeredPointers={};function ensureOverloadTable(proto,methodName,humanName){if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError("Function '"+humanName+"' called with an invalid number of arguments ("+arguments.length+") - expects one of ("+proto[methodName].overloadTable+")!")}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}}function exposePublicSymbol(name,value,numArguments){if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError("Cannot register public name '"+name+"' twice")}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError("Cannot register multiple overloads of a function with the same number of arguments ("+numArguments+")!")}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}}function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}function upcastPointer(ptr,ptrClass,desiredClass){while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError("Expected null or instance of "+desiredClass.name+", got an instance of "+ptrClass.name)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr}function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError("Passing raw pointer to smart pointer is illegal")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError("Cannot convert argument of type "+(handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name)+" to parameter type "+this.name)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle["clone"]();ptr=this.rawShare(ptr,__emval_register(function(){clonedHandle["delete"]()}));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError("Unsupporting sharing policy")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError("null is not a valid "+this.name)}return 0}if(!handle.$$){throwBindingError('Cannot pass "'+_embind_repr(handle)+'" as a '+this.name)}if(!handle.$$.ptr){throwBindingError("Cannot pass deleted object as a pointer of type "+this.name)}if(handle.$$.ptrType.isConst){throwBindingError("Cannot convert argument of type "+handle.$$.ptrType.name+" to parameter type "+this.name)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function RegisteredPointer_getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr}function RegisteredPointer_destructor(ptr){if(this.rawDestructor){this.rawDestructor(ptr)}}function RegisteredPointer_deleteObject(handle){if(handle!==null){handle["delete"]()}}function downcastPointer(ptr,ptrClass,desiredClass){if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)}function getInheritedInstance(class_,ptr){ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]}function makeClassHandle(prototype,record){if(!record.ptrType||!record.ptr){throwInternalError("makeClassHandle requires ptr and ptrType")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError("Both smartPtrType and smartPtr must be specified")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record}}))}function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance["clone"]()}else{var rv=registeredInstance["clone"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr:ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}function init_RegisteredPointer(){RegisteredPointer.prototype.getPointee=RegisteredPointer_getPointee;RegisteredPointer.prototype.destructor=RegisteredPointer_destructor;RegisteredPointer.prototype["argPackAdvance"]=8;RegisteredPointer.prototype["readValueFromPointer"]=simpleReadValueFromPointer;RegisteredPointer.prototype["deleteObject"]=RegisteredPointer_deleteObject;RegisteredPointer.prototype["fromWireType"]=RegisteredPointer_fromWireType}function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&®isteredClass.baseClass===undefined){if(isConst){this["toWireType"]=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this["toWireType"]=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this["toWireType"]=genericPointerToWireType}}function replacePublicSymbol(name,value,numArguments){if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}}function dynCallLegacy(sig,ptr,args){assert("dynCall_"+sig in Module,"bad function pointer type - no table for sig '"+sig+"'");if(args&&args.length){assert(args.length===sig.substring(1).replace(/j/g,"--").length)}else{assert(sig.length==1)}var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)}function dynCall(sig,ptr,args){if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}assert(wasmTable.get(ptr),"missing table entry in dynCall: "+ptr);return wasmTable.get(ptr).apply(null,args)}function getDynCaller(sig,ptr){assert(sig.includes("j"),"getDynCaller should only be called with i64 sigs");var argCache=[];return function(){argCache.length=arguments.length;for(var i=0;i0?", ":"")+argsListWired}invokerFnBody+=(returns?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i>2)+i])}return array}function __embind_register_class_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,fn){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}var proto=classType.registeredClass.constructor;if(undefined===proto[methodName]){unboundTypesHandler.argCount=argCount-1;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-1]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));var func=craftInvokerFunction(humanName,invokerArgsArray,null,rawInvoker,fn);if(undefined===proto[methodName].overloadTable){func.argCount=argCount-1;proto[methodName]=func}else{proto[methodName].overloadTable[argCount-1]=func}return[]});return[]})}function __embind_register_class_constructor(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor){assert(argCount>0);var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName="constructor "+classType.name;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError("Cannot register multiple constructors with identical number of parameters ("+(argCount-1)+") for class '"+classType.name+"'! Overload resolution is currently only performed using the parameter count, not actual type info!")}classType.registeredClass.constructor_body[argCount-1]=function unboundTypeHandler(){throwUnboundTypeError("Cannot construct "+classType.name+" due to unbound types",rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})}function __embind_register_class_function(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual){var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=readLatin1String(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker);whenDependentTypesAreResolved([],[rawClassType],function(classType){classType=classType[0];var humanName=classType.name+"."+methodName;if(methodName.startsWith("@@")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError("Cannot call "+humanName+" due to unbound types",rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,function(argTypes){var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})}function validateThis(this_,classType,humanName){if(!(this_ instanceof Object)){throwBindingError(humanName+' with invalid "this": '+this_)}if(!(this_ instanceof classType.registeredClass.constructor)){throwBindingError(humanName+' incompatible with "this" of type '+this_.constructor.name)}if(!this_.$$.ptr){throwBindingError("cannot call emscripten binding method "+humanName+" on deleted object")}return upcastPointer(this_.$$.ptr,this_.$$.ptrType.registeredClass,classType.registeredClass)}function __embind_register_class_property(classType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){fieldName=readLatin1String(fieldName);getter=embind__requireFunction(getterSignature,getter);whenDependentTypesAreResolved([],[classType],function(classType){classType=classType[0];var humanName=classType.name+"."+fieldName;var desc={get:function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])},enumerable:true,configurable:true};if(setter){desc.set=function(){throwUnboundTypeError("Cannot access "+humanName+" due to unbound types",[getterReturnType,setterArgumentType])}}else{desc.set=function(v){throwBindingError(humanName+" is a read-only property")}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);whenDependentTypesAreResolved([],setter?[getterReturnType,setterArgumentType]:[getterReturnType],function(types){var getterReturnType=types[0];var desc={get:function(){var ptr=validateThis(this,classType,humanName+" getter");return getterReturnType["fromWireType"](getter(getterContext,ptr))},enumerable:true};if(setter){setter=embind__requireFunction(setterSignature,setter);var setterArgumentType=types[1];desc.set=function(v){var ptr=validateThis(this,classType,humanName+" setter");var destructors=[];setter(setterContext,ptr,setterArgumentType["toWireType"](destructors,v));runDestructors(destructors)}}Object.defineProperty(classType.registeredClass.instancePrototype,fieldName,desc);return[]});return[]})}function __emval_decref(handle){if(handle>4&&0===--emval_handle_array[handle].refcount){emval_handle_array[handle]=undefined;emval_free_list.push(handle)}}function __embind_register_emval(rawType,name){name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(handle){var rv=emval_handle_array[handle].value;__emval_decref(handle);return rv},"toWireType":function(destructors,value){return __emval_register(value)},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})}function _embind_repr(v){if(v===null){return"null"}var t=typeof v;if(t==="object"||t==="array"||t==="function"){return v.toString()}else{return""+v}}function floatReadValueFromPointer(name,shift){switch(shift){case 2:return function(pointer){return this["fromWireType"](HEAPF32[pointer>>2])};case 3:return function(pointer){return this["fromWireType"](HEAPF64[pointer>>3])};default:throw new TypeError("Unknown float type: "+name)}}function __embind_register_float(rawType,name,size){var shift=getShiftFromSize(size);name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(value){return value},"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}return value},"argPackAdvance":8,"readValueFromPointer":floatReadValueFromPointer(name,shift),destructorFunction:null})}function __embind_register_function(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn){var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError("Cannot call "+name+" due to unbound types",argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn),argCount-1);return[]})}function integerReadValueFromPointer(name,shift,signed){switch(shift){case 0:return signed?function readS8FromPointer(pointer){return HEAP8[pointer]}:function readU8FromPointer(pointer){return HEAPU8[pointer]};case 1:return signed?function readS16FromPointer(pointer){return HEAP16[pointer>>1]}:function readU16FromPointer(pointer){return HEAPU16[pointer>>1]};case 2:return signed?function readS32FromPointer(pointer){return HEAP32[pointer>>2]}:function readU32FromPointer(pointer){return HEAPU32[pointer>>2]};default:throw new TypeError("Unknown integer type: "+name)}}function __embind_register_integer(primitiveType,name,size,minRange,maxRange){name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var shift=getShiftFromSize(size);var fromWireType=function(value){return value};if(minRange===0){var bitshift=32-8*size;fromWireType=function(value){return value<>>bitshift}}var isUnsignedType=name.includes("unsigned");registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":function(destructors,value){if(typeof value!=="number"&&typeof value!=="boolean"){throw new TypeError('Cannot convert "'+_embind_repr(value)+'" to '+this.name)}if(valuemaxRange){throw new TypeError('Passing a number "'+_embind_repr(value)+'" from JS side to C/C++ side to an argument of type "'+name+'", which is outside the valid range ['+minRange+", "+maxRange+"]!")}return isUnsignedType?value>>>0:value|0},"argPackAdvance":8,"readValueFromPointer":integerReadValueFromPointer(name,shift,minRange!==0),destructorFunction:null})}function __embind_register_memory_view(rawType,dataTypeIndex,name){var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){handle=handle>>2;var heap=HEAPU32;var size=heap[handle];var data=heap[handle+1];return new TA(buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":8,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})}function __embind_register_std_string(rawType,name){name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":function(value){var length=HEAPU32[value>>2];var str;if(stdStringIsUTF8){var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i;if(i==length||HEAPU8[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr+4,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}HEAPU8[ptr+4+i]=charCode}}else{for(var i=0;i>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":function(destructors,value){if(!(typeof value==="string")){throwBindingError("Cannot pass non-string to C++ string type "+name)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":8,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:function(ptr){_free(ptr)}})}function __embind_register_value_object(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor){structRegistrations[rawType]={name:readLatin1String(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}}function __embind_register_value_object_field(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext){structRegistrations[structType].fields.push({fieldName:readLatin1String(fieldName),getterReturnType:getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext:getterContext,setterArgumentType:setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext:setterContext})}function __embind_register_void(rawType,name){name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":function(){return undefined},"toWireType":function(destructors,o){return undefined}})}var emval_symbols={};function getStringOrSymbol(address){var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}else{return symbol}}var emval_methodCallers=[];function __emval_call_void_method(caller,handle,methodName,args){caller=emval_methodCallers[caller];handle=requireHandle(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)}function __emval_addMethodCaller(caller){var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id}function __emval_lookupTypes(argCount,argTypes){var a=new Array(argCount);for(var i=0;i>2)+i],"parameter "+i)}return a}function __emval_get_method_caller(argCount,argTypes){var types=__emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var params=["retType"];var args=[retType];var argsList="";for(var i=0;i4){emval_handle_array[handle].refcount+=1}}function __emval_take_value(type,argv){type=requireRegisteredType(type,"_emval_take_value");var v=type["readValueFromPointer"](argv);return __emval_register(v)}function _abort(){abort()}var _emscripten_get_now_is_monotonic=true;function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if((clk_id===1||clk_id===4)&&_emscripten_get_now_is_monotonic){now=_emscripten_get_now()}else{setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function _dlopen(filename,flag){abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")}function _dlsym(handle,symbol){abort("To use dlopen, you need to use Emscripten's linking support, see https://github.com/emscripten-core/emscripten/wiki/Linking")}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){assert(Array.isArray(readAsmConstArgsArray));assert(buf%16==0);readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){assert(ch===100||ch===102||ch===105);var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);if(!ASM_CONSTS.hasOwnProperty(code))abort("No EM_ASM constant found at address "+code);return ASM_CONSTS[code].apply(null,args)}function _emscripten_get_heap_max(){return 2147483648}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_pc_get_function(pc){abort("Cannot use emscripten_pc_get_function without -s USE_OFFSET_CONVERTER")}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){err("emscripten_realloc_buffer: Attempted to grow heap from "+buffer.byteLength+" bytes to "+size+" bytes, but got error: "+e)}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;assert(requestedSize>oldSize);var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){err("Cannot enlarge memory, asked to go up to "+requestedSize+" bytes, but the limit is "+maxHeapSize+" bytes!");return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}err("Failed to grow the heap from "+oldSize+" bytes to "+newSize+" bytes, not enough memory!");return false}function _emscripten_generate_pc(frame){abort("Cannot use emscripten_generate_pc (needed by __builtin_return_address) without -s USE_OFFSET_CONVERTER")}var UNWIND_CACHE={};function __emscripten_save_in_unwind_cache(callstack){callstack.forEach(function(frame){var pc=_emscripten_generate_pc(frame);if(pc){UNWIND_CACHE[pc]=frame}})}function _emscripten_stack_snapshot(){var callstack=(new Error).stack.split("\n");if(callstack[0]=="Error"){callstack.shift()}__emscripten_save_in_unwind_cache(callstack);UNWIND_CACHE.last_addr=_emscripten_generate_pc(callstack[2]);UNWIND_CACHE.last_stack=callstack;return UNWIND_CACHE.last_addr}function _emscripten_stack_unwind_buffer(addr,buffer,count){var stack;if(UNWIND_CACHE.last_addr==addr){stack=UNWIND_CACHE.last_stack}else{stack=(new Error).stack.split("\n");if(stack[0]=="Error"){stack.shift()}__emscripten_save_in_unwind_cache(stack)}var offset=2;while(stack[offset]&&_emscripten_generate_pc(stack[offset])!=addr){++offset}for(var i=0;i>2]=_emscripten_generate_pc(stack[i+offset])}return i}function _emscripten_thread_sleep(msecs){var start=_emscripten_get_now();while(_emscripten_get_now()-start>1;var quadIndexes=new Uint16Array(numIndexes);var i=0,v=0;while(1){quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+1;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v;if(i>=numIndexes)break;quadIndexes[i++]=v+2;if(i>=numIndexes)break;quadIndexes[i++]=v+3;if(i>=numIndexes)break;v+=4}context.GLctx.bufferData(34963,quadIndexes,35044);context.GLctx.bindBuffer(34963,null)}},getTempVertexBuffer:function getTempVertexBuffer(sizeBytes){var idx=GL.log2ceilLookup(sizeBytes);var ringbuffer=GL.currentContext.tempVertexBuffers1[idx];var nextFreeBufferIndex=GL.currentContext.tempVertexBufferCounters1[idx];GL.currentContext.tempVertexBufferCounters1[idx]=GL.currentContext.tempVertexBufferCounters1[idx]+1&GL.numTempVertexBuffersPerSize-1;var vbo=ringbuffer[nextFreeBufferIndex];if(vbo){return vbo}var prevVBO=GLctx.getParameter(34964);ringbuffer[nextFreeBufferIndex]=GLctx.createBuffer();GLctx.bindBuffer(34962,ringbuffer[nextFreeBufferIndex]);GLctx.bufferData(34962,1<>2]:-1;source+=UTF8ToString(HEAP32[string+i*4>>2],len<0?undefined:len)}return source},calcBufLength:function calcBufLength(size,type,stride,count){if(stride>0){return count*stride}var typeSize=GL.byteSizeByType[type-GL.byteSizeByTypeRoot];return size*typeSize*count},usedTempBuffers:[],preDrawHandleClientVertexAttribBindings:function preDrawHandleClientVertexAttribBindings(count){GL.resetBufferBinding=false;for(var i=0;i1?canvas.getContext("webgl2",webGLContextAttributes):canvas.getContext("webgl",webGLContextAttributes);if(!ctx)return 0;var handle=GL.registerContext(ctx,webGLContextAttributes);return handle},enableOffscreenFramebufferAttributes:function(webGLContextAttributes){webGLContextAttributes.renderViaOffscreenBackBuffer=true;webGLContextAttributes.preserveDrawingBuffer=true},createOffscreenFramebuffer:function(context){var gl=context.GLctx;var fbo=gl.createFramebuffer();gl.bindFramebuffer(36160,fbo);context.defaultFbo=fbo;context.defaultFboForbidBlitFramebuffer=false;if(gl.getContextAttributes().antialias){context.defaultFboForbidBlitFramebuffer=true}else{var firefoxMatch=navigator.userAgent.toLowerCase().match(/firefox\/(\d\d)/);if(firefoxMatch!=null){var firefoxVersion=firefoxMatch[1];context.defaultFboForbidBlitFramebuffer=firefoxVersion<67}}context.defaultColorTarget=gl.createTexture();context.defaultDepthTarget=gl.createRenderbuffer();GL.resizeOffscreenFramebuffer(context);gl.bindTexture(3553,context.defaultColorTarget);gl.texParameteri(3553,10241,9728);gl.texParameteri(3553,10240,9728);gl.texParameteri(3553,10242,33071);gl.texParameteri(3553,10243,33071);gl.texImage2D(3553,0,6408,gl.canvas.width,gl.canvas.height,0,6408,5121,null);gl.framebufferTexture2D(36160,36064,3553,context.defaultColorTarget,0);gl.bindTexture(3553,null);var depthTarget=gl.createRenderbuffer();gl.bindRenderbuffer(36161,context.defaultDepthTarget);gl.renderbufferStorage(36161,33189,gl.canvas.width,gl.canvas.height);gl.framebufferRenderbuffer(36160,36096,36161,context.defaultDepthTarget);gl.bindRenderbuffer(36161,null);var vertices=[-1,-1,-1,1,1,-1,1,1];var vb=gl.createBuffer();gl.bindBuffer(34962,vb);gl.bufferData(34962,new Float32Array(vertices),35044);gl.bindBuffer(34962,null);context.blitVB=vb;var vsCode="attribute vec2 pos;"+"varying lowp vec2 tex;"+"void main() { tex = pos * 0.5 + vec2(0.5,0.5); gl_Position = vec4(pos, 0.0, 1.0); }";var vs=gl.createShader(35633);gl.shaderSource(vs,vsCode);gl.compileShader(vs);var fsCode="varying lowp vec2 tex;"+"uniform sampler2D sampler;"+"void main() { gl_FragColor = texture2D(sampler, tex); }";var fs=gl.createShader(35632);gl.shaderSource(fs,fsCode);gl.compileShader(fs);var blitProgram=gl.createProgram();gl.attachShader(blitProgram,vs);gl.attachShader(blitProgram,fs);gl.linkProgram(blitProgram);context.blitProgram=blitProgram;context.blitPosLoc=gl.getAttribLocation(blitProgram,"pos");gl.useProgram(blitProgram);gl.uniform1i(gl.getUniformLocation(blitProgram,"sampler"),0);gl.useProgram(null);context.defaultVao=undefined;if(gl.createVertexArray){context.defaultVao=gl.createVertexArray();gl.bindVertexArray(context.defaultVao);gl.enableVertexAttribArray(context.blitPosLoc);gl.bindVertexArray(null)}},resizeOffscreenFramebuffer:function(context){var gl=context.GLctx;if(context.defaultColorTarget){var prevTextureBinding=gl.getParameter(32873);gl.bindTexture(3553,context.defaultColorTarget);gl.texImage2D(3553,0,6408,gl.drawingBufferWidth,gl.drawingBufferHeight,0,6408,5121,null);gl.bindTexture(3553,prevTextureBinding)}if(context.defaultDepthTarget){var prevRenderBufferBinding=gl.getParameter(36007);gl.bindRenderbuffer(36161,context.defaultDepthTarget);gl.renderbufferStorage(36161,33189,gl.drawingBufferWidth,gl.drawingBufferHeight);gl.bindRenderbuffer(36161,prevRenderBufferBinding)}},blitOffscreenFramebuffer:function(context){var gl=context.GLctx;var prevScissorTest=gl.getParameter(3089);if(prevScissorTest)gl.disable(3089);var prevFbo=gl.getParameter(36006);if(gl.blitFramebuffer&&!context.defaultFboForbidBlitFramebuffer){gl.bindFramebuffer(36008,context.defaultFbo);gl.bindFramebuffer(36009,null);gl.blitFramebuffer(0,0,gl.canvas.width,gl.canvas.height,0,0,gl.canvas.width,gl.canvas.height,16384,9728)}else{gl.bindFramebuffer(36160,null);var prevProgram=gl.getParameter(35725);gl.useProgram(context.blitProgram);var prevVB=gl.getParameter(34964);gl.bindBuffer(34962,context.blitVB);var prevActiveTexture=gl.getParameter(34016);gl.activeTexture(33984);var prevTextureBinding=gl.getParameter(32873);gl.bindTexture(3553,context.defaultColorTarget);var prevBlend=gl.getParameter(3042);if(prevBlend)gl.disable(3042);var prevCullFace=gl.getParameter(2884);if(prevCullFace)gl.disable(2884);var prevDepthTest=gl.getParameter(2929);if(prevDepthTest)gl.disable(2929);var prevStencilTest=gl.getParameter(2960);if(prevStencilTest)gl.disable(2960);function draw(){gl.vertexAttribPointer(context.blitPosLoc,2,5126,false,0,0);gl.drawArrays(5,0,4)}if(context.defaultVao){var prevVAO=gl.getParameter(34229);gl.bindVertexArray(context.defaultVao);draw();gl.bindVertexArray(prevVAO)}else{var prevVertexAttribPointer={buffer:gl.getVertexAttrib(context.blitPosLoc,34975),size:gl.getVertexAttrib(context.blitPosLoc,34339),stride:gl.getVertexAttrib(context.blitPosLoc,34340),type:gl.getVertexAttrib(context.blitPosLoc,34341),normalized:gl.getVertexAttrib(context.blitPosLoc,34922),pointer:gl.getVertexAttribOffset(context.blitPosLoc,34373)};var maxVertexAttribs=gl.getParameter(34921);var prevVertexAttribEnables=[];for(var i=0;i=2){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query_webgl2")}if(context.version<2||!GLctx.disjointTimerQueryExt){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query")}__webgl_enable_WEBGL_multi_draw(GLctx);var exts=GLctx.getSupportedExtensions()||[];exts.forEach(function(ext){if(!ext.includes("lose_context")&&!ext.includes("debug")){GLctx.getExtension(ext)}})}};var JSEvents={inEventHandler:0,removeAllEventListeners:function(){for(var i=JSEvents.eventHandlers.length-1;i>=0;--i){JSEvents._removeHandler(i)}JSEvents.eventHandlers=[];JSEvents.deferredCalls=[]},registerRemoveEventListeners:function(){if(!JSEvents.removeEventListenersRegistered){__ATEXIT__.push(JSEvents.removeAllEventListeners);JSEvents.removeEventListenersRegistered=true}},deferredCalls:[],deferCall:function(targetFunction,precedence,argsList){function arraysHaveEqualContent(arrA,arrB){if(arrA.length!=arrB.length)return false;for(var i in arrA){if(arrA[i]!=arrB[i])return false}return true}for(var i in JSEvents.deferredCalls){var call=JSEvents.deferredCalls[i];if(call.targetFunction==targetFunction&&arraysHaveEqualContent(call.argsList,argsList)){return}}JSEvents.deferredCalls.push({targetFunction:targetFunction,precedence:precedence,argsList:argsList});JSEvents.deferredCalls.sort(function(x,y){return x.precedence>2;var powerPreference=HEAP32[a+(24>>2)];var contextAttributes={"alpha":!!HEAP32[a+(0>>2)],"depth":!!HEAP32[a+(4>>2)],"stencil":!!HEAP32[a+(8>>2)],"antialias":!!HEAP32[a+(12>>2)],"premultipliedAlpha":!!HEAP32[a+(16>>2)],"preserveDrawingBuffer":!!HEAP32[a+(20>>2)],"powerPreference":__emscripten_webgl_power_preferences[powerPreference],"failIfMajorPerformanceCaveat":!!HEAP32[a+(28>>2)],majorVersion:HEAP32[a+(32>>2)],minorVersion:HEAP32[a+(36>>2)],enableExtensionsByDefault:HEAP32[a+(40>>2)],explicitSwapControl:HEAP32[a+(44>>2)],proxyContextToMainThread:HEAP32[a+(48>>2)],renderViaOffscreenBackBuffer:HEAP32[a+(52>>2)]};var canvas=findCanvasEventTarget(target);if(!canvas){return 0}if(canvas.offscreenCanvas)canvas=canvas.offscreenCanvas;if(contextAttributes.explicitSwapControl){var supportsOffscreenCanvas=canvas.transferControlToOffscreen||typeof OffscreenCanvas!=="undefined"&&canvas instanceof OffscreenCanvas;if(!supportsOffscreenCanvas){if(!contextAttributes.renderViaOffscreenBackBuffer){contextAttributes.renderViaOffscreenBackBuffer=true}}if(canvas.transferControlToOffscreen){if(!canvas.controlTransferredOffscreen){GL.offscreenCanvases[canvas.id]={canvas:canvas.transferControlToOffscreen(),canvasSharedPtr:_malloc(12),id:canvas.id};canvas.controlTransferredOffscreen=true}else if(!GL.offscreenCanvases[canvas.id]){return 0}canvas=GL.offscreenCanvases[canvas.id]}}var contextHandle=GL.createContext(canvas,contextAttributes);return contextHandle}function _emscripten_webgl_create_context(a0,a1){return _emscripten_webgl_do_create_context(a0,a1)}function _emscripten_webgl_do_get_current_context(){return GL.currentContext?GL.currentContext.handle:0}function _emscripten_webgl_get_current_context(){return _emscripten_webgl_do_get_current_context()}Module["_emscripten_webgl_get_current_context"]=_emscripten_webgl_get_current_context;function _emscripten_webgl_make_context_current(contextHandle){var success=GL.makeContextCurrent(contextHandle);return success?0:-5}Module["_emscripten_webgl_make_context_current"]=_emscripten_webgl_make_context_current;function _emscripten_webgl_destroy_context(contextHandle){if(GL.currentContext==contextHandle)GL.currentContext=0;GL.deleteContext(contextHandle)}function _emscripten_webgl_get_context_attributes(c,a){if(!a)return-5;c=GL.contexts[c];if(!c)return-3;var t=c.GLctx;if(!t)return-3;t=t.getContextAttributes();HEAP32[a>>2]=t.alpha;HEAP32[a+4>>2]=t.depth;HEAP32[a+8>>2]=t.stencil;HEAP32[a+12>>2]=t.antialias;HEAP32[a+16>>2]=t.premultipliedAlpha;HEAP32[a+20>>2]=t.preserveDrawingBuffer;var power=t["powerPreference"]&&__emscripten_webgl_power_preferences.indexOf(t["powerPreference"]);HEAP32[a+24>>2]=power;HEAP32[a+28>>2]=t.failIfMajorPerformanceCaveat;HEAP32[a+32>>2]=c.version;HEAP32[a+36>>2]=0;HEAP32[a+40>>2]=c.attributes.enableExtensionsByDefault;return 0}function _emscripten_webgl_init_context_attributes(attributes){assert(attributes);var a=attributes>>2;for(var i=0;i<56>>2;++i){HEAP32[a+i]=0}HEAP32[a+(0>>2)]=HEAP32[a+(4>>2)]=HEAP32[a+(12>>2)]=HEAP32[a+(16>>2)]=HEAP32[a+(32>>2)]=HEAP32[a+(40>>2)]=1}var ENV={};function getExecutableName(){return thisProgram||"./this.program"}function getEnvStrings(){if(!getEnvStrings.strings){var lang=(typeof navigator==="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(x+"="+env[x])}getEnvStrings.strings=strings}return getEnvStrings.strings}function _environ_get(__environ,environ_buf){var bufSize=0;getEnvStrings().forEach(function(string,i){var ptr=environ_buf+bufSize;HEAP32[__environ+i*4>>2]=ptr;writeAsciiToMemory(string,ptr);bufSize+=string.length+1});return 0}function _environ_sizes_get(penviron_count,penviron_buf_size){var strings=getEnvStrings();HEAP32[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(function(string){bufSize+=string.length+1});HEAP32[penviron_buf_size>>2]=bufSize;return 0}function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getTempRet0(){return getTempRet0()}function _getentropy(buffer,size){if(!_getentropy.randomDevice){_getentropy.randomDevice=getRandomDevice()}for(var i=0;i>0]=_getentropy.randomDevice()}return 0}function _glActiveTexture(x0){GLctx["activeTexture"](x0)}function _glAttachShader(program,shader){GLctx.attachShader(GL.programs[program],GL.shaders[shader])}function _glBindAttribLocation(program,index,name){GLctx.bindAttribLocation(GL.programs[program],index,UTF8ToString(name))}function _glBindBuffer(target,buffer){if(target==34962){GLctx.currentArrayBufferBinding=buffer}else if(target==34963){GLctx.currentElementArrayBufferBinding=buffer}if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])}function _glBindBufferBase(target,index,buffer){GLctx["bindBufferBase"](target,index,GL.buffers[buffer])}function _glBindFramebuffer(target,framebuffer){GLctx.bindFramebuffer(target,framebuffer?GL.framebuffers[framebuffer]:GL.currentContext.defaultFbo)}function _glBindTexture(target,texture){GLctx.bindTexture(target,GL.textures[texture])}function _glBindVertexArray(vao){GLctx["bindVertexArray"](GL.vaos[vao]);var ibo=GLctx.getParameter(34965);GLctx.currentElementArrayBufferBinding=ibo?ibo.name|0:0}function _glBufferData(target,size,data,usage){if(GL.currentContext.version>=2){if(data){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data,data+size):size,usage)}}function convertI32PairToI53(lo,hi){assert(hi===(hi|0));return(lo>>>0)+hi*4294967296}function _glClientWaitSync(sync,flags,timeoutLo,timeoutHi){return GLctx.clientWaitSync(GL.syncs[sync],flags,convertI32PairToI53(timeoutLo,timeoutHi))}function _glCompileShader(shader){GLctx.compileShader(GL.shaders[shader])}function _glCreateProgram(){var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;program.maxUniformLength=program.maxAttributeLength=program.maxUniformBlockNameLength=0;program.uniformIdCounter=1;GL.programs[id]=program;return id}function _glCreateShader(shaderType){var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id}function _glDeleteBuffers(n,buffers){for(var i=0;i>2];var buffer=GL.buffers[id];if(!buffer)continue;GLctx.deleteBuffer(buffer);buffer.name=0;GL.buffers[id]=null;if(id==GLctx.currentArrayBufferBinding)GLctx.currentArrayBufferBinding=0;if(id==GLctx.currentElementArrayBufferBinding)GLctx.currentElementArrayBufferBinding=0;if(id==GLctx.currentPixelPackBufferBinding)GLctx.currentPixelPackBufferBinding=0;if(id==GLctx.currentPixelUnpackBufferBinding)GLctx.currentPixelUnpackBufferBinding=0}}function _glDeleteFramebuffers(n,framebuffers){for(var i=0;i>2];var framebuffer=GL.framebuffers[id];if(!framebuffer)continue;GLctx.deleteFramebuffer(framebuffer);framebuffer.name=0;GL.framebuffers[id]=null}}function _glDeleteProgram(id){if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null}function _glDeleteShader(id){if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null}function _glDeleteSync(id){if(!id)return;var sync=GL.syncs[id];if(!sync){GL.recordError(1281);return}GLctx.deleteSync(sync);sync.name=0;GL.syncs[id]=null}function _glDeleteTextures(n,textures){for(var i=0;i>2];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}function _glDeleteVertexArrays(n,vaos){for(var i=0;i>2];GLctx["deleteVertexArray"](GL.vaos[id]);GL.vaos[id]=null}}function _glDisable(x0){GLctx["disable"](x0)}function _glDisableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=false;GLctx.disableVertexAttribArray(index)}function _glDrawArrays(mode,first,count){GL.preDrawHandleClientVertexAttribBindings(first+count);GLctx.drawArrays(mode,first,count);GL.postDrawHandleClientVertexAttribBindings()}var tempFixedLengthArray=[];function _glDrawBuffers(n,bufs){var bufArray=tempFixedLengthArray[n];for(var i=0;i>2]}GLctx["drawBuffers"](bufArray)}function _glEnableVertexAttribArray(index){var cb=GL.currentContext.clientBuffers[index];cb.enabled=true;GLctx.enableVertexAttribArray(index)}function _glFenceSync(condition,flags){var sync=GLctx.fenceSync(condition,flags);if(sync){var id=GL.getNewId(GL.syncs);sync.name=id;GL.syncs[id]=sync;return id}else{return 0}}function _glFinish(){GLctx["finish"]()}function _glFlush(){GLctx["flush"]()}function _glFramebufferTexture2D(target,attachment,textarget,texture,level){GLctx.framebufferTexture2D(target,attachment,textarget,GL.textures[texture],level)}function _glFramebufferTextureLayer(target,attachment,texture,level,layer){GLctx.framebufferTextureLayer(target,attachment,GL.textures[texture],level,layer)}function __glGenObject(n,buffers,createFunction,objectTable){for(var i=0;i>2]=id}}function _glGenBuffers(n,buffers){__glGenObject(n,buffers,"createBuffer",GL.buffers)}function _glGenFramebuffers(n,ids){__glGenObject(n,ids,"createFramebuffer",GL.framebuffers)}function _glGenTextures(n,textures){__glGenObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){__glGenObject(n,arrays,"createVertexArray",GL.vaos)}function _glGetAttribLocation(program,name){return GLctx.getAttribLocation(GL.programs[program],UTF8ToString(name))}function _glGetError(){var error=GLctx.getError()||GL.lastError;GL.lastError=0;return error}function readI53FromI64(ptr){return HEAPU32[ptr>>2]+HEAP32[ptr+4>>2]*4294967296}function readI53FromU64(ptr){return HEAPU32[ptr>>2]+HEAPU32[ptr+4>>2]*4294967296}function writeI53ToI64(ptr,num){HEAPU32[ptr>>2]=num;HEAPU32[ptr+4>>2]=(num-HEAPU32[ptr>>2])/4294967296;var deserialized=num>=0?readI53FromU64(ptr):readI53FromI64(ptr);if(deserialized!=num)warnOnce("writeI53ToI64() out of range: serialized JS Number "+num+" to Wasm heap as bytes lo=0x"+HEAPU32[ptr>>2].toString(16)+", hi=0x"+HEAPU32[ptr+4>>2].toString(16)+", which deserializes back to "+deserialized+" instead!")}function emscriptenWebGLGet(name_,p,type){if(!p){GL.recordError(1281);return}var ret=undefined;switch(name_){case 36346:ret=1;break;case 36344:if(type!=0&&type!=1){GL.recordError(1280)}return;case 34814:case 36345:ret=0;break;case 34466:var formats=GLctx.getParameter(34467);ret=formats?formats.length:0;break;case 33309:if(GL.currentContext.version<2){GL.recordError(1282);return}var exts=GLctx.getSupportedExtensions()||[];ret=2*exts.length;break;case 33307:case 33308:if(GL.currentContext.version<2){GL.recordError(1280);return}ret=name_==33307?3:0;break}if(ret===undefined){var result=GLctx.getParameter(name_);switch(typeof result){case"number":ret=result;break;case"boolean":ret=result?1:0;break;case"string":GL.recordError(1280);return;case"object":if(result===null){switch(name_){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:{ret=0;break}default:{GL.recordError(1280);return}}}else if(result instanceof Float32Array||result instanceof Uint32Array||result instanceof Int32Array||result instanceof Array){for(var i=0;i>2]=result[i];break;case 2:HEAPF32[p+i*4>>2]=result[i];break;case 4:HEAP8[p+i>>0]=result[i]?1:0;break}}return}else{try{ret=result.name|0}catch(e){GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Unknown object returned from WebGL getParameter("+name_+")! (error: "+e+")");return}}break;default:GL.recordError(1280);err("GL_INVALID_ENUM in glGet"+type+"v: Native code calling glGet"+type+"v("+name_+") and it returns "+result+" of type "+typeof result+"!");return}}switch(type){case 1:writeI53ToI64(p,ret);break;case 0:HEAP32[p>>2]=ret;break;case 2:HEAPF32[p>>2]=ret;break;case 4:HEAP8[p>>0]=ret?1:0;break}}function _glGetIntegerv(name_,p){emscriptenWebGLGet(name_,p,0)}function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _glGetString(name_){var ret=GL.stringCache[name_];if(!ret){switch(name_){case 7939:var exts=GLctx.getSupportedExtensions()||[];exts=exts.concat(exts.map(function(e){return"GL_"+e}));ret=stringToNewUTF8(exts.join(" "));break;case 7936:case 7937:case 37445:case 37446:var s=GLctx.getParameter(name_);if(!s){GL.recordError(1280)}ret=s&&stringToNewUTF8(s);break;case 7938:var glVersion=GLctx.getParameter(7938);if(GL.currentContext.version>=2)glVersion="OpenGL ES 3.0 ("+glVersion+")";else{glVersion="OpenGL ES 2.0 ("+glVersion+")"}ret=stringToNewUTF8(glVersion);break;case 35724:var glslVersion=GLctx.getParameter(35724);var ver_re=/^WebGL GLSL ES ([0-9]\.[0-9][0-9]?)(?:$| .*)/;var ver_num=glslVersion.match(ver_re);if(ver_num!==null){if(ver_num[1].length==3)ver_num[1]=ver_num[1]+"0";glslVersion="OpenGL ES GLSL ES "+ver_num[1]+" ("+glslVersion+")"}ret=stringToNewUTF8(glslVersion);break;default:GL.recordError(1280)}GL.stringCache[name_]=ret}return ret}function _glGetUniformBlockIndex(program,uniformBlockName){return GLctx["getUniformBlockIndex"](GL.programs[program],UTF8ToString(uniformBlockName))}function jstoi_q(str){return parseInt(str)}function webglGetLeftBracePos(name){return name.slice(-1)=="]"&&name.lastIndexOf("[")}function webglPrepareUniformLocationsBeforeFirstUse(program){var uniformLocsById=program.uniformLocsById,uniformSizeAndIdsByName=program.uniformSizeAndIdsByName,i,j;if(!uniformLocsById){program.uniformLocsById=uniformLocsById={};program.uniformArrayNamesById={};for(i=0;i0?nm.slice(0,lb):nm;var id=program.uniformIdCounter;program.uniformIdCounter+=sz;uniformSizeAndIdsByName[arrayName]=[sz,id];for(j=0;j0){arrayIndex=jstoi_q(name.slice(leftBrace+1))>>>0;uniformBaseName=name.slice(0,leftBrace)}var sizeAndId=program.uniformSizeAndIdsByName[uniformBaseName];if(sizeAndId&&arrayIndex>shift,pixels+bytes>>shift)}function _glReadPixels(x,y,width,height,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);GLctx.readPixels(x,y,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glShaderSource(shader,count,string,length){var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}function _glTexParameterfv(target,pname,params){var param=HEAPF32[params>>2];GLctx.texParameterf(target,pname,param)}function _glTexParameteri(x0,x1,x2){GLctx["texParameteri"](x0,x1,x2)}function _glTexStorage2D(x0,x1,x2,x3,x4){GLctx["texStorage2D"](x0,x1,x2,x3,x4)}function _glTexStorage3D(x0,x1,x2,x3,x4,x5){GLctx["texStorage3D"](x0,x1,x2,x3,x4,x5)}function _glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels){if(GL.currentContext.version>=2){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,null)}return}var pixelData=null;if(pixels)pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,0);GLctx.texSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixelData)}function _glTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels){if(GLctx.currentPixelUnpackBufferBinding){GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,heap,pixels>>heapAccessShiftForWebGLHeap(heap))}else{GLctx["texSubImage3D"](target,level,xoffset,yoffset,zoffset,width,height,depth,format,type,null)}}function webglGetUniformLocation(location){var p=GLctx.currentProgram;if(p){var webglLoc=p.uniformLocsById[location];if(typeof webglLoc==="number"){p.uniformLocsById[location]=webglLoc=GLctx.getUniformLocation(p,p.uniformArrayNamesById[location]+(webglLoc>0?"["+webglLoc+"]":""))}return webglLoc}else{GL.recordError(1282)}}function _glUniform1f(location,v0){GLctx.uniform1f(webglGetUniformLocation(location),v0)}function _glUniform1i(location,v0){GLctx.uniform1i(webglGetUniformLocation(location),v0)}var miniTempWebGLFloatBuffers=[];function _glUniform2fv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform2fv(webglGetUniformLocation(location),HEAPF32,value>>2,count*2);return}if(count<=144){var view=miniTempWebGLFloatBuffers[2*count-1];for(var i=0;i<2*count;i+=2){view[i]=HEAPF32[value+4*i>>2];view[i+1]=HEAPF32[value+(4*i+4)>>2]}}else{var view=HEAPF32.subarray(value>>2,value+count*8>>2)}GLctx.uniform2fv(webglGetUniformLocation(location),view)}function _glUniform4fv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform4fv(webglGetUniformLocation(location),HEAPF32,value>>2,count*4);return}if(count<=72){var view=miniTempWebGLFloatBuffers[4*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<4*count;i+=4){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3]}}else{var view=HEAPF32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4fv(webglGetUniformLocation(location),view)}var __miniTempWebGLIntBuffers=[];function _glUniform4iv(location,count,value){if(GL.currentContext.version>=2){GLctx.uniform4iv(webglGetUniformLocation(location),HEAP32,value>>2,count*4);return}if(count<=72){var view=__miniTempWebGLIntBuffers[4*count-1];for(var i=0;i<4*count;i+=4){view[i]=HEAP32[value+4*i>>2];view[i+1]=HEAP32[value+(4*i+4)>>2];view[i+2]=HEAP32[value+(4*i+8)>>2];view[i+3]=HEAP32[value+(4*i+12)>>2]}}else{var view=HEAP32.subarray(value>>2,value+count*16>>2)}GLctx.uniform4iv(webglGetUniformLocation(location),view)}function _glUniformBlockBinding(program,uniformBlockIndex,uniformBlockBinding){program=GL.programs[program];GLctx["uniformBlockBinding"](program,uniformBlockIndex,uniformBlockBinding)}function _glUniformMatrix4fv(location,count,transpose,value){if(GL.currentContext.version>=2){GLctx.uniformMatrix4fv(webglGetUniformLocation(location),!!transpose,HEAPF32,value>>2,count*16);return}if(count<=18){var view=miniTempWebGLFloatBuffers[16*count-1];var heap=HEAPF32;value>>=2;for(var i=0;i<16*count;i+=16){var dst=value+i;view[i]=heap[dst];view[i+1]=heap[dst+1];view[i+2]=heap[dst+2];view[i+3]=heap[dst+3];view[i+4]=heap[dst+4];view[i+5]=heap[dst+5];view[i+6]=heap[dst+6];view[i+7]=heap[dst+7];view[i+8]=heap[dst+8];view[i+9]=heap[dst+9];view[i+10]=heap[dst+10];view[i+11]=heap[dst+11];view[i+12]=heap[dst+12];view[i+13]=heap[dst+13];view[i+14]=heap[dst+14];view[i+15]=heap[dst+15]}}else{var view=HEAPF32.subarray(value>>2,value+count*64>>2)}GLctx.uniformMatrix4fv(webglGetUniformLocation(location),!!transpose,view)}function _glUseProgram(program){program=GL.programs[program];GLctx.useProgram(program);GLctx.currentProgram=program}function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){var cb=GL.currentContext.clientBuffers[index];if(!GLctx.currentArrayBufferBinding){cb.size=size;cb.type=type;cb.normalized=normalized;cb.stride=stride;cb.ptr=ptr;cb.clientside=true;cb.vertexAttribPointerAdaptor=function(index,size,type,normalized,stride,ptr){this.vertexAttribPointer(index,size,type,normalized,stride,ptr)};return}cb.clientside=false;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}function _glViewport(x0,x1,x2,x3){GLctx["viewport"](x0,x1,x2,x3)}function _gmtime_r(time,tmPtr){var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getUTCSeconds();HEAP32[tmPtr+4>>2]=date.getUTCMinutes();HEAP32[tmPtr+8>>2]=date.getUTCHours();HEAP32[tmPtr+12>>2]=date.getUTCDate();HEAP32[tmPtr+16>>2]=date.getUTCMonth();HEAP32[tmPtr+20>>2]=date.getUTCFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getUTCDay();HEAP32[tmPtr+36>>2]=0;HEAP32[tmPtr+32>>2]=0;var start=Date.UTC(date.getUTCFullYear(),0,1,0,0,0,0);var yday=(date.getTime()-start)/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;if(!_gmtime_r.GMTString)_gmtime_r.GMTString=allocateUTF8("GMT");HEAP32[tmPtr+40>>2]=_gmtime_r.GMTString;return tmPtr}function _llvm_eh_typeid_for(type){return type}function _tzset(){if(_tzset.called)return;_tzset.called=true;var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAP32[__get_timezone()>>2]=stdTimezoneOffset*60;HEAP32[__get_daylight()>>2]=Number(winterOffset!=summerOffset);function extractZone(date){var match=date.toTimeString().match(/\(([A-Za-z ]+)\)$/);return match?match[1]:"GMT"}var winterName=extractZone(winter);var summerName=extractZone(summer);var winterNamePtr=allocateUTF8(winterName);var summerNamePtr=allocateUTF8(summerName);if(summerOffset>2]=winterNamePtr;HEAP32[__get_tzname()+4>>2]=summerNamePtr}else{HEAP32[__get_tzname()>>2]=summerNamePtr;HEAP32[__get_tzname()+4>>2]=winterNamePtr}}function _localtime_r(time,tmPtr){_tzset();var date=new Date(HEAP32[time>>2]*1e3);HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();HEAP32[tmPtr+20>>2]=date.getFullYear()-1900;HEAP32[tmPtr+24>>2]=date.getDay();var start=new Date(date.getFullYear(),0,1);var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr+36>>2]=-(date.getTimezoneOffset()*60);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dst=(summerOffset!=winterOffset&&date.getTimezoneOffset()==Math.min(winterOffset,summerOffset))|0;HEAP32[tmPtr+32>>2]=dst;var zonePtr=HEAP32[__get_tzname()+(dst?4:0)>>2];HEAP32[tmPtr+40>>2]=zonePtr;return tmPtr}function _mktime(tmPtr){_tzset();var date=new Date(HEAP32[tmPtr+20>>2]+1900,HEAP32[tmPtr+16>>2],HEAP32[tmPtr+12>>2],HEAP32[tmPtr+8>>2],HEAP32[tmPtr+4>>2],HEAP32[tmPtr>>2],0);var dst=HEAP32[tmPtr+32>>2];var guessedOffset=date.getTimezoneOffset();var start=new Date(date.getFullYear(),0,1);var summerOffset=new Date(date.getFullYear(),6,1).getTimezoneOffset();var winterOffset=start.getTimezoneOffset();var dstOffset=Math.min(winterOffset,summerOffset);if(dst<0){HEAP32[tmPtr+32>>2]=Number(summerOffset!=winterOffset&&dstOffset==guessedOffset)}else if(dst>0!=(dstOffset==guessedOffset)){var nonDstOffset=Math.max(winterOffset,summerOffset);var trueOffset=dst>0?dstOffset:nonDstOffset;date.setTime(date.getTime()+(trueOffset-guessedOffset)*6e4)}HEAP32[tmPtr+24>>2]=date.getDay();var yday=(date.getTime()-start.getTime())/(1e3*60*60*24)|0;HEAP32[tmPtr+28>>2]=yday;HEAP32[tmPtr>>2]=date.getSeconds();HEAP32[tmPtr+4>>2]=date.getMinutes();HEAP32[tmPtr+8>>2]=date.getHours();HEAP32[tmPtr+12>>2]=date.getDate();HEAP32[tmPtr+16>>2]=date.getMonth();return date.getTime()/1e3|0}function _proc_exit(code){procExit(code)}function _setTempRet0(val){setTempRet0(val)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}Module["requestFullscreen"]=function Module_requestFullscreen(lockPointer,resizeCanvas){Browser.requestFullscreen(lockPointer,resizeCanvas)};Module["requestFullScreen"]=function Module_requestFullScreen(){Browser.requestFullScreen()};Module["requestAnimationFrame"]=function Module_requestAnimationFrame(func){Browser.requestAnimationFrame(func)};Module["setCanvasSize"]=function Module_setCanvasSize(width,height,noUpdates){Browser.setCanvasSize(width,height,noUpdates)};Module["pauseMainLoop"]=function Module_pauseMainLoop(){Browser.mainLoop.pause()};Module["resumeMainLoop"]=function Module_resumeMainLoop(){Browser.mainLoop.resume()};Module["getUserMedia"]=function Module_getUserMedia(){Browser.getUserMedia()};Module["createContext"]=function Module_createContext(canvas,useWebGL,setInModule,webGLContextAttributes){return Browser.createContext(canvas,useWebGL,setInModule,webGLContextAttributes)};var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_unlink"]=FS.unlink;init_emval();PureVirtualError=Module["PureVirtualError"]=extendError(Error,"PureVirtualError");embind_init_charCodes();init_embind();BindingError=Module["BindingError"]=extendError(Error,"BindingError");InternalError=Module["InternalError"]=extendError(Error,"InternalError");init_ClassHandle();init_RegisteredPointer();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");var GLctx;for(var i=0;i<32;++i)tempFixedLengthArray.push(new Array(i));var miniTempWebGLFloatBuffersStorage=new Float32Array(288);for(var i=0;i<288;++i){miniTempWebGLFloatBuffers[i]=miniTempWebGLFloatBuffersStorage.subarray(0,i+1)}var __miniTempWebGLIntBuffersStorage=new Int32Array(288);for(var i=0;i<288;++i){__miniTempWebGLIntBuffers[i]=__miniTempWebGLIntBuffersStorage.subarray(0,i+1)}var ASSERTIONS=true;function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var decodeBase64=typeof atob==="function"?atob:function(input){var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");do{enc1=keyStr.indexOf(input.charAt(i++));enc2=keyStr.indexOf(input.charAt(i++));enc3=keyStr.indexOf(input.charAt(i++));enc4=keyStr.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!==64){output=output+String.fromCharCode(chr2)}if(enc4!==64){output=output+String.fromCharCode(chr3)}}while(i0){return}stackCheckInit();preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();assert(!Module["_main"],'compiled without a main, but one is present. if you added it from JS, use Module["onRuntimeInitialized"]');postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}checkStackCookie()}Module["run"]=run;function checkUnflushedContent(){var oldOut=out;var oldErr=err;var has=false;out=err=function(x){has=true};try{var flush=Module["_fflush"];if(flush)flush(0);["stdout","stderr"].forEach(function(name){var info=FS.analyzePath("/dev/"+name);if(!info)return;var stream=info.object;var rdev=stream.rdev;var tty=TTY.ttys[rdev];if(tty&&tty.output&&tty.output.length){has=true}})}catch(e){}out=oldOut;err=oldErr;if(has){warnOnce("stdio streams had content in them that was not flushed. you should set EXIT_RUNTIME to 1 (see the FAQ), or make sure to emit a newline when you printf etc.")}}function exit(status,implicit){EXITSTATUS=status;checkUnflushedContent();if(keepRuntimeAlive()){if(!implicit){var msg="program exited (with status: "+status+"), but EXIT_RUNTIME is not set, so halting execution but not exiting the runtime or preventing further async execution (build with EXIT_RUNTIME=1, if you want a true shutdown)";readyPromiseReject(msg);err(msg)}}else{exitRuntime()}procExit(status)}function procExit(code){EXITSTATUS=code;if(!keepRuntimeAlive()){if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); + + + return createMediapipeSolutionsWasm.ready +} +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = createMediapipeSolutionsWasm; +else if (typeof define === 'function' && define['amd']) + define([], function() { return createMediapipeSolutionsWasm; }); +else if (typeof exports === 'object') + exports["createMediapipeSolutionsWasm"] = createMediapipeSolutionsWasm; diff --git a/src/assets/mediapipe/face_mesh_solution_wasm_bin.wasm b/src/assets/mediapipe/face_mesh_solution_wasm_bin.wasm new file mode 100644 index 0000000..fc24e02 Binary files /dev/null and b/src/assets/mediapipe/face_mesh_solution_wasm_bin.wasm differ diff --git a/src/assets/pdf.worker.min.js b/src/assets/pdf.worker.min.js new file mode 100644 index 0000000..ef58002 --- /dev/null +++ b/src/assets/pdf.worker.min.js @@ -0,0 +1,31 @@ +/** + * @licstart The following is the entire license notice for the + * JavaScript code in this page + * + * Copyright 2024 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @licend The above is the entire license notice for the + * JavaScript code in this page + */ +/** + * pdfjsVersion = 5.7.284 + * pdfjsBuild = 7e5b36c2d + */const e=!("object"!=typeof process||process+""!="[object process]"||process.versions.nw||process.versions.electron&&process.type&&"browser"!==process.type),t=[1/0,1/0,-1/0,-1/0],a=new Float32Array(t),n=[.001,0,0,.001,0,0],s=1.35,r=.35,i=.25925925925925924,o=1,l=2,f=4,c=8,h=16,u=64,m=128,p=256,d="pdfjs_internal_editor_",g=3,b=9,w=13,j=15,k=101,y={PRINT:4,MODIFY_CONTENTS:8,COPY:16,MODIFY_ANNOTATIONS:32,FILL_INTERACTIVE_FORMS:256,COPY_FOR_ACCESSIBILITY:512,ASSEMBLE:1024,PRINT_HIGH_QUALITY:2048},q=1,v=2,S=3,x=0,C=4,F=1,T=2,O=3,R={TEXT:1,LINK:2,FREETEXT:3,LINE:4,SQUARE:5,CIRCLE:6,POLYGON:7,POLYLINE:8,HIGHLIGHT:9,UNDERLINE:10,SQUIGGLY:11,STRIKEOUT:12,STAMP:13,CARET:14,INK:15,POPUP:16,FILEATTACHMENT:17,SOUND:18,MOVIE:19,WIDGET:20,SCREEN:21,PRINTERMARK:22,TRAPNET:23,WATERMARK:24,THREED:25,REDACT:26},H="Group",D="R",M=1,N=2,E=4,_=16,z=32,L=128,U=512,X=1,W=2,K=4096,G=8192,V=32768,$=65536,Y=131072,J=1048576,Q=2097152,Z=8388608,ee=16777216,te=1,ae=2,ne=3,se=4,re=5,ie={E:"Mouse Enter",X:"Mouse Exit",D:"Mouse Down",U:"Mouse Up",Fo:"Focus",Bl:"Blur",PO:"PageOpen",PC:"PageClose",PV:"PageVisible",PI:"PageInvisible",K:"Keystroke",F:"Format",V:"Validate",C:"Calculate"},oe={WC:"WillClose",WS:"WillSave",DS:"DidSave",WP:"WillPrint",DP:"DidPrint"},le={O:"PageOpen",C:"PageClose"},fe=1,ce=5,he=1,ue=2,me=3,pe=4,de=5,ge=6,be=7,we=8,je=9,ke=10,ye=11,qe=12,ve=13,Se=14,Ae=15,xe=16,Ce=17,Ie=18,Fe=19,Te=20,Oe=21,Re=22,He=23,Be=24,De=25,Me=26,Ne=27,Pe=28,Ee=29,_e=30,ze=31,Le=32,Ue=33,Xe=34,We=35,Ke=36,Ge=37,Ve=38,$e=39,Ye=40,Je=41,Qe=42,Ze=43,et=44,tt=45,at=46,nt=47,st=48,rt=49,it=50,ot=51,lt=52,ft=53,ct=54,ht=55,ut=56,mt=57,pt=58,dt=59,gt=60,bt=61,wt=62,jt=63,kt=64,yt=65,qt=66,vt=67,St=68,At=69,xt=70,Ct=71,It=72,Ft=73,Tt=74,Ot=75,Rt=76,Ht=77,Bt=80,Dt=81,Mt=83,Nt=84,Pt=85,Et=86,_t=87,zt=88,Lt=89,Ut=90,Xt=91,Wt=92,Kt=93,Gt=94,Vt=0,$t=1,Yt=2,Jt=3,Qt=4,Zt=1,ea=2;let ta=fe;function getVerbosityLevel(){return ta}function info(e){ta>=ce&&console.info(`Info: ${e}`)}function warn(e){ta>=fe&&console.warn(`Warning: ${e}`)}function unreachable(e){throw new Error(e)}function assert(e,t){e||unreachable(t)}function createValidAbsoluteUrl(e,t=null,a=null){if(!e)return null;if(a&&"string"==typeof e){if(a.addDefaultProtocol&&e.startsWith("www.")){const t=e.match(/\./g);t?.length>=2&&(e=`http://${e}`)}if(a.tryConvertEncoding)try{e=stringToUTF8String(e)}catch{}}const n=t?URL.parse(e,t):URL.parse(e);return function _isValidProtocol(e){switch(e?.protocol){case"http:":case"https:":case"ftp:":case"mailto:":case"tel:":return!0;default:return!1}}(n)?n:null}function shadow(e,t,a,n=!1){Object.defineProperty(e,t,{value:a,enumerable:!n,configurable:!0,writable:!1});return a}const aa=function BaseExceptionClosure(){function BaseException(e,t){this.message=e;this.name=t}BaseException.prototype=new Error;BaseException.constructor=BaseException;return BaseException}();class PasswordException extends aa{constructor(e,t){super(e,"PasswordException");this.code=t}}class UnknownErrorException extends aa{constructor(e,t){super(e,"UnknownErrorException");this.details=t}}class InvalidPDFException extends aa{constructor(e){super(e,"InvalidPDFException")}}class ResponseException extends aa{constructor(e,t,a){super(e,"ResponseException");this.status=t;this.missing=a}}class FormatError extends aa{constructor(e){super(e,"FormatError")}}class AbortException extends aa{constructor(e){super(e,"AbortException")}}function bytesToString(e){"object"==typeof e&&void 0!==e?.length||unreachable("Invalid argument for bytesToString");const t=e.length,a=8192;if(t{if("undefined"==typeof document)return!1;const e=document.createElement("input");e.type="color";e.setAttribute("alpha","");e.value="#ff000080";return"#ff0000"!==e.value})())}}class Util{static get hexNums(){return shadow(this,"hexNums",Array.from(Array(256).keys(),e=>e.toString(16).padStart(2,"0")))}static makeHexColor(e,t,a){return`#${this.hexNums[e]}${this.hexNums[t]}${this.hexNums[a]}`}static domMatrixToTransform(e){return[e.a,e.b,e.c,e.d,e.e,e.f]}static scaleMinMax(e,t){let a;if(e[0]){if(e[0]<0){a=t[0];t[0]=t[2];t[2]=a}t[0]*=e[0];t[2]*=e[0];if(e[3]<0){a=t[1];t[1]=t[3];t[3]=a}t[1]*=e[3];t[3]*=e[3]}else{a=t[0];t[0]=t[1];t[1]=a;a=t[2];t[2]=t[3];t[3]=a;if(e[1]<0){a=t[1];t[1]=t[3];t[3]=a}t[1]*=e[1];t[3]*=e[1];if(e[2]<0){a=t[0];t[0]=t[2];t[2]=a}t[0]*=e[2];t[2]*=e[2]}t[0]+=e[4];t[1]+=e[5];t[2]+=e[4];t[3]+=e[5]}static transform(e,t){return[e[0]*t[0]+e[2]*t[1],e[1]*t[0]+e[3]*t[1],e[0]*t[2]+e[2]*t[3],e[1]*t[2]+e[3]*t[3],e[0]*t[4]+e[2]*t[5]+e[4],e[1]*t[4]+e[3]*t[5]+e[5]]}static multiplyByDOMMatrix(e,t){return[e[0]*t.a+e[2]*t.b,e[1]*t.a+e[3]*t.b,e[0]*t.c+e[2]*t.d,e[1]*t.c+e[3]*t.d,e[0]*t.e+e[2]*t.f+e[4],e[1]*t.e+e[3]*t.f+e[5]]}static applyTransform(e,t,a=0){const n=e[a],s=e[a+1];e[a]=n*t[0]+s*t[2]+t[4];e[a+1]=n*t[1]+s*t[3]+t[5]}static applyTransformToBezier(e,t,a=0){const n=t[0],s=t[1],r=t[2],i=t[3],o=t[4],l=t[5];for(let t=0;t<6;t+=2){const f=e[a+t],c=e[a+t+1];e[a+t]=f*n+c*r+o;e[a+t+1]=f*s+c*i+l}}static applyInverseTransform(e,t){const a=e[0],n=e[1],s=t[0]*t[3]-t[1]*t[2];e[0]=(a*t[3]-n*t[2]+t[2]*t[5]-t[4]*t[3])/s;e[1]=(-a*t[1]+n*t[0]+t[4]*t[1]-t[5]*t[0])/s}static axialAlignedBoundingBox(e,t,a){const n=t[0],s=t[1],r=t[2],i=t[3],o=t[4],l=t[5],f=e[0],c=e[1],h=e[2],u=e[3];let m=n*f+o,p=m,d=n*h+o,g=d,b=i*c+l,w=b,j=i*u+l,k=j;if(0!==s||0!==r){const e=s*f,t=s*h,a=r*c,n=r*u;m+=a;g+=a;d+=n;p+=n;b+=e;k+=e;j+=t;w+=t}a[0]=Math.min(a[0],m,d,p,g);a[1]=Math.min(a[1],b,j,w,k);a[2]=Math.max(a[2],m,d,p,g);a[3]=Math.max(a[3],b,j,w,k)}static inverseTransform(e){const t=e[0]*e[3]-e[1]*e[2];return[e[3]/t,-e[1]/t,-e[2]/t,e[0]/t,(e[2]*e[5]-e[4]*e[3])/t,(e[4]*e[1]-e[5]*e[0])/t]}static singularValueDecompose2dScale(e,t){const a=e[0],n=e[1],s=e[2],r=e[3],i=a**2+n**2,o=a*s+n*r,l=s**2+r**2,f=(i+l)/2,c=Math.sqrt(f**2-(i*l-o**2));t[0]=Math.sqrt(f+c||1);t[1]=Math.sqrt(f-c||1)}static normalizeRect(e){const t=e.slice(0);if(e[0]>e[2]){t[0]=e[2];t[2]=e[0]}if(e[1]>e[3]){t[1]=e[3];t[3]=e[1]}return t}static intersect(e,t){const a=Math.max(Math.min(e[0],e[2]),Math.min(t[0],t[2])),n=Math.min(Math.max(e[0],e[2]),Math.max(t[0],t[2]));if(a>n)return null;const s=Math.max(Math.min(e[1],e[3]),Math.min(t[1],t[3])),r=Math.min(Math.max(e[1],e[3]),Math.max(t[1],t[3]));return s>r?null:[a,s,n,r]}static pointBoundingBox(e,t,a){a[0]=Math.min(a[0],e);a[1]=Math.min(a[1],t);a[2]=Math.max(a[2],e);a[3]=Math.max(a[3],t)}static rectBoundingBox(e,t,a,n,s){s[0]=Math.min(s[0],e,a);s[1]=Math.min(s[1],t,n);s[2]=Math.max(s[2],e,a);s[3]=Math.max(s[3],t,n)}static#e(e,t,a,n,s,r,i,o,l,f){if(l<=0||l>=1)return;const c=1-l,h=l*l,u=h*l,m=c*(c*(c*e+3*l*t)+3*h*a)+u*n,p=c*(c*(c*s+3*l*r)+3*h*i)+u*o;f[0]=Math.min(f[0],m);f[1]=Math.min(f[1],p);f[2]=Math.max(f[2],m);f[3]=Math.max(f[3],p)}static#t(e,t,a,n,s,r,i,o,l,f,c,h){if(Math.abs(l)<1e-12){Math.abs(f)>=1e-12&&this.#e(e,t,a,n,s,r,i,o,-c/f,h);return}const u=f**2-4*c*l;if(u<0)return;const m=Math.sqrt(u),p=2*l;this.#e(e,t,a,n,s,r,i,o,(-f+m)/p,h);this.#e(e,t,a,n,s,r,i,o,(-f-m)/p,h)}static bezierBoundingBox(e,t,a,n,s,r,i,o,l){l[0]=Math.min(l[0],e,i);l[1]=Math.min(l[1],t,o);l[2]=Math.max(l[2],e,i);l[3]=Math.max(l[3],t,o);this.#t(e,a,s,i,t,n,r,o,3*(3*(a-s)-e+i),6*(e-2*a+s),3*(a-e),l);this.#t(e,a,s,i,t,n,r,o,3*(3*(n-r)-t+o),6*(t-2*n+r),3*(n-t),l)}}const na=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,728,711,710,729,733,731,730,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8226,8224,8225,8230,8212,8211,402,8260,8249,8250,8722,8240,8222,8220,8221,8216,8217,8218,8482,64257,64258,321,338,352,376,381,305,322,339,353,382,0,8364];function stringToPDFString(e,t=!1){if(e[0]>="ï"){let a;if("þ"===e[0]&&"ÿ"===e[1]){a="utf-16be";e.length%2==1&&(e=e.slice(0,-1))}else if("ÿ"===e[0]&&"þ"===e[1]){a="utf-16le";e.length%2==1&&(e=e.slice(0,-1))}else"ï"===e[0]&&"»"===e[1]&&"¿"===e[2]&&(a="utf-8");if(a)try{const n=new TextDecoder(a,{fatal:!0}),s=stringToBytes(e),r=n.decode(s);return t||!r.includes("")?r:r.replaceAll(/\x1b[^\x1b]*(?:\x1b|$)/g,"")}catch(e){warn(`stringToPDFString: "${e}".`)}}const a=[];for(let n=0,s=e.length;n[],makeMap=()=>new Map,makeObj=()=>Object.create(null),ia=Symbol("CIRCULAR_REF"),oa=Symbol("EOF");let la=Object.create(null),fa=Object.create(null),ca=Object.create(null);class Name{constructor(e){this.name=e}static get(e){return fa[e]||=new Name(e)}}class Cmd{constructor(e){this.cmd=e}static get(e){return la[e]||=new Cmd(e)}}const ha=function nonSerializableClosure(){return ha};class Dict{__nonSerializable__=ha;#a=new Map;objId=null;suppressEncryption=!1;xref;constructor(e=null){this.xref=e}assignXref(e){this.xref=e}get size(){return this.#a.size}#n(e,t,a,n){let s=this.#a.get(t);if(void 0===s&&void 0!==a){s=this.#a.get(a);void 0===s&&void 0!==n&&(s=this.#a.get(n))}return s instanceof Ref&&this.xref?e?this.xref.fetchAsync(s,this.suppressEncryption):this.xref.fetch(s,this.suppressEncryption):s}get(e,t,a){return this.#n(!1,e,t,a)}async getAsync(e,t,a){return this.#n(!0,e,t,a)}getArray(e,t,a){let n=this.#n(!1,e,t,a);if(Array.isArray(n)){n=n.slice();for(let e=0,t=n.length;e{unreachable("Should not call `set` on the empty dictionary.")};return shadow(this,"empty",e)}static merge({xref:e,dictArray:t,mergeSubDicts:a=!1}){const n=new Dict(e),s=new Map;for(const e of t)if(e instanceof Dict)for(const[t,n]of e.getRawEntries()){let e=s.get(t);if(void 0===e){e=[];s.set(t,e)}else if(!(a&&n instanceof Dict))continue;e.push(n)}for(const[t,a]of s){if(1===a.length||!(a[0]instanceof Dict)){n.set(t,a[0]);continue}const s=new Dict(e);for(const e of a)for(const[t,a]of e.getRawEntries())s.setIfNotExists(t,a);s.size>0&&n.set(t,s)}s.clear();return n.size>0?n:Dict.empty}clone(){const e=new Dict(this.xref);for(const[t,a]of this.#a)e.set(t,a);return e}delete(e){this.#a.delete(e)}}class Ref{constructor(e,t){this.num=e;this.gen=t}toString(){return 0===this.gen?`${this.num}R`:`${this.num}R${this.gen}`}static fromString(e){const t=ca[e];if(t)return t;const a=/^(\d+)R(\d*)$/.exec(e);return a&&"0"!==a[1]?ca[e]=new Ref(parseInt(a[1],10),a[2]?parseInt(a[2],10):0):null}static get(e,t){const a=0===t?`${e}R`:`${e}R${t}`;return ca[a]||=new Ref(e,t)}}class RefSet{constructor(e=null){this._set=new Set(e?._set)}has(e){return this._set.has(e.toString())}put(e){this._set.add(e.toString())}remove(e){this._set.delete(e.toString())}[Symbol.iterator](){return this._set.values()}clear(){this._set.clear()}}class RefSetCache{_map=new Map;get size(){return this._map.size}get(e){return this._map.get(e.toString())}has(e){return this._map.has(e.toString())}put(e,t){this._map.set(e.toString(),t)}putAlias(e,t){this._map.set(e.toString(),this.get(t))}[Symbol.iterator](){return this._map.values()}clear(){this._map.clear()}*values(){yield*this._map.values()}*items(){for(const[e,t]of this._map)yield[Ref.fromString(e),t]}*keys(){for(const e of this._map.keys())yield Ref.fromString(e)}}function isName(e,t){return e instanceof Name&&(void 0===t||e.name===t)}function isCmd(e,t){return e instanceof Cmd&&(void 0===t||e.cmd===t)}function isDict(e,t){return e instanceof Dict&&(void 0===t||isName(e.get("Type"),t))}function isRefsEqual(e,t){return e.num===t.num&&e.gen===t.gen}class BaseStream{get length(){unreachable("Abstract getter `length` accessed")}get isEmpty(){unreachable("Abstract getter `isEmpty` accessed")}get isDataLoaded(){return shadow(this,"isDataLoaded",!0)}getByte(){unreachable("Abstract method `getByte` called")}getBytes(e){unreachable("Abstract method `getBytes` called")}async getImageData(e,t){return this.getBytes(e,t)}async asyncGetBytes(){unreachable("Abstract method `asyncGetBytes` called")}get isAsync(){return!1}get isAsyncDecoder(){return!1}get isImageStream(){return!1}get canAsyncDecodeImageFromBuffer(){return!1}async getTransferableImage(){return null}peekByte(){const e=this.getByte();-1!==e&&this.pos--;return e}peekBytes(e){const t=this.getBytes(e);this.pos-=t.length;return t}getUint16(){const e=this.getByte(),t=this.getByte();return-1===e||-1===t?-1:(e<<8)+t}getInt32(){return(this.getByte()<<24)+(this.getByte()<<16)+(this.getByte()<<8)+this.getByte()}getByteRange(e,t){unreachable("Abstract method `getByteRange` called")}getString(e){return bytesToString(this.getBytes(e))}skip(e){this.pos+=e||1}reset(){unreachable("Abstract method `reset` called")}moveStart(){unreachable("Abstract method `moveStart` called")}makeSubStream(e,t,a=null){unreachable("Abstract method `makeSubStream` called")}getBaseStreams(){return null}getOriginalStream(){return this.stream?.getOriginalStream()||this}}const ua=/^[1-9]\.\d$/,ma=2**31-1,pa=[1,0,0,1,0,0],da=["ColorSpace","ExtGState","Font","Pattern","Properties","Shading","XObject"],ga=["ExtGState","Font","Properties","XObject"];function getLookupTableFactory(e){let t;return function(){if(e){t=Object.create(null);e(t);e=null}return t}}class MissingDataException extends aa{constructor(e,t){super(`Missing data [${e}, ${t})`,"MissingDataException");this.begin=e;this.end=t}}class ParserEOFException extends aa{constructor(e){super(e,"ParserEOFException")}}class XRefEntryException extends aa{constructor(e){super(e,"XRefEntryException")}}class XRefParseException extends aa{constructor(e){super(e,"XRefParseException")}}function arrayBuffersToBytes(e){const t=e.length;if(0===t)return new Uint8Array(0);if(1===t)return new Uint8Array(e[0]);let a=0;for(let n=0;n0,"The number should be a positive integer.");const a="M".repeat(e/1e3|0)+ba[e%1e3/100|0]+ba[10+(e%100/10|0)]+ba[20+e%10];return t?a.toLowerCase():a}function isWhiteSpace(e){return 32===e||9===e||13===e||10===e}function isNumberArray(e,t){return Array.isArray(e)?(null===t||e.length===t)&&e.every(e=>"number"==typeof e):ArrayBuffer.isView(e)&&!(e instanceof BigInt64Array||e instanceof BigUint64Array)&&(null===t||e.length===t)}function lookupMatrix(e,t){return isNumberArray(e,6)?e:t}function lookupRect(e,t){return isNumberArray(e,4)?e:t}function lookupNormalRect(e,t){return isNumberArray(e,4)?Util.normalizeRect(e):t}function parseXFAPath(e){const t=/(.+)\[(\d+)\]$/;return e.split(".").map(e=>{const a=e.match(t);return a?{name:a[1],pos:parseInt(a[2],10)}:{name:e,pos:0}})}function escapePDFName(e){const t=[];let a=0;for(let n=0,s=e.length;n126||35===s||40===s||41===s||60===s||62===s||91===s||93===s||123===s||125===s||47===s||37===s){a"\n"===e?"\\n":"\r"===e?"\\r":`\\${e}`)}function _collectJS(e,t,a,n){if(!e)return;let s=null;if(e instanceof Ref){if(n.has(e))return;s=e;n.put(s);e=t.fetch(e)}if(Array.isArray(e))for(const s of e)_collectJS(s,t,a,n);else if(e instanceof Dict){if(isName(e.get("S"),"JavaScript")){const t=e.get("JS");let n;t instanceof BaseStream?n=t.getString():"string"==typeof t&&(n=t);n&&=stringToPDFString(n,!0).replaceAll("\0","");n&&a.push(n.trim())}_collectJS(e.getRaw("Next"),t,a,n)}s&&n.remove(s)}function collectActions(e,t,a){const n=Object.create(null),s=getInheritableProperty({dict:t,key:"AA",stopWhenFound:!1});if(s)for(let t=s.length-1;t>=0;t--){const r=s[t];if(r instanceof Dict)for(const[t,s]of r.getRawEntries()){const r=a[t];if(!r)continue;const i=[];_collectJS(s,e,i,new RefSet);i.length>0&&(n[r]=i)}}if(t.has("A")){const a=[];_collectJS(t.get("A"),e,a,new RefSet);a.length>0&&(n.Action=a)}return objectSize(n)>0?n:null}const wa={60:"<",62:">",38:"&",34:""",39:"'"};function*codePointIter(e){for(let t=0,a=e.length;t55295&&(a<57344||a>65533)&&t++;yield a}}function encodeToXmlString(e){const t=[];let a=0;for(let n=0,s=e.length;n55295&&(s<57344||s>65533)&&n++;a=n+1}}if(0===t.length)return e;a: ${e}.`);return!1}return!0}function validateCSSFont(e){const t=new Set(["100","200","300","400","500","600","700","800","900","1000","normal","bold","bolder","lighter"]),{fontFamily:a,fontWeight:n,italicAngle:s}=e;if(!validateFontName(a,!0))return!1;const r=n?n.toString():"";e.fontWeight=t.has(r)?r:"400";const i=parseFloat(s);e.italicAngle=isNaN(i)||i<-90||i>90?"14":s.toString();return!0}function recoverJsURL(e){const t=new RegExp("^\\s*("+["app.launchURL","window.open","xfa.host.gotoURL"].join("|").replaceAll(".","\\.")+")\\((?:'|\")([^'\"]*)(?:'|\")(?:,\\s*(\\w+)\\)|\\))","i").exec(e);return t?.[2]?{url:t[2],newWindow:"app.launchURL"===t[1]&&"true"===t[3]}:null}function numberToString(e){if(Number.isInteger(e))return e.toString();const t=Math.round(100*e);return t%100==0?(t/100).toString():t%10==0?e.toFixed(1):e.toFixed(2)}function getNewAnnotationsMap(e){if(!e)return null;const t=new Map;for(const[a,n]of e)a.startsWith(d)&&t.getOrInsertComputed(n.pageIndex,makeArr).push(n);return t.size>0?t:null}function stringToAsciiOrUTF16BE(e){return null==e||function isAscii(e){if("string"!=typeof e)return!1;return!e||/^[\x00-\x7F]*$/.test(e)}(e)?e:stringToUTF16String(e,!0)}function stringToUTF16HexString(e){const t=[];for(let a=0,n=e.length;a>8&255],Util.hexNums[255&n])}return t.join("")}function stringToUTF16String(e,t=!1){const a=[];t&&a.push("þÿ");for(let t=0,n=e.length;t>8&255),String.fromCharCode(255&n))}return a.join("")}function getRotationMatrix(e,t,a){switch(e){case 90:return[0,1,-1,0,t,0];case 180:return[-1,0,0,-1,t,a];case 270:return[0,-1,1,0,0,a];default:throw new Error("Invalid rotation")}}function getSizeInBytes(e){return Math.ceil(Math.ceil(Math.log2(1+e))/8)}class QCMS{static#s=null;static _memory=null;static _mustAddAlpha=!1;static _destBuffer=null;static _destOffset=0;static _destLength=0;static _cssColor="";static _makeHexColor=null;static get _memoryArray(){const e=this.#s;return e?.byteLength?e:this.#s=new Uint8Array(this._memory.buffer)}}const ja=Object.freeze({RGB8:0,0:"RGB8",RGBA8:1,1:"RGBA8",BGRA8:2,2:"BGRA8",Gray8:3,3:"Gray8",GrayA8:4,4:"GrayA8",CMYK:5,5:"CMYK"}),ka=Object.freeze({Perceptual:0,0:"Perceptual",RelativeColorimetric:1,1:"RelativeColorimetric",Saturation:2,2:"Saturation",AbsoluteColorimetric:3,3:"AbsoluteColorimetric"});function __wbg_get_imports(){return{__proto__:null,"./qcms_bg.js":{__proto__:null,__wbg___wbindgen_throw_6b64449b9b9ed33c:function(e,t){throw new Error(function getStringFromWasm0(e,t){return function decodeText(e,t){Sa+=t;if(Sa>=va){qa=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});qa.decode();Sa=t}return qa.decode(getUint8ArrayMemory0().subarray(e,e+t))}(e>>>=0,t)}(e,t))},__wbg_copy_result_0d15f3bf9d9012ae:function(e,t){!function copy_result(e,t){const{_mustAddAlpha:a,_destBuffer:n,_destOffset:s,_destLength:r,_memoryArray:i}=QCMS;if(t!==r)if(a)for(let a=e,r=e+t,o=s;a>>0,t>>>0)},__wbg_copy_rgb_0106d9d9464fce43:function(e){!function copy_rgb(e){const{_destBuffer:t,_destOffset:a,_memoryArray:n}=QCMS;t[a]=n[e];t[a+1]=n[e+1];t[a+2]=n[e+2]}(e>>>0)},__wbg_make_cssRGB_8e24b34f71f5363e:function(e){!function make_cssRGB(e){const{_memoryArray:t}=QCMS;QCMS._cssColor=QCMS._makeHexColor(t[e],t[e+1],t[e+2])}(e>>>0)},__wbindgen_init_externref_table:function(){const e=xa.__wbindgen_externrefs,t=e.grow(4);e.set(0,void 0);e.set(t+0,void 0);e.set(t+1,null);e.set(t+2,!0);e.set(t+3,!1)}}}}let ya=null;function getUint8ArrayMemory0(){null!==ya&&0!==ya.byteLength||(ya=new Uint8Array(xa.memory.buffer));return ya}function passArray8ToWasm0(e,t){const a=t(1*e.length,1)>>>0;getUint8ArrayMemory0().set(e,a/1);Ca=e.length;return a}let qa=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});qa.decode();const va=2146435072;let Sa=0;let Aa,xa,Ca=0;function __wbg_finalize_init(e,t){xa=e.exports;Aa=t;ya=null;xa.__wbindgen_start();return xa}function MathClamp(e,t,a){return Math.min(Math.max(e,t),a)}function isDefaultDecodeHelper(e,t){if(!Array.isArray(e))return!0;const a=e.length;if(at){info("Truncating too long decode map.");e.length=t}return!1}class ColorSpace{static#r=new Uint8ClampedArray(3);constructor(e,t){this.name=e;this.numComps=t}getRgb(e,t,a=new Uint8ClampedArray(3)){this.getRgbItem(e,t,a,0);return a}getRgbHex(e,t){const a=this.getRgb(e,t,ColorSpace.#r);return Util.makeHexColor(a[0],a[1],a[2])}getRgbItem(e,t,a,n){unreachable("Should not call ColorSpace.getRgbItem")}getRgbBuffer(e,t,a,n,s,r,i){unreachable("Should not call ColorSpace.getRgbBuffer")}getOutputLength(e,t){unreachable("Should not call ColorSpace.getOutputLength")}isPassthrough(e){return!1}isDefaultDecode(e,t){return ColorSpace.isDefaultDecode(e,this.numComps)}fillRgb(e,t,a,n,s,r,i,o,l){const f=t*a;let c=null;const h=1<h&&"DeviceGray"!==this.name&&"DeviceRGB"!==this.name){const t=i<=8?new Uint8Array(h):new Uint16Array(h);for(let e=0;e=.99554525?1:MathClamp(1.055*e**(1/2.4)-.055,0,1)}#j(e){return e<0?-this.#j(-e):e>8?((e+16)/116)**3:e*CalRGBCS.#p}#k(e,t,a){if(0===e[0]&&0===e[1]&&0===e[2]){a[0]=t[0];a[1]=t[1];a[2]=t[2];return}const n=this.#j(0),s=(1-n)/(1-this.#j(e[0])),r=1-s,i=(1-n)/(1-this.#j(e[1])),o=1-i,l=(1-n)/(1-this.#j(e[2])),f=1-l;a[0]=t[0]*s+r;a[1]=t[1]*i+o;a[2]=t[2]*l+f}#y(e,t,a){if(1===e[0]&&1===e[2]){a[0]=t[0];a[1]=t[1];a[2]=t[2];return}const n=a;this.#d(CalRGBCS.#o,t,n);const s=CalRGBCS.#h;this.#g(e,n,s);this.#d(CalRGBCS.#l,s,a)}#q(e,t,a){const n=a;this.#d(CalRGBCS.#o,t,n);const s=CalRGBCS.#h;this.#b(e,n,s);this.#d(CalRGBCS.#l,s,a)}#i(e,t,a,n,s){const r=MathClamp(e[t]*s,0,1),i=MathClamp(e[t+1]*s,0,1),o=MathClamp(e[t+2]*s,0,1),l=1===r?1:r**this.GR,f=1===i?1:i**this.GG,c=1===o?1:o**this.GB,h=this.MXA*l+this.MXB*f+this.MXC*c,u=this.MYA*l+this.MYB*f+this.MYC*c,m=this.MZA*l+this.MZB*f+this.MZC*c,p=CalRGBCS.#u;p[0]=h;p[1]=u;p[2]=m;const d=CalRGBCS.#m;this.#y(this.whitePoint,p,d);const g=CalRGBCS.#u;this.#k(this.blackPoint,d,g);const b=CalRGBCS.#m;this.#q(CalRGBCS.#c,g,b);const w=CalRGBCS.#u;this.#d(CalRGBCS.#f,b,w);a[n]=255*this.#w(w[0]);a[n+1]=255*this.#w(w[1]);a[n+2]=255*this.#w(w[2])}getRgbItem(e,t,a,n){this.#i(e,t,a,n,1)}getRgbBuffer(e,t,a,n,s,r,i){const o=1/((1<this.amax||this.bmin>this.bmax){info("Invalid Range, falling back to defaults");this.amin=-100;this.amax=100;this.bmin=-100;this.bmax=100}}#v(e){return e>=6/29?e**3:108/841*(e-4/29)}#S(e,t,a,n){return a+e*(n-a)/t}#i(e,t,a,n,s){let r=e[t],i=e[t+1],o=e[t+2];if(!1!==a){r=this.#S(r,a,0,100);i=this.#S(i,a,this.amin,this.amax);o=this.#S(o,a,this.bmin,this.bmax)}i>this.amax?i=this.amax:ithis.bmax?o=this.bmax:ofunction qcms_convert_one(e,t,a){xa.qcms_convert_one(e,t,a)}(this.#A,255*e[t],a);break;case 3:n=ja.RGB8;this.#x=(e,t,a)=>function qcms_convert_three(e,t,a,n,s){xa.qcms_convert_three(e,t,a,n,s)}(this.#A,255*e[t],255*e[t+1],255*e[t+2],a);break;case 4:n=ja.CMYK;this.#x=(e,t,a)=>function qcms_convert_four(e,t,a,n,s,r){xa.qcms_convert_four(e,t,a,n,s,r)}(this.#A,255*e[t],255*e[t+1],255*e[t+2],255*e[t+3],a);break;default:throw new Error(`Unsupported number of components: ${a}`)}this.#A=function qcms_transformer_from_memory(e,t,a){const n=passArray8ToWasm0(e,xa.__wbindgen_malloc),s=Ca;return xa.qcms_transformer_from_memory(n,s,t,a)>>>0}(e,n,ka.Perceptual);if(!this.#A)throw new Error("Failed to create ICC color space");IccColorSpace.#F||=new FinalizationRegistry(e=>{!function qcms_drop_transformer(e){xa.qcms_drop_transformer(e)}(e)});IccColorSpace.#F.register(this,this.#A)}getRgbHex(e,t){this.#x(e,t,!0);return QCMS._cssColor}getRgbItem(e,t,a,n){QCMS._destBuffer=a;QCMS._destOffset=n;QCMS._destLength=3;this.#x(e,t,!1);QCMS._destBuffer=null}getRgbBuffer(e,t,a,n,s,r,i){e=e.subarray(t,t+a*this.numComps);if(8!==r){const t=255/((1<=this.end?-1:this.bytes[this.pos++]}getBytes(e){const t=this.bytes,a=this.pos,n=this.end;if(!e){this.pos=n;return t.subarray(a,n)}let s=a+e;s>n&&(s=n);this.pos=s;return t.subarray(a,s)}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);return this.bytes.subarray(e,t)}reset(){this.pos=this.start}moveStart(){this.start=this.pos}makeSubStream(e,t,a=null){return new Stream(this.bytes.buffer,e,t,a)}clone(){return new Stream(this.bytes.buffer,this.start,this.end-this.start,this.dict.clone())}}class StringStream extends Stream{constructor(e){super(stringToBytes(e))}}class NullStream extends Stream{constructor(){super(new Uint8Array(0))}}class ChunkedStream extends Stream{progressiveDataLength=0;_lastSuccessfulEnsureByteChunk=-1;_loadedChunks=new Set;constructor(e,t,a){super(new Uint8Array(e),0,e,null);this.chunkSize=t;this.numChunks=Math.ceil(e/t);this.manager=a}getMissingChunks(){const e=[];for(let t=0,a=this.numChunks;t=this.end?this.numChunks:Math.floor(t/this.chunkSize);for(let e=a;ethis.numChunks)&&t!==this._lastSuccessfulEnsureByteChunk){if(!this._loadedChunks.has(t))throw new MissingDataException(e,e+1);this._lastSuccessfulEnsureByteChunk=t}}ensureRange(e,t){if(e>=t)return;if(t<=this.progressiveDataLength)return;const a=Math.floor(e/this.chunkSize);if(a>this.numChunks)return;const n=Math.min(Math.floor((t-1)/this.chunkSize)+1,this.numChunks);for(let s=a;s=this.end)return-1;e>=this.progressiveDataLength&&this.ensureByte(e);return this.bytes[this.pos++]}getBytes(e){const t=this.bytes,a=this.pos,n=this.end;if(!e){n>this.progressiveDataLength&&this.ensureRange(a,n);this.pos=n;return t.subarray(a,n)}let s=a+e;s>n&&(s=n);s>this.progressiveDataLength&&this.ensureRange(a,s);this.pos=s;return t.subarray(a,s)}getByteRange(e,t){e<0&&(e=0);t>this.end&&(t=this.end);t>this.progressiveDataLength&&this.ensureRange(e,t);return this.bytes.subarray(e,t)}makeSubStream(e,t,a=null){t?e+t>this.progressiveDataLength&&this.ensureRange(e,e+t):e>=this.progressiveDataLength&&this.ensureByte(e);function ChunkedStreamSubstream(){}ChunkedStreamSubstream.prototype=Object.create(this);ChunkedStreamSubstream.prototype.getMissingChunks=function(){const e=this.chunkSize,t=Math.floor(this.start/e),a=Math.floor((this.end-1)/e)+1,n=[];for(let e=t;e0){const e=this.groupChunks(s);for(const t of e){const e=t.beginChunk*this.chunkSize,a=Math.min(t.endChunk*this.chunkSize,this.length);this.sendRequest(e,a).catch(n.reject)}}return n.promise.catch(e=>{if(!this.aborted)throw e})}getStream(){return this.stream}requestRange(e,t){t=Math.min(t,this.length);const a=this.getBeginChunk(e),n=this.getEndChunk(t),s=[];for(let e=a;ee-t);return this._requestChunks(t)}groupChunks(e){const t=[];let a=-1,n=-1;for(let s=0,r=e.length;s=0&&n+1!==r){t.push({beginChunk:a,endChunk:n+1});a=r}s+1===e.length&&t.push({beginChunk:a,endChunk:r+1});n=r}return t}onReceiveData(e){const{chunkSize:t,length:a,stream:n}=this,s=e.chunk,r=void 0===e.begin,i=r?n.progressiveDataLength:e.begin,o=i+s.byteLength,l=Math.floor(i/t),f=o0||c.push(a)}}}if(!this.disableAutoFetch&&0===this._requestsByChunk.size){let e;if(1===n.numChunksLoaded){const t=n.numChunks-1;n.hasChunk(t)||(e=t)}else e=n.nextEmptyChunk(f);Number.isInteger(e)&&this._requestChunks([e])}for(const e of c){const t=this._promisesByRequest.get(e);this._promisesByRequest.delete(e);t.resolve()}this.msgHandler.send("DocProgress",{loaded:MathClamp(n.numChunksLoaded*t,n.progressiveDataLength,a),total:a})}onError(e){this._loadedStreamCapability.reject(e)}getBeginChunk(e){return Math.floor(e/this.chunkSize)}getEndChunk(e){return Math.floor((e-1)/this.chunkSize)+1}abort(e){this.aborted=!0;this.pdfStream?.cancelAllRequests(e);for(const t of this._promisesByRequest.values())t.reject(e)}}function convertToRGBA(e){switch(e.kind){case F:return convertBlackAndWhiteToRGBA(e);case T:return function convertRGBToRGBA({src:e,srcPos:t=0,dest:a,destPos:n=0,width:s,height:r}){let i=0;const o=s*r*3,l=o>>2,f=new Uint32Array(e.buffer,t,l),c=FeatureTest.isLittleEndian?4278190080:255;if(FeatureTest.isLittleEndian){for(;i>>24|t<<8|c;a[n+2]=t>>>16|s<<16|c;a[n+3]=s>>>8|c}for(let s=4*i,r=t+o;s>>8|c;a[n+2]=t<<16|s>>>16|c;a[n+3]=s<<8|c}for(let s=4*i,r=t+o;s>3,h=7&n,u=l^f,m=e.length;a=new Uint32Array(a.buffer);let p=0;for(let n=0;n>7&1)&u;a[p+1]=l^-(n>>6&1)&u;a[p+2]=l^-(n>>5&1)&u;a[p+3]=l^-(n>>4&1)&u;a[p+4]=l^-(n>>3&1)&u;a[p+5]=l^-(n>>2&1)&u;a[p+6]=l^-(n>>1&1)&u;a[p+7]=l^-(1&n)&u}if(0===h)continue;const n=t>7-e&1)&u}return{srcPos:t,destPos:p}}class ImageResizer{static#O=2048;static#R=FeatureTest.isImageDecoderSupported;constructor(e,t){this._imgData=e;this._isMask=t}static get canUseImageDecoder(){return shadow(this,"canUseImageDecoder",this.#R?ImageDecoder.isTypeSupported("image/bmp"):Promise.resolve(!1))}static needsToBeResized(e,t){if(e<=this.#O&&t<=this.#O)return!1;const{MAX_DIM:a}=this;if(e>a||t>a)return!0;const n=e*t;if(this._hasMaxArea)return n>this.MAX_AREA;if(n(this.MAX_AREA=this.#O**2)}static getReducePowerForJPX(e,t,a){const n=e*t,s=2**30/(4*a);if(!this.needsToBeResized(e,t))return n>s?Math.ceil(Math.log2(n/s)):0;const{MAX_DIM:r,MAX_AREA:i}=this,o=Math.max(e/r,t/r,Math.sqrt(n/Math.min(s,i)));return Math.ceil(Math.log2(o))}static get MAX_DIM(){return shadow(this,"MAX_DIM",this._guessMax(2048,32768,0,1))}static get MAX_AREA(){this._hasMaxArea=!0;return shadow(this,"MAX_AREA",this._guessMax(this.#O,this.MAX_DIM,128,0)**2)}static set MAX_AREA(e){if(e>=0){this._hasMaxArea=!0;shadow(this,"MAX_AREA",e)}}static setOptions({canvasMaxAreaInBytes:e=-1,isImageDecoderSupported:t=!1}){this._hasMaxArea||(this.MAX_AREA=e>>2);this.#R=t}static _areGoodDims(e,t){try{const a=new OffscreenCanvas(e,t),n=a.getContext("2d");n.fillRect(0,0,1,1);const s=n.getImageData(0,0,1,1).data[3];a.width=a.height=1;return 0!==s}catch{return!1}}static _guessMax(e,t,a,n){for(;e+a+1ma){const e=this.#H();if(e)return e}const n=this._encodeBMP();let s,r;if(await ImageResizer.canUseImageDecoder){s=new ImageDecoder({data:n,type:"image/bmp",preferAnimation:!1,transfer:[n.buffer]});r=s.decode().catch(e=>{warn(`BMP image decoding failed: ${e}`);return createImageBitmap(new Blob([this._encodeBMP().buffer],{type:"image/bmp"}))}).finally(()=>{s.close()})}else r=createImageBitmap(new Blob([n.buffer],{type:"image/bmp"}));const{MAX_AREA:i,MAX_DIM:o}=ImageResizer,l=Math.max(t/o,a/o,Math.sqrt(t*a/i)),f=Math.max(l,2),c=Math.round(10*(l+1.25))/10/f,h=Math.floor(Math.log2(c)),u=new Array(h+2).fill(2);u[0]=f;u.splice(-1,1,c/(1<>i,l=n>>i;let f,c=n;try{f=new Uint8Array(r)}catch{let e=Math.floor(Math.log2(r+1));for(;;)try{f=new Uint8Array(2**e-1);break}catch{e-=1}c=Math.floor((2**e-1)/(4*a));const t=a*c*4;t>i;e>3,i=a+3&-4;if(a!==i){const e=new Uint8Array(i*t);let n=0;for(let r=0,o=t*a;r{throw t},a=import.meta.url;try{new URL(".",a).href}catch{}0;console.log.bind(console);var n,s,r,i,o,l=console.error.bind(console),f=!1,c=!1;function updateMemoryViews(){var e=u.buffer;i=new Int8Array(e);new Int16Array(e);o=new Uint8Array(e);new Uint16Array(e);new Int32Array(e);new Uint32Array(e);new Float32Array(e);new Float64Array(e);new BigInt64Array(e);new BigUint64Array(e)}class ExitStatus{name="ExitStatus";constructor(e){this.message=`Program terminated with exit(${e})`;this.status=e}}var h,u,callRuntimeCallbacks=e=>{for(;e.length>0;)e.shift()(t)},m=[],addOnPostRun=e=>m.push(e),p=[],addOnPreRun=e=>p.push(e),d=!0,g=0,b={},handleException=e=>{if(e instanceof ExitStatus||"unwind"==e)return n;quit_(0,e)},keepRuntimeAlive=()=>d||g>0,_proc_exit=e=>{n=e;if(!keepRuntimeAlive()){t.onExit?.(e);f=!0}quit_(0,new ExitStatus(e))},_exit=(e,t)=>{n=e;_proc_exit(e)},callUserCallback=e=>{if(!f)try{return e()}catch(e){handleException(e)}finally{(()=>{if(!keepRuntimeAlive())try{_exit(n)}catch(e){handleException(e)}})()}},alignMemory=(e,t)=>Math.ceil(e/t)*t,growMemory=e=>{var t=(e-u.buffer.byteLength+65535)/65536|0;try{u.grow(t);updateMemoryViews();return 1}catch(e){}};t.noExitRuntime&&(d=t.noExitRuntime);t.print&&t.print;t.printErr&&(l=t.printErr);t.wasmBinary&&t.wasmBinary;t.arguments&&t.arguments;t.thisProgram&&t.thisProgram;if(t.preInit){"function"==typeof t.preInit&&(t.preInit=[t.preInit]);for(;t.preInit.length>0;)t.preInit.shift()()}t.writeArrayToMemory=(e,t)=>{i.set(e,t)};var w,j={e:()=>function abort(e){t.onAbort?.(e);l(e="Aborted("+e+")");f=!0;e+=". Build with -sASSERTIONS for more info.";var a=new WebAssembly.RuntimeError(e);r?.(a);throw a}(""),b:()=>{d=!1;g=0},c:(e,t)=>{if(b[e]){clearTimeout(b[e].id);delete b[e]}if(!t)return 0;var a=setTimeout(()=>{delete b[e];callUserCallback(()=>h(e,performance.now()))},t);b[e]={id:a,timeout_ms:t};return 0},g:function _createImageData(e){t.imageData=new Uint8Array(e)},d:e=>{var t=o.length,a=2147483648;if((e>>>=0)>a)return!1;for(var n=1;n<=4;n*=2){var s=t*(1+.2/n);s=Math.min(s,e+100663296);var r=Math.min(a,alignMemory(Math.max(e,s),65536));if(growMemory(r))return!0}return!1},a:_proc_exit,h:function _setImageData(e,a,n,s){if(n===a){t.imageData=new Uint8ClampedArray(o.subarray(e,e+n*s));return}const r=a*s,i=t.imageData=new Uint8ClampedArray(r);for(let t=e,s=0;s{t.instantiateWasm(e,(e,t)=>{a(receiveInstance(e))})})}();!function run(){!function preRun(){if(t.preRun){"function"==typeof t.preRun&&(t.preRun=[t.preRun]);for(;t.preRun.length;)addOnPreRun(t.preRun.shift())}callRuntimeCallbacks(p)}();function doRun(){t.calledRun=!0;if(!f){!function initRuntime(){c=!0;w.j()}();s?.(t);t.onRuntimeInitialized?.();!function postRun(){if(t.postRun){"function"==typeof t.postRun&&(t.postRun=[t.postRun]);for(;t.postRun.length;)addOnPostRun(t.postRun.shift())}callRuntimeCallbacks(m)}()}}if(t.setStatus){t.setStatus("Running...");setTimeout(()=>{setTimeout(()=>t.setStatus(""),1);doRun()},1)}else doRun()}();return c?t:new Promise((e,t)=>{s=e;r=t})};class Jbig2Error extends aa{constructor(e){super(e,"Jbig2Error")}}class JBig2CCITTFaxImage{static#B=null;static#D=null;static#M=null;static#C=!0;static#N=!0;static#I=null;static setOptions({handler:e,useWasm:t,useWorkerFetch:a,wasmUrl:n}){this.#C=t;this.#N=a;this.#I=n;a||(this.#D=e)}static async#P(e){const t=`${this.#I}jbig2_nowasm_fallback.js`;let a=null;try{a=(await import( +/*webpackIgnore: true*/ +/*@vite-ignore*/ +t)).default()}catch(e){warn(`JBig2CCITTFaxImage#getJsModule: ${e}`)}e(a)}static async#E(e,t,a){const n="jbig2.wasm";try{this.#B||(this.#N?this.#B=await fetchBinaryData(`${this.#I}${n}`):this.#B=await this.#D.sendWithPromise("FetchBinaryData",{kind:"wasmUrl",filename:n}));return a((await WebAssembly.instantiate(this.#B,t)).instance)}catch(t){warn(`JBig2CCITTFaxImage#instantiateWasm: ${t}`);this.#P(e);return null}finally{this.#D=null}}static async decode(e,t,a,n,s){if(!this.#M){const{promise:e,resolve:t}=Promise.withResolvers(),a=[e];this.#C?a.push(Ia({warn,instantiateWasm:this.#E.bind(this,t)})):this.#P(t);this.#M=Promise.race(a)}const r=await this.#M;if(!r)throw new Jbig2Error("JBig2 failed to initialize");let i,o;try{const l=e.length;i=r._malloc(l);r.writeArrayToMemory(e,i);if(s)r._ccitt_decode(i,l,t,a,s.K,s.EndOfLine?1:0,s.EncodedByteAlign?1:0,s.BlackIs1?1:0,s.Columns,s.Rows);else{const e=n?n.length:0;if(e>0){o=r._malloc(e);r.writeArrayToMemory(n,o)}r._jbig2_decode(i,l,t,a,o,e)}if(!r.imageData)throw new Jbig2Error("Unknown error");const{imageData:f}=r;r.imageData=null;return f}finally{i&&r._free(i);o&&r._free(o)}}static cleanup(){this.#M=null}}const Fa=new Uint8Array(0);class DecodeStream extends BaseStream{constructor(e){super();this._rawMinBufferLength=e||0;this.pos=0;this.bufferLength=0;this.eof=!1;this.buffer=Fa;this.minBufferLength=512;if(e)for(;this.minBufferLengths&&(n=s)}else{for(;!this.eof;)this.readBlock(t);n=this.bufferLength}this.pos=n;return this.buffer.subarray(a,n)}async getImageData(e,t){if(!this.canAsyncDecodeImageFromBuffer)return this.isAsyncDecoder?this.decodeImage(null,e,t):this.getBytes(e,t);const a=await this.stream.asyncGetBytes();return this.decodeImage(a,e,t)}async asyncGetBytesFromDecompressionStream(e){this.stream.reset();const t=this.stream.isAsync?await this.stream.asyncGetBytes():this.stream.getBytes();try{const{readable:a,writable:n}=new DecompressionStream(e),s=n.getWriter();await s.ready;s.write(t).then(async()=>{await s.ready;await s.close()}).catch(()=>{});const r=[];let i=0;for await(const e of a){r.push(e);i+=e.byteLength}const o=new Uint8Array(i);let l=0;for(const e of r){o.set(e,l);l+=e.byteLength}return{decompressed:o,compressed:t}}catch{return{decompressed:null,compressed:t}}}reset(){this.pos=0}makeSubStream(e,t,a=null){if(void 0===t)for(;!this.eof;)this.readBlock();else{const a=e+t;for(;this.bufferLength<=a&&!this.eof;)this.readBlock()}return new Stream(this.buffer,e,t,a)}getBaseStreams(){return this.stream?this.stream.getBaseStreams():null}clone(){for(;!this.eof;)this.readBlock();return new Stream(this.buffer,this.start,this.end-this.start,this.dict.clone())}}class StreamsSequenceStream extends DecodeStream{constructor(e,t=null){e=e.filter(e=>e instanceof BaseStream&&!e.isImageStream);let a=0;for(const t of e)a+=t instanceof DecodeStream?t._rawMinBufferLength:t.length;super(a);this.streams=e;this._onError=t}readBlock(){const e=this.streams;if(0===e.length){this.eof=!0;return}const t=e.shift();let a;try{a=t.getBytes()}catch(e){if(this._onError){this._onError(e,t.dict?.objId);return}throw e}const n=this.bufferLength,s=n+a.length;this.ensureBuffer(s).set(a,n);this.bufferLength=s}getBaseStreams(){const e=[];for(const t of this.streams){const a=t.getBaseStreams();a&&e.push(...a)}return e.length>0?e:null}}class ColorSpaceUtils{static parse({cs:e,xref:t,resources:a=null,pdfFunctionFactory:n,globalColorSpaceCache:s,localColorSpaceCache:r,asyncIfNotCached:i=!1}){const o={xref:t,resources:a,pdfFunctionFactory:n,globalColorSpaceCache:s,localColorSpaceCache:r};let l,f,c;if(e instanceof Ref){f=e;const a=s.getByRef(f)||r.getByRef(f);if(a)return a;e=t.fetch(e)}if(e instanceof Name){l=e.name;const t=r.getByName(l);if(t)return t}try{c=this.#_(e,o)}catch(e){if(i&&!(e instanceof MissingDataException))return Promise.reject(e);throw e}if(l||f){r.set(l,f,c);f&&s.set(null,f,c)}return i?Promise.resolve(c):c}static#z(e,t){const{globalColorSpaceCache:a}=t;let n;if(e instanceof Ref){n=e;const t=a.getByRef(n);if(t)return t}const s=this.#_(e,t);n&&a.set(null,n,s);return s}static#_(e,t){const{xref:a,resources:n,pdfFunctionFactory:s,globalColorSpaceCache:r}=t;if((e=a.fetchIfRef(e))instanceof Name)switch(e.name){case"G":case"DeviceGray":return this.gray;case"RGB":case"DeviceRGB":return this.rgb;case"DeviceRGBA":return this.rgba;case"CMYK":case"DeviceCMYK":return this.cmyk;case"Pattern":return new PatternCS(null);default:if(n instanceof Dict){const a=n.get("ColorSpace");if(a instanceof Dict){const n=a.get(e.name);if(n){if(n instanceof Name)return this.#_(n,t);e=n;break}}}warn(`Unrecognized ColorSpace: ${e.name}`);return this.gray}if(Array.isArray(e)){const n=a.fetchIfRef(e[0]).name;let i,o,l,f,c,h;switch(n){case"G":case"DeviceGray":return this.gray;case"RGB":case"DeviceRGB":return this.rgb;case"CMYK":case"DeviceCMYK":return this.cmyk;case"CalGray":i=a.fetchIfRef(e[1]);f=i.getArray("WhitePoint");c=i.getArray("BlackPoint");h=i.get("Gamma");return new CalGrayCS(f,c,h);case"CalRGB":i=a.fetchIfRef(e[1]);f=i.getArray("WhitePoint");c=i.getArray("BlackPoint");h=i.getArray("Gamma");const u=i.getArray("Matrix");return new CalRGBCS(f,c,h,u);case"ICCBased":const m=e[1]instanceof Ref;if(m){const t=r.getByRef(e[1]);if(t)return t}const p=a.fetchIfRef(e[1]),d=p.dict;o=d.get("N");if(IccColorSpace.isUsable)try{const t=new IccColorSpace(p.getBytes(),"ICCBased",o);m&&r.set(null,e[1],t);return t}catch(t){if(t instanceof MissingDataException)throw t;warn(`ICCBased color space (${e[1]}): "${t}".`)}const g=d.getRaw("Alternate");if(g){const e=this.#z(g,t);if(e.numComps===o)return e;warn("ICCBased color space: Ignoring incorrect /Alternate entry.")}if(1===o)return this.gray;if(3===o)return this.rgb;if(4===o)return this.cmyk;break;case"Pattern":l=e[1]||null;l&&(l=this.#z(l,t));return new PatternCS(l);case"I":case"Indexed":l=this.#z(e[1],t);const b=MathClamp(a.fetchIfRef(e[2]),0,255),w=a.fetchIfRef(e[3]);return new IndexedCS(l,b,w);case"Separation":case"DeviceN":const j=a.fetchIfRef(e[1]);o=Array.isArray(j)?j.length:1;l=this.#z(e[2],t);const k=s.create(e[3]);return new AlternateCS(o,l,k);case"Lab":i=a.fetchIfRef(e[1]);f=i.getArray("WhitePoint");c=i.getArray("BlackPoint");const y=i.getArray("Range");return new LabCS(f,c,y);default:warn(`Unimplemented ColorSpace object: ${n}`);return this.gray}}warn(`Unrecognized ColorSpace object: ${e}`);return this.gray}static get gray(){return shadow(this,"gray",new DeviceGrayCS)}static get rgb(){return shadow(this,"rgb",new DeviceRgbCS)}static get rgba(){return shadow(this,"rgba",new DeviceRgbaCS)}static get cmyk(){if(CmykICCBasedCS.isUsable)try{return shadow(this,"cmyk",new CmykICCBasedCS)}catch{warn("CMYK fallback: DeviceCMYK")}return shadow(this,"cmyk",new DeviceCmykCS)}}class JpegError extends aa{constructor(e){super(e,"JpegError")}}class DNLMarkerError extends aa{constructor(e,t){super(e,"DNLMarkerError");this.scanLines=t}}class EOIMarkerError extends aa{constructor(e){super(e,"EOIMarkerError")}}const Ta=new Uint8Array([0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63]),Oa=4017,Ra=799,Ha=3406,Ba=2276,Da=1567,Ma=3784,Na=5793,Pa=2896;function buildHuffmanTable(e,t){let a,n,s=0,r=16;for(;r>0&&!e[r-1];)r--;const i=[{children:[],index:0}];let o,l=i[0];for(a=0;a0;)l=i.pop();l.index++;i.push(l);for(;i.length<=a;){i.push(o={children:[],index:0});l.children[l.index]=o.children;l=o}s++}if(a+10){d--;return p>>d&1}p=e[a++];if(255===p){const s=e[a++];if(s){if(220===s&&c){a+=2;const e=t.getUint16(a);a+=2;if(e>0&&e!==n.scanLines)throw new DNLMarkerError("Found DNL marker (0xFFDC) while parsing scan data",e)}else if(217===s){if(c){const e=j*(8===n.precision?8:0);if(e>0&&Math.round(n.scanLines/e)>=5)throw new DNLMarkerError("Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter",e)}throw new EOIMarkerError("Found EOI marker (0xFFD9) while parsing scan data")}throw new JpegError(`unexpected marker ${(p<<8|s).toString(16)}`)}}d=7;return p>>>7}function decodeHuffman(e){let t=e;for(;;){t=t[readBit()];switch(typeof t){case"number":return t;case"object":continue}throw new JpegError("invalid huffman sequence")}}function receive(e){let t=0;for(;e>0;){t=t<<1|readBit();e--}return t}function receiveAndExtend(e){if(1===e)return 1===readBit()?1:-1;const t=receive(e);return t>=1<0){g--;return}let a=i;const n=o;for(;a<=n;){const n=decodeHuffman(e.huffmanTableAC),s=15&n,r=n>>4;if(0===s){if(r<15){g=receive(r)+(1<>4;if(0===s)if(l<15){g=receive(l)+(1<>4;if(0===n){if(r<15)break;s+=16;continue}s+=r;const i=Ta[s];e.blockData[t+i]=receiveAndExtend(n);s++}};let F,T=0;const O=1===k?s[0].blocksPerLine*s[0].blocksPerColumn:h*n.mcusPerColumn;let R,H;for(;T<=O;){const n=r?Math.min(O-T,r):O;if(n>0){for(q=0;q0?"unexpected":"excessive"} MCU data, current marker is: ${F.invalid}`);a=F.offset}if(!(F.marker>=65488&&F.marker<=65495))break;a+=2}return a-m}function quantizeAndInverse(e,t,a){const n=e.quantizationTable,s=e.blockData;let r,i,o,l,f,c,h,u,m,p,d,g,b,w,j,k,y;if(!n)throw new JpegError("missing required Quantization Table.");for(let e=0;e<64;e+=8){m=s[t+e];p=s[t+e+1];d=s[t+e+2];g=s[t+e+3];b=s[t+e+4];w=s[t+e+5];j=s[t+e+6];k=s[t+e+7];m*=n[e];if(0!==(p|d|g|b|w|j|k)){p*=n[e+1];d*=n[e+2];g*=n[e+3];b*=n[e+4];w*=n[e+5];j*=n[e+6];k*=n[e+7];r=Na*m+128>>8;i=Na*b+128>>8;o=d;l=j;f=Pa*(p-k)+128>>8;u=Pa*(p+k)+128>>8;c=g<<4;h=w<<4;r=r+i+1>>1;i=r-i;y=o*Ma+l*Da+128>>8;o=o*Da-l*Ma+128>>8;l=y;f=f+h+1>>1;h=f-h;u=u+c+1>>1;c=u-c;r=r+l+1>>1;l=r-l;i=i+o+1>>1;o=i-o;y=f*Ba+u*Ha+2048>>12;f=f*Ha-u*Ba+2048>>12;u=y;y=c*Ra+h*Oa+2048>>12;c=c*Oa-h*Ra+2048>>12;h=y;a[e]=r+u;a[e+7]=r-u;a[e+1]=i+h;a[e+6]=i-h;a[e+2]=o+c;a[e+5]=o-c;a[e+3]=l+f;a[e+4]=l-f}else{y=Na*m+512>>10;a[e]=y;a[e+1]=y;a[e+2]=y;a[e+3]=y;a[e+4]=y;a[e+5]=y;a[e+6]=y;a[e+7]=y}}for(let e=0;e<8;++e){m=a[e];p=a[e+8];d=a[e+16];g=a[e+24];b=a[e+32];w=a[e+40];j=a[e+48];k=a[e+56];if(0!==(p|d|g|b|w|j|k)){r=Na*m+2048>>12;i=Na*b+2048>>12;o=d;l=j;f=Pa*(p-k)+2048>>12;u=Pa*(p+k)+2048>>12;c=g;h=w;r=4112+(r+i+1>>1);i=r-i;y=o*Ma+l*Da+2048>>12;o=o*Da-l*Ma+2048>>12;l=y;f=f+h+1>>1;h=f-h;u=u+c+1>>1;c=u-c;r=r+l+1>>1;l=r-l;i=i+o+1>>1;o=i-o;y=f*Ba+u*Ha+2048>>12;f=f*Ha-u*Ba+2048>>12;u=y;y=c*Ra+h*Oa+2048>>12;c=c*Oa-h*Ra+2048>>12;h=y;m=r+u;k=r-u;p=i+h;j=i-h;d=o+c;w=o-c;g=l+f;b=l-f;m<16?m=0:m>=4080?m=255:m>>=4;p<16?p=0:p>=4080?p=255:p>>=4;d<16?d=0:d>=4080?d=255:d>>=4;g<16?g=0:g>=4080?g=255:g>>=4;b<16?b=0:b>=4080?b=255:b>>=4;w<16?w=0:w>=4080?w=255:w>>=4;j<16?j=0:j>=4080?j=255:j>>=4;k<16?k=0:k>=4080?k=255:k>>=4;s[t+e]=m;s[t+e+8]=p;s[t+e+16]=d;s[t+e+24]=g;s[t+e+32]=b;s[t+e+40]=w;s[t+e+48]=j;s[t+e+56]=k}else{y=Na*m+8192>>14;y=y<-2040?0:y>=2024?255:y+2056>>4;s[t+e]=y;s[t+e+8]=y;s[t+e+16]=y;s[t+e+24]=y;s[t+e+32]=y;s[t+e+40]=y;s[t+e+48]=y;s[t+e+56]=y}}}function buildComponentData(e,t){const a=t.blocksPerLine,n=t.blocksPerColumn,s=new Int16Array(64);for(let e=0;e=s)return null;const i=t.getUint16(a);if(i>=65472&&i<=65534)return{invalid:null,marker:i,offset:a};let o=t.getUint16(r);for(;!(o>=65472&&o<=65534);){if(++r>=s)return null;o=t.getUint16(r)}return{invalid:i.toString(16),marker:o,offset:r}}function prepareComponents(e){const t=Math.ceil(e.samplesPerLine/8/e.maxH),a=Math.ceil(e.scanLines/8/e.maxV);for(const n of e.components){const s=Math.ceil(Math.ceil(e.samplesPerLine/8)*n.h/e.maxH),r=Math.ceil(Math.ceil(e.scanLines/8)*n.v/e.maxV),i=t*n.h,o=64*(a*n.v)*(i+1);n.blockData=new Int16Array(o);n.blocksPerLine=s;n.blocksPerColumn=r}e.mcusPerLine=t;e.mcusPerColumn=a}function readDataBlock(e,t,a){const n=t.getUint16(a);let s=(a+=2)+n-2;const r=findNextFileMarker(e,t,s,a);if(r?.invalid){warn("readDataBlock - incorrect length, current marker is: "+r.invalid);s=r.offset}const i=e.subarray(a,s);return{appData:i,oldOffset:a,newOffset:a+i.length}}function skipData(e,t,a){const n=t.getUint16(a),s=(a+=2)+n-2,r=findNextFileMarker(e,t,s,a);return r?.invalid?r.offset:s}class JpegImage{constructor({decodeTransform:e=null,colorTransform:t=-1}={}){this._decodeTransform=e;this._colorTransform=t}static canUseImageDecoder(e,t=-1){const a=new DataView(e.buffer,e.byteOffset,e.byteLength);let n=null,s=0,r=null,i=a.getUint16(s);s+=2;if(65496!==i)throw new JpegError("SOI not found");i=a.getUint16(s);s+=2;e:for(;65497!==i;){switch(i){case 65505:const{appData:t,oldOffset:o,newOffset:l}=readDataBlock(e,a,s);s=l;if(69===t[0]&&120===t[1]&&105===t[2]&&102===t[3]&&0===t[4]&&0===t[5]){if(n)throw new JpegError("Duplicate EXIF-blocks found.");n={exifStart:o+6,exifEnd:l}}i=a.getUint16(s);s+=2;continue;case 65472:case 65473:case 65474:r=e[s+7];break e;case 65535:255!==e[s]&&s--}s=skipData(e,a,s);i=a.getUint16(s);s+=2}return 4===r||3===r&&0===t?null:n||{}}parse(e,{dnlScanLines:t=null}={}){const a=new DataView(e.buffer,e.byteOffset,e.byteLength),n=e.length-1;let s,r,i=0,o=null,l=null,f=0;const c=[],h=[],u=[];let m=a.getUint16(i);i+=2;if(65496!==m)throw new JpegError("SOI not found");m=a.getUint16(i);i+=2;e:for(;65497!==m;){let p,d,g;switch(m){case 65504:case 65505:case 65506:case 65507:case 65508:case 65509:case 65510:case 65511:case 65512:case 65513:case 65514:case 65515:case 65516:case 65517:case 65518:case 65519:case 65534:const{appData:b,newOffset:w}=readDataBlock(e,a,i);i=w;65504===m&&74===b[0]&&70===b[1]&&73===b[2]&&70===b[3]&&0===b[4]&&(o={version:{major:b[5],minor:b[6]},densityUnits:b[7],xDensity:b[8]<<8|b[9],yDensity:b[10]<<8|b[11],thumbWidth:b[12],thumbHeight:b[13],thumbData:b.subarray(14,14+3*b[12]*b[13])});65518===m&&65===b[0]&&100===b[1]&&111===b[2]&&98===b[3]&&101===b[4]&&(l={version:b[5]<<8|b[6],flags0:b[7]<<8|b[8],flags1:b[9]<<8|b[10],transformCode:b[11]});break;case 65499:const j=a.getUint16(i);i+=2;const k=j+i-2;let y;for(;i>4){if(t>>4!=1)throw new JpegError("DQT - invalid table spec");for(d=0;d<64;d++){y=Ta[d];n[y]=a.getUint16(i);i+=2}}else for(d=0;d<64;d++){y=Ta[d];n[y]=e[i++]}c[15&t]=n}break;case 65472:case 65473:case 65474:if(s)throw new JpegError("Only single frame JPEGs supported");i+=2;s={};s.extended=65473===m;s.progressive=65474===m;s.precision=e[i++];const q=a.getUint16(i);i+=2;s.scanLines=t||q;s.samplesPerLine=a.getUint16(i);i+=2;s.components=[];s.componentIds={};const v=e[i++];let S=0,x=0;for(p=0;p>4,n=15&e[i+1];S>4?h:u)[15&t]=buildHuffmanTable(a,s)}break;case 65501:i+=2;r=a.getUint16(i);i+=2;break;case 65498:const F=1===++f&&!t;i+=2;const T=e[i++],O=[];for(p=0;p>4];n.huffmanTableAC=h[15&r];O.push(n)}const R=e[i++],H=e[i++],D=e[i++];try{i+=decodeScan(e,a,i,s,O,r,R,H,D>>4,15&D,F)}catch(t){if(t instanceof DNLMarkerError){warn(`${t.message} -- attempting to re-parse the JPEG image.`);return this.parse(e,{dnlScanLines:t.scanLines})}if(t instanceof EOIMarkerError){warn(`${t.message} -- ignoring the rest of the image data.`);break e}throw t}break;case 65500:i+=4;break;case 65535:255!==e[i]&&i--;break;default:const M=findNextFileMarker(e,a,i-2,i-3);if(M?.invalid){warn("JpegImage.parse - unexpected data, current marker is: "+M.invalid);i=M.offset;break}if(!M||i>=n){warn("JpegImage.parse - reached the end of the image data without finding an EOI marker (0xFFD9).");break e}throw new JpegError("JpegImage.parse - unknown marker: "+m.toString(16))}if(i>8)+v[m+1];return j}get _isColorConversionNeeded(){return this.adobe?!!this.adobe.transformCode:3===this.numComponents?0!==this._colorTransform&&(82!==this.components[0].index||71!==this.components[1].index||66!==this.components[2].index):1===this._colorTransform}_convertYccToRgb(e){let t,a,n;for(let s=0,r=e.length;s4)throw new JpegError("Unsupported color mode");const r=this._getLinearizedBlockData(e,t,s);if(1===this.numComponents&&(a||n)){const e=r.length*(a?4:3),t=new Uint8ClampedArray(e);let n=0;if(a)!function grayToRGBA(e,t){if(FeatureTest.isLittleEndian)for(let a=0,n=e.length;a0&&(e=e.subarray(t));break}return e}decodeImage(e){if(this.eof)return this.buffer;e=this.#L(e||this.bytes);const t=new JpegImage(this.jpegOptions);t.parse(e);const a=t.getData({width:this.drawWidth,height:this.drawHeight,forceRGBA:this.forceRGBA,forceRGB:this.forceRGB,isSourcePDF:!0});this.buffer=a;this.bufferLength=a.length;this.eof=!0;return this.buffer}get canAsyncDecodeImageFromBuffer(){return this.stream.isAsync}async getTransferableImage(){if(!await JpegStream.canUseImageDecoder)return null;const e=this.jpegOptions;if(e.decodeTransform)return null;let t;try{const a=this.canAsyncDecodeImageFromBuffer&&await this.stream.asyncGetBytes()||this.bytes;if(!a)return null;let n=this.#L(a);const s=JpegImage.canUseImageDecoder(n,e.colorTransform);if(!s)return null;if(s.exifStart){n=n.slice();n.fill(0,s.exifStart,s.exifEnd)}t=new ImageDecoder({data:n,type:"image/jpeg",preferAnimation:!1});return(await t.decode()).image}catch(e){warn(`getTransferableImage - failed: "${e}".`);return null}finally{t?.close()}}get isImageStream(){return!0}}const Ea=async function OpenJPEG(e={}){var t=e,a="./this.program",quit_=(e,t)=>{throw t},n=import.meta.url;try{new URL(".",n).href}catch{}0;var s,r,i,o,l,f,c,h=console.log.bind(console),u=console.error.bind(console),m=!1,p=!1;function updateMemoryViews(){var e=g.buffer;l=new Int8Array(e);new Int16Array(e);c=new Uint8Array(e);new Uint16Array(e);o=new Int32Array(e);f=new Uint32Array(e);new Float32Array(e);new Float64Array(e);new BigInt64Array(e);new BigUint64Array(e)}class ExitStatus{name="ExitStatus";constructor(e){this.message=`Program terminated with exit(${e})`;this.status=e}}var d,g,callRuntimeCallbacks=e=>{for(;e.length>0;)e.shift()(t)},b=[],addOnPostRun=e=>b.push(e),w=[],addOnPreRun=e=>w.push(e),j=!0,k=0,y={},handleException=e=>{if(e instanceof ExitStatus||"unwind"==e)return s;quit_(0,e)},keepRuntimeAlive=()=>j||k>0,_proc_exit=e=>{s=e;if(!keepRuntimeAlive()){t.onExit?.(e);m=!0}quit_(0,new ExitStatus(e))},_exit=(e,t)=>{s=e;_proc_exit(e)},callUserCallback=e=>{if(!m)try{return e()}catch(e){handleException(e)}finally{(()=>{if(!keepRuntimeAlive())try{_exit(s)}catch(e){handleException(e)}})()}},alignMemory=(e,t)=>Math.ceil(e/t)*t,growMemory=e=>{var t=(e-g.buffer.byteLength+65535)/65536|0;try{g.grow(t);updateMemoryViews();return 1}catch(e){}},q={},getEnvStrings=()=>{if(!getEnvStrings.strings){var e={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:(globalThis.navigator?.language??"C").replace("-","_")+".UTF-8",_:a||"./this.program"};for(var t in q)void 0===q[t]?delete e[t]:e[t]=q[t];var n=[];for(var t in e)n.push(`${t}=${e[t]}`);getEnvStrings.strings=n}return getEnvStrings.strings},stringToUTF8=(e,t,a)=>((e,t,a,n)=>{if(!(n>0))return 0;for(var s=a,r=a+n-1,i=0;i=r)break;t[a++]=o}else if(o<=2047){if(a+1>=r)break;t[a++]=192|o>>6;t[a++]=128|63&o}else if(o<=65535){if(a+2>=r)break;t[a++]=224|o>>12;t[a++]=128|o>>6&63;t[a++]=128|63&o}else{if(a+3>=r)break;t[a++]=240|o>>18;t[a++]=128|o>>12&63;t[a++]=128|o>>6&63;t[a++]=128|63&o;i++}}t[a]=0;return a-s})(e,c,t,a),lengthBytesUTF8=e=>{for(var t=0,a=0;a=55296&&n<=57343){t+=4;++a}else t+=3}return t},v=[null,[],[]],S=globalThis.TextDecoder&&new TextDecoder,UTF8ArrayToString=(e,t=0,a,n)=>{var s=((e,t,a,n)=>{var s=t+a;if(n)return s;for(;e[t]&&!(t>=s);)++t;return t})(e,t,a,n);if(s-t>16&&e.buffer&&S)return S.decode(e.subarray(t,s));for(var r="";t>10,56320|1023&f)}}else r+=String.fromCharCode((31&i)<<6|o)}else r+=String.fromCharCode(i)}return r},printChar=(e,t)=>{var a=v[e];if(0===t||10===t){(1===e?h:u)(UTF8ArrayToString(a));a.length=0}else a.push(t)},UTF8ToString=(e,t,a)=>e?UTF8ArrayToString(c,e,t,a):"";t.noExitRuntime&&(j=t.noExitRuntime);t.print&&(h=t.print);t.printErr&&(u=t.printErr);t.wasmBinary&&t.wasmBinary;t.arguments&&t.arguments;t.thisProgram&&(a=t.thisProgram);if(t.preInit){"function"==typeof t.preInit&&(t.preInit=[t.preInit]);for(;t.preInit.length>0;)t.preInit.shift()()}t.writeArrayToMemory=(e,t)=>{l.set(e,t)};var x,C={m:()=>function abort(e){t.onAbort?.(e);u(e=`Aborted(${e})`);m=!0;e+=". Build with -sASSERTIONS for more info.";var a=new WebAssembly.RuntimeError(e);i?.(a);throw a}(""),l:()=>{j=!1;k=0},i:(e,t)=>{if(y[e]){clearTimeout(y[e].id);delete y[e]}if(!t)return 0;var a=setTimeout(()=>{delete y[e];callUserCallback(()=>d(e,performance.now()))},t);y[e]={id:a,timeout_ms:t};return 0},f:function _copy_pixels_1(e,a){e>>=2;const n=t.imageData=new Uint8ClampedArray(a),s=o.subarray(e,e+a);n.set(s)},e:function _copy_pixels_3(e,a,n,s){e>>=2;a>>=2;n>>=2;const r=t.imageData=new Uint8ClampedArray(3*s),i=o.subarray(e,e+s),l=o.subarray(a,a+s),f=o.subarray(n,n+s);for(let e=0;e>=2;a>>=2;n>>=2;s>>=2;const i=t.imageData=new Uint8ClampedArray(4*r),l=o.subarray(e,e+r),f=o.subarray(a,a+r),c=o.subarray(n,n+r),h=o.subarray(s,s+r);for(let e=0;e{var t=c.length,a=2147483648;if((e>>>=0)>a)return!1;for(var n=1;n<=4;n*=2){var s=t*(1+.2/n);s=Math.min(s,e+100663296);var r=Math.min(a,alignMemory(Math.max(e,s),65536));if(growMemory(r))return!0}return!1},o:(e,t)=>{var a=0,n=0;for(var s of getEnvStrings()){var r=t+a;f[e+n>>2]=r;a+=stringToUTF8(s,r,1/0)+1;n+=4}return 0},p:(e,t)=>{var a=getEnvStrings();f[e>>2]=a.length;var n=0;for(var s of a)n+=lengthBytesUTF8(s)+1;f[t>>2]=n;return 0},n:function _fd_seek(e,t,a,n){t=(s=t)<-9007199254740992||s>9007199254740992?NaN:Number(s);var s;return 70},b:(e,t,a,n)=>{for(var s=0,r=0;r>2],o=f[t+4>>2];t+=8;for(var l=0;l>2]=s;return 0},q:function _gray_to_rgba(e,a){e>>=2;const n=t.imageData=new Uint8ClampedArray(4*a),s=o.subarray(e,e+a);for(let e=0;e>=2;a>>=2;const s=t.imageData=new Uint8ClampedArray(4*n),r=o.subarray(e,e+n),i=o.subarray(a,a+n);for(let e=0;e>=2;a>>=2;n>>=2;const r=t.imageData=new Uint8ClampedArray(4*s),i=o.subarray(e,e+s),l=o.subarray(a,a+s),f=o.subarray(n,n+s);for(let e=0;e{t.instantiateWasm(e,(e,t)=>{a(receiveInstance(e))})})}();!function run(){!function preRun(){if(t.preRun){"function"==typeof t.preRun&&(t.preRun=[t.preRun]);for(;t.preRun.length;)addOnPreRun(t.preRun.shift())}callRuntimeCallbacks(w)}();function doRun(){t.calledRun=!0;if(!m){!function initRuntime(){p=!0;x.s()}();r?.(t);t.onRuntimeInitialized?.();!function postRun(){if(t.postRun){"function"==typeof t.postRun&&(t.postRun=[t.postRun]);for(;t.postRun.length;)addOnPostRun(t.postRun.shift())}callRuntimeCallbacks(b)}()}}if(t.setStatus){t.setStatus("Running...");setTimeout(()=>{setTimeout(()=>t.setStatus(""),1);doRun()},1)}else doRun()}();return p?t:new Promise((e,t)=>{r=e;i=t})};class JpxError extends aa{constructor(e){super(e,"JpxError")}}class JpxImage{static#B=null;static#D=null;static#M=null;static#C=!0;static#N=!0;static#I=null;static setOptions({handler:e,useWasm:t,useWorkerFetch:a,wasmUrl:n}){this.#C=t;this.#N=a;this.#I=n;a||(this.#D=e)}static async#P(e){const t=`${this.#I}openjpeg_nowasm_fallback.js`;let a=null;try{a=(await import( +/*webpackIgnore: true*/ +/*@vite-ignore*/ +t)).default()}catch(e){warn(`JpxImage#getJsModule: ${e}`)}e(a)}static async#E(e,t,a){const n="openjpeg.wasm";try{this.#B||(this.#N?this.#B=await fetchBinaryData(`${this.#I}${n}`):this.#B=await this.#D.sendWithPromise("FetchBinaryData",{kind:"wasmUrl",filename:n}));return a((await WebAssembly.instantiate(this.#B,t)).instance)}catch(t){warn(`JpxImage#instantiateWasm: ${t}`);this.#P(e);return null}finally{this.#D=null}}static async decode(e,{numComponents:t=4,isIndexedColormap:a=!1,smaskInData:n=!1,reducePower:s=0}={}){if(!this.#M){const{promise:e,resolve:t}=Promise.withResolvers(),a=[e];this.#C?a.push(Ea({warn,instantiateWasm:this.#E.bind(this,t)})):this.#P(t);this.#M=Promise.race(a)}const r=await this.#M;if(!r)throw new JpxError("OpenJPEG failed to initialize");let i;try{const o=e.length;i=r._malloc(o);r.writeArrayToMemory(e,i);if(r._jp2_decode(i,o,t>0?t:0,!!a,!!n,s)){const{errorMessages:e}=r;if(e){delete r.errorMessages;throw new JpxError(e)}throw new JpxError("Unknown error")}const{imageData:l}=r;r.imageData=null;return l}finally{i&&r._free(i)}}static cleanup(){this.#M=null}static parseImageProperties(e){let t=e.getByte();for(;t>=0;){const a=t;t=e.getByte();if(65361===(a<<8|t)){e.skip(4);const t=e.getInt32()>>>0,a=e.getInt32()>>>0,n=e.getInt32()>>>0,s=e.getInt32()>>>0;e.skip(16);return{width:t-n,height:a-s,bitsPerComponent:8,componentsCount:e.getUint16()}}}throw new JpxError("No size marker found in JPX stream")}}function addState(e,t,a,n,s){let r=e;for(let e=0,a=t.length-1;e1e3){f=Math.max(f,u);m+=h+2;u=0;h=0}c.push({transform:t,x:u,y:m,w:a.width,h:a.height});u+=a.width+2;h=Math.max(h,a.height)}const p=Math.max(f,u)+1,d=m+h+1,g=new Uint8Array(p*d*4),b=p<<2;for(let e=0;e=0;){t[r-4]=t[r];t[r-3]=t[r+1];t[r-2]=t[r+2];t[r-1]=t[r+3];t[r+a]=t[r+a-4];t[r+a+1]=t[r+a-3];t[r+a+2]=t[r+a-2];t[r+a+3]=t[r+a-1];r-=b}}const w={width:p,height:d};if(e.isOffscreenCanvasSupported){const e=new OffscreenCanvas(p,d);e.getContext("2d").putImageData(new ImageData(new Uint8ClampedArray(g.buffer),p,d),0,0);w.bitmap=e.transferToImageBitmap();w.data=null}else{w.kind=O;w.data=g}a.splice(r,4*l,_t);n.splice(r,4*l,[w,c]);return r+1});addState(_a,[ke,qe,Mt,ye],null,function iterateImageMaskGroup(e,t){const a=e.fnArray,n=(t-(e.iCurr-3))%4;switch(n){case 0:return a[t]===ke;case 1:return a[t]===qe;case 2:return a[t]===Mt;case 3:return a[t]===ye}throw new Error(`iterateImageMaskGroup - invalid pos: ${n}`)},function foundImageMaskGroup(e,t){const a=e.fnArray,n=e.argsArray,s=e.iCurr,r=s-3,i=s-2,o=s-1;let l=Math.floor((t-r)/4);if(l<10)return t-(t-r)%4;let f,c,h=!1;const u=n[o][0],m=n[i][0],p=n[i][1],d=n[i][2],g=n[i][3];if(p===d){h=!0;f=i+4;let e=o+4;for(let t=1;t=4&&a[r-4]===a[i]&&a[r-3]===a[o]&&a[r-2]===a[l]&&a[r-1]===a[f]&&n[r-4][0]===c&&n[r-4][1]===h){u++;m-=5}let p=m+4;for(let e=1;e{const t=e.argsArray,a=t[e.iCurr-1][0];if(a!==Te&&a!==Oe&&a!==Be&&a!==De&&a!==Me&&a!==Ne)return!0;const n=t[e.iCurr-2];return 1===n[0]&&0===n[1]&&0===n[2]&&1===n[3]},()=>!1,(e,t)=>{const{fnArray:n,argsArray:s}=e,r=e.iCurr,i=r-3,o=r-2,l=s[r-1],f=s[o],[,[c],h]=l;if(h){const e=a.slice();Util.axialAlignedBoundingBox(h,f,e);h.set(e);for(let e=0,t=c.length;e=a)break}n=(n||_a)[e[t]];if(n&&!Array.isArray(n)){r.iCurr=t;t++;if(!n.checkFn||(0,n.checkFn)(r)){s=n;n=null}else n=null}else t++}this.state=n;this.match=s;this.lastProcessed=t}flush(){for(;this.match;){const e=this.queue.fnArray.length;this.lastProcessed=(0,this.match.processFn)(this.context,e);this.match=null;this.state=null;this._optimize()}}reset(){this.state=null;this.match=null;this.lastProcessed=0}}class OperatorList{static CHUNK_SIZE=1e3;static CHUNK_SIZE_ABOUT=this.CHUNK_SIZE-5;static isOffscreenCanvasSupported=!1;constructor(e=0,t){this._streamSink=t;this.fnArray=[];this.argsArray=[];this.optimizer=!t||e&p?new NullOptimizer(this):new QueueOptimizer(this);this.dependencies=new Set;this._totalLength=0;this.weight=0;this._resolved=t?null:Promise.resolve()}static setOptions({isOffscreenCanvasSupported:e}){this.isOffscreenCanvasSupported=e}get length(){return this.argsArray.length}get ready(){return this._resolved||this._streamSink.ready}get totalLength(){return this._totalLength+this.length}addOp(e,t){this.optimizer.push(e,t);this.weight++;this._streamSink&&(this.weight>=OperatorList.CHUNK_SIZE||this.weight>=OperatorList.CHUNK_SIZE_ABOUT&&(e===ye||e===Le))&&this.flush()}addImageOps(e,t,a,n=!1){if(n){this.addOp(ke);this.addOp(je,[[["SMask",!1]]])}void 0!==a&&this.addOp(xt,["OC",a]);this.addOp(e,t);void 0!==a&&this.addOp(Ct,[]);n&&this.addOp(ye)}addDependency(e){if(!this.dependencies.has(e)){this.dependencies.add(e);this.addOp(he,[e])}}addDependencies(e){for(const t of e)this.addDependency(t)}addOpList(e){if(e instanceof OperatorList){for(const t of e.dependencies)this.dependencies.add(t);for(let t=0,a=e.length;t"boolean"==typeof e)})(m,2)&&([h,u]=m);this.extendStart=h;this.extendEnd=u;const p=e.getRaw("Function"),d=n.create(p,!0),g=(f-l)/840,b=this.colorStops=[];if(l>=f||g<=0){info("Bad shading domain.");return}const w=new Float32Array(o.numComps),j=new Float32Array(1);let k=0;j[0]=l;d(j,0,w,0);const y=new Uint8ClampedArray(3);o.getRgb(w,0,y);let[q,v,S]=y;b.push([0,Util.makeHexColor(q,v,S)]);let x=1;j[0]=l+g;d(j,0,w,0);o.getRgb(w,0,y);let[C,F,T]=y,O=C-q+1,R=F-v+1,H=T-S+1,D=C-q-1,M=F-v-1,N=T-S-1;for(let e=2;e<840;e++){j[0]=l+e*g;d(j,0,w,0);o.getRgb(w,0,y);const[t,a,n]=y,s=e-k;O=Math.min(O,(t-q+1)/s);R=Math.min(R,(a-v+1)/s);H=Math.min(H,(n-S+1)/s);D=Math.max(D,(t-q-1)/s);M=Math.max(M,(a-v-1)/s);N=Math.max(N,(n-S-1)/s);if(!(D<=O&&M<=R&&N<=H)){const e=Util.makeHexColor(C,F,T);b.push([x/840,e]);O=t-C+1;R=a-F+1;H=n-T+1;D=t-C-1;M=a-F-1;N=n-T-1;k=x;q=C;v=F;S=T}x=e;C=t;F=a;T=n}b.push([1,Util.makeHexColor(C,F,T)]);let E="transparent";e.has("Background")&&(E=o.getRgbHex(e.get("Background"),0));if(!h){b.unshift([0,E]);b[1][0]+=BaseShading.SMALL_NUMBER}if(!u){b.at(-1)[0]-=BaseShading.SMALL_NUMBER;b.push([1,E])}this.colorStops=b}getIR(){const{coordsArr:e,shadingType:t}=this;let a,n,s,r,i;if(t===La){n=[e[0],e[1]];s=[e[2],e[3]];r=null;i=null;a="axial"}else if(t===Ua){n=[e[0],e[1]];s=[e[3],e[4]];r=e[2];i=e[5];a="radial"}else unreachable(`getPattern type unknown: ${t}`);return["RadialAxial",a,this.bbox,this.colorStops,n,s,r,i]}}function buildMeshVertexData(e,t,a){let n=0;for(const e of a)if(e.type===q)n+=e.coords.length;else if(e.type===v){const t=e.verticesPerRow;n+=(Math.floor(e.coords.length/t)-1)*(t-1)*6}const s=new Float32Array(2*n),r=new Uint8Array(4*n);let i=0,o=0;const addVertex=(a,n)=>{s[i++]=e[2*a];s[i++]=e[2*a+1];r[o++]=t[4*n];r[o++]=t[4*n+1];r[o++]=t[4*n+2];o++};for(const e of a){const t=e.coords,a=e.colors;if(e.type===q)for(let e=0,n=t.length;e0)return!0;const e=this.stream.getByte();if(e<0)return!1;this.buffer=e;this.bufferLength=8;return!0}readBits(e){const{stream:t}=this;let{buffer:a,bufferLength:n}=this;if(32===e){if(0===n)return t.getInt32()>>>0;a=a<<24|t.getByte()<<16|t.getByte()<<8|t.getByte();const e=t.getByte();this.buffer=e&(1<>n)>>>0}if(8===e&&0===n)return t.getByte();for(;n>n}align(){this.buffer=0;this.bufferLength=0}readFlag(){return this.readBits(this.context.bitsPerFlag)}readCoordinate(){const{bitsPerCoordinate:e,decode:t}=this.context,a=this.readBits(e),n=this.readBits(e),s=e<32?1/((1<i?i:t;a=a>o?o:a;n=n>>0}function hexToStr(e,t){return 1===t?String.fromCharCode(e[0],e[1]):3===t?String.fromCharCode(e[0],e[1],e[2],e[3]):String.fromCharCode(...e.subarray(0,t+1))}function addHex(e,t,a){let n=0;for(let s=a;s>=0;s--){n+=e[s]+t[s];e[s]=255&n;n>>=8}}function incHex(e,t){let a=1;for(let n=t;n>=0&&a>0;n--){a+=e[n];e[n]=255&a;a>>=8}}const $a=16;class BinaryCMapStream extends Stream{tmpBuf=new Uint8Array(19);constructor(e){super(e,0,e.length,null)}readNumber(){let e,t=0;do{const a=this.getByte();if(a<0)throw new FormatError("unexpected EOF in bcmap");e=!(128&a);t=t<<7|127&a}while(!e);return t}readSigned(){const e=this.readNumber();return 1&e?~(e>>>1):e>>>1}readHex(e,t){e.set(this.getBytes(t+1))}readHexNumber(e,t){let a;const n=this.tmpBuf;let s=0;do{const e=this.getByte();if(e<0)throw new FormatError("unexpected EOF in bcmap");a=!(128&e);n[s++]=127&e}while(!a);let r=t,i=0,o=0;for(;r>=0;){for(;o<8&&n.length>0;){i|=n[--s]<>=8;o-=8}}readHexSigned(e,t){this.readHexNumber(e,t);const a=1&e[t]?255:0;let n=0;for(let s=0;s<=t;s++){n=(1&n)<<8|e[s];e[s]=n>>1^a}}readString(){const e=this.readNumber(),t=new Array(e);for(let a=0;a=0;){const e=u>>5;if(7===e){switch(31&u){case 0:n.readString();break;case 1:r=n.readString()}continue}const a=!!(16&u),s=15&u;if(s+1>$a)throw new Error("BinaryCMapReader.process: Invalid dataSize.");const m=1,p=n.readNumber();switch(e){case 0:n.readHex(i,s);n.readHexNumber(o,s);addHex(o,i,s);t.addCodespaceRange(s+1,hexToInt(i,s),hexToInt(o,s));for(let e=1;e=0;--s){n[a+s]=255&i;i>>=8}}}}class AsciiHexStream extends DecodeStream{constructor(e,t){t&&(t*=.5);super(t);this.stream=e;this.dict=e.dict;this.firstDigit=-1}readBlock(){const e=this.stream.getBytes(8e3);if(!e.length){this.eof=!0;return}const t=e.length+1>>1,a=this.ensureBuffer(this.bufferLength+t);let n=this.bufferLength,s=this.firstDigit;for(const t of e){let e;if(t>=48&&t<=57)e=15&t;else{if(!(t>=65&&t<=70||t>=97&&t<=102)){if(62===t){this.eof=!0;break}continue}e=9+(15&t)}if(s<0)s=e;else{a[n++]=s<<4|e;s=-1}}if(s>=0&&this.eof){a[n++]=s<<4;s=-1}this.firstDigit=s;this.bufferLength=n}}let Ya=(()=>{const e=Int32Array.from([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]),t=Int32Array.from([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),a=Int32Array.from([0,3,2,1,0,0,0,0,0,0,3,3,3,3,3,3]),n=Int32Array.from([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),s=Int32Array.from([131072,131076,131075,196610,131072,131076,131075,262145,131072,131076,131075,196610,131072,131076,131075,262149]),r=Int32Array.from([1,5,9,13,17,25,33,41,49,65,81,97,113,145,177,209,241,305,369,497,753,1265,2289,4337,8433,16625]),i=Int32Array.from([2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,8,9,10,11,12,13,24]),o=Int16Array.from([0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,12,14,24]),l=Int16Array.from([0,0,0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,24]),f=new Int16Array(2816);!function unpackCommandLookupTable(e){const t=new Int32Array(24),a=new Int32Array(24);a[0]=2;for(let e=0;e<23;++e){t[e+1]=t[e]+(1<>6,r=-4;if(s>=2){s-=2;r=0}const i=(170064>>2*s&3)<<3|n>>3&7,f=(156228>>2*s&3)<<3|7&n,c=a[f],h=r+Math.min(c,5)-2,u=4*n;e[u]=o[i]|l[f]<<8;e[u+1]=t[i];e[u+2]=a[f];e[u+3]=h}}(f);function log2floor(e){let t=-1,a=16,n=e;for(;a>0;){let e=n>>a;if(0!==e){t+=a;n=e}a>>=1}return t+n}function calculateDistanceAlphabetSize(e,t,a){return 16+t+2*(a<>a),r=log2floor(s)-1;return((r-1<<1|s>>r&1)-1<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}if(0!==readFewBits(e,1)){const t=readFewBits(e,3);return 0===t?1:readFewBits(e,t)+(1<>>a.bitOffset;n+=255&s;const r=e[n]>>16,i=65535&e[n];if(r<=8){a.bitOffset+=r;return i}n+=i;n+=(s&(1<>>8;a.bitOffset+=8+(e[n]>>16);return 65535&e[n]}function readBlockLength(e,t,a){if(a.bitOffset>=16){a.accumulator32=a.shortBuffer[a.halfOffset++]<<16|a.accumulator32>>>16;a.bitOffset-=16}const n=readSymbol(e,t,a),s=i[n];if(a.bitOffset>=16){a.accumulator32=a.shortBuffer[a.halfOffset++]<<16|a.accumulator32>>>16;a.bitOffset-=16}return r[n]+(s<=16?readFewBits(a,s):readManyBits(a,s))}function moveToFront(e,t){let a=t;const n=e[a];for(;a>0;){e[a]=e[a-1];a--}e[0]=n}function readSimpleHuffmanCode(e,t,a,n,s){const r=new Int32Array(t),i=new Int32Array(4),o=1+log2floor(e-1),l=readFewBits(s,2)+1;for(let e=0;e=16){s.accumulator32=s.shortBuffer[s.halfOffset++]<<16|s.accumulator32>>>16;s.bitOffset-=16}const a=readFewBits(s,o);if(a>=t)return makeError(s,-15);i[e]=a}const f=function checkDupes(e,t,a){for(let n=0;n=16){i.accumulator32=i.shortBuffer[i.halfOffset++]<<16|i.accumulator32>>>16;i.bitOffset-=16}const n=i.accumulator32>>>i.bitOffset&15;i.bitOffset+=s[n]>>16;const r=65535&s[n];l[a]=r;if(0!==r){f-=32>>r;c++;if(f<=0)break}}if(0!==f&&1!==c)return makeError(i,-4);const h=function readHuffmanCodeLengths(e,t,a,n){let s=0,r=8,i=0,o=0,l=32768;const f=new Int32Array(33);buildHuffmanTable(f,f.length-1,5,e,18);for(;s0;){if(n.halfOffset>2030){const e=readMoreInput(n);if(e<0)return e}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}const e=n.accumulator32>>>n.bitOffset&31;n.bitOffset+=f[e]>>16;const c=65535&f[e];if(c<16){i=0;a[s++]=c;if(0!==c){r=c;l-=32768>>c}}else{const e=c-14;let f=0;16===c&&(f=r);if(o!==f){i=0;o=f}const h=i;if(i>0){i-=2;i<<=e}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}i+=readFewBits(n,e)+3;const u=i-h;if(s+u>t)return makeError(n,-2);for(let e=0;e2030){const e=readMoreInput(s);if(e<0)return e}if(s.bitOffset>=16){s.accumulator32=s.shortBuffer[s.halfOffset++]<<16|s.accumulator32>>>16;s.bitOffset-=16}const r=readFewBits(s,2);return 1===r?readSimpleHuffmanCode(e,t,a,n,s):readComplexHuffmanCode(t,r,a,n,s)}function decodeContextMap(t,a,n){let s;if(n.halfOffset>2030){s=readMoreInput(n);if(s<0)return s}const r=decodeVarLenUnsignedByte(n)+1;if(1===r){a.fill(0,0,t);return r}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}let i=0;0!==readFewBits(n,1)&&(i=readFewBits(n,4)+1);const o=r+i,l=e[o+31>>5],f=new Int32Array(l+1),c=f.length-1;s=readHuffmanCode(o,o,f,c,n);if(s<0)return s;let h=0;for(;h2030){s=readMoreInput(n);if(s<0)return s}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}const e=readSymbol(f,c,n);if(0===e){a[h]=0;h++}else if(e<=i){if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}let s=(1<=t)return makeError(n,-3);a[h]=0;h++;s--}}else{a[h]=e-i;h++}}if(n.bitOffset>=16){n.accumulator32=n.shortBuffer[n.halfOffset++]<<16|n.accumulator32>>>16;n.bitOffset-=16}1===readFewBits(n,1)&&function inverseMoveToFrontTransform(e,t){const a=new Int32Array(256);for(let e=0;e<256;++e)a[e]=e;for(let n=0;n=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}let r=readSymbol(e.blockTrees,2*t,e);const i=readBlockLength(e.blockTrees,2*t+1,e);1===r?r=n[s+1]+1:0===r?r=n[s]:r-=2;r>=a&&(r-=a);n[s]=n[s+1];n[s+1]=r;return i}function decodeLiteralBlockSwitch(e){e.literalBlockLength=decodeBlockTypeAndLength(e,0,e.numLiteralBlockTypes);const t=e.rings[5];e.contextMapSlice=t<<6;e.literalTreeIdx=255&e.contextMap[e.contextMapSlice];const a=e.contextModes[t];e.contextLookupOffset1=a<<9;e.contextLookupOffset2=e.contextLookupOffset1+256}function decodeCommandBlockSwitch(e){e.commandBlockLength=decodeBlockTypeAndLength(e,1,e.numCommandBlockTypes);e.commandTreeIdx=e.rings[7]}function decodeDistanceBlockSwitch(e){e.distanceBlockLength=decodeBlockTypeAndLength(e,2,e.numDistanceBlockTypes);e.distContextMapSlice=e.rings[9]<<2}function readNextMetablockHeader(e){if(0!==e.inputEnd){e.nextRunningState=10;e.runningState=12;return 0}e.literalTreeGroup=new Int32Array(0);e.commandTreeGroup=new Int32Array(0);e.distanceTreeGroup=new Int32Array(0);let t;if(e.halfOffset>2030){t=readMoreInput(e);if(t<0)return t}t=function decodeMetaBlockLength(e){if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.inputEnd=readFewBits(e,1);e.metaBlockLength=0;e.isUncompressed=0;e.isMetadata=0;if(0!==e.inputEnd&&0!==readFewBits(e,1))return 0;const t=readFewBits(e,2)+4;if(7===t){e.isMetadata=1;if(0!==readFewBits(e,1))return makeError(e,-6);const t=readFewBits(e,2);if(0===t)return 0;for(let a=0;a=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const n=readFewBits(e,8);if(0===n&&a+1===t&&t>1)return makeError(e,-8);e.metaBlockLength+=n<<8*a}}else for(let a=0;a=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const n=readFewBits(e,4);if(0===n&&a+1===t&&t>4)return makeError(e,-8);e.metaBlockLength+=n<<4*a}e.metaBlockLength++;0===e.inputEnd&&(e.isUncompressed=readFewBits(e,1));return 0}(e);if(t<0)return t;if(0===e.metaBlockLength&&0===e.isMetadata)return 0;if(0!==e.isUncompressed||0!==e.isMetadata){t=jumpToByteBoundary(e);if(t<0)return t;0===e.isMetadata?e.runningState=6:e.runningState=5}else e.runningState=3;if(0!==e.isMetadata)return 0;e.expectedTotalSize+=e.metaBlockLength;e.expectedTotalSize>1<<30&&(e.expectedTotalSize=1<<30);e.ringBufferSizee.expectedTotalSize){const a=e.expectedTotalSize;for(;t>>1>a;)t>>=1;0===e.inputEnd&&t<16384&&e.maxRingBufferSize>=16384&&(t=16384)}if(t<=e.ringBufferSize)return;const a=new Int8Array(t+37),n=e.ringBuffer;0!==n.length&&a.set(n.subarray(0,e.ringBufferSize),0);e.ringBuffer=a;e.ringBufferSize=t}(e);return 0}function readMetablockPartition(e,t,a){let n=e.blockTrees[2*t];if(a<=1){e.blockTrees[2*t+1]=n;e.blockTrees[2*t+2]=n;return 1<<28}const s=a+2;let r=readHuffmanCode(s,s,e.blockTrees,2*t,e);if(r<0)return r;n+=r;e.blockTrees[2*t+1]=n;r=readHuffmanCode(26,26,e.blockTrees,2*t+1,e);if(r<0)return r;n+=r;e.blockTrees[2*t+2]=n;return readBlockLength(e.blockTrees,2*t+1,e)}function readMetablockHuffmanCodesAndContextMaps(e){e.numLiteralBlockTypes=decodeVarLenUnsignedByte(e)+1;let t=readMetablockPartition(e,0,e.numLiteralBlockTypes);if(t<0)return t;e.literalBlockLength=t;e.numCommandBlockTypes=decodeVarLenUnsignedByte(e)+1;t=readMetablockPartition(e,1,e.numCommandBlockTypes);if(t<0)return t;e.commandBlockLength=t;e.numDistanceBlockTypes=decodeVarLenUnsignedByte(e)+1;t=readMetablockPartition(e,2,e.numDistanceBlockTypes);if(t<0)return t;e.distanceBlockLength=t;if(e.halfOffset>2030){t=readMoreInput(e);if(t<0)return t}if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.distancePostfixBits=readFewBits(e,2);e.numDirectDistanceCodes=readFewBits(e,4)<=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}e.contextModes[a]=readFewBits(e,2);a++}if(e.halfOffset>2030){t=readMoreInput(e);if(t<0)return t}}const n=e.numLiteralBlockTypes<<6;e.contextMap=new Int8Array(n);t=decodeContextMap(n,e.contextMap,e);if(t<0)return t;const s=t;e.trivialLiteralContext=1;for(let t=0;t>6){e.trivialLiteralContext=0;break}e.distContextMap=new Int8Array(e.numDistanceBlockTypes<<2);t=decodeContextMap(e.numDistanceBlockTypes<<2,e.distContextMap,e);if(t<0)return t;const r=t;e.literalTreeGroup=new Int32Array(huffmanTreeGroupAllocSize(256,s));t=decodeHuffmanTreeGroup(256,256,s,e,e.literalTreeGroup);if(t<0)return t;e.commandTreeGroup=new Int32Array(huffmanTreeGroupAllocSize(704,e.numCommandBlockTypes));t=decodeHuffmanTreeGroup(704,704,e.numCommandBlockTypes,e,e.commandTreeGroup);if(t<0)return t;let i=calculateDistanceAlphabetSize(e.distancePostfixBits,e.numDirectDistanceCodes,24),o=i;if(1===e.isLargeWindow){i=calculateDistanceAlphabetSize(e.distancePostfixBits,e.numDirectDistanceCodes,62);t=calculateDistanceAlphabetLimit(e,2147483644,e.distancePostfixBits,e.numDirectDistanceCodes);if(t<0)return t;o=t}e.distanceTreeGroup=new Int32Array(huffmanTreeGroupAllocSize(o,r));t=decodeHuffmanTreeGroup(i,o,r,e,e.distanceTreeGroup);if(t<0)return t;!function calculateDistanceLut(e,t){const a=e.distExtraBits,n=e.distOffset,s=e.distancePostfixBits,r=e.numDirectDistanceCodes,i=1<>>e.bitOffset;e.bitOffset+=8;r--}if(0===r)return 0;const i=Math.min(halfAvailable(e),r>>1);if(i>0){const a=e.halfOffset<<1,n=i<<1;t.set(e.byteBuffer.subarray(a,a+n),s);s+=n;r-=n;e.halfOffset+=i}if(0===r)return 0;if(halfAvailable(e)>0){if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}for(;0!==r;){t[s++]=e.accumulator32>>>e.bitOffset;e.bitOffset+=8;r--}return checkHealth(e,0)}for(;r>0;){const a=readInput(e,t,s,r);if(a<-1)return a;if(a<=0)return makeError(e,-16);s+=a;r-=a}return 0}(e,t,e.pos,n);if(a<0)return a;e.metaBlockLength-=n;e.pos+=n;if(e.pos===e.ringBufferSize){e.nextRunningState=6;e.runningState=12;return 0}a=reload(e);if(a<0)return a;e.runningState=2;return 0}function writeRingBuffer(e){const t=Math.min(e.outputLength-e.outputUsed,e.ringBufferBytesReady-e.ringBufferBytesWritten);if(0!==t){e.output.set(e.ringBuffer.subarray(e.ringBufferBytesWritten,e.ringBufferBytesWritten+t),e.outputOffset+e.outputUsed);e.outputUsed+=t;e.ringBufferBytesWritten+=t}return e.outputUsed>5]}function decodeHuffmanTreeGroup(e,t,a,n,s){let r=a;for(let i=0;i2147483644)return makeError(e,-9);const a=e.distance-e.maxDistance-1-e.cdTotalSize;if(a<0){const t=function initializeCompoundDictionaryCopy(e,t,a){-1===e.cdBlockBits&&function initializeCompoundDictionary(e){e.cdBlockMap=new Int8Array(256);let t=8;for(;e.cdTotalSize-1>>t;)t++;t-=8;e.cdBlockBits=t;let a=0,n=0;for(;a>t]=n;a+=1<>e.cdBlockBits];for(;t>=e.cdChunkOffsets[n+1];)n++;if(e.cdTotalSize>t+a)return makeError(e,-9);e.distRbIdx=e.distRbIdx+1&3;e.rings[e.distRbIdx]=e.distance;e.metaBlockLength-=a;e.cdBrIndex=n;e.cdBrOffset=t-e.cdChunkOffsets[n];e.cdBrLength=a;e.cdBrCopied=0;return 0}(e,-a-1,e.copyLength);if(t<0)return t;e.runningState=14}else{const n=u,s=e.copyLength;if(s>31)return makeError(e,-9);const r=p[s];if(0===r)return makeError(e,-9);let i=m[s];const o=a>>r;i+=(a&(1<=l.numTransforms)return makeError(e,-9);const f=function transformDictionaryWord(e,t,a,n,s,r,i){let o=t;const l=r.triplets,f=r.prefixSuffixStorage,c=r.prefixSuffixHeads,h=3*i,u=l[h],m=l[h+1],p=l[h+2];let d=c[u];const g=c[u+1];let b=c[p];const w=c[p+1];let j=m-11,k=m;(j<1||j>9)&&(j=0);(k<1||k>9)&&(k=0);for(;d!==g;)e[o++]=f[d++];let y=s;j>y&&(j=y);let q=n+j;y-=j;y-=k;let v=y;for(;v>0;){e[o++]=a[q++];v--}if(10===m||11===m){let t=o-y;10===m&&(y=1);for(;y>0;){const a=255&e[t];if(a<192){a>=97&&a<=122&&(e[t]=32^e[t]);t+=1;y-=1}else if(a<224){e[t+1]=32^e[t+1];t+=2;y-=2}else{e[t+2]=5^e[t+2];t+=3;y-=3}}}else if(21===m||22===m){let t=o-y;const a=r.params[i];let n=16777216-(32768&a)+(32767&a);for(;y>0;){let a=1;const s=255&e[t];if(s<128){n+=s;e[t]=127&n}else if(s<192);else if(s<224)if(y>=2){const r=e[t+1];n+=63&r|(31&s)<<6;e[t]=192|n>>6&31;e[t+1]=192&r|63&n;a=2}else a=y;else if(s<240)if(y>=3){const r=e[t+1],i=e[t+2];n+=63&i|(63&r)<<6|(15&s)<<12;e[t]=224|n>>12&15;e[t+1]=192&r|n>>6&63;e[t+2]=192&i|63&n;a=3}else a=y;else if(s<248)if(y>=4){const r=e[t+1],i=e[t+2],o=e[t+3];n+=63&o|(63&i)<<6|(63&r)<<12|(7&s)<<18;e[t]=240|n>>18&7;e[t+1]=192&r|n>>12&63;e[t+2]=192&i|n>>6&63;e[t+3]=192&o|63&n;a=4}else a=y;t+=a;y-=a;21===m&&(y=0)}}for(;b!==w;)e[o++]=f[b++];return o-t}(e.ringBuffer,e.pos,n,i,s,l,o);e.pos+=f;e.metaBlockLength-=f;if(e.pos>=t){e.nextRunningState=4;e.runningState=12;return 0}e.runningState=4}return 0}function copyFromCompoundDictionary(e,t){let a=e.pos;const n=a;for(;e.cdBrLength!==e.cdBrCopied;){const n=t-a,s=e.cdChunkOffsets[e.cdBrIndex+1]-e.cdChunkOffsets[e.cdBrIndex]-e.cdBrOffset;let r=e.cdBrLength-e.cdBrCopied;r>s&&(r=s);r>n&&(r=n);e.ringBuffer.set(e.cdChunks[e.cdBrIndex].subarray(e.cdBrOffset,e.cdBrOffset+r),a);a+=r;e.cdBrOffset+=r;e.cdBrCopied+=r;if(r===s){e.cdBrIndex++;e.cdBrOffset=0}if(a>=t)break}return a-n}function decompress(e){let t;if(0===e.runningState)return makeError(e,-25);if(e.runningState<0)return makeError(e,-28);if(11===e.runningState)return makeError(e,-22);if(1===e.runningState){const t=function decodeWindowBits(e){const t=e.isLargeWindow;e.isLargeWindow=0;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}if(0===readFewBits(e,1))return 16;let a=readFewBits(e,3);if(0!==a)return 17+a;a=readFewBits(e,3);if(0!==a){if(1===a){if(0===t)return-1;e.isLargeWindow=1;if(1===readFewBits(e,1))return-1;a=readFewBits(e,6);return a<10||a>30?-1:a}return 8+a}return 17}(e);if(-1===t)return makeError(e,-11);e.maxRingBufferSize=1<2030){t=readMoreInput(e);if(t<0)return t}0===e.commandBlockLength&&decodeCommandBlockSwitch(e);e.commandBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const o=readSymbol(e.commandTreeGroup,e.commandTreeIdx,e)<<2,l=f[o],c=f[o+1],u=f[o+2];e.distanceCode=f[o+3];if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const m=255&l;e.insertLength=c+(m<=16?readFewBits(e,m):readManyBits(e,m));if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const p=l>>8;e.copyLength=u+(p<=16?readFewBits(e,p):readManyBits(e,p));e.j=0;e.runningState=7;continue;case 7:if(0!==e.trivialLiteralContext)for(;e.j2030){t=readMoreInput(e);if(t<0)return t}0===e.literalBlockLength&&decodeLiteralBlockSwitch(e);e.literalBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}i[e.pos]=readSymbol(e.literalTreeGroup,e.literalTreeIdx,e);e.pos++;e.j++;if(e.pos>=s){e.nextRunningState=7;e.runningState=12;break}}else{let a=255&i[e.pos-1&r],n=255&i[e.pos-2&r];for(;e.j2030){t=readMoreInput(e);if(t<0)return t}0===e.literalBlockLength&&decodeLiteralBlockSwitch(e);const r=h[e.contextLookupOffset1+a]|h[e.contextLookupOffset2+n],o=255&e.contextMap[e.contextMapSlice+r];e.literalBlockLength--;n=a;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}a=readSymbol(e.literalTreeGroup,o,e);i[e.pos]=a;e.pos++;e.j++;if(e.pos>=s){e.nextRunningState=7;e.runningState=12;break}}}if(7!==e.runningState)continue;e.metaBlockLength-=e.insertLength;if(e.metaBlockLength<=0){e.runningState=4;continue}let d=e.distanceCode;if(d<0)e.distance=e.rings[e.distRbIdx];else{if(e.halfOffset>2030){t=readMoreInput(e);if(t<0)return t}0===e.distanceBlockLength&&decodeDistanceBlockSwitch(e);e.distanceBlockLength--;if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}const s=255&e.distContextMap[e.distContextMapSlice+d];d=readSymbol(e.distanceTreeGroup,s,e);if(d<16){const t=e.distRbIdx+a[d]&3;e.distance=e.rings[t]+n[d];if(e.distance<0)return makeError(e,-12)}else{const t=e.distExtraBits[d];let a;if(e.bitOffset+t<=32)a=readFewBits(e,t);else{if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}a=t<=16?readFewBits(e,t):readManyBits(e,t)}e.distance=e.distOffset[d]+(a<e.maxDistance){e.runningState=9;continue}if(d>0){e.distRbIdx=e.distRbIdx+1&3;e.rings[e.distRbIdx]=e.distance}if(e.copyLength>e.metaBlockLength)return makeError(e,-9);e.j=0;e.runningState=8;continue;case 8:let g=e.pos-e.distance&r,b=e.pos;const w=e.copyLength-e.j,j=g+w,k=b+w;if(jb&&k>g){const e=w+3>>2;for(let t=0;t=s){e.nextRunningState=8;e.runningState=12;break}}8===e.runningState&&(e.runningState=4);continue;case 9:t=doUseDictionary(e,s);if(t<0)return t;continue;case 14:e.pos+=copyFromCompoundDictionary(e,s);if(e.pos>=s){e.nextRunningState=14;e.runningState=12;return 2}e.runningState=4;continue;case 5:for(;e.metaBlockLength>0;){if(e.halfOffset>2030){t=readMoreInput(e);if(t<0)return t}if(e.bitOffset>=16){e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16}readFewBits(e,8);e.metaBlockLength--}e.runningState=2;continue;case 6:t=copyUncompressedData(e);if(t<0)return t;continue;case 12:e.ringBufferBytesReady=Math.min(e.pos,e.ringBufferSize);e.runningState=13;continue;case 13:t=writeRingBuffer(e);if(0!==t)return t;e.pos>=e.maxBackwardDistance&&(e.maxDistance=e.maxBackwardDistance);if(e.pos>=e.ringBufferSize){e.pos>e.ringBufferSize&&i.copyWithin(0,e.ringBufferSize,e.pos);e.pos=e.pos&r;e.ringBufferBytesWritten=0}e.runningState=e.nextRunningState;continue;default:return makeError(e,-28)}if(10!==e.runningState)return makeError(e,-29);if(e.metaBlockLength<0)return makeError(e,-10);t=jumpToByteBoundary(e);if(0!==t)return t;t=checkHealth(e,1);return 0!==t?t:1}const c=new function Transforms(e,t,a){this.numTransforms=0;this.triplets=new Int32Array(0);this.prefixSuffixStorage=new Int8Array(0);this.prefixSuffixHeads=new Int32Array(0);this.params=new Int16Array(0);this.numTransforms=e;this.triplets=new Int32Array(3*e);this.params=new Int16Array(e);this.prefixSuffixStorage=new Int8Array(t);this.prefixSuffixHeads=new Int32Array(a+1)}(121,167,50);!function unpackTransforms(e,t,a,n,s){const r=toUtf8Runes(n),i=r.length;let o=1,l=0;for(let a=0;a#\n#]# for # a # that #. # with #\'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #="# of the #. This #,# not #er #al #=\'#ful #ive #less #est #ize #ous #'," !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K");function getNextKey(e,t){let a=1<>=1;return(e&a-1)+a}function replicateValue(e,t,a,n,s){let r=n;for(;r>0;){r-=a;e[t+r]=s}}function nextTableBitSize(e,t,a){let n=t,s=1<0;){replicateValue(e,r+u,p,c,t<<16|i[m++]);u=getNextKey(u,t);o[t]--}}const d=h-1;let g=-1,b=r;p=1;for(let t=a+1;t<=15;++t){p<<=1;for(;o[t]>0;){if((u&d)!==g){b+=c;f=nextTableBitSize(o,t,a);c=1<>a),p,c,t-a<<16|i[m++]);u=getNextKey(u,t);o[t]--}}return h}function readMoreInput(e){if(0!==e.endOfStreamReached)return halfAvailable(e)>=-2?0:makeError(e,-16);const t=e.halfOffset<<1;let a=4096-t;e.byteBuffer.copyWithin(0,t,4096);e.halfOffset=0;for(;a<4096;){const t=4096-a,n=readInput(e,e.byteBuffer,a,t);if(n<-1)return n;if(n<=0){e.endOfStreamReached=1;e.tailBytes=a;a+=1;break}a+=n}!function bytesToNibbles(e,t){const a=e.byteBuffer,n=t>>1,s=e.shortBuffer;for(let e=0;e>3)-4;return a>e.tailBytes?makeError(e,-13):0!==t&&a!==e.tailBytes?makeError(e,-17):0}function readFewBits(e,t){const a=e.accumulator32>>>e.bitOffset&(1<>>16;e.bitOffset-=16;return a|readFewBits(e,t-16)<<16}function prepare(e){if(e.halfOffset>2030){const t=readMoreInput(e);if(0!==t)return t}let t=checkHealth(e,0);if(0!==t)return t;e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16;e.accumulator32=e.shortBuffer[e.halfOffset++]<<16|e.accumulator32>>>16;e.bitOffset-=16;return 0}function reload(e){return 32===e.bitOffset?prepare(e):0}function jumpToByteBoundary(e){const t=32-e.bitOffset&7;if(0!==t){if(0!==readFewBits(e,t))return makeError(e,-5)}return 0}function halfAvailable(e){let t=2048;0!==e.endOfStreamReached&&(t=e.tailBytes+1>>1);return t-e.halfOffset}const h=new Int32Array(2048);!function unpackLookupTable(e,t,a){for(let t=0;t<256;++t){e[t]=63&t;e[512+t]=t>>2;e[1792+t]=2+(t>>6)}for(let a=0;a<128;++a)e[1024+a]=4*(t.charCodeAt(a)-32);for(let t=0;t<64;++t){e[1152+t]=1&t;e[1216+t]=2+(1&t)}let n=1280;for(let t=0;t<19;++t){const s=3&t,r=a.charCodeAt(t)-32;for(let t=0;t>1;for(let e=0;e!pfwp6s{8-ip<73s{je#+pllmpfbwmlmfwvafyfqlpfmwqffgeb`wjmwldjewkbqn2;s{`bnfkjooalogyllnuljgfbpzqjmdejoosfbhjmjw`lpw0s{8ib`hwbdpajwpqloofgjwhmftmfbq?"..dqltIPLMgvwzMbnfpbofzlv#olwpsbjmibyy`logfzfpejpkttt-qjphwbapsqfu23s{qjpf16s{Aovfgjmd033/abooelqgfbqmtjogal{-ebjqob`hufqpsbjqivmfwf`kje+"sj`hfujo\'+! tbqnolqgglfpsvoo/333jgfbgqbtkvdfpslwevmgavqmkqfe`foohfzpwj`hklvqolppevfo21s{pvjwgfboQPP!bdfgdqfzDFW!fbpfbjnpdjqobjgp;s{8mbuzdqjgwjsp :::tbqpobgz`bqp*8#~sksolpfmvooubpwtjmgQPP#tfbqqfozaffmpbnfgvhfmbpb`bsftjpkdvoeW109kjwppolwdbwfhj`haovqwkfz26s{$$*8*8!=npjftjmpajqgplqwafwbpffhW2;9lqgpwqffnboo53s{ebqnlupalzpX3^-$*8!SLPWafbqhjgp*8~~nbqzwfmg+VH*rvbgyk9\n.pjy....sqls$*8ojewW2:9uj`fbmgzgfaw=QPPsllomf`haoltW259gllqfuboW249ofwpebjolqbosloomlub`lopdfmf#lxplewqlnfwjooqlpp?k0=slvqebgfsjmh?wq=njmj*"+njmfyk9abqpkfbq33*8njoh#..=jqlmeqfggjphtfmwpljosvwp,ip,klozW119JPAMW139bgbnpffp?k1=iplm$/#$`lmwW129#QPPollsbpjbnllm?,s=plvoOJMFelqw`bqwW279?k2=;3s{"..?:s{8W379njhf975Ymj`fjm`kZlqhqj`fyk9\b$**8svqfnbdfsbqbwlmfalmg904Y\\le\\$^*8333/yk9\vwbmhzbqgaltoavpk965YIbub03s{\t~\t&@0&907YifeeF[SJ`bpkujpbdloepmltyk9rvfq-`pppj`hnfbwnjm-ajmggfookjqfsj`pqfmw905YKWWS.132elwltloeFMG#{al{967YALGZgj`h8\t~\tf{jw906Yubqpafbw$~*8gjfw:::8bmmf~~?,Xj^-Obmdhn.^tjqfwlzpbggppfbobof{8\t\n~f`klmjmf-lqd336*wlmziftppbmgofdpqlle333*#133tjmfdfbqgldpallwdbqz`vwpwzofwfnswjlm-{no`l`hdbmd\'+$-63s{Sk-Gnjp`bobmolbmgfphnjofqzbmvmj{gjp`*8~\tgvpw`ojs*-\t\t43s{.133GUGp4^=?wbsfgfnlj((*tbdffvqlskjolswpklofEBRpbpjm.15WobapsfwpVQO#avoh`llh8~\tKFBGX3^*baaqivbm+2:;ofpkwtjm?,j=plmzdvzpev`hsjsf.\t"331*mgltX2^8X^8\tOld#pbow\t\n\nabmdwqjnabwk*x\t33s{\t~*8hl9\0effpbg=p9,,#X^8wloosovd+*x\tx\t#-ip$133sgvboalbw-ISD*8\t~rvlw*8\t\t$*8\t\t~1327132613251324132;132:13131312131113101317131613151314131;131:130313021301130013071306130513041320132113221323133:133;133413351336133713301331133213332:::2::;2::42::52::62::72::02::12::22::32:;:2:;;2:;42:;52:;62:;72:;02:;12:;22:;32:4:2:4;2:442:452:462:472:402:412:422:432:5:2:5;2:542:552:562:572:502:512:522:532:6:2:6;2:642:652:662:672:602:612:622:632333231720:73333::::`lnln/Mpfpwffpwbsfqlwlglkb`f`bgbb/]lajfmg/Abbp/Aujgb`bpllwqlelqlplollwqb`vbogjilpjgldqbmwjslwfnbgfafbodlrv/Efpwlmbgbwqfpsl`l`bpbabilwlgbpjmlbdvbsvfpvmlpbmwfgj`fovjpfoobnbzlylmbbnlqsjpllaqb`oj`foolgjlpklqb`bpj<[<\\!sbqhpnlvpfNlpw#---?,bnlmdaqbjmalgz#mlmf8abpfg`bqqzgqbewqfefqsbdf\\klnf-nfwfqgfobzgqfbnsqlufiljmw?,wq=gqvdp?"..#bsqjojgfboboofmf{b`welqwk`lgfpoldj`Ujft#pffnpaobmhslqwp#+133pbufg\\ojmhdlbopdqbmwdqffhklnfpqjmdpqbwfg03s{8tklpfsbqpf+*8!#Aol`hojmv{ilmfpsj{fo$*8!=*8je+.ofewgbujgklqpfEl`vpqbjpfal{fpWqb`hfnfmw?,fn=abq!=-pq`>wltfqbow>!`baofkfmqz17s{8pfwvsjwbozpkbqsnjmlqwbpwftbmwpwkjp-qfpfwtkffodjqop,`pp,233&8`ovappwveeajaofulwfp#2333hlqfb~*8\tabmgprvfvf>#x~8;3s{8`hjmdx\t\n\nbkfbg`ol`hjqjpkojhf#qbwjlpwbwpElqn!zbkll*X3^8Balvwejmgp?,k2=gfavdwbphpVQO#>`foop~*+*821s{8sqjnfwfoopwvqmp3{533-isd!psbjmafb`kwb{fpnj`qlbmdfo..=?,djewppwfuf.ojmhalgz-~*8\t\nnlvmw#+2::EBR?,qldfqeqbmh@obpp1;s{8effgp?k2=?p`lwwwfpwp11s{8gqjmh*##oftjppkboo 30:8#elq#olufgtbpwf33s{8ib9npjnlm?elmwqfsoznffwpvmwfq`kfbswjdkwAqbmg*#">#gqfpp`ojspqllnplmhfznlajonbjm-Mbnf#sobwfevmmzwqffp`ln,!2-isdtnlgfsbqbnPWBQWofew#jggfm/#132*8\t~\telqn-ujqvp`kbjqwqbmptlqpwSbdfpjwjlmsbw`k?"..\tl.`b`ejqnpwlvqp/333#bpjbmj((*xbglaf$*X3^jg>23alwk8nfmv#-1-nj-smd!hfujm`lb`k@kjogaqv`f1-isdVQO*(-isdpvjwfpoj`fkbqqz213!#ptffwwq=\tmbnf>gjfdlsbdf#ptjpp..=\t\t eee8!=Old-`ln!wqfbwpkffw*#%%#27s{8poffsmwfmwejofgib9ojg>!`Mbnf!tlqpfpklwp.al{.gfowb\t%ow8afbqp97;Y?gbwb.qvqbo?,b=#psfmgabhfqpklsp>#!!8sks!=`wjlm20s{8aqjbmkfoolpjyf>l>&1E#iljmnbzaf?jnd#jnd!=/#eipjnd!#!*X3^NWlsAWzsf!mftozGbmph`yf`kwqbjohmltp?,k6=ebr!=yk.`m23*8\t.2!*8wzsf>aovfpwqvozgbujp-ip$8=\t?"pwffo#zlv#k1=\telqn#ifpvp233&#nfmv-\t\n\ttbofpqjphpvnfmwggjmda.ojhwfb`kdje!#ufdbpgbmphffpwjpkrjspvlnjplaqfgfpgffmwqfwlglpsvfgfb/]lpfpw/Mwjfmfkbpwblwqlpsbqwfglmgfmvfulkb`fqelqnbnjpnlnfilqnvmglbrv/Ag/Abpp/_olbzvgbef`kbwlgbpwbmwlnfmlpgbwlplwqbppjwjlnv`klbklqbovdbqnbzlqfpwlpklqbpwfmfqbmwfpelwlpfpwbpsb/Apmvfubpbovgelqlpnfgjlrvjfmnfpfpslgfq`kjofpfq/Muf`fpgf`jqilp/Efpwbqufmwbdqvslkf`klfoolpwfmdlbnjdl`lpbpmjufodfmwfnjpnbbjqfpivojlwfnbpkb`jbebulqivmjlojaqfsvmwlavfmlbvwlqbaqjoavfmbwf{wlnbqylpbafqojpwbovfdl`/_nlfmfqlivfdlsfq/Vkbafqfpwlzmvm`bnvifqubolqevfqbojaqldvpwbjdvboulwlp`bplpdv/Absvfglplnlpbujplvpwfggfafmml`kfavp`bebowbfvqlppfqjfgj`kl`vqpl`obuf`bpbpof/_msobylobqdllaqbpujpwbbslzlivmwlwqbwbujpwl`qfbq`bnslkfnlp`jm`l`bqdlsjplplqgfmkb`fm/Mqfbgjp`lsfgql`fq`bsvfgbsbsfonfmlq/Vwjo`obqlilqdf`boofslmfqwbqgfmbgjfnbq`bpjdvffoobppjdol`l`kfnlwlpnbgqf`obpfqfpwlmj/]lrvfgbsbpbqabm`lkjilpujbifsbaol/Epwfujfmfqfjmlgfibqelmgl`bmbomlqwfofwqb`bvpbwlnbqnbmlpovmfpbvwlpujoobufmglsfpbqwjslpwfmdbnbq`loofubsbgqfvmjglubnlpylmbpbnalpabmgbnbqjbbavplnv`kbpvajqqjlibujujqdqbgl`kj`bboo/Ailufmgj`kbfpwbmwbofppbojqpvfolsfplpejmfpoobnbavp`l/Epwboofdbmfdqlsobybkvnlqsbdbqivmwbglaofjpobpalopbab/]lkbaobov`kb/mqfbgj`fmivdbqmlwbpuboofboo/M`bqdbglolqbabilfpw/Edvpwlnfmwfnbqjlejqnb`lpwlej`kbsobwbkldbqbqwfpofzfpbrvfonvpflabpfpsl`lpnjwbg`jfol`kj`lnjfgldbmbqpbmwlfwbsbgfafpsobzbqfgfppjfwf`lqwf`lqfbgvgbpgfpflujfilgfpfbbdvbp%rvlw8glnbjm`lnnlmpwbwvpfufmwpnbpwfqpzpwfnb`wjlmabmmfqqfnlufp`qloovsgbwfdolabonfgjvnejowfqmvnafq`kbmdfqfpvowsvaoj`p`qffm`kllpfmlqnbowqbufojppvfpplvq`fwbqdfwpsqjmdnlgvofnlajofptjw`ksklwlpalqgfqqfdjlmjwpfoepl`jbob`wjuf`lovnmqf`lqgelooltwjwof=fjwkfqofmdwkebnjozeqjfmgobzlvwbvwklq`qfbwfqfujftpvnnfqpfqufqsobzfgsobzfqf{sbmgsloj`zelqnbwglvaofsljmwppfqjfpsfqplmojujmdgfpjdmnlmwkpelq`fpvmjrvftfjdkwsflsoffmfqdzmbwvqfpfbq`kejdvqfkbujmd`vpwlnleepfwofwwfqtjmgltpvanjwqfmgfqdqlvspvsolbgkfbowknfwklgujgflpp`klloevwvqfpkbgltgfabwfubovfpLaif`wlwkfqpqjdkwpofbdvf`kqlnfpjnsofmlwj`fpkbqfgfmgjmdpfbplmqfslqwlmojmfprvbqfavwwlmjnbdfpfmbaofnlujmdobwfpwtjmwfqEqbm`fsfqjlgpwqlmdqfsfbwOlmglmgfwbjoelqnfggfnbmgpf`vqfsbppfgwlddofsob`fpgfuj`fpwbwj``jwjfppwqfbnzfooltbwwb`hpwqffweojdkwkjggfmjmel!=lsfmfgvpfevouboofz`bvpfpofbgfqpf`qfwpf`lmggbnbdfpslqwpf{`fswqbwjmdpjdmfgwkjmdpfeef`wejfogppwbwfpleej`fujpvbofgjwlqulovnfQfslqwnvpfvnnlujfpsbqfmwb``fppnlpwoznlwkfq!#jg>!nbqhfwdqlvmg`kbm`fpvqufzafelqfpznalonlnfmwpsff`knlwjlmjmpjgfnbwwfq@fmwfqlaif`wf{jpwpnjggofFvqlsfdqltwkofdb`znbmmfqfmlvdk`bqffqbmptfqlqjdjmslqwbo`ojfmwpfof`wqbmgln`olpfgwlsj`p`lnjmdebwkfqlswjlmpjnsozqbjpfgfp`bsf`klpfm`kvq`kgfejmfqfbplm`lqmfqlvwsvwnfnlqzjeqbnfsloj`fnlgfopMvnafqgvqjmdleefqppwzofphjoofgojpwfg`boofgpjoufqnbqdjmgfofwfafwwfqaqltpfojnjwpDolabopjmdoftjgdfw`fmwfqavgdfwmltqbs`qfgjw`objnpfmdjmfpbefwz`klj`fpsjqjw.pwzofpsqfbgnbhjmdmffgfgqvppjbsofbpff{wfmwP`qjswaqlhfmbooltp`kbqdfgjujgfeb`wlqnfnafq.abpfgwkflqz`lmejdbqlvmgtlqhfgkfosfg@kvq`kjnsb`wpklvogbotbzpoldl!#alwwlnojpw!=*xubq#sqfej{lqbmdfKfbgfq-svpk+`lvsofdbqgfmaqjgdfobvm`kQfujftwbhjmdujpjlmojwwofgbwjmdAvwwlmafbvwzwkfnfpelqdlwPfbq`kbm`klqbonlpwolbgfg@kbmdfqfwvqmpwqjmdqfolbgNlajofjm`lnfpvssozPlvq`flqgfqpujftfg%maps8`lvqpfBalvw#jpobmg?kwno#`llhjfmbnf>!bnbylmnlgfqmbguj`fjm?,b=9#Wkf#gjboldklvpfpAFDJM#Nf{j`lpwbqwp`fmwqfkfjdkwbggjmdJpobmgbppfwpFnsjqfP`kllofeelqwgjqf`wmfbqoznbmvboPfof`w-\t\tLmfiljmfgnfmv!=SkjojsbtbqgpkbmgofjnslqwLeej`fqfdbqgphjoopmbwjlmPslqwpgfdqfftffhoz#+f-d-afkjmggl`wlqolddfgvmjwfg?,a=?,afdjmpsobmwpbppjpwbqwjpwjppvfg033s{`bmbgbbdfm`zp`kfnfqfnbjmAqbyjopbnsofoldl!=afzlmg.p`bofb``fswpfqufgnbqjmfEllwfq`bnfqb?,k2=\t\\elqn!ofbufppwqfpp!#,=\t-dje!#lmolbgolbgfqL{elqgpjpwfqpvqujuojpwfmefnbofGfpjdmpjyf>!bssfbowf{w!=ofufopwkbmhpkjdkfqelq`fgbmjnbobmzlmfBeqj`bbdqffgqf`fmwSflsof?aq#,=tlmgfqsqj`fpwvqmfg#x~8nbjm!=jmojmfpvmgbztqbs!=ebjofg`fmpvpnjmvwfafb`lmrvlwfp263s{fpwbwfqfnlwffnbjo!ojmhfgqjdkw8pjdmboelqnbo2-kwnopjdmvssqjm`feolbw9-smd!#elqvn-B``fppsbsfqpplvmgpf{wfmgKfjdkwpojgfqVWE.;!%bns8#Afelqf-#TjwkpwvgjlltmfqpnbmbdfsqlejwiRvfqzbmmvbosbqbnpalvdkwebnlvpdlldofolmdfqj((*#xjpqbfopbzjmdgf`jgfklnf!=kfbgfqfmpvqfaqbm`ksjf`fpaol`h8pwbwfgwls!=?qb`jmdqfpjyf..%dw8sb`jwzpf{vboavqfbv-isd!#23/333lawbjmwjwofpbnlvmw/#Jm`-`lnfgznfmv!#ozqj`pwlgbz-jmgffg`lvmwz\\oldl-EbnjozollhfgNbqhfwopf#jeSobzfqwvqhfz*8ubq#elqfpwdjujmdfqqlqpGlnbjm~fopfxjmpfqwAold?,ellwfqoldjm-ebpwfqbdfmwp?algz#23s{#3sqbdnbeqjgbzivmjlqgloobqsob`fg`lufqpsovdjm6/333#sbdf!=alpwlm-wfpw+bubwbqwfpwfg\\`lvmwelqvnpp`kfnbjmgf{/ejoofgpkbqfpqfbgfqbofqw+bssfbqPvanjwojmf!=algz!=\t)#WkfWklvdkpffjmdifqpfzMftp?,ufqjezf{sfqwjmivqztjgwk>@llhjfPWBQW#b`qlpp\\jnbdfwkqfbgmbwjufsl`hfwal{!=\tPzpwfn#Gbujg`bm`fqwbaofpsqlufgBsqjo#qfboozgqjufqjwfn!=nlqf!=albqgp`lolqp`bnsvpejqpw##X^8nfgjb-dvjwbqejmjpktjgwk9pkltfgLwkfq#-sks!#bppvnfobzfqptjoplmpwlqfpqfojfeptfgfm@vpwlnfbpjoz#zlvq#Pwqjmd\t\tTkjowbzolq`ofbq9qfplqweqfm`kwklvdk!*#(#!?algz=avzjmdaqbmgpNfnafqmbnf!=lssjmdpf`wlq6s{8!=upsb`fslpwfqnbilq#`leeffnbqwjmnbwvqfkbssfm?,mbu=hbmpbpojmh!=Jnbdfp>ebopftkjof#kpsb`f3%bns8#\t\tJm##sltfqSlophj.`lolqilqgbmAlwwlnPwbqw#.`lvmw1-kwnomftp!=32-isdLmojmf.qjdkwnjoofqpfmjlqJPAM#33/333#dvjgfpubovf*f`wjlmqfsbjq-{no!##qjdkwp-kwno.aol`hqfdF{s9klufqtjwkjmujqdjmsklmfp?,wq=vpjmd#\t\nubq#=$*8\t\n?,wg=\t?,wq=\tabkbpbaqbpjodbofdlnbdzbqslophjpqsphj4]4C5d\bTA\nzk\vBl\bQ\vUmGx\bSM\nmC\bTA\twQ\nd}\bW@\bTl\bTF\ti@\tcT\vBM\v|jBV\tqw\tcC\bWI\npa\tfM\n{Z{X\bTF\bVV\bVK\tmkF\t[]\bPm\bTv\nsI\vpg\t[I\bQpmx\v_W\n^M\npe\vQ}\vGu\nel\npeChBV\bTA\tSo\nzk\vGL\vxD\nd[JzMY\bQpli\nfl\npC{BNt\vwT\ti_\bTgQQ\n|p\vXN\bQS\vxDQC\bWZ\tpD\vVS\bTWNtYh\nzuKjN}\twr\tHa\n_D\tj`\vQ}\vWp\nxZ{c\tji\tBU\nbDa|\tTn\tpV\nZd\nmC\vEV{X\tc}\tTo\bWl\bUd\tIQ\tcg\vxs\nXW\twR\vek\tc}\t]y\tJn\nrp\neg\npV\nz\\{W\npl\nz\\\nzU\tPc\t`{\bV@\nc|\bRw\ti_\bVb\nwX\tHvSu\bTF\v_W\vWs\vsIm\nTT\ndc\tUS\t}f\tiZ\bWz\tc}MD\tBe\tiD\v@@\bTl\bPv\t}tSwM`\vnU\tkW\ved\nqo\vxY\tA|\bTz\vy`BRBM\tiaXU\nyun^\tfL\tiI\nXW\tfD\bWz\bW@\tyj\tm\tav\tBN\vb\\\tpD\bTf\nY[\tJn\bQy\t[^\vWc\vyuDlCJ\vWj\vHR\t`V\vuW\tQy\np@\vGuplJm\bW[\nLP\nxC\n`m\twQuiR\nbI\twQ\tBZ\tWVBR\npg\tcgtiCW\n_y\tRg\bQa\vQB\vWc\nYble\ngESu\nL[\tQ\tea\tdj\v]W\nb~M`\twL\bTV\bVH\nt\npl\t|bs_\bU|\bTaoQlvSkM`\bTv\vK}\nfl\tcCoQBR\tHk\t|d\bQp\tHK\tBZ\vHR\bPv\vLx\vEZ\bT\bTv\tiDoDMU\vwBSuk`St\ntC\tPl\tKg\noi\tjY\vxYh}\nzk\bWZ\tm\ve`\tTB\tfE\nzk\t`zYh\nV|\tHK\tAJ\tAJ\bUL\tp\\\tql\nYcKd\nfyYh\t[I\vDgJm\n]n\nlb\bUd\n{Z\tlu\tfsoQ\bTWJm\vwB\teaYhBC\tsb\tTn\nzU\n_y\vxY\tQ]\ngwmt\tO\\\ntb\bWW\bQy\tmI\tV[\ny\\\naB\vRb\twQ\n]QQJ\bWg\vWa\bQj\ntC\bVH\nYm\vxs\bVK\nel\bWI\vxYCq\ntR\vHV\bTl\bVw\tay\bQa\bVV\t}t\tdj\nr|\tp\\\twR\n{i\nTT\t[I\ti[\tAJ\vxs\v_W\td{\vQ}\tcg\tTz\tA|\tCj\vLmN}m\nbK\tdZ\tp\\\t`V\tsV\np@\tiD\twQ\vQ}\bTfkaJm\v@@\bV`\tzp\n@NSw\tiI\tcg\noiSu\bVwloCy\tc}\vb\\\tsUBA\bWI\bTf\nxS\tVp\nd|\bTV\vbC\tNoJu\nTC\t|`\n{Z\tD]\bU|\tc}lm\bTl\tBv\tPl\tc}\bQp\tm\nLk\tkj\n@NSbKO\tj_\tp\\\nzU\bTl\bTg\bWI\tcfXO\bWW\ndzli\tBN\nd[\bWOMD\vKC\tdj\tI_\bVV\ny\\\vLmxl\txB\tkV\vb\\\vJW\vVS\tVx\vxD\td{MD\bTa\t|`\vPzR}\vWsBM\nsICN\bTaJm\npe\ti_\npV\nrh\tRd\tHv\n~A\nxR\vWh\vWk\nxS\vAz\vwX\nbIoQ\tfw\nqI\nV|\nunz\vpg\td\\\voA{D\ti_xB\bT\t`Vqr\tTTg]CA\vuR\tVJ\tT`\npw\vRb\tI_\nCxRo\vsICjKh\tBv\tWVBBoD{D\nhcKm\v^R\tQE\n{I\np@\nc|Gt\tc}Dl\nzUqN\tsVk}\tHh\v|j\nqou|\tQ]\vekZM`St\npe\tdj\bVG\veE\tm\vWc|I\n[W\tfL\bT\tBZSu\vKaCqNtY[\nqI\bTv\tfM\ti@\t}fB\\\tQy\vBl\bWgXDkc\vx[\bVV\tQ]\ta\tPy\vxD\nfI\t}foD\tdj\tSGls\t~DCN\n{Z\t\\v\n_D\nhc\vx_C[\tAJ\nLM\tVxCI\tbj\tc^\tcF\ntCSx\twrXA\bU\\\t|a\vK\\\bTV\bVj\nd|\tfsCX\ntb\bRw\tVx\tAE\tA|\bTNt\vDg\tVc\bTld@\npo\tM\tcF\npe\tiZ\tBo\bSq\nfHl`\bTx\bWf\tHE\vF{\tcO\tfD\nlm\vfZ\nlm\veU\tdGBH\bTV\tSiMW\nwX\nz\\\t\\cCX\nd}\tl}\bQp\bTV\tF~\bQ\t`i\ng@nO\bUd\bTl\nL[\twQ\tji\ntC\t|J\nLU\naB\vxYKj\tAJuN\ti[\npeSk\vDg\vx]\bVb\bVV\nea\tkV\nqI\bTaSk\nAO\tpD\ntb\nts\nyi\bVg\ti_\v_W\nLkNt\tyj\tfMR\tiI\bTl\vwX\tsV\vMl\nyu\tAJ\bVjKO\tWV\vA}\vW\nrp\tiD\v|olv\vsIBM\td~\tCU\bVbeV\npC\vwT\tj`\tc}\vxs\vps\vvh\tWV\vGg\vAe\vVK\v]W\trg\vWcF`\tBr\vb\\\tdZ\bQp\nqIkF\nLk\vAR\bWI\bTg\tbs\tdw\n{L\n_y\tiZ\bTA\tlg\bVV\bTl\tdk\n`k\ta{\ti_{Awj\twN\v@@\bTe\ti_\n_D\twL\nAH\viK\vek\n[]\tp_\tyj\bTv\tUS\t[r\n{I\npsGt\vVK\nplS}\vWP\t|dMD\vHV\bTR}M`\bTV\bVHlvCh\bW[Ke\tR{\v^R\tab\tBZ\tVA\tB`\nd|\nhsKe\tBeOi\tR{\td\\nB\bWZ\tdZ\tVJOs\tmuQ\vhZQ@QQ\nfI\bW[B\\li\nzU\nMdM`\nxS\bVV\n\\}\vxD\tm\bTpIS\nc|\tkVi~\tV{\vhZ\t|b\bWt\n@R\voA\vnU\bWI\tea\tB`\tiD\tc}\tTzBR\vQBNj\tCP\t[I\bTv\t`WuN\vpg\vpg\vWc\tiT\tbs\twL\tU_\tc\\\t|h\vKa\tNr\tfL\nq|\nzu\nz\\\tNr\bUg\t|bm`\bTv\nyd\nrp\bWf\tUXBV\nzk\nd}\twQ\t}fCe\ved\bTW\bSB\nxU\tcn\bTb\ne\ta\\\tSG\bU|\npV\nN\\Kn\vnU\tAt\tpD\v^R\vIrb[\tR{\tdE\vxD\vWK\vWA\bQL\bW@Su\bUd\nDM\tPcCADloQ\tHswiub\na\bQpOb\nLP\bTlY[\vK}\tAJ\bQn^\vsA\bSM\nqM\bWZ\n^W\vz{S|\tfD\bVK\bTv\bPvBB\tCPdF\tid\vxsmx\vws\tcC\ntC\tycM`\vW\nrh\bQp\vxD\\o\nsI_k\nzukF\tfDXsXO\tjp\bTvBS{B\tBr\nzQ\nbI\tc{BDBVnO\bTF\tcaJd\tfL\tPV\tI_\nlK`o\twX\npa\tgu\bP}{^\bWf\n{I\tBN\npaKl\vpg\tcn\tfL\vvhCq\bTl\vnU\bSqCm\twR\bUJ\npe\nyd\nYgCy\vKW\tfD\neaoQ\tj_\tBvnM\vID\bTa\nzApl\n]n\bTa\tR{\tfr\n_y\bUg{Xkk\vxD|Ixl\nfyCe\vwB\nLk\vd]\noi\n}h\tQ]\npe\bVwHkOQ\nzk\tAJ\npV\bPv\ny\\\tA{Oi\bSBXA\veE\tjp\nq}\tiDqN\v^R\tm\tiZ\tBr\bVg\noi\n\\X\tU_\nc|\vHV\bTf\tTn\\N\\N\nuBlv\nyu\tTd\bTf\bPL\v]W\tdG\nA`\nw^\ngI\npe\tdw\nz\\ia\bWZ\tcFJm\n{Z\bWO_kDfRR\td\\\bVV\vxsBNtilm\tTd\t]y\vHV\tSo\v|jXX\tA|\vZ^\vGu\bTWM`kF\vhZ\vVK\tdG\vBl\tay\nxUqEnO\bVw\nqICX\ne\tPl\bWO\vLm\tdLuHCm\tdTfn\vwBka\vnU\n@M\nyT\tHv\t\\}Kh\td~Yhk}\neR\td\\\bWI\t|b\tHK\tiD\bTWMY\npl\bQ_\twr\vAx\tHE\bTg\bSqvp\vb\\\bWO\nOl\nsI\nfy\vID\t\\c\n{Z\n^~\npe\nAO\tTT\vxvk_\bWO\v|j\vwB\tQy\ti@\tPl\tHa\tdZk}ra\tUT\vJc\ved\np@\tQN\nd|\tkj\tHkM`\noi\twr\td\\\nlq\no_\nlb\nL[\tacBBBHCm\npl\tIQ\bVK\vxs\n`e\viK\npaOi\tUS\bTp\tfD\nPGkkXA\nz\\\neg\vWh\twRqN\nqS\tcnlo\nxS\n^W\tBU\nt\tHE\tp\\\tfF\tfw\bVV\bW@\tak\vVKls\tVJ\bVV\veE\\o\nyX\nYmM`lL\nd|\nzk\tA{sE\twQXT\nt\tPl\t]y\vwT{pMD\vb\\\tQ]Kj\tJn\nAH\vRb\tBU\tHK\t\\c\nfIm\nqM\n@R\tSo\noiBT\tHv\n_yKh\tBZ\t]i\bUJ\tV{Sr\nbI\vGg\ta_\bTR\nfI\nfl\t[K\tIIS|\vuW\tiI\bWI\nqI\v|jBV\bVg\bWZkF\vx]\bTA\tab\tfr\ti@\tJd\tJd\vps\nAO\bTaxu\tiD\nzk\t|d\t|`\bW[\tlP\tdG\bVV\vw}\vqO\ti[\bQ\bTz\vVF\twNts\tdw\bTv\neS\ngi\tNryS\npe\bVV\bSq\n`m\tyj\tBZ\vWX\bSB\tc\\\nUR\t[J\tc_nM\bWQ\vAx\nMd\tBrui\vxY\bSM\vWc\v|j\vxs\t}Q\tBO\bPL\bWW\tfM\nAO\tPc\veUe^\bTg\nqI\tac\bPv\tcFoQ\tQ\vhZka\nz\\\tiK\tBU\n`k\tCPS|M`\n{I\tS{_O\tBZZiSk\tps\tp\\\nYu\n]s\nxC\bWt\nbD\tkV\vGuyS\nqA\t[r\neKM`\tdZlL\bUg\bTl\nbD\tUS\vb\\\tpV\nccS\\\tct\t`z\bPL\vWs\nA`\neg\bSquECR\vDg\t`W\vz{\vWcSkSk\tbW\bUg\tea\nxZ\tiI\tUX\tVJ\nqn\tS{\vRb\bTQ\nplGt\vuWuj\npF\nqI\tfL\t[I\tiaXO\nyu\vDg\ved\tq{VG\bQka\tVj\tkV\txB\nd|\np@\tQN\tPc\tps]j\tkV\toU\bTp\nzUnB\vB]\ta{\bV@\n]nm`\tcz\tR{m`\bQa\vwT\bSMMYqN\tdj~s\vQ}MY\vMB\tBv\twR\bRg\vQ}\tql\vKC\nrmxuCC\vwB\vvh\tBqXq\npV\ti_ObuE\nbd\nqo\v{i\nC~\tBL\veEuH\bVjEyGz\vzR\v{i\tcf\n{Z\n]nXA\vGu\vnU\thS\vGI\nCc\tHE\bTA\tHBBHCj\nCc\bTF\tHE\nXI\tA{\bQ\tc\\\vmO\vWX\nfH\np@MY\bTF\nlK\tBt\nzU\tTTKm\vwT\npV\ndt\vyI\tVx\tQ\tRg\tTd\nzU\bRS\nLM\twAnM\tTn\ndS\t]g\nLc\vwB\t}t\t[I\tCPkX\vFm\vhZm\ti[\np@\vQ}\vW\t|d\nMO\nMd\tf_\tfD\tcJ\tHz\vRb\tio\tPyY[\nxU\tct\v@@\tww\bPvBMFF\ntbv|\vKm\tBq\tBqKh`o\nZdXU\ti]\t|`\tStB\\\bQ\v_W\tTJ\nqI\t|a\tA{\vuPMD\tPl\nxR\tfL\vws\tc{\td\\\bV`\neg\tHKkc\nd|\bVV\ny\\kc\ti]\bVG\t`V\tss\tI_\tAE\tbs\tdu\nel\tpD\vW\nqslv\bSMZi\vVKia\vQB\tQ\n{Z\bPt\vKl\nlK\nhs\ndS\bVKmf\nd^\tkV\tcO\nc|\bVH\t\\]\bTv\bSq\tmI\vDg\tVJ\tcn\ny\\\bVg\bTv\nyX\bTF\t]]\bTp\noi\nhs\veU\nBf\tdjMr\n|p\t\\g\t]r\bVb{D\nd[XN\tfM\tO\\s_\tcf\tiZXN\vWc\tqv\n`m\tU^oD\nd|\vGg\tdE\vwflou}\nd|oQ\t`iOi\vxD\ndZ\nCxYw\nzk\ntb\ngw\tyj\tB`\nyX\vps\ntC\vpP\vqw\bPu\bPX\tDm\npwNj\tss\taG\vxs\bPt\noLGz\tOk\ti@\ti]eC\tIQ\tii\tdj\v@J\t|duh\bWZ\veU\vnU\bTa\tcCg]\nzkYh\bVK\nLU\np@\ntb\ntR\tCj\vNP\ti@\bP{\n\\}\n{c\nwX\tfL\bVG\tc{\t|`\tAJ\t|C\tfDln\t|d\tbs\nqI{B\vAx\np@\nzk\vRbOs\vWSe^\vD_\tBv\vWd\bVb\vxs\veE\bRw\n]n\n|p\vg|\tfwkc\bTIka\n\\TSp\tju\vps\npeu|\vGr\bVe\tCU]MXU\vxD\bTa\tIQ\vWq\tCU\tam\tdj\bSoSw\vnUCh\tQ]s_\bPt\tfS\bTa\t\\}\n@OYc\tUZ\bTx\npe\vnU\nzU\t|}\tiD\nz\\\bSM\vxDBR\nzQ\tQN]MYh\nLP\vFm\vLXvc\vqlka\tHK\bVb\ntC\nCy\bTv\nuVoQ\t`z\t[I\tB`\vRb\tyj\tsb\vWs\bTl\tkV\ved\nelL\vxN\tm\nJn\tjY\vxD\bVb\bSq\vyu\twL\vXL\bTA\tpg\tAt\tnDXX\twR\npl\nhwyS\nps\tcO\bW[\v|jXN\tsV\tp\\\tBe\nb~\nAJ\n]ek`qN\tdw\tWV\tHE\vEVJz\tid\tB`\tzhE]\tfD\bTgqN\bTa\tjaCv\bSM\nhc\bUet_\tieg]\twQ\nPn\bVB\tjw\bVg\vbE\tBZ\vRH\bP{\tjp\n\\}\ta_\tcC\t|a\vD]\tBZ\ti[\tfD\vxW\no_\td\\\n_D\ntb\t\\c\tAJ\nlKoQlo\vLx\vM@\bWZKn\vpg\nTi\nIv\n|r\v@}JzLmWhk}ln\vxD\n]sgc\vps\tBr\bTW\vBMtZ\nBYDW\tjf\vSWC}\nqo\tdE\tmv\tIQ\bPP\bUblvBC\nzQ\t[I\vgl\nig\bUsBT\vbC\bSq\tsU\tiW\nJn\tSY\tHK\trg\npV\vID\v|jKO\t`S\t|a`vbmglfmujbqnbgqjgavp`bqjmj`jlwjfnslslqrvf`vfmwbfpwbglsvfgfmivfdlp`lmwqbfpw/Mmmlnaqfwjfmfmsfqejonbmfqbbnjdlp`jvgbg`fmwqlbvmrvfsvfgfpgfmwqlsqjnfqsqf`jlpfd/Vmavfmlpuloufqsvmwlppfnbmbkba/Abbdlpwlmvfulpvmjglp`bqolpfrvjslmj/]lpnv`klpbodvmb`lqqfljnbdfmsbqwjqbqqjabnbq/Abklnaqffnsoflufqgbg`bnajlnv`kbpevfqlmsbpbglo/Amfbsbqf`fmvfubp`vqplpfpwbabrvjfqlojaqlp`vbmwlb``fplnjdvfoubqjlp`vbwqlwjfmfpdqvslppfq/Mmfvqlsbnfgjlpeqfmwfb`fq`bgfn/Mplefqwb`l`kfpnlgfoljwbojbofwqbpbod/Vm`lnsqb`vbofpf{jpwf`vfqslpjfmglsqfmpboofdbqujbifpgjmfqlnvq`jbslgq/Msvfpwlgjbqjlsvfaolrvjfqfnbmvfosqlsjl`qjpjp`jfqwlpfdvqlnvfqwfevfmwf`fqqbqdqbmgffef`wlsbqwfpnfgjgbsqlsjbleqf`fwjfqqbf.nbjoubqjbpelqnbpevwvqllaifwlpfdvjqqjfpdlmlqnbpnjpnlp/Vmj`l`bnjmlpjwjlpqby/_mgfajglsqvfabwlofglwfm/Abifp/Vpfpsfql`l`jmblqjdfmwjfmgb`jfmwl`/Mgjykbaobqpfq/Abobwjmbevfqybfpwjoldvfqqbfmwqbq/E{jwlo/_sfybdfmgbu/Agflfujwbqsbdjmbnfwqlpibujfqsbgqfpe/M`jo`bafyb/Mqfbppbojgbfmu/Alibs/_mbavplpajfmfpwf{wlpoofubqsvfgbmevfqwf`ln/Vm`obpfpkvnbmlwfmjglajoablvmjgbgfpw/Mpfgjwbq`qfbgl2%bns8Kjpwlqz#>#mft#@fmwqbovsgbwfgPsf`jboMfwtlqhqfrvjqf`lnnfmwtbqmjmd@loofdfwlloabqqfnbjmpaf`bvpffof`wfgGfvwp`kejmbm`ftlqhfqprvj`hozafwtffmf{b`wozpfwwjmdgjpfbpfPl`jfwztfbslmpf{kjajw%ow8"..@lmwqlo`obppfp`lufqfglvwojmfbwwb`hpgfuj`fp+tjmgltsvqslpfwjwof>!Nlajof#hjoojmdpkltjmdJwbojbmgqlssfgkfbujozfeef`wp.2$^*8\t`lmejqn@vqqfmwbgubm`fpkbqjmdlsfmjmdgqbtjmdajoojlmlqgfqfgDfqnbmzqfobwfg?,elqn=jm`ovgftkfwkfqgfejmfgP`jfm`f`bwboldBqwj`ofavwwlmpobqdfpwvmjelqnilvqmfzpjgfabq@kj`bdlklojgbzDfmfqbosbppbdf/%rvlw8bmjnbwfeffojmdbqqjufgsbppjmdmbwvqboqlvdkoz-\t\tWkf#avw#mlwgfmpjwzAqjwbjm@kjmfpfob`h#lewqjavwfJqfobmg!#gbwb.eb`wlqpqf`fjufwkbw#jpOjaqbqzkvpabmgjm#eb`wbeebjqp@kbqofpqbgj`boaqlvdkwejmgjmdobmgjmd9obmd>!qfwvqm#ofbgfqpsobmmfgsqfnjvnsb`hbdfBnfqj`bFgjwjlm^%rvlw8Nfppbdfmffg#wlubovf>!`lnsof{ollhjmdpwbwjlmafojfufpnboofq.nlajofqf`lqgptbmw#wlhjmg#leEjqfel{zlv#bqfpjnjobqpwvgjfgnb{jnvnkfbgjmdqbsjgoz`ojnbwfhjmdglnfnfqdfgbnlvmwpelvmgfgsjlmffqelqnvobgzmbpwzklt#wl#Pvsslqwqfufmvff`lmlnzQfpvowpaqlwkfqplogjfqobqdfoz`boojmd-%rvlw8B``lvmwFgtbqg#pfdnfmwQlafqw#feelqwpSb`jej`ofbqmfgvs#tjwkkfjdkw9tf#kbufBmdfofpmbwjlmp\\pfbq`kbssojfgb`rvjqfnbppjufdqbmwfg9#ebopfwqfbwfgajddfpwafmfejwgqjujmdPwvgjfpnjmjnvnsfqkbspnlqmjmdpfoojmdjp#vpfgqfufqpfubqjbmw#qlof>!njppjmdb`kjfufsqlnlwfpwvgfmwplnflmff{wqfnfqfpwlqfalwwln9fuloufgboo#wkfpjwfnbsfmdojpktbz#wl##Bvdvpwpznalop@lnsbmznbwwfqpnvpj`bobdbjmpwpfqujmd~*+*8\tsbznfmwwqlvaof`lm`fsw`lnsbqfsbqfmwpsobzfqpqfdjlmpnlmjwlq#$$Wkf#tjmmjmdf{solqfbgbswfgDboofqzsqlgv`fbajojwzfmkbm`f`bqffqp*-#Wkf#`loof`wPfbq`k#bm`jfmwf{jpwfgellwfq#kbmgofqsqjmwfg`lmplofFbpwfqmf{slqwptjmgltp@kbmmfojoofdbomfvwqbopvddfpw\\kfbgfqpjdmjmd-kwno!=pfwwofgtfpwfqm`bvpjmd.tfahjw`objnfgIvpwj`f`kbswfquj`wjnpWklnbp#nlyjoobsqlnjpfsbqwjfpfgjwjlmlvwpjgf9ebopf/kvmgqfgLoznsj`\\avwwlmbvwklqpqfb`kfg`kqlmj`gfnbmgppf`lmgpsqlwf`wbglswfgsqfsbqfmfjwkfqdqfbwozdqfbwfqlufqboojnsqluf`lnnbmgpsf`jbopfbq`k-tlqpkjsevmgjmdwklvdkwkjdkfpwjmpwfbgvwjojwzrvbqwfq@vowvqfwfpwjmd`ofbqozf{slpfgAqltpfqojafqbo~#`bw`kSqlif`wf{bnsofkjgf+*8EolqjgbbmptfqpbooltfgFnsfqlqgfefmpfpfqjlvpeqffglnPfufqbo.avwwlmEvqwkfqlvw#le#">#mvoowqbjmfgGfmnbqhuljg+3*,boo-ipsqfufmwQfrvfpwPwfskfm\t\tTkfm#lapfquf?,k1=\tNlgfqm#sqlujgf!#bow>!alqgfqp-\t\tElq#\t\tNbmz#bqwjpwpsltfqfgsfqelqnej`wjlmwzsf#lenfgj`bowj`hfwplsslpfg@lvm`jotjwmfppivpwj`fDflqdf#Afodjvn---?,b=wtjwwfqmlwbaoztbjwjmdtbqebqf#Lwkfq#qbmhjmdskqbpfpnfmwjlmpvqujufp`klobq?,s=\t#@lvmwqzjdmlqfgolpp#leivpw#bpDflqdjbpwqbmdf?kfbg=?pwlssfg2$^*8\tjpobmgpmlwbaofalqgfq9ojpw#le`bqqjfg233/333?,k0=\t#pfufqboaf`lnfppfof`w#tfggjmd33-kwnonlmbq`klee#wkfwfb`kfqkjdkoz#ajloldzojef#lelq#fufmqjpf#le%qbrvl8sovplmfkvmwjmd+wklvdkGlvdobpiljmjmd`jq`ofpElq#wkfBm`jfmwUjfwmbnufkj`ofpv`k#bp`qzpwboubovf#>Tjmgltpfmilzfgb#pnboobppvnfg?b#jg>!elqfjdm#Boo#qjklt#wkfGjpsobzqfwjqfgkltfufqkjggfm8abwwofppffhjmd`bajmfwtbp#mlwollh#bw`lmgv`wdfw#wkfIbmvbqzkbssfmpwvqmjmdb9klufqLmojmf#Eqfm`k#ob`hjmdwzsj`bof{wqb`wfmfnjfpfufm#jedfmfqbwgf`jgfgbqf#mlw,pfbq`kafojfep.jnbdf9ol`bwfgpwbwj`-oldjm!=`lmufqwujlofmwfmwfqfgejqpw!=`jq`vjwEjmobmg`kfnjpwpkf#tbp23s{8!=bp#pv`kgjujgfg?,psbm=tjoo#afojmf#leb#dqfbwnzpwfqz,jmgf{-eboojmdgvf#wl#qbjotbz`loofdfnlmpwfqgfp`fmwjw#tjwkmv`ofbqIftjpk#sqlwfpwAqjwjpkeoltfqpsqfgj`wqfelqnpavwwlm#tkl#tbpof`wvqfjmpwbmwpvj`jgfdfmfqj`sfqjlgpnbqhfwpPl`jbo#ejpkjmd`lnajmfdqbskj`tjmmfqp?aq#,=?az#wkf#MbwvqboSqjub`z`llhjfplvw`lnfqfploufPtfgjpkaqjfeozSfqpjbmpl#nv`k@fmwvqzgfsj`wp`lovnmpklvpjmdp`qjswpmf{w#wlafbqjmdnbssjmdqfujpfgiRvfqz+.tjgwk9wjwof!=wllowjsPf`wjlmgfpjdmpWvqhjpkzlvmdfq-nbw`k+~*+*8\t\tavqmjmdlsfqbwfgfdqffpplvq`f>Qj`kbqg`olpfozsobpwj`fmwqjfp?,wq=\t`lolq9 vo#jg>!slppfppqloojmdskzpj`pebjojmdf{f`vwf`lmwfpwojmh#wlGfebvow?aq#,=\t9#wqvf/`kbqwfqwlvqjpn`obppj`sql`ffgf{sobjm?,k2=\tlmojmf-<{no#ufkfosjmdgjbnlmgvpf#wkfbjqojmffmg#..=*-bwwq+qfbgfqpklpwjmd eeeeeeqfbojyfUjm`fmwpjdmbop#pq`>!,Sqlgv`wgfpsjwfgjufqpfwfoojmdSvaoj`#kfog#jmIlpfsk#wkfbwqfbeef`wp?pwzof=b#obqdfglfpm$wobwfq/#Fofnfmwebuj`lm`qfbwlqKvmdbqzBjqslqwpff#wkfpl#wkbwNj`kbfoPzpwfnpSqldqbnp/#bmg##tjgwk>f%rvlw8wqbgjmdofew!=\tsfqplmpDlogfm#Beebjqpdqbnnbqelqnjmdgfpwqlzjgfb#le`bpf#lelogfpw#wkjp#jp-pq`#>#`bqwllmqfdjpwq@lnnlmpNvpojnpTkbw#jpjm#nbmznbqhjmdqfufbopJmgffg/frvbooz,pklt\\blvwgllqfp`bsf+Bvpwqjbdfmfwj`pzpwfn/Jm#wkf#pjwwjmdKf#boplJpobmgpB`bgfnz\t\n\n?"..Gbmjfo#ajmgjmdaol`h!=jnslpfgvwjojyfBaqbkbn+f{`fswxtjgwk9svwwjmd*-kwno+#X^8\tGBWBX#)hjw`kfmnlvmwfgb`wvbo#gjbof`wnbjmoz#\\aobmh$jmpwboof{sfqwpje+wzsfJw#bopl%`lsz8#!=Wfqnpalqm#jmLswjlmpfbpwfqmwbohjmd`lm`fqmdbjmfg#lmdljmdivpwjez`qjwj`peb`wlqzjwp#ltmbppbvowjmujwfgobpwjmdkjp#ltmkqfe>!,!#qfo>!gfufols`lm`fqwgjbdqbngloobqp`ovpwfqsksbo`lklo*8~*+*8vpjmd#b=?psbm=ufppfopqfujuboBggqfppbnbwfvqbmgqljgboofdfgjoomfpptbohjmd`fmwfqprvbojeznbw`kfpvmjejfgf{wjm`wGfefmpfgjfg#jm\t\n?"..#`vpwlnpojmhjmdOjwwof#Allh#lefufmjmdnjm-iptfbqjmdBoo#Qjd8\t~*+*8qbjpjmd#Bopl/#`qv`jbobalvw!=gf`obqf..=\t?p`ejqfel{bp#nv`kbssojfpjmgf{/#p/#avw#wzsf#>#\t\t?"..wltbqgpQf`lqgpSqjubwfElqfjdmSqfnjfq`klj`fpUjqwvboqfwvqmp@lnnfmwSltfqfgjmojmf8slufqwz`kbnafqOjujmd#ulovnfpBmwklmzoldjm!#QfobwfgF`lmlnzqfb`kfp`vwwjmddqbujwzojef#jm@kbswfq.pkbgltMlwbaof?,wg=\t#qfwvqmpwbgjvntjgdfwpubqzjmdwqbufopkfog#aztkl#bqftlqh#jmeb`vowzbmdvobqtkl#kbgbjqslqwwltm#le\t\tPlnf#$`oj`h$`kbqdfphfztlqgjw#tjoo`jwz#le+wkjp*8Bmgqft#vmjrvf#`kf`hfglq#nlqf033s{8#qfwvqm8qpjlm>!sovdjmptjwkjm#kfqpfoePwbwjlmEfgfqboufmwvqfsvaojpkpfmw#wlwfmpjlmb`wqfpp`lnf#wlejmdfqpGvhf#lesflsof/f{soljwtkbw#jpkbqnlmzb#nbilq!9!kwwsjm#kjp#nfmv!=\tnlmwkozleej`fq`lvm`jodbjmjmdfufm#jmPvnnbqzgbwf#leolzbowzejwmfppbmg#tbpfnsfqlqpvsqfnfPf`lmg#kfbqjmdQvppjbmolmdfpwBoafqwbobwfqbopfw#le#pnboo!=-bssfmggl#tjwkefgfqboabmh#leafmfbwkGfpsjwf@bsjwbodqlvmgp*/#bmg#sfq`fmwjw#eqln`olpjmd`lmwbjmJmpwfbgejewffmbp#tfoo-zbkll-qfpslmgejdkwfqlap`vqfqfeof`wlqdbmj`>#Nbwk-fgjwjmdlmojmf#sbggjmdb#tkloflmfqqlqzfbq#lefmg#le#abqqjfqtkfm#jwkfbgfq#klnf#leqfpvnfgqfmbnfgpwqlmd=kfbwjmdqfwbjmp`olvgeqtbz#le#Nbq`k#2hmltjmdjm#sbqwAfwtffmofpplmp`olpfpwujqwvboojmhp!=`qlppfgFMG#..=ebnlvp#btbqgfgOj`fmpfKfbowk#ebjqoz#tfbowkznjmjnboBeqj`bm`lnsfwfobafo!=pjmdjmdebqnfqpAqbpjo*gjp`vppqfsob`fDqfdlqzelmw#`lsvqpvfgbssfbqpnbhf#vsqlvmgfgalwk#leaol`hfgpbt#wkfleej`fp`lolvqpje+gl`vtkfm#kffmelq`fsvpk+evBvdvpw#VWE.;!=Ebmwbpzjm#nlpwjmivqfgVpvboozebqnjmd`olpvqflaif`w#gfefm`fvpf#le#Nfgj`bo?algz=\tfujgfmwaf#vpfghfz@lgfpj{wffmJpobnj` 333333fmwjqf#tjgfoz#b`wjuf#+wzsflelmf#`bm`lolq#>psfbhfqf{wfmgpSkzpj`pwfqqbjm?walgz=evmfqboujftjmdnjggof#`qj`hfwsqlskfwpkjewfggl`wlqpQvppfoo#wbqdfw`lnsb`wbodfaqbpl`jbo.avoh#lenbm#bmg?,wg=\t#kf#ofew*-ubo+*ebopf*8oldj`boabmhjmdklnf#wlmbnjmd#Bqjylmb`qfgjwp*8\t~*8\telvmgfqjm#wvqm@loojmpafelqf#Avw#wkf`kbqdfgWjwof!=@bswbjmpsfoofgdlggfppWbd#..=Bggjmd9avw#tbpQf`fmw#sbwjfmwab`h#jm>ebopf%Ojm`lomtf#hmlt@lvmwfqIvgbjpnp`qjsw#bowfqfg$^*8\t##kbp#wkfvm`ofbqFufmw$/alwk#jmmlw#boo\t\t?"..#sob`jmdkbqg#wl#`fmwfqplqw#le`ojfmwppwqffwpAfqmbqgbppfqwpwfmg#wlebmwbpzgltm#jmkbqalvqEqffglniftfoqz,balvw--pfbq`kofdfmgpjp#nbgfnlgfqm#lmoz#lmlmoz#wljnbdf!#ojmfbq#sbjmwfqbmg#mlwqbqfoz#b`qlmzngfojufqpklqwfq33%bns8bp#nbmztjgwk>!,)#?"X@wjwof#>le#wkf#oltfpw#sj`hfg#fp`bsfgvpfp#lesflsofp#Svaoj`Nbwwkftwb`wj`pgbnbdfgtbz#elqobtp#lefbpz#wl#tjmgltpwqlmd##pjnsof~`bw`k+pfufmwkjmelal{tfmw#wlsbjmwfg`jwjyfmJ#glm$wqfwqfbw-#Plnf#tt-!*8\talnajmdnbjowl9nbgf#jm-#Nbmz#`bqqjfpx~8tjtlqh#lepzmlmzngfefbwpebulqfglswj`bosbdfWqbvmofpp#pfmgjmdofew!=?`lnP`lqBoo#wkfiRvfqz-wlvqjpw@obppj`ebopf!#Tjokfonpvavqapdfmvjmfajpklsp-psojw+dolabo#elooltpalgz#lemlnjmbo@lmwb`wpf`vobqofew#wl`kjfeoz.kjggfm.abmmfq?,oj=\t\t-#Tkfm#jm#alwkgjpnjppF{solqfbotbzp#ujb#wkfpsb/]lotfoebqfqvojmd#bqqbmdf`bswbjmkjp#plmqvof#lekf#wllhjwpfoe/>3%bns8+`boofgpbnsofpwl#nbhf`ln,sbdNbqwjm#Hfmmfgzb``fswpevoo#lekbmgofgAfpjgfp,,..=?,baof#wlwbqdfwpfppfm`fkjn#wl#jwp#az#`lnnlm-njmfqbowl#wbhftbzp#wlp-lqd,obgujpfgsfmbowzpjnsof9je#wkfzOfwwfqpb#pklqwKfqafqwpwqjhfp#dqlvsp-ofmdwkeojdkwplufqobspoltoz#ofppfq#pl`jbo#?,s=\t\n\njw#jmwlqbmhfg#qbwf#levo=\t##bwwfnswsbjq#lenbhf#jwHlmwbhwBmwlmjlkbujmd#qbwjmdp#b`wjufpwqfbnpwqbssfg!*-`pp+klpwjofofbg#wlojwwof#dqlvsp/Sj`wvqf..=\t\t#qltp>!#laif`wjmufqpf?ellwfq@vpwlnU=?_,p`qploujmd@kbnafqpobufqztlvmgfgtkfqfbp">#$vmgelq#boosbqwoz#.qjdkw9Bqbajbmab`hfg#`fmwvqzvmjw#lenlajof.Fvqlsf/jp#klnfqjph#legfpjqfg@ojmwlm`lpw#lebdf#le#af`lnf#mlmf#les%rvlw8Njggof#fbg$*X3@qjwj`ppwvgjlp=%`lsz8dqlvs!=bppfnaonbhjmd#sqfppfgtjgdfw-sp9!#<#qfavjowaz#plnfElqnfq#fgjwlqpgfobzfg@bmlmj`kbg#wkfsvpkjmd`obpp>!avw#bqfsbqwjboAbazolmalwwln#`bqqjfq@lnnbmgjwp#vpfBp#tjwk`lvqpfpb#wkjqggfmlwfpbopl#jmKlvpwlm13s{8!=b``vpfgglvaof#dlbo#leEbnlvp#*-ajmg+sqjfpwp#Lmojmfjm#Ivozpw#(#!d`lmpvowgf`jnbokfosevoqfujufgjp#ufqzq$($jswolpjmd#efnbofpjp#boplpwqjmdpgbzp#lebqqjuboevwvqf#?laif`welq`jmdPwqjmd+!#,=\t\n\nkfqf#jpfm`lgfg-##Wkf#aboollmglmf#az,`lnnlmad`lolqobt#le#Jmgjbmbbuljgfgavw#wkf1s{#0s{irvfqz-bewfq#bsloj`z-nfm#bmgellwfq.>#wqvf8elq#vpfp`qffm-Jmgjbm#jnbdf#>ebnjoz/kwws9,,#%maps8gqjufqpfwfqmbopbnf#bpmlwj`fgujftfqp~*+*8\t#jp#nlqfpfbplmpelqnfq#wkf#mftjp#ivpw`lmpfmw#Pfbq`ktbp#wkftkz#wkfpkjssfgaq=?aq=tjgwk9#kfjdkw>nbgf#le`vjpjmfjp#wkbwb#ufqz#Bgnjqbo#ej{fg8mlqnbo#NjppjlmSqfpp/#lmwbqjl`kbqpfwwqz#wl#jmubgfg>!wqvf!psb`jmdjp#nlpwb#nlqf#wlwboozeboo#le~*8\t##jnnfmpfwjnf#jmpfw#lvwpbwjpezwl#ejmggltm#wlolw#le#Sobzfqpjm#Ivmfrvbmwvnmlw#wkfwjnf#wlgjpwbmwEjmmjpkpq`#>#+pjmdof#kfos#leDfqnbm#obt#bmgobafofgelqfpwp`llhjmdpsb`f!=kfbgfq.tfoo#bpPwbmofzaqjgdfp,dolabo@qlbwjb#Balvw#X3^8\t##jw/#bmgdqlvsfgafjmd#b*xwkqltkf#nbgfojdkwfqfwkj`boEEEEEE!alwwln!ojhf#b#fnsolzpojuf#jmbp#pffmsqjmwfqnlpw#leva.ojmhqfif`wpbmg#vpfjnbdf!=pv``ffgeffgjmdMv`ofbqjmelqnbwl#kfosTlnfm$pMfjwkfqNf{j`bmsqlwfjm?wbaof#az#nbmzkfbowkzobtpvjwgfujpfg-svpk+xpfoofqppjnsoz#Wkqlvdk-`llhjf#Jnbdf+logfq!=vp-ip!=#Pjm`f#vmjufqpobqdfq#lsfm#wl"..#fmgojfp#jm$^*8\t##nbqhfwtkl#jp#+!GLN@lnbmbdfglmf#elqwzsfle#Hjmdglnsqlejwpsqlslpfwl#pklt`fmwfq8nbgf#jwgqfppfgtfqf#jmnj{wvqfsqf`jpfbqjpjmdpq`#>#$nbhf#b#pf`vqfgAbswjpwulwjmd#\t\n\nubq#Nbq`k#1dqft#vs@ojnbwf-qfnlufphjoofgtbz#wkf?,kfbg=eb`f#leb`wjmd#qjdkw!=wl#tlqhqfgv`fpkbp#kbgfqf`wfgpklt+*8b`wjlm>allh#lebm#bqfb>>#!kww?kfbgfq\t?kwno=`lmelqneb`jmd#`llhjf-qfoz#lmklpwfg#-`vpwlnkf#tfmwavw#elqpsqfbg#Ebnjoz#b#nfbmplvw#wkfelqvnp-ellwbdf!=Nlajo@ofnfmwp!#jg>!bp#kjdkjmwfmpf..=?"..efnbof#jp#pffmjnsojfgpfw#wkfb#pwbwfbmg#kjpebpwfpwafpjgfpavwwlm\\alvmgfg!=?jnd#Jmelal{fufmwp/b#zlvmdbmg#bqfMbwjuf#`kfbsfqWjnflvwbmg#kbpfmdjmfptlm#wkf+nlpwozqjdkw9#ejmg#b#.alwwlnSqjm`f#bqfb#lenlqf#lepfbq`k\\mbwvqf/ofdboozsfqjlg/obmg#lelq#tjwkjmgv`fgsqlujmdnjppjofol`boozBdbjmpwwkf#tbzh%rvlw8s{8!=\tsvpkfg#babmglmmvnfqbo@fqwbjmJm#wkjpnlqf#jmlq#plnfmbnf#jpbmg/#jm`qltmfgJPAM#3.`qfbwfpL`wlafqnbz#mlw`fmwfq#obwf#jmGfefm`ffmb`wfgtjpk#wlaqlbgoz`llojmdlmolbg>jw-#Wkfqf`lufqNfnafqpkfjdkw#bppvnfp?kwno=\tsflsof-jm#lmf#>tjmgltellwfq\\b#dllg#qfhobnblwkfqp/wl#wkjp\\`llhjfsbmfo!=Olmglm/gfejmfp`qvpkfgabswjpn`lbpwbopwbwvp#wjwof!#nluf#wlolpw#jmafwwfq#jnsojfpqjuboqzpfqufqp#PzpwfnSfqkbspfp#bmg#`lmwfmgeoltjmdobpwfg#qjpf#jmDfmfpjpujft#leqjpjmd#pffn#wlavw#jm#ab`hjmdkf#tjoodjufm#bdjujmd#`jwjfp-eolt#le#Obwfq#boo#avwKjdktbzlmoz#azpjdm#lekf#glfpgjeefqpabwwfqz%bns8obpjmdofpwkqfbwpjmwfdfqwbhf#lmqfevpfg`boofg#>VP%bnsPff#wkfmbwjufpaz#wkjppzpwfn-kfbg#le9klufq/ofpajbmpvqmbnfbmg#boo`lnnlm,kfbgfq\\\\sbqbnpKbqubqg,sj{fo-qfnlubopl#olmdqlof#leiljmwozphzp`qbVmj`lgfaq#,=\tBwobmwbmv`ofvp@lvmwz/svqfoz#`lvmw!=fbpjoz#avjog#blm`oj`hb#djufmsljmwfqk%rvlw8fufmwp#fopf#x\tgjwjlmpmlt#wkf/#tjwk#nbm#tkllqd,Tfalmf#bmg`buboqzKf#gjfgpfbwwof33/333#xtjmgltkbuf#wlje+tjmgbmg#jwpplofoz#n%rvlw8qfmftfgGfwqljwbnlmdpwfjwkfq#wkfn#jmPfmbwlqVp?,b=?Hjmd#leEqbm`jp.sqlgv`kf#vpfgbqw#bmgkjn#bmgvpfg#azp`lqjmdbw#klnfwl#kbufqfobwfpjajojwzeb`wjlmAveebolojmh!=?tkbw#kfeqff#wl@jwz#le`lnf#jmpf`wlqp`lvmwfglmf#gbzmfqulvpprvbqf#~8je+dljm#tkbwjnd!#bojp#lmozpfbq`k,wvfpgbzollpfozPlolnlmpf{vbo#.#?b#kqnfgjvn!GL#MLW#Eqbm`f/tjwk#b#tbq#bmgpf`lmg#wbhf#b#=\t\t\tnbqhfw-kjdktbzglmf#jm`wjujwz!obpw!=laojdfgqjpf#wl!vmgfejnbgf#wl#Fbqoz#sqbjpfgjm#jwp#elq#kjpbwkofwfIvsjwfqZbkll"#wfqnfg#pl#nbmzqfbooz#p-#Wkf#b#tlnbmgjqf`w#qjdkw!#aj`z`ofb`jmd>!gbz#bmgpwbwjmdQbwkfq/kjdkfq#Leej`f#bqf#mltwjnfp/#tkfm#b#sbz#elqlm#wkjp.ojmh!=8alqgfqbqlvmg#bmmvbo#wkf#Mftsvw#wkf-`ln!#wbhjm#wlb#aqjfe+jm#wkfdqlvsp-8#tjgwkfmyznfppjnsof#jm#obwfxqfwvqmwkfqbszb#sljmwabmmjmdjmhp!=\t+*8!#qfb#sob`f_v330@bbalvw#bwq=\t\n\n``lvmw#djufp#b?P@QJSWQbjotbzwkfnfp,wlloal{AzJg+!{kvnbmp/tbw`kfpjm#plnf#je#+tj`lnjmd#elqnbwp#Vmgfq#avw#kbpkbmgfg#nbgf#azwkbm#jmefbq#legfmlwfg,jeqbnfofew#jmulowbdfjm#fb`kb%rvlw8abpf#leJm#nbmzvmgfqdlqfdjnfpb`wjlm#?,s=\t?vpwlnUb8%dw8?,jnslqwplq#wkbwnlpwoz#%bns8qf#pjyf>!?,b=?,kb#`obppsbppjufKlpw#>#TkfwkfqefqwjofUbqjlvp>X^8+ev`bnfqbp,=?,wg=b`wp#bpJm#plnf=\t\t?"lqdbmjp#?aq#,=Afjijmd`bwbo/Lgfvwp`kfvqlsfvfvphbqbdbfjodfpufmphbfpsb/]bnfmpbifvpvbqjlwqbabiln/E{j`ls/Mdjmbpjfnsqfpjpwfnbl`wvaqfgvqbmwfb/]bgjqfnsqfpbnlnfmwlmvfpwqlsqjnfqbwqbu/Epdqb`jbpmvfpwqbsql`fplfpwbglp`bojgbgsfqplmbm/Vnfqlb`vfqgln/Vpj`bnjfnaqllefqwbpbodvmlpsb/Apfpfifnsolgfqf`klbgfn/Mpsqjubglbdqfdbqfmob`fpslpjaofklwfofppfujoobsqjnfql/Vowjnlfufmwlpbq`kjul`vowvqbnvifqfpfmwqbgbbmvm`jlfnabqdlnfq`bgldqbmgfpfpwvgjlnfilqfpefaqfqlgjpf/]lwvqjpnl`/_gjdlslqwbgbfpsb`jlebnjojbbmwlmjlsfqnjwfdvbqgbqbodvmbpsqf`jlpbodvjfmpfmwjglujpjwbpw/Awvol`lml`fqpfdvmgl`lmpfileqbm`jbnjmvwlppfdvmgbwfmfnlpfef`wlpn/Mobdbpfpj/_mqfujpwbdqbmbgb`lnsqbqjmdqfpldbq`/Abb``j/_mf`vbglqrvjfmfpjm`ovplgfafq/Mnbwfqjbklnaqfpnvfpwqbslgq/Abnb/]bmb/Vowjnbfpwbnlplej`jbowbnajfmmjmd/Vmpbovglpslgfnlpnfilqbqslpjwjlmavpjmfppklnfsbdfpf`vqjwzobmdvbdfpwbmgbqg`bnsbjdmefbwvqfp`bwfdlqzf{wfqmbo`kjogqfmqfpfqufgqfpfbq`kf{`kbmdfebulqjwfwfnsobwfnjojwbqzjmgvpwqzpfquj`fpnbwfqjbosqlgv`wpy.jmgf{9`lnnfmwpplewtbqf`lnsofwf`bofmgbqsobwelqnbqwj`ofpqfrvjqfgnlufnfmwrvfpwjlmavjogjmdslojwj`pslppjaofqfojdjlmskzpj`boeffgab`hqfdjpwfqsj`wvqfpgjpbaofgsqlwl`lobvgjfm`fpfwwjmdpb`wjujwzfofnfmwpofbqmjmdbmzwkjmdbapwqb`wsqldqfpplufqujftnbdbyjmff`lmlnj`wqbjmjmdsqfppvqfubqjlvp#?pwqlmd=sqlsfqwzpklssjmdwldfwkfqbgubm`fgafkbujlqgltmolbgefbwvqfgellwaboopfof`wfgObmdvbdfgjpwbm`fqfnfnafqwqb`hjmdsbpptlqgnlgjejfgpwvgfmwpgjqf`wozejdkwjmdmlqwkfqmgbwbabpfefpwjuboaqfbhjmdol`bwjlmjmwfqmfwgqlsgltmsqb`wj`ffujgfm`fevm`wjlmnbqqjbdfqfpslmpfsqlaofnpmfdbwjufsqldqbnpbmbozpjpqfofbpfgabmmfq!=svq`kbpfsloj`jfpqfdjlmbo`qfbwjufbqdvnfmwallhnbqhqfefqqfq`kfnj`bogjujpjlm`booab`hpfsbqbwfsqlif`wp`lmeoj`wkbqgtbqfjmwfqfpwgfojufqznlvmwbjmlawbjmfg>#ebopf8elq+ubq#b``fswfg`bsb`jwz`lnsvwfqjgfmwjwzbjq`qbewfnsolzfgsqlslpfgglnfpwj`jm`ovgfpsqlujgfgklpsjwboufqwj`bo`loobspfbssqlb`ksbqwmfqpoldl!=?bgbvdkwfqbvwklq!#`vowvqboebnjojfp,jnbdfp,bppfnaozsltfqevowfb`kjmdejmjpkfggjpwqj`w`qjwj`bo`dj.ajm,svqslpfpqfrvjqfpfof`wjlmaf`lnjmdsqlujgfpb`bgfnj`f{fq`jpfb`wvbooznfgj`jmf`lmpwbmwb``jgfmwNbdbyjmfgl`vnfmwpwbqwjmdalwwln!=lapfqufg9#%rvlw8f{wfmgfgsqfujlvpPlewtbqf`vpwlnfqgf`jpjlmpwqfmdwkgfwbjofgpojdkwozsobmmjmdwf{wbqfb`vqqfm`zfufqzlmfpwqbjdkwwqbmpefqslpjwjufsqlgv`fgkfqjwbdfpkjssjmdbaplovwfqf`fjufgqfofubmwavwwlm!#ujlofm`fbmztkfqfafmfejwpobvm`kfgqf`fmwozboojbm`felooltfgnvowjsofavoofwjmjm`ovgfgl``vqqfgjmwfqmbo\'+wkjp*-qfsvaoj`=?wq=?wg`lmdqfppqf`lqgfgvowjnbwfplovwjlm?vo#jg>!gjp`lufqKlnf?,b=tfapjwfpmfwtlqhpbowklvdkfmwjqfoznfnlqjbonfppbdfp`lmwjmvfb`wjuf!=plnftkbwuj`wlqjbTfpwfqm##wjwof>!Ol`bwjlm`lmwqb`wujpjwlqpGltmolbgtjwklvw#qjdkw!=\tnfbpvqfptjgwk#>#ubqjbaofjmuloufgujqdjmjbmlqnboozkbssfmfgb``lvmwppwbmgjmdmbwjlmboQfdjpwfqsqfsbqfg`lmwqlopb``vqbwfajqwkgbzpwqbwfdzleej`jbodqbskj`p`qjnjmboslppjaoz`lmpvnfqSfqplmbopsfbhjmdubojgbwfb`kjfufg-isd!#,=nb`kjmfp?,k1=\t##hfztlqgpeqjfmgozaqlwkfqp`lnajmfglqjdjmbo`lnslpfgf{sf`wfgbgfrvbwfsbhjpwbmeloolt!#ubovbaof?,obafo=qfobwjufaqjmdjmdjm`qfbpfdlufqmlqsovdjmp,Ojpw#le#Kfbgfq!=!#mbnf>!#+%rvlw8dqbgvbwf?,kfbg=\t`lnnfq`fnbobzpjbgjqf`wlqnbjmwbjm8kfjdkw9p`kfgvof`kbmdjmdab`h#wl#`bwkloj`sbwwfqmp`lolq9# dqfbwfpwpvssojfpqfojbaof?,vo=\t\n\n?pfof`w#`jwjyfmp`olwkjmdtbw`kjmd?oj#jg>!psf`jej``bqqzjmdpfmwfm`f?`fmwfq=`lmwqbpwwkjmhjmd`bw`k+f*plvwkfqmNj`kbfo#nfq`kbmw`bqlvpfosbggjmd9jmwfqjlq-psojw+!ojybwjlmL`wlafq#*xqfwvqmjnsqlufg..%dw8\t\t`lufqbdf`kbjqnbm-smd!#,=pvaif`wpQj`kbqg#tkbwfufqsqlabaozqf`lufqzabpfabooivgdnfmw`lmmf`w--`pp!#,=#tfapjwfqfslqwfggfebvow!,=?,b=\tfof`wqj`p`lwobmg`qfbwjlmrvbmwjwz-#JPAM#3gjg#mlw#jmpwbm`f.pfbq`k.!#obmd>!psfbhfqp@lnsvwfq`lmwbjmpbq`kjufpnjmjpwfqqfb`wjlmgjp`lvmwJwbojbml`qjwfqjbpwqlmdoz9#$kwws9$p`qjsw$`lufqjmdleefqjmdbssfbqfgAqjwjpk#jgfmwjezEb`fallhmvnfqlvpufkj`ofp`lm`fqmpBnfqj`bmkbmgojmdgju#jg>!Tjoojbn#sqlujgfq\\`lmwfmwb``vqb`zpf`wjlm#bmgfqplmeof{jaof@bwfdlqzobtqfm`f?p`qjsw=obzlvw>!bssqlufg#nb{jnvnkfbgfq!=?,wbaof=Pfquj`fpkbnjowlm`vqqfmw#`bmbgjbm`kbmmfop,wkfnfp,,bqwj`oflswjlmboslqwvdboubovf>!!jmwfqubotjqfofppfmwjwofgbdfm`jfpPfbq`k!#nfbpvqfgwklvpbmgpsfmgjmd%kfoojs8mft#Gbwf!#pjyf>!sbdfMbnfnjggof!#!#,=?,b=kjggfm!=pfrvfm`fsfqplmbolufqeoltlsjmjlmpjoojmljpojmhp!=\t\n?wjwof=ufqpjlmppbwvqgbzwfqnjmbojwfnsqlsfmdjmffqpf`wjlmpgfpjdmfqsqlslpbo>!ebopf!Fpsb/]loqfofbpfppvanjw!#fq%rvlw8bggjwjlmpznswlnplqjfmwfgqfplvq`fqjdkw!=?sofbpvqfpwbwjlmpkjpwlqz-ofbujmd##alqgfq>`lmwfmwp`fmwfq!=-\t\tPlnf#gjqf`wfgpvjwbaofavodbqjb-pklt+*8gfpjdmfgDfmfqbo#`lm`fswpF{bnsofptjoojbnpLqjdjmbo!=?psbm=pfbq`k!=lsfqbwlqqfrvfpwpb#%rvlw8booltjmdGl`vnfmwqfujpjlm-#\t\tWkf#zlvqpfoe@lmwb`w#nj`kjdbmFmdojpk#`lovnajbsqjlqjwzsqjmwjmdgqjmhjmdeb`jojwzqfwvqmfg@lmwfmw#leej`fqpQvppjbm#dfmfqbwf.;;6:.2!jmgj`bwfebnjojbq#rvbojwznbqdjm93#`lmwfmwujftslqw`lmwb`wp.wjwof!=slqwbaof-ofmdwk#fojdjaofjmuloufpbwobmwj`lmolbg>!gfebvow-pvssojfgsbznfmwpdolppbqz\t\tBewfq#dvjgbm`f?,wg=?wgfm`lgjmdnjggof!=`bnf#wl#gjpsobzpp`lwwjpkilmbwkbmnbilqjwztjgdfwp-`ojmj`bowkbjobmgwfb`kfqp?kfbg=\t\nbeef`wfgpvsslqwpsljmwfq8wlPwqjmd?,pnboo=lhobklnbtjoo#af#jmufpwlq3!#bow>!klojgbzpQfplvq`foj`fmpfg#+tkj`k#-#Bewfq#`lmpjgfqujpjwjmdf{solqfqsqjnbqz#pfbq`k!#bmgqljg!rvj`hoz#nffwjmdpfpwjnbwf8qfwvqm#8`lolq9 #kfjdkw>bssqlubo/#%rvlw8#`kf`hfg-njm-ip!nbdmfwj`=?,b=?,kelqf`bpw-#Tkjof#wkvqpgbzgufqwjpf%fb`vwf8kbp@obppfubovbwflqgfqjmdf{jpwjmdsbwjfmwp#Lmojmf#`lolqbglLswjlmp!`bnsafoo?"..#fmg?,psbm=??aq#,=\t\\slsvspp`jfm`fp/%rvlw8#rvbojwz#Tjmgltp#bppjdmfgkfjdkw9#?a#`obppof%rvlw8#ubovf>!#@lnsbmzf{bnsofp?jeqbnf#afojfufpsqfpfmwpnbqpkboosbqw#le#sqlsfqoz*-\t\tWkf#wb{lmlnznv`k#le#?,psbm=\t!#gbwb.pqwvdv/Fpp`qlooWl#sqlif`w?kfbg=\tbwwlqmfzfnskbpjppslmplqpebm`zal{tlqog$p#tjogojef`kf`hfg>pfppjlmpsqldqbnns{8elmw.#Sqlif`wilvqmbopafojfufgub`bwjlmwklnsplmojdkwjmdbmg#wkf#psf`jbo#alqgfq>3`kf`hjmd?,walgz=?avwwlm#@lnsofwf`ofbqej{\t?kfbg=\tbqwj`of#?pf`wjlmejmgjmdpqlof#jm#slsvobq##L`wlafqtfapjwf#f{slpvqfvpfg#wl##`kbmdfplsfqbwfg`oj`hjmdfmwfqjmd`lnnbmgpjmelqnfg#mvnafqp##?,gju=`qfbwjmdlmPvanjwnbqzobmg`loofdfpbmbozwj`ojpwjmdp`lmwb`w-olddfgJmbgujplqzpjaojmdp`lmwfmw!p%rvlw8*p-#Wkjp#sb`hbdfp`kf`hal{pvddfpwpsqfdmbmwwlnlqqltpsb`jmd>j`lm-smdibsbmfpf`lgfabpfavwwlm!=dbnaojmdpv`k#bp#/#tkjof#?,psbm=#njpplvqjpslqwjmdwls92s{#-?,psbm=wfmpjlmptjgwk>!1obyzolbgmlufnafqvpfg#jm#kfjdkw>!`qjsw!=\t%maps8?,?wq=?wg#kfjdkw91,sqlgv`w`lvmwqz#jm`ovgf#ellwfq!#%ow8"..#wjwof!=?,irvfqz-?,elqn=\t+\vBl\bQ*+\vUmGx*kqubwphjjwbojbmlqln/Nm(ow/Pqh/Kf4K4]4C5dwbnaj/Emmlwj`jbpnfmpbifpsfqplmbpgfqf`klpmb`jlmbopfquj`jl`lmwb`wlvpvbqjlpsqldqbnbdlajfqmlfnsqfpbpbmvm`jlpubofm`jb`lolnajbgfpsv/Epgfslqwfpsqlzf`wlsqlgv`wls/Vaoj`lmlplwqlpkjpwlqjbsqfpfmwfnjoolmfpnfgjbmwfsqfdvmwbbmwfqjlqqf`vqplpsqlaofnbpbmwjbdlmvfpwqlplsjmj/_mjnsqjnjqnjfmwqbpbn/Eqj`bufmgfglqpl`jfgbgqfpsf`wlqfbojybqqfdjpwqlsbobaqbpjmwfq/Epfmwlm`fpfpsf`jbonjfnaqlpqfbojgbg`/_qglabybqbdlybs/Mdjmbppl`jbofpaolrvfbqdfpwj/_mborvjofqpjpwfnbp`jfm`jbp`lnsofwlufqpj/_m`lnsofwbfpwvgjlps/Vaoj`blaifwjulboj`bmwfavp`bglq`bmwjgbgfmwqbgbpb``jlmfpbq`kjulppvsfqjlqnbzlq/Abbofnbmjbevm`j/_m/Vowjnlpkb`jfmglbrvfoolpfgj`j/_mefqmbmglbnajfmwfeb`fallhmvfpwqbp`ojfmwfpsql`fplpabpwbmwfsqfpfmwbqfslqwbq`lmdqfplsvaoj`bq`lnfq`jl`lmwqbwli/_ufmfpgjpwqjwlw/E`mj`b`lmivmwlfmfqd/Abwqbabibqbpwvqjbpqf`jfmwfvwjojybqalofw/Ampboubglq`lqqf`wbwqbabilpsqjnfqlpmfdl`jlpojafqwbggfwboofpsbmwboobsq/_{jnlbonfq/Abbmjnbofprvj/Emfp`lqby/_mpf``j/_mavp`bmglls`jlmfpf{wfqjlq`lm`fswlwlgbu/Abdbofq/Abfp`qjajqnfgj`jmboj`fm`jb`lmpvowbbpsf`wlp`q/Awj`bg/_obqfpivpwj`jbgfafq/Mmsfq/Alglmf`fpjwbnbmwfmfqsfrvf/]lqf`jajgbwqjavmbowfmfqjef`bm`j/_m`bmbqjbpgfp`bqdbgjufqplpnboolq`bqfrvjfqfw/E`mj`lgfafq/Abujujfmgbejmbmybpbgfobmwfevm`jlmb`lmpfilpgje/A`jo`jvgbgfpbmwjdvbpbubmybgbw/Eqnjmlvmjgbgfpp/Mm`kfy`bnsb/]bplewlmj`qfujpwbp`lmwjfmfpf`wlqfpnlnfmwlpeb`vowbg`q/Egjwlgjufqpbppvsvfpwleb`wlqfppfdvmglpsfrvf/]b<_!?,pfof`w=Bvpwqbojb!#`obpp>!pjwvbwjlmbvwklqjwzelooltjmdsqjnbqjozlsfqbwjlm`kboofmdfgfufolsfgbmlmznlvpevm`wjlm#evm`wjlmp`lnsbmjfppwqv`wvqfbdqffnfmw!#wjwof>!slwfmwjbofgv`bwjlmbqdvnfmwppf`lmgbqz`lszqjdkwobmdvbdfpf{`ovpjuf`lmgjwjlm?,elqn=\tpwbwfnfmwbwwfmwjlmAjldqbskz~#fopf#x\tplovwjlmptkfm#wkf#Bmbozwj`pwfnsobwfpgbmdfqlvppbwfoojwfgl`vnfmwpsvaojpkfqjnslqwbmwsqlwlwzsfjmeovfm`f%qbrvl8?,feef`wjufdfmfqboozwqbmpelqnafbvwjevowqbmpslqwlqdbmjyfgsvaojpkfgsqlnjmfmwvmwjo#wkfwkvnambjoMbwjlmbo#-el`vp+*8lufq#wkf#njdqbwjlmbmmlvm`fgellwfq!=\tf{`fswjlmofpp#wkbmf{sfmpjufelqnbwjlmeqbnftlqhwfqqjwlqzmgj`bwjlm`vqqfmwoz`obppMbnf`qjwj`jpnwqbgjwjlmfopftkfqfBof{bmgfqbssljmwfgnbwfqjbopaqlbg`bpwnfmwjlmfgbeejojbwf?,lswjlm=wqfbwnfmwgjeefqfmw,gfebvow-Sqfpjgfmwlm`oj`h>!ajldqbskzlwkfqtjpfsfqnbmfmwEqbm/KbjpKlooztllgf{sbmpjlmpwbmgbqgp?,pwzof=\tqfgv`wjlmGf`fnafq#sqfefqqfg@bnaqjgdflsslmfmwpAvpjmfpp#`lmevpjlm=\t?wjwof=sqfpfmwfgf{sobjmfgglfp#mlw#tlqogtjgfjmwfqeb`fslpjwjlmpmftpsbsfq?,wbaof=\tnlvmwbjmpojhf#wkf#fppfmwjboejmbm`jbopfof`wjlmb`wjlm>!,babmglmfgFgv`bwjlmsbqpfJmw+pwbajojwzvmbaof#wl?,wjwof=\tqfobwjlmpMlwf#wkbwfeej`jfmwsfqelqnfgwtl#zfbqpPjm`f#wkfwkfqfelqftqbssfq!=bowfqmbwfjm`qfbpfgAbwwof#lesfq`fjufgwqzjmd#wlmf`fppbqzslqwqbzfgfof`wjlmpFojybafwk?,jeqbnf=gjp`lufqzjmpvqbm`fp-ofmdwk8ofdfmgbqzDfldqbskz`bmgjgbwf`lqslqbwfplnfwjnfppfquj`fp-jmkfqjwfg?,pwqlmd=@lnnvmjwzqfojdjlvpol`bwjlmp@lnnjwwffavjogjmdpwkf#tlqogml#olmdfqafdjmmjmdqfefqfm`f`bmmlw#afeqfrvfm`zwzsj`boozjmwl#wkf#qfobwjuf8qf`lqgjmdsqfpjgfmwjmjwjboozwf`kmjrvfwkf#lwkfqjw#`bm#aff{jpwfm`fvmgfqojmfwkjp#wjnfwfofsklmfjwfnp`lsfsqb`wj`fpbgubmwbdf*8qfwvqm#Elq#lwkfqsqlujgjmdgfnl`qb`zalwk#wkf#f{wfmpjufpveefqjmdpvsslqwfg`lnsvwfqp#evm`wjlmsqb`wj`bopbjg#wkbwjw#nbz#afFmdojpk?,eqln#wkf#p`kfgvofggltmolbgp?,obafo=\tpvpsf`wfgnbqdjm9#3psjqjwvbo?,kfbg=\t\tnj`qlplewdqbgvboozgjp`vppfgkf#af`bnff{f`vwjufirvfqz-ipklvpfklog`lmejqnfgsvq`kbpfgojwfqboozgfpwqlzfgvs#wl#wkfubqjbwjlmqfnbjmjmdjw#jp#mlw`fmwvqjfpIbsbmfpf#bnlmd#wkf`lnsofwfgbodlqjwknjmwfqfpwpqfafoojlmvmgfejmfgfm`lvqbdfqfpjybaofjmuloujmdpfmpjwjufvmjufqpbosqlujpjlm+bowklvdkefbwvqjmd`lmgv`wfg*/#tkj`k#`lmwjmvfg.kfbgfq!=Efaqvbqz#mvnfqlvp#lufqeolt9`lnslmfmweqbdnfmwpf{`foofmw`lopsbm>!wf`kmj`bomfbq#wkf#Bgubm`fg#plvq`f#lef{sqfppfgKlmd#Hlmd#Eb`fallhnvowjsof#nf`kbmjpnfofubwjlmleefmpjuf?,elqn=\t\npslmplqfggl`vnfmw-lq#%rvlw8wkfqf#bqfwklpf#tklnlufnfmwpsql`fppfpgjeej`vowpvanjwwfgqf`lnnfmg`lmujm`fgsqlnlwjmd!#tjgwk>!-qfsob`f+`obppj`bo`lbojwjlmkjp#ejqpwgf`jpjlmpbppjpwbmwjmgj`bwfgfulovwjlm.tqbssfq!fmlvdk#wlbolmd#wkfgfojufqfg..=\t?"..Bnfqj`bm#sqlwf`wfgMlufnafq#?,pwzof=?evqmjwvqfJmwfqmfw##lmaovq>!pvpsfmgfgqf`jsjfmwabpfg#lm#Nlqflufq/balojpkfg`loof`wfgtfqf#nbgffnlwjlmbofnfqdfm`zmbqqbwjufbgul`bwfps{8alqgfq`lnnjwwfggjq>!owq!fnsolzffpqfpfbq`k-#pfof`wfgpv``fpplq`vpwlnfqpgjpsobzfgPfswfnafqbgg@obpp+Eb`fallh#pvddfpwfgbmg#obwfqlsfqbwjmdfobalqbwfPlnfwjnfpJmpwjwvwf`fqwbjmozjmpwboofgelooltfqpIfqvpbofnwkfz#kbuf`lnsvwjmddfmfqbwfgsqlujm`fpdvbqbmwffbqajwqbqzqf`ldmjyftbmwfg#wls{8tjgwk9wkflqz#leafkbujlvqTkjof#wkffpwjnbwfgafdbm#wl#jw#af`bnfnbdmjwvgfnvpw#kbufnlqf#wkbmGjqf`wlqzf{wfmpjlmpf`qfwbqzmbwvqboozl``vqqjmdubqjbaofpdjufm#wkfsobwelqn-?,obafo=?ebjofg#wl`lnslvmgphjmgp#le#pl`jfwjfpbolmdpjgf#..%dw8\t\tplvwktfpwwkf#qjdkwqbgjbwjlmnbz#kbuf#vmfp`bsf+pslhfm#jm!#kqfe>!,sqldqbnnflmoz#wkf#`lnf#eqlngjqf`wlqzavqjfg#jmb#pjnjobqwkfz#tfqf?,elmw=?,Mlqtfdjbmpsf`jejfgsqlgv`jmdsbppfmdfq+mft#Gbwfwfnslqbqzej`wjlmboBewfq#wkffrvbwjlmpgltmolbg-qfdvobqozgfufolsfqbaluf#wkfojmhfg#wlskfmlnfmbsfqjlg#lewllowjs!=pvapwbm`fbvwlnbwj`bpsf`w#leBnlmd#wkf`lmmf`wfgfpwjnbwfpBjq#Elq`fpzpwfn#lelaif`wjufjnnfgjbwfnbhjmd#jwsbjmwjmdp`lmrvfqfgbqf#pwjoosql`fgvqfdqltwk#lekfbgfg#azFvqlsfbm#gjujpjlmpnlof`vofpeqbm`kjpfjmwfmwjlmbwwqb`wfg`kjogkllgbopl#vpfggfgj`bwfgpjmdbslqfgfdqff#leebwkfq#le`lmeoj`wp?,b=?,s=\t`bnf#eqlntfqf#vpfgmlwf#wkbwqf`fjujmdF{f`vwjuffufm#nlqfb``fpp#wl`lnnbmgfqSlojwj`bonvpj`jbmpgfoj`jlvpsqjplmfqpbgufmw#leVWE.;!#,=?"X@GBWBX!=@lmwb`wPlvwkfqm#ad`lolq>!pfqjfp#le-#Jw#tbp#jm#Fvqlsfsfqnjwwfgubojgbwf-bssfbqjmdleej`jboppfqjlvpoz.obmdvbdfjmjwjbwfgf{wfmgjmdolmd.wfqnjmeobwjlmpv`k#wkbwdfw@llhjfnbqhfg#az?,avwwlm=jnsofnfmwavw#jw#jpjm`qfbpfpgltm#wkf#qfrvjqjmdgfsfmgfmw..=\t?"..#jmwfqujftTjwk#wkf#`lsjfp#le`lmpfmpvptbp#avjowUfmfyvfob+elqnfqozwkf#pwbwfsfqplmmfopwqbwfdj`ebulvq#lejmufmwjlmTjhjsfgjb`lmwjmfmwujqwvbooztkj`k#tbpsqjm`jsof@lnsofwf#jgfmwj`bopklt#wkbwsqjnjwjufbtbz#eqlnnlof`vobqsqf`jpfozgjpploufgVmgfq#wkfufqpjlm>!=%maps8?,Jw#jp#wkf#Wkjp#jp#tjoo#kbuflqdbmjpnpplnf#wjnfEqjfgqj`ktbp#ejqpwwkf#lmoz#eb`w#wkbwelqn#jg>!sqf`fgjmdWf`kmj`boskzpj`jpwl``vqp#jmmbujdbwlqpf`wjlm!=psbm#jg>!plvdkw#wlafolt#wkfpvqujujmd~?,pwzof=kjp#gfbwkbp#jm#wkf`bvpfg#azsbqwjboozf{jpwjmd#vpjmd#wkftbp#djufmb#ojpw#leofufop#lemlwjlm#leLeej`jbo#gjpnjppfgp`jfmwjpwqfpfnaofpgvsoj`bwff{solpjufqf`lufqfgboo#lwkfqdboofqjfpxsbggjmd9sflsof#leqfdjlm#lebggqfppfpbppl`jbwfjnd#bow>!jm#nlgfqmpklvog#afnfwklg#leqfslqwjmdwjnfpwbnsmffgfg#wlwkf#Dqfbwqfdbqgjmdpffnfg#wlujftfg#bpjnsb`w#lmjgfb#wkbwwkf#Tlqogkfjdkw#lef{sbmgjmdWkfpf#bqf`vqqfmw!=`bqfevooznbjmwbjmp`kbqdf#le@obppj`bobggqfppfgsqfgj`wfgltmfqpkjs?gju#jg>!qjdkw!=\tqfpjgfm`fofbuf#wkf`lmwfmw!=bqf#lewfm##~*+*8\tsqlabaoz#Sqlefpplq.avwwlm!#qfpslmgfgpbzp#wkbwkbg#wl#afsob`fg#jmKvmdbqjbmpwbwvp#lepfqufp#bpVmjufqpbof{f`vwjlmbddqfdbwfelq#tkj`kjmef`wjlmbdqffg#wlkltfufq/#slsvobq!=sob`fg#lm`lmpwqv`wfof`wlqbopznalo#lejm`ovgjmdqfwvqm#wlbq`kjwf`w@kqjpwjbmsqfujlvp#ojujmd#jmfbpjfq#wlsqlefpplq\t%ow8"..#feef`w#lebmbozwj`ptbp#wbhfmtkfqf#wkfwllh#lufqafojfe#jmBeqjhbbmpbp#ebq#bpsqfufmwfgtlqh#tjwkb#psf`jbo?ejfogpfw@kqjpwnbpQfwqjfufg\t\tJm#wkf#ab`h#jmwlmlqwkfbpwnbdbyjmfp=?pwqlmd=`lnnjwwffdlufqmjmddqlvsp#lepwlqfg#jmfpwbaojpkb#dfmfqbojwp#ejqpwwkfjq#ltmslsvobwfgbm#laif`w@bqjaafbmboolt#wkfgjpwqj`wptjp`lmpjmol`bwjlm-8#tjgwk9#jmkbajwfgPl`jbojpwIbmvbqz#2?,ellwfq=pjnjobqoz`klj`f#lewkf#pbnf#psf`jej`#avpjmfpp#Wkf#ejqpw-ofmdwk8#gfpjqf#wlgfbo#tjwkpjm`f#wkfvpfqBdfmw`lm`fjufgjmgf{-sksbp#%rvlw8fmdbdf#jmqf`fmwoz/eft#zfbqptfqf#bopl\t?kfbg=\t?fgjwfg#azbqf#hmltm`jwjfp#jmb``fpphfz`lmgfnmfgbopl#kbufpfquj`fp/ebnjoz#leP`kllo#le`lmufqwfgmbwvqf#le#obmdvbdfnjmjpwfqp?,laif`w=wkfqf#jp#b#slsvobqpfrvfm`fpbgul`bwfgWkfz#tfqfbmz#lwkfqol`bwjlm>fmwfq#wkfnv`k#nlqfqfeof`wfgtbp#mbnfglqjdjmbo#b#wzsj`botkfm#wkfzfmdjmffqp`lvog#mlwqfpjgfmwptfgmfpgbzwkf#wkjqg#sqlgv`wpIbmvbqz#1tkbw#wkfzb#`fqwbjmqfb`wjlmpsql`fpplqbewfq#kjpwkf#obpw#`lmwbjmfg!=?,gju=\t?,b=?,wg=gfsfmg#lmpfbq`k!=\tsjf`fp#le`lnsfwjmdQfefqfm`fwfmmfppfftkj`k#kbp#ufqpjlm>?,psbm=#??,kfbgfq=djufp#wkfkjpwlqjbmubovf>!!=sbggjmd93ujft#wkbwwldfwkfq/wkf#nlpw#tbp#elvmgpvapfw#lebwwb`h#lm`kjogqfm/sljmwp#lesfqplmbo#slpjwjlm9boofdfgoz@ofufobmgtbp#obwfqbmg#bewfqbqf#djufmtbp#pwjoop`qloojmdgfpjdm#lenbhfp#wkfnv`k#ofppBnfqj`bmp-\t\tBewfq#/#avw#wkfNvpfvn#leolvjpjbmb+eqln#wkfnjmmfplwbsbqwj`ofpb#sql`fppGlnjmj`bmulovnf#leqfwvqmjmdgfefmpjuf33s{qjdknbgf#eqlnnlvpflufq!#pwzof>!pwbwfp#le+tkj`k#jp`lmwjmvfpEqbm`jp`lavjogjmd#tjwklvw#btjwk#plnftkl#tlvogb#elqn#leb#sbqw#leafelqf#jwhmltm#bp##Pfquj`fpol`bwjlm#bmg#lewfmnfbpvqjmdbmg#jw#jpsbsfqab`hubovfp#le\t?wjwof=>#tjmglt-gfwfqnjmffq%rvlw8#sobzfg#azbmg#fbqoz?,`fmwfq=eqln#wkjpwkf#wkqffsltfq#bmgle#%rvlw8jmmfqKWNO?b#kqfe>!z9jmojmf8@kvq`k#lewkf#fufmwufqz#kjdkleej`jbo#.kfjdkw9#`lmwfmw>!,`dj.ajm,wl#`qfbwfbeqjhbbmpfpsfqbmwleqbm/Kbjpobwujf)Mvojfwvuj)_(`f)Mwjmb(af)Mwjmb\fUh\fT{\fTN\n{I\np@Fr\vBl\bQ\tA{\vUmGx\tA{ypYA\0zX\bTV\bWl\bUdBM\vB{\npV\v@xB\\\np@DbGz\tal\npa\tfM\tuD\bV~mx\vQ}\ndS\tp\\\bVK\bS]\bU|oD\tkV\ved\vHR\nb~M`\nJpoD|Q\nLPSw\bTl\nAI\nxC\bWt\tBqF`Cm\vLm\tKx\t}t\bPv\ny\\\naB\tV\nZdXUli\tfr\ti@\tBHBDBV\t`V\n[]\tp_\tTn\n~A\nxR\tuD\t`{\bV@\tTn\tHK\tAJ\vxsZf\nqIZf\vBM\v|j\t}t\bSM\nmC\vQ}pfquj`jlpbqw/A`volbqdfmwjmbabq`folmb`vborvjfqsvaoj`bglsqlgv`wlpslo/Awj`bqfpsvfpwbtjhjsfgjbpjdvjfmwfa/Vprvfgb`lnvmjgbgpfdvqjgbgsqjm`jsbosqfdvmwbp`lmwfmjglqfpslmgfqufmfyvfobsqlaofnbpgj`jfnaqfqfob`j/_mmlujfnaqfpjnjobqfpsqlzf`wlpsqldqbnbpjmpwjwvwlb`wjujgbgfm`vfmwqbf`lmln/Abjn/Mdfmfp`lmwb`wbqgfp`bqdbqmf`fpbqjlbwfm`j/_mwfo/Eelml`lnjpj/_m`bm`jlmfp`bsb`jgbgfm`lmwqbqbm/Mojpjpebulqjwlpw/Eqnjmlpsqlujm`jbfwjrvfwbpfofnfmwlpevm`jlmfpqfpvowbgl`bq/M`wfqsqlsjfgbgsqjm`jsjlmf`fpjgbgnvmj`jsbo`qfb`j/_mgfp`bqdbpsqfpfm`jb`lnfq`jbolsjmjlmfpfifq`j`jlfgjwlqjbopbobnbm`bdlmy/Mofygl`vnfmwlsfo/A`vobqf`jfmwfpdfmfqbofpwbqqbdlmbsq/M`wj`bmlufgbgfpsqlsvfpwbsb`jfmwfpw/E`mj`bplaifwjulp`lmwb`wlp\fHB\fIk\fHn\fH^\fHS\fHc\fHU\fId\fHn\fH{\fHC\fHR\fHT\fHR\fHI\fHc\fHY\fHn\fH\\\fHU\fIk\fHy\fIg\fHd\fHy\fIm\fHw\fH\\\fHU\fHR\fH@\fHR\fHJ\fHy\fHU\fHR\fHT\fHA\fIl\fHU\fIm\fHc\fH\\\fHU\fIl\fHB\fId\fHn\fHJ\fHS\fHD\fH@\fHR\fHHgjsolgl`p\fHT\fHB\fHC\fH\\\fIn\fHF\fHD\fHR\fHB\fHF\fHH\fHR\fHG\fHS\fH\\\fHx\fHT\fHH\fHH\fH\\\fHU\fH^\fIg\fH{\fHU\fIm\fHj\fH@\fHR\fH\\\fHJ\fIk\fHZ\fHU\fIm\fHd\fHz\fIk\fH^\fHC\fHJ\fHS\fHy\fHR\fHB\fHY\fIk\fH@\fHH\fIl\fHD\fH@\fIl\fHv\fHB\fI`\fHH\fHT\fHR\fH^\fH^\fIk\fHz\fHp\fIe\fH@\fHB\fHJ\fHJ\fHH\fHI\fHR\fHD\fHU\fIl\fHZ\fHU\fH\\\fHi\fH^\fH{\fHy\fHA\fIl\fHD\fH{\fH\\\fHF\fHR\fHT\fH\\\fHR\fHH\fHy\fHS\fHc\fHe\fHT\fIk\fH{\fHC\fIl\fHU\fIn\fHm\fHj\fH{\fIk\fHs\fIl\fHB\fHz\fIg\fHp\fHy\fHR\fH\\\fHi\fHA\fIl\fH{\fHC\fIk\fHH\fIm\fHB\fHY\fIg\fHs\fHJ\fIk\fHn\fHi\fH{\fH\\\fH|\fHT\fIk\fHB\fIk\fH^\fH^\fH{\fHR\fHU\fHR\fH^\fHf\fHF\fH\\\fHv\fHR\fH\\\fH|\fHT\fHR\fHJ\fIk\fH\\\fHp\fHS\fHT\fHJ\fHS\fH^\fH@\fHn\fHJ\fH@\fHD\fHR\fHU\fIn\fHn\fH^\fHR\fHz\fHp\fIl\fHH\fH@\fHs\fHD\fHB\fHS\fH^\fHk\fHT\fIk\fHj\fHD\fIk\fHD\fHC\fHR\fHy\fIm\fH^\fH^\fIe\fH{\fHA\fHR\fH{\fH\\\fIk\fH^\fHp\fH{\fHU\fH\\\fHR\fHB\fH^\fH{\fIk\fHF\fIk\fHp\fHU\fHR\fHI\fHk\fHT\fIl\fHT\fHU\fIl\fHy\fH^\fHR\fHL\fIl\fHy\fHU\fHR\fHm\fHJ\fIn\fH\\\fHH\fHU\fHH\fHT\fHR\fHH\fHC\fHR\fHJ\fHj\fHC\fHR\fHF\fHR\fHy\fHy\fI`\fHD\fHZ\fHR\fHB\fHJ\fIk\fHz\fHC\fHU\fIl\fH\\\fHR\fHC\fHz\fIm\fHJ\fH^\fH{\fIl`bwfdlqjfpf{sfqjfm`f?,wjwof=\t@lszqjdkw#ibubp`qjsw`lmgjwjlmpfufqzwkjmd?s#`obpp>!wf`kmloldzab`hdqlvmg?b#`obpp>!nbmbdfnfmw%`lsz8#132ibubP`qjsw`kbqb`wfqpaqfbg`qvnawkfnpfoufpklqjylmwbodlufqmnfmw@bojelqmjbb`wjujwjfpgjp`lufqfgMbujdbwjlmwqbmpjwjlm`lmmf`wjlmmbujdbwjlmbssfbqbm`f?,wjwof=?n`kf`hal{!#wf`kmjrvfpsqlwf`wjlmbssbqfmwozbp#tfoo#bpvmw$/#$VB.qfplovwjlmlsfqbwjlmpwfofujpjlmwqbmpobwfgTbpkjmdwlmmbujdbwlq-#>#tjmglt-jnsqfppjlm%ow8aq%dw8ojwfqbwvqfslsvobwjlmad`lolq>! fpsf`jbooz#`lmwfmw>!sqlgv`wjlmmftpofwwfqsqlsfqwjfpgfejmjwjlmofbgfqpkjsWf`kmloldzSbqojbnfmw`lnsbqjplmvo#`obpp>!-jmgf{Le+!`lm`ovpjlmgjp`vppjlm`lnslmfmwpajloldj`boQfulovwjlm\\`lmwbjmfqvmgfqpwllgmlp`qjsw=?sfqnjppjlmfb`k#lwkfqbwnlpskfqf#lmel`vp>!?elqn#jg>!sql`fppjmdwkjp-ubovfdfmfqbwjlm@lmefqfm`fpvapfrvfmwtfoo.hmltmubqjbwjlmpqfsvwbwjlmskfmlnfmlmgjp`jsojmfoldl-smd!#+gl`vnfmw/alvmgbqjfpf{sqfppjlmpfwwofnfmwAb`hdqlvmglvw#le#wkffmwfqsqjpf+!kwwsp9!#vmfp`bsf+!sbpptlqg!#gfnl`qbwj`?b#kqfe>!,tqbssfq!=\tnfnafqpkjsojmdvjpwj`s{8sbggjmdskjolplskzbppjpwbm`fvmjufqpjwzeb`jojwjfpqf`ldmjyfgsqfefqfm`fje#+wzsflenbjmwbjmfgul`bavobqzkzslwkfpjp-pvanjw+*8%bns8maps8bmmlwbwjlmafkjmg#wkfElvmgbwjlmsvaojpkfq!bppvnswjlmjmwqlgv`fg`lqqvswjlmp`jfmwjpwpf{soj`jwozjmpwfbg#legjnfmpjlmp#lm@oj`h>!`lmpjgfqfggfsbqwnfmwl``vsbwjlmpllm#bewfqjmufpwnfmwsqlmlvm`fgjgfmwjejfgf{sfqjnfmwNbmbdfnfmwdfldqbskj`!#kfjdkw>!ojmh#qfo>!-qfsob`f+,gfsqfppjlm`lmefqfm`fsvmjpknfmwfojnjmbwfgqfpjpwbm`fbgbswbwjlmlsslpjwjlmtfoo#hmltmpvssofnfmwgfwfqnjmfgk2#`obpp>!3s{8nbqdjmnf`kbmj`bopwbwjpwj`p`fofaqbwfgDlufqmnfmw\t\tGvqjmd#wgfufolsfqpbqwjej`jbofrvjubofmwlqjdjmbwfg@lnnjppjlmbwwb`knfmw?psbm#jg>!wkfqf#tfqfMfgfqobmgpafzlmg#wkfqfdjpwfqfgilvqmbojpweqfrvfmwozboo#le#wkfobmd>!fm!#?,pwzof=\tbaplovwf8#pvsslqwjmdf{wqfnfoz#nbjmpwqfbn?,pwqlmd=#slsvobqjwzfnsolznfmw?,wbaof=\t#`lopsbm>!?,elqn=\t##`lmufqpjlmbalvw#wkf#?,s=?,gju=jmwfdqbwfg!#obmd>!fmSlqwvdvfpfpvapwjwvwfjmgjujgvbojnslppjaofnvowjnfgjbbonlpw#boos{#plojg# bsbqw#eqlnpvaif`w#wljm#Fmdojpk`qjwj`jyfgf{`fsw#elqdvjgfojmfplqjdjmboozqfnbqhbaofwkf#pf`lmgk1#`obpp>!?b#wjwof>!+jm`ovgjmdsbqbnfwfqpsqlkjajwfg>#!kwws9,,gj`wjlmbqzsfq`fswjlmqfulovwjlmelvmgbwjlms{8kfjdkw9pv``fppevopvsslqwfqpnjoofmmjvnkjp#ebwkfqwkf#%rvlw8ml.qfsfbw8`lnnfq`jbojmgvpwqjbofm`lvqbdfgbnlvmw#le#vmleej`jbofeej`jfm`zQfefqfm`fp`llqgjmbwfgjp`objnfqf{sfgjwjlmgfufolsjmd`bo`vobwfgpjnsojejfgofdjwjnbwfpvapwqjmd+3!#`obpp>!`lnsofwfozjoovpwqbwfejuf#zfbqpjmpwqvnfmwSvaojpkjmd2!#`obpp>!spz`kloldz`lmejgfm`fmvnafq#le#bapfm`f#leel`vpfg#lmiljmfg#wkfpwqv`wvqfpsqfujlvpoz=?,jeqbnf=lm`f#bdbjmavw#qbwkfqjnnjdqbmwple#`lvqpf/b#dqlvs#leOjwfqbwvqfVmojhf#wkf?,b=%maps8\tevm`wjlm#jw#tbp#wkf@lmufmwjlmbvwlnlajofSqlwfpwbmwbddqfppjufbewfq#wkf#Pjnjobqoz/!#,=?,gju=`loof`wjlm\tevm`wjlmujpjajojwzwkf#vpf#leulovmwffqpbwwqb`wjlmvmgfq#wkf#wkqfbwfmfg)?"X@GBWBXjnslqwbm`fjm#dfmfqbowkf#obwwfq?,elqn=\t?,-jmgf{Le+$j#>#38#j#?gjeefqfm`fgfulwfg#wlwqbgjwjlmppfbq`k#elqvowjnbwfozwlvqmbnfmwbwwqjavwfppl.`boofg#~\t?,pwzof=fubovbwjlmfnskbpjyfgb``fppjaof?,pf`wjlm=pv``fppjlmbolmd#tjwkNfbmtkjof/jmgvpwqjfp?,b=?aq#,=kbp#af`lnfbpsf`wp#leWfofujpjlmpveej`jfmwabphfwabooalwk#pjgfp`lmwjmvjmdbm#bqwj`of?jnd#bow>!bgufmwvqfpkjp#nlwkfqnbm`kfpwfqsqjm`jsofpsbqwj`vobq`lnnfmwbqzfeef`wp#legf`jgfg#wl!=?pwqlmd=svaojpkfqpIlvqmbo#legjeej`vowzeb`jojwbwfb``fswbaofpwzof-`pp!\nevm`wjlm#jmmlubwjlm=@lszqjdkwpjwvbwjlmptlvog#kbufavpjmfppfpGj`wjlmbqzpwbwfnfmwplewfm#vpfgsfqpjpwfmwjm#Ibmvbqz`lnsqjpjmd?,wjwof=\t\ngjsolnbwj``lmwbjmjmdsfqelqnjmdf{wfmpjlmpnbz#mlw#af`lm`fsw#le#lm`oj`h>!Jw#jp#boplejmbm`jbo#nbhjmd#wkfOv{fnalvqdbggjwjlmbobqf#`boofgfmdbdfg#jm!p`qjsw!*8avw#jw#tbpfof`wqlmj`lmpvanjw>!\t?"..#Fmg#fof`wqj`boleej`jboozpvddfpwjlmwls#le#wkfvmojhf#wkfBvpwqbojbmLqjdjmboozqfefqfm`fp\t?,kfbg=\tqf`ldmjpfgjmjwjbojyfojnjwfg#wlBof{bmgqjbqfwjqfnfmwBgufmwvqfpelvq#zfbqp\t\t%ow8"..#jm`qfbpjmdgf`lqbwjlmk0#`obpp>!lqjdjmp#lelaojdbwjlmqfdvobwjlm`obppjejfg+evm`wjlm+bgubmwbdfpafjmd#wkf#kjpwlqjbmp?abpf#kqfeqfsfbwfgoztjoojmd#wl`lnsbqbaofgfpjdmbwfgmlnjmbwjlmevm`wjlmbojmpjgf#wkfqfufobwjlmfmg#le#wkfp#elq#wkf#bvwklqjyfgqfevpfg#wlwbhf#sob`fbvwlmlnlvp`lnsqlnjpfslojwj`bo#qfpwbvqbmwwtl#le#wkfEfaqvbqz#1rvbojwz#leptelaif`w-vmgfqpwbmgmfbqoz#bootqjwwfm#azjmwfqujftp!#tjgwk>!2tjwkgqbtboeolbw9ofewjp#vpvbooz`bmgjgbwfpmftpsbsfqpnzpwfqjlvpGfsbqwnfmwafpw#hmltmsbqojbnfmwpvssqfppfg`lmufmjfmwqfnfnafqfggjeefqfmw#pzpwfnbwj`kbp#ofg#wlsqlsbdbmgb`lmwqloofgjmeovfm`fp`fqfnlmjbosql`objnfgSqlwf`wjlmoj#`obpp>!P`jfmwjej``obpp>!ml.wqbgfnbqhpnlqf#wkbm#tjgfpsqfbgOjafqbwjlmwllh#sob`fgbz#le#wkfbp#olmd#bpjnsqjplmfgBggjwjlmbo\t?kfbg=\t?nObalqbwlqzMlufnafq#1f{`fswjlmpJmgvpwqjboubqjfwz#leeolbw9#ofeGvqjmd#wkfbppfppnfmwkbuf#affm#gfbop#tjwkPwbwjpwj`pl``vqqfm`f,vo=?,gju=`ofbqej{!=wkf#svaoj`nbmz#zfbqptkj`k#tfqflufq#wjnf/pzmlmznlvp`lmwfmw!=\tsqfpvnbaozkjp#ebnjozvpfqBdfmw-vmf{sf`wfgjm`ovgjmd#`kboofmdfgb#njmlqjwzvmgfejmfg!afolmdp#wlwbhfm#eqlnjm#L`wlafqslpjwjlm9#pbjg#wl#afqfojdjlvp#Efgfqbwjlm#qltpsbm>!lmoz#b#eftnfbmw#wkbwofg#wl#wkf..=\t?gju#?ejfogpfw=Bq`kajpkls#`obpp>!mlafjmd#vpfgbssqlb`kfpsqjujofdfpmlp`qjsw=\tqfpvowp#jmnbz#af#wkfFbpwfq#fddnf`kbmjpnpqfbplmbaofSlsvobwjlm@loof`wjlmpfof`wfg!=mlp`qjsw=,jmgf{-sksbqqjubo#le.ippgh$**8nbmbdfg#wljm`lnsofwf`bpvbowjfp`lnsofwjlm@kqjpwjbmpPfswfnafq#bqjwknfwj`sql`fgvqfpnjdkw#kbufSqlgv`wjlmjw#bssfbqpSkjolplskzeqjfmgpkjsofbgjmd#wldjujmd#wkfwltbqg#wkfdvbqbmwffggl`vnfmwfg`lolq9 333ujgfl#dbnf`lnnjppjlmqfeof`wjmd`kbmdf#wkfbppl`jbwfgpbmp.pfqjelmhfzsqfpp8#sbggjmd9Kf#tbp#wkfvmgfqozjmdwzsj`booz#/#bmg#wkf#pq`Fofnfmwpv``fppjufpjm`f#wkf#pklvog#af#mfwtlqhjmdb``lvmwjmdvpf#le#wkfoltfq#wkbmpkltp#wkbw?,psbm=\t\n\n`lnsobjmwp`lmwjmvlvprvbmwjwjfpbpwqlmlnfqkf#gjg#mlwgvf#wl#jwpbssojfg#wlbm#bufqbdffeelqwp#wlwkf#evwvqfbwwfnsw#wlWkfqfelqf/`bsbajojwzQfsvaoj`bmtbp#elqnfgFof`wqlmj`hjolnfwfqp`kboofmdfpsvaojpkjmdwkf#elqnfqjmgjdfmlvpgjqf`wjlmppvapjgjbqz`lmpsjqb`zgfwbjop#lebmg#jm#wkfbeelqgbaofpvapwbm`fpqfbplm#elq`lmufmwjlmjwfnwzsf>!baplovwfozpvsslpfgozqfnbjmfg#bbwwqb`wjufwqbufoojmdpfsbqbwfozel`vpfp#lmfofnfmwbqzbssoj`baofelvmg#wkbwpwzofpkffwnbmvp`qjswpwbmgp#elq#ml.qfsfbw+plnfwjnfp@lnnfq`jbojm#Bnfqj`bvmgfqwbhfmrvbqwfq#lebm#f{bnsofsfqplmboozjmgf{-sks!owqOjfvwfmbmw\t?gju#jg>!wkfz#tlvogbajojwz#lenbgf#vs#lemlwfg#wkbw`ofbq#wkbwbqdvf#wkbwwl#bmlwkfq`kjogqfm$psvqslpf#leelqnvobwfgabpfg#vslmwkf#qfdjlmpvaif`w#lesbppfmdfqpslppfppjlm-\t\tJm#wkf#Afelqf#wkfbewfqtbqgp`vqqfmwoz#b`qlpp#wkfp`jfmwjej``lnnvmjwz-`bsjwbojpnjm#Dfqnbmzqjdkw.tjmdwkf#pzpwfnPl`jfwz#leslojwj`jbmgjqf`wjlm9tfmw#lm#wlqfnlubo#le#Mft#Zlqh#bsbqwnfmwpjmgj`bwjlmgvqjmd#wkfvmofpp#wkfkjpwlqj`bokbg#affm#bgfejmjwjufjmdqfgjfmwbwwfmgbm`f@fmwfq#elqsqlnjmfm`fqfbgzPwbwfpwqbwfdjfpavw#jm#wkfbp#sbqw#le`lmpwjwvwf`objn#wkbwobalqbwlqz`lnsbwjaofebjovqf#le/#pv`k#bp#afdbm#tjwkvpjmd#wkf#wl#sqlujgfefbwvqf#leeqln#tkj`k,!#`obpp>!dfloldj`bopfufqbo#legfojafqbwfjnslqwbmw#klogp#wkbwjmd%rvlw8#ubojdm>wlswkf#Dfqnbmlvwpjgf#lemfdlwjbwfgkjp#`bqffqpfsbqbwjlmjg>!pfbq`ktbp#`boofgwkf#elvqwkqf`qfbwjlmlwkfq#wkbmsqfufmwjlmtkjof#wkf#fgv`bwjlm/`lmmf`wjmdb``vqbwfoztfqf#avjowtbp#hjoofgbdqffnfmwpnv`k#nlqf#Gvf#wl#wkftjgwk9#233plnf#lwkfqHjmdgln#lewkf#fmwjqfebnlvp#elqwl#`lmmf`wlaif`wjufpwkf#Eqfm`ksflsof#bmgefbwvqfg!=jp#pbjg#wlpwqv`wvqboqfefqfmgvnnlpw#lewfmb#pfsbqbwf.=\t?gju#jg#Leej`jbo#tlqogtjgf-bqjb.obafowkf#sobmfwbmg#jw#tbpg!#ubovf>!ollhjmd#bwafmfej`jbobqf#jm#wkfnlmjwlqjmdqfslqwfgozwkf#nlgfqmtlqhjmd#lmbooltfg#wltkfqf#wkf#jmmlubwjuf?,b=?,gju=plvmgwqb`hpfbq`kElqnwfmg#wl#afjmsvw#jg>!lsfmjmd#leqfpwqj`wfgbglswfg#azbggqfppjmdwkfloldjbmnfwklgp#leubqjbmw#le@kqjpwjbm#ufqz#obqdfbvwlnlwjufaz#ebq#wkfqbmdf#eqlnsvqpvjw#leeloolt#wkfaqlvdkw#wljm#Fmdobmgbdqff#wkbwb``vpfg#le`lnfp#eqlnsqfufmwjmdgju#pwzof>kjp#lq#kfqwqfnfmglvpeqffgln#le`lm`fqmjmd3#2fn#2fn8Abphfwaboo,pwzof-`ppbm#fbqojfqfufm#bewfq,!#wjwof>!-`ln,jmgf{wbhjmd#wkfsjwwpavqdk`lmwfmw!=?p`qjsw=+ewvqmfg#lvwkbujmd#wkf?,psbm=\t#l``bpjlmboaf`bvpf#jwpwbqwfg#wlskzpj`booz=?,gju=\t##`qfbwfg#az@vqqfmwoz/#ad`lolq>!wbajmgf{>!gjpbpwqlvpBmbozwj`p#bopl#kbp#b=?gju#jg>!?,pwzof=\t?`boofg#elqpjmdfq#bmg-pq`#>#!,,ujlobwjlmpwkjp#sljmw`lmpwbmwozjp#ol`bwfgqf`lqgjmdpg#eqln#wkfmfgfqobmgpslqwvdv/Fp;N;};D;u;F5m4K4]4_7`gfpbqqlool`lnfmwbqjlfgv`b`j/_mpfswjfnaqfqfdjpwqbglgjqf``j/_mvaj`b`j/_msvaoj`jgbgqfpsvfpwbpqfpvowbglpjnslqwbmwfqfpfqubglpbqw/A`volpgjefqfmwfppjdvjfmwfpqfs/Vaoj`bpjwvb`j/_mnjmjpwfqjlsqjub`jgbggjqf`wlqjlelqnb`j/_mslaob`j/_msqfpjgfmwf`lmw','fmjglpb``fplqjlpwf`kmlqbwjsfqplmbofp`bwfdlq/Abfpsf`jbofpgjpslmjaofb`wvbojgbgqfefqfm`jbuboobglojgajaojlwf`bqfob`jlmfp`bofmgbqjlslo/Awj`bpbmwfqjlqfpgl`vnfmwlpmbwvqbofybnbwfqjbofpgjefqfm`jbf`lm/_nj`bwqbmpslqwfqlgq/Advfysbqwj`jsbqfm`vfmwqbmgjp`vpj/_mfpwqv`wvqbevmgb`j/_meqf`vfmwfpsfqnbmfmwfwlwbonfmwf!2s{#plojg# -dje!#bow>!wqbmpsbqfmwjmelqnbwjlmbssoj`bwjlm!#lm`oj`h>!fpwbaojpkfgbgufqwjpjmd-smd!#bow>!fmujqlmnfmwsfqelqnbm`fbssqlsqjbwf%bns8ngbpk8jnnfgjbwfoz?,pwqlmd=?,qbwkfq#wkbmwfnsfqbwvqfgfufolsnfmw`lnsfwjwjlmsob`fklogfqujpjajojwz9`lszqjdkw!=3!#kfjdkw>!fufm#wklvdkqfsob`fnfmwgfpwjmbwjlm@lqslqbwjlm?vo#`obpp>!Bppl`jbwjlmjmgjujgvbopsfqpsf`wjufpfwWjnflvw+vqo+kwws9,,nbwkfnbwj`pnbqdjm.wls9fufmwvbooz#gfp`qjswjlm*#ml.qfsfbw`loof`wjlmp-ISDwkvnasbqwj`jsbwf,kfbg=?algzeolbw9ofew8?oj#`obpp>!kvmgqfgp#le\t\tKltfufq/#`lnslpjwjlm`ofbq9alwk8`llsfqbwjlmtjwkjm#wkf#obafo#elq>!alqgfq.wls9Mft#Yfbobmgqf`lnnfmgfgsklwldqbskzjmwfqfpwjmd%ow8pvs%dw8`lmwqlufqpzMfwkfqobmgpbowfqmbwjufnb{ofmdwk>!ptjwyfqobmgGfufolsnfmwfppfmwjbooz\t\tBowklvdk#?,wf{wbqfb=wkvmgfqajqgqfsqfpfmwfg%bns8mgbpk8psf`vobwjlm`lnnvmjwjfpofdjpobwjlmfof`wqlmj`p\t\n?gju#jg>!joovpwqbwfgfmdjmffqjmdwfqqjwlqjfpbvwklqjwjfpgjpwqjavwfg5!#kfjdkw>!pbmp.pfqje8`bsbaof#le#gjpbssfbqfgjmwfqb`wjufollhjmd#elqjw#tlvog#afBedkbmjpwbmtbp#`qfbwfgNbwk-eollq+pvqqlvmgjmd`bm#bopl#aflapfqubwjlmnbjmwfmbm`ffm`lvmwfqfg?k1#`obpp>!nlqf#qf`fmwjw#kbp#affmjmubpjlm#le*-dfwWjnf+*evmgbnfmwboGfpsjwf#wkf!=?gju#jg>!jmpsjqbwjlmf{bnjmbwjlmsqfsbqbwjlmf{sobmbwjlm?jmsvw#jg>!?,b=?,psbm=ufqpjlmp#lejmpwqvnfmwpafelqf#wkf##>#$kwws9,,Gfp`qjswjlmqfobwjufoz#-pvapwqjmd+fb`k#le#wkff{sfqjnfmwpjmeovfmwjbojmwfdqbwjlmnbmz#sflsofgvf#wl#wkf#`lnajmbwjlmgl#mlw#kbufNjggof#Fbpw?mlp`qjsw=?`lszqjdkw!#sfqkbsp#wkfjmpwjwvwjlmjm#Gf`fnafqbqqbmdfnfmwnlpw#ebnlvpsfqplmbojwz`qfbwjlm#leojnjwbwjlmpf{`ovpjufozplufqfjdmwz.`lmwfmw!=\t?wg#`obpp>!vmgfqdqlvmgsbqboofo#wlgl`wqjmf#lel``vsjfg#azwfqnjmloldzQfmbjppbm`fb#mvnafq#lepvsslqw#elqf{solqbwjlmqf`ldmjwjlmsqfgf`fpplq?jnd#pq`>!,?k2#`obpp>!svaoj`bwjlmnbz#bopl#afpsf`jbojyfg?,ejfogpfw=sqldqfppjufnjoojlmp#lepwbwfp#wkbwfmelq`fnfmwbqlvmg#wkf#lmf#bmlwkfq-sbqfmwMlgfbdqj`vowvqfBowfqmbwjufqfpfbq`kfqpwltbqgp#wkfNlpw#le#wkfnbmz#lwkfq#+fpsf`jbooz?wg#tjgwk>!8tjgwk9233&jmgfsfmgfmw?k0#`obpp>!#lm`kbmdf>!*-bgg@obpp+jmwfqb`wjlmLmf#le#wkf#gbvdkwfq#leb``fpplqjfpaqbm`kfp#le\t?gju#jg>!wkf#obqdfpwgf`obqbwjlmqfdvobwjlmpJmelqnbwjlmwqbmpobwjlmgl`vnfmwbqzjm#lqgfq#wl!=\t?kfbg=\t?!#kfjdkw>!2b`qlpp#wkf#lqjfmwbwjlm*8?,p`qjsw=jnsofnfmwfg`bm#af#pffmwkfqf#tbp#bgfnlmpwqbwf`lmwbjmfq!=`lmmf`wjlmpwkf#Aqjwjpktbp#tqjwwfm"jnslqwbmw8s{8#nbqdjm.elooltfg#azbajojwz#wl#`lnsoj`bwfggvqjmd#wkf#jnnjdqbwjlmbopl#`boofg?k7#`obpp>!gjpwjm`wjlmqfsob`fg#azdlufqmnfmwpol`bwjlm#lejm#Mlufnafqtkfwkfq#wkf?,s=\t?,gju=b`rvjpjwjlm`boofg#wkf#sfqpf`vwjlmgfpjdmbwjlmxelmw.pjyf9bssfbqfg#jmjmufpwjdbwff{sfqjfm`fgnlpw#ojhfoztjgfoz#vpfggjp`vppjlmpsqfpfm`f#le#+gl`vnfmw-f{wfmpjufozJw#kbp#affmjw#glfp#mlw`lmwqbqz#wljmkbajwbmwpjnsqlufnfmwp`klobqpkjs`lmpvnswjlmjmpwqv`wjlmelq#f{bnsoflmf#lq#nlqfs{8#sbggjmdwkf#`vqqfmwb#pfqjfp#lebqf#vpvboozqlof#jm#wkfsqfujlvpoz#gfqjubwjufpfujgfm`f#lef{sfqjfm`fp`lolqp`kfnfpwbwfg#wkbw`fqwjej`bwf?,b=?,gju=\t#pfof`wfg>!kjdk#p`klloqfpslmpf#wl`lnelqwbaofbglswjlm#lewkqff#zfbqpwkf#`lvmwqzjm#Efaqvbqzpl#wkbw#wkfsflsof#tkl#sqlujgfg#az?sbqbn#mbnfbeef`wfg#azjm#wfqnp#lebssljmwnfmwJPL.;;6:.2!tbp#alqm#jmkjpwlqj`bo#qfdbqgfg#bpnfbpvqfnfmwjp#abpfg#lm#bmg#lwkfq#9#evm`wjlm+pjdmjej`bmw`fofaqbwjlmwqbmpnjwwfg,ip,irvfqz-jp#hmltm#bpwkflqfwj`bo#wbajmgf{>!jw#`lvog#af?mlp`qjsw=\tkbujmd#affm\t?kfbg=\t?#%rvlw8Wkf#`lnsjobwjlmkf#kbg#affmsqlgv`fg#azskjolplskfq`lmpwqv`wfgjmwfmgfg#wlbnlmd#lwkfq`lnsbqfg#wlwl#pbz#wkbwFmdjmffqjmdb#gjeefqfmwqfefqqfg#wlgjeefqfm`fpafojfe#wkbwsklwldqbskpjgfmwjezjmdKjpwlqz#le#Qfsvaoj`#lemf`fppbqjozsqlabajojwzwf`kmj`boozofbujmd#wkfpsf`wb`vobqeqb`wjlm#lefof`wqj`jwzkfbg#le#wkfqfpwbvqbmwpsbqwmfqpkjsfnskbpjp#lmnlpw#qf`fmwpkbqf#tjwk#pbzjmd#wkbwejoofg#tjwkgfpjdmfg#wljw#jp#lewfm!=?,jeqbnf=bp#elooltp9nfqdfg#tjwkwkqlvdk#wkf`lnnfq`jbo#sljmwfg#lvwlsslqwvmjwzujft#le#wkfqfrvjqfnfmwgjujpjlm#lesqldqbnnjmdkf#qf`fjufgpfwJmwfqubo!=?,psbm=?,jm#Mft#Zlqhbggjwjlmbo#`lnsqfppjlm\t\t?gju#jg>!jm`lqslqbwf8?,p`qjsw=?bwwb`kFufmwaf`bnf#wkf#!#wbqdfw>!\\`bqqjfg#lvwPlnf#le#wkfp`jfm`f#bmgwkf#wjnf#le@lmwbjmfq!=nbjmwbjmjmd@kqjpwlskfqNv`k#le#wkftqjwjmdp#le!#kfjdkw>!1pjyf#le#wkfufqpjlm#le#nj{wvqf#le#afwtffm#wkfF{bnsofp#lefgv`bwjlmbo`lnsfwjwjuf#lmpvanjw>!gjqf`wlq#legjpwjm`wjuf,GWG#[KWNO#qfobwjmd#wlwfmgfm`z#wlsqlujm`f#letkj`k#tlvoggfpsjwf#wkfp`jfmwjej`#ofdjpobwvqf-jmmfqKWNO#boofdbwjlmpBdqj`vowvqftbp#vpfg#jmbssqlb`k#wljmwfoojdfmwzfbqp#obwfq/pbmp.pfqjegfwfqnjmjmdSfqelqnbm`fbssfbqbm`fp/#tkj`k#jp#elvmgbwjlmpbaaqfujbwfgkjdkfq#wkbmp#eqln#wkf#jmgjujgvbo#`lnslpfg#lepvsslpfg#wl`objnp#wkbwbwwqjavwjlmelmw.pjyf92fofnfmwp#leKjpwlqj`bo#kjp#aqlwkfqbw#wkf#wjnfbmmjufqpbqzdlufqmfg#azqfobwfg#wl#vowjnbwfoz#jmmlubwjlmpjw#jp#pwjoo`bm#lmoz#afgfejmjwjlmpwlDNWPwqjmdB#mvnafq#lejnd#`obpp>!Fufmwvbooz/tbp#`kbmdfgl``vqqfg#jmmfjdkalqjmdgjpwjmdvjpktkfm#kf#tbpjmwqlgv`jmdwfqqfpwqjboNbmz#le#wkfbqdvfp#wkbwbm#Bnfqj`bm`lmrvfpw#letjgfpsqfbg#tfqf#hjoofgp`qffm#bmg#Jm#lqgfq#wlf{sf`wfg#wlgfp`fmgbmwpbqf#ol`bwfgofdjpobwjufdfmfqbwjlmp#ab`hdqlvmgnlpw#sflsofzfbqp#bewfqwkfqf#jp#mlwkf#kjdkfpweqfrvfmwoz#wkfz#gl#mlwbqdvfg#wkbwpkltfg#wkbwsqfglnjmbmwwkfloldj`boaz#wkf#wjnf`lmpjgfqjmdpklqw.ojufg?,psbm=?,b=`bm#af#vpfgufqz#ojwwoflmf#le#wkf#kbg#boqfbgzjmwfqsqfwfg`lnnvmj`bwfefbwvqfp#ledlufqmnfmw/?,mlp`qjsw=fmwfqfg#wkf!#kfjdkw>!0Jmgfsfmgfmwslsvobwjlmpobqdf.p`bof-#Bowklvdk#vpfg#jm#wkfgfpwqv`wjlmslppjajojwzpwbqwjmd#jmwtl#lq#nlqff{sqfppjlmppvalqgjmbwfobqdfq#wkbmkjpwlqz#bmg?,lswjlm=\t@lmwjmfmwbofojnjmbwjmdtjoo#mlw#afsqb`wj`f#lejm#eqlmw#lepjwf#le#wkffmpvqf#wkbwwl#`qfbwf#bnjppjppjssjslwfmwjboozlvwpwbmgjmdafwwfq#wkbmtkbw#jp#mltpjwvbwfg#jmnfwb#mbnf>!WqbgjwjlmbopvddfpwjlmpWqbmpobwjlmwkf#elqn#lebwnlpskfqj`jgfloldj`bofmwfqsqjpfp`bo`vobwjmdfbpw#le#wkfqfnmbmwp#lesovdjmpsbdf,jmgf{-sks!Wkjp#jp#wkf#?b#kqfe>!,slsvobqjyfgjmuloufg#jmbqf#vpfg#wlbmg#pfufqbonbgf#az#wkfpffnp#wl#afojhfoz#wkbwSbofpwjmjbmmbnfg#bewfqjw#kbg#affmnlpw#`lnnlmwl#qfefq#wlavw#wkjp#jp`lmpf`vwjufwfnslqbqjozJm#dfmfqbo/`lmufmwjlmpwbhfp#sob`fpvagjujpjlmwfqqjwlqjbolsfqbwjlmbosfqnbmfmwoztbp#obqdfozlvwaqfbh#lejm#wkf#sbpwelooltjmd#b#{nomp9ld>!=?b#`obpp>!`obpp>!wf{w@lmufqpjlm#nbz#af#vpfgnbmveb`wvqfbewfq#afjmd`ofbqej{!=\trvfpwjlm#letbp#fof`wfgwl#af`lnf#baf`bvpf#le#plnf#sflsofjmpsjqfg#azpv``fppevo#b#wjnf#tkfmnlqf#`lnnlmbnlmdpw#wkfbm#leej`jbotjgwk9233&8wf`kmloldz/tbp#bglswfgwl#hffs#wkfpfwwofnfmwpojuf#ajqwkpjmgf{-kwno!@lmmf`wj`vwbppjdmfg#wl%bns8wjnfp8b``lvmw#elqbojdm>qjdkwwkf#`lnsbmzbotbzp#affmqfwvqmfg#wljmuloufnfmwAf`bvpf#wkfwkjp#sfqjlg!#mbnf>!r!#`lmejmfg#wlb#qfpvow#leubovf>!!#,=jp#b`wvboozFmujqlmnfmw\t?,kfbg=\t@lmufqpfoz/=\t?gju#jg>!3!#tjgwk>!2jp#sqlabaozkbuf#af`lnf`lmwqloojmdwkf#sqlaofn`jwjyfmp#leslojwj`jbmpqfb`kfg#wkfbp#fbqoz#bp9mlmf8#lufq?wbaof#`fooubojgjwz#legjqf`woz#wllmnlvpfgltmtkfqf#jw#jptkfm#jw#tbpnfnafqp#le#qfobwjlm#wlb``lnnlgbwfbolmd#tjwk#Jm#wkf#obwfwkf#Fmdojpkgfoj`jlvp!=wkjp#jp#mlwwkf#sqfpfmwje#wkfz#bqfbmg#ejmboozb#nbwwfq#le\t\n?,gju=\t\t?,p`qjsw=ebpwfq#wkbmnbilqjwz#lebewfq#tkj`k`lnsbqbwjufwl#nbjmwbjmjnsqluf#wkfbtbqgfg#wkffq!#`obpp>!eqbnfalqgfqqfpwlqbwjlmjm#wkf#pbnfbmbozpjp#lewkfjq#ejqpwGvqjmd#wkf#`lmwjmfmwbopfrvfm`f#leevm`wjlm+*xelmw.pjyf9#tlqh#lm#wkf?,p`qjsw=\t?afdjmp#tjwkibubp`qjsw9`lmpwjwvfmwtbp#elvmgfgfrvjojaqjvnbppvnf#wkbwjp#djufm#azmffgp#wl#af`llqgjmbwfpwkf#ubqjlvpbqf#sbqw#lelmoz#jm#wkfpf`wjlmp#lejp#b#`lnnlmwkflqjfp#legjp`lufqjfpbppl`jbwjlmfgdf#le#wkfpwqfmdwk#leslpjwjlm#jmsqfpfmw.gbzvmjufqpboozwl#elqn#wkfavw#jmpwfbg`lqslqbwjlmbwwb`kfg#wljp#`lnnlmozqfbplmp#elq#%rvlw8wkf#`bm#af#nbgftbp#baof#wltkj`k#nfbmpavw#gjg#mlwlmNlvpfLufqbp#slppjaoflsfqbwfg#az`lnjmd#eqlnwkf#sqjnbqzbggjwjlm#leelq#pfufqbowqbmpefqqfgb#sfqjlg#lebqf#baof#wlkltfufq/#jwpklvog#kbufnv`k#obqdfq\t\n?,p`qjsw=bglswfg#wkfsqlsfqwz#legjqf`wfg#azfeef`wjufoztbp#aqlvdkw`kjogqfm#leSqldqbnnjmdolmdfq#wkbmnbmvp`qjswptbq#bdbjmpwaz#nfbmp#lebmg#nlpw#lepjnjobq#wl#sqlsqjfwbqzlqjdjmbwjmdsqfpwjdjlvpdqbnnbwj`bof{sfqjfm`f-wl#nbhf#wkfJw#tbp#bopljp#elvmg#jm`lnsfwjwlqpjm#wkf#V-P-qfsob`f#wkfaqlvdkw#wkf`bo`vobwjlmeboo#le#wkfwkf#dfmfqbosqb`wj`boozjm#klmlq#leqfofbpfg#jmqfpjgfmwjbobmg#plnf#lehjmd#le#wkfqfb`wjlm#wl2pw#Fbqo#le`vowvqf#bmgsqjm`jsbooz?,wjwof=\t##wkfz#`bm#afab`h#wl#wkfplnf#le#kjpf{slpvqf#wlbqf#pjnjobqelqn#le#wkfbggEbulqjwf`jwjyfmpkjssbqw#jm#wkfsflsof#tjwkjm#sqb`wj`fwl#`lmwjmvf%bns8njmvp8bssqlufg#az#wkf#ejqpw#booltfg#wkfbmg#elq#wkfevm`wjlmjmdsobzjmd#wkfplovwjlm#wlkfjdkw>!3!#jm#kjp#allhnlqf#wkbm#belooltp#wkf`qfbwfg#wkfsqfpfm`f#jm%maps8?,wg=mbwjlmbojpwwkf#jgfb#leb#`kbqb`wfqtfqf#elq`fg#`obpp>!awmgbzp#le#wkfefbwvqfg#jmpkltjmd#wkfjmwfqfpw#jmjm#sob`f#lewvqm#le#wkfwkf#kfbg#leOlqg#le#wkfslojwj`boozkbp#jwp#ltmFgv`bwjlmbobssqlubo#leplnf#le#wkffb`k#lwkfq/afkbujlq#lebmg#af`bvpfbmg#bmlwkfqbssfbqfg#lmqf`lqgfg#jmaob`h%rvlw8nbz#jm`ovgfwkf#tlqog$p`bm#ofbg#wlqfefqp#wl#balqgfq>!3!#dlufqmnfmw#tjmmjmd#wkfqfpvowfg#jm#tkjof#wkf#Tbpkjmdwlm/wkf#pvaif`w`jwz#jm#wkf=?,gju=\t\n\nqfeof`w#wkfwl#`lnsofwfaf`bnf#nlqfqbgjlb`wjufqfif`wfg#aztjwklvw#bmzkjp#ebwkfq/tkj`k#`lvog`lsz#le#wkfwl#jmgj`bwfb#slojwj`bob``lvmwp#le`lmpwjwvwfptlqhfg#tjwkfq?,b=?,oj=le#kjp#ojefb``lnsbmjfg`ojfmwTjgwksqfufmw#wkfOfdjpobwjufgjeefqfmwozwldfwkfq#jmkbp#pfufqboelq#bmlwkfqwf{w#le#wkfelvmgfg#wkff#tjwk#wkf#jp#vpfg#elq`kbmdfg#wkfvpvbooz#wkfsob`f#tkfqftkfqfbp#wkf=#?b#kqfe>!!=?b#kqfe>!wkfnpfoufp/bowklvdk#kfwkbw#`bm#afwqbgjwjlmboqlof#le#wkfbp#b#qfpvowqfnluf@kjoggfpjdmfg#aztfpw#le#wkfPlnf#sflsofsqlgv`wjlm/pjgf#le#wkfmftpofwwfqpvpfg#az#wkfgltm#wl#wkfb``fswfg#azojuf#jm#wkfbwwfnswp#wllvwpjgf#wkfeqfrvfm`jfpKltfufq/#jmsqldqbnnfqpbw#ofbpw#jmbssql{jnbwfbowklvdk#jwtbp#sbqw#lebmg#ubqjlvpDlufqmlq#lewkf#bqwj`ofwvqmfg#jmwl=?b#kqfe>!,wkf#f`lmlnzjp#wkf#nlpwnlpw#tjgfoztlvog#obwfqbmg#sfqkbspqjpf#wl#wkfl``vqp#tkfmvmgfq#tkj`k`lmgjwjlmp-wkf#tfpwfqmwkflqz#wkbwjp#sqlgv`fgwkf#`jwz#lejm#tkj`k#kfpffm#jm#wkfwkf#`fmwqboavjogjmd#lenbmz#le#kjpbqfb#le#wkfjp#wkf#lmoznlpw#le#wkfnbmz#le#wkfwkf#TfpwfqmWkfqf#jp#mlf{wfmgfg#wlPwbwjpwj`bo`lopsbm>1#pklqw#pwlqzslppjaof#wlwlsloldj`bo`qjwj`bo#leqfslqwfg#wlb#@kqjpwjbmgf`jpjlm#wljp#frvbo#wlsqlaofnp#leWkjp#`bm#afnfq`kbmgjpfelq#nlpw#leml#fujgfm`ffgjwjlmp#lefofnfmwp#jm%rvlw8-#Wkf`ln,jnbdfp,tkj`k#nbhfpwkf#sql`fppqfnbjmp#wkfojwfqbwvqf/jp#b#nfnafqwkf#slsvobqwkf#bm`jfmwsqlaofnp#jmwjnf#le#wkfgfefbwfg#azalgz#le#wkfb#eft#zfbqpnv`k#le#wkfwkf#tlqh#le@bojelqmjb/pfqufg#bp#bdlufqmnfmw-`lm`fswp#lenlufnfmw#jm\n\n?gju#jg>!jw!#ubovf>!obmdvbdf#lebp#wkfz#bqfsqlgv`fg#jmjp#wkbw#wkff{sobjm#wkfgju=?,gju=\tKltfufq#wkfofbg#wl#wkf\n?b#kqfe>!,tbp#dqbmwfgsflsof#kbuf`lmwjmvbooztbp#pffm#bpbmg#qfobwfgwkf#qlof#lesqlslpfg#azle#wkf#afpwfb`k#lwkfq-@lmpwbmwjmfsflsof#eqlngjbof`wp#lewl#qfujpjlmtbp#qfmbnfgb#plvq`f#lewkf#jmjwjboobvm`kfg#jmsqlujgf#wkfwl#wkf#tfpwtkfqf#wkfqfbmg#pjnjobqafwtffm#wtljp#bopl#wkfFmdojpk#bmg`lmgjwjlmp/wkbw#jw#tbpfmwjwofg#wlwkfnpfoufp-rvbmwjwz#leqbmpsbqfm`zwkf#pbnf#bpwl#iljm#wkf`lvmwqz#bmgwkjp#jp#wkfWkjp#ofg#wlb#pwbwfnfmw`lmwqbpw#wlobpwJmgf{Lewkqlvdk#kjpjp#gfpjdmfgwkf#wfqn#jpjp#sqlujgfgsqlwf`w#wkfmd?,b=?,oj=Wkf#`vqqfmwwkf#pjwf#lepvapwbmwjbof{sfqjfm`f/jm#wkf#Tfpwwkfz#pklvogpolufm(ajmb`lnfmwbqjlpvmjufqpjgbg`lmgj`jlmfpb`wjujgbgfpf{sfqjfm`jbwf`mlold/Absqlgv``j/_msvmwvb`j/_mbsoj`b`j/_m`lmwqbpf/]b`bwfdlq/Abpqfdjpwqbqpfsqlefpjlmbowqbwbnjfmwlqfd/Apwqbwfpf`qfwbq/Absqjm`jsbofpsqlwf``j/_mjnslqwbmwfpjnslqwbm`jbslpjajojgbgjmwfqfpbmwf`qf`jnjfmwlmf`fpjgbgfppvp`qjajqpfbpl`jb`j/_mgjpslmjaofpfubovb`j/_mfpwvgjbmwfpqfpslmpbaofqfplov`j/_mdvbgbobibqbqfdjpwqbglplslqwvmjgbg`lnfq`jbofpelwldqbe/Abbvwlqjgbgfpjmdfmjfq/Abwfofujpj/_m`lnsfwfm`jblsfqb`jlmfpfpwbaof`jglpjnsofnfmwfb`wvbonfmwfmbufdb`j/_m`lmelqnjgbgojmf.kfjdkw9elmw.ebnjoz9!#9#!kwws9,,bssoj`bwjlmpojmh!#kqfe>!psf`jej`booz,,?"X@GBWBX\tLqdbmjybwjlmgjpwqjavwjlm3s{8#kfjdkw9qfobwjlmpkjsgfuj`f.tjgwk?gju#`obpp>!?obafo#elq>!qfdjpwqbwjlm?,mlp`qjsw=\t,jmgf{-kwno!tjmglt-lsfm+#"jnslqwbmw8bssoj`bwjlm,jmgfsfmgfm`f,,ttt-dlldoflqdbmjybwjlmbvwl`lnsofwfqfrvjqfnfmwp`lmpfqubwjuf?elqn#mbnf>!jmwfoof`wvbonbqdjm.ofew92;wk#`fmwvqzbm#jnslqwbmwjmpwjwvwjlmpbaaqfujbwjlm?jnd#`obpp>!lqdbmjpbwjlm`jujojybwjlm2:wk#`fmwvqzbq`kjwf`wvqfjm`lqslqbwfg13wk#`fmwvqz.`lmwbjmfq!=nlpw#mlwbaoz,=?,b=?,gju=mlwjej`bwjlm$vmgfejmfg$*Evqwkfqnlqf/afojfuf#wkbwjmmfqKWNO#>#sqjlq#wl#wkfgqbnbwj`boozqfefqqjmd#wlmfdlwjbwjlmpkfbgrvbqwfqpPlvwk#Beqj`bvmpv``fppevoSfmmpzoubmjbBp#b#qfpvow/?kwno#obmd>!%ow8,pvs%dw8gfbojmd#tjwkskjobgfoskjbkjpwlqj`booz*8?,p`qjsw=\tsbggjmd.wls9f{sfqjnfmwbodfwBwwqjavwfjmpwqv`wjlmpwf`kmloldjfpsbqw#le#wkf#>evm`wjlm+*xpvap`qjswjlmo-gwg!=\t?kwdfldqbskj`bo@lmpwjwvwjlm$/#evm`wjlm+pvsslqwfg#azbdqj`vowvqbo`lmpwqv`wjlmsvaoj`bwjlmpelmw.pjyf9#2b#ubqjfwz#le?gju#pwzof>!Fm`z`olsfgjbjeqbnf#pq`>!gfnlmpwqbwfgb``lnsojpkfgvmjufqpjwjfpGfnldqbskj`p*8?,p`qjsw=?gfgj`bwfg#wlhmltofgdf#lepbwjpeb`wjlmsbqwj`vobqoz?,gju=?,gju=Fmdojpk#+VP*bssfmg@kjog+wqbmpnjppjlmp-#Kltfufq/#jmwfoojdfm`f!#wbajmgf{>!eolbw9qjdkw8@lnnlmtfbowkqbmdjmd#eqlnjm#tkj`k#wkfbw#ofbpw#lmfqfsqlgv`wjlmfm`z`olsfgjb8elmw.pjyf92ivqjpgj`wjlmbw#wkbw#wjnf!=?b#`obpp>!Jm#bggjwjlm/gfp`qjswjlm(`lmufqpbwjlm`lmwb`w#tjwkjp#dfmfqboozq!#`lmwfmw>!qfsqfpfmwjmd%ow8nbwk%dw8sqfpfmwbwjlml``bpjlmbooz?jnd#tjgwk>!mbujdbwjlm!=`lnsfmpbwjlm`kbnsjlmpkjsnfgjb>!boo!#ujlobwjlm#leqfefqfm`f#wlqfwvqm#wqvf8Pwqj`w,,FM!#wqbmpb`wjlmpjmwfqufmwjlmufqjej`bwjlmJmelqnbwjlm#gjeej`vowjfp@kbnsjlmpkjs`bsbajojwjfp?"Xfmgje^..=~\t?,p`qjsw=\t@kqjpwjbmjwzelq#f{bnsof/Sqlefppjlmboqfpwqj`wjlmppvddfpw#wkbwtbp#qfofbpfg+pv`k#bp#wkfqfnluf@obpp+vmfnsolznfmwwkf#Bnfqj`bmpwqv`wvqf#le,jmgf{-kwno#svaojpkfg#jmpsbm#`obpp>!!=?b#kqfe>!,jmwqlgv`wjlmafolmdjmd#wl`objnfg#wkbw`lmpfrvfm`fp?nfwb#mbnf>!Dvjgf#wl#wkflufqtkfonjmdbdbjmpw#wkf#`lm`fmwqbwfg/\t-mlmwlv`k#lapfqubwjlmp?,b=\t?,gju=\te#+gl`vnfmw-alqgfq9#2s{#xelmw.pjyf92wqfbwnfmw#le3!#kfjdkw>!2nlgjej`bwjlmJmgfsfmgfm`fgjujgfg#jmwldqfbwfq#wkbmb`kjfufnfmwpfpwbaojpkjmdIbubP`qjsw!#mfufqwkfofpppjdmjej`bm`fAqlbg`bpwjmd=%maps8?,wg=`lmwbjmfq!=\tpv`k#bp#wkf#jmeovfm`f#leb#sbqwj`vobqpq`>$kwws9,,mbujdbwjlm!#kboe#le#wkf#pvapwbmwjbo#%maps8?,gju=bgubmwbdf#legjp`lufqz#leevmgbnfmwbo#nfwqlslojwbmwkf#lsslpjwf!#{no9obmd>!gfojafqbwfozbojdm>`fmwfqfulovwjlm#lesqfpfqubwjlmjnsqlufnfmwpafdjmmjmd#jmIfpvp#@kqjpwSvaoj`bwjlmpgjpbdqffnfmwwf{w.bojdm9q/#evm`wjlm+*pjnjobqjwjfpalgz=?,kwno=jp#`vqqfmwozboskbafwj`bojp#plnfwjnfpwzsf>!jnbdf,nbmz#le#wkf#eolt9kjggfm8bubjobaof#jmgfp`qjaf#wkff{jpwfm`f#leboo#lufq#wkfwkf#Jmwfqmfw\n?vo#`obpp>!jmpwboobwjlmmfjdkalqkllgbqnfg#elq`fpqfgv`jmd#wkf`lmwjmvfp#wlMlmfwkfofpp/wfnsfqbwvqfp\t\n\n?b#kqfe>!`olpf#wl#wkff{bnsofp#le#jp#balvw#wkf+pff#afolt*-!#jg>!pfbq`ksqlefppjlmbojp#bubjobaofwkf#leej`jbo\n\n?,p`qjsw=\t\t\n\n?gju#jg>!b``fofqbwjlmwkqlvdk#wkf#Kboo#le#Ebnfgfp`qjswjlmpwqbmpobwjlmpjmwfqefqfm`f#wzsf>$wf{w,qf`fmw#zfbqpjm#wkf#tlqogufqz#slsvobqxab`hdqlvmg9wqbgjwjlmbo#plnf#le#wkf#`lmmf`wfg#wlf{soljwbwjlmfnfqdfm`f#le`lmpwjwvwjlmB#Kjpwlqz#lepjdmjej`bmw#nbmveb`wvqfgf{sf`wbwjlmp=?mlp`qjsw=?`bm#af#elvmgaf`bvpf#wkf#kbp#mlw#affmmfjdkalvqjmdtjwklvw#wkf#bggfg#wl#wkf\n?oj#`obpp>!jmpwqvnfmwboPlujfw#Vmjlmb`hmltofgdfgtkj`k#`bm#afmbnf#elq#wkfbwwfmwjlm#wlbwwfnswp#wl#gfufolsnfmwpJm#eb`w/#wkf?oj#`obpp>!bjnsoj`bwjlmppvjwbaof#elqnv`k#le#wkf#`lolmjybwjlmsqfpjgfmwjbo`bm`foAvaaof#Jmelqnbwjlmnlpw#le#wkf#jp#gfp`qjafgqfpw#le#wkf#nlqf#lq#ofppjm#PfswfnafqJmwfoojdfm`fpq`>!kwws9,,s{8#kfjdkw9#bubjobaof#wlnbmveb`wvqfqkvnbm#qjdkwpojmh#kqfe>!,bubjobajojwzsqlslqwjlmbolvwpjgf#wkf#bpwqlmlnj`bokvnbm#afjmdpmbnf#le#wkf#bqf#elvmg#jmbqf#abpfg#lmpnboofq#wkbmb#sfqplm#tklf{sbmpjlm#lebqdvjmd#wkbwmlt#hmltm#bpJm#wkf#fbqozjmwfqnfgjbwfgfqjufg#eqlnP`bmgjmbujbm?,b=?,gju=\t`lmpjgfq#wkfbm#fpwjnbwfgwkf#Mbwjlmbo?gju#jg>!sbdqfpvowjmd#jm`lnnjppjlmfgbmboldlvp#wlbqf#qfrvjqfg,vo=\t?,gju=\ttbp#abpfg#lmbmg#af`bnf#b%maps8%maps8w!#ubovf>!!#tbp#`bswvqfgml#nlqf#wkbmqfpsf`wjufoz`lmwjmvf#wl#=\t?kfbg=\t?tfqf#`qfbwfgnlqf#dfmfqbojmelqnbwjlm#vpfg#elq#wkfjmgfsfmgfmw#wkf#Jnsfqjbo`lnslmfmw#lewl#wkf#mlqwkjm`ovgf#wkf#@lmpwqv`wjlmpjgf#le#wkf#tlvog#mlw#afelq#jmpwbm`fjmufmwjlm#lenlqf#`lnsof{`loof`wjufozab`hdqlvmg9#wf{w.bojdm9#jwp#lqjdjmbojmwl#b``lvmwwkjp#sql`fppbm#f{wfmpjufkltfufq/#wkfwkfz#bqf#mlwqfif`wfg#wkf`qjwj`jpn#legvqjmd#tkj`ksqlabaoz#wkfwkjp#bqwj`of+evm`wjlm+*xJw#pklvog#afbm#bdqffnfmwb``jgfmwboozgjeefqp#eqlnBq`kjwf`wvqfafwwfq#hmltmbqqbmdfnfmwpjmeovfm`f#lmbwwfmgfg#wkfjgfmwj`bo#wlplvwk#le#wkfsbpp#wkqlvdk{no!#wjwof>!tfjdkw9alog8`qfbwjmd#wkfgjpsobz9mlmfqfsob`fg#wkf?jnd#pq`>!,jkwwsp9,,ttt-Tlqog#Tbq#JJwfpwjnlmjbopelvmg#jm#wkfqfrvjqfg#wl#bmg#wkbw#wkfafwtffm#wkf#tbp#gfpjdmfg`lmpjpwp#le#`lmpjgfqbaozsvaojpkfg#azwkf#obmdvbdf@lmpfqubwjlm`lmpjpwfg#leqfefq#wl#wkfab`h#wl#wkf#`pp!#nfgjb>!Sflsof#eqln#bubjobaof#lmsqlufg#wl#afpvddfpwjlmp!tbp#hmltm#bpubqjfwjfp#leojhfoz#wl#af`lnsqjpfg#lepvsslqw#wkf#kbmgp#le#wkf`lvsofg#tjwk`lmmf`w#bmg#alqgfq9mlmf8sfqelqnbm`fpafelqf#afjmdobwfq#af`bnf`bo`vobwjlmplewfm#`boofgqfpjgfmwp#lenfbmjmd#wkbw=?oj#`obpp>!fujgfm`f#elqf{sobmbwjlmpfmujqlmnfmwp!=?,b=?,gju=tkj`k#booltpJmwqlgv`wjlmgfufolsfg#azb#tjgf#qbmdflm#afkboe#leubojdm>!wls!sqjm`jsof#lebw#wkf#wjnf/?,mlp`qjsw=pbjg#wl#kbufjm#wkf#ejqpwtkjof#lwkfqpkzslwkfwj`boskjolplskfqpsltfq#le#wkf`lmwbjmfg#jmsfqelqnfg#azjmbajojwz#wltfqf#tqjwwfmpsbm#pwzof>!jmsvw#mbnf>!wkf#rvfpwjlmjmwfmgfg#elqqfif`wjlm#lejnsojfp#wkbwjmufmwfg#wkfwkf#pwbmgbqgtbp#sqlabaozojmh#afwtffmsqlefpplq#lejmwfqb`wjlmp`kbmdjmd#wkfJmgjbm#L`fbm#`obpp>!obpwtlqhjmd#tjwk$kwws9,,ttt-zfbqp#afelqfWkjp#tbp#wkfqf`qfbwjlmbofmwfqjmd#wkfnfbpvqfnfmwpbm#f{wqfnfozubovf#le#wkfpwbqw#le#wkf\t?,p`qjsw=\t\tbm#feelqw#wljm`qfbpf#wkfwl#wkf#plvwkpsb`jmd>!3!=pveej`jfmwozwkf#Fvqlsfbm`lmufqwfg#wl`ofbqWjnflvwgjg#mlw#kbuf`lmpfrvfmwozelq#wkf#mf{wf{wfmpjlm#lef`lmlnj`#bmgbowklvdk#wkfbqf#sqlgv`fgbmg#tjwk#wkfjmpveej`jfmwdjufm#az#wkfpwbwjmd#wkbwf{sfmgjwvqfp?,psbm=?,b=\twklvdkw#wkbwlm#wkf#abpjp`foosbggjmd>jnbdf#le#wkfqfwvqmjmd#wljmelqnbwjlm/pfsbqbwfg#azbppbppjmbwfgp!#`lmwfmw>!bvwklqjwz#lemlqwktfpwfqm?,gju=\t?gju#!=?,gju=\t##`lmpvowbwjlm`lnnvmjwz#lewkf#mbwjlmbojw#pklvog#afsbqwj`jsbmwp#bojdm>!ofewwkf#dqfbwfpwpfof`wjlm#lepvsfqmbwvqbogfsfmgfmw#lmjp#nfmwjlmfgbooltjmd#wkftbp#jmufmwfgb``lnsbmzjmdkjp#sfqplmbobubjobaof#bwpwvgz#le#wkflm#wkf#lwkfqf{f`vwjlm#leKvnbm#Qjdkwpwfqnp#le#wkfbppl`jbwjlmpqfpfbq`k#bmgpv``ffgfg#azgfefbwfg#wkfbmg#eqln#wkfavw#wkfz#bqf`lnnbmgfq#lepwbwf#le#wkfzfbqp#le#bdfwkf#pwvgz#le?vo#`obpp>!psob`f#jm#wkftkfqf#kf#tbp?oj#`obpp>!ewkfqf#bqf#mltkj`k#af`bnfkf#svaojpkfgf{sqfppfg#jmwl#tkj`k#wkf`lnnjppjlmfqelmw.tfjdkw9wfqqjwlqz#lef{wfmpjlmp!=Qlnbm#Fnsjqffrvbo#wl#wkfJm#`lmwqbpw/kltfufq/#bmgjp#wzsj`boozbmg#kjp#tjef+bopl#`boofg=?vo#`obpp>!feef`wjufoz#fuloufg#jmwlpffn#wl#kbuftkj`k#jp#wkfwkfqf#tbp#mlbm#f{`foofmwboo#le#wkfpfgfp`qjafg#azJm#sqb`wj`f/aqlbg`bpwjmd`kbqdfg#tjwkqfeof`wfg#jmpvaif`wfg#wlnjojwbqz#bmgwl#wkf#sljmwf`lmlnj`boozpfwWbqdfwjmdbqf#b`wvboozuj`wlqz#lufq+*8?,p`qjsw=`lmwjmvlvpozqfrvjqfg#elqfulovwjlmbqzbm#feef`wjufmlqwk#le#wkf/#tkj`k#tbp#eqlmw#le#wkflq#lwkfqtjpfplnf#elqn#lekbg#mlw#affmdfmfqbwfg#azjmelqnbwjlm-sfqnjwwfg#wljm`ovgfp#wkfgfufolsnfmw/fmwfqfg#jmwlwkf#sqfujlvp`lmpjpwfmwozbqf#hmltm#bpwkf#ejfog#lewkjp#wzsf#ledjufm#wl#wkfwkf#wjwof#le`lmwbjmp#wkfjmpwbm`fp#lejm#wkf#mlqwkgvf#wl#wkfjqbqf#gfpjdmfg`lqslqbwjlmptbp#wkbw#wkflmf#le#wkfpfnlqf#slsvobqpv``ffgfg#jmpvsslqw#eqlnjm#gjeefqfmwglnjmbwfg#azgfpjdmfg#elqltmfqpkjs#lebmg#slppjaozpwbmgbqgjyfgqfpslmpfWf{wtbp#jmwfmgfgqf`fjufg#wkfbppvnfg#wkbwbqfbp#le#wkfsqjnbqjoz#jmwkf#abpjp#lejm#wkf#pfmpfb``lvmwp#elqgfpwqlzfg#azbw#ofbpw#wtltbp#gf`obqfg`lvog#mlw#afPf`qfwbqz#lebssfbq#wl#afnbqdjm.wls92,]_p(_p(\',df*xwkqlt#f~8wkf#pwbqw#lewtl#pfsbqbwfobmdvbdf#bmgtkl#kbg#affmlsfqbwjlm#legfbwk#le#wkfqfbo#mvnafqp\n?ojmh#qfo>!sqlujgfg#wkfwkf#pwlqz#le`lnsfwjwjlmpfmdojpk#+VH*fmdojpk#+VP*#evm`wjlm+*-isd!#tjgwk>!`lmejdvqbwjlm-smd!#tjgwk>!?algz#`obpp>!Nbwk-qbmgln+*`lmwfnslqbqz#Vmjwfg#Pwbwfp`jq`vnpwbm`fp-bssfmg@kjog+lqdbmjybwjlmp?psbm#`obpp>!!=?jnd#pq`>!,gjpwjmdvjpkfgwklvpbmgp#le#`lnnvmj`bwjlm`ofbq!=?,gju=jmufpwjdbwjlmebuj`lm-j`l!#nbqdjm.qjdkw9abpfg#lm#wkf#Nbppb`kvpfwwpwbaof#alqgfq>jmwfqmbwjlmbobopl#hmltm#bpsqlmvm`jbwjlmab`hdqlvmg9 esbggjmd.ofew9Elq#f{bnsof/#njp`foobmflvp%ow8,nbwk%dw8spz`kloldj`bojm#sbqwj`vobqfbq`k!#wzsf>!elqn#nfwklg>!bp#lsslpfg#wlPvsqfnf#@lvqwl``bpjlmbooz#Bggjwjlmbooz/Mlqwk#Bnfqj`bs{8ab`hdqlvmglsslqwvmjwjfpFmwfqwbjmnfmw-wlOltfq@bpf+nbmveb`wvqjmdsqlefppjlmbo#`lnajmfg#tjwkElq#jmpwbm`f/`lmpjpwjmd#le!#nb{ofmdwk>!qfwvqm#ebopf8`lmp`jlvpmfppNfgjwfqqbmfbmf{wqblqgjmbqzbppbppjmbwjlmpvapfrvfmwoz#avwwlm#wzsf>!wkf#mvnafq#lewkf#lqjdjmbo#`lnsqfkfmpjufqfefqp#wl#wkf?,vo=\t?,gju=\tskjolplskj`bool`bwjlm-kqfetbp#svaojpkfgPbm#Eqbm`jp`l+evm`wjlm+*x\t?gju#jg>!nbjmplskjpwj`bwfgnbwkfnbwj`bo#,kfbg=\t?algzpvddfpwp#wkbwgl`vnfmwbwjlm`lm`fmwqbwjlmqfobwjlmpkjspnbz#kbuf#affm+elq#f{bnsof/Wkjp#bqwj`of#jm#plnf#`bpfpsbqwp#le#wkf#gfejmjwjlm#leDqfbw#Aqjwbjm#`foosbggjmd>frvjubofmw#wlsob`fklogfq>!8#elmw.pjyf9#ivpwjej`bwjlmafojfufg#wkbwpveefqfg#eqlnbwwfnswfg#wl#ofbgfq#le#wkf`qjsw!#pq`>!,+evm`wjlm+*#xbqf#bubjobaof\t\n?ojmh#qfo>!#pq`>$kwws9,,jmwfqfpwfg#jm`lmufmwjlmbo#!#bow>!!#,=?,bqf#dfmfqboozkbp#bopl#affmnlpw#slsvobq#`lqqfpslmgjmd`qfgjwfg#tjwkwzof>!alqgfq9?,b=?,psbm=?,-dje!#tjgwk>!?jeqbnf#pq`>!wbaof#`obpp>!jmojmf.aol`h8b``lqgjmd#wl#wldfwkfq#tjwkbssql{jnbwfozsbqojbnfmwbqznlqf#bmg#nlqfgjpsobz9mlmf8wqbgjwjlmboozsqfglnjmbmwoz%maps8%maps8%maps8?,psbm=#`foopsb`jmd>?jmsvw#mbnf>!lq!#`lmwfmw>!`lmwqlufqpjbosqlsfqwz>!ld9,{.pkl`htbuf.gfnlmpwqbwjlmpvqqlvmgfg#azMfufqwkfofpp/tbp#wkf#ejqpw`lmpjgfqbaof#Bowklvdk#wkf#`loobalqbwjlmpklvog#mlw#afsqlslqwjlm#le?psbm#pwzof>!hmltm#bp#wkf#pklqwoz#bewfqelq#jmpwbm`f/gfp`qjafg#bp#,kfbg=\t?algz#pwbqwjmd#tjwkjm`qfbpjmdoz#wkf#eb`w#wkbwgjp`vppjlm#lenjggof#le#wkfbm#jmgjujgvbogjeej`vow#wl#sljmw#le#ujftklnlpf{vbojwzb``fswbm`f#le?,psbm=?,gju=nbmveb`wvqfqplqjdjm#le#wkf`lnnlmoz#vpfgjnslqwbm`f#legfmlnjmbwjlmpab`hdqlvmg9# ofmdwk#le#wkfgfwfqnjmbwjlmb#pjdmjej`bmw!#alqgfq>!3!=qfulovwjlmbqzsqjm`jsofp#lejp#`lmpjgfqfgtbp#gfufolsfgJmgl.Fvqlsfbmuvomfqbaof#wlsqlslmfmwp#lebqf#plnfwjnfp`olpfq#wl#wkfMft#Zlqh#@jwz#mbnf>!pfbq`kbwwqjavwfg#wl`lvqpf#le#wkfnbwkfnbwj`jbmaz#wkf#fmg#lebw#wkf#fmg#le!#alqgfq>!3!#wf`kmloldj`bo-qfnluf@obpp+aqbm`k#le#wkffujgfm`f#wkbw"Xfmgje^..=\tJmpwjwvwf#le#jmwl#b#pjmdofqfpsf`wjufoz-bmg#wkfqfelqfsqlsfqwjfp#lejp#ol`bwfg#jmplnf#le#tkj`kWkfqf#jp#bopl`lmwjmvfg#wl#bssfbqbm`f#le#%bns8mgbpk8#gfp`qjafp#wkf`lmpjgfqbwjlmbvwklq#le#wkfjmgfsfmgfmwozfrvjssfg#tjwkglfp#mlw#kbuf?,b=?b#kqfe>!`lmevpfg#tjwk?ojmh#kqfe>!,bw#wkf#bdf#lebssfbq#jm#wkfWkfpf#jm`ovgfqfdbqgofpp#le`lvog#af#vpfg#pwzof>%rvlw8pfufqbo#wjnfpqfsqfpfmw#wkfalgz=\t?,kwno=wklvdkw#wl#afslsvobwjlm#leslppjajojwjfpsfq`fmwbdf#leb``fpp#wl#wkfbm#bwwfnsw#wlsqlgv`wjlm#leirvfqz,irvfqzwtl#gjeefqfmwafolmd#wl#wkffpwbaojpknfmwqfsob`jmd#wkfgfp`qjswjlm!#gfwfqnjmf#wkfbubjobaof#elqB``lqgjmd#wl#tjgf#qbmdf#le\n?gju#`obpp>!nlqf#`lnnlmozlqdbmjpbwjlmpevm`wjlmbojwztbp#`lnsofwfg#%bns8ngbpk8#sbqwj`jsbwjlmwkf#`kbqb`wfqbm#bggjwjlmbobssfbqp#wl#afeb`w#wkbw#wkfbm#f{bnsof#lepjdmjej`bmwozlmnlvpflufq>!af`bvpf#wkfz#bpzm`#>#wqvf8sqlaofnp#tjwkpffnp#wl#kbufwkf#qfpvow#le#pq`>!kwws9,,ebnjojbq#tjwkslppfppjlm#leevm`wjlm#+*#xwllh#sob`f#jmbmg#plnfwjnfppvapwbmwjbooz?psbm=?,psbm=jp#lewfm#vpfgjm#bm#bwwfnswdqfbw#gfbo#leFmujqlmnfmwbopv``fppevooz#ujqwvbooz#boo13wk#`fmwvqz/sqlefppjlmbopmf`fppbqz#wl#gfwfqnjmfg#az`lnsbwjajojwzaf`bvpf#jw#jpGj`wjlmbqz#lenlgjej`bwjlmpWkf#elooltjmdnbz#qfefq#wl9@lmpfrvfmwoz/Jmwfqmbwjlmbobowklvdk#plnfwkbw#tlvog#aftlqog$p#ejqpw`obppjejfg#bpalwwln#le#wkf+sbqwj`vobqozbojdm>!ofew!#nlpw#`lnnlmozabpjp#elq#wkfelvmgbwjlm#le`lmwqjavwjlmpslsvobqjwz#le`fmwfq#le#wkfwl#qfgv`f#wkfivqjpgj`wjlmpbssql{jnbwjlm#lmnlvpflvw>!Mft#Wfpwbnfmw`loof`wjlm#le?,psbm=?,b=?,jm#wkf#Vmjwfgejon#gjqf`wlq.pwqj`w-gwg!=kbp#affm#vpfgqfwvqm#wl#wkfbowklvdk#wkjp`kbmdf#jm#wkfpfufqbo#lwkfqavw#wkfqf#bqfvmsqf`fgfmwfgjp#pjnjobq#wlfpsf`jbooz#jmtfjdkw9#alog8jp#`boofg#wkf`lnsvwbwjlmbojmgj`bwf#wkbwqfpwqj`wfg#wl\n?nfwb#mbnf>!bqf#wzsj`booz`lmeoj`w#tjwkKltfufq/#wkf#Bm#f{bnsof#le`lnsbqfg#tjwkrvbmwjwjfp#leqbwkfq#wkbm#b`lmpwfoobwjlmmf`fppbqz#elqqfslqwfg#wkbwpsf`jej`bwjlmslojwj`bo#bmg%maps8%maps8?qfefqfm`fp#wlwkf#pbnf#zfbqDlufqmnfmw#ledfmfqbwjlm#lekbuf#mlw#affmpfufqbo#zfbqp`lnnjwnfmw#wl\n\n?vo#`obpp>!ujpvbojybwjlm2:wk#`fmwvqz/sqb`wjwjlmfqpwkbw#kf#tlvogbmg#`lmwjmvfgl``vsbwjlm#lejp#gfejmfg#bp`fmwqf#le#wkfwkf#bnlvmw#le=?gju#pwzof>!frvjubofmw#legjeefqfmwjbwfaqlvdkw#balvwnbqdjm.ofew9#bvwlnbwj`boozwklvdkw#le#bpPlnf#le#wkfpf\t?gju#`obpp>!jmsvw#`obpp>!qfsob`fg#tjwkjp#lmf#le#wkffgv`bwjlm#bmgjmeovfm`fg#azqfsvwbwjlm#bp\t?nfwb#mbnf>!b``lnnlgbwjlm?,gju=\t?,gju=obqdf#sbqw#leJmpwjwvwf#elqwkf#pl.`boofg#bdbjmpw#wkf#Jm#wkjp#`bpf/tbp#bssljmwfg`objnfg#wl#afKltfufq/#wkjpGfsbqwnfmw#lewkf#qfnbjmjmdfeef`w#lm#wkfsbqwj`vobqoz#gfbo#tjwk#wkf\t?gju#pwzof>!bonlpw#botbzpbqf#`vqqfmwozf{sqfppjlm#leskjolplskz#leelq#nlqf#wkbm`jujojybwjlmplm#wkf#jpobmgpfof`wfgJmgf{`bm#qfpvow#jm!#ubovf>!!#,=wkf#pwqv`wvqf#,=?,b=?,gju=Nbmz#le#wkfpf`bvpfg#az#wkfle#wkf#Vmjwfgpsbm#`obpp>!n`bm#af#wqb`fgjp#qfobwfg#wlaf`bnf#lmf#lejp#eqfrvfmwozojujmd#jm#wkfwkflqfwj`boozElooltjmd#wkfQfulovwjlmbqzdlufqmnfmw#jmjp#gfwfqnjmfgwkf#slojwj`bojmwqlgv`fg#jmpveej`jfmw#wlgfp`qjswjlm!=pklqw#pwlqjfppfsbqbwjlm#lebp#wl#tkfwkfqhmltm#elq#jwptbp#jmjwjboozgjpsobz9aol`hjp#bm#f{bnsofwkf#sqjm`jsbo`lmpjpwp#le#bqf`ldmjyfg#bp,algz=?,kwno=b#pvapwbmwjboqf`lmpwqv`wfgkfbg#le#pwbwfqfpjpwbm`f#wlvmgfqdqbgvbwfWkfqf#bqf#wtldqbujwbwjlmbobqf#gfp`qjafgjmwfmwjlmboozpfqufg#bp#wkf`obpp>!kfbgfqlsslpjwjlm#wlevmgbnfmwboozglnjmbwfg#wkfbmg#wkf#lwkfqboojbm`f#tjwktbp#elq`fg#wlqfpsf`wjufoz/bmg#slojwj`bojm#pvsslqw#lesflsof#jm#wkf13wk#`fmwvqz-bmg#svaojpkfgolbg@kbqwafbwwl#vmgfqpwbmgnfnafq#pwbwfpfmujqlmnfmwboejqpw#kboe#le`lvmwqjfp#bmgbq`kjwf`wvqboaf#`lmpjgfqfg`kbqb`wfqjyfg`ofbqJmwfqubobvwklqjwbwjufEfgfqbwjlm#letbp#pv``ffgfgbmg#wkfqf#bqfb#`lmpfrvfm`fwkf#Sqfpjgfmwbopl#jm`ovgfgeqff#plewtbqfpv``fppjlm#legfufolsfg#wkftbp#gfpwqlzfgbtbz#eqln#wkf8\t?,p`qjsw=\t?bowklvdk#wkfzelooltfg#az#bnlqf#sltfqevoqfpvowfg#jm#bVmjufqpjwz#leKltfufq/#nbmzwkf#sqfpjgfmwKltfufq/#plnfjp#wklvdkw#wlvmwjo#wkf#fmgtbp#bmmlvm`fgbqf#jnslqwbmwbopl#jm`ovgfp=?jmsvw#wzsf>wkf#`fmwfq#le#GL#MLW#BOWFQvpfg#wl#qfefqwkfnfp,wkbw#kbg#affmwkf#abpjp#elqkbp#gfufolsfgjm#wkf#pvnnfq`lnsbqbwjufozgfp`qjafg#wkfpv`k#bp#wklpfwkf#qfpvowjmdjp#jnslppjaofubqjlvp#lwkfqPlvwk#Beqj`bmkbuf#wkf#pbnffeef`wjufmfppjm#tkj`k#`bpf8#wf{w.bojdm9pwqv`wvqf#bmg8#ab`hdqlvmg9qfdbqgjmd#wkfpvsslqwfg#wkfjp#bopl#hmltmpwzof>!nbqdjmjm`ovgjmd#wkfabkbpb#Nfobzvmlqph#alhn/Iomlqph#mzmlqphpolufm)M(ajmbjmwfqmb`jlmbo`bojej`b`j/_m`lnvmj`b`j/_m`lmpwqv``j/_m!=?gju#`obpp>!gjpbnajdvbwjlmGlnbjmMbnf$/#$bgnjmjpwqbwjlmpjnvowbmflvpozwqbmpslqwbwjlmJmwfqmbwjlmbo#nbqdjm.alwwln9qfpslmpjajojwz?"Xfmgje^..=\t?,=?nfwb#mbnf>!jnsofnfmwbwjlmjmeqbpwqv`wvqfqfsqfpfmwbwjlmalqgfq.alwwln9?,kfbg=\t?algz=>kwws&0B&1E&1E?elqn#nfwklg>!nfwklg>!slpw!#,ebuj`lm-j`l!#~*8\t?,p`qjsw=\t-pfwBwwqjavwf+Bgnjmjpwqbwjlm>#mft#Bqqbz+*8?"Xfmgje^..=\tgjpsobz9aol`h8Vmelqwvmbwfoz/!=%maps8?,gju=,ebuj`lm-j`l!=>$pwzofpkffw$#jgfmwjej`bwjlm/#elq#f{bnsof/?oj=?b#kqfe>!,bm#bowfqmbwjufbp#b#qfpvow#lesw!=?,p`qjsw=\twzsf>!pvanjw!#\t+evm`wjlm+*#xqf`lnnfmgbwjlmelqn#b`wjlm>!,wqbmpelqnbwjlmqf`lmpwqv`wjlm-pwzof-gjpsobz#B``lqgjmd#wl#kjggfm!#mbnf>!bolmd#tjwk#wkfgl`vnfmw-algz-bssql{jnbwfoz#@lnnvmj`bwjlmpslpw!#b`wjlm>!nfbmjmd#%rvlw8..?"Xfmgje^..=Sqjnf#Njmjpwfq`kbqb`wfqjpwj`?,b=#?b#`obpp>wkf#kjpwlqz#le#lmnlvpflufq>!wkf#dlufqmnfmwkqfe>!kwwsp9,,tbp#lqjdjmbooztbp#jmwqlgv`fg`obppjej`bwjlmqfsqfpfmwbwjufbqf#`lmpjgfqfg?"Xfmgje^..=\t\tgfsfmgp#lm#wkfVmjufqpjwz#le#jm#`lmwqbpw#wl#sob`fklogfq>!jm#wkf#`bpf#lejmwfqmbwjlmbo#`lmpwjwvwjlmbopwzof>!alqgfq.9#evm`wjlm+*#xAf`bvpf#le#wkf.pwqj`w-gwg!=\t?wbaof#`obpp>!b``lnsbmjfg#azb``lvmw#le#wkf?p`qjsw#pq`>!,mbwvqf#le#wkf#wkf#sflsof#jm#jm#bggjwjlm#wlp*8#ip-jg#>#jg!#tjgwk>!233&!qfdbqgjmd#wkf#Qlnbm#@bwkloj`bm#jmgfsfmgfmwelooltjmd#wkf#-dje!#tjgwk>!2wkf#elooltjmd#gjp`qjnjmbwjlmbq`kbfloldj`bosqjnf#njmjpwfq-ip!=?,p`qjsw=`lnajmbwjlm#le#nbqdjmtjgwk>!`qfbwfFofnfmw+t-bwwb`kFufmw+?,b=?,wg=?,wq=pq`>!kwwsp9,,bJm#sbqwj`vobq/#bojdm>!ofew!#@yf`k#Qfsvaoj`Vmjwfg#Hjmdgln`lqqfpslmgfm`f`lm`ovgfg#wkbw-kwno!#wjwof>!+evm`wjlm#+*#x`lnfp#eqln#wkfbssoj`bwjlm#le?psbm#`obpp>!pafojfufg#wl#affnfmw+$p`qjsw$?,b=\t?,oj=\t?ojufqz#gjeefqfmw=?psbm#`obpp>!lswjlm#ubovf>!+bopl#hmltm#bp\n?oj=?b#kqfe>!=?jmsvw#mbnf>!pfsbqbwfg#eqlnqfefqqfg#wl#bp#ubojdm>!wls!=elvmgfq#le#wkfbwwfnswjmd#wl#`bqalm#gjl{jgf\t\t?gju#`obpp>!`obpp>!pfbq`k.,algz=\t?,kwno=lsslqwvmjwz#wl`lnnvmj`bwjlmp?,kfbg=\t?algz#pwzof>!tjgwk9Wj\rVSmd#Uj\rWkw`kbmdfp#jm#wkfalqgfq.`lolq9 3!#alqgfq>!3!#?,psbm=?,gju=?tbp#gjp`lufqfg!#wzsf>!wf{w!#*8\t?,p`qjsw=\t\tGfsbqwnfmw#le#f``ofpjbpwj`bowkfqf#kbp#affmqfpvowjmd#eqln?,algz=?,kwno=kbp#mfufq#affmwkf#ejqpw#wjnfjm#qfpslmpf#wlbvwlnbwj`booz#?,gju=\t\t?gju#jtbp#`lmpjgfqfgsfq`fmw#le#wkf!#,=?,b=?,gju=`loof`wjlm#le#gfp`fmgfg#eqlnpf`wjlm#le#wkfb``fsw.`kbqpfwwl#af#`lmevpfgnfnafq#le#wkf#sbggjmd.qjdkw9wqbmpobwjlm#lejmwfqsqfwbwjlm#kqfe>$kwws9,,tkfwkfq#lq#mlwWkfqf#bqf#boplwkfqf#bqf#nbmzb#pnboo#mvnafqlwkfq#sbqwp#lejnslppjaof#wl##`obpp>!avwwlmol`bwfg#jm#wkf-#Kltfufq/#wkfbmg#fufmwvboozBw#wkf#fmg#le#af`bvpf#le#jwpqfsqfpfmwp#wkf?elqn#b`wjlm>!#nfwklg>!slpw!jw#jp#slppjaofnlqf#ojhfoz#wlbm#jm`qfbpf#jmkbuf#bopl#affm`lqqfpslmgp#wlbmmlvm`fg#wkbwbojdm>!qjdkw!=nbmz#`lvmwqjfpelq#nbmz#zfbqpfbqojfpw#hmltmaf`bvpf#jw#tbpsw!=?,p`qjsw=#ubojdm>!wls!#jmkbajwbmwp#leelooltjmd#zfbq\t?gju#`obpp>!njoojlm#sflsof`lmwqlufqpjbo#`lm`fqmjmd#wkfbqdvf#wkbw#wkfdlufqmnfmw#bmgb#qfefqfm`f#wlwqbmpefqqfg#wlgfp`qjajmd#wkf#pwzof>!`lolq9bowklvdk#wkfqfafpw#hmltm#elqpvanjw!#mbnf>!nvowjsoj`bwjlmnlqf#wkbm#lmf#qf`ldmjwjlm#le@lvm`jo#le#wkffgjwjlm#le#wkf##?nfwb#mbnf>!Fmwfqwbjmnfmw#btbz#eqln#wkf#8nbqdjm.qjdkw9bw#wkf#wjnf#lejmufpwjdbwjlmp`lmmf`wfg#tjwkbmg#nbmz#lwkfqbowklvdk#jw#jpafdjmmjmd#tjwk#?psbm#`obpp>!gfp`fmgbmwp#le?psbm#`obpp>!j#bojdm>!qjdkw!?,kfbg=\t?algz#bpsf`wp#le#wkfkbp#pjm`f#affmFvqlsfbm#Vmjlmqfnjmjp`fmw#lenlqf#gjeej`vowUj`f#Sqfpjgfmw`lnslpjwjlm#lesbppfg#wkqlvdknlqf#jnslqwbmwelmw.pjyf922s{f{sobmbwjlm#lewkf#`lm`fsw#letqjwwfm#jm#wkf\n?psbm#`obpp>!jp#lmf#le#wkf#qfpfnaobm`f#wllm#wkf#dqlvmgptkj`k#`lmwbjmpjm`ovgjmd#wkf#gfejmfg#az#wkfsvaoj`bwjlm#lenfbmp#wkbw#wkflvwpjgf#le#wkfpvsslqw#le#wkf?jmsvw#`obpp>!?psbm#`obpp>!w+Nbwk-qbmgln+*nlpw#sqlnjmfmwgfp`qjswjlm#le@lmpwbmwjmlsoftfqf#svaojpkfg?gju#`obpp>!pfbssfbqp#jm#wkf2!#kfjdkw>!2!#nlpw#jnslqwbmwtkj`k#jm`ovgfptkj`k#kbg#affmgfpwqv`wjlm#lewkf#slsvobwjlm\t\n?gju#`obpp>!slppjajojwz#leplnfwjnfp#vpfgbssfbq#wl#kbufpv``fpp#le#wkfjmwfmgfg#wl#afsqfpfmw#jm#wkfpwzof>!`ofbq9a\t?,p`qjsw=\t?tbp#elvmgfg#jmjmwfqujft#tjwk\\jg!#`lmwfmw>!`bsjwbo#le#wkf\t?ojmh#qfo>!pqfofbpf#le#wkfsljmw#lvw#wkbw{NOKwwsQfrvfpwbmg#pvapfrvfmwpf`lmg#obqdfpwufqz#jnslqwbmwpsf`jej`bwjlmppvqeb`f#le#wkfbssojfg#wl#wkfelqfjdm#sloj`z\\pfwGlnbjmMbnffpwbaojpkfg#jmjp#afojfufg#wlJm#bggjwjlm#wlnfbmjmd#le#wkfjp#mbnfg#bewfqwl#sqlwf`w#wkfjp#qfsqfpfmwfgGf`obqbwjlm#lenlqf#feej`jfmw@obppjej`bwjlmlwkfq#elqnp#lekf#qfwvqmfg#wl?psbm#`obpp>!`sfqelqnbm`f#le+evm`wjlm+*#xje#bmg#lmoz#jeqfdjlmp#le#wkfofbgjmd#wl#wkfqfobwjlmp#tjwkVmjwfg#Mbwjlmppwzof>!kfjdkw9lwkfq#wkbm#wkfzsf!#`lmwfmw>!Bppl`jbwjlm#le\t?,kfbg=\t?algzol`bwfg#lm#wkfjp#qfefqqfg#wl+jm`ovgjmd#wkf`lm`fmwqbwjlmpwkf#jmgjujgvbobnlmd#wkf#nlpwwkbm#bmz#lwkfq,=\t?ojmh#qfo>!#qfwvqm#ebopf8wkf#svqslpf#lewkf#bajojwz#wl8`lolq9 eee~\t-\t?psbm#`obpp>!wkf#pvaif`w#legfejmjwjlmp#le=\t?ojmh#qfo>!`objn#wkbw#wkfkbuf#gfufolsfg?wbaof#tjgwk>!`fofaqbwjlm#leElooltjmd#wkf#wl#gjpwjmdvjpk?psbm#`obpp>!awbhfp#sob`f#jmvmgfq#wkf#mbnfmlwfg#wkbw#wkf=?"Xfmgje^..=\tpwzof>!nbqdjm.jmpwfbg#le#wkfjmwqlgv`fg#wkfwkf#sql`fpp#lejm`qfbpjmd#wkfgjeefqfm`fp#jmfpwjnbwfg#wkbwfpsf`jbooz#wkf,gju=?gju#jg>!tbp#fufmwvboozwkqlvdklvw#kjpwkf#gjeefqfm`fplnfwkjmd#wkbwpsbm=?,psbm=?,pjdmjej`bmwoz#=?,p`qjsw=\t\tfmujqlmnfmwbo#wl#sqfufmw#wkfkbuf#affm#vpfgfpsf`jbooz#elqvmgfqpwbmg#wkfjp#fppfmwjbooztfqf#wkf#ejqpwjp#wkf#obqdfpwkbuf#affm#nbgf!#pq`>!kwws9,,jmwfqsqfwfg#bppf`lmg#kboe#le`qloojmd>!ml!#jp#`lnslpfg#leJJ/#Kloz#Qlnbmjp#f{sf`wfg#wlkbuf#wkfjq#ltmgfejmfg#bp#wkfwqbgjwjlmbooz#kbuf#gjeefqfmwbqf#lewfm#vpfgwl#fmpvqf#wkbwbdqffnfmw#tjwk`lmwbjmjmd#wkfbqf#eqfrvfmwozjmelqnbwjlm#lmf{bnsof#jp#wkfqfpvowjmd#jm#b?,b=?,oj=?,vo=#`obpp>!ellwfqbmg#fpsf`jboozwzsf>!avwwlm!#?,psbm=?,psbm=tkj`k#jm`ovgfg=\t?nfwb#mbnf>!`lmpjgfqfg#wkf`bqqjfg#lvw#azKltfufq/#jw#jpaf`bnf#sbqw#lejm#qfobwjlm#wlslsvobq#jm#wkfwkf#`bsjwbo#letbp#leej`jbooztkj`k#kbp#affmwkf#Kjpwlqz#lebowfqmbwjuf#wlgjeefqfmw#eqlnwl#pvsslqw#wkfpvddfpwfg#wkbwjm#wkf#sql`fpp##?gju#`obpp>!wkf#elvmgbwjlmaf`bvpf#le#kjp`lm`fqmfg#tjwkwkf#vmjufqpjwzlsslpfg#wl#wkfwkf#`lmwf{w#le?psbm#`obpp>!swf{w!#mbnf>!r!\n\n?gju#`obpp>!wkf#p`jfmwjej`qfsqfpfmwfg#aznbwkfnbwj`jbmpfof`wfg#az#wkfwkbw#kbuf#affm=?gju#`obpp>!`gju#jg>!kfbgfqjm#sbqwj`vobq/`lmufqwfg#jmwl*8\t?,p`qjsw=\t?skjolplskj`bo#pqsphlkqubwphjwj\rVSmd#Uj\rWkw!kwws9,,!=?psbm#`obpp>!nfnafqp#le#wkf#tjmglt-ol`bwjlmufqwj`bo.bojdm9,b=##?b#kqfe>!?"gl`wzsf#kwno=nfgjb>!p`qffm!#?lswjlm#ubovf>!ebuj`lm-j`l!#,=\t\n\n?gju#`obpp>!`kbqb`wfqjpwj`p!#nfwklg>!dfw!#,algz=\t?,kwno=\tpklqw`vw#j`lm!#gl`vnfmw-tqjwf+sbggjmd.alwwln9qfsqfpfmwbwjufppvanjw!#ubovf>!bojdm>!`fmwfq!#wkqlvdklvw#wkf#p`jfm`f#ej`wjlm\t##?gju#`obpp>!pvanjw!#`obpp>!lmf#le#wkf#nlpw#ubojdm>!wls!=?tbp#fpwbaojpkfg*8\t?,p`qjsw=\tqfwvqm#ebopf8!=*-pwzof-gjpsobzaf`bvpf#le#wkf#gl`vnfmw-`llhjf?elqn#b`wjlm>!,~algzxnbqdjm938Fm`z`olsfgjb#leufqpjlm#le#wkf#-`qfbwfFofnfmw+mbnf!#`lmwfmw>!?,gju=\t?,gju=\t\tbgnjmjpwqbwjuf#?,algz=\t?,kwno=kjpwlqz#le#wkf#!=?jmsvw#wzsf>!slqwjlm#le#wkf#bp#sbqw#le#wkf#%maps8?b#kqfe>!lwkfq#`lvmwqjfp!=\t?gju#`obpp>!?,psbm=?,psbm=?Jm#lwkfq#tlqgp/gjpsobz9#aol`h8`lmwqlo#le#wkf#jmwqlgv`wjlm#le,=\t?nfwb#mbnf>!bp#tfoo#bp#wkf#jm#qf`fmw#zfbqp\t\n?gju#`obpp>!?,gju=\t\n?,gju=\tjmpsjqfg#az#wkfwkf#fmg#le#wkf#`lnsbwjaof#tjwkaf`bnf#hmltm#bp#pwzof>!nbqdjm9-ip!=?,p`qjsw=?#Jmwfqmbwjlmbo#wkfqf#kbuf#affmDfqnbm#obmdvbdf#pwzof>!`lolq9 @lnnvmjpw#Sbqwz`lmpjpwfmw#tjwkalqgfq>!3!#`foo#nbqdjmkfjdkw>!wkf#nbilqjwz#le!#bojdm>!`fmwfqqfobwfg#wl#wkf#nbmz#gjeefqfmw#Lqwklgl{#@kvq`kpjnjobq#wl#wkf#,=\t?ojmh#qfo>!ptbp#lmf#le#wkf#vmwjo#kjp#gfbwk~*+*8\t?,p`qjsw=lwkfq#obmdvbdfp`lnsbqfg#wl#wkfslqwjlmp#le#wkfwkf#Mfwkfqobmgpwkf#nlpw#`lnnlmab`hdqlvmg9vqo+bqdvfg#wkbw#wkfp`qloojmd>!ml!#jm`ovgfg#jm#wkfMlqwk#Bnfqj`bm#wkf#mbnf#le#wkfjmwfqsqfwbwjlmpwkf#wqbgjwjlmbogfufolsnfmw#le#eqfrvfmwoz#vpfgb#`loof`wjlm#leufqz#pjnjobq#wlpvqqlvmgjmd#wkff{bnsof#le#wkjpbojdm>!`fmwfq!=tlvog#kbuf#affmjnbdf\\`bswjlm#>bwwb`kfg#wl#wkfpvddfpwjmd#wkbwjm#wkf#elqn#le#jmuloufg#jm#wkfjp#gfqjufg#eqlnmbnfg#bewfq#wkfJmwqlgv`wjlm#wlqfpwqj`wjlmp#lm#pwzof>!tjgwk9#`bm#af#vpfg#wl#wkf#`qfbwjlm#lenlpw#jnslqwbmw#jmelqnbwjlm#bmgqfpvowfg#jm#wkf`loobspf#le#wkfWkjp#nfbmp#wkbwfofnfmwp#le#wkftbp#qfsob`fg#azbmbozpjp#le#wkfjmpsjqbwjlm#elqqfdbqgfg#bp#wkfnlpw#pv``fppevohmltm#bp#%rvlw8b#`lnsqfkfmpjufKjpwlqz#le#wkf#tfqf#`lmpjgfqfgqfwvqmfg#wl#wkfbqf#qfefqqfg#wlVmplvq`fg#jnbdf=\t\n?gju#`obpp>!`lmpjpwp#le#wkfpwlsSqlsbdbwjlmjmwfqfpw#jm#wkfbubjobajojwz#lebssfbqp#wl#kbuffof`wqlnbdmfwj`fmbaofPfquj`fp+evm`wjlm#le#wkfJw#jp#jnslqwbmw?,p`qjsw=?,gju=evm`wjlm+*xubq#qfobwjuf#wl#wkfbp#b#qfpvow#le#wkf#slpjwjlm#leElq#f{bnsof/#jm#nfwklg>!slpw!#tbp#elooltfg#az%bns8ngbpk8#wkfwkf#bssoj`bwjlmip!=?,p`qjsw=\tvo=?,gju=?,gju=bewfq#wkf#gfbwktjwk#qfpsf`w#wlpwzof>!sbggjmd9jp#sbqwj`vobqozgjpsobz9jmojmf8#wzsf>!pvanjw!#jp#gjujgfg#jmwl\bTA\nzk#+\vBl\bQ*qfpslmpbajojgbgbgnjmjpwqb`j/_mjmwfqmb`jlmbofp`lqqfpslmgjfmwf\fHe\fHF\fHC\fIg\fH{\fHF\fIn\fH\\\fIa\fHY\fHU\fHB\fHR\fH\\\fIk\fH^\fIg\fH{\fIg\fHn\fHv\fIm\fHD\fHR\fHY\fH^\fIk\fHy\fHS\fHD\fHT\fH\\\fHy\fHR\fH\\\fHF\fIm\fH^\fHS\fHT\fHz\fIg\fHp\fIk\fHn\fHv\fHR\fHU\fHS\fHc\fHA\fIk\fHp\fIk\fHn\fHZ\fHR\fHB\fHS\fH^\fHU\fHB\fHR\fH\\\fIl\fHp\fHR\fH{\fH\\\fHO\fH@\fHD\fHR\fHD\fIk\fHy\fIm\fHB\fHR\fH\\\fH@\fIa\fH^\fIe\fH{\fHB\fHR\fH^\fHS\fHy\fHB\fHU\fHS\fH^\fHR\fHF\fIo\fH[\fIa\fHL\fH@\fHN\fHP\fHH\fIk\fHA\fHR\fHp\fHF\fHR\fHy\fIa\fH^\fHS\fHy\fHs\fIa\fH\\\fIk\fHD\fHz\fHS\fH^\fHR\fHG\fHJ\fI`\fH\\\fHR\fHD\fHB\fHR\fHB\fH^\fIk\fHB\fHH\fHJ\fHR\fHD\fH@\fHR\fHp\fHR\fH\\\fHY\fHS\fHy\fHR\fHT\fHy\fIa\fHC\fIg\fHn\fHv\fHR\fHU\fHH\fIk\fHF\fHU\fIm\fHm\fHv\fH@\fHH\fHR\fHC\fHR\fHT\fHn\fHY\fHR\fHJ\fHJ\fIk\fHz\fHD\fIk\fHF\fHS\fHw\fH^\fIk\fHY\fHS\fHZ\fIk\fH[\fH\\\fHR\fHp\fIa\fHC\fHe\fHH\fIa\fHH\fH\\\fHB\fIm\fHn\fH@\fHd\fHJ\fIg\fHD\fIg\fHn\fHe\fHF\fHy\fH\\\fHO\fHF\fHN\fHP\fIk\fHn\fHT\fIa\fHI\fHS\fHH\fHG\fHS\fH^\fIa\fHB\fHB\fIm\fHz\fIa\fHC\fHi\fHv\fIa\fHw\fHR\fHw\fIn\fHs\fHH\fIl\fHT\fHn\fH{\fIl\fHH\fHp\fHR\fHc\fH{\fHR\fHY\fHS\fHA\fHR\fH{\fHt\fHO\fIa\fHs\fIk\fHJ\fIn\fHT\fH\\\fIk\fHJ\fHS\fHD\fIg\fHn\fHU\fHH\fIa\fHC\fHR\fHT\fIk\fHy\fIa\fHT\fH{\fHR\fHn\fHK\fIl\fHY\fHS\fHZ\fIa\fHY\fH\\\fHR\fHH\fIk\fHn\fHJ\fId\fHs\fIa\fHT\fHD\fHy\fIa\fHZ\fHR\fHT\fHR\fHB\fHD\fIk\fHi\fHJ\fHR\fH^\fHH\fH@\fHS\fHp\fH^\fIl\fHF\fIm\fH\\\fIn\fH[\fHU\fHS\fHn\fHJ\fIl\fHB\fHS\fHH\fIa\fH\\\fHy\fHY\fHS\fHH\fHR\fH\\\fIm\fHF\fHC\fIk\fHT\fIa\fHI\fHR\fHD\fHy\fH\\\fIg\fHM\fHP\fHB\fIm\fHy\fIa\fHH\fHC\fIg\fHp\fHD\fHR\fHy\fIo\fHF\fHC\fHR\fHF\fIg\fHT\fIa\fHs\fHt\fH\\\fIk\fH^\fIn\fHy\fHR\fH\\\fIa\fHC\fHY\fHS\fHv\fHR\fH\\\fHT\fIn\fHv\fHD\fHR\fHB\fIn\fH^\fIa\fHC\fHJ\fIk\fHz\fIk\fHn\fHU\fHB\fIk\fHZ\fHR\fHT\fIa\fHy\fIn\fH^\fHB\fId\fHn\fHD\fIk\fHH\fId\fHC\fHR\fH\\\fHp\fHS\fHT\fHy\fIkqpp({no!#wjwof>!.wzsf!#`lmwfmw>!wjwof!#`lmwfmw>!bw#wkf#pbnf#wjnf-ip!=?,p`qjsw=\t?!#nfwklg>!slpw!#?,psbm=?,b=?,oj=ufqwj`bo.bojdm9w,irvfqz-njm-ip!=-`oj`h+evm`wjlm+#pwzof>!sbggjmd.~*+*8\t?,p`qjsw=\t?,psbm=?b#kqfe>!?b#kqfe>!kwws9,,*8#qfwvqm#ebopf8wf{w.gf`lqbwjlm9#p`qloojmd>!ml!#alqgfq.`loobspf9bppl`jbwfg#tjwk#Abkbpb#JmglmfpjbFmdojpk#obmdvbdf?wf{w#{no9psb`f>-dje!#alqgfq>!3!?,algz=\t?,kwno=\tlufqeolt9kjggfm8jnd#pq`>!kwws9,,bggFufmwOjpwfmfqqfpslmpjaof#elq#p-ip!=?,p`qjsw=\t,ebuj`lm-j`l!#,=lsfqbwjmd#pzpwfn!#pwzof>!tjgwk92wbqdfw>!\\aobmh!=Pwbwf#Vmjufqpjwzwf{w.bojdm9ofew8\tgl`vnfmw-tqjwf+/#jm`ovgjmd#wkf#bqlvmg#wkf#tlqog*8\t?,p`qjsw=\t?!#pwzof>!kfjdkw98lufqeolt9kjggfmnlqf#jmelqnbwjlmbm#jmwfqmbwjlmbob#nfnafq#le#wkf#lmf#le#wkf#ejqpw`bm#af#elvmg#jm#?,gju=\t\n\n?,gju=\tgjpsobz9#mlmf8!=!#,=\t?ojmh#qfo>!\t##+evm`wjlm+*#xwkf#26wk#`fmwvqz-sqfufmwGfebvow+obqdf#mvnafq#le#Azybmwjmf#Fnsjqf-isdwkvnaofewubpw#nbilqjwz#lenbilqjwz#le#wkf##bojdm>!`fmwfq!=Vmjufqpjwz#Sqfppglnjmbwfg#az#wkfPf`lmg#Tlqog#Tbqgjpwqjavwjlm#le#pwzof>!slpjwjlm9wkf#qfpw#le#wkf#`kbqb`wfqjyfg#az#qfo>!mleloolt!=gfqjufp#eqln#wkfqbwkfq#wkbm#wkf#b#`lnajmbwjlm#lepwzof>!tjgwk9233Fmdojpk.psfbhjmd`lnsvwfq#p`jfm`falqgfq>!3!#bow>!wkf#f{jpwfm`f#leGfnl`qbwj`#Sbqwz!#pwzof>!nbqdjm.Elq#wkjp#qfbplm/-ip!=?,p`qjsw=\t\npAzWbdMbnf+p*X3^ip!=?,p`qjsw=\t?-ip!=?,p`qjsw=\tojmh#qfo>!j`lm!#$#bow>$$#`obpp>$elqnbwjlm#le#wkfufqpjlmp#le#wkf#?,b=?,gju=?,gju=,sbdf=\t##?sbdf=\t?gju#`obpp>!`lmwaf`bnf#wkf#ejqpwabkbpb#Jmglmfpjbfmdojpk#+pjnsof*"y"W"W"["Q"U"V"@=i=l<^<\\=n=m!?gju#jg>!ellwfq!=wkf#Vmjwfg#Pwbwfp?jnd#pq`>!kwws9,,-isdqjdkwwkvna-ip!=?,p`qjsw=\t?ol`bwjlm-sqlwl`loeqbnfalqgfq>!3!#p!#,=\t?nfwb#mbnf>!?,b=?,gju=?,gju=?elmw.tfjdkw9alog8%rvlw8#bmg#%rvlw8gfsfmgjmd#lm#wkf#nbqdjm938sbggjmd9!#qfo>!mleloolt!#Sqfpjgfmw#le#wkf#wtfmwjfwk#`fmwvqzfujpjlm=\t##?,sbdfJmwfqmfw#F{solqfqb-bpzm`#>#wqvf8\tjmelqnbwjlm#balvw?gju#jg>!kfbgfq!=!#b`wjlm>!kwws9,,?b#kqfe>!kwwsp9,,?gju#jg>!`lmwfmw!?,gju=\t?,gju=\t?gfqjufg#eqln#wkf#?jnd#pq`>$kwws9,,b``lqgjmd#wl#wkf#\t?,algz=\t?,kwno=\tpwzof>!elmw.pjyf9p`qjsw#obmdvbdf>!Bqjbo/#Kfoufwj`b/?,b=?psbm#`obpp>!?,p`qjsw=?p`qjsw#slojwj`bo#sbqwjfpwg=?,wq=?,wbaof=?kqfe>!kwws9,,ttt-jmwfqsqfwbwjlm#leqfo>!pwzofpkffw!#gl`vnfmw-tqjwf+$?`kbqpfw>!vwe.;!=\tafdjmmjmd#le#wkf#qfufbofg#wkbw#wkfwfofujpjlm#pfqjfp!#qfo>!mleloolt!=#wbqdfw>!\\aobmh!=`objnjmd#wkbw#wkfkwws&0B&1E&1Ettt-nbmjefpwbwjlmp#leSqjnf#Njmjpwfq#lejmeovfm`fg#az#wkf`obpp>!`ofbqej{!=,gju=\t?,gju=\t\twkqff.gjnfmpjlmbo@kvq`k#le#Fmdobmgle#Mlqwk#@bqlojmbprvbqf#hjolnfwqfp-bggFufmwOjpwfmfqgjpwjm`w#eqln#wkf`lnnlmoz#hmltm#bpSklmfwj`#Boskbafwgf`obqfg#wkbw#wkf`lmwqloofg#az#wkfAfmibnjm#Eqbmhojmqlof.sobzjmd#dbnfwkf#Vmjufqpjwz#lejm#Tfpwfqm#Fvqlsfsfqplmbo#`lnsvwfqSqlif`w#Dvwfmafqdqfdbqgofpp#le#wkfkbp#affm#sqlslpfgwldfwkfq#tjwk#wkf=?,oj=?oj#`obpp>!jm#plnf#`lvmwqjfpnjm-ip!=?,p`qjsw=le#wkf#slsvobwjlmleej`jbo#obmdvbdf?jnd#pq`>!jnbdfp,jgfmwjejfg#az#wkfmbwvqbo#qfplvq`fp`obppjej`bwjlm#le`bm#af#`lmpjgfqfgrvbmwvn#nf`kbmj`pMfufqwkfofpp/#wkfnjoojlm#zfbqp#bdl?,algz=\t?,kwno="y"W"W"["Q"U"V"@\twbhf#bgubmwbdf#lebmg/#b``lqgjmd#wlbwwqjavwfg#wl#wkfNj`qlplew#Tjmgltpwkf#ejqpw#`fmwvqzvmgfq#wkf#`lmwqlogju#`obpp>!kfbgfqpklqwoz#bewfq#wkfmlwbaof#f{`fswjlmwfmp#le#wklvpbmgppfufqbo#gjeefqfmwbqlvmg#wkf#tlqog-qfb`kjmd#njojwbqzjplobwfg#eqln#wkflsslpjwjlm#wl#wkfwkf#Log#WfpwbnfmwBeqj`bm#Bnfqj`bmpjmpfqwfg#jmwl#wkfpfsbqbwf#eqln#wkfnfwqlslojwbm#bqfbnbhfp#jw#slppjaofb`hmltofgdfg#wkbwbqdvbaoz#wkf#nlpwwzsf>!wf{w,`pp!=\twkf#JmwfqmbwjlmboB``lqgjmd#wl#wkf#sf>!wf{w,`pp!#,=\t`ljm`jgf#tjwk#wkfwtl.wkjqgp#le#wkfGvqjmd#wkjp#wjnf/gvqjmd#wkf#sfqjlgbmmlvm`fg#wkbw#kfwkf#jmwfqmbwjlmbobmg#nlqf#qf`fmwozafojfufg#wkbw#wkf`lmp`jlvpmfpp#bmgelqnfqoz#hmltm#bppvqqlvmgfg#az#wkfejqpw#bssfbqfg#jml``bpjlmbooz#vpfgslpjwjlm9baplovwf8!#wbqdfw>!\\aobmh!#slpjwjlm9qfobwjuf8wf{w.bojdm9`fmwfq8ib{,ojap,irvfqz,2-ab`hdqlvmg.`lolq9 wzsf>!bssoj`bwjlm,bmdvbdf!#`lmwfmw>!?nfwb#kwws.frvju>!Sqjub`z#Sloj`z?,b=f+!&0@p`qjsw#pq`>$!#wbqdfw>!\\aobmh!=Lm#wkf#lwkfq#kbmg/-isdwkvnaqjdkw1?,gju=?gju#`obpp>!?gju#pwzof>!eolbw9mjmfwffmwk#`fmwvqz?,algz=\t?,kwno=\t?jnd#pq`>!kwws9,,p8wf{w.bojdm9`fmwfqelmw.tfjdkw9#alog8#B``lqgjmd#wl#wkf#gjeefqfm`f#afwtffm!#eqbnfalqgfq>!3!#!#pwzof>!slpjwjlm9ojmh#kqfe>!kwws9,,kwno7,ollpf-gwg!=\tgvqjmd#wkjp#sfqjlg?,wg=?,wq=?,wbaof=`olpfoz#qfobwfg#wlelq#wkf#ejqpw#wjnf8elmw.tfjdkw9alog8jmsvw#wzsf>!wf{w!#?psbm#pwzof>!elmw.lmqfbgzpwbwf`kbmdf\n?gju#`obpp>!`ofbqgl`vnfmw-ol`bwjlm-#Elq#f{bnsof/#wkf#b#tjgf#ubqjfwz#le#?"GL@WZSF#kwno=\t?%maps8%maps8%maps8!=?b#kqfe>!kwws9,,pwzof>!eolbw9ofew8`lm`fqmfg#tjwk#wkf>kwws&0B&1E&1Ettt-jm#slsvobq#`vowvqfwzsf>!wf{w,`pp!#,=jw#jp#slppjaof#wl#Kbqubqg#Vmjufqpjwzwzofpkffw!#kqfe>!,wkf#nbjm#`kbqb`wfqL{elqg#Vmjufqpjwz##mbnf>!hfztlqgp!#`pwzof>!wf{w.bojdm9wkf#Vmjwfg#Hjmdglnefgfqbo#dlufqmnfmw?gju#pwzof>!nbqdjm#gfsfmgjmd#lm#wkf#gfp`qjswjlm#le#wkf?gju#`obpp>!kfbgfq-njm-ip!=?,p`qjsw=gfpwqv`wjlm#le#wkfpojdkwoz#gjeefqfmwjm#b``lqgbm`f#tjwkwfof`lnnvmj`bwjlmpjmgj`bwfp#wkbw#wkfpklqwoz#wkfqfbewfqfpsf`jbooz#jm#wkf#Fvqlsfbm#`lvmwqjfpKltfufq/#wkfqf#bqfpq`>!kwws9,,pwbwj`pvddfpwfg#wkbw#wkf!#pq`>!kwws9,,ttt-b#obqdf#mvnafq#le#Wfof`lnnvmj`bwjlmp!#qfo>!mleloolt!#wKloz#Qlnbm#Fnsfqlqbonlpw#f{`ovpjufoz!#alqgfq>!3!#bow>!Pf`qfwbqz#le#Pwbwf`vonjmbwjmd#jm#wkf@JB#Tlqog#Eb`wallhwkf#nlpw#jnslqwbmwbmmjufqpbqz#le#wkfpwzof>!ab`hdqlvmg.?oj=?fn=?b#kqfe>!,wkf#Bwobmwj`#L`fbmpwqj`woz#psfbhjmd/pklqwoz#afelqf#wkfgjeefqfmw#wzsfp#lewkf#Lwwlnbm#Fnsjqf=?jnd#pq`>!kwws9,,Bm#Jmwqlgv`wjlm#wl`lmpfrvfm`f#le#wkfgfsbqwvqf#eqln#wkf@lmefgfqbwf#Pwbwfpjmgjdfmlvp#sflsofpSql`ffgjmdp#le#wkfjmelqnbwjlm#lm#wkfwkflqjfp#kbuf#affmjmuloufnfmw#jm#wkfgjujgfg#jmwl#wkqffbgib`fmw#`lvmwqjfpjp#qfpslmpjaof#elqgjpplovwjlm#le#wkf`loobalqbwjlm#tjwktjgfoz#qfdbqgfg#bpkjp#`lmwfnslqbqjfpelvmgjmd#nfnafq#leGlnjmj`bm#Qfsvaoj`dfmfqbooz#b``fswfgwkf#slppjajojwz#lebqf#bopl#bubjobaofvmgfq#`lmpwqv`wjlmqfpwlqbwjlm#le#wkfwkf#dfmfqbo#svaoj`jp#bonlpw#fmwjqfozsbppfp#wkqlvdk#wkfkbp#affm#pvddfpwfg`lnsvwfq#bmg#ujgflDfqnbmj`#obmdvbdfp#b``lqgjmd#wl#wkf#gjeefqfmw#eqln#wkfpklqwoz#bewfqtbqgpkqfe>!kwwsp9,,ttt-qf`fmw#gfufolsnfmwAlbqg#le#Gjqf`wlqp?gju#`obpp>!pfbq`k#?b#kqfe>!kwws9,,Jm#sbqwj`vobq/#wkfNvowjsof#ellwmlwfplq#lwkfq#pvapwbm`fwklvpbmgp#le#zfbqpwqbmpobwjlm#le#wkf?,gju=\t?,gju=\t\t?b#kqfe>!jmgf{-skstbp#fpwbaojpkfg#jmnjm-ip!=?,p`qjsw=\tsbqwj`jsbwf#jm#wkfb#pwqlmd#jmeovfm`fpwzof>!nbqdjm.wls9qfsqfpfmwfg#az#wkfdqbgvbwfg#eqln#wkfWqbgjwjlmbooz/#wkfFofnfmw+!p`qjsw!*8Kltfufq/#pjm`f#wkf,gju=\t?,gju=\t?gju#ofew8#nbqdjm.ofew9sqlwf`wjlm#bdbjmpw38#ufqwj`bo.bojdm9Vmelqwvmbwfoz/#wkfwzsf>!jnbdf,{.j`lm,gju=\t?gju#`obpp>!#`obpp>!`ofbqej{!=?gju#`obpp>!ellwfq\n\n?,gju=\t\n\n?,gju=\twkf#nlwjlm#sj`wvqf<}=f!t0-lqd,2:::,{kwno!=?b#wbqdfw>!\\aobmh!#wf{w,kwno8#`kbqpfw>!#wbqdfw>!\\aobmh!=?wbaof#`foosbggjmd>!bvwl`lnsofwf>!lee!#wf{w.bojdm9#`fmwfq8wl#obpw#ufqpjlm#az#ab`hdqlvmg.`lolq9# !#kqfe>!kwws9,,ttt-,gju=?,gju=?gju#jg>?b#kqfe>! !#`obpp>!!=?jnd#pq`>!kwws9,,`qjsw!#pq`>!kwws9,,\t?p`qjsw#obmdvbdf>!,,FM!#!kwws9,,ttt-tfm`lgfVQJ@lnslmfmw+!#kqfe>!ibubp`qjsw9?gju#`obpp>!`lmwfmwgl`vnfmw-tqjwf+$?p`slpjwjlm9#baplovwf8p`qjsw#pq`>!kwws9,,#pwzof>!nbqdjm.wls9-njm-ip!=?,p`qjsw=\t?,gju=\t?gju#`obpp>!t0-lqd,2:::,{kwno!#\t\t?,algz=\t?,kwno=gjpwjm`wjlm#afwtffm,!#wbqdfw>!\\aobmh!=?ojmh#kqfe>!kwws9,,fm`lgjmd>!vwe.;!<=\tt-bggFufmwOjpwfmfq!kwws9,,ttt-j`lm!#kqfe>!kwws9,,#pwzof>!ab`hdqlvmg9wzsf>!wf{w,`pp!#,=\tnfwb#sqlsfqwz>!ld9w?jmsvw#wzsf>!wf{w!##pwzof>!wf{w.bojdm9wkf#gfufolsnfmw#le#wzofpkffw!#wzsf>!wfkwno8#`kbqpfw>vwe.;jp#`lmpjgfqfg#wl#afwbaof#tjgwk>!233&!#Jm#bggjwjlm#wl#wkf#`lmwqjavwfg#wl#wkf#gjeefqfm`fp#afwtffmgfufolsnfmw#le#wkf#Jw#jp#jnslqwbmw#wl#?,p`qjsw=\t\t?p`qjsw##pwzof>!elmw.pjyf92=?,psbm=?psbm#jg>daOjaqbqz#le#@lmdqfpp?jnd#pq`>!kwws9,,jnFmdojpk#wqbmpobwjlmB`bgfnz#le#P`jfm`fpgju#pwzof>!gjpsobz9`lmpwqv`wjlm#le#wkf-dfwFofnfmwAzJg+jg*jm#`lmivm`wjlm#tjwkFofnfmw+$p`qjsw$*8#?nfwb#sqlsfqwz>!ld9<}=f!wf{w!#mbnf>!=Sqjub`z#Sloj`z?,b=bgnjmjpwfqfg#az#wkffmbaofPjmdofQfrvfpwpwzof>%rvlw8nbqdjm9?,gju=?,gju=?,gju=?=?jnd#pq`>!kwws9,,j#pwzof>%rvlw8eolbw9qfefqqfg#wl#bp#wkf#wlwbo#slsvobwjlm#lejm#Tbpkjmdwlm/#G-@-#pwzof>!ab`hdqlvmg.bnlmd#lwkfq#wkjmdp/lqdbmjybwjlm#le#wkfsbqwj`jsbwfg#jm#wkfwkf#jmwqlgv`wjlm#lejgfmwjejfg#tjwk#wkfej`wjlmbo#`kbqb`wfq#L{elqg#Vmjufqpjwz#njpvmgfqpwbmgjmd#leWkfqf#bqf/#kltfufq/pwzofpkffw!#kqfe>!,@lovnajb#Vmjufqpjwzf{sbmgfg#wl#jm`ovgfvpvbooz#qfefqqfg#wljmgj`bwjmd#wkbw#wkfkbuf#pvddfpwfg#wkbwbeejojbwfg#tjwk#wkf`lqqfobwjlm#afwtffmmvnafq#le#gjeefqfmw=?,wg=?,wq=?,wbaof=Qfsvaoj`#le#Jqfobmg\t?,p`qjsw=\t?p`qjsw#vmgfq#wkf#jmeovfm`f`lmwqjavwjlm#wl#wkfLeej`jbo#tfapjwf#lekfbgrvbqwfqp#le#wkf`fmwfqfg#bqlvmg#wkfjnsoj`bwjlmp#le#wkfkbuf#affm#gfufolsfgEfgfqbo#Qfsvaoj`#leaf`bnf#jm`qfbpjmdoz`lmwjmvbwjlm#le#wkfMlwf/#kltfufq/#wkbwpjnjobq#wl#wkbw#le#`bsbajojwjfp#le#wkfb``lqgbm`f#tjwk#wkfsbqwj`jsbmwp#jm#wkfevqwkfq#gfufolsnfmwvmgfq#wkf#gjqf`wjlmjp#lewfm#`lmpjgfqfgkjp#zlvmdfq#aqlwkfq?,wg=?,wq=?,wbaof=?b#kwws.frvju>![.VB.skzpj`bo#sqlsfqwjfple#Aqjwjpk#@lovnajbkbp#affm#`qjwj`jyfg+tjwk#wkf#f{`fswjlmrvfpwjlmp#balvw#wkfsbppjmd#wkqlvdk#wkf3!#`foosbggjmd>!3!#wklvpbmgp#le#sflsofqfgjqf`wp#kfqf-#Elqkbuf#`kjogqfm#vmgfq&0F&0@,p`qjsw&0F!**8?b#kqfe>!kwws9,,ttt-?oj=?b#kqfe>!kwws9,,pjwf\\mbnf!#`lmwfmw>!wf{w.gf`lqbwjlm9mlmfpwzof>!gjpsobz9#mlmf?nfwb#kwws.frvju>![.mft#Gbwf+*-dfwWjnf+*#wzsf>!jnbdf,{.j`lm!?,psbm=?psbm#`obpp>!obmdvbdf>!ibubp`qjswtjmglt-ol`bwjlm-kqfe?b#kqfe>!ibubp`qjsw9..=\t?p`qjsw#wzsf>!w?b#kqfe>$kwws9,,ttt-klqw`vw#j`lm!#kqfe>!?,gju=\t?gju#`obpp>!?p`qjsw#pq`>!kwws9,,!#qfo>!pwzofpkffw!#w?,gju=\t?p`qjsw#wzsf>,b=#?b#kqfe>!kwws9,,#booltWqbmpsbqfm`z>![.VB.@lnsbwjaof!#`lmqfobwjlmpkjs#afwtffm\t?,p`qjsw=\t?p`qjsw#?,b=?,oj=?,vo=?,gju=bppl`jbwfg#tjwk#wkf#sqldqbnnjmd#obmdvbdf?,b=?b#kqfe>!kwws9,,?,b=?,oj=?oj#`obpp>!elqn#b`wjlm>!kwws9,,?gju#pwzof>!gjpsobz9wzsf>!wf{w!#mbnf>!r!?wbaof#tjgwk>!233&!#ab`hdqlvmg.slpjwjlm9!#alqgfq>!3!#tjgwk>!qfo>!pklqw`vw#j`lm!#k5=?vo=?oj=?b#kqfe>!##?nfwb#kwws.frvju>!`pp!#nfgjb>!p`qffm!#qfpslmpjaof#elq#wkf#!#wzsf>!bssoj`bwjlm,!#pwzof>!ab`hdqlvmg.kwno8#`kbqpfw>vwe.;!#booltwqbmpsbqfm`z>!pwzofpkffw!#wzsf>!wf\t?nfwb#kwws.frvju>!=?,psbm=?psbm#`obpp>!3!#`foopsb`jmd>!3!=8\t?,p`qjsw=\t?p`qjsw#plnfwjnfp#`boofg#wkfglfp#mlw#mf`fppbqjozElq#nlqf#jmelqnbwjlmbw#wkf#afdjmmjmd#le#?"GL@WZSF#kwno=?kwnosbqwj`vobqoz#jm#wkf#wzsf>!kjggfm!#mbnf>!ibubp`qjsw9uljg+3*8!feef`wjufmfpp#le#wkf#bvwl`lnsofwf>!lee!#dfmfqbooz#`lmpjgfqfg=?jmsvw#wzsf>!wf{w!#!=?,p`qjsw=\t?p`qjswwkqlvdklvw#wkf#tlqog`lnnlm#njp`lm`fswjlmbppl`jbwjlm#tjwk#wkf?,gju=\t?,gju=\t?gju#`gvqjmd#kjp#ojefwjnf/`lqqfpslmgjmd#wl#wkfwzsf>!jnbdf,{.j`lm!#bm#jm`qfbpjmd#mvnafqgjsolnbwj`#qfobwjlmpbqf#lewfm#`lmpjgfqfgnfwb#`kbqpfw>!vwe.;!#?jmsvw#wzsf>!wf{w!#f{bnsofp#jm`ovgf#wkf!=?jnd#pq`>!kwws9,,jsbqwj`jsbwjlm#jm#wkfwkf#fpwbaojpknfmw#le\t?,gju=\t?gju#`obpp>!%bns8maps8%bns8maps8wl#gfwfqnjmf#tkfwkfqrvjwf#gjeefqfmw#eqlnnbqhfg#wkf#afdjmmjmdgjpwbm`f#afwtffm#wkf`lmwqjavwjlmp#wl#wkf`lmeoj`w#afwtffm#wkftjgfoz#`lmpjgfqfg#wltbp#lmf#le#wkf#ejqpwtjwk#ubqzjmd#gfdqffpkbuf#psf`vobwfg#wkbw+gl`vnfmw-dfwFofnfmwsbqwj`jsbwjmd#jm#wkflqjdjmbooz#gfufolsfgfwb#`kbqpfw>!vwe.;!=#wzsf>!wf{w,`pp!#,=\tjmwfq`kbmdfbaoz#tjwknlqf#`olpfoz#qfobwfgpl`jbo#bmg#slojwj`bowkbw#tlvog#lwkfqtjpfsfqsfmgj`vobq#wl#wkfpwzof#wzsf>!wf{w,`ppwzsf>!pvanjw!#mbnf>!ebnjojfp#qfpjgjmd#jmgfufolsjmd#`lvmwqjfp`lnsvwfq#sqldqbnnjmdf`lmlnj`#gfufolsnfmwgfwfqnjmbwjlm#le#wkfelq#nlqf#jmelqnbwjlmlm#pfufqbo#l``bpjlmpslqwvdv/Fp#+Fvqlsfv*VWE.;!#pfwWjnflvw+evm`wjlm+*gjpsobz9jmojmf.aol`h8?jmsvw#wzsf>!pvanjw!#wzsf#>#$wf{w,ibubp`qj?jnd#pq`>!kwws9,,ttt-!#!kwws9,,ttt-t0-lqd,pklqw`vw#j`lm!#kqfe>!!#bvwl`lnsofwf>!lee!#?,b=?,gju=?gju#`obpp>?,b=?,oj=\t?oj#`obpp>!`pp!#wzsf>!wf{w,`pp!#?elqn#b`wjlm>!kwws9,,{w,`pp!#kqfe>!kwws9,,ojmh#qfo>!bowfqmbwf!#\t?p`qjsw#wzsf>!wf{w,#lm`oj`h>!ibubp`qjsw9+mft#Gbwf*-dfwWjnf+*~kfjdkw>!2!#tjgwk>!2!#Sflsof$p#Qfsvaoj`#le##?b#kqfe>!kwws9,,ttt-wf{w.gf`lqbwjlm9vmgfqwkf#afdjmmjmd#le#wkf#?,gju=\t?,gju=\t?,gju=\tfpwbaojpknfmw#le#wkf#?,gju=?,gju=?,gju=?,g ujftslqwxnjm.kfjdkw9\t?p`qjsw#pq`>!kwws9,,lswjlm=?lswjlm#ubovf>lewfm#qfefqqfg#wl#bp#,lswjlm=\t?lswjlm#ubov?"GL@WZSF#kwno=\t?"..XJmwfqmbwjlmbo#Bjqslqw=\t?b#kqfe>!kwws9,,ttt?,b=?b#kqfe>!kwws9,,t\fTL\fT^\fTE\fT^\fUh\fT{\fTN\roI\ro|\roL\ro{\roO\rov\rot\nAOGx\bTA\nzk#+\vUmGx*\fHD\fHS\fH\\\fIa\fHJ\fIk\fHZ\fHM\fHR\fHe\fHD\fH^\fIg\fHM\fHy\fIa\fH[\fIk\fHH\fIa\fH\\\fHp\fHR\fHD\fHy\fHR\fH\\\fIl\fHT\fHn\fH@\fHn\fHK\fHS\fHH\fHT\fIa\fHI\fHR\fHF\fHD\fHR\fHT\fIa\fHY\fIl\fHy\fHR\fH\\\fHT\fHn\fHT\fIa\fHy\fH\\\fHO\fHT\fHR\fHB\fH{\fIa\fH\\\fIl\fHv\fHS\fHs\fIa\fHL\fIg\fHn\fHY\fHS\fHp\fIa\fHr\fHR\fHD\fHi\fHB\fIk\fH\\\fHS\fHy\fHR\fHY\fHS\fHA\fHS\fHD\fIa\fHD\fH{\fHR\fHM\fHS\fHC\fHR\fHm\fHy\fIa\fHC\fIg\fHn\fHy\fHS\fHT\fIm\fH\\\fHy\fIa\fH[\fHR\fHF\fHU\fIm\fHm\fHv\fHH\fIl\fHF\fIa\fH\\\fH@\fHn\fHK\fHD\fHs\fHS\fHF\fIa\fHF\fHO\fIl\fHy\fIa\fH\\\fHS\fHy\fIk\fHs\fHF\fIa\fH\\\fHR\fH\\\fHn\fHA\fHF\fIa\fH\\\fHR\fHF\fIa\fHH\fHB\fHR\fH^\fHS\fHy\fIg\fHn\fH\\\fHG\fHP\fIa\fHH\fHR\fH\\\fHD\fHS\fH\\\fIa\fHB\fHR\fHO\fH^\fHS\fHB\fHS\fHs\fIk\fHMgfp`qjswjlm!#`lmwfmw>!gl`vnfmw-ol`bwjlm-sqlw-dfwFofnfmwpAzWbdMbnf+?"GL@WZSF#kwno=\t?kwno#?nfwb#`kbqpfw>!vwe.;!=9vqo!#`lmwfmw>!kwws9,,-`pp!#qfo>!pwzofpkffw!pwzof#wzsf>!wf{w,`pp!=wzsf>!wf{w,`pp!#kqfe>!t0-lqd,2:::,{kwno!#{nowzsf>!wf{w,ibubp`qjsw!#nfwklg>!dfw!#b`wjlm>!ojmh#qfo>!pwzofpkffw!##>#gl`vnfmw-dfwFofnfmwwzsf>!jnbdf,{.j`lm!#,=`foosbggjmd>!3!#`foops-`pp!#wzsf>!wf{w,`pp!#?,b=?,oj=?oj=?b#kqfe>!!#tjgwk>!2!#kfjdkw>!2!!=?b#kqfe>!kwws9,,ttt-pwzof>!gjpsobz9mlmf8!=bowfqmbwf!#wzsf>!bssoj.,,T0@,,GWG#[KWNO#2-3#foopsb`jmd>!3!#`foosbg#wzsf>!kjggfm!#ubovf>!,b=%maps8?psbm#qlof>!p\t?jmsvw#wzsf>!kjggfm!#obmdvbdf>!IbubP`qjsw!##gl`vnfmw-dfwFofnfmwpAd>!3!#`foopsb`jmd>!3!#zsf>!wf{w,`pp!#nfgjb>!wzsf>$wf{w,ibubp`qjsw$tjwk#wkf#f{`fswjlm#le#zsf>!wf{w,`pp!#qfo>!pw#kfjdkw>!2!#tjgwk>!2!#>$(fm`lgfVQJ@lnslmfmw+?ojmh#qfo>!bowfqmbwf!#\talgz/#wq/#jmsvw/#wf{wnfwb#mbnf>!qlalwp!#`lmnfwklg>!slpw!#b`wjlm>!=\t?b#kqfe>!kwws9,,ttt-`pp!#qfo>!pwzofpkffw!#?,gju=?,gju=?gju#`obppobmdvbdf>!ibubp`qjsw!=bqjb.kjggfm>!wqvf!=.[?qjsw!#wzsf>!wf{w,ibubpo>38~*+*8\t+evm`wjlm+*xab`hdqlvmg.jnbdf9#vqo+,b=?,oj=?oj=?b#kqfe>!k\n\n?oj=?b#kqfe>!kwws9,,bwlq!#bqjb.kjggfm>!wqv=#?b#kqfe>!kwws9,,ttt-obmdvbdf>!ibubp`qjsw!#,lswjlm=\t?lswjlm#ubovf,gju=?,gju=?gju#`obpp>qbwlq!#bqjb.kjggfm>!wqf>+mft#Gbwf*-dfwWjnf+*slqwvdv/Fp#+gl#Aqbpjo*!wf{w,?nfwb#kwws.frvju>!@lmwfqbmpjwjlmbo,,FM!#!kwws9?kwno#{nomp>!kwws9,,ttt.,,T0@,,GWG#[KWNO#2-3#WGWG,{kwno2.wqbmpjwjlmbo,,ttt-t0-lqd,WQ,{kwno2,sf#>#$wf{w,ibubp`qjsw$8?nfwb#mbnf>!gfp`qjswjlmsbqfmwMlgf-jmpfqwAfelqf?jmsvw#wzsf>!kjggfm!#mbip!#wzsf>!wf{w,ibubp`qj+gl`vnfmw*-qfbgz+evm`wjp`qjsw#wzsf>!wf{w,ibubpjnbdf!#`lmwfmw>!kwws9,,VB.@lnsbwjaof!#`lmwfmw>wno8#`kbqpfw>vwe.;!#,=\tojmh#qfo>!pklqw`vw#j`lm?ojmh#qfo>!pwzofpkffw!#?,p`qjsw=\t?p`qjsw#wzsf>>#gl`vnfmw-`qfbwfFofnfm?b#wbqdfw>!\\aobmh!#kqfe>#gl`vnfmw-dfwFofnfmwpAjmsvw#wzsf>!wf{w!#mbnf>b-wzsf#>#$wf{w,ibubp`qjmsvw#wzsf>!kjggfm!#mbnfkwno8#`kbqpfw>vwe.;!#,=gwg!=\t?kwno#{nomp>!kwws.,,T0@,,GWG#KWNO#7-32#WfmwpAzWbdMbnf+$p`qjsw$*jmsvw#wzsf>!kjggfm!#mbn?p`qjsw#wzsf>!wf{w,ibubp!#pwzof>!gjpsobz9mlmf8!=gl`vnfmw-dfwFofnfmwAzJg+>gl`vnfmw-`qfbwfFofnfmw+$#wzsf>$wf{w,ibubp`qjsw$jmsvw#wzsf>!wf{w!#mbnf>!g-dfwFofnfmwpAzWbdMbnf+pmj`bo!#kqfe>!kwws9,,ttt-@,,GWG#KWNO#7-32#Wqbmpjw?pwzof#wzsf>!wf{w,`pp!=\t\t?pwzof#wzsf>!wf{w,`pp!=jlmbo-gwg!=\t?kwno#{nomp>kwws.frvju>!@lmwfmw.Wzsfgjmd>!3!#`foopsb`jmd>!3!kwno8#`kbqpfw>vwe.;!#,=\t#pwzof>!gjpsobz9mlmf8!=??oj=?b#kqfe>!kwws9,,ttt-#wzsf>$wf{w,ibubp`qjsw$=&*&'&^&ˆŸా&ƭ&ƒ&)&^&%&'&‚&P&1&±&3&]&m&u&E&t&C&Ï&V&V&/&>&6&ྲྀ᝼o&p&@&E&M&P&x&@&F&e&Ì&7&:&(&D&0&C&)&.&F&-&1&(&L&F&1ɞ*Ϫ⇳&፲&K&;&)&E&H&P&0&?&9&V&&-&v&a&,&E&)&?&=&'&'&B&മ&ԃ&̖*&*8&%&%&&&%,)&š&>&†&7&]&F&2&>&J&6&n&2&%&?&Ž&2&6&J&g&-&0&,&*&J&*&O&)&6&(&<&B&N&.&P&@&2&.&W&M&%Լ„(,(<&,&Ϛ&ᣇ&-&,(%&(&%&(Ļ0&X&D&&j&'&J&(&.&B&3&Z&R&h&3&E&E&<Æ-͠ỳ&%8?&@&,&Z&@&0&J&,&^&x&_&6&C&6&Cܬ⨥&f&-&-&-&-&,&J&2&8&z&8&C&Y&8&-&d&ṸÌ-&7&1&F&7&t&W&7&I&.&.&^&=ྜ᧓&8(>&/&/&ݻ')'ၥ')'%@/&0&%оী*&*@&CԽהɴ׫4෗ܚӑ6඄&/Ÿ̃Z&*%ɆϿ&Ĵ&1¨ҴŴ",g,"AAAAKKLLKKKKKJJIHHIHHGGFF");!function setData(e,t){const a=m,n=p;for(let e=0;e=0)return t;e.runningState>=0&&(e.runningState=t);throw new Error("Brotli error code: "+t)}return function decode(e,t){let a=new State;a.input=new InputStream(e);initState(a);if(t){let e=t.customDictionary;e&&function attachDictionaryChunk(e,t){if(1!==e.runningState)return makeError(e,-24);if(0===e.cdNumChunks){e.cdChunks=new Array(16);e.cdChunkOffsets=new Int32Array(16);e.cdBlockBits=-1}if(15===e.cdNumChunks)return makeError(e,-27);e.cdChunks[e.cdNumChunks]=t;e.cdNumChunks++;e.cdTotalSize+=t.length;e.cdChunkOffsets[e.cdNumChunks]=e.cdTotalSize;return 0}(a,e)}let n=0,s=[];for(;;){let e=new Int8Array(16384);s.push(e);a.output=e;a.outputOffset=0;a.outputLength=16384;a.outputUsed=0;decompress(a);n+=a.outputUsed;if(a.outputUsed<16384)break}!function close(e){if(0===e.runningState)return makeError(e,-25);e.runningState>0&&(e.runningState=11);return 0}(a);!function closeInput(e){e.input=new InputStream(new Int8Array(0))}(a);let r=new Int8Array(n),i=0;for(let e=0;e>e;this.codeSize=n-=e;return a}getCode(e){const t=this.stream,a=e[0],n=e[1];let s,r=this.codeSize,i=this.codeBuf;for(;r>16,f=65535&o;if(l<1||r>l;this.codeSize=r-l;return f}generateHuffmanTable(e){const t=e.length;let a,n=0;for(a=0;an&&(n=e[a]);const s=1<>=1}for(a=e;a>=1;if(0===t){let t;if(-1===(t=n.getByte())){this.#K("Bad block header in flate stream");return}let a=t;if(-1===(t=n.getByte())){this.#K("Bad block header in flate stream");return}a|=t<<8;if(-1===(t=n.getByte())){this.#K("Bad block header in flate stream");return}let s=t;if(-1===(t=n.getByte())){this.#K("Bad block header in flate stream");return}s|=t<<8;if(s!==(65535&~a)&&(0!==a||0!==s))throw new FormatError("Bad uncompressed block length in flate stream");this.codeBuf=0;this.codeSize=0;const r=this.bufferLength,i=r+a;e=this.ensureBuffer(i);this.bufferLength=i;if(0===a)-1===n.peekByte()&&(this.eof=!0);else{const t=n.getBytes(a);e.set(t,r);t.length0;)c[o++]=m}s=this.generateHuffmanTable(c.subarray(0,e));r=this.generateHuffmanTable(c.subarray(e,f))}}e=this.buffer;let i=e?e.length:0,o=this.bufferLength;for(;;){let t=this.getCode(s);if(t<256){if(o+1>=i){e=this.ensureBuffer(o+1);i=e.length}e[o++]=t;continue}if(256===t){this.bufferLength=o;return}t-=257;t=Qa[t];let n=t>>16;n>0&&(n=this.getBits(n));a=(65535&t)+n;t=this.getCode(r);t=Za[t];n=t>>16;n>0&&(n=this.getBits(n));const l=(65535&t)+n;if(o+a>=i){e=this.ensureBuffer(o+a);i=e.length}for(let t=0;t>>t&(1<0;if(e<256){u[0]=e;m=1}else{if(!(e>=258)){if(256===e){c=9;i=258;m=0;continue}this.eof=!0;delete this.lzwState;break}if(e=0;t--){u[t]=o[a];a=f[a]}}else u[m++]=u[0]}if(s){f[i]=h;l[i]=l[h]+1;o[i]=u[0];i++;c=i+r&i+r-1?c:0|Math.min(Math.log(i+r)/.6931471805599453+1,12)}h=e;p+=m;if(n15))throw new FormatError(`Unsupported predictor: ${n}`);this.readBlock=2===n?this.readBlockTiff:this.readBlockPng;this.stream=e;this.dict=e.dict;const s=this.colors=a.get("Colors")||1,r=this.bits=a.get("BPC","BitsPerComponent")||8,i=this.columns=a.get("Columns")||1;this.pixBytes=s*r+7>>3;this.rowBytes=i*s*r+7>>3;return this}readBlockTiff(){const e=this.rowBytes,t=this.bufferLength,a=this.ensureBuffer(t+e),n=this.bits,s=this.colors,r=this.stream.getBytes(e);this.eof=!r.length;if(this.eof)return;let i,o=0,l=0,f=0,c=0,h=t;if(1===n&&1===s)for(i=0;i>1;e^=e>>2;e^=e>>4;o=(1&e)<<7;a[h++]=e}else if(8===n){for(i=0;i>8&255;a[h++]=255&e}}else{const e=new Uint8Array(s+1),h=(1<>f-n)&h;f-=n;l=l<=8){a[m++]=l>>c-8&255;c-=8}}c>0&&(a[m++]=(l<<8-c)+(o&(1<<8-c)-1))}this.bufferLength+=e}readBlockPng(){const e=this.rowBytes,t=this.pixBytes,a=this.stream.getByte(),n=this.stream.getBytes(e);this.eof=!n.length;if(this.eof)return;const s=this.bufferLength,r=this.ensureBuffer(s+e);let i=r.subarray(s-e,s);0===i.length&&(i=new Uint8Array(e));let o,l,f,c=s;switch(a){case 0:for(o=0;o>1)+n[o];for(;o>1)+n[o]&255;c++}break;case 4:for(o=0;o0){const e=this.stream.getBytes(n);t.set(e,a);a+=n}}else{n=257-n;t=this.ensureBuffer(a+n+1);t.fill(e[1],a,a+n);a+=n}this.bufferLength=a}}class Parser{constructor({lexer:e,xref:t,allowStreams:a=!1,recoveryMode:n=!1}){this.lexer=e;this.xref=t;this.allowStreams=a;this.recoveryMode=n;this.imageCache=Object.create(null);this._imageId=0;this.refill()}refill(){this.buf1=this.lexer.getObj();this.buf2=this.lexer.getObj()}shift(){if(this.buf2 instanceof Cmd&&"ID"===this.buf2.cmd){this.buf1=this.buf2;this.buf2=null}else{this.buf1=this.buf2;this.buf2=this.lexer.getObj()}}tryShift(){try{this.shift();return!0}catch(e){if(e instanceof MissingDataException)throw e;return!1}}getObj(e=null){const t=this.buf1;this.shift();if(t instanceof Cmd)switch(t.cmd){case"BI":return this.makeInlineImage(e);case"[":const a=[];for(;!isCmd(this.buf1,"]")&&this.buf1!==oa;)a.push(this.getObj(e));if(this.buf1===oa){if(this.recoveryMode)return a;throw new ParserEOFException("End of file inside array.")}this.shift();return a;case"<<":const n=new Dict(this.xref);for(;!isCmd(this.buf1,">>")&&this.buf1!==oa;){if(!(this.buf1 instanceof Name)){info("Malformed dictionary: key must be a name object");this.shift();continue}const t=this.buf1.name;this.shift();if(this.buf1===oa)break;n.set(t,this.getObj(e))}if(this.buf1===oa){if(this.recoveryMode)return n;throw new ParserEOFException("End of file inside dictionary.")}if(isCmd(this.buf2,"stream"))return this.allowStreams?this.makeStream(n,e):n;this.shift();return n;default:return t}if(Number.isInteger(t)){if(Number.isInteger(this.buf1)&&isCmd(this.buf2,"R")){const e=Ref.get(t,this.buf1);this.shift();this.shift();return e}return t}return"string"==typeof t&&e?e.decryptString(t):t}findDefaultInlineStreamEnd(e){const{knownCommands:t}=this.lexer,a=e.pos;let n,s,r=0;for(;-1!==(n=e.getByte());)if(0===r)r=69===n?1:0;else if(1===r)r=73===n?2:0;else if(32===n||10===n||13===n){s=e.pos;const a=e.peekBytes(15),i=a.length;if(0===i)break;for(let e=0;e127))){r=0;break}}if(2!==r)continue;if(!t){warn("findDefaultInlineStreamEnd - `lexer.knownCommands` is undefined.");continue}const o=new Lexer(new Stream(e.peekBytes(75)),t);o._hexStringWarn=()=>{};let l=0;for(;;){const e=o.getObj();if(e===oa){r=0;break}if(e instanceof Cmd){const a=t[e.cmd];if(!a){r=0;break}if(a.variableArgs?l<=a.numArgs:l===a.numArgs)break;l=0;continue}l++}if(2===r)break}else r=0;if(-1===n){warn("findDefaultInlineStreamEnd: Reached the end of the stream without finding a valid EI marker");if(s){warn('... trying to recover by using the last "EI" occurrence.');e.skip(-(e.pos-s))}}let i=4;e.skip(-i);n=e.peekByte();e.skip(i);isWhiteSpace(n)||i--;return e.pos-i-a}findDCTDecodeInlineStreamEnd(e){const t=e.pos;let a,n,s=!1;for(;-1!==(a=e.getByte());)if(255===a){switch(e.getByte()){case 0:break;case 255:e.skip(-1);break;case 217:s=!0;break;case 192:case 193:case 194:case 195:case 197:case 198:case 199:case 201:case 202:case 203:case 205:case 206:case 207:case 196:case 204:case 218:case 219:case 220:case 221:case 222:case 223:case 224:case 225:case 226:case 227:case 228:case 229:case 230:case 231:case 232:case 233:case 234:case 235:case 236:case 237:case 238:case 239:case 254:n=e.getUint16();n>2?e.skip(n-2):e.skip(-2)}if(s)break}const r=e.pos-t;if(-1===a){warn("Inline DCTDecode image stream: EOI marker not found, searching for /EI/ instead.");e.skip(-r);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return r}findASCII85DecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte());)if(126===a){const t=e.pos;a=e.peekByte();for(;isWhiteSpace(a);){e.skip();a=e.peekByte()}if(62===a){e.skip();break}if(e.pos>t){const t=e.peekBytes(2);if(69===t[0]&&73===t[1])break}}const n=e.pos-t;if(-1===a){warn("Inline ASCII85Decode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-n);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return n}findASCIIHexDecodeInlineStreamEnd(e){const t=e.pos;let a;for(;-1!==(a=e.getByte())&&62!==a;);const n=e.pos-t;if(-1===a){warn("Inline ASCIIHexDecode image stream: EOD marker not found, searching for /EI/ instead.");e.skip(-n);return this.findDefaultInlineStreamEnd(e)}this.inlineStreamSkipEI(e);return n}inlineStreamSkipEI(e){let t,a=0;for(;-1!==(t=e.getByte());)if(0===a)a=69===t?1:0;else if(1===a)a=73===t?2:0;else if(2===a)break}makeInlineImage(e){const t=this.lexer,a=t.stream,n=Object.create(null);let s;for(;!isCmd(this.buf1,"ID")&&this.buf1!==oa;){if(!(this.buf1 instanceof Name))throw new FormatError("Dictionary key must be a name object");const t=this.buf1.name;this.shift();if(this.buf1===oa)break;n[t]=this.getObj(e)}-1!==t.beginInlineImagePos&&(s=a.pos-t.beginInlineImagePos);const r=this.xref.fetchIfRef(n.F||n.Filter);let i;if(r instanceof Name)i=r.name;else if(Array.isArray(r)){const e=this.xref.fetchIfRef(r[0]);e instanceof Name&&(i=e.name)}const o=a.pos;let l,f;switch(i){case"DCT":case"DCTDecode":l=this.findDCTDecodeInlineStreamEnd(a);break;case"A85":case"ASCII85Decode":l=this.findASCII85DecodeInlineStreamEnd(a);break;case"AHx":case"ASCIIHexDecode":l=this.findASCIIHexDecodeInlineStreamEnd(a);break;default:l=this.findDefaultInlineStreamEnd(a)}if(l<1e3&&s>0){const e=a.pos;a.pos=t.beginInlineImagePos;f=function getInlineImageCacheKey(e){const t=[],a=e.length;let n=0;for(;n=n){let n=!1;for(const e of s){const t=e.length;let s=0;for(;s=r){n=!0;break}if(s>=t){if(isWhiteSpace(i[l+o+s])){info(`Found "${bytesToString([...a,...e])}" when searching for endstream command.`);n=!0}break}}if(n){t.pos+=l;return t.pos-e}}l++}t.pos+=o}return-1}makeStream(e,t){const a=this.lexer;let n=a.stream;a.skipToNextLine();const s=n.pos-1;let r=e.get("Length");if(!Number.isInteger(r)){info(`Bad length "${r&&r.toString()}" in stream.`);r=0}n.pos=s+r;a.nextChar();if(this.tryShift()&&isCmd(this.buf2,"endstream"))this.shift();else{r=this.#G(s);if(r<0)throw new FormatError("Missing endstream command.");a.nextChar();this.shift();this.shift()}this.shift();n=n.makeSubStream(s,r,e);t&&(n=t.createStream(n,r));n=this.filter(n,e,r);n.dict=e;return n}filter(e,t,a){let n=t.get("F","Filter"),s=t.get("DP","DecodeParms");if(n instanceof Name){Array.isArray(s)&&warn("/DecodeParms should not be an Array, when /Filter is a Name.");return this.makeFilter(e,n.name,a,s)}let r=a;if(Array.isArray(n)){const t=n,a=s;for(let i=0,o=t.length;i=48&&e<=57?15&e:e>=65&&e<=70||e>=97&&e<=102?9+(15&e):-1}class Lexer{constructor(e,t=null){this.stream=e;this.nextChar();this.strBuf=[];this.knownCommands=t;this._hexStringNumWarn=0;this.beginInlineImagePos=-1}nextChar(){return this.currentChar=this.stream.getByte()}peekChar(){return this.stream.peekByte()}getNumber(){let e=this.currentChar,t=0,a=1;if(45===e){a=-1;e=this.nextChar();45===e&&(e=this.nextChar())}else 43===e&&(e=this.nextChar());if(10===e||13===e)do{e=this.nextChar()}while(10===e||13===e);if(46===e){t=10;e=this.nextChar()}if(e<48||e>57){const t=`Invalid number: ${String.fromCharCode(e)} (charCode ${e})`;if(isWhiteSpace(e)||40===e||60===e||-1===e){info(`Lexer.getNumber - "${t}".`);return 0}throw new FormatError(t)}let n=e-48;for(;(e=this.nextChar())>=0;)if(e>=48&&e<=57){0!==t&&(t*=10);n=10*n+(e-48)}else if(46===e){if(0!==t)break;t=1}else{if(45!==e)break;warn("Badly formatted number: minus sign in the middle")}0!==t&&(n/=t);return a*n}getString(){let e=1,t=!1;const a=this.strBuf;a.length=0;let n=this.nextChar();for(;;){let s=!1;switch(0|n){case-1:warn("Unterminated string");t=!0;break;case 40:++e;a.push("(");break;case 41:if(0===--e){this.nextChar();t=!0}else a.push(")");break;case 92:n=this.nextChar();switch(n){case-1:warn("Unterminated string");t=!0;break;case 110:a.push("\n");break;case 114:a.push("\r");break;case 116:a.push("\t");break;case 98:a.push("\b");break;case 102:a.push("\f");break;case 92:case 40:case 41:a.push(String.fromCharCode(n));break;case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:let e=15&n;n=this.nextChar();s=!0;if(n>=48&&n<=55){e=(e<<3)+(15&n);n=this.nextChar();if(n>=48&&n<=55){s=!1;e=(e<<3)+(15&n)}}a.push(String.fromCharCode(e));break;case 13:10===this.peekChar()&&this.nextChar();break;case 10:break;default:a.push(String.fromCharCode(n))}break;default:a.push(String.fromCharCode(n))}if(t)break;s||(n=this.nextChar())}return a.join("")}getName(){let e,t;const a=this.strBuf;a.length=0;for(;(e=this.nextChar())>=0&&!an[e];)if(35===e){e=this.nextChar();if(an[e]){warn("Lexer_getName: NUMBER SIGN (#) should be followed by a hexadecimal number.");a.push("#");break}const n=toHexDigit(e);if(-1!==n){t=e;e=this.nextChar();const s=toHexDigit(e);if(-1===s){warn(`Lexer_getName: Illegal digit (${String.fromCharCode(e)}) in hexadecimal number.`);a.push("#",String.fromCharCode(t));if(an[e])break;a.push(String.fromCharCode(e));continue}a.push(String.fromCharCode(n<<4|s))}else a.push("#",String.fromCharCode(e))}else a.push(String.fromCharCode(e));a.length>127&&warn(`Name token is longer than allowed by the spec: ${a.length}`);return Name.get(a.join(""))}_hexStringWarn(e){5!==this._hexStringNumWarn++?this._hexStringNumWarn>5||warn(`getHexString - ignoring invalid character: ${e}`):warn("getHexString - ignoring additional invalid characters.")}getHexString(){const e=this.strBuf;e.length=0;let t=this.currentChar,a=-1,n=-1;this._hexStringNumWarn=0;for(;;){if(t<0){warn("Unterminated hex string");break}if(62===t){this.nextChar();break}if(1!==an[t]){n=toHexDigit(t);if(-1===n)this._hexStringWarn(t);else if(-1===a)a=n;else{e.push(String.fromCharCode(a<<4|n));a=-1}t=this.nextChar()}else t=this.nextChar()}-1!==a&&e.push(String.fromCharCode(a<<4));return e.join("")}getObj(){let e=!1,t=this.currentChar;for(;;){if(t<0)return oa;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(1!==an[t])break;t=this.nextChar()}switch(0|t){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 43:case 45:case 46:return this.getNumber();case 40:return this.getString();case 47:return this.getName();case 91:this.nextChar();return Cmd.get("[");case 93:this.nextChar();return Cmd.get("]");case 60:t=this.nextChar();if(60===t){this.nextChar();return Cmd.get("<<")}return this.getHexString();case 62:t=this.nextChar();if(62===t){this.nextChar();return Cmd.get(">>")}return Cmd.get(">");case 123:this.nextChar();return Cmd.get("{");case 125:this.nextChar();return Cmd.get("}");case 41:this.nextChar();throw new FormatError(`Illegal character: ${t}`)}let a=String.fromCharCode(t);if(t<32||t>127){const e=this.peekChar();if(e>=32&&e<=127){this.nextChar();return Cmd.get(a)}}const n=this.knownCommands;let s=void 0!==n?.[a];for(;(t=this.nextChar())>=0&&!an[t];){const e=a+String.fromCharCode(t);if(s&&void 0===n[e])break;if(128===a.length)throw new FormatError(`Command token too long: ${a.length}`);a=e;s=void 0!==n?.[a]}if("true"===a)return!0;if("false"===a)return!1;if("null"===a)return null;"BI"===a&&(this.beginInlineImagePos=this.stream.pos);return Cmd.get(a)}skipToNextLine(){let e=this.currentChar;for(;e>=0;){if(13===e){e=this.nextChar();10===e&&this.nextChar();break}if(10===e){this.nextChar();break}e=this.nextChar()}}}class Linearization{static create(e){function getInt(e,t,a=!1){const n=e.get(t);if(Number.isInteger(n)&&(a?n>=0:n>0))return n;throw new Error(`The "${t}" parameter in the linearization dictionary is invalid.`)}const t=new Parser({lexer:new Lexer(e),xref:null}),a=t.getObj(),n=t.getObj(),s=t.getObj(),r=t.getObj();let i,o;if(!(Number.isInteger(a)&&Number.isInteger(n)&&isCmd(s,"obj")&&r instanceof Dict&&"number"==typeof(i=r.get("Linearized"))&&i>0))return null;if((o=getInt(r,"L"))!==e.length)throw new Error('The "L" parameter in the linearization dictionary does not equal the stream length.');return{length:o,hints:function getHints(e){const t=e.get("H");let a;if(Array.isArray(t)&&(2===(a=t.length)||4===a)){for(let e=0;e0))throw new Error(`Hint (${e}) in the linearization dictionary is invalid.`)}return t}throw new Error("Hint array in the linearization dictionary is invalid.")}(r),objectNumberFirst:getInt(r,"O"),endFirst:getInt(r,"E"),numPages:getInt(r,"N"),mainXRefEntriesOffset:getInt(r,"T"),pageFirst:r.has("P")?getInt(r,"P",!0):0}}}const nn=["Adobe-GB1-UCS2","Adobe-CNS1-UCS2","Adobe-Japan1-UCS2","Adobe-Korea1-UCS2","78-EUC-H","78-EUC-V","78-H","78-RKSJ-H","78-RKSJ-V","78-V","78ms-RKSJ-H","78ms-RKSJ-V","83pv-RKSJ-H","90ms-RKSJ-H","90ms-RKSJ-V","90msp-RKSJ-H","90msp-RKSJ-V","90pv-RKSJ-H","90pv-RKSJ-V","Add-H","Add-RKSJ-H","Add-RKSJ-V","Add-V","Adobe-CNS1-0","Adobe-CNS1-1","Adobe-CNS1-2","Adobe-CNS1-3","Adobe-CNS1-4","Adobe-CNS1-5","Adobe-CNS1-6","Adobe-GB1-0","Adobe-GB1-1","Adobe-GB1-2","Adobe-GB1-3","Adobe-GB1-4","Adobe-GB1-5","Adobe-Japan1-0","Adobe-Japan1-1","Adobe-Japan1-2","Adobe-Japan1-3","Adobe-Japan1-4","Adobe-Japan1-5","Adobe-Japan1-6","Adobe-Korea1-0","Adobe-Korea1-1","Adobe-Korea1-2","B5-H","B5-V","B5pc-H","B5pc-V","CNS-EUC-H","CNS-EUC-V","CNS1-H","CNS1-V","CNS2-H","CNS2-V","ETHK-B5-H","ETHK-B5-V","ETen-B5-H","ETen-B5-V","ETenms-B5-H","ETenms-B5-V","EUC-H","EUC-V","Ext-H","Ext-RKSJ-H","Ext-RKSJ-V","Ext-V","GB-EUC-H","GB-EUC-V","GB-H","GB-V","GBK-EUC-H","GBK-EUC-V","GBK2K-H","GBK2K-V","GBKp-EUC-H","GBKp-EUC-V","GBT-EUC-H","GBT-EUC-V","GBT-H","GBT-V","GBTpc-EUC-H","GBTpc-EUC-V","GBpc-EUC-H","GBpc-EUC-V","H","HKdla-B5-H","HKdla-B5-V","HKdlb-B5-H","HKdlb-B5-V","HKgccs-B5-H","HKgccs-B5-V","HKm314-B5-H","HKm314-B5-V","HKm471-B5-H","HKm471-B5-V","HKscs-B5-H","HKscs-B5-V","Hankaku","Hiragana","KSC-EUC-H","KSC-EUC-V","KSC-H","KSC-Johab-H","KSC-Johab-V","KSC-V","KSCms-UHC-H","KSCms-UHC-HW-H","KSCms-UHC-HW-V","KSCms-UHC-V","KSCpc-EUC-H","KSCpc-EUC-V","Katakana","NWP-H","NWP-V","RKSJ-H","RKSJ-V","Roman","UniCNS-UCS2-H","UniCNS-UCS2-V","UniCNS-UTF16-H","UniCNS-UTF16-V","UniCNS-UTF32-H","UniCNS-UTF32-V","UniCNS-UTF8-H","UniCNS-UTF8-V","UniGB-UCS2-H","UniGB-UCS2-V","UniGB-UTF16-H","UniGB-UTF16-V","UniGB-UTF32-H","UniGB-UTF32-V","UniGB-UTF8-H","UniGB-UTF8-V","UniJIS-UCS2-H","UniJIS-UCS2-HW-H","UniJIS-UCS2-HW-V","UniJIS-UCS2-V","UniJIS-UTF16-H","UniJIS-UTF16-V","UniJIS-UTF32-H","UniJIS-UTF32-V","UniJIS-UTF8-H","UniJIS-UTF8-V","UniJIS2004-UTF16-H","UniJIS2004-UTF16-V","UniJIS2004-UTF32-H","UniJIS2004-UTF32-V","UniJIS2004-UTF8-H","UniJIS2004-UTF8-V","UniJISPro-UCS2-HW-V","UniJISPro-UCS2-V","UniJISPro-UTF8-V","UniJISX0213-UTF32-H","UniJISX0213-UTF32-V","UniJISX02132004-UTF32-H","UniJISX02132004-UTF32-V","UniKS-UCS2-H","UniKS-UCS2-V","UniKS-UTF16-H","UniKS-UTF16-V","UniKS-UTF32-H","UniKS-UTF32-V","UniKS-UTF8-H","UniKS-UTF8-V","V","WP-Symbol"],sn=2**24-1;class CMap{constructor(e=!1){this.codespaceRanges=[[],[],[],[]];this.numCodespaceRanges=0;this._map=[];this.name="";this.vertical=!1;this.useCMap=null;this.builtInCMap=e}addCodespaceRange(e,t,a){this.codespaceRanges[e-1].push(t,a);this.numCodespaceRanges++}mapCidRange(e,t,a){if(t-e>sn)throw new Error("mapCidRange - ignoring data above MAX_MAP_RANGE.");for(;e<=t;)this._map[e++]=a++}mapBfRange(e,t,a){if(t-e>sn)throw new Error("mapBfRange - ignoring data above MAX_MAP_RANGE.");const n=a.length-1;for(;e<=t;){this._map[e++]=a;const t=a.charCodeAt(n)+1;t>255?a=a.substring(0,n-1)+String.fromCharCode(a.charCodeAt(n-1)+1)+"\0":a=a.substring(0,n)+String.fromCharCode(t)}}mapBfRangeToArray(e,t,a){if(t-e>sn)throw new Error("mapBfRangeToArray - ignoring data above MAX_MAP_RANGE.");const n=a.length;let s=0;for(;e<=t&&s>>0;const i=s[r];for(let e=0,t=i.length;e=t&&n<=s){a.charcode=n;a.length=r+1;return}}}a.charcode=0;a.length=1}getCharCodeLength(e){const t=this.codespaceRanges;for(let a=0,n=t.length;a=s&&e<=r)return a+1}}return 1}get length(){return this._map.length}get isIdentityCMap(){if("Identity-H"!==this.name&&"Identity-V"!==this.name)return!1;if(65536!==this._map.length)return!1;for(let e=0;e<65536;e++)if(this._map[e]!==e)return!1;return!0}}class IdentityCMap extends CMap{constructor(e,t){super();this.vertical=e;this.addCodespaceRange(t,0,65535)}mapCidRange(e,t,a){unreachable("should not call mapCidRange")}mapBfRange(e,t,a){unreachable("should not call mapBfRange")}mapBfRangeToArray(e,t,a){unreachable("should not call mapBfRangeToArray")}mapOne(e,t){unreachable("should not call mapCidOne")}lookup(e){return Number.isInteger(e)&&e<=65535?e:void 0}contains(e){return Number.isInteger(e)&&e<=65535}forEach(e){for(let t=0;t<=65535;t++)e(t,t)}charCodeOf(e){return Number.isInteger(e)&&e<=65535?e:-1}getMap(){const e=new Array(65536);for(let t=0;t<=65535;t++)e[t]=t;return e}get length(){return 65536}get isIdentityCMap(){unreachable("should not access .isIdentityCMap")}}function strToInt(e){let t=0;for(let a=0;a>>0}function expectString(e){if("string"!=typeof e)throw new FormatError("Malformed CMap: expected string.")}function expectInt(e){if(!Number.isInteger(e))throw new FormatError("Malformed CMap: expected int.")}function parseBfChar(e,t){for(;;){let a=t.getObj();if(a===oa)break;if(isCmd(a,"endbfchar"))return;expectString(a);const n=strToInt(a);a=t.getObj();expectString(a);const s=a;e.mapOne(n,s)}}function parseBfRange(e,t){for(;;){let a=t.getObj();if(a===oa)break;if(isCmd(a,"endbfrange"))return;expectString(a);const n=strToInt(a);a=t.getObj();expectString(a);const s=strToInt(a);a=t.getObj();if(Number.isInteger(a)||"string"==typeof a){const t=Number.isInteger(a)?String.fromCharCode(a):a;e.mapBfRange(n,s,t)}else{if(!isCmd(a,"["))break;{a=t.getObj();const r=[];for(;!isCmd(a,"]")&&a!==oa;){r.push(a);a=t.getObj()}e.mapBfRangeToArray(n,s,r)}}}throw new FormatError("Invalid bf range.")}function parseCidChar(e,t){for(;;){let a=t.getObj();if(a===oa)break;if(isCmd(a,"endcidchar"))return;expectString(a);const n=strToInt(a);a=t.getObj();expectInt(a);const s=a;e.mapOne(n,s)}}function parseCidRange(e,t){for(;;){let a=t.getObj();if(a===oa)break;if(isCmd(a,"endcidrange"))return;expectString(a);const n=strToInt(a);a=t.getObj();expectString(a);const s=strToInt(a);a=t.getObj();expectInt(a);const r=a;e.mapCidRange(n,s,r)}}function parseCodespaceRange(e,t){for(;;){let a=t.getObj();if(a===oa)break;if(isCmd(a,"endcodespacerange"))return;if("string"!=typeof a)break;const n=strToInt(a);a=t.getObj();if("string"!=typeof a)break;const s=strToInt(a);e.addCodespaceRange(a.length,n,s)}throw new FormatError("Invalid codespace range.")}function parseWMode(e,t){const a=t.getObj();Number.isInteger(a)&&(e.vertical=!!a)}function parseCMapName(e,t){const a=t.getObj();a instanceof Name&&(e.name=a.name)}async function parseCMap(e,t,a,n){let s,r;e:for(;;)try{const a=t.getObj();if(a===oa)break;if(a instanceof Name){"WMode"===a.name?parseWMode(e,t):"CMapName"===a.name&&parseCMapName(e,t);s=a}else if(a instanceof Cmd)switch(a.cmd){case"endcmap":break e;case"usecmap":s instanceof Name&&(r=s.name);break;case"begincodespacerange":parseCodespaceRange(e,t);break;case"beginbfchar":parseBfChar(e,t);break;case"begincidchar":parseCidChar(e,t);break;case"beginbfrange":parseBfRange(e,t);break;case"begincidrange":parseCidRange(e,t)}}catch(e){if(e instanceof MissingDataException)throw e;warn("Invalid cMap data: "+e);continue}!n&&r&&(n=r);return n?extendCMap(e,a,n):e}async function extendCMap(e,t,a){e.useCMap=await createBuiltInCMap(a,t);if(0===e.numCodespaceRanges){const t=e.useCMap.codespaceRanges;for(let a=0;aextendCMap(s,t,e));const r=new Lexer(new Stream(a));return parseCMap(s,r,t,null)}class CMapFactory{static async create({encoding:e,fetchBuiltInCMap:t,useCMap:a}){if(e instanceof Name)return createBuiltInCMap(e.name,t);if(e instanceof BaseStream){if(e.isAsync){const t=await e.asyncGetBytes();t&&(e=new Stream(t,0,t.length,e.dict))}const n=await parseCMap(new CMap,new Lexer(e),t,a);return n.isIdentityCMap?createBuiltInCMap(n.name,t):n}throw new Error("Encoding required.")}}class CSS_FONT_INFO{static strings=["fontFamily","fontWeight","italicAngle"]}class SYSTEM_FONT_INFO{static strings=["css","loadedName","baseFontName","src"]}class FONT_INFO{static bools=["black","bold","disableFontFace","fontExtraProperties","isInvalidPDFjsFont","isType3Font","italic","missingFile","remeasure","vertical"];static numbers=["ascent","defaultWidth","descent"];static strings=["fallbackName","loadedName","mimetype","name"];static OFFSET_NUMBERS=Math.ceil(2*this.bools.length/8);static OFFSET_BBOX=this.OFFSET_NUMBERS+8*this.numbers.length;static OFFSET_FONT_MATRIX=this.OFFSET_BBOX+1+8;static OFFSET_DEFAULT_VMETRICS=this.OFFSET_FONT_MATRIX+1+48;static OFFSET_STRINGS=this.OFFSET_DEFAULT_VMETRICS+1+6}class PATTERN_INFO{static KIND=0;static HAS_BBOX=1;static HAS_BACKGROUND=2;static SHADING_TYPE=3;static N_COORD=4;static N_COLOR=8;static N_STOP=12;static N_FIGURES=16}function compileFontInfo(e){const t=e.systemFontInfo?function compileSystemFontInfo(e){const t=new TextEncoder,a={};let n=0;for(const s of SYSTEM_FONT_INFO.strings){const r=t.encode(e[s]);a[s]=r;n+=4+r.length}n+=4;let s,r,i=1+n;if(e.style){s=t.encode(e.style.style);r=t.encode(e.style.weight);i+=4+s.length+4+r.length}const o=new ArrayBuffer(i),l=new Uint8Array(o),f=new DataView(o);let c=0;f.setUint8(c++,e.guessFallback?1:0);f.setUint32(c,0);c+=4;n=0;for(const e of SYSTEM_FONT_INFO.strings){const t=a[e],s=t.length;n+=4+s;f.setUint32(c,s);l.set(t,c+4);c+=4+s}f.setUint32(c-n-4,n);if(e.style){f.setUint32(c,s.length);l.set(s,c+4);c+=4+s.length;f.setUint32(c,r.length);l.set(r,c+4);c+=4+r.length}assert(c<=o.byteLength,"compileSystemFontInfo: Buffer overflow");return o.transferToFixedLength(c)}(e.systemFontInfo):null,a=e.cssFontInfo?function compileCssFontInfo(e){const t=new TextEncoder,a={};let n=0;for(const s of CSS_FONT_INFO.strings){const r=t.encode(e[s]);a[s]=r;n+=4+r.length}const s=new ArrayBuffer(n),r=new Uint8Array(s),i=new DataView(s);let o=0;for(const e of CSS_FONT_INFO.strings){const t=a[e],n=t.length;i.setUint32(o,n);r.set(t,o+4);o+=4+n}assert(o===s.byteLength,"compileCssFontInfo: Buffer overflow");return s}(e.cssFontInfo):null,n=new TextEncoder,s={};let r=0;for(const t of FONT_INFO.strings){s[t]=n.encode(e[t]);r+=4+s[t].length}const i=FONT_INFO.OFFSET_STRINGS+4+r+4+(t?.byteLength??0)+4+(a?.byteLength??0)+4+(e.data?.length??0),o=new ArrayBuffer(i),l=new Uint8Array(o),f=new DataView(o);let c=0;const h=FONT_INFO.bools.length;let u=0,m=0;for(let t=0;t=5&&t<=7))return-1;n=e.substring(1)}if(n===n.toUpperCase()){a=parseInt(n,16);if(a>=0)return a}}return-1}const gn=[[0,127],[128,255],[256,383],[384,591],[592,687,7424,7551,7552,7615],[688,767,42752,42783],[768,879,7616,7679],[880,1023],[11392,11519],[1024,1279,1280,1327,11744,11775,42560,42655],[1328,1423],[1424,1535],[42240,42559],[1536,1791,1872,1919],[1984,2047],[2304,2431],[2432,2559],[2560,2687],[2688,2815],[2816,2943],[2944,3071],[3072,3199],[3200,3327],[3328,3455],[3584,3711],[3712,3839],[4256,4351,11520,11567],[6912,7039],[4352,4607],[7680,7935,11360,11391,42784,43007],[7936,8191],[8192,8303,11776,11903],[8304,8351],[8352,8399],[8400,8447],[8448,8527],[8528,8591],[8592,8703,10224,10239,10496,10623,11008,11263],[8704,8959,10752,11007,10176,10223,10624,10751],[8960,9215],[9216,9279],[9280,9311],[9312,9471],[9472,9599],[9600,9631],[9632,9727],[9728,9983],[9984,10175],[12288,12351],[12352,12447],[12448,12543,12784,12799],[12544,12591,12704,12735],[12592,12687],[43072,43135],[12800,13055],[13056,13311],[44032,55215],[55296,57343],[67840,67871],[19968,40959,11904,12031,12032,12255,12272,12287,13312,19903,131072,173791,12688,12703],[57344,63743],[12736,12783,63744,64255,194560,195103],[64256,64335],[64336,65023],[65056,65071],[65040,65055],[65104,65135],[65136,65279],[65280,65519],[65520,65535],[3840,4095],[1792,1871],[1920,1983],[3456,3583],[4096,4255],[4608,4991,4992,5023,11648,11743],[5024,5119],[5120,5759],[5760,5791],[5792,5887],[6016,6143],[6144,6319],[10240,10495],[40960,42127],[5888,5919,5920,5951,5952,5983,5984,6015],[66304,66351],[66352,66383],[66560,66639],[118784,119039,119040,119295,119296,119375],[119808,120831],[1044480,1048573],[65024,65039,917760,917999],[917504,917631],[6400,6479],[6480,6527],[6528,6623],[6656,6687],[11264,11359],[11568,11647],[19904,19967],[43008,43055],[65536,65663,65664,65791,65792,65855],[65856,65935],[66432,66463],[66464,66527],[66640,66687],[66688,66735],[67584,67647],[68096,68191],[119552,119647],[73728,74751,74752,74879],[119648,119679],[7040,7103],[7168,7247],[7248,7295],[43136,43231],[43264,43311],[43312,43359],[43520,43615],[65936,65999],[66e3,66047],[66208,66271,66176,66207,67872,67903],[127024,127135,126976,127023]];function getUnicodeRangeFor(e,t=-1){if(-1!==t){const a=gn[t];for(let n=0,s=a.length;n=a[n]&&e<=a[n+1])return t}for(let t=0,a=gn.length;t=a[n]&&e<=a[n+1])return t}return-1}const bn=new RegExp("^(\\s)|(\\p{Mn})|(\\p{Cf})$","u"),wn=new Map;const jn=!0,kn=1,yn=2,qn=4,vn=32,Sn=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];function recoverGlyphName(e,t){if(void 0!==t[e])return e;const a=getUnicodeForGlyph(e,t);if(-1!==a)for(const e in t)if(t[e]===a)return e;info("Unable to recover a standard glyph name for: "+e);return e}function type1FontGlyphMapping(e,t,a){const n=Object.create(null);let s,r,i;const o=!!(e.flags&qn);if(e.isInternalFont){i=t;for(r=0;r=0?s:0}}else if(e.baseEncodingName){i=getEncoding(e.baseEncodingName);for(r=0;r=0?s:0}}else if(o)for(r in t)n[r]=t[r];else{i=fn;for(r=0;r=0?s:0}}const l=e.differences;let f;if(l)for(r in l){const e=l[r];s=a.indexOf(e);if(-1===s){f||(f=mn());const t=recoverGlyphName(e,f);t!==e&&(s=a.indexOf(t))}n[r]=s>=0?s:0}return n}function normalizeFontName(e){return e.replaceAll(/[,_]/g,"-").replaceAll(/\s/g,"")}const An=getLookupTableFactory(e=>{e[8211]=65074;e[8212]=65073;e[8229]=65072;e[8230]=65049;e[12289]=65041;e[12290]=65042;e[12296]=65087;e[12297]=65088;e[12298]=65085;e[12299]=65086;e[12300]=65089;e[12301]=65090;e[12302]=65091;e[12303]=65092;e[12304]=65083;e[12305]=65084;e[12308]=65081;e[12309]=65082;e[12310]=65047;e[12311]=65048;e[65103]=65076;e[65281]=65045;e[65288]=65077;e[65289]=65078;e[65292]=65040;e[65306]=65043;e[65307]=65044;e[65311]=65046;e[65339]=65095;e[65341]=65096;e[65343]=65075;e[65371]=65079;e[65373]=65080});const xn=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron"],Cn=[".notdef","space","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"],In=[".notdef","space","dollaroldstyle","dollarsuperior","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","fi","fl","ffi","ffl","parenleftinferior","parenrightinferior","hyphensuperior","colonmonetary","onefitted","rupiah","centoldstyle","figuredash","hypheninferior","onequarter","onehalf","threequarters","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior"],Fn=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"],Tn=391,On=[null,{id:"hstem",min:2,stackClearing:!0,stem:!0},null,{id:"vstem",min:2,stackClearing:!0,stem:!0},{id:"vmoveto",min:1,stackClearing:!0},{id:"rlineto",min:2,resetStack:!0},{id:"hlineto",min:1,resetStack:!0},{id:"vlineto",min:1,resetStack:!0},{id:"rrcurveto",min:6,resetStack:!0},null,{id:"callsubr",min:1},{id:"return",min:0},null,null,{id:"endchar",min:0,stackClearing:!0},null,null,null,{id:"hstemhm",min:2,stackClearing:!0,stem:!0},{id:"hintmask",min:0,stackClearing:!0},{id:"cntrmask",min:0,stackClearing:!0},{id:"rmoveto",min:2,stackClearing:!0},{id:"hmoveto",min:1,stackClearing:!0},{id:"vstemhm",min:2,stackClearing:!0,stem:!0},{id:"rcurveline",min:8,resetStack:!0},{id:"rlinecurve",min:8,resetStack:!0},{id:"vvcurveto",min:4,resetStack:!0},{id:"hhcurveto",min:4,resetStack:!0},null,{id:"callgsubr",min:1},{id:"vhcurveto",min:4,resetStack:!0},{id:"hvcurveto",min:4,resetStack:!0}],Rn=[null,null,null,{id:"and",min:2,stackDelta:-1},{id:"or",min:2,stackDelta:-1},{id:"not",min:1,stackDelta:0},null,null,null,{id:"abs",min:1,stackDelta:0},{id:"add",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]+e[t-1]}},{id:"sub",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]-e[t-1]}},{id:"div",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]/e[t-1]}},null,{id:"neg",min:1,stackDelta:0,stackFn(e,t){e[t-1]=-e[t-1]}},{id:"eq",min:2,stackDelta:-1},null,null,{id:"drop",min:1,stackDelta:-1},null,{id:"put",min:2,stackDelta:-2},{id:"get",min:1,stackDelta:0},{id:"ifelse",min:4,stackDelta:-3},{id:"random",min:0,stackDelta:1},{id:"mul",min:2,stackDelta:-1,stackFn(e,t){e[t-2]=e[t-2]*e[t-1]}},null,{id:"sqrt",min:1,stackDelta:0},{id:"dup",min:1,stackDelta:1},{id:"exch",min:2,stackDelta:0},{id:"index",min:2,stackDelta:0},{id:"roll",min:3,stackDelta:-2},null,null,null,{id:"hflex",min:7,resetStack:!0},{id:"flex",min:13,resetStack:!0},{id:"hflex1",min:9,resetStack:!0},{id:"flex1",min:11,resetStack:!0}];class CFFParser{constructor(e,t,a){this.bytes=e.getBytes();this.properties=t;this.seacAnalysisEnabled=!!a}parse(){const e=this.properties,t=new CFF(this.bytes.length);this.cff=t;const a=this.parseHeader(),n=this.parseIndex(a.endPos),s=this.parseIndex(n.endPos),r=this.parseIndex(s.endPos),i=this.parseIndex(r.endPos),o=this.parseDict(s.obj.get(0)),l=this.createDict(CFFTopDict,o,t.strings);t.header=a.obj;t.names=this.parseNameIndex(n.obj);t.strings=this.parseStringIndex(r.obj);t.topDict=l;t.globalSubrIndex=i.obj;this.parsePrivateDict(t.topDict);t.isCIDFont=l.hasName("ROS");const f=l.getByName("CharStrings"),c=this.parseIndex(f).obj;t.charStringCount=c.count;const h=l.getByName("FontMatrix");h&&(e.fontMatrix=h);const u=l.getByName("FontBBox");if(u){e.ascent=Math.max(u[3],u[1]);e.descent=Math.min(u[1],u[3]);e.ascentScaled=!0}let m,p;if(t.isCIDFont){const e=this.parseIndex(l.getByName("FDArray")).obj;for(let a=0,n=e.count;a=t)throw new FormatError("Invalid CFF header");if(0!==a){info("cff data is shifted");e=e.subarray(a);this.bytes=e}const n=e[0],s=e[1],r=e[2],i=e[3];return{obj:new CFFHeader(n,s,r,i),endPos:r}}parseDict(e){const t=new DataView(e.buffer,e.byteOffset,e.bytesLength);let a=0;function parseOperand(){let n=e[a++];if(30===n)return function parseFloatOperand(){let t="";const n=15,s=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"],r=e.length;for(;a>4,o=15&r;if(i===n)break;t+=s[i];if(o===n)break;t+=s[o]}return parseFloat(t)}();if(28===n){n=t.getInt16(a);a+=2;return n}if(29===n){n=t.getInt32(a);a+=4;return n}if(n>=32&&n<=246)return n-139;if(n>=247&&n<=250)return 256*(n-247)+e[a++]+108;if(n>=251&&n<=254)return-256*(n-251)-e[a++]-108;warn(`CFFParser.parseDict: "${n}" is a reserved command.`);return NaN}let n=[];const s=[];a=0;const r=e.length;for(;a10)return!1;const s=new DataView(t.buffer,t.byteOffset,t.bytesLength);let r=e.stackSize;const i=e.stack;let o=t.length;for(let l=0;l=4){r-=4;if(this.seacAnalysisEnabled){e.seac=i.slice(r,r+4);return!1}}c=On[f]}else if(f>=32&&f<=246){i[r]=f-139;r++}else if(f>=247&&f<=254){i[r]=f<251?(f-247<<8)+t[l]+108:-(f-251<<8)-t[l]-108;l++;r++}else if(255===f){i[r]=s.getInt32(l)/65536;l+=4;r++}else if(19===f||20===f){e.hints+=r>>1;if(0===e.hints){t.copyWithin(l-1,l,-1);l-=1;o-=1;continue}l+=e.hints+7>>3;r%=2;c=On[f]}else{if(10===f||29===f){const t=10===f?a:n;if(!t){c=On[f];warn("Missing subrsIndex for "+c.id);return!1}let s=32768;t.count<1240?s=107:t.count<33900&&(s=1131);const o=i[--r]+s;if(o<0||o>=t.count||isNaN(o)){c=On[f];warn("Out of bounds subrIndex for "+c.id);return!1}e.stackSize=r;e.callDepth++;if(!this.parseCharString(e,t.get(o),a,n))return!1;e.callDepth--;r=e.stackSize;continue}if(11===f){e.stackSize=r;return!0}if(0===f&&l===t.length){t[l-1]=14;c=On[14]}else{if(9===f){t.copyWithin(l-1,l,-1);l-=1;o-=1;continue}c=On[f]}}if(c){if(c.stem){e.hints+=r>>1;if(3===f||23===f)e.hasVStems=!0;else if(e.hasVStems&&(1===f||18===f)){warn("CFF stem hints are in wrong order");t[l-1]=1===f?3:23}}if(r=2&&c.stem?r%=2:r>1&&warn("Found too many parameters for stack-clearing command");r>0&&(e.width=i[r-1])}if("stackDelta"in c){"stackFn"in c&&c.stackFn(i,r);r+=c.stackDelta}else(c.stackClearing||c.resetStack)&&(r=0)}}o=s.length){warn("Invalid fd index for glyph index.");h=!1}if(h){m=s[e].privateDict;u=m.subrsIndex}}else t&&(u=t);h&&(h=this.parseCharString(c,l,u,a));if(null!==c.width){const e=m.getByName("nominalWidthX");o[f]=e+c.width}else{const e=m.getByName("defaultWidthX");o[f]=e}null!==c.seac&&(i[f]=c.seac);h||e.set(f,new Uint8Array([14]))}return{charStrings:e,seacs:i,widths:o}}emptyPrivateDictionary(e){const t=this.createDict(CFFPrivateDict,[],e.strings);e.setByKey(18,[0,0]);e.privateDict=t}parsePrivateDict(e){if(!e.hasName("Private")){this.emptyPrivateDictionary(e);return}const t=e.getByName("Private");if(!Array.isArray(t)||2!==t.length){e.removeByName("Private");return}const a=t[0],n=t[1];if(0===a||n>=this.bytes.length){this.emptyPrivateDictionary(e);return}const s=n+a,r=this.bytes.subarray(n,s),i=this.parseDict(r),o=this.createDict(CFFPrivateDict,i,e.strings);e.privateDict=o;0===o.getByName("ExpansionFactor")&&o.setByName("ExpansionFactor",.06);if(!o.getByName("Subrs"))return;const l=o.getByName("Subrs"),f=n+l;if(0===l||f>=this.bytes.length){this.emptyPrivateDictionary(e);return}const c=this.parseIndex(f);o.subrsIndex=c.obj}parseCharsets(e,t,a,n){if(0===e)return new CFFCharset(!0,Dn.ISO_ADOBE,xn);if(1===e)return new CFFCharset(!0,Dn.EXPERT,Cn);if(2===e)return new CFFCharset(!0,Dn.EXPERT_SUBSET,In);const s=this.bytes,r=e,i=s[e++],o=[n?0:".notdef"];let l,f,c;t-=1;switch(i){case 0:for(c=0;c=65535){warn("Not enough space in charstrings to duplicate first glyph.");return}const e=this.charStrings.get(0);this.charStrings.add(e);this.isCIDFont&&this.fdSelect.fdSelect.push(this.fdSelect.fdSelect[0])}hasGlyphId(e){if(e<0||e>=this.charStrings.count)return!1;return this.charStrings.get(e).length>0}}class CFFHeader{constructor(e,t,a,n){this.major=e;this.minor=t;this.hdrSize=a;this.offSize=n}}class CFFStrings{strings=[];get(e){return e>=0&&e<=390?Fn[e]:e-Tn<=this.strings.length?this.strings[e-Tn]:Fn[0]}getSID(e){let t=Fn.indexOf(e);if(-1!==t)return t;t=this.strings.indexOf(e);return-1!==t?t+Tn:-1}add(e){this.strings.push(e)}get count(){return this.strings.length}}class CFFIndex{objects=[];length=0;add(e){this.length+=e.length;this.objects.push(e)}set(e,t){this.length+=t.length-this.objects[e].length;this.objects[e]=t}get(e){return this.objects[e]}get count(){return this.objects.length}}class CFFDict{constructor(e,t){this.keyToNameMap=e.keyToNameMap;this.nameToKeyMap=e.nameToKeyMap;this.defaults=e.defaults;this.types=e.types;this.opcodes=e.opcodes;this.order=e.order;this.strings=t;this.values=Object.create(null)}setByKey(e,t){if(!(e in this.keyToNameMap))return!1;if(0===t.length)return!0;for(const a of t)if(isNaN(a)){warn(`Invalid CFFDict value: "${t}" for key "${e}".`);return!0}const a=this.types[e];"num"!==a&&"sid"!==a&&"offset"!==a||(t=t[0]);this.values[e]=t;return!0}setByName(e,t){if(!(e in this.nameToKeyMap))throw new FormatError(`Invalid dictionary name "${e}"`);this.values[this.nameToKeyMap[e]]=t}hasName(e){return this.nameToKeyMap[e]in this.values}getByName(e){if(!(e in this.nameToKeyMap))throw new FormatError(`Invalid dictionary name ${e}"`);const t=this.nameToKeyMap[e];return t in this.values?this.values[t]:this.defaults[t]}removeByName(e){delete this.values[this.nameToKeyMap[e]]}static createTables(e){const t={keyToNameMap:{},nameToKeyMap:{},defaults:{},types:{},opcodes:{},order:[]};for(const a of e){const e=Array.isArray(a[0])?(a[0][0]<<8)+a[0][1]:a[0];t.keyToNameMap[e]=a[1];t.nameToKeyMap[a[1]]=e;t.types[e]=a[2];t.defaults[e]=a[3];t.opcodes[e]=Array.isArray(a[0])?a[0]:[a[0]];t.order.push(e)}return t}}const Hn=[[[12,30],"ROS",["sid","sid","num"],null],[[12,20],"SyntheticBase","num",null],[0,"version","sid",null],[1,"Notice","sid",null],[[12,0],"Copyright","sid",null],[2,"FullName","sid",null],[3,"FamilyName","sid",null],[4,"Weight","sid",null],[[12,1],"isFixedPitch","num",0],[[12,2],"ItalicAngle","num",0],[[12,3],"UnderlinePosition","num",-100],[[12,4],"UnderlineThickness","num",50],[[12,5],"PaintType","num",0],[[12,6],"CharstringType","num",2],[[12,7],"FontMatrix",["num","num","num","num","num","num"],[.001,0,0,.001,0,0]],[13,"UniqueID","num",null],[5,"FontBBox",["num","num","num","num"],[0,0,0,0]],[[12,8],"StrokeWidth","num",0],[14,"XUID","array",null],[15,"charset","offset",0],[16,"Encoding","offset",0],[17,"CharStrings","offset",0],[18,"Private",["offset","offset"],null],[[12,21],"PostScript","sid",null],[[12,22],"BaseFontName","sid",null],[[12,23],"BaseFontBlend","delta",null],[[12,31],"CIDFontVersion","num",0],[[12,32],"CIDFontRevision","num",0],[[12,33],"CIDFontType","num",0],[[12,34],"CIDCount","num",8720],[[12,35],"UIDBase","num",null],[[12,37],"FDSelect","offset",null],[[12,36],"FDArray","offset",null],[[12,38],"FontName","sid",null]];class CFFTopDict extends CFFDict{static get tables(){return shadow(this,"tables",this.createTables(Hn))}constructor(e){super(CFFTopDict.tables,e);this.privateDict=null}}const Bn=[[6,"BlueValues","delta",null],[7,"OtherBlues","delta",null],[8,"FamilyBlues","delta",null],[9,"FamilyOtherBlues","delta",null],[[12,9],"BlueScale","num",.039625],[[12,10],"BlueShift","num",7],[[12,11],"BlueFuzz","num",1],[10,"StdHW","num",null],[11,"StdVW","num",null],[[12,12],"StemSnapH","delta",null],[[12,13],"StemSnapV","delta",null],[[12,14],"ForceBold","num",0],[[12,17],"LanguageGroup","num",0],[[12,18],"ExpansionFactor","num",.06],[[12,19],"initialRandomSeed","num",0],[20,"defaultWidthX","num",0],[21,"nominalWidthX","num",0],[19,"Subrs","offset",null]];class CFFPrivateDict extends CFFDict{static get tables(){return shadow(this,"tables",this.createTables(Bn))}constructor(e){super(CFFPrivateDict.tables,e);this.subrsIndex=null}}const Dn={ISO_ADOBE:0,EXPERT:1,EXPERT_SUBSET:2};class CFFCharset{constructor(e,t,a,n){this.predefined=e;this.format=t;this.charset=a;this.raw=n}}class CFFEncoding{constructor(e,t,a,n){this.predefined=e;this.format=t;this.encoding=a;this.raw=n}}class CFFFDSelect{constructor(e,t){this.format=e;this.fdSelect=t}getFDIndex(e){return e<0||e>=this.fdSelect.length?-1:this.fdSelect[e]}}class CFFOffsetTracker{offsets=Object.create(null);isTracking(e){return e in this.offsets}track(e,t){if(e in this.offsets)throw new FormatError(`Already tracking location of ${e}`);this.offsets[e]=t}offset(e){for(const t in this.offsets)this.offsets[t]+=e}setEntryLocation(e,t,a){if(!(e in this.offsets))throw new FormatError(`Not tracking location of ${e}`);const n=a.data,s=this.offsets[e];for(let e=0,a=t.length;e>24&255;n[i]=f>>16&255;n[o]=f>>8&255;n[l]=255&f}}}class CompilerOutput{#V;#$=1024;#Y=0;constructor(e){this.#J(e)}#J(e){for(;this.#$this.#$&&this.#J(t);this.#V.set(e,this.#Y);this.#Y=t}}class CFFCompiler{constructor(e){this.cff=e}compile(){const e=this.cff,t=new CompilerOutput(e.rawFileLength),a=this.compileHeader(e.header);t.add(a);const n=this.compileNameIndex(e.names);t.add(n);if(e.isCIDFont&&e.topDict.hasName("FontMatrix")){const t=e.topDict.getByName("FontMatrix");e.topDict.removeByName("FontMatrix");for(const a of e.fdArray){let e=t.slice(0);a.hasName("FontMatrix")&&(e=Util.transform(e,a.getByName("FontMatrix")));a.setByName("FontMatrix",e)}}const s=e.topDict.getByName("XUID");s?.length>16&&e.topDict.removeByName("XUID");e.topDict.setByName("charset",0);let r=this.compileTopDicts([e.topDict],t.length,e.isCIDFont);t.add(r.output);const i=r.trackers[0],o=this.compileStringIndex(e.strings.strings);t.add(o);const l=this.compileIndex(e.globalSubrIndex);t.add(l);if(e.encoding&&e.topDict.hasName("Encoding"))if(e.encoding.predefined)i.setEntryLocation("Encoding",[e.encoding.format],t);else{const a=this.compileEncoding(e.encoding);i.setEntryLocation("Encoding",[t.length],t);t.add(a)}const f=this.compileCharset(e.charset,e.charStrings.count,e.strings,e.isCIDFont);i.setEntryLocation("charset",[t.length],t);t.add(f);const c=this.compileCharStrings(e.charStrings);i.setEntryLocation("CharStrings",[t.length],t);t.add(c);if(e.isCIDFont){i.setEntryLocation("FDSelect",[t.length],t);const a=this.compileFDSelect(e.fdSelect);t.add(a);r=this.compileTopDicts(e.fdArray,t.length,!0);i.setEntryLocation("FDArray",[t.length],t);t.add(r.output);const n=r.trackers;this.compilePrivateDicts(e.fdArray,n,t)}this.compilePrivateDicts([e.topDict],[i],t);t.add([0]);return t.finalData}encodeNumber(e){return Number.isInteger(e)?this.encodeInteger(e):this.encodeFloat(e)}static get EncodeFloatRegExp(){return shadow(this,"EncodeFloatRegExp",/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/)}encodeFloat(e){let t=e.toString();const a=CFFCompiler.EncodeFloatRegExp.exec(t);if(a){const n=parseFloat("1e"+((a[2]?+a[2]:0)+a[1].length));t=(Math.round(e*n)/n).toString()}let n,s,r="";for(n=0,s=t.length;n=-107&&e<=107?[e+139]:e>=108&&e<=1131?[247+((e-=108)>>8),255&e]:e>=-1131&&e<=-108?[251+((e=-e-108)>>8),255&e]:e>=-32768&&e<=32767?[28,e>>8&255,255&e]:[29,e>>24&255,e>>16&255,e>>8&255,255&e];return t}compileHeader(e){return[e.major,e.minor,4,e.offSize]}compileNameIndex(e){const t=new CFFIndex;for(const a of e){const e=Math.min(a.length,127);let n=new Array(e);for(let t=0;t"~"||"["===e||"]"===e||"("===e||")"===e||"{"===e||"}"===e||"<"===e||">"===e||"/"===e||"%"===e)&&(e="_");n[t]=e}n=n.join("");""===n&&(n="Bad_Font_Name");t.add(stringToBytes(n))}return this.compileIndex(t)}compileTopDicts(e,t,a){const n=[];let s=new CFFIndex;for(const r of e){if(a){r.removeByName("CIDFontVersion");r.removeByName("CIDFontRevision");r.removeByName("CIDFontType");r.removeByName("CIDCount");r.removeByName("UIDBase")}const e=new CFFOffsetTracker,i=this.compileDict(r,e);n.push(e);s.add(i);e.offset(t)}s=this.compileIndex(s,n);return{trackers:n,output:s}}compilePrivateDicts(e,t,a){for(let n=0,s=e.length;n>8&255,255&e])}else{s=new Uint8Array(1+2*r);let t=0;const n=e.charset.length;let i=!1;for(let r=1;r>8&255;s[r+1]=255&o}}return s}compileEncoding(e){return e.raw}compileFDSelect(e){const t=e.format;let a,n;switch(t){case 0:a=new Uint8Array(1+e.fdSelect.length);a[0]=t;for(n=0;n>8&255,255&s,r];for(n=1;n>8&255,255&n,t);r=t}}const o=(i.length-3)/3;i[1]=o>>8&255;i[2]=255&o;i.push(n>>8&255,255&n);a=new Uint8Array(i)}return a}compileIndex(e,t=[]){const a=e.objects,n=a.length;if(0===n)return new Uint8Array(2);let s,r,i=1;for(s=0;s>8&255;o[l++]=255&n;o[l++]=r;let f=1;for(s=0;s>8&255;o[l++]=255&f}else if(3===r){o[l++]=f>>16&255;o[l++]=f>>8&255;o[l++]=255&f}else{o[l++]=f>>>24&255;o[l++]=f>>16&255;o[l++]=f>>8&255;o[l++]=255&f}a[s]&&(f+=a[s].length)}for(s=0;s=this.firstChar&&e<=this.lastChar?e:-1}amend(e){unreachable("Should not call amend()")}}class CFFFont{constructor(e,t){this.properties=t;const a=new CFFParser(e,t,jn);this.cff=a.parse();this.cff.duplicateFirstGlyph();const n=new CFFCompiler(this.cff);this.seacs=this.cff.seacs;try{this.data=n.compile()}catch{warn("Failed to compile font "+t.loadedName);this.data=e}this._createBuiltInEncoding()}get numGlyphs(){return this.cff.charStrings.count}getCharset(){return this.cff.charset.charset}getGlyphMapping(){const e=this.cff,t=this.properties,{cidToGidMap:a,cMap:n}=t,s=e.charset.charset;let r,i;if(t.composite){let t,o;if(a?.length>0){t=Object.create(null);for(let e=0,n=a.length;e=0){const n=a[t];n&&(s[e]=n)}}s.length>0&&(this.properties.builtInEncoding=s)}}function getFloat214(e,t){return e.getInt16(t)/16384}function getSubroutineBias(e){const t=e.length;let a=32768;t<1240?a=107:t<33900&&(a=1131);return a}function parseCmap(e,t,a){const n=new DataView(e.buffer,e.byteOffset,e.byteLength),s=1===n.getUint16(t+2)?n.getUint32(t+8):n.getUint32(t+16),r=n.getUint16(t+s);let i,o,l;if(4===r){const e=n.getUint16(t+s+6)>>1;o=t+s+14;i=[];for(l=0;l>1;a0;)h.push({flags:o})}for(a=0;a>1;j=!0;break;case 4:i+=s.pop();moveTo(r,i);j=!0;break;case 5:for(;s.length>0;){r+=s.shift();i+=s.shift();lineTo(r,i)}break;case 6:for(;s.length>0;){r+=s.shift();lineTo(r,i);if(0===s.length)break;i+=s.shift();lineTo(r,i)}break;case 7:for(;s.length>0;){i+=s.shift();lineTo(r,i);if(0===s.length)break;r+=s.shift();lineTo(r,i)}break;case 8:for(;s.length>0;){c=r+s.shift();u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m+s.shift();bezierCurveTo(c,u,h,m,r,i)}break;case 10:b=s.pop();w=null;if(a.isCFFCIDFont){const e=a.fdSelect.getFDIndex(n);if(e>=0&&eMath.abs(i-t)?r+=s.shift():i+=s.shift();bezierCurveTo(c,u,h,m,r,i);break;default:throw new FormatError(`unknown operator: 12 ${k}`)}break;case 14:if(s.length>=4){const e=s.pop(),n=s.pop();i=s.pop();r=s.pop();t.save();t.translate(r,i);let o=lookupCmap(a.cmap,String.fromCharCode(a.glyphNameMap[fn[e]]));compileCharString(a.glyphs[o.glyphId],t,a,o.glyphId);t.restore();o=lookupCmap(a.cmap,String.fromCharCode(a.glyphNameMap[fn[n]]));compileCharString(a.glyphs[o.glyphId],t,a,o.glyphId)}return;case 19:case 20:o+=s.length>>1;f+=o+7>>3;j=!0;break;case 21:i+=s.pop();r+=s.pop();moveTo(r,i);j=!0;break;case 22:r+=s.pop();moveTo(r,i);j=!0;break;case 24:for(;s.length>2;){c=r+s.shift();u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m+s.shift();bezierCurveTo(c,u,h,m,r,i)}r+=s.shift();i+=s.shift();lineTo(r,i);break;case 25:for(;s.length>6;){r+=s.shift();i+=s.shift();lineTo(r,i)}c=r+s.shift();u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m+s.shift();bezierCurveTo(c,u,h,m,r,i);break;case 26:s.length%2&&(r+=s.shift());for(;s.length>0;){c=r;u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h;i=m+s.shift();bezierCurveTo(c,u,h,m,r,i)}break;case 27:s.length%2&&(i+=s.shift());for(;s.length>0;){c=r+s.shift();u=i;h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m;bezierCurveTo(c,u,h,m,r,i)}break;case 28:s.push(l.getInt16(f));f+=2;break;case 29:b=s.pop()+a.gsubrsBias;w=a.gsubrs[b];w&&parse(w);break;case 30:for(;s.length>0;){c=r;u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m+(1===s.length?s.shift():0);bezierCurveTo(c,u,h,m,r,i);if(0===s.length)break;c=r+s.shift();u=i;h=c+s.shift();m=u+s.shift();i=m+s.shift();r=h+(1===s.length?s.shift():0);bezierCurveTo(c,u,h,m,r,i)}break;case 31:for(;s.length>0;){c=r+s.shift();u=i;h=c+s.shift();m=u+s.shift();i=m+s.shift();r=h+(1===s.length?s.shift():0);bezierCurveTo(c,u,h,m,r,i);if(0===s.length)break;c=r;u=i+s.shift();h=c+s.shift();m=u+s.shift();r=h+s.shift();i=m+(1===s.length?s.shift():0);bezierCurveTo(c,u,h,m,r,i)}break;default:if(k<32)throw new FormatError(`unknown operator: ${k}`);if(k<247)s.push(k-139);else if(k<251)s.push(256*(k-247)+e[f++]+108);else if(k<255)s.push(256*-(k-251)-e[f++]-108);else{s.push(l.getInt32(f)/65536);f+=4}}j&&(s.length=0)}}(e)}class Commands{cmds=[];transformStack=[];currentTransform=[1,0,0,1,0,0];add(e,t){if(t){const{currentTransform:a}=this;for(let e=0,n=t.length;e=0&&ee.getUint32(t)}else{s=2;r=(e,t)=>2*e.getUint16(t)}const i=[];let o=r(n,0);for(let a=s;ae.getSize()+3&-4))}write(){const e=this.getSize(),t=new DataView(new ArrayBuffer(e)),a=e>131070,n=a?4:2,s=new DataView(new ArrayBuffer((this.glyphs.length+1)*n));a?s.setUint32(0,0):s.setUint16(0,0);let r=0,i=0;for(const e of this.glyphs){r+=e.write(r,t);r=r+3&-4;i+=n;a?s.setUint32(i,r):s.setUint16(i,r>>1)}return{isLocationLong:a,loca:new Uint8Array(s.buffer),glyf:new Uint8Array(t.buffer)}}scale(e){for(let t=0,a=this.glyphs.length;te.getSize()));return this.header.getSize()+e}write(e,t){if(!this.header)return 0;const a=e;e+=this.header.write(e,t);if(this.simple)e+=this.simple.write(e,t);else for(const a of this.composites)e+=a.write(e,t);return e-a}scale(e){if(!this.header)return;const t=(this.header.xMin+this.header.xMax)/2;this.header.scale(t,e);if(this.simple)this.simple.scale(t,e);else for(const a of this.composites)a.scale(t,e)}}class GlyphHeader{constructor({numberOfContours:e,xMin:t,yMin:a,xMax:n,yMax:s}){this.numberOfContours=e;this.xMin=t;this.yMin=a;this.xMax=n;this.yMax=s}static parse(e,t){return[10,new GlyphHeader({numberOfContours:t.getInt16(e),xMin:t.getInt16(e+2),yMin:t.getInt16(e+4),xMax:t.getInt16(e+6),yMax:t.getInt16(e+8)})]}getSize(){return 10}write(e,t){t.setInt16(e,this.numberOfContours);t.setInt16(e+2,this.xMin);t.setInt16(e+4,this.yMin);t.setInt16(e+6,this.xMax);t.setInt16(e+8,this.yMax);return 10}scale(e,t){this.xMin=Math.round(e+(this.xMin-e)*t);this.xMax=Math.round(e+(this.xMax-e)*t)}}class Contour{constructor({flags:e,xCoordinates:t,yCoordinates:a}){this.xCoordinates=t;this.yCoordinates=a;this.flags=e}}class SimpleGlyph{constructor({contours:e,instructions:t}){this.contours=e;this.instructions=t}static parse(e,t,a){const n=[];for(let s=0;s255?e+=2:o>0&&(e+=1);t=r;o=Math.abs(i-a);o>255?e+=2:o>0&&(e+=1);a=i}}return e}write(e,t){const a=e,n=[],s=[],r=[];let i=0,o=0;for(const a of this.contours){for(let e=0,t=a.xCoordinates.length;e=0?18:2;n.push(e)}else n.push(f)}i=l;const c=a.yCoordinates[e];f=c-o;if(0===f){t|=32;s.push(0)}else{const e=Math.abs(f);if(e<=255){t|=f>=0?36:4;s.push(e)}else s.push(f)}o=c;r.push(t)}t.setUint16(e,n.length-1);e+=2}t.setUint16(e,this.instructions.length);e+=2;if(this.instructions.length){new Uint8Array(t.buffer,0,t.buffer.byteLength).set(this.instructions,e);e+=this.instructions.length}for(const a of r)t.setUint8(e++,a);for(let a=0,s=n.length;a=-128&&this.argument1<=127&&this.argument2>=-128&&this.argument2<=127||(e+=2):this.argument1>=0&&this.argument1<=255&&this.argument2>=0&&this.argument2<=255||(e+=2);return e}write(e,t){const a=e;2&this.flags?this.argument1>=-128&&this.argument1<=127&&this.argument2>=-128&&this.argument2<=127||(this.flags|=1):this.argument1>=0&&this.argument1<=255&&this.argument2>=0&&this.argument2<=255||(this.flags|=1);t.setUint16(e,this.flags);t.setUint16(e+2,this.glyphIndex);e+=4;if(1&this.flags){if(2&this.flags){t.setInt16(e,this.argument1);t.setInt16(e+2,this.argument2)}else{t.setUint16(e,this.argument1);t.setUint16(e+2,this.argument2)}e+=4}else{t.setUint8(e,this.argument1);t.setUint8(e+1,this.argument2);e+=2}if(256&this.flags){t.setUint16(e,this.instructions.length);e+=2;if(this.instructions.length){new Uint8Array(t.buffer,0,t.buffer.byteLength).set(this.instructions,e);e+=this.instructions.length}}return e-a}scale(e,t){}}class OpenTypeFileBuilder{#Q=new Map;constructor(e){this.sfnt=e}static getSearchParams(e,t){let a=1,n=0;for(;(a^e)>a;){a<<=1;n++}const s=a*t;return{range:s,entry:n,rangeShift:t*e-s}}toArray(){let e=this.sfnt;const t=this.#Q,a=[...t.keys()].sort(),n=a.length;let s=12+16*n;const r=[s];for(let e=0;e>>0;r.push(s)}const i=new Uint8Array(s),o=new DataView(i.buffer);for(let e=0;e>>0}o.setInt32(s+4,l);o.setInt32(s+8,r[e]);o.setInt32(s+12,t.get(n).length);s+=16}this.#Q.clear();return i}addTable(e,t){if(this.#Q.has(e))throw new Error(`Table ${e} already exists`);this.#Q.set(e,t)}}const Kn=[4],Gn=[5],Vn=[6],$n=[7],Yn=[8],Jn=[12,35],Qn=[14],Zn=[21],es=[22],ts=[30],as=[31];class Type1CharString{width=0;lsb=0;flexing=!1;output=[];stack=[];convert(e,t,a){const n=e.length;let s,r,i,o=!1;for(let l=0;ln)return!0;const s=n-e;for(let e=s;e>8&255,255&t);else{t=65536*t|0;this.output.push(255,t>>24&255,t>>16&255,t>>8&255,255&t)}}this.output.push(...t);a?this.stack.splice(s,e):this.stack.length=0;return!1}}function isHexDigit(e){return e>=48&&e<=57||e>=65&&e<=70||e>=97&&e<=102}function decrypt(e,t,a){if(a>=e.length)return new Uint8Array(0);let n,s,r=0|t;for(n=0;n>8;r=52845*(t+r)+22719&65535}return o}function isSpecial(e){return 47===e||91===e||93===e||123===e||125===e||40===e||41===e}class Type1Parser{constructor(e,t,a){if(t){const t=e.getBytes(),a=!((isHexDigit(t[0])||isWhiteSpace(t[0]))&&isHexDigit(t[1])&&isHexDigit(t[2])&&isHexDigit(t[3])&&isHexDigit(t[4])&&isHexDigit(t[5])&&isHexDigit(t[6])&&isHexDigit(t[7]));e=new Stream(a?decrypt(t,55665,4):function decryptAscii(e,t,a){let n=0|t;const s=e.length,r=new Uint8Array(s>>>1);let i,o;for(i=0,o=0;i>8;n=52845*(e+n)+22719&65535}}return r.slice(a,o)}(t,55665,4))}this.seacAnalysisEnabled=!!a;this.stream=e;this.nextChar()}readNumberArray(){this.getToken();const e=[];for(;;){const t=this.getToken();if(null===t||"]"===t||"}"===t)break;e.push(parseFloat(t||0))}return e}readNumber(){const e=this.getToken();return parseFloat(e||0)}readInt(){const e=this.getToken();return 0|parseInt(e||0,10)}readBoolean(){return"true"===this.getToken()?1:0}nextChar(){return this.currentChar=this.stream.getByte()}prevChar(){this.stream.skip(-2);return this.currentChar=this.stream.getByte()}getToken(){let e=!1,t=this.currentChar;for(;;){if(-1===t)return null;if(e)10!==t&&13!==t||(e=!1);else if(37===t)e=!0;else if(!isWhiteSpace(t))break;t=this.nextChar()}if(isSpecial(t)){this.nextChar();return String.fromCharCode(t)}let a="";do{a+=String.fromCharCode(t);t=this.nextChar()}while(t>=0&&!isWhiteSpace(t)&&!isSpecial(t));return a}readCharStrings(e,t){return-1===t?e:decrypt(e,4330,t)}extractFontProgram(e){const t=this.stream,a=[],n=[],s=new Map([["lenIV",4]]),r={subrs:[],charstrings:[],properties:{privateData:s}};let i,o,l,f;for(;null!==(i=this.getToken());)if("/"===i){i=this.getToken();switch(i){case"CharStrings":this.getToken();this.getToken();this.getToken();this.getToken();for(;;){i=this.getToken();if(null===i||"end"===i)break;if("/"!==i)continue;const e=this.getToken();o=this.readInt();this.getToken();l=o>0?t.getBytes(o):new Uint8Array(0);f=s.get("lenIV");const a=this.readCharStrings(l,f);this.nextChar();i=this.getToken();"noaccess"===i?this.getToken():"/"===i&&this.prevChar();n.push({glyph:e,encoded:a})}break;case"Subrs":this.readInt();this.getToken();for(;"dup"===this.getToken();){const e=this.readInt();o=this.readInt();this.getToken();l=o>0?t.getBytes(o):new Uint8Array(0);f=s.get("lenIV");const n=this.readCharStrings(l,f);this.nextChar();i=this.getToken();"noaccess"===i&&this.getToken();a[e]=n}break;case"BlueValues":case"OtherBlues":case"FamilyBlues":case"FamilyOtherBlues":const e=this.readNumberArray();e.length>0&&e.length,0;break;case"StemSnapH":case"StemSnapV":s.set(i,this.readNumberArray());break;case"StdHW":case"StdVW":s.set(i,this.readNumberArray()[0]);break;case"BlueShift":case"lenIV":case"BlueFuzz":case"BlueScale":case"LanguageGroup":s.set(i,this.readNumber());break;case"ExpansionFactor":s.set(i,this.readNumber()||.06);break;case"ForceBold":s.set(i,this.readBoolean())}}for(const{encoded:t,glyph:s}of n){const n=new Type1CharString,i=n.convert(t,a,this.seacAnalysisEnabled);let o=n.output;i&&(o=[14]);const l={glyphName:s,charstring:o,width:n.width,lsb:n.lsb,seac:n.seac};".notdef"===s?r.charstrings.unshift(l):r.charstrings.push(l);if(e.builtInEncoding){const t=e.builtInEncoding.indexOf(s);t>-1&&void 0===e.widths[t]&&t>=e.firstChar&&t<=e.lastChar&&(e.widths[t]=n.width)}}return r}extractFontHeader(e){let t;for(;null!==(t=this.getToken());)if("/"===t){t=this.getToken();switch(t){case"FontMatrix":const a=this.readNumberArray();e.fontMatrix=a;break;case"Encoding":const n=this.getToken();let s;if(/^\d+$/.test(n)){s=[];const e=0|parseInt(n,10);this.getToken();for(let a=0;a=s){i+=a;for(;i=0&&(n[e]=s)}}return type1FontGlyphMapping(e,n,a)}hasGlyphId(e){if(e<0||e>=this.numGlyphs)return!1;if(0===e)return!0;return this.charstrings[e-1].charstring.length>0}getSeacs(e){const t=[];for(let a=0,n=e.length;a0;e--)t[e]-=t[e-1];h.setByName(e,t)}r.topDict.privateDict=h;const m=new CFFIndex;for(const e of n)m.add(e);h.subrsIndex=m;return new CFFCompiler(r).compile()}}const ns=[[57344,63743],[1048576,1114109]],ss=1e3,rs=["ascent","bbox","black","bold","cssFontInfo","data","defaultVMetrics","defaultWidth","descent","disableFontFace","fallbackName","fontExtraProperties","fontMatrix","isInvalidPDFjsFont","isType3Font","italic","loadedName","mimetype","missingFile","name","remeasure","systemFontInfo","vertical"],is=["cMap","composite","defaultEncoding","differences","isMonospace","isSerifFont","isSymbolicFont","seacMap","subtype","toFontChar","toUnicode","type","vmetrics","widths"];function adjustWidths(e){if(!e.fontMatrix)return;if(e.fontMatrix[0]===n[0])return;const t=.001/e.fontMatrix[0],a=e.widths;for(const e in a)a[e]*=t;e.defaultWidth*=t}function amendFallbackToUnicode(e){if(!e.fallbackToUnicode)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;const t=[];for(const a in e.fallbackToUnicode)e.toUnicode.has(a)||(t[a]=e.fallbackToUnicode[a]);t.length>0&&e.toUnicode.amend(t)}class fonts_Glyph{constructor(e,t,a,n,s,r,i,o,l){this.originalCharCode=e;this.fontChar=t;this.unicode=a;this.accent=n;this.width=s;this.vmetric=r;this.operatorListId=i;this.isSpace=o;this.isInFont=l}get category(){return shadow(this,"category",function getCharUnicodeCategory(e){const t=wn.get(e);if(t)return t;const a=e.match(bn),n={isWhitespace:!!a?.[1],isZeroWidthDiacritic:!!a?.[2],isInvisibleFormatMark:!!a?.[3]};wn.set(e,n);return n}(this.unicode),!0)}}function int16(e,t){return(e<<8)+t}function writeSignedInt16(e,t,a){e[t+1]=a;e[t]=a>>>8}function signedInt16(e,t){const a=(e<<8)+t;return 32768&a?a-65536:a}class TrueTypeTableBuilder{#V;#$=1024;#ee=!1;#Y=0;#te;constructor({exactLength:e,minLength:t}){this.#ee=!!e;this.#J(e||t)}#J(e){if(this.#ee)this.#$=e;else for(;this.#$this.#$&&this.#J(t);this.#V.set(e,this.#Y);this.#Y=t}setInt16(e){const t=this.#Y+2;!this.#ee&&t>this.#$&&this.#J(t);this.#te.setInt16(this.#Y,e);this.#Y=t}setSafeInt16(e){const t=this.#Y+2;!this.#ee&&t>this.#$&&this.#J(t);this.#te.setInt16(this.#Y,MathClamp(e,-32768,32767));this.#Y=t}setInt32(e){const t=this.#Y+4;!this.#ee&&t>this.#$&&this.#J(t);this.#te.setInt32(this.#Y,e);this.#Y=t}}function isTrueTypeCollectionFile(e){return"ttcf"===bytesToString(e.peekBytes(4))}function getFontFileType(e,{type:t,subtype:a,composite:n}){let s,r;if(function isTrueTypeFile(e){const t=bytesToString(e.peekBytes(4));return"\0\0\0"===t||"true"===t}(e)||isTrueTypeCollectionFile(e))s=n?"CIDFontType2":"TrueType";else if(function isOpenTypeFile(e){return"OTTO"===bytesToString(e.peekBytes(4))}(e))s=n?"CIDFontType2":"OpenType";else if(function isType1File(e){const t=e.peekBytes(2);return 37===t[0]&&33===t[1]||128===t[0]&&1===t[1]}(e))s=n?"CIDFontType0":"MMType1"===t?"MMType1":"Type1";else if(function isCFFFile(e){const t=e.peekBytes(4);return t[0]>=1&&t[3]>=1&&t[3]<=4}(e))if(n){s="CIDFontType0";r="CIDFontType0C"}else{s="MMType1"===t?"MMType1":"Type1";r="Type1C"}else{warn("getFontFileType: Unable to detect correct font file Type/Subtype.");s=t;r=a}return[s,r]}function applyStandardFontGlyphMap(e,t){for(const a in t)e[+a]=t[a]}function buildToFontChar(e,t,a){const n=[];let s;for(let a=0,r=e.length;ans[0][0]<=e&&e<=ns[0][1]||ns[1][0]<=e&&e<=ns[1][1];let h=null;for(const u in e){let m=e[u];if(!t(m))continue;if(f>c){l++;if(l>=ns.length){warn("Ran out of space in font private use area.");break}f=ns[l][0];c=ns[l][1]}const p=f++;0===m&&(m=a);let d=n.get(u);if("string"==typeof d)if(1===d.length)d=d.codePointAt(0);else{if(!h){h=new Map;for(let e=64256;e<=64335;e++){const t=String.fromCharCode(e).normalize("NFKD");t.length>1&&h.set(t,e)}}d=h.get(d)||d.codePointAt(0)}if(d&&!isInPrivateArea(d)&&!o.has(m)){r.set(d,m);o.add(m)}s[p]=m;i[u]=p}return{toFontChar:i,charCodeToGlyphId:s,toUnicodeExtraMap:r,nextAvailableFontCharCode:f}}function createCmapTable(e,t,a){const n=function getRanges(e,t,a){const n=[];for(const t in e)e[t]>=a||n.push({fontCharCode:0|t,glyphId:e[t]});if(t)for(const[e,s]of t)s>=a||n.push({fontCharCode:e,glyphId:s});0===n.length&&n.push({fontCharCode:0,glyphId:0});n.sort((e,t)=>e.fontCharCode-t.fontCharCode);const s=[],r=n.length;for(let e=0;e65535?2:1,r=new TrueTypeTableBuilder({exactLength:12});r.skip(2);r.setInt16(s);r.setArray([0,3]);r.setArray([0,1]);r.setInt32(4+8*s);let i,o,l,f;for(i=n.length-1;i>=0&&!(n[i][0]<=65535);--i);const c=i+1;n[i][0]<65535&&65535===n[i][1]&&(n[i][1]=65534);const h=n[i][1]<65535?1:0,u=c+h,m=OpenTypeFileBuilder.getSearchParams(u,2),p=2*c+2*h,d=new TrueTypeTableBuilder({exactLength:p}),g=new TrueTypeTableBuilder({exactLength:p}),b=new TrueTypeTableBuilder({exactLength:p}),w=new TrueTypeTableBuilder({exactLength:p}),j=new TrueTypeTableBuilder({});let k=0;for(i=0,o=c;i0){g.setArray([255,255]);d.setArray([255,255]);b.setArray([0,1]);w.skip(2)}const y=new TrueTypeTableBuilder({exactLength:12+d.length+g.length+b.length+w.length+j.length});y.skip(2);y.setInt16(2*u);y.setInt16(m.range);y.setInt16(m.entry);y.setInt16(m.rangeShift);y.setArray(g.data);y.skip(2);y.setArray(d.data);y.setArray(b.data);y.setArray(w.data);y.setArray(j.data);let q=null,v=null,S=null;if(s>1){q=new TrueTypeTableBuilder({exactLength:8});q.setArray([0,3]);q.setArray([0,10]);q.setInt32(4+8*s+4+y.length);v=new TrueTypeTableBuilder({});for(const e of n){let t=e[0];const a=e[2];let n=a[0];for(l=1,f=a.length;le||!o)&&(o=e);l 123 are reserved for internal usage");i|=1<65535&&(l=65535)}else{o=0;l=255}const c=e.bbox||[0,0,0,0],h=a.unitsPerEm||(e.fontMatrix?1/Math.max(...e.fontMatrix.slice(0,4).map(Math.abs)):1e3),u=e.ascentScaled?1:h/ss,m=a.ascent||Math.round(u*(e.ascent||c[3]));let p=a.descent||Math.round(u*(e.descent||c[1]));p>0&&e.descent>0&&c[1]<0&&(p=-p);const d=a.yMax||m,g=-a.yMin||-p,b=new TrueTypeTableBuilder({exactLength:96});b.setArray([0,3]);b.setArray([2,36]);b.setArray([1,244]);b.setArray([0,5]);b.skip(2);b.setArray([2,138]);b.setArray([2,187]);b.skip(2);b.setArray([0,140]);b.setArray([2,138]);b.setArray([2,187]);b.skip(2);b.setArray([1,223]);b.setArray([0,49]);b.setArray([1,2]);b.skip(2);b.setArray([0,0,6,e.fixedPitch?9:0,0,0,0,0,0,0]);b.setInt32(n);b.setInt32(s);b.setInt32(r);b.setInt32(i);b.setArray([42,50,49,42]);b.setInt16(e.italicAngle?1:0);b.setInt16(o||e.firstChar);b.setInt16(l||e.lastChar);b.setInt16(m);b.setInt16(p);b.setArray([0,100]);b.setInt16(d);b.setInt16(g);b.skip(8);b.setInt16(e.xHeight);b.setInt16(e.capHeight);b.skip(2);b.setInt16(o||e.firstChar);b.setArray([0,3]);return b.data}function createPostTable(e){const t=new TrueTypeTableBuilder({exactLength:32});t.setArray([0,3,0,0]);t.setInt32(Math.floor(65536*e.italicAngle));t.skip(4);t.setInt32(e.fixedPitch?1:0);t.skip(16);return t.data}function createPostscriptName(e){return e.replaceAll(/[^\x21-\x7E]|[[\](){}<>/%]/g,"").slice(0,63)}function createNameTable(e,t){t||=[[],[]];const a=[t[0][0]||"Original licence",t[0][1]||e,t[0][2]||"Unknown",t[0][3]||"uniqueID",t[0][4]||e,t[0][5]||"Version 0.11",t[0][6]||createPostscriptName(e),t[0][7]||"Unknown",t[0][8]||"Unknown",t[0][9]||"Unknown"],n=a.map(e=>stringToBytes(e)),s=new Array(a.length);let r,i,o,l,f;for(r=0,i=a.length;re.length))+Math.sumPrecise(n.map(e=>e.length))+Math.sumPrecise(s.map(e=>e.length))});b.skip(2);b.setInt16(g);b.setInt16(12*g+6);for(const e of p)b.setArray(e);for(const e of n)b.setArray(e);for(const e of s)b.setArray(e);return b.data}class Font{#ae=new Map;#ne=new Map;charProcOperatorList;constructor(e,t,a,n){this.name=e;this.psName=null;this.mimetype=null;this.disableFontFace=n.disableFontFace;this.fontExtraProperties=n.fontExtraProperties;this.loadedName=a.loadedName;this.isType3Font=a.isType3Font;this.missingFile=!1;this.cssFontInfo=a.cssFontInfo;let s=!!(a.flags&yn);if(!s&&!a.isSimulatedFlags){const t=Mn(),a=Pn(),n=En();for(const r of e.split("+")){let e=normalizeFontName(r);e=t[e]||a[e]||e;e=e.split("-",1)[0];if(n[e]){s=!0;break}}}this.isSerifFont=s;this.isSymbolicFont=!!(a.flags&qn);this.isMonospace=!!(a.flags&kn);let{type:r,subtype:i}=a;this.type=r;this.subtype=i;this.systemFontInfo=a.systemFontInfo;const o=e.match(/^InvalidPDFjsFont_(.*)_\d+$/);this.isInvalidPDFjsFont=!!o;this.isInvalidPDFjsFont?this.fallbackName=o[1]:this.isMonospace?this.fallbackName="monospace":this.isSerifFont?this.fallbackName="serif":this.fallbackName="sans-serif";if(this.systemFontInfo?.guessFallback){this.systemFontInfo.guessFallback=!1;this.systemFontInfo.css+=`,${this.fallbackName}`}this.differences=a.differences;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.composite=a.composite;this.cMap=a.cMap;this.capHeight=a.capHeight/ss;this.ascent=a.ascent/ss;this.descent=a.descent/ss;this.lineHeight=this.ascent-this.descent;this.fontMatrix=a.fontMatrix;this.bbox=a.bbox;this.defaultEncoding=a.defaultEncoding;this.toUnicode=a.toUnicode;this.toFontChar=[];if("Type3"===a.type){for(let e=0;e<256;e++)this.toFontChar[e]=this.differences[e]||a.defaultEncoding[e];return}this.cidEncoding=a.cidEncoding||"";this.vertical=!!a.vertical;if(this.vertical){this.vmetrics=a.vmetrics;this.defaultVMetrics=a.defaultVMetrics}if(!t||t.isEmpty){t&&warn('Font file is empty in "'+e+'" ('+this.loadedName+")");this.fallbackToSystemFont(a);return}[r,i]=getFontFileType(t,a);r===this.type&&i===this.subtype||info(`Inconsistent font file Type/SubType, expected: ${this.type}/${this.subtype} but found: ${r}/${i}.`);let l;try{switch(r){case"MMType1":info("MMType1 font ("+e+"), falling back to Type1.");case"Type1":case"CIDFontType0":this.mimetype="font/opentype";const n="Type1C"===i||"CIDFontType0C"===i?new CFFFont(t,a):new Type1Font(e,t,a);adjustWidths(a);l=this.convert(e,n,a);break;case"OpenType":case"TrueType":case"CIDFontType2":this.mimetype="font/opentype";l=this.checkAndRepair(e,t,a);adjustWidths(a);this.isOpenType&&(r="OpenType");break;default:throw new FormatError(`Font ${r} is not supported`)}}catch(e){warn(e);this.fallbackToSystemFont(a);return}amendFallbackToUnicode(a);this.data=l;this.type=r;this.subtype=i;this.fontMatrix=a.fontMatrix;this.widths=a.widths;this.defaultWidth=a.defaultWidth;this.toUnicode=a.toUnicode;this.seacMap=a.seacMap}get renderer(){return shadow(this,"renderer",FontRendererFactory.create(this,jn))}#se(e){const t=Object.create(null);for(const a of e){const e=this[a];void 0!==e&&(t[a]=e)}return t}exportData(){return{buffer:compileFontInfo(this.#se(rs)),charProcOperatorList:this.charProcOperatorList,extra:this.fontExtraProperties?this.#se(is):void 0}}fallbackToSystemFont(e){this.missingFile=!0;const{name:t,type:a}=this;let n=normalizeFontName(t);const s=Mn(),r=Pn(),i=!!s[n],o=!(!r[n]||!s[r[n]]);n=s[n]||r[n]||n;const l=Wn()[n];if(l){isNaN(this.ascent)&&(this.ascent=l.ascent/ss);isNaN(this.descent)&&(this.descent=l.descent/ss);isNaN(this.capHeight)&&(this.capHeight=l.capHeight/ss)}this.bold=/bold/gi.test(n);this.italic=/oblique|italic/gi.test(n);this.black=/Black/g.test(t);const f=/Narrow/g.test(t);this.remeasure=(!i||f)&&Object.keys(this.widths).length>0;if((i||o)&&"CIDFontType2"===a&&this.cidEncoding.startsWith("Identity-")){const a=e.cidToGidMap,n=[];applyStandardFontGlyphMap(n,zn());/Arial-?Black/i.test(t)?applyStandardFontGlyphMap(n,Ln()):/Calibri/i.test(t)&&applyStandardFontGlyphMap(n,Un());if(a){for(const e in n){const t=n[e];void 0!==a[t]&&(n[+e]=a[t])}a.length!==this.toUnicode.length&&e.hasIncludedToUnicodeMap&&this.toUnicode instanceof IdentityToUnicodeMap&&this.toUnicode.forEach(function(e,t){const s=n[e];void 0===a[s]&&(n[+e]=t)})}this.toUnicode instanceof IdentityToUnicodeMap||this.toUnicode.forEach(function(e,t){n[+e]=t});this.toFontChar=n;this.toUnicode=new ToUnicodeMap(n)}else if(/Symbol/i.test(n))this.toFontChar=buildToFontChar(hn,mn(),this.differences);else if(/Dingbats/i.test(n))this.toFontChar=buildToFontChar(un,pn(),this.differences);else if(i||o){const e=buildToFontChar(this.defaultEncoding,mn(),this.differences);"CIDFontType2"!==a||this.cidEncoding.startsWith("Identity-")||this.toUnicode instanceof IdentityToUnicodeMap||this.toUnicode.forEach(function(t,a){e[+t]=a});this.toFontChar=e}else{const e=mn(),a=[];this.toUnicode.forEach((t,n)=>{if(!this.composite){const a=getUnicodeForGlyph(this.differences[t]||this.defaultEncoding[t],e);-1!==a&&(n=a)}a[+t]=n});this.composite&&this.toUnicode instanceof IdentityToUnicodeMap&&/Tahoma|Verdana/i.test(t)&&applyStandardFontGlyphMap(a,zn());this.toFontChar=a}amendFallbackToUnicode(e);this.loadedName=n.split("-",1)[0]}checkAndRepair(e,t,a){const n=["OS/2","cmap","head","hhea","hmtx","maxp","name","post","loca","glyf","fpgm","prep","cvt ","CFF "];function readTables(e,t){const a=Object.create(null);a["OS/2"]=null;a.cmap=null;a.head=null;a.hhea=null;a.hmtx=null;a.maxp=null;a.name=null;a.post=null;for(let s=0;s>>0,n=e.getInt32()>>>0,s=e.getInt32()>>>0,r=e.pos;e.pos=e.start||0;e.skip(n);const i=e.getBytes(s);e.pos=r;if("head"===t){i[8]=i[9]=i[10]=i[11]=0;i[17]|=32}return{tag:t,checksum:a,length:s,offset:n,data:i,view:new DataView(i.buffer,i.byteOffset,i.byteLength)}}function readOpenTypeHeader(e){return{version:e.getString(4),numTables:e.getUint16(),searchRange:e.getUint16(),entrySelector:e.getUint16(),rangeShift:e.getUint16()}}function sanitizeGlyph(e,t,a,n,s,r){const i={length:0,sizeOfInstructions:0};if(t<0||t>=e.length||a>e.length||a-t<=12)return i;const o=e.subarray(t,a),l=signedInt16(o[2],o[3]),f=signedInt16(o[4],o[5]),c=signedInt16(o[6],o[7]),h=signedInt16(o[8],o[9]);if(l>c){writeSignedInt16(o,2,c);writeSignedInt16(o,6,l)}if(f>h){writeSignedInt16(o,4,h);writeSignedInt16(o,8,f)}const u=signedInt16(o[0],o[1]);if(u<0){if(u<-1)return i;n.set(o,s);i.length=o.length;return i}let m,p=10,d=0;for(m=0;mo.length)return i;if(!r&&b>0){n.set(o.subarray(0,g),s);n.set([0,0],s+g);n.set(o.subarray(w,k),s+g+2);k-=b;o.length-k>3&&(k=k+3&-4);i.length=k;return i}if(o.length-k>3){k=k+3&-4;n.set(o.subarray(0,k),s);i.length=k;return i}n.set(o,s);i.length=o.length;return i}function readNameTable(e){const a=(t.start||0)+e.offset;t.pos=a;const n=[[],[]],s=[],r=e.length,i=a+r;if(0!==t.getUint16()||r<6)return[n,s];const o=t.getUint16(),l=t.getUint16();let f,c;for(f=0;fi)continue;t.pos=r;const o=e.name;if(e.encoding){let a="";for(let n=0,s=e.length;n0&&(f+=e-1)}}else{if(g||w){warn("TT: nested FDEFs not allowed");d=!0}g=!0;h=f;i=u.pop();t.functionsDefined[i]={data:l,i:f}}else if(!g&&!w){i=u.at(-1);if(isNaN(i))info("TT: CALL empty stack (or invalid entry).");else{t.functionsUsed[i]=!0;if(i in t.functionsStackDeltas){const e=u.length+t.functionsStackDeltas[i];if(e<0){warn("TT: CALL invalid functions stack delta.");t.hintsValid=!1;return}u.length=e}else if(i in t.functionsDefined&&!p.includes(i)){m.push({data:l,i:f,stackTop:u.length-1});p.push(i);o=t.functionsDefined[i];if(!o){warn("TT: CALL non-existent function");t.hintsValid=!1;return}l=o.data;f=o.i}}}if(!g&&!w){let t=0;e<=142?t=s[e]:e>=192&&e<=223?t=-1:e>=224&&(t=-2);if(e>=113&&e<=117){n=u.pop();isNaN(n)||(t=2*-n)}for(;t<0&&u.length>0;){u.pop();t++}for(;t>0;){u.push(NaN);t--}}}t.tooComplexToFollowFunctions=d;const j=[l];f>l.length&&j.push(new Uint8Array(f-l.length));if(h>c){warn("TT: complementing a missing function tail");j.push(new Uint8Array([34,45]))}!function foldTTTable(e,t){if(t.length>1){let a,n,s=0;for(a=0,n=t.length;a>>0,r=[];for(let t=0;t>>0);const i={ttcTag:t,majorVersion:a,minorVersion:n,numFonts:s,offsetTable:r};switch(a){case 1:return i;case 2:i.dsigTag=e.getInt32()>>>0;i.dsigLength=e.getInt32()>>>0;i.dsigOffset=e.getInt32()>>>0;return i}throw new FormatError(`Invalid TrueType Collection majorVersion: ${a}.`)}(e),s=t.split("+");let r;for(let i=0;i=32))throw new FormatError('"maxp" table has a wrong version number');f=65536}!function writeUint32(e,t,a){e[t+3]=255&a;e[t+2]=a>>>8;e[t+1]=a>>>16;e[t]=a>>>24}(i.maxp.data,0,f)}let h=int16(i.head.data[50],i.head.data[51]);if(i.loca){const e=h?4*(c+1):2*(c+1);if(i.loca.length!==e){warn("Incorrect 'loca' table length -- attempting to fix it.");const a=Object.values(i).filter(Boolean).sort((e,t)=>e.offset-t.offset),n=a.indexOf(i.loca),s=a[n+1]||null;if(s&&i.loca.offset+e>8&255;o[a+1]=255&n;writeSignedInt16(o,a+2,Math.round(e[t]*signedInt16(o[a+2],o[a+3])))}}let u=c+1,m=!0;if(u>65535){m=!1;u=c;warn("Not enough space in glyfs to duplicate first glyph.")}let p=0,d=0;if(f>=65536&&i.maxp.length>=32){t.pos+=8;if(t.getUint16()>2){i.maxp.data[14]=0;i.maxp.data[15]=2}t.pos+=4;p=t.getUint16();t.pos+=4;d=t.getUint16()}i.maxp.data[4]=u>>8;i.maxp.data[5]=255&u;const g=function sanitizeTTPrograms(e,t,a,n){const s={functionsDefined:[],functionsUsed:[],functionsStackDeltas:[],tooComplexToFollowFunctions:!1,hintsValid:!0};e&&sanitizeTTProgram(e,s);t&&sanitizeTTProgram(t,s);e&&function checkInvalidFunctions(e,t){if(!e.tooComplexToFollowFunctions)if(e.functionsDefined.length>t){warn("TT: more functions defined than expected");e.hintsValid=!1}else for(let a=0,n=e.functionsUsed.length;at){warn("TT: invalid function id: "+a);e.hintsValid=!1;return}if(e.functionsUsed[a]&&!e.functionsDefined[a]){warn("TT: undefined function: "+a);e.hintsValid=!1;return}}}(s,n);if(a&&1&a.length){const e=new Uint8Array(a.length+1);e.set(a.data);a.data=e}return s.hintsValid}(i.fpgm,i.prep,i["cvt "],p);if(!g){delete i.fpgm;delete i.prep;delete i["cvt "]}!function sanitizeMetrics(e,t,a,n,s,r){if(!t){a&&(a.data=null);return}e.pos=(e.start||0)+t.offset;e.pos+=4;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;e.pos+=2;const i=e.getUint16();e.pos+=8;e.pos+=2;let o=e.getUint16();if(0!==i){if(!(2&int16(n.data[44],n.data[45]))){t.data[22]=0;t.data[23]=0}}if(o>s){info(`The numOfMetrics (${o}) should not be greater than the numGlyphs (${s}).`);o=s;t.data[34]=(65280&o)>>8;t.data[35]=255&o}const l=s-o-(a.length-4*o>>1);if(l>0){const e=new Uint8Array(a.length+2*l);e.set(a.data);if(r){e[a.length]=a.data[2];e[a.length+1]=a.data[3]}a.data=e}}(t,i.hhea,i.hmtx,i.head,u,m);if(!i.head)throw new FormatError('Required "head" table is not found');!function sanitizeHead(e,t,a){const{data:n,view:s}=e,r=s.getInt32(0);if(r>>16!=1){info("Attempting to fix invalid version in head table: "+r);s.setInt32(0,65536)}const i=signedInt16(n[50],n[51]);if(i<0||i>1){info("Attempting to fix invalid indexToLocFormat in head table: "+i);const e=t+1;if(a===e<<1){n[50]=0;n[51]=0}else{if(a!==e<<2)throw new FormatError("Could not fix indexToLocFormat: "+i);n[50]=0;n[51]=1}}}(i.head,c,o?i.loca.length:0);let b=Object.create(null);if(o){const e=function sanitizeGlyphLocations(e,t,a,n,s,r,i){let o,l,f;if(n){o=4;l=function fontItemDecodeLong(e,t){return e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3]};f=function fontItemEncodeLong(e,t,a){e[t]=a>>>24&255;e[t+1]=a>>16&255;e[t+2]=a>>8&255;e[t+3]=255&a}}else{o=2;l=function fontItemDecode(e,t){return e[t]<<9|e[t+1]<<1};f=function fontItemEncode(e,t,a){e[t]=a>>9&255;e[t+1]=a>>1&255}}const c=r?a+1:a,h=o*(1+c),u=new Uint8Array(h);u.set(e.data.subarray(0,h));e.data=u;const m=t.data,p=m.length,d=new Uint8Array(p);let g,b;const w=[];for(g=0,b=0;gp&&(e=p);w.push({index:g,offset:e,endOffset:0})}w.sort((e,t)=>e.offset-t.offset);for(g=0;ge.index-t.index);for(g=0;gi&&(i=e.sizeOfInstructions);y+=t;f(u,b,y)}if(0===y){const e=new Uint8Array([0,1,0,0,0,0,0,0,0,0,0,0,0,0,49,0]);for(g=0,b=o;ga+y)t.data=d.subarray(0,a+y);else{t.data=new Uint8Array(a+y);t.data.set(d.subarray(0,y))}t.data.set(d.subarray(0,a),y);f(e.data,u.length-o,y+a)}else t.data=d.subarray(0,y);return{missingGlyphs:k,maxSizeOfInstructions:i}}(i.loca,i.glyf,c,h,g,m,d);b=e.missingGlyphs;if(f>=65536&&i.maxp.length>=32){i.maxp.data[26]=e.maxSizeOfInstructions>>8;i.maxp.data[27]=255&e.maxSizeOfInstructions}}if(!i.hhea)throw new FormatError('Required "hhea" table is not found');if(0===i.hhea.data[10]&&0===i.hhea.data[11]){i.hhea.data[10]=255;i.hhea.data[11]=255}const w={unitsPerEm:int16(i.head.data[18],i.head.data[19]),yMax:signedInt16(i.head.data[42],i.head.data[43]),yMin:signedInt16(i.head.data[38],i.head.data[39]),ascent:signedInt16(i.hhea.data[4],i.hhea.data[5]),descent:signedInt16(i.hhea.data[6],i.hhea.data[7]),lineGap:signedInt16(i.hhea.data[8],i.hhea.data[9])};this.ascent=w.ascent/w.unitsPerEm;this.descent=w.descent/w.unitsPerEm;this.lineGap=w.lineGap/w.unitsPerEm;if(this.cssFontInfo?.lineHeight){this.lineHeight=this.cssFontInfo.metrics.lineHeight;this.lineGap=this.cssFontInfo.metrics.lineGap}else this.lineHeight=this.ascent-this.descent+this.lineGap;i.post&&function readPostScriptTable(e,a,n){const s=(t.start||0)+e.offset;t.pos=s;const r=s+e.length,i=t.getInt32();t.skip(28);let o,l,f=!0;switch(i){case 65536:o=Sn;break;case 131072:const e=t.getUint16();if(e!==n){f=!1;break}const s=[];for(l=0;l=32768){f=!1;break}s.push(e)}if(!f)break;const c=[];for(;t.pos65535)throw new FormatError("Max size of CID is 65,535");let s=-1;t?s=n:void 0!==e[n]&&(s=e[n]);s>=0&&s>>0;let c=!1;if(o?.platformId!==s||o?.encodingId!==r){if(0!==s||0!==r&&1!==r&&3!==r)if(1===s&&0===r)c=!0;else if(3!==s||1!==r||!n&&o){if(a&&3===s&&0===r){c=!0;let a=!0;if(e>3;e.push(n);a=Math.max(n,a)}const n=[];for(let e=0;e<=a;e++)n.push({firstCode:t.getUint16(),entryCount:t.getUint16(),idDelta:signedInt16(t.getByte(),t.getByte()),idRangePos:t.pos+t.getUint16()});for(let a=0;a<256;a++)if(0===e[a]){t.pos=n[0].idRangePos+2*a;m=t.getUint16();h.push({charCode:a,glyphId:m})}else{const s=n[e[a]];for(u=0;u>1;t.skip(6);const a=[];let n;for(n=0;n>1)-(e-n);s.offsetIndex=i;o=Math.max(o,i+s.end-s.start+1)}else s.offsetIndex=-1}const l=[];for(u=0;u>>0;for(u=0;u>>0,a=t.getInt32()>>>0;let n=t.getInt32()>>>0;for(let t=e;t<=a;t++)h.push({charCode:t,glyphId:n++})}}}h.sort((e,t)=>e.charCode-t.charCode);const p=[],d=new Set;for(const e of h){const{charCode:t}=e;if(!d.has(t)){d.add(t);p.push(e)}}return{platformId:o.platformId,encodingId:o.encodingId,mappings:p,hasShortCmap:c}}(i.cmap,t,this.isSymbolicFont,a.hasEncoding),n=e.platformId,s=e.encodingId,r=e.mappings;let o=[],l=!1;!a.hasEncoding||"MacRomanEncoding"!==a.baseEncodingName&&"WinAnsiEncoding"!==a.baseEncodingName||(o=getEncoding(a.baseEncodingName));if(a.hasEncoding&&!this.isSymbolicFont&&(3===n&&1===s||1===n&&0===s)){const e=mn();for(let t=0;t<256;t++){let i;i=void 0!==this.differences[t]?this.differences[t]:o.length&&""!==o[t]?o[t]:fn[t];if(!i)continue;const l=recoverGlyphName(i,e);let f;3===n&&1===s?f=e[l]:1===n&&0===s&&(f=ln.indexOf(l));if(void 0===f){if(!a.glyphNames&&a.hasIncludedToUnicodeMap&&!(this.toUnicode instanceof IdentityToUnicodeMap)){const e=this.toUnicode.get(t);e&&(f=e.codePointAt(0))}if(void 0===f)continue}for(const e of r)if(e.charCode===f){j[t]=e.glyphId;break}}}else if(0===n){for(const e of r)j[e.charCode]=e.glyphId;l=!0}else if(3===n&&0===s)for(const e of r){let t=e.charCode;t>=61440&&t<=61695&&(t&=255);j[t]=e.glyphId}else for(const e of r)j[e.charCode]=e.glyphId;if(a.glyphNames&&(o.length||this.differences.length))for(let e=0;e<256;++e){if(!l&&void 0!==j[e])continue;const t=this.differences[e]||o[e];if(!t)continue;const n=a.glyphNames.indexOf(t);n>0&&hasGlyph(n)&&(j[e]=n)}}0===j.length&&(j[0]=0);let k=u-1;m||(k=0);if(!a.cssFontInfo){const e=adjustMapping(j,hasGlyph,k,this.toUnicode);this.toFontChar=e.toFontChar;i.cmap={tag:"cmap",data:createCmapTable(e.charCodeToGlyphId,e.toUnicodeExtraMap,u)};i["OS/2"]&&function validateOS2Table(e,t){t.pos=(t.start||0)+e.offset;const a=t.getUint16();t.skip(60);const n=t.getUint16();if(a<4&&768&n)return!1;if(t.getUint16()>t.getUint16())return!1;t.skip(6);if(0===t.getUint16())return!1;e.data[8]=e.data[9]=0;return!0}(i["OS/2"],t)||(i["OS/2"]={tag:"OS/2",data:createOS2Table(a,e.charCodeToGlyphId,w)})}if(i.name){const[t,n]=readNameTable(i.name);i.name.data=createNameTable(e,t);this.psName=t[0][6]||null;a.composite||function adjustTrueTypeToUnicode(e,t,a){if(e.isInternalFont)return;if(e.hasIncludedToUnicodeMap)return;if(e.hasEncoding)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;if(!t)return;if(0===a.length)return;if(e.defaultEncoding===cn)return;for(const e of a)if(!isWinNameRecord(e))return;const n=cn,s=[],r=mn();for(const e in n){const t=n[e];if(""===t)continue;const a=r[t];void 0!==a&&(s[e]=String.fromCharCode(a))}s.length>0&&e.toUnicode.amend(s)}(a,this.isSymbolicFont,n)}else i.name={tag:"name",data:createNameTable(this.name)};const y=new OpenTypeFileBuilder(r.version);for(const e in i)y.addTable(e,i[e].data);return y.toArray()}convert(e,t,a){a.fixedPitch=!1;a.builtInEncoding&&function adjustType1ToUnicode(e,t){if(e.isInternalFont)return;if(e.hasIncludedToUnicodeMap)return;if(t===e.defaultEncoding)return;if(e.toUnicode instanceof IdentityToUnicodeMap)return;const a=[],n=mn();for(const s in t){if(e.hasEncoding&&(e.baseEncodingName||void 0!==e.differences[s]))continue;const r=getUnicodeForGlyph(t[s],n);-1!==r&&(a[s]=String.fromCharCode(r))}a.length>0&&e.toUnicode.amend(a)}(a,a.builtInEncoding);let s=1;t instanceof CFFFont&&(s=t.numGlyphs-1);const r=t.getGlyphMapping(a);let i=null,o=r,l=null;if(!a.cssFontInfo){i=adjustMapping(r,t.hasGlyphId.bind(t),s,this.toUnicode);this.toFontChar=i.toFontChar;o=i.charCodeToGlyphId;l=i.toUnicodeExtraMap}const f=t.numGlyphs;function getCharCodes(e,t){let a=null;for(const n in e)t===e[n]&&(a||=[]).push(0|n);return a}function createCharCode(e,t){for(const a in e)if(t===e[a])return 0|a;i.charCodeToGlyphId[i.nextAvailableFontCharCode]=t;return i.nextAvailableFontCharCode++}const c=t.seacs;if(i&&c?.length){const e=a.fontMatrix||n,s=t.getCharset(),o=Object.create(null);for(let t in c){t|=0;const a=c[t],n=fn[a[2]],l=fn[a[3]],f=s.indexOf(n),h=s.indexOf(l);if(f<0||h<0)continue;const u={x:a[0]*e[0]+a[1]*e[2]+e[4],y:a[0]*e[1]+a[1]*e[3]+e[5]},m=getCharCodes(r,t);if(m)for(const e of m){const t=i.charCodeToGlyphId,a=createCharCode(t,f),n=createCharCode(t,h);o[e]={baseFontCharCode:a,accentFontCharCode:n,accentOffset:u}}}a.seacMap=o}const h=a.fontMatrix?1/Math.max(...a.fontMatrix.slice(0,4).map(Math.abs)):1e3,u=new OpenTypeFileBuilder("OTTO");u.addTable("CFF ",t.data);u.addTable("OS/2",createOS2Table(a,o));u.addTable("cmap",createCmapTable(o,l,f));u.addTable("head",function fontTableHead(){const e=[0,0,0,0,158,11,126,39],t=new TrueTypeTableBuilder({exactLength:54});t.setArray([0,1,0,0]);t.setArray([0,0,16,0]);t.skip(4);t.setArray([95,15,60,245]);t.skip(2);t.setSafeInt16(h);t.setArray(e);t.setArray(e);t.skip(2);t.setSafeInt16(a.descent);t.setArray([15,255]);t.setSafeInt16(a.ascent);t.setInt16(a.italicAngle?2:0);t.setArray([0,17]);t.skip(6);return t.data}());u.addTable("hhea",function fontTableHhea(){const e=new TrueTypeTableBuilder({exactLength:36});e.setArray([0,1,0,0]);e.setSafeInt16(a.ascent);e.setSafeInt16(a.descent);e.skip(2);e.setArray([255,255]);e.skip(6);e.setSafeInt16(a.capHeight);e.setSafeInt16(Math.tan(a.italicAngle)*a.xHeight);e.skip(12);e.setInt16(f);return e.data}());u.addTable("hmtx",function fontTableHmtx(){const e=t.charstrings,a=t.cff?.widths??null,n=new TrueTypeTableBuilder({exactLength:4*f});n.skip(4);for(let t=1,s=f;t=65520&&e<=65535?0:e>=62976&&e<=63743?dn()[e]||e:173===e?45:e}(a)}this.isType3Font&&(s=a);let c=null;if(this.seacMap?.[e]){f=!0;const t=this.seacMap[e];a=t.baseFontCharCode;c={fontChar:String.fromCodePoint(t.accentFontCharCode),offset:t.accentOffset}}let h="";"number"==typeof a&&(a<=1114111?h=String.fromCodePoint(a):warn(`charToGlyph - invalid fontCharCode: ${a}`));if(this.missingFile&&this.vertical&&1===h.length){const e=An()[h.charCodeAt(0)];e&&(h=l=String.fromCharCode(e))}r=new fonts_Glyph(e,h,l,c,n,o,s,t,f);this.#ne.set(e,r);return r}charsToGlyphs(e){let t=this.#ae.get(e);if(t)return t;t=[];if(this.cMap){const a=Object.create(null),n=e.length;let s=0;for(;st.length%2==1,n=this.toUnicode instanceof IdentityToUnicodeMap?e=>this.toUnicode.charCodeOf(e):e=>this.toUnicode.charCodeOf(String.fromCodePoint(e));for(let s=0,r=e.length;s55295&&(r<57344||r>65533)&&s++;if(this.toUnicode){const e=n(r);if(-1!==e){if(hasCurrentBufErrors()){t.push(a.join(""));a.length=0}for(let t=(this.cMap?this.cMap.getCharCodeLength(e):1)-1;t>=0;t--)a.push(String.fromCharCode(e>>8*t&255));continue}}if(!hasCurrentBufErrors()){t.push(a.join(""));a.length=0}a.push(String.fromCodePoint(r))}t.push(a.join(""));return t}}class ErrorFont{constructor(e){this.error=e;this.loadedName="g_font_error";this.missingFile=!0}charsToGlyphs(){return[]}encodeString(e){return[e]}exportData(){return{error:this.error}}}const os=[1.3877,1,1,1,.97801,.92482,.89552,.91133,.81988,.97566,.98152,.93548,.93548,1.2798,.85284,.92794,1,.96134,1.54657,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.82845,.82845,.85284,.85284,.85284,.75859,.92138,.83908,.7762,.73293,.87289,.73133,.7514,.81921,.87356,.95958,.59526,.75727,.69225,1.04924,.9121,.86943,.79795,.88198,.77958,.70864,.81055,.90399,.88653,.96017,.82577,.77892,.78257,.97507,1.54657,.97507,.85284,.89552,.90176,.88762,.8785,.75241,.8785,.90518,.95015,.77618,.8785,.88401,.91916,.86304,.88401,.91488,.8785,.8801,.8785,.8785,.91343,.7173,1.04106,.8785,.85075,.95794,.82616,.85162,.79492,.88331,1.69808,.88331,.85284,.97801,.89552,.91133,.89552,.91133,1.7801,.89552,1.24487,1.13254,1.12401,.96839,.85284,.68787,.70645,.85592,.90747,1.01466,1.0088,.90323,1,1.07463,1,.91056,.75806,1.19118,.96839,.78864,.82845,.84133,.75859,.83908,.83908,.83908,.83908,.83908,.83908,.77539,.73293,.73133,.73133,.73133,.73133,.95958,.95958,.95958,.95958,.88506,.9121,.86943,.86943,.86943,.86943,.86943,.85284,.87508,.90399,.90399,.90399,.90399,.77892,.79795,.90807,.88762,.88762,.88762,.88762,.88762,.88762,.8715,.75241,.90518,.90518,.90518,.90518,.88401,.88401,.88401,.88401,.8785,.8785,.8801,.8801,.8801,.8801,.8801,.90747,.89049,.8785,.8785,.8785,.8785,.85162,.8785,.85162,.83908,.88762,.83908,.88762,.83908,.88762,.73293,.75241,.73293,.75241,.73293,.75241,.73293,.75241,.87289,.83016,.88506,.93125,.73133,.90518,.73133,.90518,.73133,.90518,.73133,.90518,.73133,.90518,.81921,.77618,.81921,.77618,.81921,.77618,1,1,.87356,.8785,.91075,.89608,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.76229,.90167,.59526,.91916,1,1,.86304,.69225,.88401,1,1,.70424,.79468,.91926,.88175,.70823,.94903,.9121,.8785,1,1,.9121,.8785,.87802,.88656,.8785,.86943,.8801,.86943,.8801,.86943,.8801,.87402,.89291,.77958,.91343,1,1,.77958,.91343,.70864,.7173,.70864,.7173,.70864,.7173,.70864,.7173,1,1,.81055,.75841,.81055,1.06452,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.90399,.8785,.96017,.95794,.77892,.85162,.77892,.78257,.79492,.78257,.79492,.78257,.79492,.9297,.56892,.83908,.88762,.77539,.8715,.87508,.89049,1,1,.81055,1.04106,1.20528,1.20528,1,1.15543,.70674,.98387,.94721,1.33431,1.45894,.95161,1.06303,.83908,.80352,.57184,.6965,.56289,.82001,.56029,.81235,1.02988,.83908,.7762,.68156,.80367,.73133,.78257,.87356,.86943,.95958,.75727,.89019,1.04924,.9121,.7648,.86943,.87356,.79795,.78275,.81055,.77892,.9762,.82577,.99819,.84896,.95958,.77892,.96108,1.01407,.89049,1.02988,.94211,.96108,.8936,.84021,.87842,.96399,.79109,.89049,1.00813,1.02988,.86077,.87445,.92099,.84723,.86513,.8801,.75638,.85714,.78216,.79586,.87965,.94211,.97747,.78287,.97926,.84971,1.02988,.94211,.8801,.94211,.84971,.73133,1,1,1,1,1,1,1,1,1,1,1,1,.90264,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.90518,1,1,1,1,1,1,1,1,1,1,1,1,.90548,1,1,1,1,1,1,.96017,.95794,.96017,.95794,.96017,.95794,.77892,.85162,1,1,.89552,.90527,1,.90363,.92794,.92794,.92794,.92794,.87012,.87012,.87012,.89552,.89552,1.42259,.71143,1.06152,1,1,1.03372,1.03372,.97171,1.4956,2.2807,.93835,.83406,.91133,.84107,.91133,1,1,1,.72021,1,1.23108,.83489,.88525,.88525,.81499,.90527,1.81055,.90527,1.81055,1.31006,1.53711,.94434,1.08696,1,.95018,.77192,.85284,.90747,1.17534,.69825,.9716,1.37077,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.08004,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,.90727,.90727,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],ls={lineHeight:1.2207,lineGap:.2207},fs=[1.3877,1,1,1,.97801,.92482,.89552,.91133,.81988,.97566,.98152,.93548,.93548,1.2798,.85284,.92794,1,.96134,1.56239,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.82845,.82845,.85284,.85284,.85284,.75859,.92138,.83908,.7762,.71805,.87289,.73133,.7514,.81921,.87356,.95958,.59526,.75727,.69225,1.04924,.90872,.85938,.79795,.87068,.77958,.69766,.81055,.90399,.88653,.96068,.82577,.77892,.78257,.97507,1.529,.97507,.85284,.89552,.90176,.94908,.86411,.74012,.86411,.88323,.95015,.86411,.86331,.88401,.91916,.86304,.88401,.9039,.86331,.86331,.86411,.86411,.90464,.70852,1.04106,.86331,.84372,.95794,.82616,.84548,.79492,.88331,1.69808,.88331,.85284,.97801,.89552,.91133,.89552,.91133,1.7801,.89552,1.24487,1.13254,1.19129,.96839,.85284,.68787,.70645,.85592,.90747,1.01466,1.0088,.90323,1,1.07463,1,.91056,.75806,1.19118,.96839,.78864,.82845,.84133,.75859,.83908,.83908,.83908,.83908,.83908,.83908,.77539,.71805,.73133,.73133,.73133,.73133,.95958,.95958,.95958,.95958,.88506,.90872,.85938,.85938,.85938,.85938,.85938,.85284,.87068,.90399,.90399,.90399,.90399,.77892,.79795,.90807,.94908,.94908,.94908,.94908,.94908,.94908,.85887,.74012,.88323,.88323,.88323,.88323,.88401,.88401,.88401,.88401,.8785,.86331,.86331,.86331,.86331,.86331,.86331,.90747,.89049,.86331,.86331,.86331,.86331,.84548,.86411,.84548,.83908,.94908,.83908,.94908,.83908,.94908,.71805,.74012,.71805,.74012,.71805,.74012,.71805,.74012,.87289,.79538,.88506,.92726,.73133,.88323,.73133,.88323,.73133,.88323,.73133,.88323,.73133,.88323,.81921,.86411,.81921,.86411,.81921,.86411,1,1,.87356,.86331,.91075,.8777,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.95958,.88401,.76467,.90167,.59526,.91916,1,1,.86304,.69225,.88401,1,1,.70424,.77312,.91926,.88175,.70823,.94903,.90872,.86331,1,1,.90872,.86331,.86906,.88116,.86331,.85938,.86331,.85938,.86331,.85938,.86331,.87402,.86549,.77958,.90464,1,1,.77958,.90464,.69766,.70852,.69766,.70852,.69766,.70852,.69766,.70852,1,1,.81055,.75841,.81055,1.06452,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.90399,.86331,.96068,.95794,.77892,.84548,.77892,.78257,.79492,.78257,.79492,.78257,.79492,.9297,.56892,.83908,.94908,.77539,.85887,.87068,.89049,1,1,.81055,1.04106,1.20528,1.20528,1,1.15543,.70088,.98387,.94721,1.33431,1.45894,.95161,1.48387,.83908,.80352,.57118,.6965,.56347,.79179,.55853,.80346,1.02988,.83908,.7762,.67174,.86036,.73133,.78257,.87356,.86441,.95958,.75727,.89019,1.04924,.90872,.74889,.85938,.87891,.79795,.7957,.81055,.77892,.97447,.82577,.97466,.87179,.95958,.77892,.94252,.95612,.8753,1.02988,.92733,.94252,.87411,.84021,.8728,.95612,.74081,.8753,1.02189,1.02988,.84814,.87445,.91822,.84723,.85668,.86331,.81344,.87581,.76422,.82046,.96057,.92733,.99375,.78022,.95452,.86015,1.02988,.92733,.86331,.92733,.86015,.73133,1,1,1,1,1,1,1,1,1,1,1,1,.90631,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.88323,1,1,1,1,1,1,1,1,1,1,1,1,.85174,1,1,1,1,1,1,.96068,.95794,.96068,.95794,.96068,.95794,.77892,.84548,1,1,.89552,.90527,1,.90363,.92794,.92794,.92794,.89807,.87012,.87012,.87012,.89552,.89552,1.42259,.71094,1.06152,1,1,1.03372,1.03372,.97171,1.4956,2.2807,.92972,.83406,.91133,.83326,.91133,1,1,1,.72021,1,1.23108,.83489,.88525,.88525,.81499,.90616,1.81055,.90527,1.81055,1.3107,1.53711,.94434,1.08696,1,.95018,.77192,.85284,.90747,1.17534,.69825,.9716,1.37077,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.08004,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,.90727,.90727,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],cs={lineHeight:1.2207,lineGap:.2207},hs=[1.3877,1,1,1,1.17223,1.1293,.89552,.91133,.80395,1.02269,1.15601,.91056,.91056,1.2798,.85284,.89807,1,.90861,1.39543,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.96309,.96309,.85284,.85284,.85284,.83319,.88071,.8675,.81552,.72346,.85193,.73206,.7522,.81105,.86275,.90685,.6377,.77892,.75593,1.02638,.89249,.84118,.77452,.85374,.75186,.67789,.79776,.88844,.85066,.94309,.77818,.7306,.76659,1.10369,1.38313,1.10369,1.06139,.89552,.8739,.9245,.9245,.83203,.9245,.85865,1.09842,.9245,.9245,1.03297,1.07692,.90918,1.03297,.94959,.9245,.92274,.9245,.9245,1.02933,.77832,1.20562,.9245,.8916,.98986,.86621,.89453,.79004,.94152,1.77256,.94152,.85284,.97801,.89552,.91133,.89552,.91133,1.91729,.89552,1.17889,1.13254,1.16359,.92098,.85284,.68787,.71353,.84737,.90747,1.0088,1.0044,.87683,1,1.09091,1,.92229,.739,1.15642,.92098,.76288,.80504,.80972,.75859,.8675,.8675,.8675,.8675,.8675,.8675,.76318,.72346,.73206,.73206,.73206,.73206,.90685,.90685,.90685,.90685,.86477,.89249,.84118,.84118,.84118,.84118,.84118,.85284,.84557,.88844,.88844,.88844,.88844,.7306,.77452,.86331,.9245,.9245,.9245,.9245,.9245,.9245,.84843,.83203,.85865,.85865,.85865,.85865,.82601,.82601,.82601,.82601,.94469,.9245,.92274,.92274,.92274,.92274,.92274,.90747,.86651,.9245,.9245,.9245,.9245,.89453,.9245,.89453,.8675,.9245,.8675,.9245,.8675,.9245,.72346,.83203,.72346,.83203,.72346,.83203,.72346,.83203,.85193,.8875,.86477,.99034,.73206,.85865,.73206,.85865,.73206,.85865,.73206,.85865,.73206,.85865,.81105,.9245,.81105,.9245,.81105,.9245,1,1,.86275,.9245,.90872,.93591,.90685,.82601,.90685,.82601,.90685,.82601,.90685,1.03297,.90685,.82601,.77896,1.05611,.6377,1.07692,1,1,.90918,.75593,1.03297,1,1,.76032,.9375,.98156,.93407,.77261,1.11429,.89249,.9245,1,1,.89249,.9245,.92534,.86698,.9245,.84118,.92274,.84118,.92274,.84118,.92274,.8667,.86291,.75186,1.02933,1,1,.75186,1.02933,.67789,.77832,.67789,.77832,.67789,.77832,.67789,.77832,1,1,.79776,.97655,.79776,1.23023,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.88844,.9245,.94309,.98986,.7306,.89453,.7306,.76659,.79004,.76659,.79004,.76659,.79004,1.09231,.54873,.8675,.9245,.76318,.84843,.84557,.86651,1,1,.79776,1.20562,1.18622,1.18622,1,1.1437,.67009,.96334,.93695,1.35191,1.40909,.95161,1.48387,.8675,.90861,.6192,.7363,.64824,.82411,.56321,.85696,1.23516,.8675,.81552,.7286,.84134,.73206,.76659,.86275,.84369,.90685,.77892,.85871,1.02638,.89249,.75828,.84118,.85984,.77452,.76466,.79776,.7306,.90782,.77818,.903,.87291,.90685,.7306,.99058,1.03667,.94635,1.23516,.9849,.99058,.92393,.8916,.942,1.03667,.75026,.94635,1.0297,1.23516,.90918,.94048,.98217,.89746,.84153,.92274,.82507,.88832,.84438,.88178,1.03525,.9849,1.00225,.78086,.97248,.89404,1.23516,.9849,.92274,.9849,.89404,.73206,1,1,1,1,1,1,1,1,1,1,1,1,.89693,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.85865,1,1,1,1,1,1,1,1,1,1,1,1,.90933,1,1,1,1,1,1,.94309,.98986,.94309,.98986,.94309,.98986,.7306,.89453,1,1,.89552,.90527,1,.90186,1.12308,1.12308,1.12308,1.12308,1.2566,1.2566,1.2566,.89552,.89552,1.42259,.68994,1.03809,1,1,1.0176,1.0176,1.11523,1.4956,2.01462,.97858,.82616,.91133,.83437,.91133,1,1,1,.70508,1,1.23108,.79801,.84426,.84426,.774,.90572,1.81055,.90749,1.81055,1.28809,1.55469,.94434,1.07806,1,.97094,.7589,.85284,.90747,1.19658,.69825,.97622,1.33512,.90747,.90747,.85284,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.0336,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,1.05859,1.05859,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],us={lineHeight:1.2207,lineGap:.2207},ms=[1.3877,1,1,1,1.17223,1.1293,.89552,.91133,.80395,1.02269,1.15601,.91056,.91056,1.2798,.85284,.89807,1,.90861,1.39016,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.91133,.96309,.96309,.85284,.85284,.85284,.83319,.88071,.8675,.81552,.73834,.85193,.73206,.7522,.81105,.86275,.90685,.6377,.77892,.75593,1.02638,.89385,.85122,.77452,.86503,.75186,.68887,.79776,.88844,.85066,.94258,.77818,.7306,.76659,1.10369,1.39016,1.10369,1.06139,.89552,.8739,.86128,.94469,.8457,.94469,.89464,1.09842,.84636,.94469,1.03297,1.07692,.90918,1.03297,.95897,.94469,.9482,.94469,.94469,1.04692,.78223,1.20562,.94469,.90332,.98986,.86621,.90527,.79004,.94152,1.77256,.94152,.85284,.97801,.89552,.91133,.89552,.91133,1.91729,.89552,1.17889,1.13254,1.08707,.92098,.85284,.68787,.71353,.84737,.90747,1.0088,1.0044,.87683,1,1.09091,1,.92229,.739,1.15642,.92098,.76288,.80504,.80972,.75859,.8675,.8675,.8675,.8675,.8675,.8675,.76318,.73834,.73206,.73206,.73206,.73206,.90685,.90685,.90685,.90685,.86477,.89385,.85122,.85122,.85122,.85122,.85122,.85284,.85311,.88844,.88844,.88844,.88844,.7306,.77452,.86331,.86128,.86128,.86128,.86128,.86128,.86128,.8693,.8457,.89464,.89464,.89464,.89464,.82601,.82601,.82601,.82601,.94469,.94469,.9482,.9482,.9482,.9482,.9482,.90747,.86651,.94469,.94469,.94469,.94469,.90527,.94469,.90527,.8675,.86128,.8675,.86128,.8675,.86128,.73834,.8457,.73834,.8457,.73834,.8457,.73834,.8457,.85193,.92454,.86477,.9921,.73206,.89464,.73206,.89464,.73206,.89464,.73206,.89464,.73206,.89464,.81105,.84636,.81105,.84636,.81105,.84636,1,1,.86275,.94469,.90872,.95786,.90685,.82601,.90685,.82601,.90685,.82601,.90685,1.03297,.90685,.82601,.77741,1.05611,.6377,1.07692,1,1,.90918,.75593,1.03297,1,1,.76032,.90452,.98156,1.11842,.77261,1.11429,.89385,.94469,1,1,.89385,.94469,.95877,.86901,.94469,.85122,.9482,.85122,.9482,.85122,.9482,.8667,.90016,.75186,1.04692,1,1,.75186,1.04692,.68887,.78223,.68887,.78223,.68887,.78223,.68887,.78223,1,1,.79776,.92188,.79776,1.23023,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.88844,.94469,.94258,.98986,.7306,.90527,.7306,.76659,.79004,.76659,.79004,.76659,.79004,1.09231,.54873,.8675,.86128,.76318,.8693,.85311,.86651,1,1,.79776,1.20562,1.18622,1.18622,1,1.1437,.67742,.96334,.93695,1.35191,1.40909,.95161,1.48387,.86686,.90861,.62267,.74359,.65649,.85498,.56963,.88254,1.23516,.8675,.81552,.75443,.84503,.73206,.76659,.86275,.85122,.90685,.77892,.85746,1.02638,.89385,.75657,.85122,.86275,.77452,.74171,.79776,.7306,.95165,.77818,.89772,.88831,.90685,.7306,.98142,1.02191,.96576,1.23516,.99018,.98142,.9236,.89258,.94035,1.02191,.78848,.96576,.9561,1.23516,.90918,.92578,.95424,.89746,.83969,.9482,.80113,.89442,.85208,.86155,.98022,.99018,1.00452,.81209,.99247,.89181,1.23516,.99018,.9482,.99018,.89181,.73206,1,1,1,1,1,1,1,1,1,1,1,1,.88844,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.89464,1,1,1,1,1,1,1,1,1,1,1,1,.96766,1,1,1,1,1,1,.94258,.98986,.94258,.98986,.94258,.98986,.7306,.90527,1,1,.89552,.90527,1,.90186,1.12308,1.12308,1.12308,1.12308,1.2566,1.2566,1.2566,.89552,.89552,1.42259,.69043,1.03809,1,1,1.0176,1.0176,1.11523,1.4956,2.01462,.99331,.82616,.91133,.84286,.91133,1,1,1,.70508,1,1.23108,.79801,.84426,.84426,.774,.90527,1.81055,.90527,1.81055,1.28809,1.55469,.94434,1.07806,1,.97094,.7589,.85284,.90747,1.19658,.69825,.97622,1.33512,.90747,.90747,.85356,.90747,.90747,1.44947,.85284,.8941,.8941,.70572,.8,.70572,.70572,.70572,.70572,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.99862,.99862,1,1,1,1,1,1.0336,.91027,1,1,1,.99862,1,1,1,1,1,1,1,1,1,1,1,1,1.05859,1.05859,1,1,1,1.07185,.99413,.96334,1.08065,1,1,1,1,1,1,1,1,1,1,1],ps={lineHeight:1.2207,lineGap:.2207},ds=[.76116,1,1,1.0006,.99998,.99974,.99973,.99973,.99982,.99977,1.00087,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99998,1,1.00003,1.00003,1.00003,1.00026,.9999,.99977,.99977,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,.99973,.99977,1.00026,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,.99998,1.0006,.99998,1.00003,.99973,.99998,.99973,1.00026,.99973,1.00026,.99973,.99998,1.00026,1.00026,1.0006,1.0006,.99973,1.0006,.99982,1.00026,1.00026,1.00026,1.00026,.99959,.99973,.99998,1.00026,.99973,1.00022,.99973,.99973,1,.99959,1.00077,.99959,1.00003,.99998,.99973,.99973,.99973,.99973,1.00077,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.99973,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,.99977,.99977,.99977,.99977,.99977,.99977,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,.99973,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.06409,1.00026,1.00026,1.00026,1.00026,1.00026,.99973,1.00026,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,1.03374,.99977,1.00026,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,.99977,1.00026,.99977,1.00026,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.00042,.99973,.99973,1.0006,.99977,.99973,.99973,1.00026,1.0006,1.00026,1.0006,1.00026,1.03828,1.00026,.99999,1.00026,1.0006,.99977,1.00026,.99977,1.00026,.99977,1.00026,.9993,.9998,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1,1.00016,.99977,.99959,.99977,.99959,.99977,.99959,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00026,.99998,1.00026,.8121,1.00026,.99998,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,1.00016,1.00022,1.00001,.99973,1.00001,1.00026,1,1.00026,1,1.00026,1,1.0006,.99973,.99977,.99973,1,.99982,1.00022,1.00026,1.00001,.99973,1.00026,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,1.00034,.99977,1,.99997,1.00026,1.00078,1.00036,.99973,1.00013,1.0006,.99977,.99977,.99988,.85148,1.00001,1.00026,.99977,1.00022,1.0006,.99977,1.00001,.99999,.99977,1.00069,1.00022,.99977,1.00001,.99984,1.00026,1.00001,1.00024,1.00001,.9999,1,1.0006,1.00001,1.00041,.99962,1.00026,1.0006,.99995,1.00041,.99942,.99973,.99927,1.00082,.99902,1.00026,1.00087,1.0006,1.00069,.99973,.99867,.99973,.9993,1.00026,1.00049,1.00056,1,.99988,.99935,.99995,.99954,1.00055,.99945,1.00032,1.0006,.99995,1.00026,.99995,1.00032,1.00001,1.00008,.99971,1.00019,.9994,1.00001,1.0006,1.00044,.99973,1.00023,1.00047,1,.99942,.99561,.99989,1.00035,.99977,1.00035,.99977,1.00019,.99944,1.00001,1.00021,.99926,1.00035,1.00035,.99942,1.00048,.99999,.99977,1.00022,1.00035,1.00001,.99977,1.00026,.99989,1.00057,1.00001,.99936,1.00052,1.00012,.99996,1.00043,1,1.00035,.9994,.99976,1.00035,.99973,1.00052,1.00041,1.00119,1.00037,.99973,1.00002,.99986,1.00041,1.00041,.99902,.9996,1.00034,.99999,1.00026,.99999,1.00026,.99973,1.00052,.99973,1,.99973,1.00041,1.00075,.9994,1.0003,.99999,1,1.00041,.99955,1,.99915,.99973,.99973,1.00026,1.00119,.99955,.99973,1.0006,.99911,1.0006,1.00026,.99972,1.00026,.99902,1.00041,.99973,.99999,1,1,1.00038,1.0005,1.00016,1.00022,1.00016,1.00022,1.00016,1.00022,1.00001,.99973,1,1,.99973,1,1,.99955,1.0006,1.0006,1.0006,1.0006,1,1,1,.99973,.99973,.99972,1,1,1.00106,.99999,.99998,.99998,.99999,.99998,1.66475,1,.99973,.99973,1.00023,.99973,.99971,1.00047,1.00023,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1,1,1,1,1,1,1,.99972,1,1.20985,1.39713,1.00003,1.00031,1.00015,1,.99561,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.99972,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],gs={lineHeight:1.2,lineGap:.2},bs=[.76116,1,1,1.0006,.99998,.99974,.99973,.99973,.99982,.99977,1.00087,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99998,1,1.00003,1.00003,1.00003,1.00026,.9999,.99977,.99977,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,.99973,.99977,1.00026,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,.99998,1.0006,.99998,1.00003,.99973,.99998,.99973,1.00026,.99973,1.00026,.99973,.99998,1.00026,1.00026,1.0006,1.0006,.99973,1.0006,.99982,1.00026,1.00026,1.00026,1.00026,.99959,.99973,.99998,1.00026,.99973,1.00022,.99973,.99973,1,.99959,1.00077,.99959,1.00003,.99998,.99973,.99973,.99973,.99973,1.00077,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.99973,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,.99977,.99977,.99977,.99977,.99977,.99977,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,.99973,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.00026,1.06409,1.00026,1.00026,1.00026,1.00026,1.00026,.99973,1.00026,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,1.0044,.99977,1.00026,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,.99977,1.00026,.99977,1.00026,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99971,.99973,.99973,1.0006,.99977,.99973,.99973,1.00026,1.0006,1.00026,1.0006,1.00026,1.01011,1.00026,.99999,1.00026,1.0006,.99977,1.00026,.99977,1.00026,.99977,1.00026,.9993,.9998,1.00026,1.00022,1.00026,1.00022,1.00026,1.00022,1.00026,1,1.00016,.99977,.99959,.99977,.99959,.99977,.99959,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00026,.99998,1.00026,.8121,1.00026,.99998,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,.99977,1.00026,1.00016,1.00022,1.00001,.99973,1.00001,1.00026,1,1.00026,1,1.00026,1,1.0006,.99973,.99977,.99973,1,.99982,1.00022,1.00026,1.00001,.99973,1.00026,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99977,1,1,1.00026,.99969,.99972,.99981,.9998,1.0006,.99977,.99977,1.00022,.91155,1.00001,1.00026,.99977,1.00022,1.0006,.99977,1.00001,.99999,.99977,.99966,1.00022,1.00032,1.00001,.99944,1.00026,1.00001,.99968,1.00001,1.00047,1,1.0006,1.00001,.99981,1.00101,1.00026,1.0006,.99948,.99981,1.00064,.99973,.99942,1.00101,1.00061,1.00026,1.00069,1.0006,1.00014,.99973,1.01322,.99973,1.00065,1.00026,1.00012,.99923,1,1.00064,1.00076,.99948,1.00055,1.00063,1.00007,.99943,1.0006,.99948,1.00026,.99948,.99943,1.00001,1.00001,1.00029,1.00038,1.00035,1.00001,1.0006,1.0006,.99973,.99978,1.00001,1.00057,.99989,.99967,.99964,.99967,.99977,.99999,.99977,1.00038,.99977,1.00001,.99973,1.00066,.99967,.99967,1.00041,.99998,.99999,.99977,1.00022,.99967,1.00001,.99977,1.00026,.99964,1.00031,1.00001,.99999,.99999,1,1.00023,1,1,.99999,1.00035,1.00001,.99999,.99973,.99977,.99999,1.00058,.99973,.99973,.99955,.9995,1.00026,1.00026,1.00032,.99989,1.00034,.99999,1.00026,1.00026,1.00026,.99973,.45998,.99973,1.00026,.99973,1.00001,.99999,.99982,.99994,.99996,1,1.00042,1.00044,1.00029,1.00023,.99973,.99973,1.00026,.99949,1.00002,.99973,1.0006,1.0006,1.0006,.99975,1.00026,1.00026,1.00032,.98685,.99973,1.00026,1,1,.99966,1.00044,1.00016,1.00022,1.00016,1.00022,1.00016,1.00022,1.00001,.99973,1,1,.99973,1,1,.99955,1.0006,1.0006,1.0006,1.0006,1,1,1,.99973,.99973,.99972,1,1,1.00106,.99999,.99998,.99998,.99999,.99998,1.66475,1,.99973,.99973,1,.99973,.99971,.99978,1,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1.00098,1,1,1,1.00049,1,1,.99972,1,1.20985,1.39713,1.00003,1.00031,1.00015,1,.99561,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.99972,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],ws={lineHeight:1.35,lineGap:.2},js=[.76116,1,1,1.0006,1.0006,1.00006,.99973,.99973,.99982,1.00001,1.00043,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.0006,1,1.00003,1.00003,1.00003,.99973,.99987,1.00001,1.00001,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,1,1.00001,.99973,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,1.0006,1.0006,1.0006,.99949,.99973,.99998,.99973,.99973,1,.99973,.99973,1.0006,.99973,.99973,.99924,.99924,1,.99924,.99999,.99973,.99973,.99973,.99973,.99998,1,1.0006,.99973,1,.99977,1,1,1,1.00005,1.0009,1.00005,1.00003,.99998,.99973,.99973,.99973,.99973,1.0009,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.9998,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,1.00001,1.00001,1.00001,1.00001,1.00001,1.00001,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,1,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.06409,1.00026,.99973,.99973,.99973,.99973,1,.99973,1,1.00001,.99973,1.00001,.99973,1.00001,.99973,.99977,1,.99977,1,.99977,1,.99977,1,.99977,1.0288,.99977,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,.99977,.99973,.99977,.99973,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99924,1.0006,1.0006,.99946,1.00034,1,.99924,1.00001,1,1,.99973,.99924,.99973,.99924,.99973,1.06311,.99973,1.00024,.99973,.99924,.99977,.99973,.99977,.99973,.99977,.99973,1.00041,.9998,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1,1.00016,.99977,.99998,.99977,.99998,.99977,.99998,1.00001,1,1.00001,1,1.00001,1,1.00001,1,1.00026,1.0006,1.00026,.89547,1.00026,1.0006,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,1.00016,.99977,1.00001,1,1.00001,1.00026,1,1.00026,1,1.00026,1,.99924,.99973,1.00001,.99973,1,.99982,1.00022,1.00026,1.00001,1,1.00026,1.0006,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,1.00001,1,1.00054,.99977,1.00084,1.00007,.99973,1.00013,.99924,1.00001,1.00001,.99945,.91221,1.00001,1.00026,.99977,1.00022,1.0006,1.00001,1.00001,.99999,.99977,.99933,1.00022,1.00054,1.00001,1.00065,1.00026,1.00001,1.0001,1.00001,1.00052,1,1.0006,1.00001,.99945,.99897,.99968,.99924,1.00036,.99945,.99949,1,1.0006,.99897,.99918,.99968,.99911,.99924,1,.99962,1.01487,1,1.0005,.99973,1.00012,1.00043,1,.99995,.99994,1.00036,.99947,1.00019,1.00063,1.00025,.99924,1.00036,.99973,1.00036,1.00025,1.00001,1.00001,1.00027,1.0001,1.00068,1.00001,1.0006,1.0006,1,1.00008,.99957,.99972,.9994,.99954,.99975,1.00051,1.00001,1.00019,1.00001,1.0001,.99986,1.00001,1.00001,1.00038,.99954,.99954,.9994,1.00066,.99999,.99977,1.00022,1.00054,1.00001,.99977,1.00026,.99975,1.0001,1.00001,.99993,.9995,.99955,1.00016,.99978,.99974,1.00019,1.00022,.99955,1.00053,.99973,1.00089,1.00005,.99967,1.00048,.99973,1.00002,1.00034,.99973,.99973,.99964,1.00006,1.00066,.99947,.99973,.98894,.99973,1,.44898,1,.99946,1,1.00039,1.00082,.99991,.99991,.99985,1.00022,1.00023,1.00061,1.00006,.99966,.99973,.99973,.99973,1.00019,1.0008,1,.99924,.99924,.99924,.99983,1.00044,.99973,.99964,.98332,1,.99973,1,1,.99962,.99895,1.00016,.99977,1.00016,.99977,1.00016,.99977,1.00001,1,1,1,.99973,1,1,.99955,.99924,.99924,.99924,.99924,.99998,.99998,.99998,.99973,.99973,.99972,1,1,1.00267,.99999,.99998,.99998,1,.99998,1.66475,1,.99973,.99973,1.00023,.99973,1.00423,.99925,.99999,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1.00049,1,1.00245,1,1,1,1,.96329,1,1.20985,1.39713,1.00003,.8254,1.00015,1,1.00035,1.00027,1.00031,1.00031,1.00003,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.95317,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,.99998,.99998,.99998,.99998,1,1,1,1,1,1,1,1,1,1,1],ks={lineHeight:1.35,lineGap:.2},ys=[.76116,1,1,1.0006,1.0006,1.00006,.99973,.99973,.99982,1.00001,1.00043,.99998,.99998,.99959,1.00003,1.0006,.99998,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.0006,1,1.00003,1.00003,1.00003,.99973,.99987,1.00001,1.00001,.99977,.99977,1.00001,1.00026,1.00022,.99977,1.0006,1,1.00001,.99973,.99999,.99977,1.00022,1.00001,1.00022,.99977,1.00001,1.00026,.99977,1.00001,1.00016,1.00001,1.00001,1.00026,1.0006,1.0006,1.0006,.99949,.99973,.99998,.99973,.99973,1,.99973,.99973,1.0006,.99973,.99973,.99924,.99924,1,.99924,.99999,.99973,.99973,.99973,.99973,.99998,1,1.0006,.99973,1,.99977,1,1,1,1.00005,1.0009,1.00005,1.00003,.99998,.99973,.99973,.99973,.99973,1.0009,.99973,.99998,1.00025,.99968,.99973,1.00003,1.00025,.60299,1.00024,1.06409,1,1,.99998,1,.9998,1.0006,.99998,1,.99936,.99973,1.00002,1.00002,1.00002,1.00026,1.00001,1.00001,1.00001,1.00001,1.00001,1.00001,1,.99977,1.00001,1.00001,1.00001,1.00001,1.0006,1.0006,1.0006,1.0006,.99977,.99977,1.00022,1.00022,1.00022,1.00022,1.00022,1.00003,1.00022,.99977,.99977,.99977,.99977,1.00001,1.00001,1.00026,.99973,.99973,.99973,.99973,.99973,.99973,.99982,1,.99973,.99973,.99973,.99973,1.0006,1.0006,1.0006,1.0006,.99973,.99973,.99973,.99973,.99973,.99973,.99973,1.06409,1.00026,.99973,.99973,.99973,.99973,1,.99973,1,1.00001,.99973,1.00001,.99973,1.00001,.99973,.99977,1,.99977,1,.99977,1,.99977,1,.99977,1.04596,.99977,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00001,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,.99977,.99973,.99977,.99973,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,1.0006,.99924,1.0006,1.0006,1.00019,1.00034,1,.99924,1.00001,1,1,.99973,.99924,.99973,.99924,.99973,1.02572,.99973,1.00005,.99973,.99924,.99977,.99973,.99977,.99973,.99977,.99973,.99999,.9998,.99973,1.00022,.99973,1.00022,.99973,1.00022,.99973,1,1.00016,.99977,.99998,.99977,.99998,.99977,.99998,1.00001,1,1.00001,1,1.00001,1,1.00001,1,1.00026,1.0006,1.00026,.84533,1.00026,1.0006,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,.99977,.99973,1.00016,.99977,1.00001,1,1.00001,1.00026,1,1.00026,1,1.00026,1,.99924,.99973,1.00001,.99973,1,.99982,1.00022,1.00026,1.00001,1,1.00026,1.0006,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99998,.99928,1,.99977,1.00013,1.00055,.99947,.99945,.99941,.99924,1.00001,1.00001,1.0004,.91621,1.00001,1.00026,.99977,1.00022,1.0006,1.00001,1.00005,.99999,.99977,1.00015,1.00022,.99977,1.00001,.99973,1.00026,1.00001,1.00019,1.00001,.99946,1,1.0006,1.00001,.99978,1.00045,.99973,.99924,1.00023,.99978,.99966,1,1.00065,1.00045,1.00019,.99973,.99973,.99924,1,1,.96499,1,1.00055,.99973,1.00008,1.00027,1,.9997,.99995,1.00023,.99933,1.00019,1.00015,1.00031,.99924,1.00023,.99973,1.00023,1.00031,1.00001,.99928,1.00029,1.00092,1.00035,1.00001,1.0006,1.0006,1,.99988,.99975,1,1.00082,.99561,.9996,1.00035,1.00001,.99962,1.00001,1.00092,.99964,1.00001,.99963,.99999,1.00035,1.00035,1.00082,.99962,.99999,.99977,1.00022,1.00035,1.00001,.99977,1.00026,.9996,.99967,1.00001,1.00034,1.00074,1.00054,1.00053,1.00063,.99971,.99962,1.00035,.99975,.99977,.99973,1.00043,.99953,1.0007,.99915,.99973,1.00008,.99892,1.00073,1.00073,1.00114,.99915,1.00073,.99955,.99973,1.00092,.99973,1,.99998,1,1.0003,1,1.00043,1.00001,.99969,1.0003,1,1.00035,1.00001,.9995,1,1.00092,.99973,.99973,.99973,1.0007,.9995,1,.99924,1.0006,.99924,.99972,1.00062,.99973,1.00114,1.00073,1,.99955,1,1,1.00047,.99968,1.00016,.99977,1.00016,.99977,1.00016,.99977,1.00001,1,1,1,.99973,1,1,.99955,.99924,.99924,.99924,.99924,.99998,.99998,.99998,.99973,.99973,.99972,1,1,1.00267,.99999,.99998,.99998,1,.99998,1.66475,1,.99973,.99973,1.00023,.99973,.99971,.99925,1.00023,1,.99991,.99984,1.00002,1.00002,1.00002,1.00002,1,1,1,1,1,1,1,.96329,1,1.20985,1.39713,1.00003,.8254,1.00015,1,1.00035,1.00027,1.00031,1.00031,.99915,1.00031,1.00031,.99999,1.00003,.99999,.99999,1.41144,1.6,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.41144,1.40579,1.40579,1.36625,.99999,1,.99861,.99861,1,1.00026,1.00026,1.00026,1.00026,.95317,.99999,.99999,.99999,.99999,1.40483,1,.99977,1.00054,1,1,.99953,.99962,1.00042,.9995,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],qs={lineHeight:1.2,lineGap:.2},vs=[365,0,333,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,333,556,556,556,556,280,556,333,737,370,556,584,737,552,400,549,333,333,333,576,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,549,611,611,611,611,611,556,611,556,722,556,722,556,722,556,722,556,722,556,722,556,722,556,722,719,722,611,667,556,667,556,667,556,667,556,667,556,778,611,778,611,778,611,778,611,722,611,722,611,278,278,278,278,278,278,278,278,278,278,785,556,556,278,722,556,556,611,278,611,278,611,385,611,479,611,278,722,611,722,611,722,611,708,723,611,778,611,778,611,778,611,1e3,944,722,389,722,389,722,389,667,556,667,556,667,556,667,556,611,333,611,479,611,333,722,611,722,611,722,611,722,611,722,611,722,611,944,778,667,556,667,611,500,611,500,611,500,278,556,722,556,1e3,889,778,611,667,556,611,333,333,333,333,333,333,333,333,333,333,333,465,722,333,853,906,474,825,927,838,278,722,722,601,719,667,611,722,778,278,722,667,833,722,644,778,722,667,600,611,667,821,667,809,802,278,667,615,451,611,278,582,615,610,556,606,475,460,611,541,278,558,556,612,556,445,611,766,619,520,684,446,582,715,576,753,845,278,582,611,582,845,667,669,885,567,711,667,278,276,556,1094,1062,875,610,722,622,719,722,719,722,567,712,667,904,626,719,719,610,702,833,722,778,719,667,722,611,622,854,667,730,703,1005,1019,870,979,719,711,1031,719,556,618,615,417,635,556,709,497,615,615,500,635,740,604,611,604,611,556,490,556,875,556,615,581,833,844,729,854,615,552,854,583,556,556,611,417,552,556,278,281,278,969,906,611,500,615,556,604,778,611,487,447,944,778,944,778,944,778,667,556,333,333,556,1e3,1e3,552,278,278,278,278,500,500,500,556,556,350,1e3,1e3,240,479,333,333,604,333,167,396,556,556,1094,556,885,489,1115,1e3,768,600,834,834,834,834,1e3,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,722,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,611,611,333,333,333,333,333,333,333,333,222,222,333,333,333,333,333,333,333,333],Ss=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],As=[365,0,333,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,333,556,556,556,556,280,556,333,737,370,556,584,737,552,400,549,333,333,333,576,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,549,611,611,611,611,611,556,611,556,722,556,722,556,722,556,722,556,722,556,722,556,722,556,722,740,722,611,667,556,667,556,667,556,667,556,667,556,778,611,778,611,778,611,778,611,722,611,722,611,278,278,278,278,278,278,278,278,278,278,782,556,556,278,722,556,556,611,278,611,278,611,396,611,479,611,278,722,611,722,611,722,611,708,723,611,778,611,778,611,778,611,1e3,944,722,389,722,389,722,389,667,556,667,556,667,556,667,556,611,333,611,479,611,333,722,611,722,611,722,611,722,611,722,611,722,611,944,778,667,556,667,611,500,611,500,611,500,278,556,722,556,1e3,889,778,611,667,556,611,333,333,333,333,333,333,333,333,333,333,333,333,722,333,854,906,473,844,930,847,278,722,722,610,671,667,611,722,778,278,722,667,833,722,657,778,718,667,590,611,667,822,667,829,781,278,667,620,479,611,278,591,620,621,556,610,479,492,611,558,278,566,556,603,556,450,611,712,605,532,664,409,591,704,578,773,834,278,591,611,591,834,667,667,886,614,719,667,278,278,556,1094,1042,854,622,719,677,719,722,708,722,614,722,667,927,643,719,719,615,687,833,722,778,719,667,722,611,677,781,667,729,708,979,989,854,1e3,708,719,1042,729,556,619,604,534,618,556,736,510,611,611,507,622,740,604,611,611,611,556,889,556,885,556,646,583,889,935,707,854,594,552,865,589,556,556,611,469,563,556,278,278,278,969,906,611,507,619,556,611,778,611,575,467,944,778,944,778,944,778,667,556,333,333,556,1e3,1e3,552,278,278,278,278,500,500,500,556,556,350,1e3,1e3,240,479,333,333,604,333,167,396,556,556,1104,556,885,516,1146,1e3,768,600,834,834,834,834,999,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,722,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,611,611,333,333,333,333,333,333,333,333,222,222,333,333,333,333,333,333,333,333],xs=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Cs=[365,0,333,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,333,556,556,556,556,260,556,333,737,370,556,584,737,552,400,549,333,333,333,576,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,549,611,556,556,556,556,500,556,500,667,556,667,556,667,556,722,500,722,500,722,500,722,500,722,625,722,556,667,556,667,556,667,556,667,556,667,556,778,556,778,556,778,556,778,556,722,556,722,556,278,278,278,278,278,278,278,222,278,278,733,444,500,222,667,500,500,556,222,556,222,556,281,556,400,556,222,722,556,722,556,722,556,615,723,556,778,556,778,556,778,556,1e3,944,722,333,722,333,722,333,667,500,667,500,667,500,667,500,611,278,611,354,611,278,722,556,722,556,722,556,722,556,722,556,722,556,944,722,667,500,667,611,500,611,500,611,500,222,556,667,556,1e3,889,778,611,667,500,611,278,333,333,333,333,333,333,333,333,333,333,333,667,278,789,846,389,794,865,775,222,667,667,570,671,667,611,722,778,278,667,667,833,722,648,778,725,667,600,611,667,837,667,831,761,278,667,570,439,555,222,550,570,571,500,556,439,463,555,542,222,500,492,548,500,447,556,670,573,486,603,374,550,652,546,728,779,222,550,556,550,779,667,667,843,544,708,667,278,278,500,1066,982,844,589,715,639,724,667,651,667,544,704,667,917,614,715,715,589,686,833,722,778,725,667,722,611,639,795,667,727,673,920,923,805,886,651,694,1022,682,556,562,522,493,553,556,688,465,556,556,472,564,686,550,556,556,556,500,833,500,835,500,572,518,830,851,621,736,526,492,752,534,556,556,556,378,496,500,222,222,222,910,828,556,472,565,500,556,778,556,492,339,944,722,944,722,944,722,667,500,333,333,556,1e3,1e3,552,222,222,222,222,333,333,333,556,556,350,1e3,1e3,188,354,333,333,500,333,167,365,556,556,1094,556,885,323,1083,1e3,768,600,834,834,834,834,1e3,500,998,500,1e3,500,500,494,612,823,713,584,549,713,979,719,274,549,549,584,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,500,500,333,333,333,333,333,333,333,333,222,222,294,294,324,324,316,328,398,285],Is=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Fs=[365,0,333,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,333,556,556,556,556,260,556,333,737,370,556,584,737,552,400,549,333,333,333,576,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1e3,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,549,611,556,556,556,556,500,556,500,667,556,667,556,667,556,722,500,722,500,722,500,722,500,722,615,722,556,667,556,667,556,667,556,667,556,667,556,778,556,778,556,778,556,778,556,722,556,722,556,278,278,278,278,278,278,278,222,278,278,735,444,500,222,667,500,500,556,222,556,222,556,292,556,334,556,222,722,556,722,556,722,556,604,723,556,778,556,778,556,778,556,1e3,944,722,333,722,333,722,333,667,500,667,500,667,500,667,500,611,278,611,375,611,278,722,556,722,556,722,556,722,556,722,556,722,556,944,722,667,500,667,611,500,611,500,611,500,222,556,667,556,1e3,889,778,611,667,500,611,278,333,333,333,333,333,333,333,333,333,333,333,667,278,784,838,384,774,855,752,222,667,667,551,668,667,611,722,778,278,667,668,833,722,650,778,722,667,618,611,667,798,667,835,748,278,667,578,446,556,222,547,578,575,500,557,446,441,556,556,222,500,500,576,500,448,556,690,569,482,617,395,547,648,525,713,781,222,547,556,547,781,667,667,865,542,719,667,278,278,500,1057,1010,854,583,722,635,719,667,656,667,542,677,667,923,604,719,719,583,656,833,722,778,719,667,722,611,635,760,667,740,667,917,938,792,885,656,719,1010,722,556,573,531,365,583,556,669,458,559,559,438,583,688,552,556,542,556,500,458,500,823,500,573,521,802,823,625,719,521,510,750,542,556,556,556,365,510,500,222,278,222,906,812,556,438,559,500,552,778,556,489,411,944,722,944,722,944,722,667,500,333,333,556,1e3,1e3,552,222,222,222,222,333,333,333,556,556,350,1e3,1e3,188,354,333,333,500,333,167,365,556,556,1094,556,885,323,1073,1e3,768,600,834,834,834,834,1e3,500,1e3,500,1e3,500,500,494,612,823,713,584,549,713,979,719,274,549,549,583,549,549,604,584,604,604,708,625,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,729,604,604,354,354,1e3,990,990,990,990,494,604,604,604,604,354,1021,1052,917,750,750,531,656,594,510,500,750,750,500,500,333,333,333,333,333,333,333,333,222,222,294,294,324,324,316,328,398,285],Ts=[-1,-1,-1,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,402,506,507,508,509,510,511,536,537,538,539,710,711,713,728,729,730,731,732,733,900,901,902,903,904,905,906,908,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1138,1139,1168,1169,7808,7809,7810,7811,7812,7813,7922,7923,8208,8209,8211,8212,8213,8215,8216,8217,8218,8219,8220,8221,8222,8224,8225,8226,8230,8240,8242,8243,8249,8250,8252,8254,8260,8319,8355,8356,8359,8364,8453,8467,8470,8482,8486,8494,8539,8540,8541,8542,8592,8593,8594,8595,8596,8597,8616,8706,8710,8719,8721,8722,8730,8734,8735,8745,8747,8776,8800,8801,8804,8805,8962,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,9516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,9633,9642,9643,9644,9650,9658,9660,9668,9674,9675,9679,9688,9689,9702,9786,9787,9788,9792,9794,9824,9827,9829,9830,9834,9835,9836,61441,61442,61445,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],Os=[1.36898,1,1,.72706,.80479,.83734,.98894,.99793,.9897,.93884,.86209,.94292,.94292,1.16661,1.02058,.93582,.96694,.93582,1.19137,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.99793,.78076,.78076,1.02058,1.02058,1.02058,.72851,.78966,.90838,.83637,.82391,.96376,.80061,.86275,.8768,.95407,1.0258,.73901,.85022,.83655,1.0156,.95546,.92179,.87107,.92179,.82114,.8096,.89713,.94438,.95353,.94083,.91905,.90406,.9446,.94292,1.18777,.94292,1.02058,.89903,.90088,.94938,.97898,.81093,.97571,.94938,1.024,.9577,.95933,.98621,1.0474,.97455,.98981,.9672,.95933,.9446,.97898,.97407,.97646,.78036,1.10208,.95442,.95298,.97579,.9332,.94039,.938,.80687,1.01149,.80687,1.02058,.80479,.99793,.99793,.99793,.99793,1.01149,1.00872,.90088,.91882,1.0213,.8361,1.02058,.62295,.54324,.89022,1.08595,1,1,.90088,1,.97455,.93582,.90088,1,1.05686,.8361,.99642,.99642,.99642,.72851,.90838,.90838,.90838,.90838,.90838,.90838,.868,.82391,.80061,.80061,.80061,.80061,1.0258,1.0258,1.0258,1.0258,.97484,.95546,.92179,.92179,.92179,.92179,.92179,1.02058,.92179,.94438,.94438,.94438,.94438,.90406,.86958,.98225,.94938,.94938,.94938,.94938,.94938,.94938,.9031,.81093,.94938,.94938,.94938,.94938,.98621,.98621,.98621,.98621,.93969,.95933,.9446,.9446,.9446,.9446,.9446,1.08595,.9446,.95442,.95442,.95442,.95442,.94039,.97898,.94039,.90838,.94938,.90838,.94938,.90838,.94938,.82391,.81093,.82391,.81093,.82391,.81093,.82391,.81093,.96376,.84313,.97484,.97571,.80061,.94938,.80061,.94938,.80061,.94938,.80061,.94938,.80061,.94938,.8768,.9577,.8768,.9577,.8768,.9577,1,1,.95407,.95933,.97069,.95933,1.0258,.98621,1.0258,.98621,1.0258,.98621,1.0258,.98621,1.0258,.98621,.887,1.01591,.73901,1.0474,1,1,.97455,.83655,.98981,1,1,.83655,.73977,.83655,.73903,.84638,1.033,.95546,.95933,1,1,.95546,.95933,.8271,.95417,.95933,.92179,.9446,.92179,.9446,.92179,.9446,.936,.91964,.82114,.97646,1,1,.82114,.97646,.8096,.78036,.8096,.78036,1,1,.8096,.78036,1,1,.89713,.77452,.89713,1.10208,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94438,.95442,.94083,.97579,.90406,.94039,.90406,.9446,.938,.9446,.938,.9446,.938,1,.99793,.90838,.94938,.868,.9031,.92179,.9446,1,1,.89713,1.10208,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90989,.9358,.91945,.83181,.75261,.87992,.82976,.96034,.83689,.97268,1.0078,.90838,.83637,.8019,.90157,.80061,.9446,.95407,.92436,1.0258,.85022,.97153,1.0156,.95546,.89192,.92179,.92361,.87107,.96318,.89713,.93704,.95638,.91905,.91709,.92796,1.0258,.93704,.94836,1.0373,.95933,1.0078,.95871,.94836,.96174,.92601,.9498,.98607,.95776,.95933,1.05453,1.0078,.98275,.9314,.95617,.91701,1.05993,.9446,.78367,.9553,1,.86832,1.0128,.95871,.99394,.87548,.96361,.86774,1.0078,.95871,.9446,.95871,.86774,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.94083,.97579,.94083,.97579,.94083,.97579,.90406,.94039,.96694,1,.89903,1,1,1,.93582,.93582,.93582,1,.908,.908,.918,.94219,.94219,.96544,1,1.285,1,1,.81079,.81079,1,1,.74854,1,1,1,1,.99793,1,1,1,.65,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.17173,1,.80535,.76169,1.02058,1.0732,1.05486,1,1,1.30692,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.16161,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Rs={lineHeight:1.2,lineGap:.2},Hs=[1.36898,1,1,.66227,.80779,.81625,.97276,.97276,.97733,.92222,.83266,.94292,.94292,1.16148,1.02058,.93582,.96694,.93582,1.17337,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.97276,.78076,.78076,1.02058,1.02058,1.02058,.71541,.76813,.85576,.80591,.80729,.94299,.77512,.83655,.86523,.92222,.98621,.71743,.81698,.79726,.98558,.92222,.90637,.83809,.90637,.80729,.76463,.86275,.90699,.91605,.9154,.85308,.85458,.90531,.94292,1.21296,.94292,1.02058,.89903,1.18616,.99613,.91677,.78216,.91677,.90083,.98796,.9135,.92168,.95381,.98981,.95298,.95381,.93459,.92168,.91513,.92004,.91677,.95077,.748,1.04502,.91677,.92061,.94236,.89544,.89364,.9,.80687,.8578,.80687,1.02058,.80779,.97276,.97276,.97276,.97276,.8578,.99973,1.18616,.91339,1.08074,.82891,1.02058,.55509,.71526,.89022,1.08595,1,1,1.18616,1,.96736,.93582,1.18616,1,1.04864,.82711,.99043,.99043,.99043,.71541,.85576,.85576,.85576,.85576,.85576,.85576,.845,.80729,.77512,.77512,.77512,.77512,.98621,.98621,.98621,.98621,.95961,.92222,.90637,.90637,.90637,.90637,.90637,1.02058,.90251,.90699,.90699,.90699,.90699,.85458,.83659,.94951,.99613,.99613,.99613,.99613,.99613,.99613,.85811,.78216,.90083,.90083,.90083,.90083,.95381,.95381,.95381,.95381,.9135,.92168,.91513,.91513,.91513,.91513,.91513,1.08595,.91677,.91677,.91677,.91677,.91677,.89364,.92332,.89364,.85576,.99613,.85576,.99613,.85576,.99613,.80729,.78216,.80729,.78216,.80729,.78216,.80729,.78216,.94299,.76783,.95961,.91677,.77512,.90083,.77512,.90083,.77512,.90083,.77512,.90083,.77512,.90083,.86523,.9135,.86523,.9135,.86523,.9135,1,1,.92222,.92168,.92222,.92168,.98621,.95381,.98621,.95381,.98621,.95381,.98621,.95381,.98621,.95381,.86036,.97096,.71743,.98981,1,1,.95298,.79726,.95381,1,1,.79726,.6894,.79726,.74321,.81691,1.0006,.92222,.92168,1,1,.92222,.92168,.79464,.92098,.92168,.90637,.91513,.90637,.91513,.90637,.91513,.909,.87514,.80729,.95077,1,1,.80729,.95077,.76463,.748,.76463,.748,1,1,.76463,.748,1,1,.86275,.72651,.86275,1.04502,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.90699,.91677,.9154,.94236,.85458,.89364,.85458,.90531,.9,.90531,.9,.90531,.9,1,.97276,.85576,.99613,.845,.85811,.90251,.91677,1,1,.86275,1.04502,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.18616,1.00899,1.30628,.85576,.80178,.66862,.7927,.69323,.88127,.72459,.89711,.95381,.85576,.80591,.7805,.94729,.77512,.90531,.92222,.90637,.98621,.81698,.92655,.98558,.92222,.85359,.90637,.90976,.83809,.94523,.86275,.83509,.93157,.85308,.83392,.92346,.98621,.83509,.92886,.91324,.92168,.95381,.90646,.92886,.90557,.86847,.90276,.91324,.86842,.92168,.99531,.95381,.9224,.85408,.92699,.86847,1.0051,.91513,.80487,.93481,1,.88159,1.05214,.90646,.97355,.81539,.89398,.85923,.95381,.90646,.91513,.90646,.85923,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.9154,.94236,.9154,.94236,.9154,.94236,.85458,.89364,.96694,1,.89903,1,1,1,.91782,.91782,.91782,1,.896,.896,.896,.9332,.9332,.95973,1,1.26,1,1,.80479,.80178,1,1,.85633,1,1,1,1,.97276,1,1,1,.698,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.14542,1,.79199,.78694,1.02058,1.03493,1.05486,1,1,1.23026,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.20006,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Bs={lineHeight:1.2,lineGap:.2},Ds=[1.36898,1,1,.65507,.84943,.85639,.88465,.88465,.86936,.88307,.86948,.85283,.85283,1.06383,1.02058,.75945,.9219,.75945,1.17337,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.88465,.75945,.75945,1.02058,1.02058,1.02058,.69046,.70926,.85158,.77812,.76852,.89591,.70466,.76125,.80094,.86822,.83864,.728,.77212,.79475,.93637,.87514,.8588,.76013,.8588,.72421,.69866,.77598,.85991,.80811,.87832,.78112,.77512,.8562,1.0222,1.18417,1.0222,1.27014,.89903,1.15012,.93859,.94399,.846,.94399,.81453,1.0186,.94219,.96017,1.03075,1.02175,.912,1.03075,.96998,.96017,.93859,.94399,.94399,.95493,.746,1.12658,.94578,.91,.979,.882,.882,.83,.85034,.83537,.85034,1.02058,.70869,.88465,.88465,.88465,.88465,.83537,.90083,1.15012,.9161,.94565,.73541,1.02058,.53609,.69353,.79519,1.08595,1,1,1.15012,1,.91974,.75945,1.15012,1,.9446,.73361,.9005,.9005,.9005,.62864,.85158,.85158,.85158,.85158,.85158,.85158,.773,.76852,.70466,.70466,.70466,.70466,.83864,.83864,.83864,.83864,.90561,.87514,.8588,.8588,.8588,.8588,.8588,1.02058,.85751,.85991,.85991,.85991,.85991,.77512,.76013,.88075,.93859,.93859,.93859,.93859,.93859,.93859,.8075,.846,.81453,.81453,.81453,.81453,.82424,.82424,.82424,.82424,.9278,.96017,.93859,.93859,.93859,.93859,.93859,1.08595,.8562,.94578,.94578,.94578,.94578,.882,.94578,.882,.85158,.93859,.85158,.93859,.85158,.93859,.76852,.846,.76852,.846,.76852,.846,.76852,.846,.89591,.8544,.90561,.94399,.70466,.81453,.70466,.81453,.70466,.81453,.70466,.81453,.70466,.81453,.80094,.94219,.80094,.94219,.80094,.94219,1,1,.86822,.96017,.86822,.96017,.83864,.82424,.83864,.82424,.83864,.82424,.83864,1.03075,.83864,.82424,.81402,1.02738,.728,1.02175,1,1,.912,.79475,1.03075,1,1,.79475,.83911,.79475,.66266,.80553,1.06676,.87514,.96017,1,1,.87514,.96017,.86865,.87396,.96017,.8588,.93859,.8588,.93859,.8588,.93859,.867,.84759,.72421,.95493,1,1,.72421,.95493,.69866,.746,.69866,.746,1,1,.69866,.746,1,1,.77598,.88417,.77598,1.12658,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.85991,.94578,.87832,.979,.77512,.882,.77512,.8562,.83,.8562,.83,.8562,.83,1,.88465,.85158,.93859,.773,.8075,.85751,.8562,1,1,.77598,1.12658,1.15012,1.15012,1.15012,1.15012,1.15012,1.15313,1.15012,1.15012,1.15012,1.08106,1.03901,.85158,.77025,.62264,.7646,.65351,.86026,.69461,.89947,1.03075,.85158,.77812,.76449,.88836,.70466,.8562,.86822,.8588,.83864,.77212,.85308,.93637,.87514,.82352,.8588,.85701,.76013,.89058,.77598,.8156,.82565,.78112,.77899,.89386,.83864,.8156,.9486,.92388,.96186,1.03075,.91123,.9486,.93298,.878,.93942,.92388,.84596,.96186,.95119,1.03075,.922,.88787,.95829,.88,.93559,.93859,.78815,.93758,1,.89217,1.03737,.91123,.93969,.77487,.85769,.86799,1.03075,.91123,.93859,.91123,.86799,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.87832,.979,.87832,.979,.87832,.979,.77512,.882,.9219,1,.89903,1,1,1,.87321,.87321,.87321,1,1.027,1.027,1.027,.86847,.86847,.79121,1,1.124,1,1,.73572,.73572,1,1,.85034,1,1,1,1,.88465,1,1,1,.669,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.04828,1,.74948,.75187,1.02058,.98391,1.02119,1,1,1.06233,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.05233,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Ms={lineHeight:1.2,lineGap:.2},Ns=[1.36898,1,1,.76305,.82784,.94935,.89364,.92241,.89073,.90706,.98472,.85283,.85283,1.0664,1.02058,.74505,.9219,.74505,1.23456,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.92241,.74505,.74505,1.02058,1.02058,1.02058,.73002,.72601,.91755,.8126,.80314,.92222,.73764,.79726,.83051,.90284,.86023,.74,.8126,.84869,.96518,.91115,.8858,.79761,.8858,.74498,.73914,.81363,.89591,.83659,.89633,.85608,.8111,.90531,1.0222,1.22736,1.0222,1.27014,.89903,.90088,.86667,1.0231,.896,1.01411,.90083,1.05099,1.00512,.99793,1.05326,1.09377,.938,1.06226,1.00119,.99793,.98714,1.0231,1.01231,.98196,.792,1.19137,.99074,.962,1.01915,.926,.942,.856,.85034,.92006,.85034,1.02058,.69067,.92241,.92241,.92241,.92241,.92006,.9332,.90088,.91882,.93484,.75339,1.02058,.56866,.54324,.79519,1.08595,1,1,.90088,1,.95325,.74505,.90088,1,.97198,.75339,.91009,.91009,.91009,.66466,.91755,.91755,.91755,.91755,.91755,.91755,.788,.80314,.73764,.73764,.73764,.73764,.86023,.86023,.86023,.86023,.92915,.91115,.8858,.8858,.8858,.8858,.8858,1.02058,.8858,.89591,.89591,.89591,.89591,.8111,.79611,.89713,.86667,.86667,.86667,.86667,.86667,.86667,.86936,.896,.90083,.90083,.90083,.90083,.84224,.84224,.84224,.84224,.97276,.99793,.98714,.98714,.98714,.98714,.98714,1.08595,.89876,.99074,.99074,.99074,.99074,.942,1.0231,.942,.91755,.86667,.91755,.86667,.91755,.86667,.80314,.896,.80314,.896,.80314,.896,.80314,.896,.92222,.93372,.92915,1.01411,.73764,.90083,.73764,.90083,.73764,.90083,.73764,.90083,.73764,.90083,.83051,1.00512,.83051,1.00512,.83051,1.00512,1,1,.90284,.99793,.90976,.99793,.86023,.84224,.86023,.84224,.86023,.84224,.86023,1.05326,.86023,.84224,.82873,1.07469,.74,1.09377,1,1,.938,.84869,1.06226,1,1,.84869,.83704,.84869,.81441,.85588,1.08927,.91115,.99793,1,1,.91115,.99793,.91887,.90991,.99793,.8858,.98714,.8858,.98714,.8858,.98714,.894,.91434,.74498,.98196,1,1,.74498,.98196,.73914,.792,.73914,.792,1,1,.73914,.792,1,1,.81363,.904,.81363,1.19137,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89591,.99074,.89633,1.01915,.8111,.942,.8111,.90531,.856,.90531,.856,.90531,.856,1,.92241,.91755,.86667,.788,.86936,.8858,.89876,1,1,.81363,1.19137,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90088,.90388,1.03901,.92138,.78105,.7154,.86169,.80513,.94007,.82528,.98612,1.06226,.91755,.8126,.81884,.92819,.73764,.90531,.90284,.8858,.86023,.8126,.91172,.96518,.91115,.83089,.8858,.87791,.79761,.89297,.81363,.88157,.89992,.85608,.81992,.94307,.86023,.88157,.95308,.98699,.99793,1.06226,.95817,.95308,.97358,.928,.98088,.98699,.92761,.99793,.96017,1.06226,.986,.944,.95978,.938,.96705,.98714,.80442,.98972,1,.89762,1.04552,.95817,.99007,.87064,.91879,.88888,1.06226,.95817,.98714,.95817,.88888,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.89633,1.01915,.89633,1.01915,.89633,1.01915,.8111,.942,.9219,1,.89903,1,1,1,.93173,.93173,.93173,1,1.06304,1.06304,1.06904,.89903,.89903,.80549,1,1.156,1,1,.76575,.76575,1,1,.72458,1,1,1,1,.92241,1,1,1,.619,1,1.36145,1,1,1,1,1,1,1,1,1,1,1,1.07257,1,.74705,.71119,1.02058,1.024,1.02119,1,1,1.1536,1.08595,1.08595,1,1.08595,1.08595,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.05638,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Es={lineHeight:1.2,lineGap:.2},_s=[1.76738,1,1,.99297,.9824,1.04016,1.06497,1.03424,.97529,1.17647,1.23203,1.1085,1.1085,1.16939,1.2107,.9754,1.21408,.9754,1.59578,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,1.03424,.81378,.81378,1.2107,1.2107,1.2107,.71703,.97847,.97363,.88776,.8641,1.02096,.79795,.85132,.914,1.06085,1.1406,.8007,.89858,.83693,1.14889,1.09398,.97489,.92094,.97489,.90399,.84041,.95923,1.00135,1,1.06467,.98243,.90996,.99361,1.1085,1.56942,1.1085,1.2107,.74627,.94282,.96752,1.01519,.86304,1.01359,.97278,1.15103,1.01359,.98561,1.02285,1.02285,1.00527,1.02285,1.0302,.99041,1.0008,1.01519,1.01359,1.02258,.79104,1.16862,.99041,.97454,1.02511,.99298,.96752,.95801,.94856,1.16579,.94856,1.2107,.9824,1.03424,1.03424,1,1.03424,1.16579,.8727,1.3871,1.18622,1.10818,1.04478,1.2107,1.18622,.75155,.94994,1.28826,1.21408,1.21408,.91056,1,.91572,.9754,.64663,1.18328,1.24866,1.04478,1.14169,1.15749,1.17389,.71703,.97363,.97363,.97363,.97363,.97363,.97363,.93506,.8641,.79795,.79795,.79795,.79795,1.1406,1.1406,1.1406,1.1406,1.02096,1.09398,.97426,.97426,.97426,.97426,.97426,1.2107,.97489,1.00135,1.00135,1.00135,1.00135,.90996,.92094,1.02798,.96752,.96752,.96752,.96752,.96752,.96752,.93136,.86304,.97278,.97278,.97278,.97278,1.02285,1.02285,1.02285,1.02285,.97122,.99041,1,1,1,1,1,1.28826,1.0008,.99041,.99041,.99041,.99041,.96752,1.01519,.96752,.97363,.96752,.97363,.96752,.97363,.96752,.8641,.86304,.8641,.86304,.8641,.86304,.8641,.86304,1.02096,1.03057,1.02096,1.03517,.79795,.97278,.79795,.97278,.79795,.97278,.79795,.97278,.79795,.97278,.914,1.01359,.914,1.01359,.914,1.01359,1,1,1.06085,.98561,1.06085,1.00879,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,1.1406,1.02285,.97138,1.08692,.8007,1.02285,1,1,1.00527,.83693,1.02285,1,1,.83693,.9455,.83693,.90418,.83693,1.13005,1.09398,.99041,1,1,1.09398,.99041,.96692,1.09251,.99041,.97489,1.0008,.97489,1.0008,.97489,1.0008,.93994,.97931,.90399,1.02258,1,1,.90399,1.02258,.84041,.79104,.84041,.79104,.84041,.79104,.84041,.79104,1,1,.95923,1.07034,.95923,1.16862,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.00135,.99041,1.06467,1.02511,.90996,.96752,.90996,.99361,.95801,.99361,.95801,.99361,.95801,1.07733,1.03424,.97363,.96752,.93506,.93136,.97489,1.0008,1,1,.95923,1.16862,1.15103,1.15103,1.01173,1.03959,.75953,.81378,.79912,1.15103,1.21994,.95161,.87815,1.01149,.81525,.7676,.98167,1.01134,1.02546,.84097,1.03089,1.18102,.97363,.88776,.85134,.97826,.79795,.99361,1.06085,.97489,1.1406,.89858,1.0388,1.14889,1.09398,.86039,.97489,1.0595,.92094,.94793,.95923,.90996,.99346,.98243,1.02112,.95493,1.1406,.90996,1.03574,1.02597,1.0008,1.18102,1.06628,1.03574,1.0192,1.01932,1.00886,.97531,1.0106,1.0008,1.13189,1.18102,1.02277,.98683,1.0016,.99561,1.07237,1.0008,.90434,.99921,.93803,.8965,1.23085,1.06628,1.04983,.96268,1.0499,.98439,1.18102,1.06628,1.0008,1.06628,.98439,.79795,1,1,1,1,1,1,1,1,1,1,1,1,1.09466,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.97278,1,1,1,1,1,1,1,1,1,1,1,1,1.02065,1,1,1,1,1,1,1.06467,1.02511,1.06467,1.02511,1.06467,1.02511,.90996,.96752,1,1.21408,.89903,1,1,.75155,1.04394,1.04394,1.04394,1.04394,.98633,.98633,.98633,.73047,.73047,1.20642,.91211,1.25635,1.222,1.02956,1.03372,1.03372,.96039,1.24633,1,1.12454,.93503,1.03424,1.19687,1.03424,1,1,1,.771,1,1,1.15749,1.15749,1.15749,1.10948,.86279,.94434,.86279,.94434,.86182,1,1,1.16897,1,.96085,.90137,1.2107,1.18416,1.13973,.69825,.9716,2.10339,1.29004,1.29004,1.21172,1.29004,1.29004,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18874,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.09193,1.09193,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],zs={lineHeight:1.33008,lineGap:0},Ls=[1.76738,1,1,.98946,1.03959,1.04016,1.02809,1.036,.97639,1.10953,1.23203,1.11144,1.11144,1.16939,1.21237,.9754,1.21261,.9754,1.59754,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,1.036,.81378,.81378,1.21237,1.21237,1.21237,.73541,.97847,.97363,.89723,.87897,1.0426,.79429,.85292,.91149,1.05815,1.1406,.79631,.90128,.83853,1.04396,1.10615,.97552,.94436,.97552,.88641,.80527,.96083,1.00135,1,1.06777,.9817,.91142,.99361,1.11144,1.57293,1.11144,1.21237,.74627,1.31818,1.06585,.97042,.83055,.97042,.93503,1.1261,.97042,.97922,1.14236,.94552,1.01054,1.14236,1.02471,.97922,.94165,.97042,.97042,1.0276,.78929,1.1261,.97922,.95874,1.02197,.98507,.96752,.97168,.95107,1.16579,.95107,1.21237,1.03959,1.036,1.036,1,1.036,1.16579,.87357,1.31818,1.18754,1.26781,1.05356,1.21237,1.18622,.79487,.94994,1.29004,1.24047,1.24047,1.31818,1,.91484,.9754,1.31818,1.1349,1.24866,1.05356,1.13934,1.15574,1.17389,.73541,.97363,.97363,.97363,.97363,.97363,.97363,.94385,.87897,.79429,.79429,.79429,.79429,1.1406,1.1406,1.1406,1.1406,1.0426,1.10615,.97552,.97552,.97552,.97552,.97552,1.21237,.97552,1.00135,1.00135,1.00135,1.00135,.91142,.94436,.98721,1.06585,1.06585,1.06585,1.06585,1.06585,1.06585,.96705,.83055,.93503,.93503,.93503,.93503,1.14236,1.14236,1.14236,1.14236,.93125,.97922,.94165,.94165,.94165,.94165,.94165,1.29004,.94165,.97922,.97922,.97922,.97922,.96752,.97042,.96752,.97363,1.06585,.97363,1.06585,.97363,1.06585,.87897,.83055,.87897,.83055,.87897,.83055,.87897,.83055,1.0426,1.0033,1.0426,.97042,.79429,.93503,.79429,.93503,.79429,.93503,.79429,.93503,.79429,.93503,.91149,.97042,.91149,.97042,.91149,.97042,1,1,1.05815,.97922,1.05815,.97922,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,1.1406,1.14236,.97441,1.04302,.79631,1.01582,1,1,1.01054,.83853,1.14236,1,1,.83853,1.09125,.83853,.90418,.83853,1.19508,1.10615,.97922,1,1,1.10615,.97922,1.01034,1.10466,.97922,.97552,.94165,.97552,.94165,.97552,.94165,.91602,.91981,.88641,1.0276,1,1,.88641,1.0276,.80527,.78929,.80527,.78929,.80527,.78929,.80527,.78929,1,1,.96083,1.05403,.95923,1.16862,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.00135,.97922,1.06777,1.02197,.91142,.96752,.91142,.99361,.97168,.99361,.97168,.99361,.97168,1.23199,1.036,.97363,1.06585,.94385,.96705,.97552,.94165,1,1,.96083,1.1261,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,1.31818,.95161,1.27126,1.00811,.83284,.77702,.99137,.95253,1.0347,.86142,1.07205,1.14236,.97363,.89723,.86869,1.09818,.79429,.99361,1.05815,.97552,1.1406,.90128,1.06662,1.04396,1.10615,.84918,.97552,1.04694,.94436,.98015,.96083,.91142,1.00356,.9817,1.01945,.98999,1.1406,.91142,1.04961,.9898,1.00639,1.14236,1.07514,1.04961,.99607,1.02897,1.008,.9898,.95134,1.00639,1.11121,1.14236,1.00518,.97981,1.02186,1,1.08578,.94165,.99314,.98387,.93028,.93377,1.35125,1.07514,1.10687,.93491,1.04232,1.00351,1.14236,1.07514,.94165,1.07514,1.00351,.79429,1,1,1,1,1,1,1,1,1,1,1,1,1.09097,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.93503,1,1,1,1,1,1,1,1,1,1,1,1,.96609,1,1,1,1,1,1,1.06777,1.02197,1.06777,1.02197,1.06777,1.02197,.91142,.96752,1,1.21261,.89903,1,1,.75155,1.04745,1.04745,1.04745,1.04394,.98633,.98633,.98633,.72959,.72959,1.20502,.91406,1.26514,1.222,1.02956,1.03372,1.03372,.96039,1.24633,1,1.09125,.93327,1.03336,1.16541,1.036,1,1,1,.771,1,1,1.15574,1.15574,1.15574,1.15574,.86364,.94434,.86279,.94434,.86224,1,1,1.16798,1,.96085,.90068,1.21237,1.18416,1.13904,.69825,.9716,2.10339,1.29004,1.29004,1.21339,1.29004,1.29004,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18775,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.13269,1.13269,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Us={lineHeight:1.33008,lineGap:0},Xs=[1.76738,1,1,.98946,1.14763,1.05365,1.06234,.96927,.92586,1.15373,1.18414,.91349,.91349,1.07403,1.17308,.78383,1.20088,.78383,1.42531,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.78383,.78383,1.17308,1.17308,1.17308,.77349,.94565,.94729,.85944,.88506,.9858,.74817,.80016,.88449,.98039,.95782,.69238,.89898,.83231,.98183,1.03989,.96924,.86237,.96924,.80595,.74524,.86091,.95402,.94143,.98448,.8858,.83089,.93285,1.0949,1.39016,1.0949,1.45994,.74627,1.04839,.97454,.97454,.87207,.97454,.87533,1.06151,.97454,1.00176,1.16484,1.08132,.98047,1.16484,1.02989,1.01054,.96225,.97454,.97454,1.06598,.79004,1.16344,1.00351,.94629,.9973,.91016,.96777,.9043,.91082,.92481,.91082,1.17308,.95748,.96927,.96927,1,.96927,.92481,.80597,1.04839,1.23393,1.1781,.9245,1.17308,1.20808,.63218,.94261,1.24822,1.09971,1.09971,1.04839,1,.85273,.78032,1.04839,1.09971,1.22326,.9245,1.09836,1.13525,1.15222,.70424,.94729,.94729,.94729,.94729,.94729,.94729,.85498,.88506,.74817,.74817,.74817,.74817,.95782,.95782,.95782,.95782,.9858,1.03989,.96924,.96924,.96924,.96924,.96924,1.17308,.96924,.95402,.95402,.95402,.95402,.83089,.86237,.88409,.97454,.97454,.97454,.97454,.97454,.97454,.92916,.87207,.87533,.87533,.87533,.87533,.93146,.93146,.93146,.93146,.93854,1.01054,.96225,.96225,.96225,.96225,.96225,1.24822,.8761,1.00351,1.00351,1.00351,1.00351,.96777,.97454,.96777,.94729,.97454,.94729,.97454,.94729,.97454,.88506,.87207,.88506,.87207,.88506,.87207,.88506,.87207,.9858,.95391,.9858,.97454,.74817,.87533,.74817,.87533,.74817,.87533,.74817,.87533,.74817,.87533,.88449,.97454,.88449,.97454,.88449,.97454,1,1,.98039,1.00176,.98039,1.00176,.95782,.93146,.95782,.93146,.95782,.93146,.95782,1.16484,.95782,.93146,.84421,1.12761,.69238,1.08132,1,1,.98047,.83231,1.16484,1,1,.84723,1.04861,.84723,.78755,.83231,1.23736,1.03989,1.01054,1,1,1.03989,1.01054,.9857,1.03849,1.01054,.96924,.96225,.96924,.96225,.96924,.96225,.92383,.90171,.80595,1.06598,1,1,.80595,1.06598,.74524,.79004,.74524,.79004,.74524,.79004,.74524,.79004,1,1,.86091,1.02759,.85771,1.16344,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.95402,1.00351,.98448,.9973,.83089,.96777,.83089,.93285,.9043,.93285,.9043,.93285,.9043,1.31868,.96927,.94729,.97454,.85498,.92916,.96924,.8761,1,1,.86091,1.16344,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,1.04839,.81965,.81965,.94729,.78032,.71022,.90883,.84171,.99877,.77596,1.05734,1.2,.94729,.85944,.82791,.9607,.74817,.93285,.98039,.96924,.95782,.89898,.98316,.98183,1.03989,.78614,.96924,.97642,.86237,.86075,.86091,.83089,.90082,.8858,.97296,1.01284,.95782,.83089,1.0976,1.04,1.03342,1.2,1.0675,1.0976,.98205,1.03809,1.05097,1.04,.95364,1.03342,1.05401,1.2,1.02148,1.0119,1.04724,1.0127,1.02732,.96225,.8965,.97783,.93574,.94818,1.30679,1.0675,1.11826,.99821,1.0557,1.0326,1.2,1.0675,.96225,1.0675,1.0326,.74817,1,1,1,1,1,1,1,1,1,1,1,1,1.03754,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.87533,1,1,1,1,1,1,1,1,1,1,1,1,.98705,1,1,1,1,1,1,.98448,.9973,.98448,.9973,.98448,.9973,.83089,.96777,1,1.20088,.89903,1,1,.75155,.94945,.94945,.94945,.94945,1.12317,1.12317,1.12317,.67603,.67603,1.15621,.73584,1.21191,1.22135,1.06483,.94868,.94868,.95996,1.24633,1,1.07497,.87709,.96927,1.01473,.96927,1,1,1,.77295,1,1,1.09836,1.09836,1.09836,1.01522,.86321,.94434,.8649,.94434,.86182,1,1,1.083,1,.91578,.86438,1.17308,1.18416,1.14589,.69825,.97622,1.96791,1.24822,1.24822,1.17308,1.24822,1.24822,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.17984,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.10742,1.10742,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],Ws={lineHeight:1.33008,lineGap:0},Ks=[1.76738,1,1,.98594,1.02285,1.10454,1.06234,.96927,.92037,1.19985,1.2046,.90616,.90616,1.07152,1.1714,.78032,1.20088,.78032,1.40246,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.96927,.78032,.78032,1.1714,1.1714,1.1714,.80597,.94084,.96706,.85944,.85734,.97093,.75842,.79936,.88198,.9831,.95782,.71387,.86969,.84636,1.07796,1.03584,.96924,.83968,.96924,.82826,.79649,.85771,.95132,.93119,.98965,.88433,.8287,.93365,1.08612,1.3638,1.08612,1.45786,.74627,.80499,.91484,1.05707,.92383,1.05882,.9403,1.12654,1.05882,1.01756,1.09011,1.09011,.99414,1.09011,1.034,1.01756,1.05356,1.05707,1.05882,1.04399,.84863,1.21968,1.01756,.95801,1.00068,.91797,.96777,.9043,.90351,.92105,.90351,1.1714,.85337,.96927,.96927,.99912,.96927,.92105,.80597,1.2434,1.20808,1.05937,.90957,1.1714,1.20808,.75155,.94261,1.24644,1.09971,1.09971,.84751,1,.85273,.78032,.61584,1.05425,1.17914,.90957,1.08665,1.11593,1.14169,.73381,.96706,.96706,.96706,.96706,.96706,.96706,.86035,.85734,.75842,.75842,.75842,.75842,.95782,.95782,.95782,.95782,.97093,1.03584,.96924,.96924,.96924,.96924,.96924,1.1714,.96924,.95132,.95132,.95132,.95132,.8287,.83968,.89049,.91484,.91484,.91484,.91484,.91484,.91484,.93575,.92383,.9403,.9403,.9403,.9403,.8717,.8717,.8717,.8717,1.00527,1.01756,1.05356,1.05356,1.05356,1.05356,1.05356,1.24644,.95923,1.01756,1.01756,1.01756,1.01756,.96777,1.05707,.96777,.96706,.91484,.96706,.91484,.96706,.91484,.85734,.92383,.85734,.92383,.85734,.92383,.85734,.92383,.97093,1.0969,.97093,1.05882,.75842,.9403,.75842,.9403,.75842,.9403,.75842,.9403,.75842,.9403,.88198,1.05882,.88198,1.05882,.88198,1.05882,1,1,.9831,1.01756,.9831,1.01756,.95782,.8717,.95782,.8717,.95782,.8717,.95782,1.09011,.95782,.8717,.84784,1.11551,.71387,1.09011,1,1,.99414,.84636,1.09011,1,1,.84636,1.0536,.84636,.94298,.84636,1.23297,1.03584,1.01756,1,1,1.03584,1.01756,1.00323,1.03444,1.01756,.96924,1.05356,.96924,1.05356,.96924,1.05356,.93066,.98293,.82826,1.04399,1,1,.82826,1.04399,.79649,.84863,.79649,.84863,.79649,.84863,.79649,.84863,1,1,.85771,1.17318,.85771,1.21968,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.95132,1.01756,.98965,1.00068,.8287,.96777,.8287,.93365,.9043,.93365,.9043,.93365,.9043,1.08571,.96927,.96706,.91484,.86035,.93575,.96924,.95923,1,1,.85771,1.21968,1.11437,1.11437,.93109,.91202,.60411,.84164,.55572,1.01173,.97361,.81818,.81818,.96635,.78032,.72727,.92366,.98601,1.03405,.77968,1.09799,1.2,.96706,.85944,.85638,.96491,.75842,.93365,.9831,.96924,.95782,.86969,.94152,1.07796,1.03584,.78437,.96924,.98715,.83968,.83491,.85771,.8287,.94492,.88433,.9287,1.0098,.95782,.8287,1.0625,.98248,1.03424,1.2,1.01071,1.0625,.95246,1.03809,1.04912,.98248,1.00221,1.03424,1.05443,1.2,1.04785,.99609,1.00169,1.05176,.99346,1.05356,.9087,1.03004,.95542,.93117,1.23362,1.01071,1.07831,1.02512,1.05205,1.03502,1.2,1.01071,1.05356,1.01071,1.03502,.75842,1,1,1,1,1,1,1,1,1,1,1,1,1.03719,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.9403,1,1,1,1,1,1,1,1,1,1,1,1,1.04021,1,1,1,1,1,1,.98965,1.00068,.98965,1.00068,.98965,1.00068,.8287,.96777,1,1.20088,.89903,1,1,.75155,1.03077,1.03077,1.03077,1.03077,1.13196,1.13196,1.13196,.67428,.67428,1.16039,.73291,1.20996,1.22135,1.06483,.94868,.94868,.95996,1.24633,1,1.07497,.87796,.96927,1.01518,.96927,1,1,1,.77295,1,1,1.10539,1.10539,1.11358,1.06967,.86279,.94434,.86279,.94434,.86182,1,1,1.083,1,.91578,.86507,1.1714,1.18416,1.14589,.69825,.97622,1.9697,1.24822,1.24822,1.17238,1.24822,1.24822,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.42603,1,.99862,.99862,1,.87025,.87025,.87025,.87025,1.18083,1.42603,1,1.42603,1.42603,.99862,1,1,1,1,1,1.2886,1.04315,1.15296,1.34163,1,1,1,1.10938,1.10938,1,1,1,1.05425,1.09971,1.09971,1.09971,1,1,1,1,1,1,1,1,1,1,1],Gs={lineHeight:1.33008,lineGap:0},Vs=getLookupTableFactory(function(e){e["MyriadPro-Regular"]=e["PdfJS-Fallback-Regular"]={name:"LiberationSans-Regular",factors:Ns,baseWidths:Fs,baseMapping:Ts,metrics:Es};e["MyriadPro-Bold"]=e["PdfJS-Fallback-Bold"]={name:"LiberationSans-Bold",factors:Os,baseWidths:vs,baseMapping:Ss,metrics:Rs};e["MyriadPro-It"]=e["MyriadPro-Italic"]=e["PdfJS-Fallback-Italic"]={name:"LiberationSans-Italic",factors:Ds,baseWidths:Cs,baseMapping:Is,metrics:Ms};e["MyriadPro-BoldIt"]=e["MyriadPro-BoldItalic"]=e["PdfJS-Fallback-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:Hs,baseWidths:As,baseMapping:xs,metrics:Bs};e.ArialMT=e.Arial=e["Arial-Regular"]={name:"LiberationSans-Regular",baseWidths:Fs,baseMapping:Ts};e["Arial-BoldMT"]=e["Arial-Bold"]={name:"LiberationSans-Bold",baseWidths:vs,baseMapping:Ss};e["Arial-ItalicMT"]=e["Arial-Italic"]={name:"LiberationSans-Italic",baseWidths:Cs,baseMapping:Is};e["Arial-BoldItalicMT"]=e["Arial-BoldItalic"]={name:"LiberationSans-BoldItalic",baseWidths:As,baseMapping:xs};e["Calibri-Regular"]={name:"LiberationSans-Regular",factors:ms,baseWidths:Fs,baseMapping:Ts,metrics:ps};e["Calibri-Bold"]={name:"LiberationSans-Bold",factors:os,baseWidths:vs,baseMapping:Ss,metrics:ls};e["Calibri-Italic"]={name:"LiberationSans-Italic",factors:hs,baseWidths:Cs,baseMapping:Is,metrics:us};e["Calibri-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:fs,baseWidths:As,baseMapping:xs,metrics:cs};e["Segoeui-Regular"]={name:"LiberationSans-Regular",factors:Ks,baseWidths:Fs,baseMapping:Ts,metrics:Gs};e["Segoeui-Bold"]={name:"LiberationSans-Bold",factors:_s,baseWidths:vs,baseMapping:Ss,metrics:zs};e["Segoeui-Italic"]={name:"LiberationSans-Italic",factors:Xs,baseWidths:Cs,baseMapping:Is,metrics:Ws};e["Segoeui-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:Ls,baseWidths:As,baseMapping:xs,metrics:Us};e["Helvetica-Regular"]=e.Helvetica={name:"LiberationSans-Regular",factors:ys,baseWidths:Fs,baseMapping:Ts,metrics:qs};e["Helvetica-Bold"]={name:"LiberationSans-Bold",factors:ds,baseWidths:vs,baseMapping:Ss,metrics:gs};e["Helvetica-Italic"]={name:"LiberationSans-Italic",factors:js,baseWidths:Cs,baseMapping:Is,metrics:ks};e["Helvetica-BoldItalic"]={name:"LiberationSans-BoldItalic",factors:bs,baseWidths:As,baseMapping:xs,metrics:ws}});function getXfaFontName(e){const t=normalizeFontName(e);return Vs()[t]}function getXfaFontDict(e){const t=function getXfaFontWidths(e){const t=getXfaFontName(e);if(!t)return null;const{baseWidths:a,baseMapping:n,factors:s}=t,r=s?a.map((e,t)=>e*s[t]):a;let i,o=-2;const l=[];for(const[e,t]of n.map((e,t)=>[e,t]).sort(([e],[t])=>e-t))if(-1!==e)if(e===o+1){i.push(r[t]);o+=1}else{o=e;i=[r[t]];l.push(e,i)}return l}(e),a=new Dict(null);a.set("BaseFont",Name.get(e));a.set("Type",Name.get("Font"));a.set("Subtype",Name.get("CIDFontType2"));a.set("Encoding",Name.get("Identity-H"));a.set("CIDToGIDMap",Name.get("Identity"));a.set("W",t);a.set("FirstChar",t[0]);a.set("LastChar",t.at(-2)+t.at(-1).length-1);const n=new Dict(null);a.set("FontDescriptor",n);const s=new Dict(null);s.set("Ordering","Identity");s.set("Registry","Adobe");s.set("Supplement",0);a.set("CIDSystemInfo",s);return a}const $s={number:0,lbrace:1,rbrace:2,true:3,false:4,add:5,sub:6,mul:7,div:8,idiv:9,mod:10,exp:11,eq:12,ne:13,gt:14,ge:15,lt:16,le:17,and:18,or:19,xor:20,bitshift:21,abs:22,neg:23,ceiling:24,floor:25,round:26,truncate:27,not:28,sqrt:29,sin:30,cos:31,ln:32,log:33,atan:34,cvi:35,cvr:36,dup:37,exch:38,pop:39,copy:40,index:41,roll:42,if:43,ifelse:44,eof:45,min:46,max:47};class Token{constructor(e,t=null){this.id=e;this.value=t}}class lexer_Lexer{static#re=null;static#ie=null;static#oe(){const e=Object.create(null),t=Object.create(null);for(const[a,n]of Object.entries($s)){if("number"===a)continue;const s=n>=$s.true&&n<=$s.ifelse,r=new Token(n,s?a:null);e[a]=r;s&&(t[a]=r)}this.#re=e;this.#ie=t}constructor(e){lexer_Lexer.#re||lexer_Lexer.#oe();this.data=e;this.pos=0;this.len=e.length;this._numberPattern=/[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?/y;this._identifierPattern=/[a-z]+/y}_skipComment(){const e=this.data.indexOf("\n",this.pos),t=this.data.indexOf("\r",this.pos),a=Math.min(e<0?this.len:e,t<0?this.len:t);this.pos=Math.min(a+1,this.len)}_getNumber(){this._numberPattern.lastIndex=this.pos;const e=this._numberPattern.exec(this.data);if(!e)return new Token($s.number,0);const t=parseFloat(e[0]);if(!Number.isFinite(t))return new Token($s.number,0);this.pos=this._numberPattern.lastIndex;return new Token($s.number,t)}_getOperator(){this._identifierPattern.lastIndex=this.pos;const e=this._identifierPattern.exec(this.data);if(!e)return new Token($s.number,0);this.pos=this._identifierPattern.lastIndex;const t=e[0],a=lexer_Lexer.#ie[t];return a||new Token($s.number,0)}next(){for(;this.pos=48&&e<=57){this.pos--;return this._getNumber()}if(e>=97&&e<=122){this.pos--;return this._getOperator()}return new Token($s.number,0)}}return lexer_Lexer.#re.eof}}const Ys=0,Js=1,Qs=2,Zs=0,er=1,tr=2,ar=3,nr=4,sr=5,rr=6,ir=7,or=8,lr=9,fr=10;class PsNode{constructor(e){this.type=e}}class PsProgram extends PsNode{constructor(e){super(Zs);this.body=e}}class PsBlock extends PsNode{constructor(e){super(er);this.instructions=e}}class PsNumber extends PsNode{constructor(e){super(tr);this.value=e}}class PsOperator extends PsNode{constructor(e){super(ar);this.op=e}}class PsIf extends PsNode{constructor(e){super(nr);this.then=e}}class PsIfElse extends PsNode{constructor(e,t){super(sr);this.then=e;this.otherwise=t}}class PsArgNode extends PsNode{constructor(e){super(rr);this.index=e;this.valueType=Ys}}class PsConstNode extends PsNode{constructor(e){super(ir);this.value=e;this.valueType="boolean"==typeof e?Js:Ys}}class PsUnaryNode extends PsNode{constructor(e,t,a=Qs){super(or);this.op=e;this.operand=t;this.valueType=a}}class PsBinaryNode extends PsNode{constructor(e,t,a,n=Qs){super(lr);this.op=e;this.first=t;this.second=a;this.valueType=n}}class PsTernaryNode extends PsNode{constructor(e,t,a,n=Qs){super(fr);this.cond=e;this.then=t;this.otherwise=a;this.valueType=n}}class ast_Parser{constructor(e){this.lexer=e;this._token=null}static _isRegularOperator(e){return e>=$s.true&&e<$s.if}_advance(){this._token=this.lexer.next()}_expect(e){if(this._token.id!==e)throw new FormatError(`PostScript function: expected token id ${e}, got ${this._token.id}.`);const t=this._token;this._advance();return t}parse(){this._advance();this._expect($s.lbrace);const e=this._parseBlock();this._expect($s.rbrace);this._token.id!==$s.eof&&warn("PostScript function: unexpected content after closing brace.");return new PsProgram(e)}_parseBlock(){const e=[];for(;;){const t=this._token;switch(t.id){case $s.number:e.push(new PsNumber(t.value));this._advance();break;case $s.lbrace:{this._advance();const t=this._parseBlock();this._expect($s.rbrace);if(this._token.id===$s.if){this._advance();e.push(new PsIf(t))}else{if(this._token.id!==$s.lbrace)throw new FormatError("PostScript function: a procedure block must be followed by 'if' or '{…} ifelse'.");{this._advance();const a=this._parseBlock();this._expect($s.rbrace);this._expect($s.ifelse);e.push(new PsIfElse(t,a))}}break}case $s.rbrace:case $s.eof:return new PsBlock(e);case $s.if:case $s.ifelse:throw new FormatError(`PostScript function: unexpected '${t.value}' operator.`);default:if(ast_Parser._isRegularOperator(t.id)){e.push(new PsOperator(t.id));this._advance();break}throw new FormatError(`PostScript function: unexpected token id ${t.id}.`)}}}}function parsePostScriptFunction(e){return new ast_Parser(new lexer_Lexer(e)).parse()}function _nodesEqual(e,t){if(e===t)return!0;if(e.type!==t.type)return!1;switch(e.type){case rr:return e.index===t.index;case ir:return e.value===t.value;case or:return e.op===t.op&&_nodesEqual(e.operand,t.operand);case lr:return e.op===t.op&&_nodesEqual(e.first,t.first)&&_nodesEqual(e.second,t.second);case fr:return _nodesEqual(e.cond,t.cond)&&_nodesEqual(e.then,t.then)&&_nodesEqual(e.otherwise,t.otherwise);default:return!1}}const cr=100;class PSStackToTree{static#le=null;static#fe=null;static#ce=null;static#he=null;static#ue(){this.#le=new Set([$s.add,$s.sub,$s.mul,$s.div,$s.idiv,$s.mod,$s.exp,$s.atan,$s.eq,$s.ne,$s.gt,$s.ge,$s.lt,$s.le,$s.and,$s.or,$s.xor,$s.bitshift]);this.#fe=new Set([$s.abs,$s.neg,$s.ceiling,$s.floor,$s.round,$s.truncate,$s.sqrt,$s.sin,$s.cos,$s.ln,$s.log,$s.cvi,$s.cvr,$s.not]);this.#ce=new Set([$s.abs,$s.ceiling,$s.cvi,$s.cvr,$s.floor,$s.round,$s.truncate]);this.#he=new Map([[$s.eq,$s.ne],[$s.ne,$s.eq],[$s.lt,$s.ge],[$s.le,$s.gt],[$s.gt,$s.le],[$s.ge,$s.lt]])}evaluate(e,t){PSStackToTree.#le||PSStackToTree.#ue();this._failed=!1;if(t>cr)return null;const a=[];for(let e=0;e{if(!e||e.type===rr||e.type===ir)return;const a=t.get(e)??0;t.set(e,a+1);if(!(a>0))switch(e.type){case or:visit(e.operand);break;case lr:visit(e.first);visit(e.second);break;case fr:visit(e.cond);visit(e.then);visit(e.otherwise)}};for(const t of e)visit(t);for(const[e,a]of t)if(a>1){e.shared=!0;e.sharedCount=a}}_evalBlock(e,t){this._evalBlockFrom(e.instructions,0,t)}_evalBlockFrom(e,t,a){for(let n=t;ncr&&(this._failed=!0);break;case ar:this._evalOp(t.op,a);break;case nr:{if(a.length<1){this._failed=!0;break}const s=a.pop(),r=a.slice();this._evalBlock(t.then,a);if(this._failed)break;if(a.length===r.length)for(let e=0;er.length){if(s.type===ir){if(!s.value){a.length=0;a.push(...r)}break}const t=a.slice();this._evalBlockFrom(e,n+1,t);if(this._failed)break;const i=r;this._evalBlockFrom(e,n+1,i);if(this._failed)break;if(t.length!==i.length){const e=new PsConstNode(0);for(;t.lengthcr&&(this._failed=!0);break;case $s.false:t.push(new PsConstNode(!1));t.length>cr&&(this._failed=!0);break;case $s.dup:if(t.length<1){this._failed=!0;break}t.push(t.at(-1));t.length>cr&&(this._failed=!0);break;case $s.exch:{if(t.length<2){this._failed=!0;break}const e=t.pop(),a=t.pop();t.push(e,a);break}case $s.pop:if(t.length<1){this._failed=!0;break}t.pop();break;case $s.copy:{if(t.length<1){this._failed=!0;break}const e=t.pop();if(e.type===ir){const a=0|e.value;if(0===a);else if(a<0||a>t.length)this._failed=!0;else{t.push(...t.slice(-a));t.length>cr&&(this._failed=!0)}}else this._failed=!0;break}case $s.index:{if(t.length<1){this._failed=!0;break}const e=t.pop();if(e.type===ir){const a=0|e.value;a<0||a>=t.length?this._failed=!0:t.push(t.at(-a-1))}else this._failed=!0;break}case $s.roll:{if(t.length<2){this._failed=!0;break}const e=t.pop(),a=t.pop();if(a.type===ir&&e.type===ir){const n=0|a.value;if(0===n);else if(n<0||n>t.length)this._failed=!0;else{const a=((0|e.value)%n+n)%n;if(a>0){const e=t.splice(-n,n);t.push(...e.slice(n-a),...e.slice(0,n-a))}}}else this._failed=!0;break}default:this._failed=!0}}_makeBinary(e,t,a){if(t.type===ir&&a.type===ir){const n=function _evalBinaryConst(e,t,a){switch(e){case $s.add:return t+a;case $s.sub:return t-a;case $s.mul:return t*a;case $s.div:return 0!==a?t/a:0;case $s.idiv:return 0!==a?Math.trunc(t/a):0;case $s.mod:return 0!==a?t-Math.trunc(t/a)*a:0;case $s.exp:{const e=t**a;return Number.isFinite(e)?e:void 0}case $s.atan:{let e=Math.atan2(t,a)*(180/Math.PI);e<0&&(e+=360);return e}case $s.eq:return t===a;case $s.ne:return t!==a;case $s.gt:return t>a;case $s.ge:return t>=a;case $s.lt:return t=0?t<>-a|0;case $s.min:return Math.min(t,a);case $s.max:return Math.max(t,a);default:return}}(e,a.value,t.value);if(void 0!==n)return new PsConstNode(n)}if(_nodesEqual(t,a))switch(e){case $s.sub:return new PsConstNode(0);case $s.xor:return new PsConstNode(t.valueType!==Js&&0);case $s.and:case $s.or:case $s.min:case $s.max:return t;case $s.eq:case $s.ge:case $s.le:return new PsConstNode(!0);case $s.ne:case $s.gt:case $s.lt:return new PsConstNode(!1)}if(t.type===ir){const n=t.value;switch(e){case $s.add:case $s.sub:if(0===n)return a;break;case $s.mul:if(1===n)return a;if(0===n)return t;if(-1===n)return this._makeUnary($s.neg,a);break;case $s.div:if(0!==n)return this._makeBinary($s.mul,new PsConstNode(1/n),a);break;case $s.idiv:if(1===n)return a;break;case $s.exp:if(1===n)return a;if(-1===n)return this._makeBinary($s.div,a,new PsConstNode(1));if(.5===n)return this._makeUnary($s.sqrt,a);if(.25===n){const e=this._makeUnary($s.sqrt,a);return this._makeUnary($s.sqrt,e)}if(2===n)return this._makeBinary($s.mul,a,a);if(3===n)return this._makeBinary($s.mul,this._makeBinary($s.mul,a,a),a);if(4===n){const e=this._makeBinary($s.mul,a,a);return this._makeBinary($s.mul,e,e)}if(0===n)return new PsConstNode(1);break;case $s.and:if(!0===n)return a;if(!1===n)return t;break;case $s.or:if(!1===n)return a;if(!0===n)return t;break;case $s.min:if(a.type===lr&&a.op===$s.max&&a.first.type===ir&&a.first.value>=n)return t;break;case $s.max:if(a.type===lr&&a.op===$s.min&&a.first.type===ir&&a.first.value<=n)return t}}if(a.type===ir){const n=a.value;switch(e){case $s.add:if(0===n)return t;break;case $s.sub:if(0===n)return this._makeUnary($s.neg,t);break;case $s.mul:if(1===n)return t;if(0===n)return a;if(-1===n)return this._makeUnary($s.neg,t);break;case $s.and:if(!0===n)return t;if(!1===n)return a;break;case $s.or:if(!1===n)return t;if(!0===n)return a}}return new PsBinaryNode(e,t,a,function _binaryValueType(e,t,a){switch(e){case $s.eq:case $s.ne:case $s.gt:case $s.ge:case $s.lt:case $s.le:return Js;case $s.and:case $s.or:case $s.xor:return t===a&&t!==Qs?t:Qs;default:return Ys}}(e,t.valueType,a.valueType))}_makeUnary(e,t){if(t.type===ir){const a=function _evalUnaryConst(e,t){switch(e){case $s.abs:return Math.abs(t);case $s.neg:return-t;case $s.ceiling:return Math.ceil(t);case $s.floor:return Math.floor(t);case $s.round:return Math.round(t);case $s.truncate:return Math.trunc(t);case $s.sqrt:{const e=Math.sqrt(t);return Number.isFinite(e)?e:void 0}case $s.sin:return Math.sin(t%360*Math.PI/180);case $s.cos:return Math.cos(t%360*Math.PI/180);case $s.ln:{const e=Math.log(t);return Number.isFinite(e)?e:void 0}case $s.log:{const e=Math.log10(t);return Number.isFinite(e)?e:void 0}case $s.cvi:return Math.trunc(t);case $s.cvr:return t;case $s.not:return"boolean"==typeof t?!t:~t;default:return}}(e,t.value);if(void 0!==a)return new PsConstNode(a)}if(e===$s.not&&t.type===lr){const e=PSStackToTree.#he.get(t.op);if(void 0!==e)return new PsBinaryNode(e,t.first,t.second,Js)}if(e===$s.neg&&t.type===lr&&t.op===$s.sub)return this._makeBinary($s.sub,t.second,t.first);if(t.type===or){if(e===$s.neg&&t.op===$s.neg||e===$s.not&&t.op===$s.not)return t.operand;if(e===$s.abs&&t.op===$s.neg)return this._makeUnary($s.abs,t.operand);if(PSStackToTree.#ce.has(e)&&e===t.op)return t}return new PsUnaryNode(e,t,function _unaryValueType(e,t){return e===$s.not?t:Ys}(e,t.valueType))}_makeTernary(e,t,a){if(e.type===ir)return e.value?t:a;if(_nodesEqual(t,a))return t;if(t.type===ir&&a.type===ir){if(!0===t.value&&!1===a.value)return e;if(!1===t.value&&!0===a.value)return this._makeUnary($s.not,e)}if(e.type===lr){const{op:n,first:s,second:r}=e;if(n===$s.gt||n===$s.ge){if(_nodesEqual(t,s)&&_nodesEqual(a,r))return this._makeBinary($s.min,s,r);if(_nodesEqual(t,r)&&_nodesEqual(a,s))return this._makeBinary($s.max,s,r)}else if(n===$s.lt||n===$s.le){if(_nodesEqual(t,s)&&_nodesEqual(a,r))return this._makeBinary($s.max,s,r);if(_nodesEqual(t,r)&&_nodesEqual(a,s))return this._makeBinary($s.min,s,r)}}return new PsTernaryNode(e,t,a,t.valueType===a.valueType?t.valueType:Qs)}}const hr=0,ur=1,mr=2,pr=3,dr=4,gr=5,br=6,wr=7,jr=8,kr=9,yr=10,qr=11,vr=12,Sr=13,Ar=14,xr=15,Cr=16,Ir=17,Fr=18,Tr=19,Or=20,Rr=21,Hr=22,Dr=23,Mr=24,Nr=25,Pr=26,Er=27,_r=28,zr=29,Lr=30,Ur=31,Xr=32,Wr=33,Kr=34,Gr=35,Vr=36,$r=37,Yr=38,Jr=39,Qr=40,Zr=Math.PI/180,ei=180/Math.PI;class PsJsCompiler{static#pe=new Float64Array(64);static#de=new Float64Array(64);constructor(e,t){this.nIn=e.length>>1;this.nOut=t.length>>1;this.range=t;this.ir=[];this._tmpMap=new Map;this._nextTmp=0}_compileNode(e){if(e.shared){const t=this._tmpMap.get(e);if(void 0!==t){this.ir.push(Qr,t);return!0}if(!this._compileNodeImpl(e))return!1;const a=this._nextTmp++;this._tmpMap.set(e,a);this.ir.push(Jr,a);return!0}return this._compileNodeImpl(e)}_compileNodeImpl(e){switch(e.type){case rr:this.ir.push(hr,e.index);return!0;case ir:{const t=e.value;this.ir.push(ur,"boolean"==typeof t?Number(t):t);return!0}case or:return this._compileUnary(e);case lr:return this._compileBinary(e);case fr:return this._compileTernary(e);default:return!1}}_compileUnary(e){const{op:t,operand:a,valueType:n}=e;if(t===$s.cvr)return this._compileNode(a);if(!this._compileNode(a))return!1;switch(t){case $s.abs:this.ir.push(gr);break;case $s.neg:this.ir.push(br);break;case $s.ceiling:this.ir.push(wr);break;case $s.floor:this.ir.push(jr);break;case $s.round:this.ir.push(kr);break;case $s.truncate:this.ir.push(yr);break;case $s.sqrt:this.ir.push(Sr);break;case $s.sin:this.ir.push(Ar);break;case $s.cos:this.ir.push(xr);break;case $s.ln:this.ir.push(Cr);break;case $s.log:this.ir.push(Ir);break;case $s.cvi:this.ir.push(Fr);break;case $s.not:if(n===Js)this.ir.push(qr);else{if(n!==Ys)return!1;this.ir.push(vr)}break;default:return!1}return!0}_compileBinary(e){const{op:t,first:a,second:n}=e;if(t===$s.bitshift){if(a.type!==ir||!Number.isInteger(a.value))return!1;if(!this._compileNode(n))return!1;this.ir.push(Tr,a.value);return!0}if(!this._compileNode(n))return!1;if(!this._compileNode(a))return!1;switch(t){case $s.add:this.ir.push(Or);break;case $s.sub:this.ir.push(Rr);break;case $s.mul:this.ir.push(Hr);break;case $s.div:this.ir.push(Dr);break;case $s.idiv:this.ir.push(Mr);break;case $s.mod:this.ir.push(Nr);break;case $s.exp:this.ir.push(Pr);break;case $s.eq:this.ir.push(Er);break;case $s.ne:this.ir.push(_r);break;case $s.gt:this.ir.push(zr);break;case $s.ge:this.ir.push(Lr);break;case $s.lt:this.ir.push(Ur);break;case $s.le:this.ir.push(Xr);break;case $s.and:this.ir.push(Wr);break;case $s.or:this.ir.push(Kr);break;case $s.xor:this.ir.push(Gr);break;case $s.atan:this.ir.push(Vr);break;case $s.min:this.ir.push($r);break;case $s.max:this.ir.push(Yr);break;default:return!1}return!0}_compileTernary(e){if(!this._compileNode(e.cond))return!1;this.ir.push(pr,0);const t=this.ir.length-1;if(!this._compileNode(e.then))return!1;this.ir.push(dr,0);const a=this.ir.length-1;this.ir[t]=this.ir.length;if(!this._compileNode(e.otherwise))return!1;this.ir[a]=this.ir.length;return!0}compile(e){const t=(new PSStackToTree).evaluate(e,this.nIn);if(!t||t.length0?a<>-t:a;break}case Or:{const e=l[--i];l[i-1]+=e;break}case Rr:{const e=l[--i];l[i-1]-=e;break}case Hr:{const e=l[--i];l[i-1]*=e;break}case Dr:{const e=l[--i];l[i-1]=0!==e?l[i-1]/e:0;break}case Mr:{const e=l[--i];l[i-1]=0!==e?Math.trunc(l[i-1]/e):0;break}case Nr:{const e=l[--i];l[i-1]=0!==e?l[i-1]%e:0;break}case Pr:{const e=l[--i];l[i-1]**=e;break}case Er:{const e=l[--i];l[i-1]=l[i-1]===e?1:0;break}case _r:{const e=l[--i];l[i-1]=l[i-1]!==e?1:0;break}case zr:{const e=l[--i];l[i-1]=l[i-1]>e?1:0;break}case Lr:{const e=l[--i];l[i-1]=l[i-1]>=e?1:0;break}case Ur:{const e=l[--i];l[i-1]=l[i-1]e?1:0;break}case $s.ge:{const e=t[--this.#ge];t[this.#ge-1]=t[this.#ge-1]>=e?1:0;break}case $s.lt:{const e=t[--this.#ge];t[this.#ge-1]=t[this.#ge-1]0?a<>-e;break}case $s.min:{const e=t[--this.#ge];t[this.#ge-1]=Math.min(t[this.#ge-1],e);break}case $s.max:{const e=t[--this.#ge];t[this.#ge-1]=Math.max(t[this.#ge-1],e);break}case $s.dup:this.#be(t[this.#ge-1]);break;case $s.exch:{const e=t[--this.#ge],a=t[--this.#ge];this.#be(e);this.#be(a);break}case $s.pop:this.#ge--;break;case $s.copy:{const e=Math.trunc(t[--this.#ge]),a=this.#ge-e;for(let n=0;n1&&0!==e){const n=(e%a+a)%a;if(0!==n){const e=this.#ge-a,s=t.slice(e,this.#ge);for(let r=0;r>1,s=a.length>>1,{instructions:r}=e.body;return(e,t,i,o)=>{this.#ge=0;for(let a=0;a=0?this.#pe[l+e]:0;i[o+e]=MathClamp(a[2*e+1],a[2*e],t)}}}}const ti={if:4,else:5,end:11,select:27,call:16,local_get:32,local_set:33,local_tee:34,i32_const:65,i32_eqz:69,i32_and:113,i32_or:114,i32_xor:115,i32_shl:116,i32_shr_s:117,i32_trunc_f64_s:170,f64_const:68,f64_eq:97,f64_ne:98,f64_lt:99,f64_gt:100,f64_le:101,f64_ge:102,f64_abs:153,f64_neg:154,f64_ceil:155,f64_floor:156,f64_trunc:157,f64_nearest:158,f64_sqrt:159,f64_add:160,f64_sub:161,f64_mul:162,f64_div:163,f64_min:164,f64_max:165,f64_convert_i32_s:183,f64_store:57},ai=124,ni=1,si=2,ri=3,ii=5,oi=7,li=10;function unsignedLEB128(e){const t=[];do{let a=127&e;0!==(e>>>=7)&&(a|=128);t.push(a)}while(0!==e);return t}function encodeASCIIString(e){return[...unsignedLEB128(e.length),...Array.from(e,e=>e.charCodeAt(0))]}function section(e,t){return[e,...unsignedLEB128(t.length),...t]}function vec(e){const t=unsignedLEB128(e.length);for(const a of e)if("number"!=typeof a)for(const e of a)t.push(e);else t.push(a);return t}const fi=[["sin","Math","sin",[ai],[ai]],["cos","Math","cos",[ai],[ai]],["atan2","Math","atan2",[ai,ai],[ai]],["log","Math","log",[ai],[ai]],["log10","Math","log10",[ai],[ai]],["pow","Math","pow",[ai,ai],[ai]]],ci={Math:Object.fromEntries(fi.map(([e])=>[e,Math[e]]))};class PsWasmCompiler{static#ke=!1;static#ye=null;static#qe=null;static#ve=0;static#Se=0;static#Ae=null;static#xe=null;static#Ce=null;static#Ie=null;static#Fe=null;static#Te=null;static#Oe=null;static#Re=null;static#ue(){this.#ye=new Map([[$s.eq,ti.f64_eq],[$s.ne,ti.f64_ne],[$s.lt,ti.f64_lt],[$s.le,ti.f64_le],[$s.gt,ti.f64_gt],[$s.ge,ti.f64_ge]]);this.#qe=Object.create(null);for(let e=0;e[96,...vec(e),...vec(t)]);this.#xe=new Uint8Array(section(si,vec(fi.map(([,e,t],a)=>[...encodeASCIIString(e),...encodeASCIIString(t),0,...unsignedLEB128(a+1)]))));this.#Ce=new Uint8Array(section(ri,vec([[0]])));this.#Ie=new Uint8Array(section(ii,vec([[0,1]])));this.#Fe=new Uint8Array(section(oi,vec([[...encodeASCIIString("fn"),0,...unsignedLEB128(fi.length)],[...encodeASCIIString("mem"),2,0]])));this.#Te=new Uint8Array([0,97,115,109,1,0,0,0]);const e=new ArrayBuffer(8);this.#Oe=new DataView(e);this.#Re=new Uint8Array(e);this.#ke=!0}constructor(e,t){PsWasmCompiler.#ke||PsWasmCompiler.#ue();this._nIn=e.length>>1;this._nOut=t.length>>1;this._range=t;this._code=[];this._nextLocal=this._nIn;this._freeLocals=[];this._sharedLocals=new Map}_allocLocal(){return this._freeLocals.pop()??this._nextLocal++}_releaseLocal(e){this._freeLocals.push(e)}_emitULEB128(e){do{let t=127&e;0!==(e>>>=7)&&(t|=128);this._code.push(t)}while(0!==e)}_emitF64Const(e){this._code.push(ti.f64_const);PsWasmCompiler.#Oe.setFloat64(0,e,!0);for(let e=0;e<8;e++)this._code.push(PsWasmCompiler.#Re[e])}_emitLocalGet(e){this._code.push(ti.local_get);this._emitULEB128(e)}_emitLocalSet(e){this._code.push(ti.local_set);this._emitULEB128(e)}_emitLocalTee(e){this._code.push(ti.local_tee);this._emitULEB128(e)}_compileNode(e){if(e.shared){const t=this._sharedLocals.get(e);if(void 0!==t){this._emitLocalGet(t.local);0===--t.remaining&&this._releaseLocal(t.local);return!0}if(!this._compileNodeImpl(e))return!1;const a=this._allocLocal();this._sharedLocals.set(e,{local:a,remaining:e.sharedCount-1});this._emitLocalTee(a);return!0}return this._compileNodeImpl(e)}_compileNodeImpl(e){switch(e.type){case rr:this._emitLocalGet(e.index);return!0;case ir:{let t=e.value;"boolean"==typeof t&&(t=t?1:0);this._emitF64Const(t);return!0}case or:return this._compileUnaryNode(e);case lr:return this._compileBinaryNode(e);case fr:return this._compileTernaryNode(e);default:return!1}}_compileSinCosNode(e){const t=this._allocLocal();try{if(!this._compileNode(e.operand))return!1;const a=this._code;this._emitLocalSet(t);this._emitLocalGet(t);this._emitLocalGet(t);this._emitF64Const(360);a.push(ti.f64_div,ti.f64_trunc);this._emitF64Const(360);a.push(ti.f64_mul,ti.f64_sub);this._emitF64Const(PsWasmCompiler.#ve);a.push(ti.f64_mul,ti.call);this._emitULEB128(PsWasmCompiler.#qe[e.op===$s.sin?"sin":"cos"]);return!0}finally{this._releaseLocal(t)}}_compileUnaryNode(e){const t=this._code;if(e.op===$s.sin||e.op===$s.cos)return this._compileSinCosNode(e);if(e.op===$s.not){if(e.valueType===Js){if(!this._compileNodeAsBoolI32(e.operand))return!1;t.push(ti.i32_eqz,ti.f64_convert_i32_s);return!0}if(e.valueType===Ys){if(!this._compileNode(e.operand))return!1;t.push(ti.i32_trunc_f64_s,ti.i32_const,127,ti.i32_xor,ti.f64_convert_i32_s);return!0}return!1}if(!this._compileNode(e.operand))return!1;switch(e.op){case $s.abs:t.push(ti.f64_abs);break;case $s.neg:t.push(ti.f64_neg);break;case $s.sqrt:t.push(ti.f64_sqrt);break;case $s.floor:t.push(ti.f64_floor);break;case $s.ceiling:t.push(ti.f64_ceil);break;case $s.round:this._emitF64Const(.5);t.push(ti.f64_add,ti.f64_floor);break;case $s.truncate:t.push(ti.f64_trunc);break;case $s.cvi:t.push(ti.i32_trunc_f64_s,ti.f64_convert_i32_s);break;case $s.cvr:break;case $s.ln:t.push(ti.call);this._emitULEB128(PsWasmCompiler.#qe.log);break;case $s.log:t.push(ti.call);this._emitULEB128(PsWasmCompiler.#qe.log10);break;default:return!1}return!0}_compileSafeDivNode(e,t){const a=this._allocLocal();try{if(!this._compileNode(t))return!1;if(!this._compileNode(e))return!1;const n=this._code;this._emitLocalTee(a);n.push(ti.f64_div);this._emitF64Const(0);this._emitLocalGet(a);this._emitF64Const(0);n.push(ti.f64_ne,ti.select);return!0}finally{this._releaseLocal(a)}}_compileSafeIdivNode(e,t){const a=this._allocLocal();try{if(!this._compileNode(t))return!1;if(!this._compileNode(e))return!1;const n=this._code;this._emitLocalTee(a);n.push(ti.f64_div,ti.f64_trunc);this._emitF64Const(0);this._emitLocalGet(a);this._emitF64Const(0);n.push(ti.f64_ne,ti.select);return!0}finally{this._releaseLocal(a)}}_compileBitshiftNode(e,t){if(e.type!==ir||!Number.isInteger(e.value))return!1;if(!this._compileNode(t))return!1;const a=this._code;a.push(ti.i32_trunc_f64_s);const n=e.value;if(n>0){a.push(ti.i32_const);this._emitULEB128(n);a.push(ti.i32_shl)}else if(n<0){a.push(ti.i32_const);this._emitULEB128(-n);a.push(ti.i32_shr_s)}a.push(ti.f64_convert_i32_s);return!0}_compileModNode(e,t){if(e.type===ir&&0===e.value){if(!this._compileNode(t))return!1;this._code.push(ti.drop);this._emitF64Const(0);return!0}const a=this._allocLocal();try{if(!this._compileNode(t))return!1;this._emitLocalTee(a);const n=this._code;if(e.type===ir){this._emitLocalGet(a);this._emitF64Const(e.value);n.push(ti.f64_div,ti.f64_trunc);this._emitF64Const(e.value);n.push(ti.f64_mul,ti.f64_sub)}else{const t=this._allocLocal();try{if(!this._compileNode(e))return!1;this._emitLocalSet(t);this._emitLocalGet(a);this._emitLocalGet(t);n.push(ti.f64_div,ti.f64_trunc);this._emitLocalGet(t);n.push(ti.f64_mul,ti.f64_sub);this._emitF64Const(0);this._emitLocalGet(t);this._emitF64Const(0);n.push(ti.f64_ne,ti.select)}finally{this._releaseLocal(t)}}return!0}finally{this._releaseLocal(a)}}_compileAtanNode(e,t){const a=this._allocLocal();try{if(!this._compileNode(t))return!1;if(!this._compileNode(e))return!1;const n=this._code;n.push(ti.call);this._emitULEB128(PsWasmCompiler.#qe.atan2);this._emitF64Const(PsWasmCompiler.#Se);n.push(ti.f64_mul);this._emitLocalTee(a);this._emitF64Const(0);n.push(ti.f64_lt,ti.if,ai);this._emitLocalGet(a);this._emitF64Const(360);n.push(ti.f64_add,ti.else);this._emitLocalGet(a);n.push(ti.end);return!0}finally{this._releaseLocal(a)}}_compileBitwiseNode(e,t,a){if(!this._compileBitwiseOperandI32(a))return!1;if(!this._compileBitwiseOperandI32(t))return!1;const n=this._code;switch(e){case $s.and:n.push(ti.i32_and);break;case $s.or:n.push(ti.i32_or);break;case $s.xor:n.push(ti.i32_xor);break;default:return!1}n.push(ti.f64_convert_i32_s);return!0}_compileBitwiseOperandI32(e){if(e.valueType===Js)return this._compileNodeAsBoolI32(e);if(!this._compileNode(e))return!1;this._code.push(ti.i32_trunc_f64_s);return!0}_compileStandardBinaryNode(e,t,a){if(t!==a||t.type===rr||t.type===ir||t.shared){if(!this._compileNode(a))return!1;if(!this._compileNode(t))return!1}else{const e=this._allocLocal();try{if(!this._compileNode(t))return!1;this._emitLocalTee(e);this._emitLocalGet(e)}finally{this._releaseLocal(e)}}const n=this._code;switch(e){case $s.add:n.push(ti.f64_add);break;case $s.sub:n.push(ti.f64_sub);break;case $s.mul:n.push(ti.f64_mul);break;case $s.exp:n.push(ti.call);this._emitULEB128(PsWasmCompiler.#qe.pow);break;case $s.eq:n.push(ti.f64_eq,ti.f64_convert_i32_s);break;case $s.ne:n.push(ti.f64_ne,ti.f64_convert_i32_s);break;case $s.lt:n.push(ti.f64_lt,ti.f64_convert_i32_s);break;case $s.le:n.push(ti.f64_le,ti.f64_convert_i32_s);break;case $s.gt:n.push(ti.f64_gt,ti.f64_convert_i32_s);break;case $s.ge:n.push(ti.f64_ge,ti.f64_convert_i32_s);break;case $s.min:n.push(ti.f64_min);break;case $s.max:n.push(ti.f64_max);break;default:return!1}return!0}_compileBinaryNode(e){const{op:t,first:a,second:n}=e;return t===$s.bitshift?this._compileBitshiftNode(a,n):t===$s.div?this._compileSafeDivNode(a,n):t===$s.idiv?this._compileSafeIdivNode(a,n):t===$s.mod?this._compileModNode(a,n):t===$s.atan?this._compileAtanNode(a,n):t===$s.and||t===$s.or||t===$s.xor?this._compileBitwiseNode(t,a,n):this._compileStandardBinaryNode(t,a,n)}_compileNodeAsBoolI32(e){if(e.type===lr){const t=PsWasmCompiler.#ye.get(e.op);if(void 0!==t){if(!this._compileNode(e.second))return!1;if(!this._compileNode(e.first))return!1;this._code.push(t);return!0}if(e.valueType===Js&&(e.op===$s.and||e.op===$s.or||e.op===$s.xor)){if(!this._compileNodeAsBoolI32(e.second))return!1;if(!this._compileNodeAsBoolI32(e.first))return!1;switch(e.op){case $s.and:this._code.push(ti.i32_and);break;case $s.or:this._code.push(ti.i32_or);break;case $s.xor:this._code.push(ti.i32_xor)}return!0}}if(e.type===or&&e.op===$s.not&&e.valueType===Js){if(!this._compileNodeAsBoolI32(e.operand))return!1;this._code.push(ti.i32_eqz);return!0}if(!this._compileNode(e))return!1;if(e.valueType===Js)this._code.push(ti.i32_trunc_f64_s);else{this._emitF64Const(0);this._code.push(ti.f64_ne)}return!0}_compileTernaryNode(e){if(!this._compileNodeAsBoolI32(e.cond))return!1;this._code.push(ti.if,ai);if(!this._compileNode(e.then))return!1;this._code.push(ti.else);if(!this._compileNode(e.otherwise))return!1;this._code.push(ti.end);return!0}compile(e){const t=(new PSStackToTree).evaluate(e,this._nIn);if(!t||t.length0?[[...unsignedLEB128(s),ai]]:[]),l=o.length+a.length,f=new Uint8Array(section(li,vec([[...unsignedLEB128(l),...o,...a]]))),c=PsWasmCompiler.#Te,h=PsWasmCompiler.#xe,u=PsWasmCompiler.#Ce,m=PsWasmCompiler.#Ie,p=PsWasmCompiler.#Fe,d=c.length+i.length+h.length+u.length+m.length+p.length+f.length,g=new Uint8Array(d);let b=0;g.set(c,b);b+=c.length;g.set(i,b);b+=i.length;g.set(h,b);b+=h.length;g.set(u,b);b+=u.length;g.set(m,b);b+=m.length;g.set(p,b);b+=p.length;g.set(f,b);return g}}function buildPostScriptWasmFunction(e,t,a){const n=function compilePostScriptToWasm(e,t,a){return new PsWasmCompiler(t,a).compile(parsePostScriptFunction(e))}(e,t,a);if(!n)return null;try{return function _makeWrapper(e,t,a){const{fn:n,mem:s}=e,r=new Float64Array(s.buffer,0,a);let i;switch(a){case 1:i=(e,t)=>{e[t]=r[0]};break;case 2:i=(e,t)=>{e[t]=r[0];e[t+1]=r[1]};break;case 3:i=(e,t)=>{e[t]=r[0];e[t+1]=r[1];e[t+2]=r[2]};break;case 4:i=(e,t)=>{e[t]=r[0];e[t+1]=r[1];e[t+2]=r[2];e[t+3]=r[3]};break;default:i=(e,t)=>{for(let n=0;n{n(e[t]);i(a,s)};case 2:return(e,t,a,s)=>{n(e[t],e[t+1]);i(a,s)};case 3:return(e,t,a,s)=>{n(e[t],e[t+1],e[t+2]);i(a,s)};case 4:return(e,t,a,s)=>{n(e[t],e[t+1],e[t+2],e[t+3]);i(a,s)};default:{const e=new Float64Array(t);return(a,s,r,o)=>{for(let n=0;n>1,a.length>>1)}catch{return null}}class BaseLocalCache{constructor(e){this._onlyRefs=!0===e?.onlyRefs;if(!this._onlyRefs){this._nameRefMap=new Map;this._imageMap=new Map}this._imageCache=new RefSetCache}getByName(e){this._onlyRefs&&unreachable("Should not call `getByName` method.");const t=this._nameRefMap.get(e);return t?this.getByRef(t):this._imageMap.get(e)||null}getByRef(e){return this._imageCache.get(e)||null}set(e,t,a){unreachable("Abstract method `set` called.")}}class LocalImageCache extends BaseLocalCache{set(e,t=null,a){if("string"!=typeof e)throw new Error('LocalImageCache.set - expected "name" argument.');if(t){if(this._imageCache.has(t))return;this._nameRefMap.set(e,t);this._imageCache.put(t,a)}else this._imageMap.has(e)||this._imageMap.set(e,a)}}class LocalColorSpaceCache extends BaseLocalCache{set(e=null,t=null,a){if("string"!=typeof e&&!t)throw new Error('LocalColorSpaceCache.set - expected "name" and/or "ref" argument.');if(t){if(this._imageCache.has(t))return;null!==e&&this._nameRefMap.set(e,t);this._imageCache.put(t,a)}else this._imageMap.has(e)||this._imageMap.set(e,a)}}class LocalFunctionCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,a){if(!t)throw new Error('LocalFunctionCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,a)}}class LocalGStateCache extends BaseLocalCache{set(e,t=null,a){if("string"!=typeof e)throw new Error('LocalGStateCache.set - expected "name" argument.');if(t){if(this._imageCache.has(t))return;this._nameRefMap.set(e,t);this._imageCache.put(t,a)}else this._imageMap.has(e)||this._imageMap.set(e,a)}}class LocalTilingPatternCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,a){if(!t)throw new Error('LocalTilingPatternCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,a)}}class RegionalImageCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,a){if(!t)throw new Error('RegionalImageCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,a)}}class GlobalColorSpaceCache extends BaseLocalCache{constructor(e){super({onlyRefs:!0})}set(e=null,t,a){if(!t)throw new Error('GlobalColorSpaceCache.set - expected "ref" argument.');this._imageCache.has(t)||this._imageCache.put(t,a)}clear(){this._imageCache.clear()}}class GlobalImageCache{static NUM_PAGES_THRESHOLD=2;static MIN_IMAGES_TO_CACHE=10;static MAX_BYTE_SIZE=5e7;#He=new RefSet;constructor(){this._refCache=new RefSetCache;this._imageCache=new RefSetCache}get#Be(){let e=0;for(const t of this._imageCache)e+=t.byteSize;return e}get#De(){return!(this._imageCache.size+e):null}class PDFFunction{static getSampleArray(e,t,a,n){let s=t;for(const t of e)s*=t;const r=new Array(s);let i=0,o=0;const l=1/(2**a-1),f=n.getBytes((s*a+7)/8);let c=0;for(let e=0;e>i)*l;o&=(1<0?r[h-1]:a[0],m=h{PsJsCompiler.execute(r,e,t,a,n)}:PSStackBasedInterpreter.build(s,t,a)}(r,n,s)}}function isPDFFunction(e){let t;if(e instanceof Dict)t=e;else{if(!(e instanceof BaseStream))return!1;t=e.dict}return t.has("FunctionType")}const di=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],gi=["AN","AN","AN","AN","AN","AN","ON","ON","AL","ET","ET","AL","CS","AL","ON","ON","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","AN","AN","AN","AN","AN","AN","AN","AN","AN","ET","AN","AN","AL","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","ON","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","NSM","NSM","ON","NSM","NSM","NSM","NSM","AL","AL","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","AL","AL","AL","AL","AL","AL"];function isOdd(e){return!!(1&e)}function isEven(e){return!(1&e)}function findUnequal(e,t,a){let n,s;for(n=t,s=e.length;n4){n=!0;t=0}else{n=!1;t=1}const l=[];for(r=0;r=0&&"ET"===wi[e];--e)wi[e]="EN";for(let e=r+1;e=0;e--){const a=wi[e];if("L"===a){t="L";break}if("R"===a||"EN"===a||"AN"===a){t="R";break}}let a=h;for(let t=e;tp&&isOdd(p)&&(g=p)}for(p=d;p>=g;--p){let e=-1;for(r=0,i=l.length;r=0){reverseValues(bi,e,r);e=-1}}else e<0&&(e=r);e>=0&&reverseValues(bi,e,l.length)}for(r=0,i=bi.length;r"!==e||(bi[r]="")}return createBidiText(bi.join(""),n)}const ji={style:"normal",weight:"normal"},ki={style:"normal",weight:"bold"},yi={style:"italic",weight:"normal"},qi={style:"italic",weight:"bold"},vi=new Map([["Times-Roman",{local:["Times New Roman","Times-Roman","Times","Liberation Serif","Nimbus Roman","Nimbus Roman L","Tinos","Thorndale","TeX Gyre Termes","FreeSerif","Linux Libertine O","Libertinus Serif","PT Astra Serif","DejaVu Serif","Bitstream Vera Serif","Ubuntu"],style:ji,ultimate:"serif"}],["Times-Bold",{alias:"Times-Roman",style:ki,ultimate:"serif"}],["Times-Italic",{alias:"Times-Roman",style:yi,ultimate:"serif"}],["Times-BoldItalic",{alias:"Times-Roman",style:qi,ultimate:"serif"}],["Helvetica",{local:["Helvetica","Helvetica Neue","Arial","Arial Nova","Liberation Sans","Arimo","Nimbus Sans","Nimbus Sans L","A030","TeX Gyre Heros","FreeSans","DejaVu Sans","Albany","Bitstream Vera Sans","Arial Unicode MS","Microsoft Sans Serif","Apple Symbols","Cantarell"],path:"LiberationSans-Regular.ttf",style:ji,ultimate:"sans-serif"}],["Helvetica-Bold",{alias:"Helvetica",path:"LiberationSans-Bold.ttf",style:ki,ultimate:"sans-serif"}],["Helvetica-Oblique",{alias:"Helvetica",path:"LiberationSans-Italic.ttf",style:yi,ultimate:"sans-serif"}],["Helvetica-BoldOblique",{alias:"Helvetica",path:"LiberationSans-BoldItalic.ttf",style:qi,ultimate:"sans-serif"}],["Courier",{local:["Courier","Courier New","Liberation Mono","Nimbus Mono","Nimbus Mono L","Cousine","Cumberland","TeX Gyre Cursor","FreeMono","Linux Libertine Mono O","Libertinus Mono"],style:ji,ultimate:"monospace"}],["Courier-Bold",{alias:"Courier",style:ki,ultimate:"monospace"}],["Courier-Oblique",{alias:"Courier",style:yi,ultimate:"monospace"}],["Courier-BoldOblique",{alias:"Courier",style:qi,ultimate:"monospace"}],["ArialBlack",{local:["Arial Black"],style:{style:"normal",weight:"900"},fallback:"Helvetica-Bold"}],["ArialBlack-Bold",{alias:"ArialBlack"}],["ArialBlack-Italic",{alias:"ArialBlack",style:{style:"italic",weight:"900"},fallback:"Helvetica-BoldOblique"}],["ArialBlack-BoldItalic",{alias:"ArialBlack-Italic"}],["ArialNarrow",{local:["Arial Narrow","Liberation Sans Narrow","Helvetica Condensed","Nimbus Sans Narrow","TeX Gyre Heros Cn"],style:ji,fallback:"Helvetica"}],["ArialNarrow-Bold",{alias:"ArialNarrow",style:ki,fallback:"Helvetica-Bold"}],["ArialNarrow-Italic",{alias:"ArialNarrow",style:yi,fallback:"Helvetica-Oblique"}],["ArialNarrow-BoldItalic",{alias:"ArialNarrow",style:qi,fallback:"Helvetica-BoldOblique"}],["Calibri",{local:["Calibri","Carlito"],style:ji,fallback:"Helvetica"}],["Calibri-Bold",{alias:"Calibri",style:ki,fallback:"Helvetica-Bold"}],["Calibri-Italic",{alias:"Calibri",style:yi,fallback:"Helvetica-Oblique"}],["Calibri-BoldItalic",{alias:"Calibri",style:qi,fallback:"Helvetica-BoldOblique"}],["Wingdings",{local:["Wingdings","URW Dingbats"],style:ji}],["Wingdings-Regular",{alias:"Wingdings"}],["Wingdings-Bold",{alias:"Wingdings"}],["ËÎÌå",{local:["SimSun","SimSun Regular","NSimSun"],style:ji,ultimate:"serif"}],["ºÚÌå",{local:["SimHei","SimHei Regular"],style:ji,ultimate:"sans-serif"}],["¿¬Ìå",{local:["KaiTi","SimKai","SimKai Regular"],style:ji,ultimate:"sans-serif"}],["·ÂËÎ",{local:["FangSong","SimFang","SimFang Regular"],style:ji,ultimate:"serif"}],["¿¬Ìå_GB2312",{alias:"¿¬Ìå"}],["·ÂËÎ_GB2312",{alias:"·ÂËÎ"}],["Á¥Êé",{local:["SimLi","SimLi Regular"],style:ji,ultimate:"serif"}],["ÐÂËÎ",{alias:"ËÎÌå"}]]),Si=new Map([["Arial-Black","ArialBlack"]]);function getFamilyName(e){const t=new Set(["thin","extralight","ultralight","demilight","semilight","light","book","regular","normal","medium","demibold","semibold","bold","extrabold","ultrabold","black","heavy","extrablack","ultrablack","roman","italic","oblique","ultracondensed","extracondensed","condensed","semicondensed","normal","semiexpanded","expanded","extraexpanded","ultraexpanded","bolditalic"]);return e.split(/[- ,+]+/g).filter(e=>!t.has(e.toLowerCase())).join(" ")}function generateFont({alias:e,local:t,path:a,fallback:n,style:s,ultimate:r},i,o,l=!0,f=!0,c=""){const h={style:null,ultimate:null};if(t){const e=c?` ${c}`:"";for(const a of t)i.push(`local(${a}${e})`)}if(e){const t=vi.get(e),r=c||function getStyleToAppend(e){switch(e){case ki:return"Bold";case yi:return"Italic";case qi:return"Bold Italic";default:if("bold"===e?.weight)return"Bold";if("italic"===e?.style)return"Italic"}return""}(s);Object.assign(h,generateFont(t,i,o,l&&!n,f&&!a,r))}s&&(h.style=s);r&&(h.ultimate=r);if(l&&n){const e=vi.get(n),{ultimate:t}=generateFont(e,i,o,l,f&&!a,c);h.ultimate||=t}f&&a&&o&&i.push(`url(${o}${a})`);return h}function getFontSubstitution(e,t,a,n,s,r){if(n.startsWith("InvalidPDFjsFont_"))return null;"TrueType"!==r&&"Type1"!==r||!/^[A-Z]{6}\+/.test(n)||(n=n.slice(7));const i=n=normalizeFontName(n);let o=e.get(i);if(o)return o;let l=vi.get(n);if(!l)for(const[e,t]of Si)if(n.startsWith(e)){n=`${t}${n.substring(e.length)}`;l=vi.get(n);break}let f=!1;if(!l){l=vi.get(s);f=!0}const c=`${t.getDocId()}_s${t.createFontId()}`;if(!l){if(!validateFontName(n)){warn(`Cannot substitute the font because of its name: ${n}`);e.set(i,null);return null}const t=/bold/gi.test(n),a=/oblique|italic/gi.test(n),s=t&&a&&qi||t&&ki||a&&yi||ji;o={css:`"${getFamilyName(n)}",${c}`,guessFallback:!0,loadedName:c,baseFontName:n,src:`local(${n})`,style:s};e.set(i,o);return o}const h=[];f&&validateFontName(n)&&h.push(`local(${n})`);const{style:u,ultimate:m}=generateFont(l,h,a),p=null===m,d=p?"":`,${m}`;o={css:`"${getFamilyName(n)}",${c}${d}`,guessFallback:p,loadedName:c,baseFontName:n,src:h.join(","),style:u};e.set(i,o);return o}const Ai=3285377520,xi=4294901760,Ci=65535;class MurmurHash3_64{constructor(e){this.h1=e?4294967295&e:Ai;this.h2=e?4294967295&e:Ai}update(e){let t,a;if("string"==typeof e){t=new Uint8Array(2*e.length);a=0;for(let n=0,s=e.length;n>>8;t[a++]=255&s}}}else{if(!ArrayBuffer.isView(e))throw new Error("Invalid data format, must be a string or TypedArray.");t=e.slice();a=t.byteLength}const n=a>>2,s=a-4*n,r=new Uint32Array(t.buffer,0,n);let i=0,o=0,l=this.h1,f=this.h2;const c=3432918353,h=461845907,u=11601,m=13715;for(let e=0;e>>17;i=i*h&xi|i*m&Ci;l^=i;l=l<<13|l>>>19;l=5*l+3864292196}else{o=r[e];o=o*c&xi|o*u&Ci;o=o<<15|o>>>17;o=o*h&xi|o*m&Ci;f^=o;f=f<<13|f>>>19;f=5*f+3864292196}i=0;switch(s){case 3:i^=t[4*n+2]<<16;case 2:i^=t[4*n+1]<<8;case 1:i^=t[4*n];i=i*c&xi|i*u&Ci;i=i<<15|i>>>17;i=i*h&xi|i*m&Ci;1&n?l^=i:f^=i}this.h1=l;this.h2=f}hexdigest(){let e=this.h1,t=this.h2;e^=t>>>1;e=3981806797*e&xi|36045*e&Ci;t=4283543511*t&xi|(2950163797*(t<<16|e>>>16)&xi)>>>16;e^=t>>>1;e=444984403*e&xi|60499*e&Ci;t=3301882366*t&xi|(3120437893*(t<<16|e>>>16)&xi)>>>16;e^=t>>>1;return(e>>>0).toString(16).padStart(8,"0")+(t>>>0).toString(16).padStart(8,"0")}}class PDFImage{constructor({xref:e,res:t,image:a,isInline:n=!1,smask:s=null,mask:r=null,isMask:i=!1,pdfFunctionFactory:o,globalColorSpaceCache:l,localColorSpaceCache:f}){this.image=a;const c=a.dict,h=c.get("F","Filter");let u;if(h instanceof Name)u=h.name;else if(Array.isArray(h)){const t=e.fetchIfRef(h[0]);t instanceof Name&&(u=t.name)}switch(u){case"JPXDecode":({width:a.width,height:a.height,componentsCount:a.numComps,bitsPerComponent:a.bitsPerComponent}=JpxImage.parseImageProperties(a.stream));a.stream.reset();const e=ImageResizer.getReducePowerForJPX(a.width,a.height,a.numComps);this.jpxDecoderOptions={numComponents:0,isIndexedColormap:!1,smaskInData:c.has("SMaskInData"),reducePower:e};if(e){const t=2**e;a.width=Math.ceil(a.width/t);a.height=Math.ceil(a.height/t)}break;case"JBIG2Decode":a.bitsPerComponent=1;a.numComps=1}let m=c.get("W","Width"),p=c.get("H","Height");if(Number.isInteger(a.width)&&a.width>0&&Number.isInteger(a.height)&&a.height>0&&(a.width!==m||a.height!==p)){warn("PDFImage - using the Width/Height of the image data, rather than the image dictionary.");m=a.width;p=a.height}else{const e="number"==typeof m&&m>0,t="number"==typeof p&&p>0;if(!e||!t){if(!a.fallbackDims)throw new FormatError(`Invalid image width: ${m} or height: ${p}`);warn("PDFImage - using the Width/Height of the parent image, for SMask/Mask data.");e||(m=a.fallbackDims.width);t||(p=a.fallbackDims.height)}}this.width=m;this.height=p;this.interpolate=c.get("I","Interpolate");this.imageMask=c.get("IM","ImageMask")||!1;this.matte=c.get("Matte")||!1;let d=a.bitsPerComponent;if(!d){d=c.get("BPC","BitsPerComponent");if(!d){if(!this.imageMask)throw new FormatError(`Bits per component missing in image: ${this.imageMask}`);d=1}}this.bpc=d;if(this.imageMask)this.numComps=1;else{let s=c.getRaw("CS")||c.getRaw("ColorSpace");const r=!!s;if(r)this.jpxDecoderOptions?.smaskInData&&(s=Name.get("DeviceRGBA"));else if(this.jpxDecoderOptions)s=Name.get("DeviceRGBA");else switch(a.numComps){case 1:s=Name.get("DeviceGray");break;case 3:s=Name.get("DeviceRGB");break;case 4:s=Name.get("DeviceCMYK");break;default:throw new Error(`Images with ${a.numComps} color components not supported.`)}this.colorSpace=ColorSpaceUtils.parse({cs:s,xref:e,resources:n?t:null,pdfFunctionFactory:o,globalColorSpaceCache:l,localColorSpaceCache:f});this.numComps=this.colorSpace.numComps;if(this.jpxDecoderOptions){this.jpxDecoderOptions.numComponents=r?this.numComps:0;this.jpxDecoderOptions.isIndexedColormap="Indexed"===this.colorSpace.name}}this.decode=c.getArray("D","Decode");this.needsDecode=!1;if(this.decode&&(this.colorSpace&&!this.colorSpace.isDefaultDecode(this.decode,d)||i&&!ColorSpace.isDefaultDecode(this.decode,1))){this.needsDecode=!0;const e=(1<0,l=(n+7>>3)*s,f=await e.getImageData(l),c=1===n&&1===s&&o===(0===f.length||!!(128&f[0]));if(c)return{isSingleOpaquePixel:c};if(t){if(ImageResizer.needsToBeResized(n,s)){const e=new Uint8ClampedArray(n*s*4);convertBlackAndWhiteToRGBA({src:f,dest:e,width:n,height:s,nonBlackColor:0,inverseDecode:o});return ImageResizer.createImage({kind:O,data:e,width:n,height:s,interpolate:r})}const e=new OffscreenCanvas(n,s),t=e.getContext("2d"),a=t.createImageData(n,s);convertBlackAndWhiteToRGBA({src:f,dest:a.data,width:n,height:s,nonBlackColor:0,inverseDecode:o});t.putImageData(a,0,0);return{data:null,width:n,height:s,interpolate:r,bitmap:e.transferToImageBitmap()}}const h=f.byteLength;let u;if(e instanceof DecodeStream&&(!o||l===h))u=f;else if(o){u=new Uint8Array(l);u.set(f);u.fill(255,h)}else u=new Uint8Array(f);if(o)for(let e=0;e>7&1;i[u+1]=h>>6&1;i[u+2]=h>>5&1;i[u+3]=h>>4&1;i[u+4]=h>>3&1;i[u+5]=h>>2&1;i[u+6]=h>>1&1;i[u+7]=1&h;u+=8}if(u>=1}}}}else{let a=0;h=0;for(u=0,c=r;u>n;s<0?s=0:s>f&&(s=f);i[u]=s;h&=(1<this.smask.fillGrayBuffer(e,{...n,destWidth:t,destHeight:a});else if(this.mask)if(this.mask instanceof PDFImage)r=(e,n)=>this.mask.fillGrayBuffer(e,{...n,invertOutput:!0,destWidth:t,destHeight:a});else{if(!Array.isArray(this.mask))throw new FormatError("Unknown mask format.");r=(e,{maxRows:a,offset:n,stride:r})=>{for(let i=0,o=t*a;ithis.mask[r+1]){t=255;break}}e[i*r+n]=t}}}else r=(e,{maxRows:a,offset:n,stride:s})=>{for(let r=0,i=t*a;r>3,c=t&&ImageResizer.needsToBeResized(a,n);if(!this.smask&&!this.mask&&"DeviceRGBA"===this.colorSpace.name){s.kind=O;const e=s.data=await this.getImageBytes(o*i*4,{internal:t&&c});return t?c?ImageResizer.createImage(s,!1):this.createBitmap(O,a,n,e):s}if(!e){let e;"DeviceGray"===this.colorSpace.name&&1===l?e=F:"DeviceRGB"!==this.colorSpace.name||8!==l||this.needsDecode||(e=T);if(e&&!this.smask&&!this.mask&&a===i&&n===o){const r=await this.#Me(i,o);if(r)return r;const l=await this.getImageBytes(o*f,{internal:t&&c});if(t)return c?ImageResizer.createImage({data:l,kind:e,width:a,height:n,interpolate:this.interpolate},this.needsDecode):this.createBitmap(e,i,o,l);s.kind=e;s.data=l;if(this.needsDecode){assert(e===F,"PDFImage.createImageData: The image must be grayscale.");const t=s.data;for(let e=0,a=t.length;e>3,u=await this.getImageBytes(f*h,{internal:!0}),m=this.getComponents(u),p=t??l,d=a??f,g=p!==l||d!==f,b=void 0===s?d:Math.min(d,s);let w=l,j=0,k=null;if(g){w=p;j=f/d;const e=l/p;k=new Uint32Array(p);for(let t=0;t0&&n[0].count++}class TimeSlotManager{static TIME_SLOT_DURATION_MS=20;static CHECK_TIME_EVERY=100;constructor(){this.reset()}check(){if(++this.checked!isFinite(e))&&(m=null);l.has("OC")&&(h=await this.parseMarkedContentProps(l.get("OC"),e));void 0!==h&&n.addOp(xt,["OC",h]);const p=l.get("Group");let d;const g=[f&&new Float32Array(f),!p&&m||null],b=l.get("Resources");if(p){u={matrix:f,bbox:m,smask:a,isolated:!1,knockout:!1,needsIsolation:!1};let t=null;if(isName(p.get("S"),"Transparency")){u.isolated=p.get("I")||!1;u.knockout=p.get("K")||!1;if(p.has("CS")){const a=this._getColorSpace(p.getRaw("CS"),e,i);t=a instanceof ColorSpace?a:await this._handleColorSpace(a)}}if(a?.backdrop){t||=ColorSpaceUtils.rgb;a.backdrop=t.getRgbHex(a.backdrop,0)}d=new CheckedOperatorList}else{d=n;n.addOp(Tt,g)}await this.getOperatorList({stream:t,task:s,resources:b instanceof Dict?b:e,operatorList:d,initialState:r,prevRefs:o});if(p){u.needsIsolation=d.needsIsolation||!!a;n.addOp(Rt,[u]);n.addOp(Tt,g);n.addOpList(d);n.addOp(Ot,[]);n.addOp(Ht,[u])}else n.addOp(Ot,[]);void 0!==h&&n.addOp(Ct,[])}_sendImgData(e,t,a=!1){const n=t?[t.bitmap||t.data.buffer]:null;return this.parsingType3Font||a?this.handler.send("commonobj",[e,"Image",t],n):this.handler.send("obj",[e,this.pageIndex,"Image",t],n)}async buildPaintImageXObject({resources:e,image:t,isInline:a=!1,operatorList:n,cacheKey:s,localImageCache:r,localColorSpaceCache:i}){const{maxImageSize:o,ignoreErrors:l,isOffscreenCanvasSupported:f}=this.options,{dict:c}=t,h=c.objId,u=c.get("W","Width"),m=c.get("H","Height");if(!u||"number"!=typeof u||!m||"number"!=typeof m){warn("Image dimensions are missing, or not numbers.");return}if(-1!==o&&u*m>o){const e="Image exceeded maximum allowed size and was removed.";if(!l)throw new Error(e);warn(e);return}let p;c.has("OC")&&(p=await this.parseMarkedContentProps(c.get("OC"),e));let d,g,b;if(c.get("IM","ImageMask")||!1){d=await PDFImage.createMask({image:t,isOffscreenCanvasSupported:f&&!this.parsingType3Font});if(d.isSingleOpaquePixel){g=Ut;b=[];n.addImageOps(g,b,p);if(s){const e={fn:g,args:b,optionalContent:p};r.set(s,h,e);h&&this._regionalImageCache.set(null,h,e)}return}if(this.parsingType3Font){b=function compileType3Glyph({data:e,width:t,height:a}){if(t>1e3||a>1e3)return null;const n=new Uint8Array([0,2,4,0,1,0,5,4,8,10,0,8,0,2,1,0]),s=t+1,r=new Uint8Array(s*(a+1));let i,o,l;const f=t+7&-8,c=new Uint8Array(f*a);let h=0;for(const t of e){let e=128;for(;e>0;){c[h++]=t&e?0:255;e>>=1}}let u=0;h=0;if(0!==c[h]){r[0]=1;++u}for(o=1;o>2)+(c[h+1]?4:0)+(c[h-f+1]?8:0);if(n[e]){r[l+o]=n[e];++u}h++}if(c[h-f]!==c[h]){r[l+o]=c[h]?2:4;++u}if(u>1e3)return null}h=f*(a-1);l=i*s;if(0!==c[h]){r[l]=8;++u}for(o=1;o1e3)return null;const m=new Int32Array([0,s,-1,0,-s,0,0,0,1]),p=[],{a:d,b:g,c:b,d:w,e:j,f:k}=(new DOMMatrix).scaleSelf(1/t,-1/a).translateSelf(0,-a);for(i=0;u&&i<=a;i++){let e=i*s;const a=e+t;for(;e>4;r[e]&=f>>2|f<<2}n=e%s;o=e/s|0;p.push($t,d*n+b*o+j,g*n+w*o+k);r[e]||--u}while(l!==e);--i}return[Gt,[new Float32Array(p)],new Float32Array([0,0,t,a])]}(d);if(b){n.addImageOps(Xt,b,p);return}warn("Cannot compile Type3 glyph.");n.addImageOps(Mt,[d],p);return}const e=`mask_${this.idFactory.createObjId()}`;n.addDependency(e);d.dataLen=d.bitmap?d.width*d.height*4:d.data.length;this._sendImgData(e,d);g=Mt;b=[{data:e,width:d.width,height:d.height,interpolate:d.interpolate,count:1}];n.addImageOps(g,b,p);if(s){const t={objId:e,fn:g,args:b,optionalContent:p};r.set(s,h,t);h&&this._regionalImageCache.set(null,h,t)}return}const w=c.has("SMask")||c.has("Mask");if(a&&u+m<200&&!w){try{const s=new PDFImage({xref:this.xref,res:e,image:t,isInline:a,pdfFunctionFactory:this._pdfFunctionFactory,globalColorSpaceCache:this.globalColorSpaceCache,localColorSpaceCache:i});d=await s.createImageData(!0,!1);n.addImageOps(Et,[d],p)}catch(e){const t=`Unable to decode inline image: "${e}".`;if(!l)throw new Error(t);warn(t)}return}let j=`img_${this.idFactory.createObjId()}`,k=!1,y=null;if(this.parsingType3Font)j=`${this.idFactory.getDocId()}_type3_${j}`;else if(s&&h){k=this.globalImageCache.shouldCache(h,this.pageIndex);if(k){assert(!a,"Cannot cache an inline image globally.");j=`${this.idFactory.getDocId()}_${j}`}}n.addDependency(j);g=Pt;b=[j,u,m];n.addImageOps(g,b,p,w);if(k){y={objId:j,fn:g,args:b,optionalContent:p,hasMask:w,byteSize:0};if(this.globalImageCache.hasDecodeFailed(h)){this.globalImageCache.setData(h,y);this._sendImgData(j,null,k);return}if(u*m>25e4||w){const e=await this.handler.sendWithPromise("commonobj",[j,"CopyLocalImage",{imageRef:h}]);if(e){this.globalImageCache.setData(h,y);this.globalImageCache.addByteSize(h,e);return}}}PDFImage.buildImage({xref:this.xref,res:e,image:t,isInline:a,pdfFunctionFactory:this._pdfFunctionFactory,globalColorSpaceCache:this.globalColorSpaceCache,localColorSpaceCache:i}).then(async e=>{d=await e.createImageData(!1,f);d.dataLen=d.bitmap?d.width*d.height*4:d.data.length;d.ref=h;k&&this.globalImageCache.addByteSize(h,d.dataLen);return this._sendImgData(j,d,k)}).catch(e=>{warn(`Unable to decode image "${j}": "${e}".`);h&&this.globalImageCache.addDecodeFailed(h);return this._sendImgData(j,null,k)});if(s){const e={objId:j,fn:g,args:b,optionalContent:p,hasMask:w};r.set(s,h,e);if(h){this._regionalImageCache.set(null,h,e);if(k){assert(y,"The global cache-data must be available.");this.globalImageCache.setData(h,y)}}}}handleSMask(e,t,a,n,s,r,i){const o=e.get("G"),l={subtype:e.get("S").name,backdrop:e.get("BC")},f=e.get("TR");if(isPDFFunction(f)){const e=this._pdfFunctionFactory.create(f),t=new Uint8Array(256),a=new Float32Array(1);for(let n=0;n<256;n++){a[0]=n/255;e(a,0,a,0);t[n]=255*a[0]|0}l.transferMap=t}return this.buildFormXObject(t,o,l,a,n,s.state.clone({newPath:!0}),r,i)}handleTransferFunction(e){let t;if(Array.isArray(e)){t=e;e.length>1&&e.every(t=>t===e[0])&&(t=[e[0]])}else{if(!isPDFFunction(e))return null;t=[e]}const a=[];let n=0,s=0;for(const e of t){const t=this.xref.fetchIfRef(e);n++;if(isName(t,"Identity")){a.push(null);continue}if(!isPDFFunction(t))return null;const r=this._pdfFunctionFactory.create(t),i=new Uint8Array(256),o=new Float32Array(1);for(let e=0;e<256;e++){o[0]=e/255;r(o,0,o,0);i[e]=255*o[0]|0}a.push(i);s++}return 1!==n&&4!==n||0===s?null:a}handleTilingType(e,t,a,n,s,r,i,o){const l=new CheckedOperatorList,f=Dict.merge({xref:this.xref,dictArray:[s.get("Resources"),a]});return this.getOperatorList({stream:n,task:i,resources:f,operatorList:l}).then(function(){const a=l.getIR(),{needsIsolation:n}=l,i=getTilingPatternIR(a,s,t,n);r.addDependencies(l.dependencies);r.addOp(e,i);s.objId&&o.set(null,s.objId,{operatorListIR:a,needsIsolation:n,dict:s})}).catch(e=>{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`handleTilingType - ignoring pattern: "${e}".`)}})}async handleSetFont(e,t,a,n,s,r,i=null,o=null){const l=t?.[0]instanceof Name?t[0].name:null,f=await this.loadFont(l,a,e,s,i,o);f.font.isType3Font&&n.addDependencies(f.type3Dependencies);r.font=f.font;f.send(this.handler);return f.loadedName}handleText(e,t){const a=t.font,n=a.charsToGlyphs(e);if(a.data){(!!(t.textRenderingMode&C)||"Pattern"===t.fillColorSpace.name||"Pattern"===t.strokeColorSpace.name||a.disableFontFace)&&PartialEvaluator.buildFontPaths(a,n,this.handler,this.options)}return n}ensureStateFont(e){if(e.font)return;const t=new FormatError("Missing setFont (Tf) operator before text rendering operator.");if(!this.options.ignoreErrors)throw t;warn(`ensureStateFont: "${t}".`)}async setGState({resources:e,gState:t,operatorList:a,cacheKey:n,task:s,stateManager:r,localGStateCache:i,localColorSpaceCache:o,seenRefs:l}){const f=t.objId;let c=!0;const h=[];let u=Promise.resolve();for(const[n,i]of t)switch(n){case"Type":break;case"LW":if("number"!=typeof i){warn(`Invalid LW (line width): ${i}`);break}h.push([n,Math.abs(i)]);break;case"LC":case"LJ":case"ML":case"D":case"RI":case"FL":case"CA":case"ca":h.push([n,i]);break;case"Font":c=!1;u=u.then(()=>this.handleSetFont(e,null,i[0],a,s,r.state).then(function(e){a.addDependency(e);h.push([n,[e,i[1]]])}));break;case"BM":h.push([n,normalizeBlendMode(i)]);break;case"SMask":if(isName(i,"None")){h.push([n,!1]);break}if(i instanceof Dict){c=!1;u=u.then(()=>this.handleSMask(i,e,a,s,r,o,l));h.push([n,!0])}else warn("Unsupported SMask type");break;case"TR":const t=this.handleTransferFunction(i);h.push([n,t]);break;case"OP":case"op":case"OPM":case"BG":case"BG2":case"UCR":case"UCR2":case"TR2":case"HT":case"SM":case"SA":case"AIS":case"TK":info("graphic state operator "+n);break;default:info("Unknown graphic state operator "+n)}await u;h.length>0&&a.addOp(je,[h]);c&&i.set(n,f,h)}loadFont(e,t,a,n,s=null,r=null){const errorFont=async()=>new TranslatedFont({loadedName:"g_font_error",font:new ErrorFont(`Font "${e}" is not available.`),dict:t});let i;if(t)t instanceof Ref&&(i=t);else{const t=a.get("Font");t&&(i=t.getRaw(e))}if(i){if(this.type3FontRefs?.has(i))return errorFont();if(this.fontCache.has(i))return this.fontCache.get(i);try{t=this.xref.fetchIfRef(i)}catch(e){warn(`loadFont - lookup failed: "${e}".`)}}if(!(t instanceof Dict)){if(!this.options.ignoreErrors&&!this.parsingType3Font){warn(`Font "${e}" is not available.`);return errorFont()}warn(`Font "${e}" is not available -- attempting to fallback to a default font.`);t=s||PartialEvaluator.fallbackFontDict}if(t.cacheKey&&this.fontCache.has(t.cacheKey))return this.fontCache.get(t.cacheKey);const{promise:o,resolve:l}=Promise.withResolvers();let f;try{f=this.preEvaluateFont(t);f.cssFontInfo=r}catch(e){warn(`loadFont - preEvaluateFont failed: "${e}".`);return errorFont()}const{descriptor:c,hash:h}=f,u=i instanceof Ref;let m;if(h&&c instanceof Dict){const e=c.fontAliases||=Object.create(null);if(e[h]){const t=e[h].aliasRef;if(u&&t&&this.fontCache.has(t)){this.fontCache.putAlias(i,t);return this.fontCache.get(i)}}else e[h]={fontID:this.idFactory.createFontId()};u&&(e[h].aliasRef=i);m=e[h].fontID}else m=this.idFactory.createFontId();assert(m?.startsWith("f"),'The "fontID" must be (correctly) defined.');if(u)this.fontCache.put(i,o);else{t.cacheKey=`cacheKey_${m}`;this.fontCache.put(t.cacheKey,o)}t.loadedName=`${this.idFactory.getDocId()}_${m}`;this.translateFont(f).then(async e=>{const s=new TranslatedFont({loadedName:t.loadedName,font:e,dict:t});if(e.isType3Font)try{await s.loadType3Data(this,a,n)}catch(e){throw new Error(`Type3 font load error: ${e}`)}l(s)}).catch(e=>{warn(`loadFont - translateFont failed: "${e}".`);l(new TranslatedFont({loadedName:t.loadedName,font:new ErrorFont(e?.message),dict:t}))});return o}buildPath(e,t,a){const{pathMinMax:n,pathBuffer:s}=a;switch(0|e){case Fe:{const e=a.currentPointX=t[0],r=a.currentPointY=t[1],i=t[2],o=t[3],l=e+i,f=r+o;0===i||0===o?s.push(Vt,e,r,$t,l,f,Qt):s.push(Vt,e,r,$t,l,r,$t,l,f,$t,e,f,Qt);Util.rectBoundingBox(e,r,l,f,n);break}case ve:{const e=a.currentPointX=t[0],r=a.currentPointY=t[1];s.push(Vt,e,r);Util.pointBoundingBox(e,r,n);break}case Se:{const e=a.currentPointX=t[0],r=a.currentPointY=t[1];s.push($t,e,r);Util.pointBoundingBox(e,r,n);break}case Ae:{const e=a.currentPointX,r=a.currentPointY,[i,o,l,f,c,h]=t;a.currentPointX=c;a.currentPointY=h;s.push(Yt,i,o,l,f,c,h);Util.bezierBoundingBox(e,r,i,o,l,f,c,h,n);break}case xe:{const e=a.currentPointX,r=a.currentPointY,[i,o,l,f]=t;a.currentPointX=l;a.currentPointY=f;s.push(Yt,e,r,i,o,l,f);Util.bezierBoundingBox(e,r,e,r,i,o,l,f,n);break}case Ce:{const e=a.currentPointX,r=a.currentPointY,[i,o,l,f]=t;a.currentPointX=l;a.currentPointY=f;s.push(Yt,i,o,l,f,l,f);Util.bezierBoundingBox(e,r,i,o,l,f,l,f,n);break}case Ie:s.push(Qt)}}_getColorSpace(e,t,a){return ColorSpaceUtils.parse({cs:e,xref:this.xref,resources:t,pdfFunctionFactory:this._pdfFunctionFactory,globalColorSpaceCache:this.globalColorSpaceCache,localColorSpaceCache:a,asyncIfNotCached:!0})}async _handleColorSpace(e){try{return await e}catch(e){if(e instanceof AbortException)return null;if(this.options.ignoreErrors){warn(`_handleColorSpace - ignoring ColorSpace: "${e}".`);return null}throw e}}parseShading({shading:e,resources:t,localColorSpaceCache:a,localShadingPatternCache:n}){let s,r=n.get(e);if(r)return r;try{s=Pattern.parseShading(e,this.xref,t,this._pdfFunctionFactory,this.globalColorSpaceCache,a).getIR()}catch(t){if(t instanceof AbortException)return null;if(this.options.ignoreErrors){warn(`parseShading - ignoring shading: "${t}".`);n.set(e,null);return null}throw t}r=`pattern_${this.idFactory.createObjId()}`;this.parsingType3Font&&(r=`${this.idFactory.getDocId()}_type3_${r}`);n.set(e,r);if(this.parsingType3Font){const e=function compilePatternInfo(e){let t,a=null,n=[],s=[],r=[],i=null,o=null;switch(e[0]){case"RadialAxial":t="axial"===e[1]?1:2;a=e[2];r=e[3];1===t?n.push(...e[4],...e[5]):n.push(e[4][0],e[4][1],e[6],e[5][0],e[5][1],e[7]);break;case"Mesh":t=3;i=e[1];n=e[2];s=e[3];a=e[6];o=e[7];break;default:throw new Error(`Unsupported pattern type: ${e[0]}`)}const l=Math.floor(n.length/2),f=Math.floor(s.length/4),c=r.length,h=new ArrayBuffer(20+8*l+4*f+8*c+(a?16:0)+(o?3:0)),u=new DataView(h),m=new Uint8Array(h);u.setUint8(PATTERN_INFO.KIND,t);u.setUint8(PATTERN_INFO.HAS_BBOX,a?1:0);u.setUint8(PATTERN_INFO.HAS_BACKGROUND,o?1:0);u.setUint8(PATTERN_INFO.SHADING_TYPE,i);u.setUint32(PATTERN_INFO.N_COORD,l,!0);u.setUint32(PATTERN_INFO.N_COLOR,f,!0);u.setUint32(PATTERN_INFO.N_STOP,c,!0);u.setUint32(PATTERN_INFO.N_FIGURES,0,!0);let p=20;new Float32Array(h,p,2*l).set(n);p+=8*l;m.set(s,p);p+=4*f;for(const[e,t]of r){u.setFloat32(p,e,!0);p+=4;u.setUint32(p,parseInt(t.slice(1),16),!0);p+=4}if(a)for(const e of a){u.setFloat32(p,e,!0);p+=4}o&&m.set(o,p);return h}(s);this.handler.send("commonobj",[r,"Pattern",e],[e])}else this.handler.send("obj",[r,this.pageIndex,"Pattern",s]);return r}handleColorN(e,t,a,n,s,r,i,o,l,f){const c=a.pop();if(c instanceof Name){const h=s.getRaw(c.name),u=h instanceof Ref&&l.getByRef(h);if(u)try{const s=n.base?n.base.getRgbHex(a,0):null,r=getTilingPatternIR(u.operatorListIR,u.dict,s,u.needsIsolation);e.addOp(t,r);return}catch{}const m=this.xref.fetchIfRef(h);if(m){const s=m instanceof BaseStream?m.dict:m,c=s.get("PatternType");if(c===Fi){const o=n.base?n.base.getRgbHex(a,0):null;return this.handleTilingType(t,o,r,m,s,e,i,l)}if(c===Ti){const a=s.get("Shading"),n=this.parseShading({shading:a,resources:r,localColorSpaceCache:o,localShadingPatternCache:f});if(n){const a=lookupMatrix(s.getArray("Matrix"),null);e.addOp(t,["Shading",n,a])}return}throw new FormatError(`Unknown PatternType: ${c}`)}}throw new FormatError(`Unknown PatternName: ${c}`)}_parseVisibilityExpression(e,t,a){if(++t>10){warn("Visibility expression is too deeply nested");return}const n=e.length,s=this.xref.fetchIfRef(e[0]);if(!(n<2)&&s instanceof Name){switch(s.name){case"And":case"Or":case"Not":a.push(s.name);break;default:warn(`Invalid operator ${s.name} in visibility expression`);return}for(let s=1;s0)return{type:"OCMD",expression:t}}const t=a.get("OCGs");if(Array.isArray(t)||t instanceof Dict){const e=[];if(Array.isArray(t))for(const a of t)e.push(a.toString());else e.push(t.objId);return{type:n,ids:e,policy:a.get("P")instanceof Name?a.get("P").name:null,expression:null}}if(t instanceof Ref)return{type:n,id:t.toString()}}return null}async getOperatorList({stream:e,task:a,resources:n,operatorList:s,initialState:r=null,fallbackFontDict:i=null,prevRefs:o=null}){if(e.isAsync){const t=await e.asyncGetBytes();t&&(e=new Stream(t,0,t.length,e.dict))}const l=e.dict?.objId,f=new RefSet(o);if(l){if(o?.has(l))throw new Error(`getOperatorList - ignoring circular reference: ${l}`);f.put(l)}n||=Dict.empty;r||=new EvalState;if(!s)throw new Error('getOperatorList: missing "operatorList" parameter');const c=this,h=this.xref,u=new LocalImageCache,m=new LocalColorSpaceCache,p=new LocalGStateCache,d=new LocalTilingPatternCache,g=new Map,b=n.get("XObject")||Dict.empty,w=n.get("Pattern")||Dict.empty,j=new StateManager(r),k=new EvaluatorPreprocessor(e,h,j),y=new TimeSlotManager;function closePendingRestoreOPS(e){for(let e=0,t=k.savedStatesDepth;e{j.state.fillColorSpace=e||ColorSpaceUtils.gray}));return}case it:{const t=c._getColorSpace(e[0],n,m);if(t instanceof ColorSpace){j.state.strokeColorSpace=t;continue}next(c._handleColorSpace(t).then(e=>{j.state.strokeColorSpace=e||ColorSpaceUtils.gray}));return}case ct:S=j.state.fillColorSpace;e=[S.getRgbHex(e,0)];r=dt;break;case lt:S=j.state.strokeColorSpace;e=[S.getRgbHex(e,0)];r=pt;break;case mt:j.state.fillColorSpace=ColorSpaceUtils.gray;e=[ColorSpaceUtils.gray.getRgbHex(e,0)];r=dt;break;case ut:j.state.strokeColorSpace=ColorSpaceUtils.gray;e=[ColorSpaceUtils.gray.getRgbHex(e,0)];r=pt;break;case bt:j.state.fillColorSpace=ColorSpaceUtils.cmyk;e=[ColorSpaceUtils.cmyk.getRgbHex(e,0)];r=dt;break;case gt:j.state.strokeColorSpace=ColorSpaceUtils.cmyk;e=[ColorSpaceUtils.cmyk.getRgbHex(e,0)];r=pt;break;case dt:j.state.fillColorSpace=ColorSpaceUtils.rgb;e=[ColorSpaceUtils.rgb.getRgbHex(e,0)];break;case pt:j.state.strokeColorSpace=ColorSpaceUtils.rgb;e=[ColorSpaceUtils.rgb.getRgbHex(e,0)];break;case ht:S=j.state.patternFillColorSpace;if(!S){if(isNumberArray(e,null)){e=[ColorSpaceUtils.gray.getRgbHex(e,0)];r=dt;break}e=[];r=Kt;break}if("Pattern"===S.name){next(c.handleColorN(s,ht,e,S,w,n,a,m,d,g));return}e=[S.getRgbHex(e,0)];r=dt;break;case ft:S=j.state.patternStrokeColorSpace;if(!S){if(isNumberArray(e,null)){e=[ColorSpaceUtils.gray.getRgbHex(e,0)];r=pt;break}e=[];r=Wt;break}if("Pattern"===S.name){next(c.handleColorN(s,ft,e,S,w,n,a,m,d,g));return}e=[S.getRgbHex(e,0)];r=pt;break;case wt:let F;try{const t=n.get("Shading");if(!t)throw new FormatError("No shading resource found");F=t.get(e[0].name);if(!F)throw new FormatError("No shading object found")}catch(e){if(e instanceof AbortException)continue;if(c.options.ignoreErrors){warn(`getOperatorList - ignoring Shading: "${e}".`);continue}throw e}const T=c.parseShading({shading:F,resources:n,localColorSpaceCache:m,localShadingPatternCache:g});if(!T)continue;e=[T];r=wt;break;case je:C=e[0]instanceof Name;x=e[0].name;if(C){const t=p.getByName(x);if(t){t.length>0&&s.addOp(je,[t]);e=null;continue}}next(new Promise(function(e,t){if(!C)throw new FormatError("GState must be referred to by name.");const r=n.get("ExtGState");if(!(r instanceof Dict))throw new FormatError("ExtGState should be a dictionary.");const i=r.get(x);if(!(i instanceof Dict))throw new FormatError("GState should be a dictionary.");c.setGState({resources:n,gState:i,operatorList:s,cacheKey:x,task:a,stateManager:j,localGStateCache:p,localColorSpaceCache:m,seenRefs:f}).then(e,t)}).catch(function(e){if(!(e instanceof AbortException)){if(!c.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring ExtGState: "${e}".`)}}));return;case ue:{const[t]=e;if("number"!=typeof t){warn(`Invalid setLineWidth: ${t}`);continue}e[0]=Math.abs(t);break}case ge:{const t=e[1];if("number"!=typeof t){warn(`Invalid setDash: ${t}`);continue}const a=e[0];if(!Array.isArray(a)){warn(`Invalid setDash: ${a}`);continue}a.some(e=>"number"!=typeof e)&&(e[0]=a.filter(e=>"number"==typeof e));break}case ve:case Se:case Ae:case xe:case Ce:case Ie:case Fe:c.buildPath(r,e,j.state);continue;case Te:case Oe:case Re:case He:case Be:case De:case Me:case Ne:case Pe:{const{state:{pathBuffer:e,pathMinMax:a}}=j;r!==Oe&&r!==Me&&r!==Ne||e.push(Qt);if(0===e.length)s.addOp(Xt,[r,[null],null]);else{s.addOp(Xt,[r,[new Float32Array(e)],a.slice()]);e.length=0;a.set(t,0)}continue}case Qe:s.addOp(r,[new Float32Array(e)]);continue;case vt:case St:case It:case Ft:continue;case xt:if(!(e[0]instanceof Name)){warn(`Expected name for beginMarkedContentProps arg0=${e[0]}`);s.addOp(xt,["OC",null]);continue}if("OC"===e[0].name){next(c.parseMarkedContentProps(e[1],n).then(e=>{s.addOp(xt,["OC",e])}).catch(e=>{if(!(e instanceof AbortException)){if(!c.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring beginMarkedContentProps: "${e}".`);s.addOp(xt,["OC",null])}}));return}e=[e[0].name,e[1]instanceof Dict?e[1].get("MCID"):null];break;default:if(null!==e){for(q=0,v=e.length;q{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`getOperatorList - ignoring errors during "${a.name}" task: "${e}".`);closePendingRestoreOPS()}})}async getTextContent({stream:e,task:t,resources:a,stateManager:s=null,includeMarkedContent:r=!1,sink:i,seenStyles:o=new Set,viewBox:l,lang:f=null,markedContentData:c=null,disableNormalization:h=!1,keepWhiteSpace:u=!1,prevRefs:m=null,intersector:p=null}){if(e.isAsync){const t=await e.asyncGetBytes();t&&(e=new Stream(t,0,t.length,e.dict))}const d=e.dict?.objId,g=new RefSet(m);if(d){if(m?.has(d))throw new Error(`getTextContent - ignoring circular reference: ${d}`);g.put(d)}a||=Dict.empty;s||=new StateManager(new TextState);r&&(c||={level:0});const b={items:[],styles:Object.create(null),lang:f},w={initialized:!1,str:[],totalWidth:0,totalHeight:0,width:0,height:0,vertical:!1,prevTransform:null,prevTextRise:0,textAdvanceScale:0,spaceInFlowMin:0,spaceInFlowMax:0,trackingSpaceMin:1/0,negativeSpaceMax:-1/0,notASpace:-1/0,transform:null,fontName:null,hasEOL:!1},j=[" "," "];let k=0;function saveLastChar(e){const t=(k+1)%2,a=" "!==j[k]&&" "===j[t];j[k]=e;k=t;return!u&&a}function shouldAddWhitepsace(){return!u&&" "!==j[k]&&" "===j[(k+1)%2]}function resetLastChars(){j[0]=j[1]=" ";k=0}const y=this,q=this.xref,v=[];let S=null;const x=new LocalImageCache,C=new LocalGStateCache,F=new EvaluatorPreprocessor(e,q,s);let T,O;function pushWhitespace({width:e=0,height:t=0,transform:a=w.prevTransform,fontName:n=w.fontName}){p?.addExtraChar(" ");b.items.push({str:" ",dir:"ltr",width:e,height:t,transform:a,fontName:n,hasEOL:!1})}function getCurrentTextTransform(){const e=T.font,t=[T.fontSize*T.textHScale,0,0,T.fontSize,0,T.textRise];if(e.isType3Font&&(T.fontSize<=1||e.isCharBBox)&&!isArrayEqual(T.fontMatrix,n)){const a=e.bbox[3]-e.bbox[1];a>0&&(t[3]*=a*T.fontMatrix[3])}return Util.transform(T.ctm,Util.transform(T.textMatrix,t))}function ensureTextContentItem(){if(w.initialized)return w;const{font:e,loadedName:t}=T;if(!o.has(t)){o.add(t);b.styles[t]={fontFamily:e.fallbackName,ascent:e.ascent,descent:e.descent,vertical:e.vertical};if(y.options.fontExtraProperties&&e.systemFontInfo){const a=b.styles[t];a.fontSubstitution=e.systemFontInfo.css;a.fontSubstitutionLoadedName=e.systemFontInfo.loadedName}}w.fontName=t;const a=w.transform=getCurrentTextTransform();if(e.vertical){w.width=w.totalWidth=Math.hypot(a[0],a[1]);w.height=w.totalHeight=0;w.vertical=!0}else{w.width=w.totalWidth=0;w.height=w.totalHeight=Math.hypot(a[2],a[3]);w.vertical=!1}const n=Math.hypot(T.textLineMatrix[0],T.textLineMatrix[1]),s=Math.hypot(T.ctm[0],T.ctm[1]);w.textAdvanceScale=s*n;const{fontSize:r}=T;w.trackingSpaceMin=.102*r;w.notASpace=.03*r;w.negativeSpaceMax=-.2*r;w.spaceInFlowMin=.102*r;w.spaceInFlowMax=.6*r;w.hasEOL=!1;w.initialized=!0;return w}function updateAdvanceScale(){if(!w.initialized)return;const e=Math.hypot(T.textLineMatrix[0],T.textLineMatrix[1]),t=Math.hypot(T.ctm[0],T.ctm[1])*e;if(t!==w.textAdvanceScale){if(w.vertical){w.totalHeight+=w.height*w.textAdvanceScale;w.height=0}else{w.totalWidth+=w.width*w.textAdvanceScale;w.width=0}w.textAdvanceScale=t}}function runBidiTransform(e){let t=e.str.join("");h||(t=function normalizeUnicode(e){if(!sa){sa=/([\u00a0\u00b5\u037e\u0eb3\u2000-\u200a\u202f\u2126\ufb00-\ufb04\ufb06\ufb20-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufba1\ufba4-\ufba9\ufbae-\ufbb1\ufbd3-\ufbdc\ufbde-\ufbe7\ufbea-\ufbf8\ufbfc-\ufbfd\ufc00-\ufc5d\ufc64-\ufcf1\ufcf5-\ufd3d\ufd88\ufdf4\ufdfa-\ufdfb\ufe71\ufe77\ufe79\ufe7b\ufe7d]+)|(\ufb05+)/gu;ra=new Map([["ſt","ſt"]])}return e.replaceAll(sa,(e,t,a)=>t?t.normalize("NFKC"):ra.get(a))}(t));const a=bidi(t,-1,e.vertical);return{str:a.str,dir:a.dir,width:Math.abs(e.totalWidth),height:Math.abs(e.totalHeight),transform:e.transform,fontName:e.fontName,hasEOL:e.hasEOL}}async function handleSetFont(e,s){const r=await y.loadFont(e,s,a,t);T.loadedName=r.loadedName;T.font=r.font;T.fontMatrix=r.font.fontMatrix||n}function applyInverseRotation(e,t,a){const n=Math.hypot(a[0],a[1]);return[(a[0]*e+a[1]*t)/n,(a[2]*e+a[3]*t)/n]}function compareWithLastPosition(e){const t=getCurrentTextTransform();let a=t[4],n=t[5];if(T.font?.vertical){if(al[2]||n+el[3])return!1}else if(a+el[2]||nl[3])return!1;if(!T.font||!w.prevTransform)return!0;let s=w.prevTransform[4],r=w.prevTransform[5];if(s===a&&r===n)return!0;let i=-1;t[0]&&0===t[1]&&0===t[2]?i=t[0]>0?0:180:t[1]&&0===t[0]&&0===t[3]&&(i=t[1]>0?90:270);switch(i){case 0:break;case 90:[a,n]=[n,a];[s,r]=[r,s];break;case 180:[a,n,s,r]=[-a,-n,-s,-r];break;case 270:[a,n]=[-n,-a];[s,r]=[-r,-s];break;default:[a,n]=applyInverseRotation(a,n,t);[s,r]=applyInverseRotation(s,r,w.prevTransform)}if(T.font.vertical){const e=(r-n)/w.textAdvanceScale,t=a-s,i=Math.sign(w.height||w.totalHeight);if(e.5*w.width){appendEOL();return!0}resetLastChars();flushTextContentItem();return!0}if(Math.abs(t)>w.width){appendEOL();return!0}e<=i*w.notASpace&&resetLastChars();if(e<=i*w.trackingSpaceMin)if(shouldAddWhitepsace()){resetLastChars();flushTextContentItem();pushWhitespace({height:Math.abs(e)})}else w.height+=e;else if(!addFakeSpaces(e,w.prevTransform,i))if(0===w.str.length){resetLastChars();pushWhitespace({height:Math.abs(e)})}else w.height+=e;Math.abs(t)>.25*w.width&&flushTextContentItem();return!0}const o=(a-s)/w.textAdvanceScale,f=n-r,c=Math.sign(w.width||w.totalWidth);if(o.5*w.height){appendEOL();return!0}resetLastChars();flushTextContentItem();return!0}const h=T.textRise-w.prevTextRise,u=0===h?f:f-t[3]/T.fontSize*h;if(Math.abs(u)>w.height){appendEOL();return!0}o<=c*w.notASpace&&resetLastChars();if(o<=c*w.trackingSpaceMin)if(shouldAddWhitepsace()){resetLastChars();flushTextContentItem();pushWhitespace({width:Math.abs(o)})}else w.width+=o;else if(!addFakeSpaces(o,w.prevTransform,c))if(0===w.str.length){resetLastChars();pushWhitespace({width:Math.abs(o)})}else w.width+=o;Math.abs(f)>.25*w.height&&flushTextContentItem();return!0}function buildTextContentItem({chars:e,extraSpacing:t}){if(O!==T&&(O.fontSize!==T.fontSize||O.fontName!==T.fontName&&(O.font.name!==T.font.name||O.font.vertical!==T.font.vertical))){flushTextContentItem();O=T.clone()}const a=T.font,n=a.vertical?-T.charSpacing:T.charSpacing;if(!e){const e=n+t;e&&(a.vertical?T.translateTextMatrix(0,-e):T.translateTextMatrix(e*T.textHScale,0));u&&compareWithLastPosition(0);return}const s=a.charsToGlyphs(e),r=T.fontMatrix[0]*T.fontSize;for(let e=0,i=s.length;e0){const e=v.join("");v.length=0;buildTextContentItem({chars:e,extraSpacing:0})}break;case et:if(!s.state.font){y.ensureStateFont(s.state);continue}buildTextContentItem({chars:j[0],extraSpacing:0});break;case at:if(!s.state.font){y.ensureStateFont(s.state);continue}T.carriageReturn();buildTextContentItem({chars:j[0],extraSpacing:0});break;case nt:if(!s.state.font){y.ensureStateFont(s.state);continue}T.wordSpacing=j[0];T.charSpacing=j[1];T.carriageReturn();buildTextContentItem({chars:j[2],extraSpacing:0});break;case qt:flushTextContentItem();S??=a.get("XObject")||Dict.empty;w=j[0]instanceof Name;d=j[0].name;if(w&&x.getByName(d))break;next(new Promise(function(e,n){if(!w)throw new FormatError("XObject must be referred to by name.");let m=S.getRaw(d);if(m instanceof Ref){if(x.getByRef(m)){e();return}if(y.globalImageCache.getData(m,y.pageIndex)){e();return}m=q.fetch(m)}if(!(m instanceof BaseStream))throw new FormatError("XObject should be a stream");const{dict:p}=m,b=p.get("Subtype");if(!(b instanceof Name))throw new FormatError("XObject should have a Name subtype");if("Form"!==b.name){x.set(d,p.objId,!0);e();return}const j=s.state.clone(),k=new StateManager(j),v=lookupMatrix(p.getArray("Matrix"),null);v&&k.transform(v);const C=p.get("Resources");enqueueChunk();const F={enqueueInvoked:!1,enqueue(e,t){this.enqueueInvoked=!0;i.enqueue(e,t)},get desiredSize(){return i.desiredSize??0},get ready(){return i.ready}};y.getTextContent({stream:m,task:t,resources:C instanceof Dict?C:a,stateManager:k,includeMarkedContent:r,sink:i&&F,seenStyles:o,viewBox:l,lang:f,markedContentData:c,disableNormalization:h,keepWhiteSpace:u,prevRefs:g}).then(function(){F.enqueueInvoked||x.set(d,p.objId,!0);e()},n)}).catch(function(e){if(!(e instanceof AbortException)){if(!y.options.ignoreErrors)throw e;warn(`getTextContent - ignoring XObject: "${e}".`)}}));return;case je:w=j[0]instanceof Name;d=j[0].name;if(w&&C.getByName(d))break;next(new Promise(function(e,t){if(!w)throw new FormatError("GState must be referred to by name.");const n=a.get("ExtGState");if(!(n instanceof Dict))throw new FormatError("ExtGState should be a dictionary.");const s=n.get(d);if(!(s instanceof Dict))throw new FormatError("GState should be a dictionary.");const r=s.get("Font");if(r){flushTextContentItem();T.fontName=null;T.fontSize=r[1];handleSetFont(null,r[0]).then(e,t)}else{C.set(d,s.objId,!0);e()}}).catch(function(e){if(!(e instanceof AbortException)){if(!y.options.ignoreErrors)throw e;warn(`getTextContent - ignoring ExtGState: "${e}".`)}}));return;case At:flushTextContentItem();if(r){c.level++;b.items.push({type:"beginMarkedContent",tag:j[0]instanceof Name?j[0].name:null})}break;case xt:flushTextContentItem();if(r){c.level++;let e=null;j[1]instanceof Dict&&(e=j[1].get("MCID"));b.items.push({type:"beginMarkedContentProps",id:Number.isInteger(e)?`${y.idFactory.getPageObjId()}_mc${e}`:null,tag:j[0]instanceof Name?j[0].name:null})}break;case Ct:flushTextContentItem();if(r){if(0===c.level)break;c.level--;b.items.push({type:"endMarkedContent"})}}if(b.items.length>=(i?.desiredSize??1)){p=!0;break}}if(p)next(Oi);else{flushTextContentItem();enqueueChunk();e()}}).catch(e=>{if(!(e instanceof AbortException)){if(!this.options.ignoreErrors)throw e;warn(`getTextContent - ignoring errors during "${t.name}" task: "${e}".`);flushTextContentItem();enqueueChunk()}})}async extractDataStructures(e,t){const a=this.xref;let n;const s=this.readToUnicode(t.toUnicode);if(t.composite){const a=e.get("CIDSystemInfo");a instanceof Dict&&!t.cidSystemInfo&&(t.cidSystemInfo={registry:stringToPDFString(a.get("Registry")),ordering:stringToPDFString(a.get("Ordering")),supplement:a.get("Supplement")});try{const t=e.get("CIDToGIDMap");t instanceof BaseStream&&(n=t.getBytes())}catch(e){if(!this.options.ignoreErrors)throw e;warn(`extractDataStructures - ignoring CIDToGIDMap data: "${e}".`)}}const r=[];let i,o=null;if(e.has("Encoding")){i=e.get("Encoding");if(i instanceof Dict){o=i.get("BaseEncoding");o=o instanceof Name?o.name:null;if(i.has("Differences")){const e=i.get("Differences");let t=0;for(const n of e){const e=a.fetchIfRef(n);if("number"==typeof e)t=e;else{if(!(e instanceof Name))throw new FormatError(`Invalid entry in 'Differences' array: ${e}`);r[t++]=e.name}}}}else if(i instanceof Name)o=i.name;else{const e="Encoding is not a Name nor a Dict";if(!this.options.ignoreErrors)throw new FormatError(e);warn(e)}"MacRomanEncoding"!==o&&"MacExpertEncoding"!==o&&"WinAnsiEncoding"!==o&&(o=null)}const l=!t.file||t.isInternalFont,f=_n()[t.name];o&&l&&f&&(o=null);if("WinAnsiEncoding"===o&&l&&t.name?.charCodeAt(0)>=183){const e=t.name;if(["ËÎÌå","ºÚÌå","¿¬Ìå","·ÂËÎ","¿¬Ìå_GB2312","·ÂËÎ_GB2312","Á¥Êé","ÐÂËÎ","·ÂËÎÌå","С±êËÎ"].includes(e)){o=null;t.defaultEncoding="Adobe-GB1-UCS2";t.composite=!0;t.cidEncoding=Name.get("GBK-EUC-H");const e=await CMapFactory.create({encoding:t.cidEncoding,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null});t.cMap=e;t.vertical=t.cMap.vertical;t.cidSystemInfo={registry:"Adobe",ordering:"GB1",supplement:0}}}if(o)t.defaultEncoding=getEncoding(o);else{let e=!!(t.flags&qn);const a=!!(t.flags&vn);if("TrueType"===t.type&&e&&a&&0!==r.length){t.flags&=~qn;e=!1}i=fn;"TrueType"!==t.type||a||(i=cn);if(e||f){i=ln;l&&(/Symbol/i.test(t.name)?i=hn:/Dingbats/i.test(t.name)?i=un:/Wingdings/i.test(t.name)&&(i=cn))}t.defaultEncoding=i}t.differences=r;t.baseEncodingName=o;t.hasEncoding=!!o||r.length>0;t.dict=e;t.toUnicode=await s;const c=await this.buildToUnicode(t);t.toUnicode=c;n&&(t.cidToGidMap=this.readCidToGidMap(n,c));return t}_simpleFontToUnicode(e,t=!1){assert(!e.composite,"Must be a simple font.");const a=[],n=e.defaultEncoding.slice(),s=e.baseEncodingName,r=e.differences;for(const e in r){const t=r[e];".notdef"!==t&&(n[e]=t)}const i=mn();for(const r in n){let o=n[r];if(""===o)continue;let l=i[o];if(void 0!==l){a[r]=String.fromCharCode(l);continue}let f=0;switch(o[0]){case"G":3===o.length&&(f=parseInt(o.substring(1),16));break;case"g":5===o.length&&(f=parseInt(o.substring(1),16));break;case"C":case"c":if(o.length>=3&&o.length<=4){const a=o.substring(1);if(t){f=parseInt(a,16);break}f=+a;if(Number.isNaN(f)&&Number.isInteger(parseInt(a,16)))return this._simpleFontToUnicode(e,!0)}break;case"u":l=getUnicodeForGlyph(o,i);-1!==l&&(f=l);break;default:switch(o){case"f_h":case"f_t":case"T_h":a[r]=o.replaceAll("_","");continue}}if(f>0&&f<=1114111&&Number.isInteger(f)){if(s&&f===+r){const e=getEncoding(s);if(e&&(o=e[r])){a[r]=String.fromCharCode(i[o]);continue}}a[r]=String.fromCodePoint(f)}}return a}async buildToUnicode(e){e.hasIncludedToUnicodeMap=e.toUnicode?.length>0;if(e.hasIncludedToUnicodeMap){!e.composite&&e.hasEncoding&&(e.fallbackToUnicode=this._simpleFontToUnicode(e));return e.toUnicode}if(!e.composite)return new ToUnicodeMap(this._simpleFontToUnicode(e));if(e.composite&&(e.cMap.builtInCMap&&!(e.cMap instanceof IdentityCMap)||"Adobe"===e.cidSystemInfo?.registry&&("GB1"===e.cidSystemInfo.ordering||"CNS1"===e.cidSystemInfo.ordering||"Japan1"===e.cidSystemInfo.ordering||"Korea1"===e.cidSystemInfo.ordering))){const{registry:t,ordering:a}=e.cidSystemInfo,n=Name.get(`${t}-${a}-UCS2`),s=await CMapFactory.create({encoding:n,fetchBuiltInCMap:this._fetchBuiltInCMapBound,useCMap:null}),r=[],i=[];e.cMap.forEach(function(e,t){if(t>65535)throw new FormatError("Max size of CID is 65,535");const a=s.lookup(t);if(a){i.length=0;for(let e=0,t=a.length;e>1;(0!==s||t.has(r))&&(a[r]=s)}return a}extractWidths(e,t,a){const n=this.xref;let s=[],r=0;const i=[];let o;if(a.composite){const t=e.get("DW");r="number"==typeof t?Math.ceil(t):1e3;const l=e.get("W");if(Array.isArray(l))for(let e=0,t=l.length;e{const t=l.get(e),n=new OperatorList;return r.getOperatorList({stream:t,task:a,resources:f,operatorList:n}).then(()=>{switch(n.fnArray[0]){case rt:this.#Ee(n,b);break;case st:b||this.#_e(n)}c[e]=n.getIR();for(const e of n.dependencies)s.add(e)}).catch(function(t){warn(`Type3 font resource "${e}" is not available.`);const a=new OperatorList;c[e]=a.getIR()})});this.#Pe=o.then(()=>{n.charProcOperatorList=c;if(this._bbox){n.isCharBBox=!0;n.bbox=this._bbox}});return this.#Pe}#Ee(e,a=NaN){const n=Util.normalizeRect(e.argsArray[0].slice(2)),s=n[2]-n[0],r=n[3]-n[1],i=Math.hypot(s,r);if(0===s||0===r){e.fnArray.splice(0,1);e.argsArray.splice(0,1)}else if(0===a||Math.round(i/a)>=10){this._bbox??=t.slice();Util.rectBoundingBox(...n,this._bbox)}let o=0,l=e.length;for(;o=ve&&r<=Pe;if(s.variableArgs)o>i&&info(`Command ${n}: expected [0, ${i}] args, but received ${o} args.`);else{if(o!==i){const e=this.nonProcessedArgs;for(;o>i;){e.push(t.shift());o--}for(;oEvaluatorPreprocessor.MAX_INVALID_PATH_OPS)throw new FormatError(`Invalid ${e}`);warn(`Skipping ${e}`);null!==t&&(t.length=0);continue}}this.preprocessCommand(r,t);e.fn=r;e.args=t;return!0}if(a===oa)return!1;if(null!==a){null===t&&(t=[]);t.push(a);if(t.length>33)throw new FormatError("Too many arguments")}}}preprocessCommand(e,t){switch(0|e){case ke:this.stateManager.save();break;case ye:this.stateManager.restore();break;case qe:this.stateManager.transform(t)}}}class DefaultAppearanceEvaluator extends EvaluatorPreprocessor{constructor(e){super(new StringStream(e))}parse(){const e={fn:0,args:[]},t={fontSize:0,fontName:"",fontColor:new Uint8ClampedArray(3)};try{for(;;){e.args.length=0;if(!this.read(e))break;if(0!==this.savedStatesDepth)continue;const{fn:a,args:n}=e;switch(0|a){case Ge:const[e,a]=n;e instanceof Name&&(t.fontName=e.name);"number"==typeof a&&a>0&&(t.fontSize=a);break;case dt:ColorSpaceUtils.rgb.getRgbItem(n,0,t.fontColor,0);break;case mt:ColorSpaceUtils.gray.getRgbItem(n,0,t.fontColor,0);break;case bt:ColorSpaceUtils.cmyk.getRgbItem(n,0,t.fontColor,0)}}}catch(e){warn(`parseDefaultAppearance - ignoring errors: "${e}".`)}return t}}function parseDefaultAppearance(e){return new DefaultAppearanceEvaluator(e).parse()}class AppearanceStreamEvaluator extends EvaluatorPreprocessor{constructor(e,t,a){super(e);this.stream=e;this.xref=t;this.globalColorSpaceCache=a;this.resources=e.dict?.get("Resources")}parse(){const e={fn:0,args:[]};let t={scaleFactor:1,fontSize:0,fontName:"",fontColor:new Uint8ClampedArray(3),fillColorSpace:ColorSpaceUtils.gray},a=!1;const n=[];try{for(;;){e.args.length=0;if(a||!this.read(e))break;const{fn:s,args:r}=e;switch(0|s){case ke:n.push({scaleFactor:t.scaleFactor,fontSize:t.fontSize,fontName:t.fontName,fontColor:t.fontColor.slice(),fillColorSpace:t.fillColorSpace});break;case ye:t=n.pop()||t;break;case Qe:t.scaleFactor*=Math.hypot(r[0],r[1]);break;case Ge:const[e,s]=r;e instanceof Name&&(t.fontName=e.name);"number"==typeof s&&s>0&&(t.fontSize=s*t.scaleFactor);break;case ot:t.fillColorSpace=ColorSpaceUtils.parse({cs:r[0],xref:this.xref,resources:this.resources,pdfFunctionFactory:this._pdfFunctionFactory,globalColorSpaceCache:this.globalColorSpaceCache,localColorSpaceCache:this._localColorSpaceCache});break;case ct:t.fillColorSpace.getRgbItem(r,0,t.fontColor,0);break;case dt:ColorSpaceUtils.rgb.getRgbItem(r,0,t.fontColor,0);break;case mt:ColorSpaceUtils.gray.getRgbItem(r,0,t.fontColor,0);break;case bt:ColorSpaceUtils.cmyk.getRgbItem(r,0,t.fontColor,0);break;case et:case tt:case at:case nt:a=!0}}}catch(e){warn(`parseAppearanceStream - ignoring errors: "${e}".`)}this.stream.reset();delete t.scaleFactor;delete t.fillColorSpace;return t}get _localColorSpaceCache(){return shadow(this,"_localColorSpaceCache",new LocalColorSpaceCache)}get _pdfFunctionFactory(){return shadow(this,"_pdfFunctionFactory",new PDFFunctionFactory({xref:this.xref}))}}function getPdfColor(e,t){if(e[0]===e[1]&&e[1]===e[2]){return`${numberToString(e[0]/255)} ${t?"g":"G"}`}return Array.from(e,e=>numberToString(e/255)).join(" ")+" "+(t?"rg":"RG")}class FakeUnicodeFont{static#ze=1;constructor(e,t){this.xref=e;this.widths=null;this.firstChar=1/0;this.lastChar=-1/0;this.fontFamily=t;const a=new OffscreenCanvas(1,1);this.ctxMeasure=a.getContext("2d",{willReadFrequently:!0});this.fontName=Name.get(`InvalidPDFjsFont_${t}_${FakeUnicodeFont.#ze++}`)}get fontDescriptorRef(){if(!FakeUnicodeFont._fontDescriptorRef){const e=new Dict(this.xref);e.setIfName("Type","FontDescriptor");e.set("FontName",this.fontName);e.set("FontFamily","MyriadPro Regular");e.set("FontBBox",[0,0,0,0]);e.setIfName("FontStretch","Normal");e.set("FontWeight",400);e.set("ItalicAngle",0);FakeUnicodeFont._fontDescriptorRef=this.xref.getNewPersistentRef(e)}return FakeUnicodeFont._fontDescriptorRef}get descendantFontRef(){const e=new Dict(this.xref);e.set("BaseFont",this.fontName);e.setIfName("Type","Font");e.setIfName("Subtype","CIDFontType0");e.setIfName("CIDToGIDMap","Identity");e.set("FirstChar",this.firstChar);e.set("LastChar",this.lastChar);e.set("FontDescriptor",this.fontDescriptorRef);e.set("DW",1e3);const t=[],a=[...this.widths].sort();let n=null,s=null;for(const[e,r]of a)if(n)if(e===n+s.length)s.push(r);else{t.push(n,s);n=e;s=[r]}else{n=e;s=[r]}n&&t.push(n,s);e.set("W",t);const r=new Dict(this.xref);r.set("Ordering","Identity");r.set("Registry","Adobe");r.set("Supplement",0);e.set("CIDSystemInfo",r);return this.xref.getNewPersistentRef(e)}get baseFontRef(){const e=new Dict(this.xref);e.set("BaseFont",this.fontName);e.setIfName("Type","Font");e.setIfName("Subtype","Type0");e.setIfName("Encoding","Identity-H");e.set("DescendantFonts",[this.descendantFontRef]);e.setIfName("ToUnicode","Identity-H");return this.xref.getNewPersistentRef(e)}get resources(){const e=new Dict(this.xref),t=new Dict(this.xref);t.set(this.fontName.name,this.baseFontRef);e.set("Font",t);return e}_createContext(){this.widths=new Map;this.ctxMeasure.font=`1000px ${this.fontFamily}`;return this.ctxMeasure}createFontResources(e){const t=this._createContext();for(const a of e.split(/\r\n?|\n/))for(const e of a.split("")){const a=e.charCodeAt(0);if(this.widths.has(a))continue;const n=t.measureText(e),s=Math.ceil(n.width);this.widths.set(a,s);this.firstChar=Math.min(a,this.firstChar);this.lastChar=Math.max(a,this.lastChar)}return this.resources}static getFirstPositionInfo(e,t,a){const[n,i,o,l]=e;let f=o-n,c=l-i;t%180!=0&&([f,c]=[c,f]);const h=s*a;return{coords:[0,c+r*a-h],bbox:[0,0,f,c],matrix:0!==t?getRotationMatrix(t,c,h):void 0}}createAppearance(e,t,a,n,i,o){const l=this._createContext(),f=[];let c=-1/0;for(const t of e.split(/\r\n?|\n/)){f.push(t);const e=l.measureText(t).width;c=Math.max(c,e);for(const e of codePointIter(t)){const t=String.fromCodePoint(e);let a=this.widths.get(e);if(void 0===a){const n=l.measureText(t);a=Math.ceil(n.width);this.widths.set(e,a);this.firstChar=Math.min(e,this.firstChar);this.lastChar=Math.max(e,this.lastChar)}}}c*=n/1e3;const[h,u,m,p]=t;let d=m-h,g=p-u;a%180!=0&&([d,g]=[g,d]);let b=1;c>d&&(b=d/c);let w=1;const j=s*n,k=r*n,y=j*f.length;y>g&&(w=g/y);const q=n*Math.min(b,w),v=["q",`0 0 ${numberToString(d)} ${numberToString(g)} re W n`,"BT",`1 0 0 1 0 ${numberToString(g+k)} Tm 0 Tc ${getPdfColor(i,!0)}`,`/${this.fontName.name} ${numberToString(q)} Tf`],{resources:S}=this;if(1!==(o="number"==typeof o&&o>=0&&o<=1?o:1)){v.push("/R0 gs");const e=new Dict(this.xref),t=new Dict(this.xref);t.set("ca",o);t.set("CA",o);t.setIfName("Type","ExtGState");e.set("R0",t);S.set("ExtGState",e)}const x=numberToString(j);for(const e of f)v.push(`0 -${x} Td <${stringToUTF16HexString(e)}> Tj`);v.push("ET","Q");const C=v.join("\n"),F=new Dict(this.xref);F.setIfName("Subtype","Form");F.setIfName("Type","XObject");F.set("BBox",[0,0,d,g]);F.set("Length",C.length);F.set("Resources",S);if(a){const e=getRotationMatrix(a,d,g);F.set("Matrix",e)}const T=new StringStream(C);T.dict=F;return T}}const Ri=["m/d","m/d/yy","mm/dd/yy","mm/yy","d-mmm","d-mmm-yy","dd-mmm-yy","yy-mm-dd","mmm-yy","mmmm-yy","mmm d, yyyy","mmmm d, yyyy","m/d/yy h:MM tt","m/d/yy HH:MM"],Hi=["HH:MM","h:MM tt","HH:MM:ss","h:MM:ss tt"];class NameOrNumberTree{constructor(e,t,a){this.root=e;this.xref=t;this._type=a}getAll(e=!1){const t=new Map;if(!this.root)return t;const a=this.xref,n=new RefSet;this.root instanceof Ref&&n.put(this.root);const s=[this.root];for(;s.length>0;){const r=a.fetchIfRef(s.shift());if(!(r instanceof Dict))continue;if(r.has("Kids")){const e=r.get("Kids");if(!Array.isArray(e))continue;for(const t of e){if(t instanceof Ref){if(n.has(t))throw new FormatError(`Duplicate entry in "${this._type}" tree.`);n.put(t)}s.push(t)}continue}const i=r.get(this._type);if(Array.isArray(i))for(let n=0,s=i.length;n10){warn(`Search depth limit reached for "${this._type}" tree.`);return null}const s=a.get("Kids");if(!Array.isArray(s))return null;let r=0,i=s.length-1;for(;r<=i;){const n=r+i>>1,o=t.fetchIfRef(s[n]),l=o.get("Limits");if(et.fetchIfRef(l[1]))){a=o;break}r=n+1}}if(r>i)return null}const s=a.get(this._type);if(Array.isArray(s)){let a=0,n=s.length-2;for(;a<=n;){const r=a+n>>1,i=r+(1&r),o=t.fetchIfRef(s[i]);if(eo))return s[i+1];a=i+2}}}return null}get(e){return this.xref.fetchIfRef(this.getRaw(e))}}class NameTree extends NameOrNumberTree{constructor(e,t){super(e,t,"Names")}}class NumberTree extends NameOrNumberTree{constructor(e,t){super(e,t,"Nums")}}function clearGlobalCaches(){!function clearPatternCaches(){Va=Object.create(null)}();!function clearPrimitiveCaches(){la=Object.create(null);fa=Object.create(null);ca=Object.create(null)}();!function clearUnicodeCaches(){wn.clear()}();JBig2CCITTFaxImage.cleanup();JpxImage.cleanup()}function pickPlatformItem(e){if(e instanceof Dict)for(const t of["UF","F","Unix","Mac","DOS"])if(e.has(t))return e.get(t);return null}class FileSpec{#Le=!1;constructor(e,t=!1){if(e instanceof Dict){this.root=e;e.has("FS")&&(this.fs=e.get("FS"));e.has("RF")&&warn("Related file specifications are not supported");t||(e.has("EF")?this.#Le=!0:warn("Non-embedded file specifications are not supported"))}}get filename(){const e=pickPlatformItem(this.root);return e&&"string"==typeof e?stringToPDFString(e,!0).replaceAll("\\\\","\\").replaceAll("\\/","/").replaceAll("\\","/"):""}get content(){if(!this.#Le)return null;const e=pickPlatformItem(this.root?.get("EF"));if(e instanceof BaseStream)return e.getBytes();warn("Embedded file specification points to non-existing/invalid content");return null}get description(){const e=this.root?.get("Desc");return e&&"string"==typeof e?stringToPDFString(e):""}get serializable(){const{filename:e,content:t,description:a}=this;return{rawFilename:e,filename:(n=e,n.substring(n.lastIndexOf("/")+1))||"unnamed",content:t,description:a};var n}}const Bi=0,Di=-2,Mi=-3,Ni=-4,Pi=-5,Ei=-6,_i=-9;function isWhitespace(e,t){const a=e[t];return" "===a||"\n"===a||"\r"===a||"\t"===a}class XMLParserBase{_resolveEntities(e){return e.replaceAll(/&([^;]+);/g,(e,t)=>{if("#x"===t.substring(0,2))return String.fromCodePoint(parseInt(t.substring(2),16));if("#"===t.substring(0,1))return String.fromCodePoint(parseInt(t.substring(1),10));switch(t){case"lt":return"<";case"gt":return">";case"amp":return"&";case"quot":return'"';case"apos":return"'"}return this.onResolveEntity(t)})}_parseContent(e,t){const a=[];let n=t;function skipWs(){for(;n"!==e[n]&&"/"!==e[n];)++n;const s=e.substring(t,n);skipWs();for(;n"!==e[n]&&"/"!==e[n]&&"?"!==e[n];){skipWs();let t="",s="";for(;n"!==e[a]&&"?"!==e[a]&&"/"!==e[a];)++a;const n=e.substring(t,a);!function skipWs(){for(;a"!==e[a+1]);)++a;return{name:n,value:e.substring(s,a),parsed:a-t}}parseXml(e){let t=0;for(;t",a);if(t<0){this.onError(_i);return}this.onEndElement(e.substring(a,t));a=t+1;break;case"?":++a;const n=this._parseProcessingInstruction(e,a);if("?>"!==e.substring(a+n.parsed,a+n.parsed+2)){this.onError(Mi);return}this.onPi(n.name,n.value);a+=n.parsed+2;break;case"!":if("--"===e.substring(a+1,a+3)){t=e.indexOf("--\x3e",a+3);if(t<0){this.onError(Pi);return}this.onComment(e.substring(a+3,t));a=t+3}else if("[CDATA["===e.substring(a+1,a+8)){t=e.indexOf("]]>",a+8);if(t<0){this.onError(Di);return}this.onCdata(e.substring(a+8,t));a=t+3}else{if("DOCTYPE"!==e.substring(a+1,a+8)){this.onError(Ei);return}{const n=e.indexOf("[",a+8);let s=!1;t=e.indexOf(">",a+8);if(t<0){this.onError(Ni);return}if(n>0&&t>n){t=e.indexOf("]>",a+8);if(t<0){this.onError(Ni);return}s=!0}const r=e.substring(a+8,t+(s?1:0));this.onDoctype(r);a=t+(s?2:1)}}break;default:const s=this._parseContent(e,a);if(null===s){this.onError(Ei);return}let r=!1;if("/>"===e.substring(a+s.parsed,a+s.parsed+2))r=!0;else if(">"!==e.substring(a+s.parsed,a+s.parsed+1)){this.onError(_i);return}this.onBeginElement(s.name,s.attributes,r);a+=s.parsed+(r?2:1)}}else{for(;ae.textContent).join(""):this.nodeValue||""}get children(){return this.childNodes||[]}hasChildNodes(){return this.childNodes?.length>0}searchNode(e,t){if(t>=e.length)return this;const a=e[t];if(a.name.startsWith("#")&&t0){n.push([s,0]);s=s.childNodes[0]}else{if(0===n.length)return null;for(;0!==n.length;){const[e,t]=n.pop(),a=t+1;if(a");for(const t of this.childNodes)t.dump(e);e.push(``)}else this.nodeValue?e.push(`>${encodeToXmlString(this.nodeValue)}`):e.push("/>")}else e.push(encodeToXmlString(this.nodeValue))}}class SimpleXMLParser extends XMLParserBase{constructor({hasAttributes:e=!1,lowerCaseName:t=!1}){super();this._currentFragment=null;this._stack=null;this._errorCode=Bi;this._hasAttributes=e;this._lowerCaseName=t}parseFromString(e){this._currentFragment=[];this._stack=[];this._errorCode=Bi;this.parseXml(e);if(this._errorCode!==Bi)return;const[t]=this._currentFragment;return t?{documentElement:t}:void 0}onText(e){if(function isWhitespaceString(e){for(let t=0,a=e.length;t\\376\\377([^<]+)/g,function(e,t){const a=t.replaceAll(/\\([0-3])([0-7])([0-7])/g,function(e,t,a,n){return String.fromCharCode(64*t+8*a+1*n)}).replaceAll(/&(amp|apos|gt|lt|quot);/g,function(e,t){switch(t){case"amp":return"&";case"apos":return"'";case"gt":return">";case"lt":return"<";case"quot":return'"'}throw new Error(`_repair: ${t} isn't defined.`)}),n=[">"];for(let e=0,t=a.length;e=32&&t<127&&60!==t&&62!==t&&38!==t?n.push(String.fromCharCode(t)):n.push("&#x"+(65536+t).toString(16).substring(1)+";")}return n.join("")})}_getSequence(e){const t=e.nodeName;return"rdf:bag"!==t&&"rdf:seq"!==t&&"rdf:alt"!==t?null:e.childNodes.filter(e=>"rdf:li"===e.nodeName)}_parseArray(e){if(!e.hasChildNodes())return;const[t]=e.childNodes,a=this._getSequence(t)||[];this._metadataMap.set(e.nodeName,a.map(e=>e.textContent.trim()))}_parse(e){let t=e.documentElement;if("rdf:rdf"!==t.nodeName){t=t.firstChild;for(;t&&"rdf:rdf"!==t.nodeName;)t=t.nextSibling}if(t&&"rdf:rdf"===t.nodeName&&t.hasChildNodes())for(const e of t.childNodes)if("rdf:description"===e.nodeName)for(const t of e.childNodes){const e=t.nodeName;switch(e){case"#text":continue;case"dc:creator":case"dc:subject":this._parseArray(t);continue}this._metadataMap.set(e,t.textContent.trim())}}get serializable(){return{parsedData:this._metadataMap,rawData:this._data}}}const zi=1,Xi=2,Wi=3,Ki=4,Gi=5;class StructTreeRoot{constructor(e,t,a){this.xref=e;this.dict=t;this.ref=a instanceof Ref?a:null;this.roleMap=new Map;this.structParentIds=null;this.kidRefToPosition=void 0;this.parentTree=null}getKidPosition(e){if(void 0===this.kidRefToPosition){const e=this.dict.get("K");if(Array.isArray(e)){const t=this.kidRefToPosition=new Map;for(let a=0,n=e.length;a=0||(e.parentTreeId=a++);i=!1}}if(i){for(const e of t.values())for(const t of e){delete t.parentTreeId;delete t.structTreeParent}return!1}return!0}async updateStructureTree({newAnnotationsByPage:e,pdfManager:t,changes:a}){const{ref:n,xref:s}=this,r=this.dict.clone(),i=new RefSetCache;i.put(n,r);let o,l=r.getRaw("ParentTree");if(l instanceof Ref)o=s.fetch(l);else{o=l;l=s.getNewTemporaryRef();r.set("ParentTree",l)}o=o.clone();i.put(l,o);let f=o.getRaw("Nums"),c=null;if(f instanceof Ref){c=f;f=s.fetch(c)}f=f.slice();c||o.set("Nums",f);const h=await StructTreeRoot.#Xe({newAnnotationsByPage:e,structTreeRootRef:n,structTreeRoot:this,kids:null,nums:f,xref:s,pdfManager:t,changes:a,cache:i});if(-1!==h){r.set("ParentTreeNextKey",h);c&&i.put(c,f);for(const[e,t]of i.items())a.put(e,{data:t})}}static async#Xe({newAnnotationsByPage:e,structTreeRootRef:t,structTreeRoot:a,kids:n,nums:s,xref:r,pdfManager:i,changes:o,cache:l}){const f=Name.get("OBJR");let c,h=-1;for(const[u,m]of e){const e=await i.getPage(u),{ref:p}=e,d=p instanceof Ref;for(const{accessibilityData:i,ref:g,parentTreeId:b,structTreeParent:w}of m){if(!i?.type)continue;const{structParent:m}=i;if(a&&Number.isInteger(m)&&m>=0){let t=(c||=new Map).get(u);if(void 0===t){t=new StructTreePage(a,e.pageDict).collectObjects(p);c.set(u,t)}const n=t?.get(m);if(n){const e=r.fetch(n).clone();StructTreeRoot.#Ke(e,i);o.put(n,{data:e});continue}}h=Math.max(h,b);const j=r.getNewTemporaryRef(),k=new Dict(r);StructTreeRoot.#Ke(k,i);await this.#Ge({structTreeParent:w,tagDict:k,newTagRef:j,structTreeRootRef:t,fallbackKids:n,xref:r,cache:l});const y=new Dict(r);k.set("K",y);y.set("Type",f);d&&y.set("Pg",p);y.set("Obj",g);l.put(j,k);s.push(b,j)}}return h+1}static#Ke(e,{type:t,title:a,lang:n,alt:s,expanded:r,actualText:i}){e.set("S",Name.get(t));a&&e.set("T",stringToAsciiOrUTF16BE(a));n&&e.set("Lang",stringToAsciiOrUTF16BE(n));s&&e.set("Alt",stringToAsciiOrUTF16BE(s));r&&e.set("E",stringToAsciiOrUTF16BE(r));i&&e.set("ActualText",stringToAsciiOrUTF16BE(i))}static#We({elements:e,xref:t,pageDict:a,numberTree:n}){const s=new Map;for(const t of e)if(t.structTreeParentId){const e=parseInt(t.structTreeParentId.split("_mc")[1],10);s.getOrInsertComputed(e,makeArr).push(t)}const r=a.get("StructParents");if(!Number.isInteger(r))return;const i=n.get(r),updateElement=(e,a,n)=>{const r=s.get(e);if(r){const e=a.getRaw("P"),s=t.fetchIfRef(e);if(e instanceof Ref&&s instanceof Dict){const e={ref:n,dict:a};for(const t of r)t.structTreeParent=e}return!0}return!1};for(const e of i){if(!(e instanceof Ref))continue;const a=t.fetch(e),n=a.get("K");if(Number.isInteger(n))updateElement(n,a,e);else if(Array.isArray(n))for(let s of n){s=t.fetchIfRef(s);if(Number.isInteger(s)&&updateElement(s,a,e))break;if(!(s instanceof Dict))continue;if(!isName(s.get("Type"),"MCR"))break;const n=s.get("MCID");if(Number.isInteger(n)&&updateElement(n,a,e))break}}}static async#Ge({structTreeParent:e,tagDict:t,newTagRef:a,structTreeRootRef:n,fallbackKids:s,xref:r,cache:i}){let o,l=null;if(e){({ref:l}=e);o=e.dict.getRaw("P")||n}else o=n;t.set("P",o);const f=r.fetchIfRef(o);if(!f){s.push(a);return}let c=i.get(o);if(!c){c=f.clone();i.put(o,c)}const h=c.getRaw("K");let u=h instanceof Ref?i.get(h):null;if(!u){u=r.fetchIfRef(h);u=Array.isArray(u)?u.slice():[h];const e=r.getNewTemporaryRef();c.set("K",e);i.put(e,u)}const m=u.indexOf(l);u.splice(m>=0?m+1:u.length,0,a)}}class StructElementNode{constructor(e,t){this.tree=e;this.xref=e.xref;this.dict=t;this.kids=[];this.parseKids()}get role(){const e=this.dict.get("S"),t=e instanceof Name?e.name:"",{root:a}=this.tree;return a.roleMap.get(t)??t}get mathML(){let e=this.dict.get("AF")||[];Array.isArray(e)||(e=[e]);for(let t of e){t=this.xref.fetchIfRef(t);if(!(t instanceof Dict))continue;if(!isName(t.get("Type"),"Filespec"))continue;if(!isName(t.get("AFRelationship"),"Supplement"))continue;const e=t.get("EF");if(!(e instanceof Dict))continue;const a=e.get("UF")||e.get("F");if(a instanceof BaseStream&&(isName(a.dict.get("Type"),"EmbeddedFile")&&isName(a.dict.get("Subtype"),"application/mathml+xml")))return stringToUTF8String(a.getString())}const t=this.dict.get("A");if(t instanceof Dict){if(isName(t.get("O"),"MSFT_Office")){const e=t.get("MSFT_MathML");return e?stringToPDFString(e):null}}return null}parseKids(){let e=null;const t=this.dict.getRaw("Pg");t instanceof Ref&&(e=t.toString());const a=this.dict.get("K");if(Array.isArray(a))for(const t of a){const a=this.parseKid(e,this.xref.fetchIfRef(t));a&&this.kids.push(a)}else{const t=this.parseKid(e,a);t&&this.kids.push(t)}}parseKid(e,t){if(Number.isInteger(t))return this.tree.pageDict.objId!==e?null:new StructElement({type:zi,mcid:t,pageObjId:e});if(!(t instanceof Dict))return null;const a=t.getRaw("Pg");a instanceof Ref&&(e=a.toString());const n=t.get("Type")instanceof Name?t.get("Type").name:null;if("MCR"===n){if(this.tree.pageDict.objId!==e)return null;const a=t.getRaw("Stm");return new StructElement({type:Xi,refObjId:a instanceof Ref?a.toString():null,pageObjId:e,mcid:t.get("MCID")})}if("OBJR"===n){if(this.tree.pageDict.objId!==e)return null;const a=t.getRaw("Obj");return new StructElement({type:Wi,refObjId:a instanceof Ref?a.toString():null,pageObjId:e})}return new StructElement({type:Gi,dict:t})}}class StructElement{constructor({type:e,dict:t=null,mcid:a=null,pageObjId:n=null,refObjId:s=null}){this.type=e;this.dict=t;this.mcid=a;this.pageObjId=n;this.refObjId=s;this.parentNode=null}}class StructTreePage{constructor(e,t){this.root=e;this.xref=e?.xref??null;this.rootDict=e?.dict??null;this.pageDict=t;this.nodes=[]}collectObjects(e){if(!(this.root&&this.rootDict&&e instanceof Ref))return null;const t=this.rootDict.get("ParentTree");if(!t)return null;const a=this.root.structParentIds?.get(e);if(!a)return null;const n=new Map,s=new NumberTree(t,this.xref);for(const[e]of a){const t=s.getRaw(e);t instanceof Ref&&n.set(e,t)}return n}parse(e){if(!(this.root&&this.rootDict&&e instanceof Ref))return;const{parentTree:t}=this.root;if(!t)return;const a=this.pageDict.get("StructParents"),n=this.root.structParentIds?.get(e);if(!Number.isInteger(a)&&!n)return;const s=new Map;if(Number.isInteger(a)){const e=t.get(a);if(Array.isArray(e))for(const t of e)t instanceof Ref&&this.addNode(this.xref.fetch(t),s)}if(n)for(const[e,a]of n){const n=t.get(e);if(n){const e=this.addNode(this.xref.fetchIfRef(n),s);1===e?.kids?.length&&e.kids[0].type===Wi&&(e.kids[0].type=a)}}}addNode(e,t,a=0){if(a>40){warn("StructTree MAX_DEPTH reached.");return null}if(!(e instanceof Dict))return null;if(t.has(e))return t.get(e);const n=new StructElementNode(this,e);t.set(e,n);switch(n.role){case"L":case"LBody":case"LI":case"Table":case"THead":case"TBody":case"TFoot":case"TR":for(const e of n.kids)e.type===Gi&&this.addNode(e.dict,t,a-1)}const s=e.get("P");if(!(s instanceof Dict)||isName(s.get("Type"),"StructTreeRoot")){this.addTopLevelNode(e,n)||t.delete(e);return n}const r=this.addNode(s,t,a+1);if(!r)return n;let i=!1;for(const t of r.kids)if(t.type===Gi&&t.dict===e){t.parentNode=n;i=!0}i||t.delete(e);return n}addTopLevelNode(e,t){const a=this.root.getKidPosition(e.objId);if(isNaN(a))return!1;-1!==a&&(this.nodes[a]=t);return!0}get serializable(){function nodeToSerializable(e,t,a=0){if(a>40){warn("StructTree too deep to be fully serialized.");return}const n=Object.create(null);n.role=e.role;n.children=[];t.children.push(n);let s=e.dict.get("Alt");"string"!=typeof s&&(s=e.dict.get("ActualText"));"string"==typeof s&&(n.alt=stringToPDFString(s));if("Formula"===n.role){const{mathML:t}=e;t&&(n.mathML=t)}const r=e.dict.get("A");if(r instanceof Dict){const e=lookupNormalRect(r.getArray("BBox"),null);if(e)n.bbox=e;else{const e=r.get("Width"),t=r.get("Height");"number"==typeof e&&e>0&&"number"==typeof t&&t>0&&(n.bbox=[0,0,e,t])}}const i=e.dict.get("Lang");"string"==typeof i&&(n.lang=stringToPDFString(i));for(const t of e.kids){const e=t.type===Gi?t.parentNode:null;e?nodeToSerializable(e,n,a+1):t.type===zi||t.type===Xi?n.children.push({type:"content",id:`p${t.pageObjId}_mc${t.mcid}`}):t.type===Wi?n.children.push({type:"object",id:t.refObjId}):t.type===Ki&&n.children.push({type:"annotation",id:`pdfjs_internal_id_${t.refObjId}`})}}const e=Object.create(null);e.children=[];e.role="Root";for(const t of this.nodes)t&&nodeToSerializable(t,e);return e}}const Vi=function _isValidExplicitDest(e,t,a){if(!Array.isArray(a)||a.length<2)return!1;const[n,s,...r]=a;if(!e(n)&&!Number.isInteger(n))return!1;if(!t(s))return!1;const i=r.length;let o=!0;switch(s.name){case"XYZ":if(i<2||i>3)return!1;break;case"Fit":case"FitB":return 0===i;case"FitH":case"FitBH":case"FitV":case"FitBV":if(i>1)return!1;break;case"FitR":if(4!==i)return!1;o=!1;break;default:return!1}for(const e of r)if(!("number"==typeof e||o&&null===e))return!1;return!0}.bind(null,e=>e instanceof Ref,isName);function fetchDest(e){e instanceof Dict&&(e=e.get("D"));return Vi(e)?e:null}function fetchRemoteDest(e){let t=e.get("D");if(t){t instanceof Name&&(t=t.name);if("string"==typeof t)return stringToPDFString(t,!0);if(Vi(t))return JSON.stringify(t)}return null}class Catalog{#Ve=null;#$e=null;builtInCMapCache=new Map;fontCache=new RefSetCache;globalColorSpaceCache=new GlobalColorSpaceCache;globalImageCache=new GlobalImageCache;nonBlendModesSet=new RefSet;pageDictCache=new RefSetCache;pageIndexCache=new RefSetCache;pageKidsCountCache=new RefSetCache;standardFontDataCache=new Map;systemFontCache=new Map;constructor(e,t){this.pdfManager=e;this.xref=t;this.#$e=t.getCatalogObj();if(!(this.#$e instanceof Dict))throw new FormatError("Catalog object is not a dictionary.");this.toplevelPagesDict}cloneDict(){return this.#$e.clone()}get version(){const e=this.#$e.get("Version");if(e instanceof Name){if(ua.test(e.name))return shadow(this,"version",e.name);warn(`Invalid PDF catalog version: ${e.name}`)}return shadow(this,"version",null)}get lang(){const e=this.#$e.get("Lang");return shadow(this,"lang",e&&"string"==typeof e?stringToPDFString(e):null)}get needsRendering(){const e=this.#$e.get("NeedsRendering");return shadow(this,"needsRendering","boolean"==typeof e&&e)}get collection(){let e=null;try{const t=this.#$e.get("Collection");t instanceof Dict&&t.size>0&&(e=t)}catch(e){if(e instanceof MissingDataException)throw e;info("Cannot fetch Collection entry; assuming no collection is present.")}return shadow(this,"collection",e)}get acroForm(){let e=null;try{const t=this.#$e.get("AcroForm");t instanceof Dict&&t.size>0&&(e=t)}catch(e){if(e instanceof MissingDataException)throw e;info("Cannot fetch AcroForm entry; assuming no forms are present.")}return shadow(this,"acroForm",e)}get acroFormRef(){const e=this.#$e.getRaw("AcroForm");return shadow(this,"acroFormRef",e instanceof Ref?e:null)}get metadata(){const e=this.#$e.getRaw("Metadata");if(!(e instanceof Ref))return shadow(this,"metadata",null);let t=null;try{const a=this.xref.fetch(e,!this.xref.encrypt?.encryptMetadata);if(a instanceof BaseStream&&a.dict instanceof Dict){const e=a.dict.get("Type"),n=a.dict.get("Subtype");if(isName(e,"Metadata")&&isName(n,"XML")){const e=stringToUTF8String(a.getString());e&&(t=new MetadataParser(e).serializable)}}}catch(e){if(e instanceof MissingDataException)throw e;info(`Skipping invalid Metadata: "${e}".`)}return shadow(this,"metadata",t)}get markInfo(){let e=null;try{e=this.#Ye()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read mark info.")}return shadow(this,"markInfo",e)}#Ye(){const e=this.#$e.get("MarkInfo");if(!(e instanceof Dict))return null;const t={Marked:!1,UserProperties:!1,Suspects:!1};for(const a in t){const n=e.get(a);"boolean"==typeof n&&(t[a]=n)}return t}get hasStructTree(){return this.#$e.has("StructTreeRoot")}get structTreeRoot(){let e=null;try{e=this.#Je()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable read to structTreeRoot info.")}return shadow(this,"structTreeRoot",e)}#Je(){const e=this.#$e.getRaw("StructTreeRoot"),t=this.xref.fetchIfRef(e);if(!(t instanceof Dict))return null;const a=new StructTreeRoot(this.xref,t,e);a.init();return a}get toplevelPagesDict(){const e=this.#$e.get("Pages");if(!(e instanceof Dict))throw new FormatError("Invalid top-level pages dictionary.");return shadow(this,"toplevelPagesDict",e)}get documentOutline(){let e=null;try{e=this.#Qe()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read document outline.")}return shadow(this,"documentOutline",e)}#Qe(e={}){let t=this.#$e.get("Outlines");if(!(t instanceof Dict))return null;t=t.getRaw("First");if(!(t instanceof Ref))return null;const a={items:[]},n=[{obj:t,parent:a}],s=new RefSet;s.put(t);const r=this.xref,i=new Uint8ClampedArray(3);for(;n.length>0;){const a=n.shift(),o=r.fetchIfRef(a.obj);if(null===o)continue;o.has("Title")||warn("Invalid outline item encountered.");const l={url:null,dest:null,action:null};Catalog.parseDestDictionary({destDict:o,resultObj:l,docBaseUrl:this.baseUrl,docAttachments:this.attachments});const f=o.get("Title"),c=o.get("F")||0,h=o.getArray("C"),u=o.get("Count");let m=i;!isNumberArray(h,3)||0===h[0]&&0===h[1]&&0===h[2]||(m=ColorSpaceUtils.rgb.getRgb(h,0));const p={action:l.action,attachment:l.attachment,dest:l.dest,url:l.url,unsafeUrl:l.unsafeUrl,newWindow:l.newWindow,setOCGState:l.setOCGState,title:"string"==typeof f?stringToPDFString(f):"",color:m,count:Number.isInteger(u)?u:void 0,bold:!!(2&c),italic:!!(1&c),items:[]};e.keepRawDict&&(p.rawDict=o);a.parent.items.push(p);t=o.getRaw("First");if(t instanceof Ref&&!s.has(t)){n.push({obj:t,parent:p});s.put(t)}t=o.getRaw("Next");if(t instanceof Ref&&!s.has(t)){n.push({obj:t,parent:a.parent});s.put(t)}}return a.items.length>0?a.items:null}get documentOutlineForEditor(){let e=null;try{e=this.#Qe({keepRawDict:!0})}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read document outline.")}return shadow(this,"documentOutlineForEditor",e)}get permissions(){let e=null;try{e=this.#Ze()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read permissions.")}return shadow(this,"permissions",e)}#Ze(){const e=this.xref.trailer.get("Encrypt");if(!(e instanceof Dict))return null;let t=e.get("P");if("number"!=typeof t)return null;t+=2**32;const a=[];for(const e in y){const n=y[e];t&n&&a.push(n)}return a}get optionalContentConfig(){let e=null;try{const t=this.#$e.get("OCProperties");if(!t)return shadow(this,"optionalContentConfig",null);const a=t.get("D");if(!a)return shadow(this,"optionalContentConfig",null);const n=t.get("OCGs");if(!Array.isArray(n))return shadow(this,"optionalContentConfig",null);const s=new RefSetCache;for(const e of n)e instanceof Ref&&!s.has(e)&&s.put(e,this.#et(e));e=this.#tt(a,s)}catch(e){if(e instanceof MissingDataException)throw e;warn(`Unable to read optional content config: ${e}`)}return shadow(this,"optionalContentConfig",e)}#et(e){const t=this.xref.fetch(e),a={id:e.toString(),name:null,intent:null,usage:{print:null,view:null},rbGroups:[]},n=t.get("Name");"string"==typeof n&&(a.name=stringToPDFString(n));let s=t.getArray("Intent");Array.isArray(s)||(s=[s]);s.every(e=>e instanceof Name)&&(a.intent=s.map(e=>e.name));const r=t.get("Usage");if(!(r instanceof Dict))return a;const i=a.usage,o=r.get("Print");if(o instanceof Dict){const e=o.get("PrintState");if(e instanceof Name)switch(e.name){case"ON":case"OFF":i.print={printState:e.name}}}const l=r.get("View");if(l instanceof Dict){const e=l.get("ViewState");if(e instanceof Name)switch(e.name){case"ON":case"OFF":i.view={viewState:e.name}}}return a}#tt(e,t){function parseOnOff(e){const a=[];if(Array.isArray(e))for(const n of e)n instanceof Ref&&t.has(n)&&a.push(n.toString());return a}function parseOrder(e,a=0){if(!Array.isArray(e))return null;const s=[];for(const r of e){if(r instanceof Ref&&t.has(r)){n.put(r);s.push(r.toString());continue}const e=parseNestedOrder(r,a);e&&s.push(e)}if(a>0)return s;const r=[];for(const[e]of t.items())n.has(e)||r.push(e.toString());r.length&&s.push({name:null,order:r});return s}function parseNestedOrder(e,t){if(++t>s){warn("parseNestedOrder - reached MAX_NESTED_LEVELS.");return null}const n=a.fetchIfRef(e);if(!Array.isArray(n))return null;const r=a.fetchIfRef(n[0]);if("string"!=typeof r)return null;const i=parseOrder(n.slice(1),t);return i?.length?{name:stringToPDFString(r),order:i}:null}const a=this.xref,n=new RefSet,s=10;!function parseRBGroups(e){if(Array.isArray(e))for(const n of e){const e=a.fetchIfRef(n);if(!Array.isArray(e)||!e.length)continue;const s=new Set;for(const a of e)if(a instanceof Ref&&t.has(a)&&!s.has(a.toString())){s.add(a.toString());t.get(a).rbGroups.push(s)}}}(e.get("RBGroups"));return{name:"string"==typeof e.get("Name")?stringToPDFString(e.get("Name")):null,creator:"string"==typeof e.get("Creator")?stringToPDFString(e.get("Creator")):null,baseState:e.get("BaseState")instanceof Name?e.get("BaseState").name:null,on:parseOnOff(e.get("ON")),off:parseOnOff(e.get("OFF")),order:parseOrder(e.get("Order")),groups:[...t]}}setActualNumPages(e=null){this.#Ve=e}get hasActualNumPages(){return null!==this.#Ve}get _pagesCount(){const e=this.toplevelPagesDict.get("Count");if(!Number.isInteger(e))throw new FormatError("Page count in top-level pages dictionary is not an integer.");return shadow(this,"_pagesCount",e)}get numPages(){return this.#Ve??this._pagesCount}get destinations(){const e=this.#at(),t=Object.create(null);for(const a of e)if(a instanceof NameTree)for(const[e,n]of a.getAll()){const a=fetchDest(n);a&&(t[stringToPDFString(e,!0)]=a)}else if(a instanceof Dict)for(const[e,n]of a){const a=fetchDest(n);a&&(t[stringToPDFString(e,!0)]||=a)}return shadow(this,"destinations",t)}getDestination(e){if(Object.hasOwn(this,"destinations"))return this.destinations[e]??null;const t=this.#at();for(const a of t)if(a instanceof NameTree||a instanceof Dict){const t=fetchDest(a.get(e));if(t)return t}if(t.length){const t=this.destinations[e];if(t)return t}return null}#at(){const e=this.#$e.get("Names"),t=[];e?.has("Dests")&&t.push(new NameTree(e.getRaw("Dests"),this.xref));this.#$e.has("Dests")&&t.push(this.#$e.get("Dests"));return t}get rawPageLabels(){const e=this.#$e.getRaw("PageLabels");if(!e)return null;return new NumberTree(e,this.xref).getAll()}get pageLabels(){let e=null;try{e=this.#nt()}catch(e){if(e instanceof MissingDataException)throw e;warn("Unable to read page labels.")}return shadow(this,"pageLabels",e)}#nt(){const e=this.rawPageLabels;if(!e)return null;const t=new Array(this.numPages);let a=null,n="",s="",r=1;for(let i=0,o=this.numPages;i=1))throw new FormatError("Invalid start in PageLabel dictionary.");r=e}else r=1}switch(a){case"D":s=r;break;case"R":case"r":s=toRomanNumerals(r,"r"===a);break;case"A":case"a":const e=26,t="a"===a?97:65,n=r-1;s=String.fromCharCode(t+n%e).repeat(Math.floor(n/e)+1);break;default:if(a)throw new FormatError(`Invalid style "${a}" in PageLabel dictionary.`);s=""}t[i]=n+s;r++}return t}get pageLayout(){const e=this.#$e.get("PageLayout");let t="";if(e instanceof Name)switch(e.name){case"SinglePage":case"OneColumn":case"TwoColumnLeft":case"TwoColumnRight":case"TwoPageLeft":case"TwoPageRight":t=e.name}return shadow(this,"pageLayout",t)}get pageMode(){const e=this.#$e.get("PageMode");let t="UseNone";if(e instanceof Name)switch(e.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"FullScreen":case"UseOC":case"UseAttachments":t=e.name}return shadow(this,"pageMode",t)}get viewerPreferences(){const e=this.#$e.get("ViewerPreferences");if(!(e instanceof Dict))return shadow(this,"viewerPreferences",null);let t=null;for(const[a,n]of e){let e;switch(a){case"HideToolbar":case"HideMenubar":case"HideWindowUI":case"FitWindow":case"CenterWindow":case"DisplayDocTitle":case"PickTrayByPDFSize":"boolean"==typeof n&&(e=n);break;case"NonFullScreenPageMode":if(n instanceof Name)switch(n.name){case"UseNone":case"UseOutlines":case"UseThumbs":case"UseOC":e=n.name;break;default:e="UseNone"}break;case"Direction":if(n instanceof Name)switch(n.name){case"L2R":case"R2L":e=n.name;break;default:e="L2R"}break;case"ViewArea":case"ViewClip":case"PrintArea":case"PrintClip":if(n instanceof Name)switch(n.name){case"MediaBox":case"CropBox":case"BleedBox":case"TrimBox":case"ArtBox":e=n.name;break;default:e="CropBox"}break;case"PrintScaling":if(n instanceof Name)switch(n.name){case"None":case"AppDefault":e=n.name;break;default:e="AppDefault"}break;case"Duplex":if(n instanceof Name)switch(n.name){case"Simplex":case"DuplexFlipShortEdge":case"DuplexFlipLongEdge":e=n.name;break;default:e="None"}break;case"PrintPageRange":if(Array.isArray(n)&&n.length%2==0){n.every((e,t,a)=>Number.isInteger(e)&&e>0&&(0===t||e>=a[t-1])&&e<=this.numPages)&&(e=n)}break;case"NumCopies":Number.isInteger(n)&&n>0&&(e=n);break;default:warn(`Ignoring non-standard key in ViewerPreferences: ${a}.`);continue}if(void 0!==e){t??=Object.create(null);t[a]=e}else warn(`Bad value, for key "${a}", in ViewerPreferences: ${n}.`)}return shadow(this,"viewerPreferences",t)}get openAction(){const e=this.#$e.get("OpenAction"),t=Object.create(null);if(e instanceof Dict){const a=new Dict(this.xref);a.set("A",e);const n={url:null,dest:null,action:null};Catalog.parseDestDictionary({destDict:a,resultObj:n});Array.isArray(n.dest)?t.dest=n.dest:n.action&&(t.action=n.action)}else Vi(e)&&(t.dest=e);return shadow(this,"openAction",objectSize(t)>0?t:null)}get attachments(){const e=this.#$e.get("Names");let t=null;if(e instanceof Dict&&e.has("EmbeddedFiles")){const a=new NameTree(e.getRaw("EmbeddedFiles"),this.xref);for(const[e,n]of a.getAll()){const a=new FileSpec(n);t??=Object.create(null);t[stringToPDFString(e,!0)]=a.serializable}}return shadow(this,"attachments",t)}get rawEmbeddedFiles(){const e=this.#$e.get("Names");if(!(e instanceof Dict&&e.has("EmbeddedFiles")))return null;return new NameTree(e.getRaw("EmbeddedFiles"),this.xref).getAll(!0)}get xfaImages(){const e=this.#$e.get("Names");let t=null;if(e instanceof Dict&&e.has("XFAImages")){const a=new NameTree(e.getRaw("XFAImages"),this.xref);for(const[e,n]of a.getAll())if(n instanceof BaseStream){t??=new Map;t.set(stringToPDFString(e,!0),n.getBytes())}}return shadow(this,"xfaImages",t)}#st(){const e=this.#$e.get("Names");let t=null;function appendIfJavaScriptDict(e,a){if(!(a instanceof Dict))return;if(!isName(a.get("S"),"JavaScript"))return;let n=a.get("JS");if(n instanceof BaseStream)n=n.getString();else if("string"!=typeof n)return;n=stringToPDFString(n,!0).replaceAll("\0","");n&&(t||=new Map).set(e,n)}if(e instanceof Dict&&e.has("JavaScript")){const t=new NameTree(e.getRaw("JavaScript"),this.xref);for(const[e,a]of t.getAll())appendIfJavaScriptDict(stringToPDFString(e,!0),a)}const a=this.#$e.get("OpenAction");a&&appendIfJavaScriptDict("OpenAction",a);return t}get jsActions(){const e=this.#st();let t=collectActions(this.xref,this.#$e,oe);if(e){t||=Object.create(null);for(const[a,n]of e)a in t?t[a].push(n):t[a]=[n]}return shadow(this,"jsActions",t)}async cleanup(e=!1){clearGlobalCaches();this.globalColorSpaceCache.clear();this.globalImageCache.clear(e);this.pageKidsCountCache.clear();this.pageIndexCache.clear();this.pageDictCache.clear();this.nonBlendModesSet.clear();for(const{dict:e}of await Promise.all(this.fontCache))delete e.cacheKey;this.fontCache.clear();this.builtInCMapCache.clear();this.standardFontDataCache.clear();this.systemFontCache.clear()}async getPageDict(e){const t=[this.toplevelPagesDict],a=new RefSet,n=this.#$e.getRaw("Pages");n instanceof Ref&&a.put(n);const s=this.xref,r=this.pageKidsCountCache,i=this.pageIndexCache,o=this.pageDictCache;let l=0;for(;t.length;){const n=t.pop();if(n instanceof Ref){const f=r.get(n);if(f>=0&&l+f<=e){l+=f;continue}if(a.has(n))throw new FormatError("Pages tree contains circular reference.");a.put(n);const c=await(o.get(n)||s.fetchAsync(n));if(c instanceof Dict){let t=c.getRaw("Type");t instanceof Ref&&(t=await s.fetchAsync(t));if(isName(t,"Page")||!c.has("Kids")){r.has(n)||r.put(n,1);i.has(n)||i.put(n,l);if(l===e)return[c,n];l++;continue}}t.push(c);continue}if(!(n instanceof Dict))throw new FormatError("Page dictionary kid reference points to wrong type of object.");const{objId:f}=n;let c=n.getRaw("Count");c instanceof Ref&&(c=await s.fetchAsync(c));if(Number.isInteger(c)&&c>=0){f&&!r.has(f)&&r.put(f,c);if(l+c<=e){l+=c;continue}}let h=n.getRaw("Kids");h instanceof Ref&&(h=await s.fetchAsync(h));if(!Array.isArray(h)){let t=n.getRaw("Type");t instanceof Ref&&(t=await s.fetchAsync(t));if(isName(t,"Page")||!n.has("Kids")){if(l===e)return[n,null];l++;continue}throw new FormatError("Page dictionary kids object is not an array.")}for(let e=h.length-1;e>=0;e--){const a=h[e];t.push(a);n===this.toplevelPagesDict&&a instanceof Ref&&!o.has(a)&&o.put(a,s.fetchAsync(a))}}throw new Error(`Page index ${e} not found.`)}async getAllPageDicts(e=!1){const{ignoreErrors:t}=this.pdfManager.evaluatorOptions,a=[{currentNode:this.toplevelPagesDict,posInKids:0}],n=new RefSet,s=this.#$e.getRaw("Pages");s instanceof Ref&&n.put(s);const r=new Map,i=this.xref,o=this.pageIndexCache;let l=0;function addPageDict(e,t){t&&!o.has(t)&&o.put(t,l);r.set(l++,[e,t])}function addPageError(a){if(a instanceof XRefEntryException&&!e)throw a;if(e&&t&&0===l){warn(`getAllPageDicts - Skipping invalid first page: "${a}".`);a=Dict.empty}r.set(l++,[a,null])}for(;a.length>0;){const e=a.at(-1),{currentNode:t,posInKids:s}=e;let r=t.getRaw("Kids");if(r instanceof Ref)try{r=await i.fetchAsync(r)}catch(e){addPageError(e);break}if(!Array.isArray(r)){addPageError(new FormatError("Page dictionary kids object is not an array."));break}if(s>=r.length){a.pop();continue}const o=r[s];let l;if(o instanceof Ref){if(n.has(o)){addPageError(new FormatError("Pages tree contains circular reference."));break}n.put(o);try{l=await i.fetchAsync(o)}catch(e){addPageError(e);break}}else l=o;if(!(l instanceof Dict)){addPageError(new FormatError("Page dictionary kid reference points to wrong type of object."));break}let f=l.getRaw("Type");if(f instanceof Ref)try{f=await i.fetchAsync(f)}catch(e){addPageError(e);break}isName(f,"Page")||!l.has("Kids")?addPageDict(l,o instanceof Ref?o:null):a.push({currentNode:l,posInKids:0});e.posInKids++}return r}getPageIndex(e){const t=this.pageIndexCache.get(e);if(void 0!==t)return Promise.resolve(t);const a=this.xref;let n=0;const next=t=>function pagesBeforeRef(t){let n,s=0;return a.fetchAsync(t).then(function(a){if(isRefsEqual(t,e)&&!isDict(a,"Page")&&!(a instanceof Dict&&!a.has("Type")&&a.has("Contents")))throw new FormatError("The reference does not point to a /Page dictionary.");if(!a)return null;if(!(a instanceof Dict))throw new FormatError("Node must be a dictionary.");n=a.getRaw("Parent");return a.getAsync("Parent")}).then(function(e){if(!e)return null;if(!(e instanceof Dict))throw new FormatError("Parent must be a dictionary.");return e.getAsync("Kids")}).then(function(e){if(!e)return null;const r=[];let i=!1;for(const n of e){if(!(n instanceof Ref))throw new FormatError("Kid must be a reference.");if(isRefsEqual(n,t)){i=!0;break}r.push(a.fetchAsync(n).then(function(e){if(!(e instanceof Dict))throw new FormatError("Kid node must be a dictionary.");e.has("Count")?s+=e.get("Count"):s++}))}if(!i)throw new FormatError("Kid reference not found in parent's kids.");return Promise.all(r).then(()=>[s,n])})}(t).then(t=>{if(!t){this.pageIndexCache.put(e,n);return n}const[a,s]=t;n+=a;return next(s)});return next(e)}get baseUrl(){const e=this.#$e.get("URI");if(e instanceof Dict){const t=e.get("Base");if("string"==typeof t){const e=createValidAbsoluteUrl(t,null,{tryConvertEncoding:!0});if(e)return shadow(this,"baseUrl",e.href)}}return shadow(this,"baseUrl",this.pdfManager.docBaseUrl)}static#rt(e,t){const a=e.fetchIfRef(t);if(!(a instanceof Dict))return null;let n=null;const s=a.getRaw("Pg");s instanceof Ref&&(n=s);if(!n){const t=[a];for(;t.length>0&&!n;){const a=t.shift().get("K");let s;if(Array.isArray(a))s=a;else{if(!a)continue;s=[a]}for(const a of s){const s=e.fetchIfRef(a);if(!(s instanceof Dict))continue;const r=s.getRaw("Pg");if(r instanceof Ref){n=r;break}t.push(s)}}}if(!n){const t=40;let s=a;for(let a=0;ae.startsWith("http://www.xfa.org/schema/xci/")},connectionSet:{id:1,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-connection-set/")},datasets:{id:2,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-data/")},form:{id:3,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-form/")},localeSet:{id:4,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-locale-set/")},pdf:{id:5,check:e=>"http://ns.adobe.com/xdp/pdf/"===e},signature:{id:6,check:e=>"http://www.w3.org/2000/09/xmldsig#"===e},sourceSet:{id:7,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-source-set/")},stylesheet:{id:8,check:e=>"http://www.w3.org/1999/XSL/Transform"===e},template:{id:9,check:e=>e.startsWith("http://www.xfa.org/schema/xfa-template/")},xdc:{id:10,check:e=>e.startsWith("http://www.xfa.org/schema/xdc/")},xdp:{id:11,check:e=>"http://ns.adobe.com/xdp/"===e},xfdf:{id:12,check:e=>"http://ns.adobe.com/xfdf/"===e},xhtml:{id:13,check:e=>"http://www.w3.org/1999/xhtml"===e},xmpmeta:{id:14,check:e=>"http://ns.adobe.com/xmpmeta/"===e}},ml={pt:e=>e,cm:e=>e/2.54*72,mm:e=>e/25.4*72,in:e=>72*e,px:e=>e},pl=/([+-]?\d+\.?\d*)(.*)/;function stripQuotes(e){return e.startsWith("'")||e.startsWith('"')?e.slice(1,-1):e}function getInteger({data:e,defaultValue:t,validate:a}){if(!e)return t;e=e.trim();const n=parseInt(e,10);return!isNaN(n)&&a(n)?n:t}function getFloat({data:e,defaultValue:t,validate:a}){if(!e)return t;e=e.trim();const n=parseFloat(e);return!isNaN(n)&&a(n)?n:t}function getKeyword({data:e,defaultValue:t,validate:a}){return e&&a(e=e.trim())?e:t}function getStringOption(e,t){return getKeyword({data:e,defaultValue:t[0],validate:e=>t.includes(e)})}function getMeasurement(e,t="0"){t||="0";if(!e)return getMeasurement(t);const a=e.trim().match(pl);if(!a)return getMeasurement(t);const[,n,s]=a,r=parseFloat(n);if(isNaN(r))return getMeasurement(t);if(0===r)return 0;const i=ml[s];return i?i(r):r}function getRatio(e){if(!e)return{num:1,den:1};const t=e.split(":",2).map(e=>parseFloat(e.trim())).filter(e=>!isNaN(e));1===t.length&&t.push(1);if(0===t.length)return{num:1,den:1};const[a,n]=t;return{num:a,den:n}}function getRelevant(e){return e?e.trim().split(/\s+/).map(e=>({excluded:"-"===e[0],viewname:e.substring(1)})):[]}class HTMLResult{static get FAILURE(){return shadow(this,"FAILURE",new HTMLResult(!1,null,null,null))}static get EMPTY(){return shadow(this,"EMPTY",new HTMLResult(!0,null,null,null))}constructor(e,t,a,n){this.success=e;this.html=t;this.bbox=a;this.breakNode=n}isBreak(){return!!this.breakNode}static breakNode(e){return new HTMLResult(!1,null,null,e)}static success(e,t=null){return new HTMLResult(!0,e,t,null)}}class FontFinder{constructor(e){this.fonts=new Map;this.cache=new Map;this.warned=new Set;this.defaultFont=null;this.add(e)}add(e,t=null){for(const t of e)this.addPdfFont(t);for(const e of this.fonts.values())e.regular||(e.regular=e.italic||e.bold||e.bolditalic);if(!t||0===t.size)return;const a=this.fonts.get("PdfJS-Fallback-PdfJS-XFA");for(const e of t)this.fonts.set(e,a)}addPdfFont(e){const t=e.cssFontInfo,a=t.fontFamily,n=this.fonts.getOrInsertComputed(a,makeObj);this.defaultFont??=n;let s="";const r=parseFloat(t.fontWeight);0!==parseFloat(t.italicAngle)?s=r>=700?"bolditalic":"italic":r>=700&&(s="bold");if(!s){(e.name.includes("Bold")||e.psName?.includes("Bold"))&&(s="bold");(e.name.includes("Italic")||e.name.endsWith("It")||e.psName?.includes("Italic")||e.psName?.endsWith("It"))&&(s+="italic")}s||(s="regular");n[s]=e}getDefault(){return this.defaultFont}find(e,t=!0){let a=this.fonts.get(e)||this.cache.get(e);if(a)return a;const n=/,|-|_| |bolditalic|bold|italic|regular|it/gi;let s=e.replaceAll(n,"");a=this.fonts.get(s);if(a){this.cache.set(e,a);return a}s=s.toLowerCase();const r=[];for(const[e,t]of this.fonts)e.replaceAll(n,"").toLowerCase().startsWith(s)&&r.push(t);if(0===r.length)for(const e of this.fonts.values())e.regular.name?.replaceAll(n,"").toLowerCase().startsWith(s)&&r.push(e);if(0===r.length){s=s.replaceAll(/psmt|mt/gi,"");for(const[e,t]of this.fonts)e.replaceAll(n,"").toLowerCase().startsWith(s)&&r.push(t)}if(0===r.length)for(const e of this.fonts.values())e.regular.name?.replaceAll(n,"").toLowerCase().startsWith(s)&&r.push(e);if(r.length>=1){1!==r.length&&t&&warn(`XFA - Too many choices to guess the correct font: ${e}`);this.cache.set(e,r[0]);return r[0]}if(t&&!this.warned.has(e)){this.warned.add(e);warn(`XFA - Cannot find the font: ${e}`)}return null}}function selectFont(e,t){return"italic"===e.posture?"bold"===e.weight?t.bolditalic:t.italic:"bold"===e.weight?t.bold:t.regular}class FontInfo{constructor(e,t,a,n){this.lineHeight=a;this.paraMargin=t||{top:0,bottom:0,left:0,right:0};if(!e){[this.pdfFont,this.xfaFont]=this.defaultFont(n);return}this.xfaFont={typeface:e.typeface,posture:e.posture,weight:e.weight,size:e.size,letterSpacing:e.letterSpacing};const s=n.find(e.typeface);if(s){this.pdfFont=selectFont(e,s);this.pdfFont||([this.pdfFont,this.xfaFont]=this.defaultFont(n))}else[this.pdfFont,this.xfaFont]=this.defaultFont(n)}defaultFont(e){const t=e.find("Helvetica",!1)||e.find("Myriad Pro",!1)||e.find("Arial",!1)||e.getDefault();if(t?.regular){const e=t.regular;return[e,{typeface:e.cssFontInfo.fontFamily,posture:"normal",weight:"normal",size:10,letterSpacing:0}]}return[null,{typeface:"Courier",posture:"normal",weight:"normal",size:10,letterSpacing:0}]}}class FontSelector{constructor(e,t,a,n){this.fontFinder=n;this.stack=[new FontInfo(e,t,a,n)]}pushData(e,t,a){const n=this.stack.at(-1);for(const t of["typeface","posture","weight","size","letterSpacing"])e[t]||=n.xfaFont[t];for(const e of["top","bottom","left","right"])isNaN(t[e])&&(t[e]=n.paraMargin[e]);const s=new FontInfo(e,t,a||n.lineHeight,this.fontFinder);s.pdfFont||=n.pdfFont;this.stack.push(s)}popFont(){this.stack.pop()}topFont(){return this.stack.at(-1)}}class TextMeasure{constructor(e,t,a,n){this.glyphs=[];this.fontSelector=new FontSelector(e,t,a,n);this.extraHeight=0}pushData(e,t,a){this.fontSelector.pushData(e,t,a)}popFont(e){return this.fontSelector.popFont()}addPara(){const e=this.fontSelector.topFont();this.extraHeight+=e.paraMargin.top+e.paraMargin.bottom}addString(e){if(!e)return;const t=this.fontSelector.topFont(),a=t.xfaFont.size;if(t.pdfFont){const n=t.xfaFont.letterSpacing,s=t.pdfFont,r=s.lineHeight||1.2,i=t.lineHeight||Math.max(1.2,r)*a,o=r-(void 0===s.lineGap?.2:s.lineGap),l=Math.max(1,o)*a,f=a/1e3,c=s.defaultWidth||s.charsToGlyphs(" ")[0].width;for(const t of e.split(/[\u2029\n]/)){const e=s.encodeString(t).join(""),a=s.charsToGlyphs(e);for(const e of a){const t=e.width||c;this.glyphs.push([t*f+n,i,l,e.unicode,!1])}this.glyphs.push([0,0,0,"\n",!0])}this.glyphs.pop();return}for(const t of e.split(/[\u2029\n]/)){for(const e of t.split(""))this.glyphs.push([a,1.2*a,a,e,!1]);this.glyphs.push([0,0,0,"\n",!0])}this.glyphs.pop()}compute(e){let t=-1,a=0,n=0,s=0,r=0,i=0,o=!1,l=!0;for(let f=0,c=this.glyphs.length;fe){n=Math.max(n,r);r=0;s+=i;i=g;t=-1;a=0;o=!0;l=!1}else{i=Math.max(g,i);a=r;r+=c;t=f}else if(r+c>e){s+=i;i=g;if(-1!==t){f=t;n=Math.max(n,a);r=0;t=-1;a=0}else{n=Math.max(n,r);r=c}o=!0;l=!1}else{r+=c;i=Math.max(g,i)}}n=Math.max(n,r);s+=i+this.extraHeight;return{width:1.02*n,height:s,isBroken:o}}}const dl=/^[^.[]+/,gl=/^[^\]]+/,bl=0,wl=1,jl=2,kl=3,yl=4,ql=new Map([["$data",(e,t)=>e.datasets?e.datasets.data:e],["$record",(e,t)=>(e.datasets?e.datasets.data:e)[ko]()[0]],["$template",(e,t)=>e.template],["$connectionSet",(e,t)=>e.connectionSet],["$form",(e,t)=>e.form],["$layout",(e,t)=>e.layout],["$host",(e,t)=>e.host],["$dataWindow",(e,t)=>e.dataWindow],["$event",(e,t)=>e.event],["!",(e,t)=>e.datasets],["$xfa",(e,t)=>e],["xfa",(e,t)=>e],["$",(e,t)=>t]]),vl=new WeakMap;function parseIndex(e){return"*"===(e=e.trim())?1/0:parseInt(e,10)||0}function parseExpression(e,t,a=!0){let n=e.match(dl);if(!n)return null;let[s]=n;const r=[{name:s,cacheName:"."+s,index:0,js:null,formCalc:null,operator:bl}];let i=s.length;for(;i0&&c.push(e)}if(0===c.length&&!o&&0===l){const a=t[So]();if(!(t=a))return null;l=-1;e=[t];continue}e=isFinite(f)?c.filter(e=>fe[f]):c.flat()}return 0===e.length?null:e}function createDataNode(e,t,a){const n=parseExpression(a);if(!n)return null;if(n.some(e=>e.operator===wl))return null;const s=ql.get(n[0].name);let r=0;if(s){e=s(e,t);r=1}else e=t||e;for(let t=n.length;re[rl]()).join("")}get[xl](){const e=Object.getPrototypeOf(this);if(!e._attributes){const t=e._attributes=new Set;for(const e of Object.getOwnPropertyNames(this)){if(null===this[e]||this[e]instanceof XFAObject||this[e]instanceof XFAObjectArray)break;t.add(e)}}return shadow(this,xl,e._attributes)}[Do](e){let t=this;for(;t;){if(t===e)return!0;t=t[So]()}return!1}[So](){return this[Pl]}[vo](){return this[So]()}[ko](e=null){return e?this[e]:this[Cl]}[io](){const e=Object.create(null);this[so]&&(e.$content=this[so]);for(const t of Object.getOwnPropertyNames(this)){const a=this[t];null!==a&&(a instanceof XFAObject?e[t]=a[io]():a instanceof XFAObjectArray?a.isEmpty()||(e[t]=a.dump()):e[t]=a)}return e}[fl](){return null}[ol](){return HTMLResult.EMPTY}*[yo](){for(const e of this[ko]())yield e}*[Rl](e,t){for(const a of this[yo]())if(!e||t===e.has(a[Uo])){const e=this[uo](),t=a[ol](e);t.success||(this[oo].failingNode=a);yield t}}[fo](){return null}[Yi](e,t){this[oo].children.push(e)}[uo](){}[Qi]({filter:e=null,include:t=!0}){if(this[oo].generator){const e=this[uo](),t=this[oo].failingNode[ol](e);if(!t.success)return t;t.html&&this[Yi](t.html,t.bbox);delete this[oo].failingNode}else this[oo].generator=this[Rl](e,t);for(;;){const e=this[oo].generator.next();if(e.done)break;const t=e.value;if(!t.success)return t;t.html&&this[Yi](t.html,t.bbox)}this[oo].generator=null;return HTMLResult.EMPTY}[al](e){this[_l]=new Set(Object.keys(e))}[Bl](e){const t=this[xl],a=this[_l];return[...e].filter(e=>t.has(e)&&!a.has(e))}[Zo](e,t=new Set){for(const a of this[Cl])a[El](e,t)}[El](e,t){const a=this[Hl](e,t);a?this[Sl](a,e,t):this[Zo](e,t)}[Hl](e,t){const{use:a,usehref:n}=this;if(!a&&!n)return null;let s=null,r=null,i=null,o=a;if(n){o=n;n.startsWith("#som(")&&n.endsWith(")")?r=n.slice(5,-1):n.startsWith(".#som(")&&n.endsWith(")")?r=n.slice(6,-1):n.startsWith("#")?i=n.slice(1):n.startsWith(".#")&&(i=n.slice(2))}else a.startsWith("#")?i=a.slice(1):r=a;this.use=this.usehref="";if(i)s=e.get(i);else{s=searchNode(e.get(Qo),this,r,!0,!1);s&&(s=s[0])}if(!s){warn(`XFA - Invalid prototype reference: ${o}.`);return null}if(s[Uo]!==this[Uo]){warn(`XFA - Incompatible prototype: ${s[Uo]} !== ${this[Uo]}.`);return null}if(t.has(s)){warn("XFA - Cycle detected in prototypes use.");return null}t.add(s);const l=s[Hl](e,t);l&&s[Sl](l,e,t);s[Zo](e,t);t.delete(s);return s}[Sl](e,t,a){if(a.has(e)){warn("XFA - Cycle detected in prototypes use.");return}!this[so]&&e[so]&&(this[so]=e[so]);new Set(a).add(e);for(const t of this[Bl](e[_l])){this[t]=e[t];this[_l]&&this[_l].add(t)}for(const n of Object.getOwnPropertyNames(this)){if(this[xl].has(n))continue;const s=this[n],r=e[n];if(s instanceof XFAObjectArray){for(const e of s[Cl])e[El](t,a);for(let n=s[Cl].length,i=r[Cl].length;nXFAObject[Il](e)):"object"==typeof e&&null!==e?Object.assign({},e):e}[ao](){const e=Object.create(Object.getPrototypeOf(this));for(const t of Object.getOwnPropertySymbols(this))try{e[t]=this[t]}catch{shadow(e,t,this[t])}e[cl]=`${e[Uo]}${Ll++}`;e[Cl]=[];for(const t of Object.getOwnPropertyNames(this)){if(this[xl].has(t)){e[t]=XFAObject[Il](this[t]);continue}const a=this[t];e[t]=a instanceof XFAObjectArray?new XFAObjectArray(a[Ml]):null}for(const t of this[Cl]){const a=t[Uo],n=t[ao]();e[Cl].push(n);n[Pl]=e;null===e[a]?e[a]=n:e[a][Cl].push(n)}return e}[ko](e=null){return e?this[Cl].filter(t=>t[Uo]===e):this[Cl]}[mo](e){return this[e]}[po](e,t,a=!0){return Array.from(this[go](e,t,a))}*[go](e,t,a=!0){if("parent"!==e){for(const a of this[Cl]){a[Uo]===e&&(yield a);a.name===e&&(yield a);(t||a[Eo]())&&(yield*a[go](e,t,!1))}a&&this[xl].has(e)&&(yield new XFAAttribute(this,e,this[e]))}else yield this[Pl]}}class XFAObjectArray{constructor(e=1/0){this[Ml]=e;this[Cl]=[]}get isXFAObject(){return!1}get isXFAObjectArray(){return!0}push(e){if(this[Cl].length<=this[Ml]){this[Cl].push(e);return!0}warn(`XFA - node "${e[Uo]}" accepts no more than ${this[Ml]} children`);return!1}isEmpty(){return 0===this[Cl].length}dump(){return 1===this[Cl].length?this[Cl][0][io]():this[Cl].map(e=>e[io]())}[ao](){const e=new XFAObjectArray(this[Ml]);e[Cl]=this[Cl].map(e=>e[ao]());return e}get children(){return this[Cl]}clear(){this[Cl].length=0}}class XFAAttribute{constructor(e,t,a){this[Pl]=e;this[Uo]=t;this[so]=a;this[no]=!1;this[cl]="attribute"+Ll++}[So](){return this[Pl]}[Bo](){return!0}[bo](){return this[so].trim()}[nl](e){e=e.value||"";this[so]=e.toString()}[rl](){return this[so]}[Do](e){return this[Pl]===e||this[Pl][Do](e)}}class XmlObject extends XFAObject{constructor(e,t,a={}){super(e,t);this[so]="";this[Fl]=null;if("#text"!==t){const e=new Map;this[Al]=e;for(const[t,n]of Object.entries(a))e.set(t,new XFAAttribute(this,t,n));if(Object.hasOwn(a,Xo)){const e=a[Xo].xfa.dataNode;void 0!==e&&("dataGroup"===e?this[Fl]=!1:"dataValue"===e&&(this[Fl]=!0))}}this[no]=!1}[ll](e){const t=this[Uo];if("#text"===t){e.push(encodeToXmlString(this[so]));return}const a=utf8StringToString(t),n=this[Lo]===Xl?"xfa:":"";e.push(`<${n}${a}`);for(const[t,a]of this[Al]){const n=utf8StringToString(t);e.push(` ${n}="${encodeToXmlString(a[so])}"`)}null!==this[Fl]&&(this[Fl]?e.push(' xfa:dataNode="dataValue"'):e.push(' xfa:dataNode="dataGroup"'));if(this[so]||0!==this[Cl].length){e.push(">");if(this[so])"string"==typeof this[so]?e.push(encodeToXmlString(this[so])):this[so][ll](e);else for(const t of this[Cl])t[ll](e);e.push(``)}else e.push("/>")}[Wo](e){if(this[so]){const e=new XmlObject(this[Lo],"#text");this[Ji](e);e[so]=this[so];this[so]=""}this[Ji](e);return!0}[Go](e){this[so]+=e}[lo](){if(this[so]&&this[Cl].length>0){const e=new XmlObject(this[Lo],"#text");this[Ji](e);e[so]=this[so];delete this[so]}}[ol](){return"#text"===this[Uo]?HTMLResult.success({name:"#text",value:this[so]}):HTMLResult.EMPTY}[ko](e=null){return e?this[Cl].filter(t=>t[Uo]===e):this[Cl]}[ho](){return this[Al]}[mo](e){const t=this[Al].get(e);return void 0!==t?t:this[ko](e)}*[go](e,t){const a=this[Al].get(e);a&&(yield a);for(const a of this[Cl]){a[Uo]===e&&(yield a);t&&(yield*a[go](e,t))}}*[co](e,t){const a=this[Al].get(e);!a||t&&a[no]||(yield a);for(const a of this[Cl])yield*a[co](e,t)}*[jo](e,t,a){for(const n of this[Cl]){n[Uo]!==e||a&&n[no]||(yield n);t&&(yield*n[jo](e,t,a))}}[Bo](){return null===this[Fl]?0===this[Cl].length||this[Cl][0][Lo]===ul.xhtml.id:this[Fl]}[bo](){return null===this[Fl]?0===this[Cl].length?this[so].trim():this[Cl][0][Lo]===ul.xhtml.id?this[Cl][0][rl]().trim():null:this[so].trim()}[nl](e){e=e.value||"";this[so]=e.toString()}[io](e=!1){const t=Object.create(null);e&&(t.$ns=this[Lo]);this[so]&&(t.$content=this[so]);t.$name=this[Uo];t.children=[];for(const a of this[Cl])t.children.push(a[io](e));t.attributes=Object.create(null);for(const[e,a]of this[Al])t.attributes[e]=a[so];return t}}class ContentObject extends XFAObject{constructor(e,t){super(e,t);this[so]=""}[Go](e){this[so]+=e}[lo](){}}class OptionObject extends ContentObject{constructor(e,t,a){super(e,t);this[Nl]=a}[lo](){this[so]=getKeyword({data:this[so],defaultValue:this[Nl][0],validate:e=>this[Nl].includes(e)})}[Zi](e){super[Zi](e);delete this[Nl]}}class StringObject extends ContentObject{[lo](){this[so]=this[so].trim()}}class IntegerObject extends ContentObject{constructor(e,t,a,n){super(e,t);this[Tl]=a;this[zl]=n}[lo](){this[so]=getInteger({data:this[so],defaultValue:this[Tl],validate:this[zl]})}[Zi](e){super[Zi](e);delete this[Tl];delete this[zl]}}class Option01 extends IntegerObject{constructor(e,t){super(e,t,0,e=>1===e)}}class Option10 extends IntegerObject{constructor(e,t){super(e,t,1,e=>0===e)}}function measureToString(e){return"string"==typeof e?"0px":Number.isInteger(e)?`${e}px`:`${e.toFixed(2)}px`}const Wl={anchorType(e,t){const a=e[vo]();if(a&&(!a.layout||"position"===a.layout)){"transform"in t||(t.transform="");switch(e.anchorType){case"bottomCenter":t.transform+="translate(-50%, -100%)";break;case"bottomLeft":t.transform+="translate(0,-100%)";break;case"bottomRight":t.transform+="translate(-100%,-100%)";break;case"middleCenter":t.transform+="translate(-50%,-50%)";break;case"middleLeft":t.transform+="translate(0,-50%)";break;case"middleRight":t.transform+="translate(-100%,-50%)";break;case"topCenter":t.transform+="translate(-50%,0)";break;case"topRight":t.transform+="translate(-100%,0)"}}},dimensions(e,t){const a=e[vo]();let n=e.w;const s=e.h;if(a.layout?.includes("row")){const t=a[oo],s=e.colSpan;let r;if(-1===s){r=Math.sumPrecise(t.columnWidths.slice(t.currentColumn));t.currentColumn=0}else{r=Math.sumPrecise(t.columnWidths.slice(t.currentColumn,t.currentColumn+s));t.currentColumn=(t.currentColumn+e.colSpan)%t.columnWidths.length}isNaN(r)||(n=e.w=r)}t.width=""!==n?measureToString(n):"auto";t.height=""!==s?measureToString(s):"auto"},position(e,t){const a=e[vo]();if(!a?.layout||"position"===a.layout){t.position="absolute";t.left=measureToString(e.x);t.top=measureToString(e.y)}},rotate(e,t){if(e.rotate){"transform"in t||(t.transform="");t.transform+=`rotate(-${e.rotate}deg)`;t.transformOrigin="top left"}},presence(e,t){switch(e.presence){case"invisible":t.visibility="hidden";break;case"hidden":case"inactive":t.display="none"}},hAlign(e,t){if("para"===e[Uo])switch(e.hAlign){case"justifyAll":t.textAlign="justify-all";break;case"radix":t.textAlign="left";break;default:t.textAlign=e.hAlign}else switch(e.hAlign){case"left":t.alignSelf="start";break;case"center":t.alignSelf="center";break;case"right":t.alignSelf="end"}},margin(e,t){e.margin&&(t.margin=e.margin[fl]().margin)}};function setMinMaxDimensions(e,t){if("position"===e[vo]().layout){e.minW>0&&(t.minWidth=measureToString(e.minW));e.maxW>0&&(t.maxWidth=measureToString(e.maxW));e.minH>0&&(t.minHeight=measureToString(e.minH));e.maxH>0&&(t.maxHeight=measureToString(e.maxH))}}function layoutText(e,t,a,n,s,r){const i=new TextMeasure(t,a,n,s);"string"==typeof e?i.addString(e):e[Vo](i);return i.compute(r)}function layoutNode(e,t){let a=null,n=null,s=!1;if((!e.w||!e.h)&&e.value){let r=0,i=0;if(e.margin){r=e.margin.leftInset+e.margin.rightInset;i=e.margin.topInset+e.margin.bottomInset}let o=null,l=null;if(e.para){l=Object.create(null);o=""===e.para.lineHeight?null:e.para.lineHeight;l.top=""===e.para.spaceAbove?0:e.para.spaceAbove;l.bottom=""===e.para.spaceBelow?0:e.para.spaceBelow;l.left=""===e.para.marginLeft?0:e.para.marginLeft;l.right=""===e.para.marginRight?0:e.para.marginRight}let f=e.font;if(!f){const t=e[Ao]();let a=e[So]();for(;a&&a!==t;){if(a.font){f=a.font;break}a=a[So]()}}const c=(e.w||t.width)-r,h=e[xo].fontFinder;if(e.value.exData&&e.value.exData[so]&&"text/html"===e.value.exData.contentType){const t=layoutText(e.value.exData[so],f,l,o,h,c);n=t.width;a=t.height;s=t.isBroken}else{const t=e.value[rl]();if(t){const e=layoutText(t,f,l,o,h,c);n=e.width;a=e.height;s=e.isBroken}}null===n||e.w||(n+=r);null===a||e.h||(a+=i)}return{w:n,h:a,isBroken:s}}function computeBbox(e,t,a){let n;if(""!==e.w&&""!==e.h)n=[e.x,e.y,e.w,e.h];else{if(!a)return null;let s=e.w;if(""===s){if(0===e.maxW){const t=e[vo]();s="position"===t.layout&&""!==t.w?0:e.minW}else s=Math.min(e.maxW,a.width);t.attributes.style.width=measureToString(s)}let r=e.h;if(""===r){if(0===e.maxH){const t=e[vo]();r="position"===t.layout&&""!==t.h?0:e.minH}else r=Math.min(e.maxH,a.height);t.attributes.style.height=measureToString(r)}n=[e.x,e.y,s,r]}return n}function fixDimensions(e){const t=e[vo]();if(t.layout?.includes("row")){const a=t[oo],n=e.colSpan;let s;s=-1===n?Math.sumPrecise(a.columnWidths.slice(a.currentColumn)):Math.sumPrecise(a.columnWidths.slice(a.currentColumn,a.currentColumn+n));isNaN(s)||(e.w=s)}t.layout&&"position"!==t.layout&&(e.x=e.y=0);"table"===e.layout&&""===e.w&&Array.isArray(e.columnWidths)&&(e.w=Math.sumPrecise(e.columnWidths))}function layoutClass(e){switch(e.layout){case"position":default:return"xfaPosition";case"lr-tb":return"xfaLrTb";case"rl-row":return"xfaRlRow";case"rl-tb":return"xfaRlTb";case"row":return"xfaRow";case"table":return"xfaTable";case"tb":return"xfaTb"}}function toStyle(e,...t){const a=Object.create(null);for(const n of t){const t=e[n];if(null!==t)if(Object.hasOwn(Wl,n))Wl[n](e,a);else if(t instanceof XFAObject){const e=t[fl]();e?Object.assign(a,e):warn(`(DEBUG) - XFA - style for ${n} not implemented yet`)}}return a}function createWrapper(e,t){const{attributes:a}=t,{style:n}=a,s={name:"div",attributes:{class:["xfaWrapper"],style:Object.create(null)},children:[]};a.class.push("xfaWrapped");if(e.border){const{widths:a,insets:r}=e.border[oo];let i,o,l=r[0],f=r[3];const c=r[0]+r[2],h=r[1]+r[3];switch(e.border.hand){case"even":l-=a[0]/2;f-=a[3]/2;i=`calc(100% + ${(a[1]+a[3])/2-h}px)`;o=`calc(100% + ${(a[0]+a[2])/2-c}px)`;break;case"left":l-=a[0];f-=a[3];i=`calc(100% + ${a[1]+a[3]-h}px)`;o=`calc(100% + ${a[0]+a[2]-c}px)`;break;case"right":i=h?`calc(100% - ${h}px)`:"100%";o=c?`calc(100% - ${c}px)`:"100%"}const u=["xfaBorder"];isPrintOnly(e.border)&&u.push("xfaPrintOnly");const m={name:"div",attributes:{class:u,style:{top:`${l}px`,left:`${f}px`,width:i,height:o}},children:[]};for(const e of["border","borderWidth","borderColor","borderRadius","borderStyle"])if(void 0!==n[e]){m.attributes.style[e]=n[e];delete n[e]}s.children.push(m,t)}else s.children.push(t);for(const e of["background","backgroundClip","top","left","width","height","minWidth","minHeight","maxWidth","maxHeight","transform","transformOrigin","visibility"])if(void 0!==n[e]){s.attributes.style[e]=n[e];delete n[e]}s.attributes.style.position="absolute"===n.position?"absolute":"relative";delete n.position;if(n.alignSelf){s.attributes.style.alignSelf=n.alignSelf;delete n.alignSelf}return s}function fixTextIndent(e){const t=getMeasurement(e.textIndent,"0px");if(t>=0)return;const a="padding"+("left"===("right"===e.textAlign?"right":"left")?"Left":"Right"),n=getMeasurement(e[a],"0px");e[a]=n-t+"px"}function setAccess(e,t){switch(e.access){case"nonInteractive":t.push("xfaNonInteractive");break;case"readOnly":t.push("xfaReadOnly");break;case"protected":t.push("xfaDisabled")}}function isPrintOnly(e){return e.relevant.length>0&&!e.relevant[0].excluded&&"print"===e.relevant[0].viewname}function getCurrentPara(e){const t=e[Ao]()[oo].paraStack;return t.length?t.at(-1):null}function setPara(e,t,a){if(a.attributes.class?.includes("xfaRich")){if(t){""===e.h&&(t.height="auto");""===e.w&&(t.width="auto")}const n=getCurrentPara(e);if(n){const e=a.attributes.style;e.display="flex";e.flexDirection="column";switch(n.vAlign){case"top":e.justifyContent="start";break;case"bottom":e.justifyContent="end";break;case"middle":e.justifyContent="center"}const t=n[fl]();for(const[a,n]of Object.entries(t))a in e||(e[a]=n)}}}function setFontFamily(e,t,a,n){if(!a){delete n.fontFamily;return}const s=stripQuotes(e.typeface);n.fontFamily=`"${s}"`;const r=a.find(s);if(r){const{fontFamily:a}=r.regular.cssFontInfo;a!==s&&(n.fontFamily=`"${a}"`);const i=getCurrentPara(t);if(i&&""!==i.lineHeight)return;if(n.lineHeight)return;const o=selectFont(e,r);o&&(n.lineHeight=Math.max(1.2,o.lineHeight))}}function fixURL(e){const t=createValidAbsoluteUrl(e,null,{addDefaultProtocol:!0,tryConvertEncoding:!0});return t?t.href:null}function createLine(e,t){return{name:"div",attributes:{class:["lr-tb"===e.layout?"xfaLr":"xfaRl"]},children:t}}function flushHTML(e){if(!e[oo])return null;const t={name:"div",attributes:e[oo].attributes,children:e[oo].children};if(e[oo].failingNode){const a=e[oo].failingNode[fo]();a&&(e.layout.endsWith("-tb")?t.children.push(createLine(e,[a])):t.children.push(a))}return 0===t.children.length?null:t}function addHTML(e,t,a){const n=e[oo],s=n.availableSpace,[r,i,o,l]=a;switch(e.layout){case"position":n.width=Math.max(n.width,r+o);n.height=Math.max(n.height,i+l);n.children.push(t);break;case"lr-tb":case"rl-tb":if(!n.line||1===n.attempt){n.line=createLine(e,[]);n.children.push(n.line);n.numberInLine=0}n.numberInLine+=1;n.line.children.push(t);if(0===n.attempt){n.currentWidth+=o;n.height=Math.max(n.height,n.prevHeight+l)}else{n.currentWidth=o;n.prevHeight=n.height;n.height+=l;n.attempt=0}n.width=Math.max(n.width,n.currentWidth);break;case"rl-row":case"row":{n.children.push(t);n.width+=o;n.height=Math.max(n.height,l);const e=measureToString(n.height);for(const t of n.children)t.attributes.style.height=e;break}case"table":case"tb":n.width=MathClamp(o,n.width,s.width);n.height+=l;n.children.push(t)}}function getAvailableSpace(e){const t=e[oo].availableSpace,a=e.margin?e.margin.topInset+e.margin.bottomInset:0,n=e.margin?e.margin.leftInset+e.margin.rightInset:0;switch(e.layout){case"lr-tb":case"rl-tb":return 0===e[oo].attempt?{width:t.width-n-e[oo].currentWidth,height:t.height-a-e[oo].prevHeight}:{width:t.width-n,height:t.height-a-e[oo].height};case"rl-row":case"row":return{width:Math.sumPrecise(e[oo].columnWidths.slice(e[oo].currentColumn)),height:t.height-n};case"table":case"tb":return{width:t.width-n,height:t.height-a-e[oo].height};default:return t}}function checkDimensions(e,t){if(null===e[Ao]()[oo].firstUnsplittable)return!0;if(0===e.w||0===e.h)return!0;const a=e[vo](),n=a[oo]?.attempt||0,[,s,r,i]=function getTransformedBBox(e){let t,a,n=""===e.w?NaN:e.w,s=""===e.h?NaN:e.h,[r,i]=[0,0];switch(e.anchorType||""){case"bottomCenter":[r,i]=[n/2,s];break;case"bottomLeft":[r,i]=[0,s];break;case"bottomRight":[r,i]=[n,s];break;case"middleCenter":[r,i]=[n/2,s/2];break;case"middleLeft":[r,i]=[0,s/2];break;case"middleRight":[r,i]=[n,s/2];break;case"topCenter":[r,i]=[n/2,0];break;case"topRight":[r,i]=[n,0]}switch(e.rotate||0){case 0:[t,a]=[-r,-i];break;case 90:[t,a]=[-i,r];[n,s]=[s,-n];break;case 180:[t,a]=[r,i];[n,s]=[-n,-s];break;case 270:[t,a]=[i,-r];[n,s]=[-s,n]}return[e.x+t+Math.min(0,n),e.y+a+Math.min(0,s),Math.abs(n),Math.abs(s)]}(e);switch(a.layout){case"lr-tb":case"rl-tb":return 0===n?e[Ao]()[oo].noLayoutFailure?""!==e.w?Math.round(r-t.width)<=2:t.width>2:!(""!==e.h&&Math.round(i-t.height)>2)&&(""!==e.w?Math.round(r-t.width)<=2||0===a[oo].numberInLine&&t.height>2:t.width>2):!!e[Ao]()[oo].noLayoutFailure||!(""!==e.h&&Math.round(i-t.height)>2)&&((""===e.w||Math.round(r-t.width)<=2||!a[Po]())&&t.height>2);case"table":case"tb":return!!e[Ao]()[oo].noLayoutFailure||(""===e.h||e[No]()?(""===e.w||Math.round(r-t.width)<=2||!a[Po]())&&t.height>2:Math.round(i-t.height)<=2);case"position":if(e[Ao]()[oo].noLayoutFailure)return!0;if(""===e.h||Math.round(i+s-t.height)<=2)return!0;return i+s>e[Ao]()[oo].currentContentArea.h;case"rl-row":case"row":return!!e[Ao]()[oo].noLayoutFailure||(""===e.h||Math.round(i-t.height)<=2);default:return!0}}const Kl=ul.template.id,Gl="http://www.w3.org/2000/svg",Vl=/^H(\d+)$/,$l=new Set(["image/gif","image/jpeg","image/jpg","image/pjpeg","image/png","image/apng","image/x-png","image/bmp","image/x-ms-bmp","image/tiff","image/tif","application/octet-stream"]),Yl=[[[66,77],"image/bmp"],[[255,216,255],"image/jpeg"],[[73,73,42,0],"image/tiff"],[[77,77,0,42],"image/tiff"],[[71,73,70,56,57,97],"image/gif"],[[137,80,78,71,13,10,26,10],"image/png"]];function getBorderDims(e){if(!e||!e.border)return{w:0,h:0};const t=e.border[wo]();return t?{w:t.widths[0]+t.widths[2]+t.insets[0]+t.insets[2],h:t.widths[1]+t.widths[3]+t.insets[1]+t.insets[3]}:{w:0,h:0}}function hasMargin(e){return e.margin&&(e.margin.topInset||e.margin.rightInset||e.margin.bottomInset||e.margin.leftInset)}function _setValue(e,t){if(!e.value){const t=new Value({});e[Ji](t);e.value=t}e.value[nl](t)}function*getContainedChildren(e){for(const t of e[ko]())t instanceof SubformSet?yield*t[yo]():yield t}function isRequired(e){return"error"===e.validate?.nullTest}function setTabIndex(e){for(;e;){if(!e.traversal){e[sl]=e[So]()[sl];return}if(e[sl])return;let t=null;for(const a of e.traversal[ko]())if("next"===a.operation){t=a;break}if(!t||!t.ref){e[sl]=e[So]()[sl];return}const a=e[Ao]();e[sl]=++a[sl];const n=a[el](t.ref,e);if(!n)return;e=n[0]}}function applyAssist(e,t){const a=e.assist;if(a){const e=a[ol]();e&&(t.title=e);const n=a.role.match(Vl);if(n){const e="heading",a=n[1];t.role=e;t["aria-level"]=a}}if("table"===e.layout)t.role="table";else if("row"===e.layout)t.role="row";else{const a=e[So]();"row"===a.layout&&(t.role="TH"===a.assist?.role?"columnheader":"cell")}}function ariaLabel(e){if(!e.assist)return null;const t=e.assist;return t.speak&&""!==t.speak[so]?t.speak[so]:t.toolTip?t.toolTip[so]:null}function valueToHtml(e){return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:Object.create(null)},children:[{name:"span",attributes:{style:Object.create(null)},value:e}]})}function setFirstUnsplittable(e){const t=e[Ao]();if(null===t[oo].firstUnsplittable){t[oo].firstUnsplittable=e;t[oo].noLayoutFailure=!0}}function unsetFirstUnsplittable(e){const t=e[Ao]();t[oo].firstUnsplittable===e&&(t[oo].noLayoutFailure=!1)}function handleBreak(e){if(e[oo])return!1;e[oo]=Object.create(null);if("auto"===e.targetType)return!1;const t=e[Ao]();let a=null;if(e.target){a=t[el](e.target,e[So]());if(!a)return!1;a=a[0]}const{currentPageArea:n,currentContentArea:s}=t[oo];if("pageArea"===e.targetType){a instanceof PageArea||(a=null);if(e.startNew){e[oo].target=a||n;return!0}if(a&&a!==n){e[oo].target=a;return!0}return!1}a instanceof ContentArea||(a=null);const r=a&&a[So]();let i,o=r;if(e.startNew)if(a){const e=r.contentArea.children,t=e.indexOf(s),n=e.indexOf(a);-1!==t&&te;n[oo].noLayoutFailure=!0;const i=t[ol](a);e[Yi](i.html,i.bbox);n[oo].noLayoutFailure=s;t[vo]=r}class AppearanceFilter extends StringObject{constructor(e){super(Kl,"appearanceFilter");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Arc extends XFAObject{constructor(e){super(Kl,"arc",!0);this.circular=getInteger({data:e.circular,defaultValue:0,validate:e=>1===e});this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.startAngle=getFloat({data:e.startAngle,defaultValue:0,validate:e=>!0});this.sweepAngle=getFloat({data:e.sweepAngle,defaultValue:360,validate:e=>!0});this.use=e.use||"";this.usehref=e.usehref||"";this.edge=null;this.fill=null}[ol](){const e=this.edge||new Edge({}),t=e[fl](),a=Object.create(null);"visible"===this.fill?.presence?Object.assign(a,this.fill[fl]()):a.fill="transparent";a.strokeWidth=measureToString("visible"===e.presence?e.thickness:0);a.stroke=t.color;let n;const s={xmlns:Gl,style:{width:"100%",height:"100%",overflow:"visible"}};if(360===this.sweepAngle)n={name:"ellipse",attributes:{xmlns:Gl,cx:"50%",cy:"50%",rx:"50%",ry:"50%",style:a}};else{const e=this.startAngle*Math.PI/180,t=this.sweepAngle*Math.PI/180,r=this.sweepAngle>180?1:0,[i,o,l,f]=[50*(1+Math.cos(e)),50*(1-Math.sin(e)),50*(1+Math.cos(e+t)),50*(1-Math.sin(e+t))];n={name:"path",attributes:{xmlns:Gl,d:`M ${i} ${o} A 50 50 0 ${r} 0 ${l} ${f}`,vectorEffect:"non-scaling-stroke",style:a}};Object.assign(s,{viewBox:"0 0 100 100",preserveAspectRatio:"none"})}const r={name:"svg",children:[n],attributes:s};if(hasMargin(this[So]()[So]()))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[r]});r.attributes.style.position="absolute";return HTMLResult.success(r)}}class Area extends XFAObject{constructor(e){super(Kl,"area",!0);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.id=e.id||"";this.name=e.name||"";this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.desc=null;this.extras=null;this.area=new XFAObjectArray;this.draw=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}*[yo](){yield*getContainedChildren(this)}[Eo](){return!0}[Ho](){return!0}[Yi](e,t){const[a,n,s,r]=t;this[oo].width=Math.max(this[oo].width,a+s);this[oo].height=Math.max(this[oo].height,n+r);this[oo].children.push(e)}[uo](){return this[oo].availableSpace}[ol](e){const t=toStyle(this,"position"),a={style:t,id:this[cl],class:["xfaArea"]};isPrintOnly(this)&&a.class.push("xfaPrintOnly");this.name&&(a.xfaName=this.name);const n=[];this[oo]={children:n,width:0,height:0,availableSpace:e};const s=this[Qi]({filter:new Set(["area","draw","field","exclGroup","subform","subformSet"]),include:!0});if(!s.success){if(s.isBreak())return s;delete this[oo];return HTMLResult.FAILURE}t.width=measureToString(this[oo].width);t.height=measureToString(this[oo].height);const r={name:"div",attributes:a,children:n},i=[this.x,this.y,this[oo].width,this[oo].height];delete this[oo];return HTMLResult.success(r,i)}}class Assist extends XFAObject{constructor(e){super(Kl,"assist",!0);this.id=e.id||"";this.role=e.role||"";this.use=e.use||"";this.usehref=e.usehref||"";this.speak=null;this.toolTip=null}[ol](){return this.toolTip?.[so]||null}}class Barcode extends XFAObject{constructor(e){super(Kl,"barcode",!0);this.charEncoding=getKeyword({data:e.charEncoding?e.charEncoding.toLowerCase():"",defaultValue:"",validate:e=>["utf-8","big-five","fontspecific","gbk","gb-18030","gb-2312","ksc-5601","none","shift-jis","ucs-2","utf-16"].includes(e)||e.match(/iso-8859-\d{2}/)});this.checksum=getStringOption(e.checksum,["none","1mod10","1mod10_1mod11","2mod10","auto"]);this.dataColumnCount=getInteger({data:e.dataColumnCount,defaultValue:-1,validate:e=>e>=0});this.dataLength=getInteger({data:e.dataLength,defaultValue:-1,validate:e=>e>=0});this.dataPrep=getStringOption(e.dataPrep,["none","flateCompress"]);this.dataRowCount=getInteger({data:e.dataRowCount,defaultValue:-1,validate:e=>e>=0});this.endChar=e.endChar||"";this.errorCorrectionLevel=getInteger({data:e.errorCorrectionLevel,defaultValue:-1,validate:e=>e>=0&&e<=8});this.id=e.id||"";this.moduleHeight=getMeasurement(e.moduleHeight,"5mm");this.moduleWidth=getMeasurement(e.moduleWidth,"0.25mm");this.printCheckDigit=getInteger({data:e.printCheckDigit,defaultValue:0,validate:e=>1===e});this.rowColumnRatio=getRatio(e.rowColumnRatio);this.startChar=e.startChar||"";this.textLocation=getStringOption(e.textLocation,["below","above","aboveEmbedded","belowEmbedded","none"]);this.truncate=getInteger({data:e.truncate,defaultValue:0,validate:e=>1===e});this.type=getStringOption(e.type?e.type.toLowerCase():"",["aztec","codabar","code2of5industrial","code2of5interleaved","code2of5matrix","code2of5standard","code3of9","code3of9extended","code11","code49","code93","code128","code128a","code128b","code128c","code128sscc","datamatrix","ean8","ean8add2","ean8add5","ean13","ean13add2","ean13add5","ean13pwcd","fim","logmars","maxicode","msi","pdf417","pdf417macro","plessey","postauscust2","postauscust3","postausreplypaid","postausstandard","postukrm4scc","postusdpbc","postusimb","postusstandard","postus5zip","qrcode","rfid","rss14","rss14expanded","rss14limited","rss14stacked","rss14stackedomni","rss14truncated","telepen","ucc128","ucc128random","ucc128sscc","upca","upcaadd2","upcaadd5","upcapwcd","upce","upceadd2","upceadd5","upcean2","upcean5","upsmaxicode"]);this.upsMode=getStringOption(e.upsMode,["usCarrier","internationalCarrier","secureSymbol","standardSymbol"]);this.use=e.use||"";this.usehref=e.usehref||"";this.wideNarrowRatio=getRatio(e.wideNarrowRatio);this.encrypt=null;this.extras=null}}class Bind extends XFAObject{constructor(e){super(Kl,"bind",!0);this.match=getStringOption(e.match,["once","dataRef","global","none"]);this.ref=e.ref||"";this.picture=null}}class BindItems extends XFAObject{constructor(e){super(Kl,"bindItems");this.connection=e.connection||"";this.labelRef=e.labelRef||"";this.ref=e.ref||"";this.valueRef=e.valueRef||""}}class Bookend extends XFAObject{constructor(e){super(Kl,"bookend");this.id=e.id||"";this.leader=e.leader||"";this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||""}}class BooleanElement extends Option01{constructor(e){super(Kl,"boolean");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[ol](e){return valueToHtml(1===this[so]?"1":"0")}}class Border extends XFAObject{constructor(e){super(Kl,"border",!0);this.break=getStringOption(e.break,["close","open"]);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.corner=new XFAObjectArray(4);this.edge=new XFAObjectArray(4);this.extras=null;this.fill=null;this.margin=null}[wo](){if(!this[oo]){const e=this.edge.children.slice();if(e.length<4){const t=e.at(-1)||new Edge({});for(let a=e.length;a<4;a++)e.push(t)}const t=e.map(e=>e.thickness),a=[0,0,0,0];if(this.margin){a[0]=this.margin.topInset;a[1]=this.margin.rightInset;a[2]=this.margin.bottomInset;a[3]=this.margin.leftInset}this[oo]={widths:t,insets:a,edges:e}}return this[oo]}[fl](){const{edges:e}=this[wo](),t=e.map(e=>{const t=e[fl]();t.color||="#000000";return t}),a=Object.create(null);this.margin&&Object.assign(a,this.margin[fl]());"visible"===this.fill?.presence&&Object.assign(a,this.fill[fl]());if(this.corner.children.some(e=>0!==e.radius)){const e=this.corner.children.map(e=>e[fl]());if(2===e.length||3===e.length){const t=e.at(-1);for(let a=e.length;a<4;a++)e.push(t)}a.borderRadius=e.map(e=>e.radius).join(" ")}switch(this.presence){case"invisible":case"hidden":a.borderStyle="";break;case"inactive":a.borderStyle="none";break;default:a.borderStyle=t.map(e=>e.style).join(" ")}a.borderWidth=t.map(e=>e.width).join(" ");a.borderColor=t.map(e=>e.color).join(" ");return a}}class Break extends XFAObject{constructor(e){super(Kl,"break",!0);this.after=getStringOption(e.after,["auto","contentArea","pageArea","pageEven","pageOdd"]);this.afterTarget=e.afterTarget||"";this.before=getStringOption(e.before,["auto","contentArea","pageArea","pageEven","pageOdd"]);this.beforeTarget=e.beforeTarget||"";this.bookendLeader=e.bookendLeader||"";this.bookendTrailer=e.bookendTrailer||"";this.id=e.id||"";this.overflowLeader=e.overflowLeader||"";this.overflowTarget=e.overflowTarget||"";this.overflowTrailer=e.overflowTrailer||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class BreakAfter extends XFAObject{constructor(e){super(Kl,"breakAfter",!0);this.id=e.id||"";this.leader=e.leader||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.target=e.target||"";this.targetType=getStringOption(e.targetType,["auto","contentArea","pageArea"]);this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||"";this.script=null}}class BreakBefore extends XFAObject{constructor(e){super(Kl,"breakBefore",!0);this.id=e.id||"";this.leader=e.leader||"";this.startNew=getInteger({data:e.startNew,defaultValue:0,validate:e=>1===e});this.target=e.target||"";this.targetType=getStringOption(e.targetType,["auto","contentArea","pageArea"]);this.trailer=e.trailer||"";this.use=e.use||"";this.usehref=e.usehref||"";this.script=null}[ol](e){this[oo]={};return HTMLResult.FAILURE}}class Button extends XFAObject{constructor(e){super(Kl,"button",!0);this.highlight=getStringOption(e.highlight,["inverted","none","outline","push"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[ol](e){const t=this[So]()[So](),a={name:"button",attributes:{id:this[cl],class:["xfaButton"],style:{}},children:[]};for(const e of t.event.children){if("click"!==e.activity||!e.script)continue;const t=recoverJsURL(e.script[so]);if(!t)continue;const n=fixURL(t.url);n&&a.children.push({name:"a",attributes:{id:"link"+this[cl],href:n,newWindow:t.newWindow,class:["xfaLink"],style:{}},children:[]})}return HTMLResult.success(a)}}class Calculate extends XFAObject{constructor(e){super(Kl,"calculate",!0);this.id=e.id||"";this.override=getStringOption(e.override,["disabled","error","ignore","warning"]);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.message=null;this.script=null}}class Caption extends XFAObject{constructor(e){super(Kl,"caption",!0);this.id=e.id||"";this.placement=getStringOption(e.placement,["left","bottom","inline","right","top"]);this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.reserve=Math.ceil(getMeasurement(e.reserve));this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.font=null;this.margin=null;this.para=null;this.value=null}[nl](e){_setValue(this,e)}[wo](e){if(!this[oo]){let{width:t,height:a}=e;switch(this.placement){case"left":case"right":case"inline":t=this.reserve<=0?t:this.reserve;break;case"top":case"bottom":a=this.reserve<=0?a:this.reserve}this[oo]=layoutNode(this,{width:t,height:a})}return this[oo]}[ol](e){if(!this.value)return HTMLResult.EMPTY;this[Yo]();const t=this.value[ol](e).html;if(!t){this[$o]();return HTMLResult.EMPTY}const a=this.reserve;if(this.reserve<=0){const{w:t,h:a}=this[wo](e);switch(this.placement){case"left":case"right":case"inline":this.reserve=t;break;case"top":case"bottom":this.reserve=a}}const n=[];"string"==typeof t?n.push({name:"#text",value:t}):n.push(t);const s=toStyle(this,"font","margin","visibility");switch(this.placement){case"left":case"right":this.reserve>0&&(s.width=measureToString(this.reserve));break;case"top":case"bottom":this.reserve>0&&(s.height=measureToString(this.reserve))}setPara(this,null,t);this[$o]();this.reserve=a;return HTMLResult.success({name:"div",attributes:{style:s,class:["xfaCaption"]},children:n})}}class Certificate extends StringObject{constructor(e){super(Kl,"certificate");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Certificates extends XFAObject{constructor(e){super(Kl,"certificates",!0);this.credentialServerPolicy=getStringOption(e.credentialServerPolicy,["optional","required"]);this.id=e.id||"";this.url=e.url||"";this.urlPolicy=e.urlPolicy||"";this.use=e.use||"";this.usehref=e.usehref||"";this.encryption=null;this.issuers=null;this.keyUsage=null;this.oids=null;this.signing=null;this.subjectDNs=null}}class CheckButton extends XFAObject{constructor(e){super(Kl,"checkButton",!0);this.id=e.id||"";this.mark=getStringOption(e.mark,["default","check","circle","cross","diamond","square","star"]);this.shape=getStringOption(e.shape,["square","round"]);this.size=getMeasurement(e.size,"10pt");this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[ol](e){const t=toStyle(this,"margin"),a=measureToString(this.size);t.width=t.height=a;let n,s,r;const i=this[So]()[So](),o=i.items.children.length&&i.items.children[0][ol]().html||[],l={on:(void 0!==o[0]?o[0]:"on").toString(),off:(void 0!==o[1]?o[1]:"off").toString()},f=(i.value?.[rl]()||"off")===l.on||void 0,c=i[vo](),h=i[cl];let u;if(c instanceof ExclGroup){r=c[cl];n="radio";s="xfaRadio";u=c[ro]?.[cl]||c[cl]}else{n="checkbox";s="xfaCheckbox";u=i[ro]?.[cl]||i[cl]}const m={name:"input",attributes:{class:[s],style:t,fieldId:h,dataId:u,type:n,checked:f,xfaOn:l.on,xfaOff:l.off,"aria-label":ariaLabel(i),"aria-required":!1}};r&&(m.attributes.name=r);if(isRequired(i)){m.attributes["aria-required"]=!0;m.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[m]})}}class ChoiceList extends XFAObject{constructor(e){super(Kl,"choiceList",!0);this.commitOn=getStringOption(e.commitOn,["select","exit"]);this.id=e.id||"";this.open=getStringOption(e.open,["userControl","always","multiSelect","onEntry"]);this.textEntry=getInteger({data:e.textEntry,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[ol](e){const t=toStyle(this,"border","margin"),a=this[So]()[So](),n={fontSize:`calc(${a.font?.size||10}px * var(--total-scale-factor))`},s=[];if(a.items.children.length>0){const e=a.items;let t=0,r=0;if(2===e.children.length){t=e.children[0].save;r=1-t}const i=e.children[t][ol]().html,o=e.children[r][ol]().html;let l=!1;const f=a.value?.[rl]()||"";for(let e=0,t=i.length;eMathClamp(parseInt(e.trim(),10),0,255)).map(e=>isNaN(e)?0:e);if(r.length<3)return{r:a,g:n,b:s};[a,n,s]=r;return{r:a,g:n,b:s}}(e.value):"";this.extras=null}[Co](){return!1}[fl](){return this.value?Util.makeHexColor(this.value.r,this.value.g,this.value.b):null}}class Comb extends XFAObject{constructor(e){super(Kl,"comb");this.id=e.id||"";this.numberOfCells=getInteger({data:e.numberOfCells,defaultValue:0,validate:e=>e>=0});this.use=e.use||"";this.usehref=e.usehref||""}}class Connect extends XFAObject{constructor(e){super(Kl,"connect",!0);this.connection=e.connection||"";this.id=e.id||"";this.ref=e.ref||"";this.usage=getStringOption(e.usage,["exportAndImport","exportOnly","importOnly"]);this.use=e.use||"";this.usehref=e.usehref||"";this.picture=null}}class ContentArea extends XFAObject{constructor(e){super(Kl,"contentArea",!0);this.h=getMeasurement(e.h);this.id=e.id||"";this.name=e.name||"";this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.w=getMeasurement(e.w);this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.desc=null;this.extras=null}[ol](e){const t={left:measureToString(this.x),top:measureToString(this.y),width:measureToString(this.w),height:measureToString(this.h)},a=["xfaContentarea"];isPrintOnly(this)&&a.push("xfaPrintOnly");return HTMLResult.success({name:"div",children:[],attributes:{style:t,class:a,id:this[cl]}})}}class Corner extends XFAObject{constructor(e){super(Kl,"corner",!0);this.id=e.id||"";this.inverted=getInteger({data:e.inverted,defaultValue:0,validate:e=>1===e});this.join=getStringOption(e.join,["square","round"]);this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.radius=getMeasurement(e.radius);this.stroke=getStringOption(e.stroke,["solid","dashDot","dashDotDot","dashed","dotted","embossed","etched","lowered","raised"]);this.thickness=getMeasurement(e.thickness,"0.5pt");this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](){const e=toStyle(this,"visibility");e.radius=measureToString("square"===this.join?0:this.radius);return e}}class DateElement extends ContentObject{constructor(e){super(Kl,"date");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=this[so].trim();this[so]=e?new Date(e):null}[ol](e){return valueToHtml(this[so]?this[so].toString():"")}}class DateTime extends ContentObject{constructor(e){super(Kl,"dateTime");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=this[so].trim();this[so]=e?new Date(e):null}[ol](e){return valueToHtml(this[so]?this[so].toString():"")}}class DateTimeEdit extends XFAObject{constructor(e){super(Kl,"dateTimeEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.picker=getStringOption(e.picker,["host","none"]);this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.comb=null;this.extras=null;this.margin=null}[ol](e){const t=toStyle(this,"border","font","margin"),a=this[So]()[So](),n={name:"input",attributes:{type:"text",fieldId:a[cl],dataId:a[ro]?.[cl]||a[cl],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(a),"aria-required":!1}};if(isRequired(a)){n.attributes["aria-required"]=!0;n.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[n]})}}class Decimal extends ContentObject{constructor(e){super(Kl,"decimal");this.fracDigits=getInteger({data:e.fracDigits,defaultValue:2,validate:e=>!0});this.id=e.id||"";this.leadDigits=getInteger({data:e.leadDigits,defaultValue:-1,validate:e=>!0});this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=parseFloat(this[so].trim());this[so]=isNaN(e)?null:e}[ol](e){return valueToHtml(null!==this[so]?this[so].toString():"")}}class DefaultUi extends XFAObject{constructor(e){super(Kl,"defaultUi",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class Desc extends XFAObject{constructor(e){super(Kl,"desc",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}}class DigestMethod extends OptionObject{constructor(e){super(Kl,"digestMethod",["","SHA1","SHA256","SHA512","RIPEMD160"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class DigestMethods extends XFAObject{constructor(e){super(Kl,"digestMethods",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.digestMethod=new XFAObjectArray}}class Draw extends XFAObject{constructor(e){super(Kl,"draw",!0);this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.rotate=getInteger({data:e.rotate,defaultValue:0,validate:e=>e%90==0});this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.border=null;this.caption=null;this.desc=null;this.extras=null;this.font=null;this.keep=null;this.margin=null;this.para=null;this.traversal=null;this.ui=null;this.value=null;this.setProperty=new XFAObjectArray}[nl](e){_setValue(this,e)}[ol](e){setTabIndex(this);if("hidden"===this.presence||"inactive"===this.presence)return HTMLResult.EMPTY;fixDimensions(this);this[Yo]();const t=this.w,a=this.h,{w:n,h:s,isBroken:r}=layoutNode(this,e);if(n&&""===this.w){if(r&&this[vo]()[Po]()){this[$o]();return HTMLResult.FAILURE}this.w=n}s&&""===this.h&&(this.h=s);setFirstUnsplittable(this);if(!checkDimensions(this,e)){this.w=t;this.h=a;this[$o]();return HTMLResult.FAILURE}unsetFirstUnsplittable(this);const i=toStyle(this,"font","hAlign","dimensions","position","presence","rotate","anchorType","border","margin");setMinMaxDimensions(this,i);if(i.margin){i.padding=i.margin;delete i.margin}const o=["xfaDraw"];this.font&&o.push("xfaFont");isPrintOnly(this)&&o.push("xfaPrintOnly");const l={style:i,id:this[cl],class:o};this.name&&(l.xfaName=this.name);const f={name:"div",attributes:l,children:[]};applyAssist(this,l);const c=computeBbox(this,f,e),h=this.value?this.value[ol](e).html:null;if(null===h){this.w=t;this.h=a;this[$o]();return HTMLResult.success(createWrapper(this,f),c)}f.children.push(h);setPara(this,i,h);this.w=t;this.h=a;this[$o]();return HTMLResult.success(createWrapper(this,f),c)}}class Edge extends XFAObject{constructor(e){super(Kl,"edge",!0);this.cap=getStringOption(e.cap,["square","butt","round"]);this.id=e.id||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.stroke=getStringOption(e.stroke,["solid","dashDot","dashDotDot","dashed","dotted","embossed","etched","lowered","raised"]);this.thickness=getMeasurement(e.thickness,"0.5pt");this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](){const e=toStyle(this,"visibility");Object.assign(e,{linecap:this.cap,width:measureToString(this.thickness),color:this.color?this.color[fl]():"#000000",style:""});if("visible"!==this.presence)e.style="none";else switch(this.stroke){case"solid":e.style="solid";break;case"dashDot":case"dashDotDot":case"dashed":e.style="dashed";break;case"dotted":e.style="dotted";break;case"embossed":e.style="ridge";break;case"etched":e.style="groove";break;case"lowered":e.style="inset";break;case"raised":e.style="outset"}return e}}class Encoding extends OptionObject{constructor(e){super(Kl,"encoding",["adbe.x509.rsa_sha1","adbe.pkcs7.detached","adbe.pkcs7.sha1"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Encodings extends XFAObject{constructor(e){super(Kl,"encodings",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.encoding=new XFAObjectArray}}class Encrypt extends XFAObject{constructor(e){super(Kl,"encrypt",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=null}}class EncryptData extends XFAObject{constructor(e){super(Kl,"encryptData",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["encrypt","decrypt"]);this.target=e.target||"";this.use=e.use||"";this.usehref=e.usehref||"";this.filter=null;this.manifest=null}}class Encryption extends XFAObject{constructor(e){super(Kl,"encryption",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class EncryptionMethod extends OptionObject{constructor(e){super(Kl,"encryptionMethod",["","AES256-CBC","TRIPLEDES-CBC","AES128-CBC","AES192-CBC"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class EncryptionMethods extends XFAObject{constructor(e){super(Kl,"encryptionMethods",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.encryptionMethod=new XFAObjectArray}}class Event extends XFAObject{constructor(e){super(Kl,"event",!0);this.activity=getStringOption(e.activity,["click","change","docClose","docReady","enter","exit","full","indexChange","initialize","mouseDown","mouseEnter","mouseExit","mouseUp","postExecute","postOpen","postPrint","postSave","postSign","postSubmit","preExecute","preOpen","prePrint","preSave","preSign","preSubmit","ready","validationState"]);this.id=e.id||"";this.listen=getStringOption(e.listen,["refOnly","refAndDescendents"]);this.name=e.name||"";this.ref=e.ref||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.encryptData=null;this.execute=null;this.script=null;this.signData=null;this.submit=null}}class ExData extends ContentObject{constructor(e){super(Kl,"exData");this.contentType=e.contentType||"";this.href=e.href||"";this.id=e.id||"";this.maxLength=getInteger({data:e.maxLength,defaultValue:-1,validate:e=>e>=-1});this.name=e.name||"";this.rid=e.rid||"";this.transferEncoding=getStringOption(e.transferEncoding,["none","base64","package"]);this.use=e.use||"";this.usehref=e.usehref||""}[Ro](){return"text/html"===this.contentType}[Wo](e){if("text/html"===this.contentType&&e[Lo]===ul.xhtml.id){this[so]=e;return!0}if("text/xml"===this.contentType){this[so]=e;return!0}return!1}[ol](e){return"text/html"===this.contentType&&this[so]?this[so][ol](e):HTMLResult.EMPTY}}class ExObject extends XFAObject{constructor(e){super(Kl,"exObject",!0);this.archive=e.archive||"";this.classId=e.classId||"";this.codeBase=e.codeBase||"";this.codeType=e.codeType||"";this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.exObject=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}}class ExclGroup extends XFAObject{constructor(e){super(Kl,"exclGroup",!0);this.access=getStringOption(e.access,["open","nonInteractive","protected","readOnly"]);this.accessKey=e.accessKey||"";this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.layout=getStringOption(e.layout,["position","lr-tb","rl-row","rl-tb","row","table","tb"]);this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.border=null;this.calculate=null;this.caption=null;this.desc=null;this.extras=null;this.margin=null;this.para=null;this.traversal=null;this.validate=null;this.connect=new XFAObjectArray;this.event=new XFAObjectArray;this.field=new XFAObjectArray;this.setProperty=new XFAObjectArray}[Ho](){return!0}[Co](){return!0}[nl](e){for(const t of this.field.children){if(!t.value){const e=new Value({});t[Ji](e);t.value=e}t.value[nl](e)}}[Po](){return this.layout.endsWith("-tb")&&0===this[oo].attempt&&this[oo].numberInLine>0||this[So]()[Po]()}[No](){const e=this[vo]();if(!e[No]())return!1;if(void 0!==this[oo]._isSplittable)return this[oo]._isSplittable;if("position"===this.layout||this.layout.includes("row")){this[oo]._isSplittable=!1;return!1}if(e.layout?.endsWith("-tb")&&0!==e[oo].numberInLine)return!1;this[oo]._isSplittable=!0;return!0}[fo](){return flushHTML(this)}[Yi](e,t){addHTML(this,e,t)}[uo](){return getAvailableSpace(this)}[ol](e){setTabIndex(this);if("hidden"===this.presence||"inactive"===this.presence||0===this.h||0===this.w)return HTMLResult.EMPTY;fixDimensions(this);const t=[],a={id:this[cl],class:[]};setAccess(this,a.class);this[oo]||=Object.create(null);Object.assign(this[oo],{children:t,attributes:a,attempt:0,line:null,numberInLine:0,availableSpace:{width:Math.min(this.w||1/0,e.width),height:Math.min(this.h||1/0,e.height)},width:0,height:0,prevHeight:0,currentWidth:0});const n=this[No]();n||setFirstUnsplittable(this);if(!checkDimensions(this,e))return HTMLResult.FAILURE;const s=new Set(["field"]);if(this.layout.includes("row")){const e=this[vo]().columnWidths;if(Array.isArray(e)&&e.length>0){this[oo].columnWidths=e;this[oo].currentColumn=0}}const r=toStyle(this,"anchorType","dimensions","position","presence","border","margin","hAlign"),i=["xfaExclgroup"],o=layoutClass(this);o&&i.push(o);isPrintOnly(this)&&i.push("xfaPrintOnly");a.style=r;a.class=i;this.name&&(a.xfaName=this.name);this[Yo]();const l="lr-tb"===this.layout||"rl-tb"===this.layout,f=l?2:1;for(;this[oo].attempte>=1||-1===e});this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.rotate=getInteger({data:e.rotate,defaultValue:0,validate:e=>e%90==0});this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.border=null;this.calculate=null;this.caption=null;this.desc=null;this.extras=null;this.font=null;this.format=null;this.items=new XFAObjectArray(2);this.keep=null;this.margin=null;this.para=null;this.traversal=null;this.ui=null;this.validate=null;this.value=null;this.bindItems=new XFAObjectArray;this.connect=new XFAObjectArray;this.event=new XFAObjectArray;this.setProperty=new XFAObjectArray}[Ho](){return!0}[nl](e){_setValue(this,e)}[ol](e){setTabIndex(this);if(!this.ui){this.ui=new Ui({});this.ui[xo]=this[xo];this[Ji](this.ui);let e;switch(this.items.children.length){case 0:e=new TextEdit({});this.ui.textEdit=e;break;case 1:e=new CheckButton({});this.ui.checkButton=e;break;case 2:e=new ChoiceList({});this.ui.choiceList=e}this.ui[Ji](e)}if(!this.ui||"hidden"===this.presence||"inactive"===this.presence||0===this.h||0===this.w)return HTMLResult.EMPTY;this.caption&&delete this.caption[oo];this[Yo]();const t=this.caption?this.caption[ol](e).html:null,a=this.w,n=this.h;let s=0,r=0;if(this.margin){s=this.margin.leftInset+this.margin.rightInset;r=this.margin.topInset+this.margin.bottomInset}let i=null;if(""===this.w||""===this.h){let t=null,a=null,n=0,o=0;if(this.ui.checkButton)n=o=this.ui.checkButton.size;else{const{w:t,h:a}=layoutNode(this,e);if(null!==t){n=t;o=a}else o=function fonts_getMetrics(e,t=!1){let a=null;if(e){const t=stripQuotes(e.typeface),n=e[xo].fontFinder.find(t);a=selectFont(e,n)}if(!a)return{lineHeight:12,lineGap:2,lineNoGap:10};const n=e.size||10,s=a.lineHeight?Math.max(t?0:1.2,a.lineHeight):1.2,r=void 0===a.lineGap?.2:a.lineGap;return{lineHeight:s*n,lineGap:r*n,lineNoGap:Math.max(1,s-r)*n}}(this.font,!0).lineNoGap}i=getBorderDims(this.ui[wo]());n+=i.w;o+=i.h;if(this.caption){const{w:s,h:r,isBroken:i}=this.caption[wo](e);if(i&&this[vo]()[Po]()){this[$o]();return HTMLResult.FAILURE}t=s;a=r;switch(this.caption.placement){case"left":case"right":case"inline":t+=n;break;case"top":case"bottom":a+=o}}else{t=n;a=o}if(t&&""===this.w){t+=s;this.w=Math.min(this.maxW<=0?1/0:this.maxW,this.minW+1e>=1&&e<=5});this.appearanceFilter=null;this.certificates=null;this.digestMethods=null;this.encodings=null;this.encryptionMethods=null;this.handler=null;this.lockDocument=null;this.mdp=null;this.reasons=null;this.timeStamp=null}}class Float extends ContentObject{constructor(e){super(Kl,"float");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=parseFloat(this[so].trim());this[so]=isNaN(e)?null:e}[ol](e){return valueToHtml(null!==this[so]?this[so].toString():"")}}class template_Font extends XFAObject{constructor(e){super(Kl,"font",!0);this.baselineShift=getMeasurement(e.baselineShift);this.fontHorizontalScale=getFloat({data:e.fontHorizontalScale,defaultValue:100,validate:e=>e>=0});this.fontVerticalScale=getFloat({data:e.fontVerticalScale,defaultValue:100,validate:e=>e>=0});this.id=e.id||"";this.kerningMode=getStringOption(e.kerningMode,["none","pair"]);this.letterSpacing=getMeasurement(e.letterSpacing,"0");this.lineThrough=getInteger({data:e.lineThrough,defaultValue:0,validate:e=>1===e||2===e});this.lineThroughPeriod=getStringOption(e.lineThroughPeriod,["all","word"]);this.overline=getInteger({data:e.overline,defaultValue:0,validate:e=>1===e||2===e});this.overlinePeriod=getStringOption(e.overlinePeriod,["all","word"]);this.posture=getStringOption(e.posture,["normal","italic"]);this.size=getMeasurement(e.size,"10pt");this.typeface=e.typeface||"Courier";this.underline=getInteger({data:e.underline,defaultValue:0,validate:e=>1===e||2===e});this.underlinePeriod=getStringOption(e.underlinePeriod,["all","word"]);this.use=e.use||"";this.usehref=e.usehref||"";this.weight=getStringOption(e.weight,["normal","bold"]);this.extras=null;this.fill=null}[Zi](e){super[Zi](e);this[xo].usedTypefaces.add(this.typeface)}[fl](){const e=toStyle(this,"fill"),t=e.color;if(t)if("#000000"===t)delete e.color;else if(!t.startsWith("#")){e.background=t;e.backgroundClip="text";e.color="transparent"}this.baselineShift&&(e.verticalAlign=measureToString(this.baselineShift));e.fontKerning="none"===this.kerningMode?"none":"normal";e.letterSpacing=measureToString(this.letterSpacing);if(0!==this.lineThrough){e.textDecoration="line-through";2===this.lineThrough&&(e.textDecorationStyle="double")}if(0!==this.overline){e.textDecoration="overline";2===this.overline&&(e.textDecorationStyle="double")}e.fontStyle=this.posture;e.fontSize=measureToString(.99*this.size);setFontFamily(this,this,this[xo].fontFinder,e);if(0!==this.underline){e.textDecoration="underline";2===this.underline&&(e.textDecorationStyle="double")}e.fontWeight=this.weight;return e}}class Format extends XFAObject{constructor(e){super(Kl,"format",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.picture=null}}class Handler extends StringObject{constructor(e){super(Kl,"handler");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Hyphenation extends XFAObject{constructor(e){super(Kl,"hyphenation");this.excludeAllCaps=getInteger({data:e.excludeAllCaps,defaultValue:0,validate:e=>1===e});this.excludeInitialCap=getInteger({data:e.excludeInitialCap,defaultValue:0,validate:e=>1===e});this.hyphenate=getInteger({data:e.hyphenate,defaultValue:0,validate:e=>1===e});this.id=e.id||"";this.pushCharacterCount=getInteger({data:e.pushCharacterCount,defaultValue:3,validate:e=>e>=0});this.remainCharacterCount=getInteger({data:e.remainCharacterCount,defaultValue:3,validate:e=>e>=0});this.use=e.use||"";this.usehref=e.usehref||"";this.wordCharacterCount=getInteger({data:e.wordCharacterCount,defaultValue:7,validate:e=>e>=0})}}class Image extends StringObject{constructor(e){super(Kl,"image");this.aspect=getStringOption(e.aspect,["fit","actual","height","none","width"]);this.contentType=e.contentType||"";this.href=e.href||"";this.id=e.id||"";this.name=e.name||"";this.transferEncoding=getStringOption(e.transferEncoding,["base64","none","package"]);this.use=e.use||"";this.usehref=e.usehref||""}[ol](){if(this.contentType&&!$l.has(this.contentType.toLowerCase()))return HTMLResult.EMPTY;let e=this[xo].images?.get(this.href);if(!e&&(this.href||!this[so]))return HTMLResult.EMPTY;e||"base64"!==this.transferEncoding||(e=Uint8Array.fromBase64(this[so]));if(!e)return HTMLResult.EMPTY;if(!this.contentType){for(const[t,a]of Yl)if(e.length>t.length&&t.every((t,a)=>t===e[a])){this.contentType=a;break}if(!this.contentType)return HTMLResult.EMPTY}const t=new Blob([e],{type:this.contentType});let a;switch(this.aspect){case"fit":case"actual":break;case"height":a={height:"100%",objectFit:"fill"};break;case"none":a={width:"100%",height:"100%",objectFit:"fill"};break;case"width":a={width:"100%",objectFit:"fill"}}const n=this[So]();return HTMLResult.success({name:"img",attributes:{class:["xfaImage"],style:a,src:URL.createObjectURL(t),alt:n?ariaLabel(n[So]()):null}})}}class ImageEdit extends XFAObject{constructor(e){super(Kl,"imageEdit",!0);this.data=getStringOption(e.data,["link","embed"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}[ol](e){return"embed"===this.data?HTMLResult.success({name:"div",children:[],attributes:{}}):HTMLResult.EMPTY}}class Integer extends ContentObject{constructor(e){super(Kl,"integer");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=parseInt(this[so].trim(),10);this[so]=isNaN(e)?null:e}[ol](e){return valueToHtml(null!==this[so]?this[so].toString():"")}}class Issuers extends XFAObject{constructor(e){super(Kl,"issuers",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class Items extends XFAObject{constructor(e){super(Kl,"items",!0);this.id=e.id||"";this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.ref=e.ref||"";this.save=getInteger({data:e.save,defaultValue:0,validate:e=>1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}[ol](){const e=[];for(const t of this[ko]())e.push(t[rl]());return HTMLResult.success(e)}}class Keep extends XFAObject{constructor(e){super(Kl,"keep",!0);this.id=e.id||"";const t=["none","contentArea","pageArea"];this.intact=getStringOption(e.intact,t);this.next=getStringOption(e.next,t);this.previous=getStringOption(e.previous,t);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}}class KeyUsage extends XFAObject{constructor(e){super(Kl,"keyUsage");const t=["","yes","no"];this.crlSign=getStringOption(e.crlSign,t);this.dataEncipherment=getStringOption(e.dataEncipherment,t);this.decipherOnly=getStringOption(e.decipherOnly,t);this.digitalSignature=getStringOption(e.digitalSignature,t);this.encipherOnly=getStringOption(e.encipherOnly,t);this.id=e.id||"";this.keyAgreement=getStringOption(e.keyAgreement,t);this.keyCertSign=getStringOption(e.keyCertSign,t);this.keyEncipherment=getStringOption(e.keyEncipherment,t);this.nonRepudiation=getStringOption(e.nonRepudiation,t);this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Line extends XFAObject{constructor(e){super(Kl,"line",!0);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.slope=getStringOption(e.slope,["\\","/"]);this.use=e.use||"";this.usehref=e.usehref||"";this.edge=null}[ol](){const e=this[So]()[So](),t=this.edge||new Edge({}),a=t[fl](),n=Object.create(null),s="visible"===t.presence?t.thickness:0;n.strokeWidth=measureToString(s);n.stroke=a.color;let r,i,o,l,f="100%",c="100%";if(e.w<=s){[r,i,o,l]=["50%",0,"50%","100%"];f=n.strokeWidth}else if(e.h<=s){[r,i,o,l]=[0,"50%","100%","50%"];c=n.strokeWidth}else"\\"===this.slope?[r,i,o,l]=[0,0,"100%","100%"]:[r,i,o,l]=[0,"100%","100%",0];const h={name:"svg",children:[{name:"line",attributes:{xmlns:Gl,x1:r,y1:i,x2:o,y2:l,style:n}}],attributes:{xmlns:Gl,width:f,height:c,style:{overflow:"visible"}}};if(hasMargin(e))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[h]});h.attributes.style.position="absolute";return HTMLResult.success(h)}}class Linear extends XFAObject{constructor(e){super(Kl,"linear",!0);this.id=e.id||"";this.type=getStringOption(e.type,["toRight","toBottom","toLeft","toTop"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](e){e=e?e[fl]():"#FFFFFF";return`linear-gradient(${this.type.replace(/([RBLT])/," $1").toLowerCase()}, ${e}, ${this.color?this.color[fl]():"#000000"})`}}class LockDocument extends ContentObject{constructor(e){super(Kl,"lockDocument");this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}[lo](){this[so]=getStringOption(this[so],["auto","0","1"])}}class Manifest extends XFAObject{constructor(e){super(Kl,"manifest",!0);this.action=getStringOption(e.action,["include","all","exclude"]);this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.ref=new XFAObjectArray}}class Margin extends XFAObject{constructor(e){super(Kl,"margin",!0);this.bottomInset=getMeasurement(e.bottomInset,"0");this.id=e.id||"";this.leftInset=getMeasurement(e.leftInset,"0");this.rightInset=getMeasurement(e.rightInset,"0");this.topInset=getMeasurement(e.topInset,"0");this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[fl](){return{margin:measureToString(this.topInset)+" "+measureToString(this.rightInset)+" "+measureToString(this.bottomInset)+" "+measureToString(this.leftInset)}}}class Mdp extends XFAObject{constructor(e){super(Kl,"mdp");this.id=e.id||"";this.permissions=getInteger({data:e.permissions,defaultValue:2,validate:e=>1===e||3===e});this.signatureType=getStringOption(e.signatureType,["filler","author"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Medium extends XFAObject{constructor(e){super(Kl,"medium");this.id=e.id||"";this.imagingBBox=function getBBox(e){const t=-1;if(!e)return{x:t,y:t,width:t,height:t};const a=e.split(",",4).map(e=>getMeasurement(e.trim(),"-1"));if(a.length<4||a[2]<0||a[3]<0)return{x:t,y:t,width:t,height:t};const[n,s,r,i]=a;return{x:n,y:s,width:r,height:i}}(e.imagingBBox);this.long=getMeasurement(e.long);this.orientation=getStringOption(e.orientation,["portrait","landscape"]);this.short=getMeasurement(e.short);this.stock=e.stock||"";this.trayIn=getStringOption(e.trayIn,["auto","delegate","pageFront"]);this.trayOut=getStringOption(e.trayOut,["auto","delegate"]);this.use=e.use||"";this.usehref=e.usehref||""}}class Message extends XFAObject{constructor(e){super(Kl,"message",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.text=new XFAObjectArray}}class NumericEdit extends XFAObject{constructor(e){super(Kl,"numericEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.comb=null;this.extras=null;this.margin=null}[ol](e){const t=toStyle(this,"border","font","margin"),a=this[So]()[So](),n={name:"input",attributes:{type:"text",fieldId:a[cl],dataId:a[ro]?.[cl]||a[cl],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(a),"aria-required":!1}};if(isRequired(a)){n.attributes["aria-required"]=!0;n.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[n]})}}class Occur extends XFAObject{constructor(e){super(Kl,"occur",!0);this.id=e.id||"";this.initial=""!==e.initial?getInteger({data:e.initial,defaultValue:"",validate:e=>!0}):"";this.max=""!==e.max?getInteger({data:e.max,defaultValue:-1,validate:e=>!0}):"";this.min=""!==e.min?getInteger({data:e.min,defaultValue:1,validate:e=>!0}):"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[Zi](){const e=this[So](),t=this.min;""===this.min&&(this.min=e instanceof PageArea||e instanceof PageSet?0:1);""===this.max&&(this.max=""===t?e instanceof PageArea||e instanceof PageSet?-1:1:this.min);-1!==this.max&&this.max!0});this.name=e.name||"";this.numbered=getInteger({data:e.numbered,defaultValue:1,validate:e=>!0});this.oddOrEven=getStringOption(e.oddOrEven,["any","even","odd"]);this.pagePosition=getStringOption(e.pagePosition,["any","first","last","only","rest"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.desc=null;this.extras=null;this.medium=null;this.occur=null;this.area=new XFAObjectArray;this.contentArea=new XFAObjectArray;this.draw=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.subform=new XFAObjectArray}[_o](){if(!this[oo]){this[oo]={numberOfUse:0};return!0}return!this.occur||-1===this.occur.max||this[oo].numberOfUsee.oddOrEven===t&&e.pagePosition===a);if(n)return n;n=this.pageArea.children.find(e=>"any"===e.oddOrEven&&e.pagePosition===a);if(n)return n;n=this.pageArea.children.find(e=>"any"===e.oddOrEven&&"any"===e.pagePosition);return n||this.pageArea.children[0]}}class Para extends XFAObject{constructor(e){super(Kl,"para",!0);this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.lineHeight=e.lineHeight?getMeasurement(e.lineHeight,"0pt"):"";this.marginLeft=e.marginLeft?getMeasurement(e.marginLeft,"0pt"):"";this.marginRight=e.marginRight?getMeasurement(e.marginRight,"0pt"):"";this.orphans=getInteger({data:e.orphans,defaultValue:0,validate:e=>e>=0});this.preserve=e.preserve||"";this.radixOffset=e.radixOffset?getMeasurement(e.radixOffset,"0pt"):"";this.spaceAbove=e.spaceAbove?getMeasurement(e.spaceAbove,"0pt"):"";this.spaceBelow=e.spaceBelow?getMeasurement(e.spaceBelow,"0pt"):"";this.tabDefault=e.tabDefault?getMeasurement(this.tabDefault):"";this.tabStops=(e.tabStops||"").trim().split(/\s+/).map((e,t)=>t%2==1?getMeasurement(e):e);this.textIndent=e.textIndent?getMeasurement(e.textIndent,"0pt"):"";this.use=e.use||"";this.usehref=e.usehref||"";this.vAlign=getStringOption(e.vAlign,["top","bottom","middle"]);this.widows=getInteger({data:e.widows,defaultValue:0,validate:e=>e>=0});this.hyphenation=null}[fl](){const e=toStyle(this,"hAlign");""!==this.marginLeft&&(e.paddingLeft=measureToString(this.marginLeft));""!==this.marginRight&&(e.paddingRight=measureToString(this.marginRight));""!==this.spaceAbove&&(e.paddingTop=measureToString(this.spaceAbove));""!==this.spaceBelow&&(e.paddingBottom=measureToString(this.spaceBelow));if(""!==this.textIndent){e.textIndent=measureToString(this.textIndent);fixTextIndent(e)}this.lineHeight>0&&(e.lineHeight=measureToString(this.lineHeight));""!==this.tabDefault&&(e.tabSize=measureToString(this.tabDefault));this.tabStops.length;this.hyphenatation&&Object.assign(e,this.hyphenatation[fl]());return e}}class PasswordEdit extends XFAObject{constructor(e){super(Kl,"passwordEdit",!0);this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.passwordChar=e.passwordChar||"*";this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.margin=null}}class template_Pattern extends XFAObject{constructor(e){super(Kl,"pattern",!0);this.id=e.id||"";this.type=getStringOption(e.type,["crossHatch","crossDiagonal","diagonalLeft","diagonalRight","horizontal","vertical"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](e){e=e?e[fl]():"#FFFFFF";const t=this.color?this.color[fl]():"#000000",a="repeating-linear-gradient",n=`${e},${e} 5px,${t} 5px,${t} 10px`;switch(this.type){case"crossHatch":return`${a}(to top,${n}) ${a}(to right,${n})`;case"crossDiagonal":return`${a}(45deg,${n}) ${a}(-45deg,${n})`;case"diagonalLeft":return`${a}(45deg,${n})`;case"diagonalRight":return`${a}(-45deg,${n})`;case"horizontal":return`${a}(to top,${n})`;case"vertical":return`${a}(to right,${n})`}return""}}class Picture extends StringObject{constructor(e){super(Kl,"picture");this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Proto extends XFAObject{constructor(e){super(Kl,"proto",!0);this.appearanceFilter=new XFAObjectArray;this.arc=new XFAObjectArray;this.area=new XFAObjectArray;this.assist=new XFAObjectArray;this.barcode=new XFAObjectArray;this.bindItems=new XFAObjectArray;this.bookend=new XFAObjectArray;this.boolean=new XFAObjectArray;this.border=new XFAObjectArray;this.break=new XFAObjectArray;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.button=new XFAObjectArray;this.calculate=new XFAObjectArray;this.caption=new XFAObjectArray;this.certificate=new XFAObjectArray;this.certificates=new XFAObjectArray;this.checkButton=new XFAObjectArray;this.choiceList=new XFAObjectArray;this.color=new XFAObjectArray;this.comb=new XFAObjectArray;this.connect=new XFAObjectArray;this.contentArea=new XFAObjectArray;this.corner=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.dateTimeEdit=new XFAObjectArray;this.decimal=new XFAObjectArray;this.defaultUi=new XFAObjectArray;this.desc=new XFAObjectArray;this.digestMethod=new XFAObjectArray;this.digestMethods=new XFAObjectArray;this.draw=new XFAObjectArray;this.edge=new XFAObjectArray;this.encoding=new XFAObjectArray;this.encodings=new XFAObjectArray;this.encrypt=new XFAObjectArray;this.encryptData=new XFAObjectArray;this.encryption=new XFAObjectArray;this.encryptionMethod=new XFAObjectArray;this.encryptionMethods=new XFAObjectArray;this.event=new XFAObjectArray;this.exData=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.execute=new XFAObjectArray;this.extras=new XFAObjectArray;this.field=new XFAObjectArray;this.fill=new XFAObjectArray;this.filter=new XFAObjectArray;this.float=new XFAObjectArray;this.font=new XFAObjectArray;this.format=new XFAObjectArray;this.handler=new XFAObjectArray;this.hyphenation=new XFAObjectArray;this.image=new XFAObjectArray;this.imageEdit=new XFAObjectArray;this.integer=new XFAObjectArray;this.issuers=new XFAObjectArray;this.items=new XFAObjectArray;this.keep=new XFAObjectArray;this.keyUsage=new XFAObjectArray;this.line=new XFAObjectArray;this.linear=new XFAObjectArray;this.lockDocument=new XFAObjectArray;this.manifest=new XFAObjectArray;this.margin=new XFAObjectArray;this.mdp=new XFAObjectArray;this.medium=new XFAObjectArray;this.message=new XFAObjectArray;this.numericEdit=new XFAObjectArray;this.occur=new XFAObjectArray;this.oid=new XFAObjectArray;this.oids=new XFAObjectArray;this.overflow=new XFAObjectArray;this.pageArea=new XFAObjectArray;this.pageSet=new XFAObjectArray;this.para=new XFAObjectArray;this.passwordEdit=new XFAObjectArray;this.pattern=new XFAObjectArray;this.picture=new XFAObjectArray;this.radial=new XFAObjectArray;this.reason=new XFAObjectArray;this.reasons=new XFAObjectArray;this.rectangle=new XFAObjectArray;this.ref=new XFAObjectArray;this.script=new XFAObjectArray;this.setProperty=new XFAObjectArray;this.signData=new XFAObjectArray;this.signature=new XFAObjectArray;this.signing=new XFAObjectArray;this.solid=new XFAObjectArray;this.speak=new XFAObjectArray;this.stipple=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray;this.subjectDN=new XFAObjectArray;this.subjectDNs=new XFAObjectArray;this.submit=new XFAObjectArray;this.text=new XFAObjectArray;this.textEdit=new XFAObjectArray;this.time=new XFAObjectArray;this.timeStamp=new XFAObjectArray;this.toolTip=new XFAObjectArray;this.traversal=new XFAObjectArray;this.traverse=new XFAObjectArray;this.ui=new XFAObjectArray;this.validate=new XFAObjectArray;this.value=new XFAObjectArray;this.variables=new XFAObjectArray}}class Radial extends XFAObject{constructor(e){super(Kl,"radial",!0);this.id=e.id||"";this.type=getStringOption(e.type,["toEdge","toCenter"]);this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](e){e=e?e[fl]():"#FFFFFF";const t=this.color?this.color[fl]():"#000000";return`radial-gradient(circle at center, ${"toEdge"===this.type?`${e},${t}`:`${t},${e}`})`}}class Reason extends StringObject{constructor(e){super(Kl,"reason");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Reasons extends XFAObject{constructor(e){super(Kl,"reasons",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.reason=new XFAObjectArray}}class Rectangle extends XFAObject{constructor(e){super(Kl,"rectangle",!0);this.hand=getStringOption(e.hand,["even","left","right"]);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.corner=new XFAObjectArray(4);this.edge=new XFAObjectArray(4);this.fill=null}[ol](){const e=this.edge.children.length?this.edge.children[0]:new Edge({}),t=e[fl](),a=Object.create(null);"visible"===this.fill?.presence?Object.assign(a,this.fill[fl]()):a.fill="transparent";a.strokeWidth=measureToString("visible"===e.presence?e.thickness:0);a.stroke=t.color;const n=(this.corner.children.length?this.corner.children[0]:new Corner({}))[fl](),s={name:"svg",children:[{name:"rect",attributes:{xmlns:Gl,width:"100%",height:"100%",x:0,y:0,rx:n.radius,ry:n.radius,style:a}}],attributes:{xmlns:Gl,style:{overflow:"visible"},width:"100%",height:"100%"}};if(hasMargin(this[So]()[So]()))return HTMLResult.success({name:"div",attributes:{style:{display:"inline",width:"100%",height:"100%"}},children:[s]});s.attributes.style.position="absolute";return HTMLResult.success(s)}}class RefElement extends StringObject{constructor(e){super(Kl,"ref");this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Script extends StringObject{constructor(e){super(Kl,"script");this.binding=e.binding||"";this.contentType=e.contentType||"";this.id=e.id||"";this.name=e.name||"";this.runAt=getStringOption(e.runAt,["client","both","server"]);this.use=e.use||"";this.usehref=e.usehref||""}}class SetProperty extends XFAObject{constructor(e){super(Kl,"setProperty");this.connection=e.connection||"";this.ref=e.ref||"";this.target=e.target||""}}class SignData extends XFAObject{constructor(e){super(Kl,"signData",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["sign","clear","verify"]);this.ref=e.ref||"";this.target=e.target||"";this.use=e.use||"";this.usehref=e.usehref||"";this.filter=null;this.manifest=null}}class Signature extends XFAObject{constructor(e){super(Kl,"signature",!0);this.id=e.id||"";this.type=getStringOption(e.type,["PDF1.3","PDF1.6"]);this.use=e.use||"";this.usehref=e.usehref||"";this.border=null;this.extras=null;this.filter=null;this.manifest=null;this.margin=null}}class Signing extends XFAObject{constructor(e){super(Kl,"signing",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.certificate=new XFAObjectArray}}class Solid extends XFAObject{constructor(e){super(Kl,"solid",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null}[fl](e){return e?e[fl]():"#FFFFFF"}}class Speak extends StringObject{constructor(e){super(Kl,"speak");this.disable=getInteger({data:e.disable,defaultValue:0,validate:e=>1===e});this.id=e.id||"";this.priority=getStringOption(e.priority,["custom","caption","name","toolTip"]);this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Stipple extends XFAObject{constructor(e){super(Kl,"stipple",!0);this.id=e.id||"";this.rate=getInteger({data:e.rate,defaultValue:50,validate:e=>e>=0&&e<=100});this.use=e.use||"";this.usehref=e.usehref||"";this.color=null;this.extras=null}[fl](e){const t=this.rate/100;return Util.makeHexColor(Math.round(e.value.r*(1-t)+this.value.r*t),Math.round(e.value.g*(1-t)+this.value.g*t),Math.round(e.value.b*(1-t)+this.value.b*t))}}class Subform extends XFAObject{constructor(e){super(Kl,"subform",!0);this.access=getStringOption(e.access,["open","nonInteractive","protected","readOnly"]);this.allowMacro=getInteger({data:e.allowMacro,defaultValue:0,validate:e=>1===e});this.anchorType=getStringOption(e.anchorType,["topLeft","bottomCenter","bottomLeft","bottomRight","middleCenter","middleLeft","middleRight","topCenter","topRight"]);this.colSpan=getInteger({data:e.colSpan,defaultValue:1,validate:e=>e>=1||-1===e});this.columnWidths=(e.columnWidths||"").trim().split(/\s+/).map(e=>"-1"===e?-1:getMeasurement(e));this.h=e.h?getMeasurement(e.h):"";this.hAlign=getStringOption(e.hAlign,["left","center","justify","justifyAll","radix","right"]);this.id=e.id||"";this.layout=getStringOption(e.layout,["position","lr-tb","rl-row","rl-tb","row","table","tb"]);this.locale=e.locale||"";this.maxH=getMeasurement(e.maxH,"0pt");this.maxW=getMeasurement(e.maxW,"0pt");this.mergeMode=getStringOption(e.mergeMode,["consumeData","matchTemplate"]);this.minH=getMeasurement(e.minH,"0pt");this.minW=getMeasurement(e.minW,"0pt");this.name=e.name||"";this.presence=getStringOption(e.presence,["visible","hidden","inactive","invisible"]);this.relevant=getRelevant(e.relevant);this.restoreState=getStringOption(e.restoreState,["manual","auto"]);this.scope=getStringOption(e.scope,["name","none"]);this.use=e.use||"";this.usehref=e.usehref||"";this.w=e.w?getMeasurement(e.w):"";this.x=getMeasurement(e.x,"0pt");this.y=getMeasurement(e.y,"0pt");this.assist=null;this.bind=null;this.bookend=null;this.border=null;this.break=null;this.calculate=null;this.desc=null;this.extras=null;this.keep=null;this.margin=null;this.occur=null;this.overflow=null;this.pageSet=null;this.para=null;this.traversal=null;this.validate=null;this.variables=null;this.area=new XFAObjectArray;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.connect=new XFAObjectArray;this.draw=new XFAObjectArray;this.event=new XFAObjectArray;this.exObject=new XFAObjectArray;this.exclGroup=new XFAObjectArray;this.field=new XFAObjectArray;this.proto=new XFAObjectArray;this.setProperty=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}[vo](){const e=this[So]();return e instanceof SubformSet?e[vo]():e}[Ho](){return!0}[Po](){return this.layout.endsWith("-tb")&&0===this[oo].attempt&&this[oo].numberInLine>0||this[So]()[Po]()}*[yo](){yield*getContainedChildren(this)}[fo](){return flushHTML(this)}[Yi](e,t){addHTML(this,e,t)}[uo](){return getAvailableSpace(this)}[No](){const e=this[vo]();if(!e[No]())return!1;if(void 0!==this[oo]._isSplittable)return this[oo]._isSplittable;if("position"===this.layout||this.layout.includes("row")){this[oo]._isSplittable=!1;return!1}if(this.keep&&"none"!==this.keep.intact){this[oo]._isSplittable=!1;return!1}if(e.layout?.endsWith("-tb")&&0!==e[oo].numberInLine)return!1;this[oo]._isSplittable=!0;return!0}[ol](e){setTabIndex(this);if(this.break){if("auto"!==this.break.after||""!==this.break.afterTarget){const e=new BreakAfter({targetType:this.break.after,target:this.break.afterTarget,startNew:this.break.startNew.toString()});e[xo]=this[xo];this[Ji](e);this.breakAfter.push(e)}if("auto"!==this.break.before||""!==this.break.beforeTarget){const e=new BreakBefore({targetType:this.break.before,target:this.break.beforeTarget,startNew:this.break.startNew.toString()});e[xo]=this[xo];this[Ji](e);this.breakBefore.push(e)}if(""!==this.break.overflowTarget){const e=new Overflow({target:this.break.overflowTarget,leader:this.break.overflowLeader,trailer:this.break.overflowTrailer});e[xo]=this[xo];this[Ji](e);this.overflow.push(e)}this[Jo](this.break);this.break=null}if("hidden"===this.presence||"inactive"===this.presence)return HTMLResult.EMPTY;(this.breakBefore.children.length>1||this.breakAfter.children.length>1)&&warn("XFA - Several breakBefore or breakAfter in subforms: please file a bug.");if(this.breakBefore.children.length>=1){const e=this.breakBefore.children[0];if(handleBreak(e))return HTMLResult.breakNode(e)}if(this[oo]?.afterBreakAfter)return HTMLResult.EMPTY;fixDimensions(this);const t=[],a={id:this[cl],class:[]};setAccess(this,a.class);this[oo]||=Object.create(null);Object.assign(this[oo],{children:t,line:null,attributes:a,attempt:0,numberInLine:0,availableSpace:{width:Math.min(this.w||1/0,e.width),height:Math.min(this.h||1/0,e.height)},width:0,height:0,prevHeight:0,currentWidth:0});const n=this[Ao](),s=n[oo].noLayoutFailure,r=this[No]();r||setFirstUnsplittable(this);if(!checkDimensions(this,e))return HTMLResult.FAILURE;const i=new Set(["area","draw","exclGroup","field","subform","subformSet"]);if(this.layout.includes("row")){const e=this[vo]().columnWidths;if(Array.isArray(e)&&e.length>0){this[oo].columnWidths=e;this[oo].currentColumn=0}}const o=toStyle(this,"anchorType","dimensions","position","presence","border","margin","hAlign"),l=["xfaSubform"],f=layoutClass(this);f&&l.push(f);a.style=o;a.class=l;this.name&&(a.xfaName=this.name);if(this.overflow){const t=this.overflow[wo]();if(t.addLeader){t.addLeader=!1;handleOverflow(this,t.leader,e)}}this[Yo]();const c="lr-tb"===this.layout||"rl-tb"===this.layout,h=c?2:1;for(;this[oo].attempt=1){const e=this.breakAfter.children[0];if(handleBreak(e)){this[oo].afterBreakAfter=w;return HTMLResult.breakNode(e)}}delete this[oo];return w}}class SubformSet extends XFAObject{constructor(e){super(Kl,"subformSet",!0);this.id=e.id||"";this.name=e.name||"";this.relation=getStringOption(e.relation,["ordered","choice","unordered"]);this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.bookend=null;this.break=null;this.desc=null;this.extras=null;this.occur=null;this.overflow=null;this.breakAfter=new XFAObjectArray;this.breakBefore=new XFAObjectArray;this.subform=new XFAObjectArray;this.subformSet=new XFAObjectArray}*[yo](){yield*getContainedChildren(this)}[vo](){let e=this[So]();for(;!(e instanceof Subform);)e=e[So]();return e}[Ho](){return!0}}class SubjectDN extends ContentObject{constructor(e){super(Kl,"subjectDN");this.delimiter=e.delimiter||",";this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){this[so]=new Map(this[so].split(this.delimiter).map(e=>{(e=e.split("=",2))[0]=e[0].trim();return e}))}}class SubjectDNs extends XFAObject{constructor(e){super(Kl,"subjectDNs",!0);this.id=e.id||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||"";this.subjectDN=new XFAObjectArray}}class Submit extends XFAObject{constructor(e){super(Kl,"submit",!0);this.embedPDF=getInteger({data:e.embedPDF,defaultValue:0,validate:e=>1===e});this.format=getStringOption(e.format,["xdp","formdata","pdf","urlencoded","xfd","xml"]);this.id=e.id||"";this.target=e.target||"";this.textEncoding=getKeyword({data:e.textEncoding?e.textEncoding.toLowerCase():"",defaultValue:"",validate:e=>["utf-8","big-five","fontspecific","gbk","gb-18030","gb-2312","ksc-5601","none","shift-jis","ucs-2","utf-16"].includes(e)||e.match(/iso-8859-\d{2}/)});this.use=e.use||"";this.usehref=e.usehref||"";this.xdpContent=e.xdpContent||"";this.encrypt=null;this.encryptData=new XFAObjectArray;this.signData=new XFAObjectArray}}class Template extends XFAObject{constructor(e){super(Kl,"template",!0);this.baseProfile=getStringOption(e.baseProfile,["full","interactiveForms"]);this.extras=null;this.subform=new XFAObjectArray}[lo](){0===this.subform.children.length&&warn("XFA - No subforms in template node.");this.subform.children.length>=2&&warn("XFA - Several subforms in template node: please file a bug.");this[sl]=5e3}[No](){return!0}[el](e,t){return e.startsWith("#")?[this[Io].get(e.slice(1))]:searchNode(this,t,e,!0,!0)}*[il](){if(!this.subform.children.length)return HTMLResult.success({name:"div",children:[]});this[oo]={overflowNode:null,firstUnsplittable:null,currentContentArea:null,currentPageArea:null,noLayoutFailure:!1,pageNumber:1,pagePosition:"first",oddOrEven:"odd",blankOrNotBlank:"nonBlank",paraStack:[]};const e=this.subform.children[0];e.pageSet[eo]();const t=e.pageSet.pageArea.children,a={name:"div",children:[]};let n=null,s=null,r=null;if(e.breakBefore.children.length>=1){s=e.breakBefore.children[0];r=s.target}else if(e.subform.children.length>=1&&e.subform.children[0].breakBefore.children.length>=1){s=e.subform.children[0].breakBefore.children[0];r=s.target}else if(e.break?.beforeTarget){s=e.break;r=s.beforeTarget}else if(e.subform.children.length>=1&&e.subform.children[0].break?.beforeTarget){s=e.subform.children[0].break;r=s.beforeTarget}if(s){const e=this[el](r,s[So]());if(e instanceof PageArea){n=e;s[oo]={}}}n||=t[0];n[oo]={numberOfUse:1};const i=n[So]();i[oo]={numberOfUse:1,pageIndex:i.pageArea.children.indexOf(n),pageSetIndex:0};let o,l=null,f=null,c=!0,h=0,u=0;for(;;){if(c)h=0;else{a.children.pop();if(3===++h){warn("XFA - Something goes wrong: please file a bug.");return a}}o=null;this[oo].currentPageArea=n;const t=n[ol]().html;a.children.push(t);if(l){this[oo].noLayoutFailure=!0;t.children.push(l[ol](n[oo].space).html);l=null}if(f){this[oo].noLayoutFailure=!0;t.children.push(f[ol](n[oo].space).html);f=null}const s=n.contentArea.children,r=t.children.filter(e=>e.attributes.class.includes("xfaContentarea"));c=!1;this[oo].firstUnsplittable=null;this[oo].noLayoutFailure=!1;const flush=t=>{const a=e[fo]();if(a){c||=a.children?.length>0;r[t].children.push(a)}};for(let t=u,n=s.length;t0;r[t].children.push(h.html)}else!c&&a.children.length>1&&a.children.pop();return a}if(h.isBreak()){const e=h.breakNode;flush(t);if("auto"===e.targetType)continue;if(e.leader){l=this[el](e.leader,e[So]());l=l?l[0]:null}if(e.trailer){f=this[el](e.trailer,e[So]());f=f?f[0]:null}if("pageArea"===e.targetType){o=e[oo].target;t=1/0}else if(e[oo].target){o=e[oo].target;u=e[oo].index+1;t=1/0}else t=e[oo].index;continue}if(this[oo].overflowNode){const e=this[oo].overflowNode;this[oo].overflowNode=null;const a=e[wo](),n=a.target;a.addLeader=null!==a.leader;a.addTrailer=null!==a.trailer;flush(t);const r=t;t=1/0;if(n instanceof PageArea)o=n;else if(n instanceof ContentArea){const e=s.indexOf(n);if(-1!==e)e>r?t=e-1:u=e;else{o=n[So]();u=o.contentArea.children.indexOf(n)}}continue}flush(t)}this[oo].pageNumber+=1;o&&(o[_o]()?o[oo].numberOfUse+=1:o=null);n=o||n[qo]();yield null}}}class Text extends ContentObject{constructor(e){super(Kl,"text");this.id=e.id||"";this.maxChars=getInteger({data:e.maxChars,defaultValue:0,validate:e=>e>=0});this.name=e.name||"";this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}[$i](){return!0}[Wo](e){if(e[Lo]===ul.xhtml.id){this[so]=e;return!0}warn(`XFA - Invalid content in Text: ${e[Uo]}.`);return!1}[Go](e){this[so]instanceof XFAObject||super[Go](e)}[lo](){"string"==typeof this[so]&&(this[so]=this[so].replaceAll("\r\n","\n"))}[wo](){return"string"==typeof this[so]?this[so].split(/[\u2029\u2028\n]/).filter(e=>!!e).join("\n"):this[so][rl]()}[ol](e){if("string"==typeof this[so]){const e=valueToHtml(this[so]).html;if(this[so].includes("\u2029")){e.name="div";e.children=[];this[so].split("\u2029").map(e=>e.split(/[\u2028\n]/).flatMap(e=>[{name:"span",value:e},{name:"br"}])).forEach(t=>{e.children.push({name:"p",children:t})})}else if(/[\u2028\n]/.test(this[so])){e.name="div";e.children=[];this[so].split(/[\u2028\n]/).forEach(t=>{e.children.push({name:"span",value:t},{name:"br"})})}return HTMLResult.success(e)}return this[so][ol](e)}}class TextEdit extends XFAObject{constructor(e){super(Kl,"textEdit",!0);this.allowRichText=getInteger({data:e.allowRichText,defaultValue:0,validate:e=>1===e});this.hScrollPolicy=getStringOption(e.hScrollPolicy,["auto","off","on"]);this.id=e.id||"";this.multiLine=getInteger({data:e.multiLine,defaultValue:"",validate:e=>0===e||1===e});this.use=e.use||"";this.usehref=e.usehref||"";this.vScrollPolicy=getStringOption(e.vScrollPolicy,["auto","off","on"]);this.border=null;this.comb=null;this.extras=null;this.margin=null}[ol](e){const t=toStyle(this,"border","font","margin");let a;const n=this[So]()[So]();""===this.multiLine&&(this.multiLine=n instanceof Draw?1:0);a=1===this.multiLine?{name:"textarea",attributes:{dataId:n[ro]?.[cl]||n[cl],fieldId:n[cl],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(n),"aria-required":!1}}:{name:"input",attributes:{type:"text",dataId:n[ro]?.[cl]||n[cl],fieldId:n[cl],class:["xfaTextfield"],style:t,"aria-label":ariaLabel(n),"aria-required":!1}};if(isRequired(n)){a.attributes["aria-required"]=!0;a.attributes.required=!0}return HTMLResult.success({name:"label",attributes:{class:["xfaLabel"]},children:[a]})}}class Time extends StringObject{constructor(e){super(Kl,"time");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}[lo](){const e=this[so].trim();this[so]=e?new Date(e):null}[ol](e){return valueToHtml(this[so]?this[so].toString():"")}}class TimeStamp extends XFAObject{constructor(e){super(Kl,"timeStamp");this.id=e.id||"";this.server=e.server||"";this.type=getStringOption(e.type,["optional","required"]);this.use=e.use||"";this.usehref=e.usehref||""}}class ToolTip extends StringObject{constructor(e){super(Kl,"toolTip");this.id=e.id||"";this.rid=e.rid||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Traversal extends XFAObject{constructor(e){super(Kl,"traversal",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.traverse=new XFAObjectArray}}class Traverse extends XFAObject{constructor(e){super(Kl,"traverse",!0);this.id=e.id||"";this.operation=getStringOption(e.operation,["next","back","down","first","left","right","up"]);this.ref=e.ref||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.script=null}get name(){return this.operation}[Eo](){return!1}}class Ui extends XFAObject{constructor(e){super(Kl,"ui",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.picture=null;this.barcode=null;this.button=null;this.checkButton=null;this.choiceList=null;this.dateTimeEdit=null;this.defaultUi=null;this.imageEdit=null;this.numericEdit=null;this.passwordEdit=null;this.signature=null;this.textEdit=null}[wo](){if(void 0===this[oo]){for(const e of Object.getOwnPropertyNames(this)){if("extras"===e||"picture"===e)continue;const t=this[e];if(t instanceof XFAObject){this[oo]=t;return t}}this[oo]=null}return this[oo]}[ol](e){const t=this[wo]();return t?t[ol](e):HTMLResult.EMPTY}}class Validate extends XFAObject{constructor(e){super(Kl,"validate",!0);this.formatTest=getStringOption(e.formatTest,["warning","disabled","error"]);this.id=e.id||"";this.nullTest=getStringOption(e.nullTest,["disabled","error","warning"]);this.scriptTest=getStringOption(e.scriptTest,["error","disabled","warning"]);this.use=e.use||"";this.usehref=e.usehref||"";this.extras=null;this.message=null;this.picture=null;this.script=null}}class Value extends XFAObject{constructor(e){super(Kl,"value",!0);this.id=e.id||"";this.override=getInteger({data:e.override,defaultValue:0,validate:e=>1===e});this.relevant=getRelevant(e.relevant);this.use=e.use||"";this.usehref=e.usehref||"";this.arc=null;this.boolean=null;this.date=null;this.dateTime=null;this.decimal=null;this.exData=null;this.float=null;this.image=null;this.integer=null;this.line=null;this.rectangle=null;this.text=null;this.time=null}[nl](e){const t=this[So]();if(t instanceof Field&&t.ui?.imageEdit){if(!this.image){this.image=new Image({});this[Ji](this.image)}this.image[so]=e[so];return}const a=e[Uo];if(null===this[a]){for(const e of Object.getOwnPropertyNames(this)){const t=this[e];if(t instanceof XFAObject){this[e]=null;this[Jo](t)}}this[e[Uo]]=e;this[Ji](e)}else this[a][so]=e[so]}[rl](){if(this.exData)return"string"==typeof this.exData[so]?this.exData[so].trim():this.exData[so][rl]().trim();for(const e of Object.getOwnPropertyNames(this)){if("image"===e)continue;const t=this[e];if(t instanceof XFAObject)return(t[so]||"").toString().trim()}return null}[ol](e){for(const t of Object.getOwnPropertyNames(this)){const a=this[t];if(a instanceof XFAObject)return a[ol](e)}return HTMLResult.EMPTY}}class Variables extends XFAObject{constructor(e){super(Kl,"variables",!0);this.id=e.id||"";this.use=e.use||"";this.usehref=e.usehref||"";this.boolean=new XFAObjectArray;this.date=new XFAObjectArray;this.dateTime=new XFAObjectArray;this.decimal=new XFAObjectArray;this.exData=new XFAObjectArray;this.float=new XFAObjectArray;this.image=new XFAObjectArray;this.integer=new XFAObjectArray;this.manifest=new XFAObjectArray;this.script=new XFAObjectArray;this.text=new XFAObjectArray;this.time=new XFAObjectArray}[Eo](){return!0}}class TemplateNamespace{static[hl](e,t){if(Object.hasOwn(TemplateNamespace,e)){const a=TemplateNamespace[e](t);a[al](t);return a}}static appearanceFilter(e){return new AppearanceFilter(e)}static arc(e){return new Arc(e)}static area(e){return new Area(e)}static assist(e){return new Assist(e)}static barcode(e){return new Barcode(e)}static bind(e){return new Bind(e)}static bindItems(e){return new BindItems(e)}static bookend(e){return new Bookend(e)}static boolean(e){return new BooleanElement(e)}static border(e){return new Border(e)}static break(e){return new Break(e)}static breakAfter(e){return new BreakAfter(e)}static breakBefore(e){return new BreakBefore(e)}static button(e){return new Button(e)}static calculate(e){return new Calculate(e)}static caption(e){return new Caption(e)}static certificate(e){return new Certificate(e)}static certificates(e){return new Certificates(e)}static checkButton(e){return new CheckButton(e)}static choiceList(e){return new ChoiceList(e)}static color(e){return new Color(e)}static comb(e){return new Comb(e)}static connect(e){return new Connect(e)}static contentArea(e){return new ContentArea(e)}static corner(e){return new Corner(e)}static date(e){return new DateElement(e)}static dateTime(e){return new DateTime(e)}static dateTimeEdit(e){return new DateTimeEdit(e)}static decimal(e){return new Decimal(e)}static defaultUi(e){return new DefaultUi(e)}static desc(e){return new Desc(e)}static digestMethod(e){return new DigestMethod(e)}static digestMethods(e){return new DigestMethods(e)}static draw(e){return new Draw(e)}static edge(e){return new Edge(e)}static encoding(e){return new Encoding(e)}static encodings(e){return new Encodings(e)}static encrypt(e){return new Encrypt(e)}static encryptData(e){return new EncryptData(e)}static encryption(e){return new Encryption(e)}static encryptionMethod(e){return new EncryptionMethod(e)}static encryptionMethods(e){return new EncryptionMethods(e)}static event(e){return new Event(e)}static exData(e){return new ExData(e)}static exObject(e){return new ExObject(e)}static exclGroup(e){return new ExclGroup(e)}static execute(e){return new Execute(e)}static extras(e){return new Extras(e)}static field(e){return new Field(e)}static fill(e){return new Fill(e)}static filter(e){return new Filter(e)}static float(e){return new Float(e)}static font(e){return new template_Font(e)}static format(e){return new Format(e)}static handler(e){return new Handler(e)}static hyphenation(e){return new Hyphenation(e)}static image(e){return new Image(e)}static imageEdit(e){return new ImageEdit(e)}static integer(e){return new Integer(e)}static issuers(e){return new Issuers(e)}static items(e){return new Items(e)}static keep(e){return new Keep(e)}static keyUsage(e){return new KeyUsage(e)}static line(e){return new Line(e)}static linear(e){return new Linear(e)}static lockDocument(e){return new LockDocument(e)}static manifest(e){return new Manifest(e)}static margin(e){return new Margin(e)}static mdp(e){return new Mdp(e)}static medium(e){return new Medium(e)}static message(e){return new Message(e)}static numericEdit(e){return new NumericEdit(e)}static occur(e){return new Occur(e)}static oid(e){return new Oid(e)}static oids(e){return new Oids(e)}static overflow(e){return new Overflow(e)}static pageArea(e){return new PageArea(e)}static pageSet(e){return new PageSet(e)}static para(e){return new Para(e)}static passwordEdit(e){return new PasswordEdit(e)}static pattern(e){return new template_Pattern(e)}static picture(e){return new Picture(e)}static proto(e){return new Proto(e)}static radial(e){return new Radial(e)}static reason(e){return new Reason(e)}static reasons(e){return new Reasons(e)}static rectangle(e){return new Rectangle(e)}static ref(e){return new RefElement(e)}static script(e){return new Script(e)}static setProperty(e){return new SetProperty(e)}static signData(e){return new SignData(e)}static signature(e){return new Signature(e)}static signing(e){return new Signing(e)}static solid(e){return new Solid(e)}static speak(e){return new Speak(e)}static stipple(e){return new Stipple(e)}static subform(e){return new Subform(e)}static subformSet(e){return new SubformSet(e)}static subjectDN(e){return new SubjectDN(e)}static subjectDNs(e){return new SubjectDNs(e)}static submit(e){return new Submit(e)}static template(e){return new Template(e)}static text(e){return new Text(e)}static textEdit(e){return new TextEdit(e)}static time(e){return new Time(e)}static timeStamp(e){return new TimeStamp(e)}static toolTip(e){return new ToolTip(e)}static traversal(e){return new Traversal(e)}static traverse(e){return new Traverse(e)}static ui(e){return new Ui(e)}static validate(e){return new Validate(e)}static value(e){return new Value(e)}static variables(e){return new Variables(e)}}const Jl=ul.datasets.id;function createText(e){const t=new Text({});t[so]=e;return t}class Binder{constructor(e){this.root=e;this.datasets=e.datasets;this.data=e.datasets?.data||new XmlObject(ul.datasets.id,"data");this.emptyMerge=0===this.data[ko]().length;this.root.form=this.form=e.template[ao]()}_isConsumeData(){return!this.emptyMerge&&this._mergeMode}_isMatchTemplate(){return!this._isConsumeData()}bind(){this._bindElement(this.form,this.data);return this.form}getData(){return this.data}_bindValue(e,t,a){e[ro]=t;if(e[Co]())if(t[Bo]()){const a=t[bo]();e[nl](createText(a))}else if(e instanceof Field&&"multiSelect"===e.ui?.choiceList?.open){const a=t[ko]().map(e=>e[so].trim()).join("\n");e[nl](createText(a))}else this._isConsumeData()&&warn("XFA - Nodes haven't the same type.");else!t[Bo]()||this._isMatchTemplate()?this._bindElement(e,t):warn("XFA - Nodes haven't the same type.")}_findDataByNameToConsume(e,t,a,n){if(!e)return null;let s,r;for(let n=0;n<3;n++){s=a[jo](e,!1,!0);for(;;){r=s.next().value;if(!r)break;if(t===r[Bo]())return r}if(a[Lo]===ul.datasets.id&&"data"===a[Uo])break;a=a[So]()}if(!n)return null;s=this.data[jo](e,!0,!1);r=s.next().value;if(r)return r;s=this.data[co](e,!0);r=s.next().value;return r?.[Bo]()?r:null}_setProperties(e,t){if(Object.hasOwn(e,"setProperty"))for(const{ref:a,target:n,connection:s}of e.setProperty.children){if(s)continue;if(!a)continue;const r=searchNode(this.root,t,a,!1,!1);if(!r){warn(`XFA - Invalid reference: ${a}.`);continue}const[i]=r;if(!i[Do](this.data)){warn("XFA - Invalid node: must be a data node.");continue}const o=searchNode(this.root,e,n,!1,!1);if(!o){warn(`XFA - Invalid target: ${n}.`);continue}const[l]=o;if(!l[Do](e)){warn("XFA - Invalid target: must be a property or subproperty.");continue}const f=l[So]();if(l instanceof SetProperty||f instanceof SetProperty){warn("XFA - Invalid target: cannot be a setProperty or one of its properties.");continue}if(l instanceof BindItems||f instanceof BindItems){warn("XFA - Invalid target: cannot be a bindItems or one of its properties.");continue}const c=i[rl](),h=l[Uo];if(l instanceof XFAAttribute){const e=Object.create(null);e[h]=c;const t=Reflect.construct(Object.getPrototypeOf(f).constructor,[e]);f[h]=t[h];continue}if(Object.hasOwn(l,so)){l[ro]=i;l[so]=c;l[lo]()}else warn("XFA - Invalid node to use in setProperty")}}_bindItems(e,t){if(!Object.hasOwn(e,"items")||!Object.hasOwn(e,"bindItems")||e.bindItems.isEmpty())return;for(const t of e.items.children)e[Jo](t);e.items.clear();const a=new Items({}),n=new Items({});e[Ji](a);e.items.push(a);e[Ji](n);e.items.push(n);for(const{ref:s,labelRef:r,valueRef:i,connection:o}of e.bindItems.children){if(o)continue;if(!s)continue;const e=searchNode(this.root,t,s,!1,!1);if(e)for(const t of e){if(!t[Do](this.datasets)){warn(`XFA - Invalid ref (${s}): must be a datasets child.`);continue}const e=searchNode(this.root,t,r,!0,!1);if(!e){warn(`XFA - Invalid label: ${r}.`);continue}const[o]=e;if(!o[Do](this.datasets)){warn("XFA - Invalid label: must be a datasets child.");continue}const l=searchNode(this.root,t,i,!0,!1);if(!l){warn(`XFA - Invalid value: ${i}.`);continue}const[f]=l;if(!f[Do](this.datasets)){warn("XFA - Invalid value: must be a datasets child.");continue}const c=createText(o[rl]()),h=createText(f[rl]());a[Ji](c);a.text.push(c);n[Ji](h);n.text.push(h)}else warn(`XFA - Invalid reference: ${s}.`)}}_bindOccurrences(e,t,a){let n;if(t.length>1){n=e[ao]();n[Jo](n.occur);n.occur=null}this._bindValue(e,t[0],a);this._setProperties(e,t[0]);this._bindItems(e,t[0]);if(1===t.length)return;const s=e[So](),r=e[Uo],i=s[Fo](e);for(let e=1,o=t.length;et.name===e.name).length:a[n].children.length;const r=a[Fo](e)+1,i=t.initial-s;if(i){const t=e[ao]();t[Jo](t.occur);t.occur=null;a[n].push(t);a[Oo](r,t);for(let e=1;e0)this._bindOccurrences(n,[e[0]],null);else if(this.emptyMerge){const e=t[Lo]===Jl?-1:t[Lo],a=n[ro]=new XmlObject(e,n.name||"root");t[Ji](a);this._bindElement(n,a)}continue}if(!n[Ho]())continue;let e=!1,s=null,r=null,i=null;if(n.bind){switch(n.bind.match){case"none":this._setAndBind(n,t);continue;case"global":e=!0;break;case"dataRef":if(!n.bind.ref){warn(`XFA - ref is empty in node ${n[Uo]}.`);this._setAndBind(n,t);continue}r=n.bind.ref}n.bind.picture&&(s=n.bind.picture[so])}const[o,l]=this._getOccurInfo(n);if(r){i=searchNode(this.root,t,r,!0,!1);if(null===i){i=createDataNode(this.data,t,r);if(!i)continue;this._isConsumeData()&&(i[no]=!0);this._setAndBind(n,i);continue}this._isConsumeData()&&(i=i.filter(e=>!e[no]));i.length>l?i=i.slice(0,l):0===i.length&&(i=null);i&&this._isConsumeData()&&i.forEach(e=>{e[no]=!0})}else{if(!n.name){this._setAndBind(n,t);continue}if(this._isConsumeData()){const a=[];for(;a.length0?a:null}else{i=t[jo](n.name,!1,this.emptyMerge).next().value;if(!i){if(0===o){a.push(n);continue}const e=t[Lo]===Jl?-1:t[Lo];i=n[ro]=new XmlObject(e,n.name);this.emptyMerge&&(i[no]=!0);t[Ji](i);this._setAndBind(n,i);continue}this.emptyMerge&&(i[no]=!0);i=[i]}}i?this._bindOccurrences(n,i,s):o>0?this._setAndBind(n,t):a.push(n)}a.forEach(e=>e[So]()[Jo](e))}}class DataHandler{constructor(e,t){this.data=t;this.dataset=e.datasets||null}serialize(e){const t=[[-1,this.data[ko]()]];for(;t.length>0;){const a=t.at(-1),[n,s]=a;if(n+1===s.length){t.pop();continue}const r=s[++a[0]],i=e.get(r[cl]);if(i)r[nl](i);else{const t=r[ho]();for(const a of t.values()){const t=e.get(a[cl]);if(t){a[nl](t);break}}}const o=r[ko]();o.length>0&&t.push([-1,o])}const a=[''];if(this.dataset)for(const e of this.dataset[ko]())"data"!==e[Uo]&&e[ll](a);this.data[ll](a);a.push("");return a.join("")}}const Ql=ul.config.id;class Acrobat extends XFAObject{constructor(e){super(Ql,"acrobat",!0);this.acrobat7=null;this.autoSave=null;this.common=null;this.validate=null;this.validateApprovalSignatures=null;this.submitUrl=new XFAObjectArray}}class Acrobat7 extends XFAObject{constructor(e){super(Ql,"acrobat7",!0);this.dynamicRender=null}}class ADBE_JSConsole extends OptionObject{constructor(e){super(Ql,"ADBE_JSConsole",["delegate","Enable","Disable"])}}class ADBE_JSDebugger extends OptionObject{constructor(e){super(Ql,"ADBE_JSDebugger",["delegate","Enable","Disable"])}}class AddSilentPrint extends Option01{constructor(e){super(Ql,"addSilentPrint")}}class AddViewerPreferences extends Option01{constructor(e){super(Ql,"addViewerPreferences")}}class AdjustData extends Option10{constructor(e){super(Ql,"adjustData")}}class AdobeExtensionLevel extends IntegerObject{constructor(e){super(Ql,"adobeExtensionLevel",0,e=>e>=1&&e<=8)}}class Agent extends XFAObject{constructor(e){super(Ql,"agent",!0);this.name=e.name?e.name.trim():"";this.common=new XFAObjectArray}}class AlwaysEmbed extends ContentObject{constructor(e){super(Ql,"alwaysEmbed")}}class Amd extends StringObject{constructor(e){super(Ql,"amd")}}class config_Area extends XFAObject{constructor(e){super(Ql,"area");this.level=getInteger({data:e.level,defaultValue:0,validate:e=>e>=1&&e<=3});this.name=getStringOption(e.name,["","barcode","coreinit","deviceDriver","font","general","layout","merge","script","signature","sourceSet","templateCache"])}}class Attributes extends OptionObject{constructor(e){super(Ql,"attributes",["preserve","delegate","ignore"])}}class AutoSave extends OptionObject{constructor(e){super(Ql,"autoSave",["disabled","enabled"])}}class Base extends StringObject{constructor(e){super(Ql,"base")}}class BatchOutput extends XFAObject{constructor(e){super(Ql,"batchOutput");this.format=getStringOption(e.format,["none","concat","zip","zipCompress"])}}class BehaviorOverride extends ContentObject{constructor(e){super(Ql,"behaviorOverride")}[lo](){this[so]=new Map(this[so].trim().split(/\s+/).filter(e=>e.includes(":")).map(e=>e.split(":",2)))}}class Cache extends XFAObject{constructor(e){super(Ql,"cache",!0);this.templateCache=null}}class Change extends Option01{constructor(e){super(Ql,"change")}}class Common extends XFAObject{constructor(e){super(Ql,"common",!0);this.data=null;this.locale=null;this.localeSet=null;this.messaging=null;this.suppressBanner=null;this.template=null;this.validationMessaging=null;this.versionControl=null;this.log=new XFAObjectArray}}class Compress extends XFAObject{constructor(e){super(Ql,"compress");this.scope=getStringOption(e.scope,["imageOnly","document"])}}class CompressLogicalStructure extends Option01{constructor(e){super(Ql,"compressLogicalStructure")}}class CompressObjectStream extends Option10{constructor(e){super(Ql,"compressObjectStream")}}class Compression extends XFAObject{constructor(e){super(Ql,"compression",!0);this.compressLogicalStructure=null;this.compressObjectStream=null;this.level=null;this.type=null}}class Config extends XFAObject{constructor(e){super(Ql,"config",!0);this.acrobat=null;this.present=null;this.trace=null;this.agent=new XFAObjectArray}}class Conformance extends OptionObject{constructor(e){super(Ql,"conformance",["A","B"])}}class ContentCopy extends Option01{constructor(e){super(Ql,"contentCopy")}}class Copies extends IntegerObject{constructor(e){super(Ql,"copies",1,e=>e>=1)}}class Creator extends StringObject{constructor(e){super(Ql,"creator")}}class CurrentPage extends IntegerObject{constructor(e){super(Ql,"currentPage",0,e=>e>=0)}}class Data extends XFAObject{constructor(e){super(Ql,"data",!0);this.adjustData=null;this.attributes=null;this.incrementalLoad=null;this.outputXSL=null;this.range=null;this.record=null;this.startNode=null;this.uri=null;this.window=null;this.xsl=null;this.excludeNS=new XFAObjectArray;this.transform=new XFAObjectArray}}class Debug extends XFAObject{constructor(e){super(Ql,"debug",!0);this.uri=null}}class DefaultTypeface extends ContentObject{constructor(e){super(Ql,"defaultTypeface");this.writingScript=getStringOption(e.writingScript,["*","Arabic","Cyrillic","EastEuropeanRoman","Greek","Hebrew","Japanese","Korean","Roman","SimplifiedChinese","Thai","TraditionalChinese","Vietnamese"])}}class Destination extends OptionObject{constructor(e){super(Ql,"destination",["pdf","pcl","ps","webClient","zpl"])}}class DocumentAssembly extends Option01{constructor(e){super(Ql,"documentAssembly")}}class Driver extends XFAObject{constructor(e){super(Ql,"driver",!0);this.name=e.name?e.name.trim():"";this.fontInfo=null;this.xdc=null}}class DuplexOption extends OptionObject{constructor(e){super(Ql,"duplexOption",["simplex","duplexFlipLongEdge","duplexFlipShortEdge"])}}class DynamicRender extends OptionObject{constructor(e){super(Ql,"dynamicRender",["forbidden","required"])}}class Embed extends Option01{constructor(e){super(Ql,"embed")}}class config_Encrypt extends Option01{constructor(e){super(Ql,"encrypt")}}class config_Encryption extends XFAObject{constructor(e){super(Ql,"encryption",!0);this.encrypt=null;this.encryptionLevel=null;this.permissions=null}}class EncryptionLevel extends OptionObject{constructor(e){super(Ql,"encryptionLevel",["40bit","128bit"])}}class Enforce extends StringObject{constructor(e){super(Ql,"enforce")}}class Equate extends XFAObject{constructor(e){super(Ql,"equate");this.force=getInteger({data:e.force,defaultValue:1,validate:e=>0===e});this.from=e.from||"";this.to=e.to||""}}class EquateRange extends XFAObject{constructor(e){super(Ql,"equateRange");this.from=e.from||"";this.to=e.to||"";this._unicodeRange=e.unicodeRange||""}get unicodeRange(){const e=[],t=/U\+([0-9a-fA-F]+)/,a=this._unicodeRange;for(let n of a.split(",").map(e=>e.trim()).filter(e=>!!e)){n=n.split("-",2).map(e=>{const a=e.match(t);return a?parseInt(a[1],16):0});1===n.length&&n.push(n[0]);e.push(n)}return shadow(this,"unicodeRange",e)}}class Exclude extends ContentObject{constructor(e){super(Ql,"exclude")}[lo](){this[so]=this[so].trim().split(/\s+/).filter(e=>e&&["calculate","close","enter","exit","initialize","ready","validate"].includes(e))}}class ExcludeNS extends StringObject{constructor(e){super(Ql,"excludeNS")}}class FlipLabel extends OptionObject{constructor(e){super(Ql,"flipLabel",["usePrinterSetting","on","off"])}}class config_FontInfo extends XFAObject{constructor(e){super(Ql,"fontInfo",!0);this.embed=null;this.map=null;this.subsetBelow=null;this.alwaysEmbed=new XFAObjectArray;this.defaultTypeface=new XFAObjectArray;this.neverEmbed=new XFAObjectArray}}class FormFieldFilling extends Option01{constructor(e){super(Ql,"formFieldFilling")}}class GroupParent extends StringObject{constructor(e){super(Ql,"groupParent")}}class IfEmpty extends OptionObject{constructor(e){super(Ql,"ifEmpty",["dataValue","dataGroup","ignore","remove"])}}class IncludeXDPContent extends StringObject{constructor(e){super(Ql,"includeXDPContent")}}class IncrementalLoad extends OptionObject{constructor(e){super(Ql,"incrementalLoad",["none","forwardOnly"])}}class IncrementalMerge extends Option01{constructor(e){super(Ql,"incrementalMerge")}}class Interactive extends Option01{constructor(e){super(Ql,"interactive")}}class Jog extends OptionObject{constructor(e){super(Ql,"jog",["usePrinterSetting","none","pageSet"])}}class LabelPrinter extends XFAObject{constructor(e){super(Ql,"labelPrinter",!0);this.name=getStringOption(e.name,["zpl","dpl","ipl","tcpl"]);this.batchOutput=null;this.flipLabel=null;this.fontInfo=null;this.xdc=null}}class Layout extends OptionObject{constructor(e){super(Ql,"layout",["paginate","panel"])}}class Level extends IntegerObject{constructor(e){super(Ql,"level",0,e=>e>0)}}class Linearized extends Option01{constructor(e){super(Ql,"linearized")}}class Locale extends StringObject{constructor(e){super(Ql,"locale")}}class LocaleSet extends StringObject{constructor(e){super(Ql,"localeSet")}}class Log extends XFAObject{constructor(e){super(Ql,"log",!0);this.mode=null;this.threshold=null;this.to=null;this.uri=null}}class MapElement extends XFAObject{constructor(e){super(Ql,"map",!0);this.equate=new XFAObjectArray;this.equateRange=new XFAObjectArray}}class MediumInfo extends XFAObject{constructor(e){super(Ql,"mediumInfo",!0);this.map=null}}class config_Message extends XFAObject{constructor(e){super(Ql,"message",!0);this.msgId=null;this.severity=null}}class Messaging extends XFAObject{constructor(e){super(Ql,"messaging",!0);this.message=new XFAObjectArray}}class Mode extends OptionObject{constructor(e){super(Ql,"mode",["append","overwrite"])}}class ModifyAnnots extends Option01{constructor(e){super(Ql,"modifyAnnots")}}class MsgId extends IntegerObject{constructor(e){super(Ql,"msgId",1,e=>e>=1)}}class NameAttr extends StringObject{constructor(e){super(Ql,"nameAttr")}}class NeverEmbed extends ContentObject{constructor(e){super(Ql,"neverEmbed")}}class NumberOfCopies extends IntegerObject{constructor(e){super(Ql,"numberOfCopies",null,e=>e>=2&&e<=5)}}class OpenAction extends XFAObject{constructor(e){super(Ql,"openAction",!0);this.destination=null}}class Output extends XFAObject{constructor(e){super(Ql,"output",!0);this.to=null;this.type=null;this.uri=null}}class OutputBin extends StringObject{constructor(e){super(Ql,"outputBin")}}class OutputXSL extends XFAObject{constructor(e){super(Ql,"outputXSL",!0);this.uri=null}}class Overprint extends OptionObject{constructor(e){super(Ql,"overprint",["none","both","draw","field"])}}class Packets extends StringObject{constructor(e){super(Ql,"packets")}[lo](){"*"!==this[so]&&(this[so]=this[so].trim().split(/\s+/).filter(e=>["config","datasets","template","xfdf","xslt"].includes(e)))}}class PageOffset extends XFAObject{constructor(e){super(Ql,"pageOffset");this.x=getInteger({data:e.x,defaultValue:"useXDCSetting",validate:e=>!0});this.y=getInteger({data:e.y,defaultValue:"useXDCSetting",validate:e=>!0})}}class PageRange extends StringObject{constructor(e){super(Ql,"pageRange")}[lo](){const e=this[so].trim().split(/\s+/).map(e=>parseInt(e,10)),t=[];for(let a=0,n=e.length;a!1)}}class Pcl extends XFAObject{constructor(e){super(Ql,"pcl",!0);this.name=e.name||"";this.batchOutput=null;this.fontInfo=null;this.jog=null;this.mediumInfo=null;this.outputBin=null;this.pageOffset=null;this.staple=null;this.xdc=null}}class Pdf extends XFAObject{constructor(e){super(Ql,"pdf",!0);this.name=e.name||"";this.adobeExtensionLevel=null;this.batchOutput=null;this.compression=null;this.creator=null;this.encryption=null;this.fontInfo=null;this.interactive=null;this.linearized=null;this.openAction=null;this.pdfa=null;this.producer=null;this.renderPolicy=null;this.scriptModel=null;this.silentPrint=null;this.submitFormat=null;this.tagged=null;this.version=null;this.viewerPreferences=null;this.xdc=null}}class Pdfa extends XFAObject{constructor(e){super(Ql,"pdfa",!0);this.amd=null;this.conformance=null;this.includeXDPContent=null;this.part=null}}class Permissions extends XFAObject{constructor(e){super(Ql,"permissions",!0);this.accessibleContent=null;this.change=null;this.contentCopy=null;this.documentAssembly=null;this.formFieldFilling=null;this.modifyAnnots=null;this.plaintextMetadata=null;this.print=null;this.printHighQuality=null}}class PickTrayByPDFSize extends Option01{constructor(e){super(Ql,"pickTrayByPDFSize")}}class config_Picture extends StringObject{constructor(e){super(Ql,"picture")}}class PlaintextMetadata extends Option01{constructor(e){super(Ql,"plaintextMetadata")}}class Presence extends OptionObject{constructor(e){super(Ql,"presence",["preserve","dissolve","dissolveStructure","ignore","remove"])}}class Present extends XFAObject{constructor(e){super(Ql,"present",!0);this.behaviorOverride=null;this.cache=null;this.common=null;this.copies=null;this.destination=null;this.incrementalMerge=null;this.layout=null;this.output=null;this.overprint=null;this.pagination=null;this.paginationOverride=null;this.script=null;this.validate=null;this.xdp=null;this.driver=new XFAObjectArray;this.labelPrinter=new XFAObjectArray;this.pcl=new XFAObjectArray;this.pdf=new XFAObjectArray;this.ps=new XFAObjectArray;this.submitUrl=new XFAObjectArray;this.webClient=new XFAObjectArray;this.zpl=new XFAObjectArray}}class Print extends Option01{constructor(e){super(Ql,"print")}}class PrintHighQuality extends Option01{constructor(e){super(Ql,"printHighQuality")}}class PrintScaling extends OptionObject{constructor(e){super(Ql,"printScaling",["appdefault","noScaling"])}}class PrinterName extends StringObject{constructor(e){super(Ql,"printerName")}}class Producer extends StringObject{constructor(e){super(Ql,"producer")}}class Ps extends XFAObject{constructor(e){super(Ql,"ps",!0);this.name=e.name||"";this.batchOutput=null;this.fontInfo=null;this.jog=null;this.mediumInfo=null;this.outputBin=null;this.staple=null;this.xdc=null}}class Range extends ContentObject{constructor(e){super(Ql,"range")}[lo](){this[so]=this[so].split(",",2).map(e=>e.split("-").map(e=>parseInt(e.trim(),10))).filter(e=>e.every(e=>!isNaN(e))).map(e=>{1===e.length&&e.push(e[0]);return e})}}class Record extends ContentObject{constructor(e){super(Ql,"record")}[lo](){this[so]=this[so].trim();const e=parseInt(this[so],10);!isNaN(e)&&e>=0&&(this[so]=e)}}class Relevant extends ContentObject{constructor(e){super(Ql,"relevant")}[lo](){this[so]=this[so].trim().split(/\s+/)}}class Rename extends ContentObject{constructor(e){super(Ql,"rename")}[lo](){this[so]=this[so].trim();(this[so].toLowerCase().startsWith("xml")||new RegExp("[\\p{L}_][\\p{L}\\d._\\p{M}-]*","u").test(this[so]))&&warn("XFA - Rename: invalid XFA name")}}class RenderPolicy extends OptionObject{constructor(e){super(Ql,"renderPolicy",["server","client"])}}class RunScripts extends OptionObject{constructor(e){super(Ql,"runScripts",["both","client","none","server"])}}class config_Script extends XFAObject{constructor(e){super(Ql,"script",!0);this.currentPage=null;this.exclude=null;this.runScripts=null}}class ScriptModel extends OptionObject{constructor(e){super(Ql,"scriptModel",["XFA","none"])}}class Severity extends OptionObject{constructor(e){super(Ql,"severity",["ignore","error","information","trace","warning"])}}class SilentPrint extends XFAObject{constructor(e){super(Ql,"silentPrint",!0);this.addSilentPrint=null;this.printerName=null}}class Staple extends XFAObject{constructor(e){super(Ql,"staple");this.mode=getStringOption(e.mode,["usePrinterSetting","on","off"])}}class StartNode extends StringObject{constructor(e){super(Ql,"startNode")}}class StartPage extends IntegerObject{constructor(e){super(Ql,"startPage",0,e=>!0)}}class SubmitFormat extends OptionObject{constructor(e){super(Ql,"submitFormat",["html","delegate","fdf","xml","pdf"])}}class SubmitUrl extends StringObject{constructor(e){super(Ql,"submitUrl")}}class SubsetBelow extends IntegerObject{constructor(e){super(Ql,"subsetBelow",100,e=>e>=0&&e<=100)}}class SuppressBanner extends Option01{constructor(e){super(Ql,"suppressBanner")}}class Tagged extends Option01{constructor(e){super(Ql,"tagged")}}class config_Template extends XFAObject{constructor(e){super(Ql,"template",!0);this.base=null;this.relevant=null;this.startPage=null;this.uri=null;this.xsl=null}}class Threshold extends OptionObject{constructor(e){super(Ql,"threshold",["trace","error","information","warning"])}}class To extends OptionObject{constructor(e){super(Ql,"to",["null","memory","stderr","stdout","system","uri"])}}class TemplateCache extends XFAObject{constructor(e){super(Ql,"templateCache");this.maxEntries=getInteger({data:e.maxEntries,defaultValue:5,validate:e=>e>=0})}}class Trace extends XFAObject{constructor(e){super(Ql,"trace",!0);this.area=new XFAObjectArray}}class Transform extends XFAObject{constructor(e){super(Ql,"transform",!0);this.groupParent=null;this.ifEmpty=null;this.nameAttr=null;this.picture=null;this.presence=null;this.rename=null;this.whitespace=null}}class Type extends OptionObject{constructor(e){super(Ql,"type",["none","ascii85","asciiHex","ccittfax","flate","lzw","runLength","native","xdp","mergedXDP"])}}class Uri extends StringObject{constructor(e){super(Ql,"uri")}}class config_Validate extends OptionObject{constructor(e){super(Ql,"validate",["preSubmit","prePrint","preExecute","preSave"])}}class ValidateApprovalSignatures extends ContentObject{constructor(e){super(Ql,"validateApprovalSignatures")}[lo](){this[so]=this[so].trim().split(/\s+/).filter(e=>["docReady","postSign"].includes(e))}}class ValidationMessaging extends OptionObject{constructor(e){super(Ql,"validationMessaging",["allMessagesIndividually","allMessagesTogether","firstMessageOnly","noMessages"])}}class Version extends OptionObject{constructor(e){super(Ql,"version",["1.7","1.6","1.5","1.4","1.3","1.2"])}}class VersionControl extends XFAObject{constructor(e){super(Ql,"VersionControl");this.outputBelow=getStringOption(e.outputBelow,["warn","error","update"]);this.sourceAbove=getStringOption(e.sourceAbove,["warn","error"]);this.sourceBelow=getStringOption(e.sourceBelow,["update","maintain"])}}class ViewerPreferences extends XFAObject{constructor(e){super(Ql,"viewerPreferences",!0);this.ADBE_JSConsole=null;this.ADBE_JSDebugger=null;this.addViewerPreferences=null;this.duplexOption=null;this.enforce=null;this.numberOfCopies=null;this.pageRange=null;this.pickTrayByPDFSize=null;this.printScaling=null}}class WebClient extends XFAObject{constructor(e){super(Ql,"webClient",!0);this.name=e.name?e.name.trim():"";this.fontInfo=null;this.xdc=null}}class Whitespace extends OptionObject{constructor(e){super(Ql,"whitespace",["preserve","ltrim","normalize","rtrim","trim"])}}class Window extends ContentObject{constructor(e){super(Ql,"window")}[lo](){const e=this[so].split(",",2).map(e=>parseInt(e.trim(),10));if(e.some(e=>isNaN(e)))this[so]=[0,0];else{1===e.length&&e.push(e[0]);this[so]=e}}}class Xdc extends XFAObject{constructor(e){super(Ql,"xdc",!0);this.uri=new XFAObjectArray;this.xsl=new XFAObjectArray}}class Xdp extends XFAObject{constructor(e){super(Ql,"xdp",!0);this.packets=null}}class Xsl extends XFAObject{constructor(e){super(Ql,"xsl",!0);this.debug=null;this.uri=null}}class Zpl extends XFAObject{constructor(e){super(Ql,"zpl",!0);this.name=e.name?e.name.trim():"";this.batchOutput=null;this.flipLabel=null;this.fontInfo=null;this.xdc=null}}class ConfigNamespace{static[hl](e,t){if(Object.hasOwn(ConfigNamespace,e))return ConfigNamespace[e](t)}static acrobat(e){return new Acrobat(e)}static acrobat7(e){return new Acrobat7(e)}static ADBE_JSConsole(e){return new ADBE_JSConsole(e)}static ADBE_JSDebugger(e){return new ADBE_JSDebugger(e)}static addSilentPrint(e){return new AddSilentPrint(e)}static addViewerPreferences(e){return new AddViewerPreferences(e)}static adjustData(e){return new AdjustData(e)}static adobeExtensionLevel(e){return new AdobeExtensionLevel(e)}static agent(e){return new Agent(e)}static alwaysEmbed(e){return new AlwaysEmbed(e)}static amd(e){return new Amd(e)}static area(e){return new config_Area(e)}static attributes(e){return new Attributes(e)}static autoSave(e){return new AutoSave(e)}static base(e){return new Base(e)}static batchOutput(e){return new BatchOutput(e)}static behaviorOverride(e){return new BehaviorOverride(e)}static cache(e){return new Cache(e)}static change(e){return new Change(e)}static common(e){return new Common(e)}static compress(e){return new Compress(e)}static compressLogicalStructure(e){return new CompressLogicalStructure(e)}static compressObjectStream(e){return new CompressObjectStream(e)}static compression(e){return new Compression(e)}static config(e){return new Config(e)}static conformance(e){return new Conformance(e)}static contentCopy(e){return new ContentCopy(e)}static copies(e){return new Copies(e)}static creator(e){return new Creator(e)}static currentPage(e){return new CurrentPage(e)}static data(e){return new Data(e)}static debug(e){return new Debug(e)}static defaultTypeface(e){return new DefaultTypeface(e)}static destination(e){return new Destination(e)}static documentAssembly(e){return new DocumentAssembly(e)}static driver(e){return new Driver(e)}static duplexOption(e){return new DuplexOption(e)}static dynamicRender(e){return new DynamicRender(e)}static embed(e){return new Embed(e)}static encrypt(e){return new config_Encrypt(e)}static encryption(e){return new config_Encryption(e)}static encryptionLevel(e){return new EncryptionLevel(e)}static enforce(e){return new Enforce(e)}static equate(e){return new Equate(e)}static equateRange(e){return new EquateRange(e)}static exclude(e){return new Exclude(e)}static excludeNS(e){return new ExcludeNS(e)}static flipLabel(e){return new FlipLabel(e)}static fontInfo(e){return new config_FontInfo(e)}static formFieldFilling(e){return new FormFieldFilling(e)}static groupParent(e){return new GroupParent(e)}static ifEmpty(e){return new IfEmpty(e)}static includeXDPContent(e){return new IncludeXDPContent(e)}static incrementalLoad(e){return new IncrementalLoad(e)}static incrementalMerge(e){return new IncrementalMerge(e)}static interactive(e){return new Interactive(e)}static jog(e){return new Jog(e)}static labelPrinter(e){return new LabelPrinter(e)}static layout(e){return new Layout(e)}static level(e){return new Level(e)}static linearized(e){return new Linearized(e)}static locale(e){return new Locale(e)}static localeSet(e){return new LocaleSet(e)}static log(e){return new Log(e)}static map(e){return new MapElement(e)}static mediumInfo(e){return new MediumInfo(e)}static message(e){return new config_Message(e)}static messaging(e){return new Messaging(e)}static mode(e){return new Mode(e)}static modifyAnnots(e){return new ModifyAnnots(e)}static msgId(e){return new MsgId(e)}static nameAttr(e){return new NameAttr(e)}static neverEmbed(e){return new NeverEmbed(e)}static numberOfCopies(e){return new NumberOfCopies(e)}static openAction(e){return new OpenAction(e)}static output(e){return new Output(e)}static outputBin(e){return new OutputBin(e)}static outputXSL(e){return new OutputXSL(e)}static overprint(e){return new Overprint(e)}static packets(e){return new Packets(e)}static pageOffset(e){return new PageOffset(e)}static pageRange(e){return new PageRange(e)}static pagination(e){return new Pagination(e)}static paginationOverride(e){return new PaginationOverride(e)}static part(e){return new Part(e)}static pcl(e){return new Pcl(e)}static pdf(e){return new Pdf(e)}static pdfa(e){return new Pdfa(e)}static permissions(e){return new Permissions(e)}static pickTrayByPDFSize(e){return new PickTrayByPDFSize(e)}static picture(e){return new config_Picture(e)}static plaintextMetadata(e){return new PlaintextMetadata(e)}static presence(e){return new Presence(e)}static present(e){return new Present(e)}static print(e){return new Print(e)}static printHighQuality(e){return new PrintHighQuality(e)}static printScaling(e){return new PrintScaling(e)}static printerName(e){return new PrinterName(e)}static producer(e){return new Producer(e)}static ps(e){return new Ps(e)}static range(e){return new Range(e)}static record(e){return new Record(e)}static relevant(e){return new Relevant(e)}static rename(e){return new Rename(e)}static renderPolicy(e){return new RenderPolicy(e)}static runScripts(e){return new RunScripts(e)}static script(e){return new config_Script(e)}static scriptModel(e){return new ScriptModel(e)}static severity(e){return new Severity(e)}static silentPrint(e){return new SilentPrint(e)}static staple(e){return new Staple(e)}static startNode(e){return new StartNode(e)}static startPage(e){return new StartPage(e)}static submitFormat(e){return new SubmitFormat(e)}static submitUrl(e){return new SubmitUrl(e)}static subsetBelow(e){return new SubsetBelow(e)}static suppressBanner(e){return new SuppressBanner(e)}static tagged(e){return new Tagged(e)}static template(e){return new config_Template(e)}static templateCache(e){return new TemplateCache(e)}static threshold(e){return new Threshold(e)}static to(e){return new To(e)}static trace(e){return new Trace(e)}static transform(e){return new Transform(e)}static type(e){return new Type(e)}static uri(e){return new Uri(e)}static validate(e){return new config_Validate(e)}static validateApprovalSignatures(e){return new ValidateApprovalSignatures(e)}static validationMessaging(e){return new ValidationMessaging(e)}static version(e){return new Version(e)}static versionControl(e){return new VersionControl(e)}static viewerPreferences(e){return new ViewerPreferences(e)}static webClient(e){return new WebClient(e)}static whitespace(e){return new Whitespace(e)}static window(e){return new Window(e)}static xdc(e){return new Xdc(e)}static xdp(e){return new Xdp(e)}static xsl(e){return new Xsl(e)}static zpl(e){return new Zpl(e)}}const Zl=ul.connectionSet.id;class ConnectionSet extends XFAObject{constructor(e){super(Zl,"connectionSet",!0);this.wsdlConnection=new XFAObjectArray;this.xmlConnection=new XFAObjectArray;this.xsdConnection=new XFAObjectArray}}class EffectiveInputPolicy extends XFAObject{constructor(e){super(Zl,"effectiveInputPolicy");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class EffectiveOutputPolicy extends XFAObject{constructor(e){super(Zl,"effectiveOutputPolicy");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class Operation extends StringObject{constructor(e){super(Zl,"operation");this.id=e.id||"";this.input=e.input||"";this.name=e.name||"";this.output=e.output||"";this.use=e.use||"";this.usehref=e.usehref||""}}class RootElement extends StringObject{constructor(e){super(Zl,"rootElement");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class SoapAction extends StringObject{constructor(e){super(Zl,"soapAction");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class SoapAddress extends StringObject{constructor(e){super(Zl,"soapAddress");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class connection_set_Uri extends StringObject{constructor(e){super(Zl,"uri");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class WsdlAddress extends StringObject{constructor(e){super(Zl,"wsdlAddress");this.id=e.id||"";this.name=e.name||"";this.use=e.use||"";this.usehref=e.usehref||""}}class WsdlConnection extends XFAObject{constructor(e){super(Zl,"wsdlConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.effectiveInputPolicy=null;this.effectiveOutputPolicy=null;this.operation=null;this.soapAction=null;this.soapAddress=null;this.wsdlAddress=null}}class XmlConnection extends XFAObject{constructor(e){super(Zl,"xmlConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.uri=null}}class XsdConnection extends XFAObject{constructor(e){super(Zl,"xsdConnection",!0);this.dataDescription=e.dataDescription||"";this.name=e.name||"";this.rootElement=null;this.uri=null}}class ConnectionSetNamespace{static[hl](e,t){if(Object.hasOwn(ConnectionSetNamespace,e))return ConnectionSetNamespace[e](t)}static connectionSet(e){return new ConnectionSet(e)}static effectiveInputPolicy(e){return new EffectiveInputPolicy(e)}static effectiveOutputPolicy(e){return new EffectiveOutputPolicy(e)}static operation(e){return new Operation(e)}static rootElement(e){return new RootElement(e)}static soapAction(e){return new SoapAction(e)}static soapAddress(e){return new SoapAddress(e)}static uri(e){return new connection_set_Uri(e)}static wsdlAddress(e){return new WsdlAddress(e)}static wsdlConnection(e){return new WsdlConnection(e)}static xmlConnection(e){return new XmlConnection(e)}static xsdConnection(e){return new XsdConnection(e)}}const ef=ul.datasets.id;class datasets_Data extends XmlObject{constructor(e){super(ef,"data",e)}[Mo](){return!0}}class Datasets extends XFAObject{constructor(e){super(ef,"datasets",!0);this.data=null;this.Signature=null}[Wo](e){const t=e[Uo];("data"===t&&e[Lo]===ef||"Signature"===t&&e[Lo]===ul.signature.id)&&(this[t]=e);this[Ji](e)}}class DatasetsNamespace{static[hl](e,t){if(Object.hasOwn(DatasetsNamespace,e))return DatasetsNamespace[e](t)}static datasets(e){return new Datasets(e)}static data(e){return new datasets_Data(e)}}const tf=ul.localeSet.id;class CalendarSymbols extends XFAObject{constructor(e){super(tf,"calendarSymbols",!0);this.name="gregorian";this.dayNames=new XFAObjectArray(2);this.eraNames=null;this.meridiemNames=null;this.monthNames=new XFAObjectArray(2)}}class CurrencySymbol extends StringObject{constructor(e){super(tf,"currencySymbol");this.name=getStringOption(e.name,["symbol","isoname","decimal"])}}class CurrencySymbols extends XFAObject{constructor(e){super(tf,"currencySymbols",!0);this.currencySymbol=new XFAObjectArray(3)}}class DatePattern extends StringObject{constructor(e){super(tf,"datePattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class DatePatterns extends XFAObject{constructor(e){super(tf,"datePatterns",!0);this.datePattern=new XFAObjectArray(4)}}class DateTimeSymbols extends ContentObject{constructor(e){super(tf,"dateTimeSymbols")}}class Day extends StringObject{constructor(e){super(tf,"day")}}class DayNames extends XFAObject{constructor(e){super(tf,"dayNames",!0);this.abbr=getInteger({data:e.abbr,defaultValue:0,validate:e=>1===e});this.day=new XFAObjectArray(7)}}class Era extends StringObject{constructor(e){super(tf,"era")}}class EraNames extends XFAObject{constructor(e){super(tf,"eraNames",!0);this.era=new XFAObjectArray(2)}}class locale_set_Locale extends XFAObject{constructor(e){super(tf,"locale",!0);this.desc=e.desc||"";this.name="isoname";this.calendarSymbols=null;this.currencySymbols=null;this.datePatterns=null;this.dateTimeSymbols=null;this.numberPatterns=null;this.numberSymbols=null;this.timePatterns=null;this.typeFaces=null}}class locale_set_LocaleSet extends XFAObject{constructor(e){super(tf,"localeSet",!0);this.locale=new XFAObjectArray}}class Meridiem extends StringObject{constructor(e){super(tf,"meridiem")}}class MeridiemNames extends XFAObject{constructor(e){super(tf,"meridiemNames",!0);this.meridiem=new XFAObjectArray(2)}}class Month extends StringObject{constructor(e){super(tf,"month")}}class MonthNames extends XFAObject{constructor(e){super(tf,"monthNames",!0);this.abbr=getInteger({data:e.abbr,defaultValue:0,validate:e=>1===e});this.month=new XFAObjectArray(12)}}class NumberPattern extends StringObject{constructor(e){super(tf,"numberPattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class NumberPatterns extends XFAObject{constructor(e){super(tf,"numberPatterns",!0);this.numberPattern=new XFAObjectArray(4)}}class NumberSymbol extends StringObject{constructor(e){super(tf,"numberSymbol");this.name=getStringOption(e.name,["decimal","grouping","percent","minus","zero"])}}class NumberSymbols extends XFAObject{constructor(e){super(tf,"numberSymbols",!0);this.numberSymbol=new XFAObjectArray(5)}}class TimePattern extends StringObject{constructor(e){super(tf,"timePattern");this.name=getStringOption(e.name,["full","long","med","short"])}}class TimePatterns extends XFAObject{constructor(e){super(tf,"timePatterns",!0);this.timePattern=new XFAObjectArray(4)}}class TypeFace extends XFAObject{constructor(e){super(tf,"typeFace",!0);this.name=""|e.name}}class TypeFaces extends XFAObject{constructor(e){super(tf,"typeFaces",!0);this.typeFace=new XFAObjectArray}}class LocaleSetNamespace{static[hl](e,t){if(Object.hasOwn(LocaleSetNamespace,e))return LocaleSetNamespace[e](t)}static calendarSymbols(e){return new CalendarSymbols(e)}static currencySymbol(e){return new CurrencySymbol(e)}static currencySymbols(e){return new CurrencySymbols(e)}static datePattern(e){return new DatePattern(e)}static datePatterns(e){return new DatePatterns(e)}static dateTimeSymbols(e){return new DateTimeSymbols(e)}static day(e){return new Day(e)}static dayNames(e){return new DayNames(e)}static era(e){return new Era(e)}static eraNames(e){return new EraNames(e)}static locale(e){return new locale_set_Locale(e)}static localeSet(e){return new locale_set_LocaleSet(e)}static meridiem(e){return new Meridiem(e)}static meridiemNames(e){return new MeridiemNames(e)}static month(e){return new Month(e)}static monthNames(e){return new MonthNames(e)}static numberPattern(e){return new NumberPattern(e)}static numberPatterns(e){return new NumberPatterns(e)}static numberSymbol(e){return new NumberSymbol(e)}static numberSymbols(e){return new NumberSymbols(e)}static timePattern(e){return new TimePattern(e)}static timePatterns(e){return new TimePatterns(e)}static typeFace(e){return new TypeFace(e)}static typeFaces(e){return new TypeFaces(e)}}const af=ul.signature.id;class signature_Signature extends XFAObject{constructor(e){super(af,"signature",!0)}}class SignatureNamespace{static[hl](e,t){if(Object.hasOwn(SignatureNamespace,e))return SignatureNamespace[e](t)}static signature(e){return new signature_Signature(e)}}const nf=ul.stylesheet.id;class Stylesheet extends XFAObject{constructor(e){super(nf,"stylesheet",!0)}}class StylesheetNamespace{static[hl](e,t){if(Object.hasOwn(StylesheetNamespace,e))return StylesheetNamespace[e](t)}static stylesheet(e){return new Stylesheet(e)}}const sf=ul.xdp.id;class xdp_Xdp extends XFAObject{constructor(e){super(sf,"xdp",!0);this.uuid=e.uuid||"";this.timeStamp=e.timeStamp||"";this.config=null;this.connectionSet=null;this.datasets=null;this.localeSet=null;this.stylesheet=new XFAObjectArray;this.template=null}[Ko](e){const t=ul[e[Uo]];return t&&e[Lo]===t.id}}class XdpNamespace{static[hl](e,t){if(Object.hasOwn(XdpNamespace,e))return XdpNamespace[e](t)}static xdp(e){return new xdp_Xdp(e)}}const rf=ul.xhtml.id,of=Symbol(),lf=new Set(["color","font","font-family","font-size","font-stretch","font-style","font-weight","margin","margin-bottom","margin-left","margin-right","margin-top","letter-spacing","line-height","orphans","page-break-after","page-break-before","page-break-inside","tab-interval","tab-stop","text-align","text-decoration","text-indent","vertical-align","widows","kerning-mode","xfa-font-horizontal-scale","xfa-font-vertical-scale","xfa-spacerun","xfa-tab-stops"]),ff=new Map([["page-break-after","breakAfter"],["page-break-before","breakBefore"],["page-break-inside","breakInside"],["kerning-mode",e=>"none"===e?"none":"normal"],["xfa-font-horizontal-scale",e=>`scaleX(${Math.max(0,parseInt(e,10)/100).toFixed(2)})`],["xfa-font-vertical-scale",e=>`scaleY(${Math.max(0,parseInt(e,10)/100).toFixed(2)})`],["xfa-spacerun",""],["xfa-tab-stops",""],["font-size",(e,t)=>measureToString(.99*(e=t.fontSize=Math.abs(getMeasurement(e))))],["letter-spacing",e=>measureToString(getMeasurement(e))],["line-height",e=>measureToString(getMeasurement(e))],["margin",e=>measureToString(getMeasurement(e))],["margin-bottom",e=>measureToString(getMeasurement(e))],["margin-left",e=>measureToString(getMeasurement(e))],["margin-right",e=>measureToString(getMeasurement(e))],["margin-top",e=>measureToString(getMeasurement(e))],["text-indent",e=>measureToString(getMeasurement(e))],["font-family",e=>e],["vertical-align",e=>measureToString(getMeasurement(e))]]),cf=/\s+/g,hf=/[\r\n]+/g,uf=/\r\n?/g;function mapStyle(e,t,a){const n=Object.create(null);if(!e)return n;const s=Object.create(null);for(const[t,a]of e.split(";").map(e=>e.split(":",2))){const e=ff.get(t);if(""===e)continue;let r=a;e&&(r="string"==typeof e?e:e(a,s));t.endsWith("scale")?n.transform=n.transform?`${n[t]} ${r}`:r:n[t.replaceAll(/-([a-zA-Z])/g,(e,t)=>t.toUpperCase())]=r}n.fontFamily&&setFontFamily({typeface:n.fontFamily,weight:n.fontWeight||"normal",posture:n.fontStyle||"normal",size:s.fontSize||0},t,t[xo].fontFinder,n);if(a&&n.verticalAlign&&"0px"!==n.verticalAlign&&n.fontSize){const e=.583,t=.333,a=getMeasurement(n.fontSize);n.fontSize=measureToString(a*e);n.verticalAlign=measureToString(Math.sign(getMeasurement(n.verticalAlign))*a*t)}a&&n.fontSize&&(n.fontSize=`calc(${n.fontSize} * var(--total-scale-factor))`);fixTextIndent(n);return n}const mf=new Set(["body","html"]);class XhtmlObject extends XmlObject{constructor(e,t){super(rf,t);this[of]=!1;this.style=e.style||""}[Zi](e){super[Zi](e);this.style=function checkStyle(e){return e.style?e.style.split(";").filter(e=>!!e.trim()).map(e=>e.split(":",2).map(e=>e.trim())).filter(([t,a])=>{"font-family"===t&&e[xo].usedTypefaces.add(a);return lf.has(t)}).map(e=>e.join(":")).join(";"):""}(this)}[$i](){return!mf.has(this[Uo])}[Go](e,t=!1){if(t)this[of]=!0;else{e=e.replaceAll(hf,"");this.style.includes("xfa-spacerun:yes")||(e=e.replaceAll(cf," "))}e&&(this[so]+=e)}[Vo](e,t=!0){const a=Object.create(null),n={top:NaN,bottom:NaN,left:NaN,right:NaN};let s=null;for(const[e,t]of this.style.split(";").map(e=>e.split(":",2)))switch(e){case"font-family":a.typeface=stripQuotes(t);break;case"font-size":a.size=getMeasurement(t);break;case"font-weight":a.weight=t;break;case"font-style":a.posture=t;break;case"letter-spacing":a.letterSpacing=getMeasurement(t);break;case"margin":const e=t.split(/ \t/).map(e=>getMeasurement(e));switch(e.length){case 1:n.top=n.bottom=n.left=n.right=e[0];break;case 2:n.top=n.bottom=e[0];n.left=n.right=e[1];break;case 3:n.top=e[0];n.bottom=e[2];n.left=n.right=e[1];break;case 4:n.top=e[0];n.left=e[1];n.bottom=e[2];n.right=e[3]}break;case"margin-top":n.top=getMeasurement(t);break;case"margin-bottom":n.bottom=getMeasurement(t);break;case"margin-left":n.left=getMeasurement(t);break;case"margin-right":n.right=getMeasurement(t);break;case"line-height":s=getMeasurement(t)}e.pushData(a,n,s);if(this[so])e.addString(this[so]);else for(const t of this[ko]())"#text"!==t[Uo]?t[Vo](e):e.addString(t[so]);t&&e.popFont()}[ol](e){const t=[];this[oo]={children:t};this[Qi]({});if(0===t.length&&!this[so])return HTMLResult.EMPTY;let a;a=this[of]?this[so]?this[so].replaceAll(uf,"\n"):void 0:this[so]||void 0;return HTMLResult.success({name:this[Uo],attributes:{href:this.href,style:mapStyle(this.style,this,this[of])},children:t,value:a})}}class A extends XhtmlObject{constructor(e){super(e,"a");this.href=fixURL(e.href)||""}}class B extends XhtmlObject{constructor(e){super(e,"b")}[Vo](e){e.pushFont({weight:"bold"});super[Vo](e);e.popFont()}}class Body extends XhtmlObject{constructor(e){super(e,"body")}[ol](e){const t=super[ol](e),{html:a}=t;if(!a)return HTMLResult.EMPTY;a.name="div";a.attributes.class=["xfaRich"];return t}}class Br extends XhtmlObject{constructor(e){super(e,"br")}[rl](){return"\n"}[Vo](e){e.addString("\n")}[ol](e){return HTMLResult.success({name:"br"})}}class Html extends XhtmlObject{constructor(e){super(e,"html")}[ol](e){const t=[];this[oo]={children:t};this[Qi]({});if(0===t.length)return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:{}},value:this[so]||""});if(1===t.length){const e=t[0];if(e.attributes?.class.includes("xfaRich"))return HTMLResult.success(e)}return HTMLResult.success({name:"div",attributes:{class:["xfaRich"],style:{}},children:t})}}class I extends XhtmlObject{constructor(e){super(e,"i")}[Vo](e){e.pushFont({posture:"italic"});super[Vo](e);e.popFont()}}class Li extends XhtmlObject{constructor(e){super(e,"li")}}class Ol extends XhtmlObject{constructor(e){super(e,"ol")}}class P extends XhtmlObject{constructor(e){super(e,"p")}[Vo](e){super[Vo](e,!1);e.addString("\n");e.addPara();e.popFont()}[rl](){return this[So]()[ko]().at(-1)===this?super[rl]():super[rl]()+"\n"}}class Span extends XhtmlObject{constructor(e){super(e,"span")}}class Sub extends XhtmlObject{constructor(e){super(e,"sub")}}class Sup extends XhtmlObject{constructor(e){super(e,"sup")}}class Ul extends XhtmlObject{constructor(e){super(e,"ul")}}class XhtmlNamespace{static[hl](e,t){if(Object.hasOwn(XhtmlNamespace,e))return XhtmlNamespace[e](t)}static a(e){return new A(e)}static b(e){return new B(e)}static body(e){return new Body(e)}static br(e){return new Br(e)}static html(e){return new Html(e)}static i(e){return new I(e)}static li(e){return new Li(e)}static ol(e){return new Ol(e)}static p(e){return new P(e)}static span(e){return new Span(e)}static sub(e){return new Sub(e)}static sup(e){return new Sup(e)}static ul(e){return new Ul(e)}}const pf={config:ConfigNamespace,connection:ConnectionSetNamespace,datasets:DatasetsNamespace,localeSet:LocaleSetNamespace,signature:SignatureNamespace,stylesheet:StylesheetNamespace,template:TemplateNamespace,xdp:XdpNamespace,xhtml:XhtmlNamespace};class UnknownNamespace{constructor(e){this.namespaceId=e}[hl](e,t){return new XmlObject(this.namespaceId,e,t)}}class Root extends XFAObject{constructor(e){super(-1,"root",Object.create(null));this.element=null;this[Io]=e}[Wo](e){this.element=e;return!0}[lo](){super[lo]();if(this.element.template instanceof Template){this[Io].set(Qo,this.element);this.element.template[Zo](this[Io]);this.element.template[Io]=this[Io]}}}class Empty extends XFAObject{constructor(){super(-1,"",Object.create(null))}[Wo](e){return!1}}class Builder{constructor(e=null){this._namespaceStack=[];this._nsAgnosticLevel=0;this._namespacePrefixes=new Map;this._namespaces=new Map;this._nextNsId=Math.max(...Object.values(ul).map(({id:e})=>e));this._currentNamespace=e||new UnknownNamespace(++this._nextNsId)}buildRoot(e){return new Root(e)}build({nsPrefix:e,name:t,attributes:a,namespace:n,prefixes:s}){const r=null!==n;if(r){this._namespaceStack.push(this._currentNamespace);this._currentNamespace=this._searchNamespace(n)}s&&this._addNamespacePrefix(s);if(Object.hasOwn(a,Xo)){const e=pf.datasets,t=a[Xo];let n=null;for(const[a,s]of Object.entries(t)){if(this._getNamespaceToUse(a)===e){n={xfa:s};break}}n?a[Xo]=n:delete a[Xo]}const i=this._getNamespaceToUse(e),o=i?.[hl](t,a)||new Empty;o[Mo]()&&this._nsAgnosticLevel++;(r||s||o[Mo]())&&(o[to]={hasNamespace:r,prefixes:s,nsAgnostic:o[Mo]()});return o}isNsAgnostic(){return this._nsAgnosticLevel>0}_searchNamespace(e){let t=this._namespaces.get(e);if(t)return t;for(const[a,{check:n}]of Object.entries(ul))if(n(e)){t=pf[a];if(t){this._namespaces.set(e,t);return t}break}t=new UnknownNamespace(++this._nextNsId);this._namespaces.set(e,t);return t}_addNamespacePrefix(e){for(const{prefix:t,value:a}of e){const e=this._searchNamespace(a);this._namespacePrefixes.getOrInsertComputed(t,makeArr).push(e)}}_getNamespaceToUse(e){if(!e)return this._currentNamespace;const t=this._namespacePrefixes.get(e);if(t?.length>0)return t.at(-1);warn(`Unknown namespace prefix: ${e}.`);return null}clean(e){const{hasNamespace:t,prefixes:a,nsAgnostic:n}=e;t&&(this._currentNamespace=this._namespaceStack.pop());a&&a.forEach(({prefix:e})=>{this._namespacePrefixes.get(e).pop()});n&&this._nsAgnosticLevel--}}class XFAParser extends XMLParserBase{constructor(e=null,t=!1){super();this._builder=new Builder(e);this._stack=[];this._globalData={usedTypefaces:new Set};this._ids=new Map;this._current=this._builder.buildRoot(this._ids);this._errorCode=Bi;this._whiteRegex=/^\s+$/;this._nbsps=/\xa0+/g;this._richText=t}parse(e){this.parseXml(e);if(this._errorCode===Bi){this._current[lo]();return this._current.element}}onText(e){e=e.replace(this._nbsps,e=>e.slice(1)+" ");this._richText||this._current[$i]()?this._current[Go](e,this._richText):this._whiteRegex.test(e)||this._current[Go](e.trim())}onCdata(e){this._current[Go](e)}_mkAttributes(e,t){let a=null,n=null;const s=Object.create({});for(const{name:r,value:i}of e)if("xmlns"===r)a?warn(`XFA - multiple namespace definition in <${t}>`):a=i;else if(r.startsWith("xmlns:")){const e=r.substring(6);n??=[];n.push({prefix:e,value:i})}else{const e=r.indexOf(":");if(-1===e)s[r]=i;else{const t=s[Xo]??=Object.create(null),[a,n]=[r.slice(0,e),r.slice(e+1)];(t[a]||=Object.create(null))[n]=i}}return[a,n,s]}_getNameAndPrefix(e,t){const a=e.indexOf(":");return-1===a?[e,null]:[e.substring(a+1),t?"":e.substring(0,a)]}onBeginElement(e,t,a){const[n,s,r]=this._mkAttributes(t,e),[i,o]=this._getNameAndPrefix(e,this._builder.isNsAgnostic()),l=this._builder.build({nsPrefix:o,name:i,attributes:r,namespace:n,prefixes:s});l[xo]=this._globalData;if(a){l[lo]();this._current[Wo](l)&&l[tl](this._ids);l[Zi](this._builder)}else{this._stack.push(this._current);this._current=l}}onEndElement(e){const t=this._current;if(t[Ro]()&&"string"==typeof t[so]){const e=new XFAParser;e._globalData=this._globalData;const a=e.parse(t[so]);t[so]=null;t[Wo](a)}t[lo]();this._current=this._stack.pop();this._current[Wo](t)&&t[tl](this._ids);t[Zi](this._builder)}onError(e){this._errorCode=e}}class XFAFactory{constructor(e){try{this.root=(new XFAParser).parse(XFAFactory._createDocument(e));const t=new Binder(this.root);this.form=t.bind();this.dataHandler=new DataHandler(this.root,t.getData());this.form[xo].template=this.form}catch(e){warn(`XFA - an error occurred during parsing and binding: ${e}`)}}isValid(){return!(!this.root||!this.form)}_createPagesHelper(){const e=this.form[il]();return new Promise((t,a)=>{const nextIteration=()=>{try{const a=e.next();a.done?t(a.value):setTimeout(nextIteration,0)}catch(e){a(e)}};setTimeout(nextIteration,0)})}async _createPages(){try{this.pages=await this._createPagesHelper();this.dims=this.pages.children.map(e=>{const{width:t,height:a}=e.attributes.style;return[0,0,parseInt(t,10),parseInt(a,10)]})}catch(e){warn(`XFA - an error occurred during layout: ${e}`)}}getBoundingBox(e){return this.dims[e]}async getNumPages(){this.pages||await this._createPages();return this.dims.length}setImages(e){this.form[xo].images=e}setFonts(e){this.form[xo].fontFinder=new FontFinder(e);const t=[];for(let e of this.form[xo].usedTypefaces){e=stripQuotes(e);this.form[xo].fontFinder.find(e)||t.push(e)}return t.length>0?t:null}appendFonts(e,t){this.form[xo].fontFinder.add(e,t)}async getPages(){this.pages||await this._createPages();const e=this.pages;this.pages=null;return e}serializeData(e){return this.dataHandler.serialize(e)}static _createDocument(e){return e["/xdp:xdp"]?Object.values(e).join(""):e["xdp:xdp"]}static getRichTextAsHtml(e){if(!e||"string"!=typeof e)return null;try{let t=new XFAParser(XhtmlNamespace,!0).parse(e);if(!["body","xhtml"].includes(t[Uo])){const e=XhtmlNamespace.body({});e[Ji](t);t=e}const a=t[ol]();if(!a.success)return null;const{html:n}=a,{attributes:s}=n;if(s){s.class&&(s.class=s.class.filter(e=>!e.startsWith("xfa")));s.dir="auto"}return{html:n,str:t[rl]()}}catch(e){warn(`XFA - an error occurred during parsing of rich text: ${e}`)}return null}}class AnnotationFactory{static createGlobals(e){return Promise.all([e.ensureCatalog("acroForm"),e.ensureDoc("xfaDatasets"),e.ensureCatalog("structTreeRoot"),e.ensureCatalog("baseUrl"),e.ensureCatalog("attachments"),e.ensureCatalog("globalColorSpaceCache")]).then(([t,a,n,s,r,i])=>({pdfManager:e,acroForm:t instanceof Dict?t:Dict.empty,xfaDatasets:a,structTreeRoot:n,baseUrl:s,attachments:r,globalColorSpaceCache:i}),e=>{warn(`createGlobals: "${e}".`);return null})}static async create(e,t,a,n,s,r,i,o){const l=s?await this._getPageIndex(e,t,a.pdfManager):null;return a.pdfManager.ensure(this,"_create",[e,t,a,n,s,r,i,l,o])}static _create(e,t,a,n,s=!1,r=null,i=null,o=null,l=null){const f=e.fetchIfRef(t);if(!(f instanceof Dict))return;let c=f.get("Subtype");c=c instanceof Name?c.name:null;if(i&&!i.has(R[c?.toUpperCase()]))return null;const{acroForm:h,pdfManager:u}=a,m=t instanceof Ref?t.toString():`annot_${n.createObjId()}`,p={xref:e,ref:t,dict:f,subtype:c,id:m,annotationGlobals:a,collectFields:s,orphanFields:r,needAppearances:!s&&!0===h.get("NeedAppearances"),pageIndex:o,evaluatorOptions:u.evaluatorOptions,pageRef:l};switch(c){case"Link":return new LinkAnnotation(p);case"Text":return new TextAnnotation(p);case"Widget":let e=getInheritableProperty({dict:f,key:"FT"});e=e instanceof Name?e.name:null;switch(e){case"Tx":return new TextWidgetAnnotation(p);case"Btn":return new ButtonWidgetAnnotation(p);case"Ch":return new ChoiceWidgetAnnotation(p);case"Sig":return new SignatureWidgetAnnotation(p)}warn(`Unimplemented widget field type "${e}", falling back to base field type.`);return new WidgetAnnotation(p);case"Popup":return new PopupAnnotation(p);case"FreeText":return new FreeTextAnnotation(p);case"Line":return new LineAnnotation(p);case"Square":return new SquareAnnotation(p);case"Circle":return new CircleAnnotation(p);case"PolyLine":return new PolylineAnnotation(p);case"Polygon":return new PolygonAnnotation(p);case"Caret":return new CaretAnnotation(p);case"Ink":return new InkAnnotation(p);case"Highlight":return new HighlightAnnotation(p);case"Underline":return new UnderlineAnnotation(p);case"Squiggly":return new SquigglyAnnotation(p);case"StrikeOut":return new StrikeOutAnnotation(p);case"Stamp":return new StampAnnotation(p);case"FileAttachment":return new FileAttachmentAnnotation(p);default:s||warn(c?`Unimplemented annotation type "${c}", falling back to base annotation.`:"Annotation is missing the required /Subtype.");return new Annotation(p)}}static async _getPageIndex(e,t,a){try{const n=await e.fetchIfRefAsync(t);if(!(n instanceof Dict))return-1;const s=n.getRaw("P");if(s instanceof Ref)try{return await a.ensureCatalog("getPageIndex",[s])}catch(e){info(`_getPageIndex -- not a valid page reference: "${e}".`)}if(n.has("Kids"))return-1;const r=await a.ensureDoc("numPages");for(let e=0;ee/255)||t}function getQuadPoints(e,t){const a=e.getArray("QuadPoints");if(!isNumberArray(a,null)||0===a.length||a.length%8>0)return null;const n=new Float32Array(a.length);for(let e=0,s=a.length;et[2]||pt[3]))return null;n.set([u,d,m,d,u,p,m,p],e)}return n}function getTransformMatrix(e,t,n){const s=a.slice();Util.axialAlignedBoundingBox(t,n,s);const[r,i,o,l]=s;if(r===o||i===l)return[1,0,0,1,e[0],e[1]];const f=(e[2]-e[0])/(o-r),c=(e[3]-e[1])/(l-i);return[f,0,0,c,e[0]-r*f,e[1]-i*c]}class Annotation{constructor(e){const{annotationGlobals:t,dict:a,orphanFields:n,ref:s,subtype:r,xref:i}=e,o=n?.get(s);o&&a.set("Parent",o);this.setTitle(a.get("T"));this.setContents(a.get("Contents"));this.setModificationDate(a.get("M"));this.setFlags(a.get("F"));this.setRectangle(a.getArray("Rect"));this.setColor(a.getArray("C"));this.setBorderStyle(a);this.setAppearance(a);this.setOptionalContent(a);const l=a.get("MK");this.setBorderAndBackgroundColors(l);this.setRotation(l,a);this.ref=e.ref instanceof Ref?e.ref:null;this._streams=[];this.appearance&&this._streams.push(this.appearance);const f=!!(this.flags&L),c=!!(this.flags&U);this.data={annotationType:R[r?.toUpperCase()],annotationFlags:this.flags,borderStyle:this.borderStyle,color:this.color,backgroundColor:this.backgroundColor,borderColor:this.borderColor,rotation:this.rotation,contentsObj:this._contents,hasAppearance:!!this.appearance,id:e.id,modificationDate:this.modificationDate,rect:this.rectangle,subtype:r,hasOwnCanvas:!1,noRotate:!!(this.flags&_),noHTML:f&&c,isEditable:!1,structParent:-1};if(t.structTreeRoot){let n=a.get("StructParent");this.data.structParent=n=Number.isInteger(n)&&n>=0?n:-1;t.structTreeRoot.addAnnotationIdToPage(e.pageRef,n)}if(e.collectFields){const t=a.get("Kids");if(Array.isArray(t)){const e=[];for(const a of t)a instanceof Ref&&e.push(a.toString());0!==e.length&&(this.data.kidIds=e)}this.data.actions=collectActions(i,a,ie);this.data.fieldName=this._constructFieldName(a);this.data.pageIndex=e.pageIndex}const h=a.get("IT");h instanceof Name&&(this.data.it=h.name);this._isOffscreenCanvasSupported=e.evaluatorOptions.isOffscreenCanvasSupported;this._fallbackFontDict=null;this._needAppearances=!1}_hasFlag(e,t){return!!(e&t)}_buildFlags(e,t){let{flags:a}=this;if(void 0===e){if(void 0===t)return;return t?a&~E:a&~N|E}if(e){a|=E;return t?a&~z|N:a&~N|z}a&=~(N|z);return t?a&~E:a|E}_isViewable(e){return!this._hasFlag(e,M)&&!this._hasFlag(e,z)}_isPrintable(e){return this._hasFlag(e,E)&&!this._hasFlag(e,N)&&!this._hasFlag(e,M)}mustBeViewed(e,t){const a=e?.get(this.data.id)?.noView;return void 0!==a?!a:this.viewable&&!this._hasFlag(this.flags,N)}mustBePrinted(e){const t=e?.get(this.data.id)?.noPrint;return void 0!==t?!t:this.printable}mustBeViewedWhenEditing(e,t=null){return e?!this.data.isEditable:!t?.has(this.data.id)}get viewable(){return null!==this.data.quadPoints&&(0===this.flags||this._isViewable(this.flags))}get printable(){return null!==this.data.quadPoints&&(0!==this.flags&&this._isPrintable(this.flags))}_parseStringHelper(e){const t="string"==typeof e?stringToPDFString(e):"";return{str:t,dir:t&&"rtl"===bidi(t).dir?"rtl":"ltr"}}setDefaultAppearance(e){const{dict:t,annotationGlobals:a}=e,n=getInheritableProperty({dict:t,key:"DA"})||a.acroForm.get("DA");this._defaultAppearance="string"==typeof n?n:"";this.data.defaultAppearanceData=parseDefaultAppearance(this._defaultAppearance)}setTitle(e){this._title=this._parseStringHelper(e)}setContents(e){this._contents=this._parseStringHelper(e)}setModificationDate(e){this.modificationDate="string"==typeof e?e:null}setFlags(e){this.flags=Number.isInteger(e)&&e>0?e:0;this.flags&M&&"Annotation"!==this.constructor.name&&(this.flags^=M)}hasFlag(e){return this._hasFlag(this.flags,e)}setRectangle(e){this.rectangle=lookupNormalRect(e,[0,0,0,0])}setColor(e){this.color=getRgbColor(e)}setLineEndings(e){this.lineEndings=["None","None"];if(Array.isArray(e)&&2===e.length)for(let t=0;t<2;t++){const a=e[t];if(a instanceof Name)switch(a.name){case"None":continue;case"Square":case"Circle":case"Diamond":case"OpenArrow":case"ClosedArrow":case"Butt":case"ROpenArrow":case"RClosedArrow":case"Slash":this.lineEndings[t]=a.name;continue}warn(`Ignoring invalid lineEnding: ${a}`)}}setRotation(e,t){this.rotation=0;let a=e instanceof Dict?e.get("R")||0:t.get("Rotate")||0;if(Number.isInteger(a)&&0!==a){a%=360;a<0&&(a+=360);a%90==0&&(this.rotation=a)}}setBorderAndBackgroundColors(e){if(e instanceof Dict){this.borderColor=getRgbColor(e.getArray("BC"),null);this.backgroundColor=getRgbColor(e.getArray("BG"),null)}else this.borderColor=this.backgroundColor=null}setBorderStyle(e){this.borderStyle=new AnnotationBorderStyle;if(e instanceof Dict)if(e.has("BS")){const t=e.get("BS");if(t instanceof Dict){const e=t.get("Type");if(!e||isName(e,"Border")){this.borderStyle.setWidth(t.get("W"),this.rectangle);this.borderStyle.setStyle(t.get("S"));this.borderStyle.setDashArray(t.getArray("D"))}}}else if(e.has("Border")){const t=e.getArray("Border");if(Array.isArray(t))if(t.length>=3){this.borderStyle.setHorizontalCornerRadius(t[0]);this.borderStyle.setVerticalCornerRadius(t[1]);this.borderStyle.setWidth(t[2],this.rectangle);4===t.length&&this.borderStyle.setDashArray(t[3],!0)}else 0===t.length&&this.borderStyle.setWidth(0)}else this.borderStyle.setWidth(0)}setAppearance(e){this.appearance=null;const t=e.get("AP");if(!(t instanceof Dict))return;const a=t.get("N");if(a instanceof BaseStream){this.appearance=a;return}if(!(a instanceof Dict))return;const n=e.get("AS");if(!(n instanceof Name&&a.has(n.name)))return;const s=a.get(n.name);s instanceof BaseStream&&(this.appearance=s)}setOptionalContent(e){this.oc=null;const t=e.get("OC");t instanceof Name?warn("setOptionalContent: Support for /Name-entry is not implemented."):t instanceof Dict&&(this.oc=t)}async loadResources(e,t){const a=await t.dict.getAsync("Resources");a&&await ObjectLoader.load(a,e,a.xref);return a}async getOperatorList(e,t,a,n){const{hasOwnCanvas:s,id:r,rect:i}=this.data;let o=this.appearance;const f=!!(s&&a&l);if(f&&(0===this.width||0===this.height)){this.data.hasOwnCanvas=!1;return{opList:new OperatorList,separateForm:!1,separateCanvas:!1}}if(!o){if(!f)return{opList:new OperatorList,separateForm:!1,separateCanvas:!1};o=new StringStream("");o.dict=new Dict}const c=o.dict,h=await this.loadResources(da,o),u=lookupRect(c.getArray("BBox"),[0,0,1,1]),m=lookupMatrix(c.getArray("Matrix"),pa),p=getTransformMatrix(i,u,m),d=new OperatorList;let g;this.oc&&(g=await e.parseMarkedContentProps(this.oc,null));void 0!==g&&d.addOp(xt,["OC",g]);d.addOp(Bt,[r,i,p,m,f]);await e.getOperatorList({stream:o,task:t,resources:h,operatorList:d,fallbackFontDict:this._fallbackFontDict});d.addOp(Dt,[]);void 0!==g&&d.addOp(Ct,[]);this.reset();return{opList:d,separateForm:!1,separateCanvas:f}}async save(e,t,a,n){return null}get overlaysTextContent(){return!1}get hasTextContent(){return!1}async extractTextContent(e,t,a){if(!this.appearance)return;const n=await this.loadResources(ga,this.appearance),s=[],r=[];let i=null;const o={desiredSize:Math.Infinity,ready:!0,enqueue(e,t){for(const t of e.items)if(void 0!==t.str){i||=t.transform.slice(-2);r.push(t.str);if(t.hasEOL){s.push(r.join("").trimEnd());r.length=0}}}};await e.getTextContent({stream:this.appearance,task:t,resources:n,includeMarkedContent:!0,keepWhiteSpace:!0,sink:o,viewBox:a});this.reset();r.length&&s.push(r.join("").trimEnd());if(s.length>1||s[0]){const e=this.appearance.dict,t=lookupRect(e.getArray("BBox"),null),a=lookupMatrix(e.getArray("Matrix"),null);this.data.textPosition=this._transformPoint(i,t,a);this.data.textContent=s}}_transformPoint(e,t,a){const{rect:n}=this.data;t||=[0,0,1,1];a||=[1,0,0,1,0,0];const s=getTransformMatrix(n,t,a);s[4]-=n[0];s[5]-=n[1];const r=e.slice();Util.applyTransform(r,s);Util.applyTransform(r,a);return r}getFieldObject(){return this.data.kidIds?{id:this.data.id,actions:this.data.actions,name:this.data.fieldName,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,type:"",kidIds:this.data.kidIds,page:this.data.pageIndex,rotation:this.rotation}:null}reset(){for(const e of this._streams)e.reset()}_constructFieldName(e){if(!e.has("T")&&!e.has("Parent")){warn("Unknown field name, falling back to empty field name.");return""}if(!e.has("Parent"))return stringToPDFString(e.get("T"));const t=[];e.has("T")&&t.unshift(stringToPDFString(e.get("T")));let a=e;const n=new RefSet;e.objId&&n.put(e.objId);for(;a.has("Parent");){a=a.get("Parent");if(!(a instanceof Dict)||a.objId&&n.has(a.objId))break;a.objId&&n.put(a.objId);a.has("T")&&t.unshift(stringToPDFString(a.get("T")))}return t.join(".")}get width(){return this.data.rect[2]-this.data.rect[0]}get height(){return this.data.rect[3]-this.data.rect[1]}}class AnnotationBorderStyle{width=1;rawWidth=1;style=te;dashArray=[3];horizontalCornerRadius=0;verticalCornerRadius=0;setWidth(e,t=[0,0,0,0]){if(e instanceof Name)this.width=0;else if("number"==typeof e){if(e>0){this.rawWidth=e;const a=(t[2]-t[0])/2,n=(t[3]-t[1])/2;if(a>0&&n>0&&(e>a||e>n)){warn(`AnnotationBorderStyle.setWidth - ignoring width: ${e}`);e=1}}this.width=e}}setStyle(e){if(e instanceof Name)switch(e.name){case"S":this.style=te;break;case"D":this.style=ae;break;case"B":this.style=ne;break;case"I":this.style=se;break;case"U":this.style=re}}setDashArray(e,t=!1){if(Array.isArray(e)){let a=!0,n=!0;for(const t of e){if(!(+t>=0)){a=!1;break}t>0&&(n=!1)}if(0===e.length||a&&!n){this.dashArray=e;t&&this.setStyle(Name.get("D"))}else this.width=0}else e&&(this.width=0)}setHorizontalCornerRadius(e){Number.isInteger(e)&&(this.horizontalCornerRadius=e)}setVerticalCornerRadius(e){Number.isInteger(e)&&(this.verticalCornerRadius=e)}}class MarkupAnnotation extends Annotation{constructor(e){super(e);const{dict:t}=e;if(t.has("IRT")){const e=t.getRaw("IRT");this.data.inReplyTo=e instanceof Ref?e.toString():null;const a=t.get("RT");this.data.replyType=a instanceof Name?a.name:D}let a=null;if(this.data.replyType===H){const e=t.get("IRT");this.setTitle(e.get("T"));this.data.titleObj=this._title;this.setContents(e.get("Contents"));this.data.contentsObj=this._contents;if(e.has("CreationDate")){this.setCreationDate(e.get("CreationDate"));this.data.creationDate=this.creationDate}else this.data.creationDate=null;if(e.has("M")){this.setModificationDate(e.get("M"));this.data.modificationDate=this.modificationDate}else this.data.modificationDate=null;a=e.getRaw("Popup");if(e.has("C")){this.setColor(e.getArray("C"));this.data.color=this.color}else this.data.color=null}else{this.data.titleObj=this._title;this.setCreationDate(t.get("CreationDate"));this.data.creationDate=this.creationDate;a=t.getRaw("Popup");t.has("C")||(this.data.color=null)}this.data.popupRef=a instanceof Ref?a.toString():null;t.has("RC")&&(this.data.richText=XFAFactory.getRichTextAsHtml(t.get("RC")))}setCreationDate(e){this.creationDate="string"==typeof e?e:null}_setDefaultAppearance({xref:e,extra:a,strokeColor:n,fillColor:s,blendMode:r,strokeAlpha:i,fillAlpha:o,pointsCallback:l}){const f=this.data.rect=t.slice(),c=["q"];a&&c.push(a);n&&c.push(`${n[0]} ${n[1]} ${n[2]} RG`);s&&c.push(`${s[0]} ${s[1]} ${s[2]} rg`);const h=this.data.quadPoints||Float32Array.from([this.rectangle[0],this.rectangle[3],this.rectangle[2],this.rectangle[3],this.rectangle[0],this.rectangle[1],this.rectangle[2],this.rectangle[1]]);for(let e=0,t=h.length;ethis._decodeFormValue(e)).filter(e=>null!==e);return t.length>0?t:null}return e instanceof Name?e.name:"string"==typeof e?stringToPDFString(e):null}hasFieldFlag(e){return!!(this.data.fieldFlags&e)}_isViewable(e){return!0}mustBeViewed(e,t){return t?this.viewable:super.mustBeViewed(e,t)&&!this._hasFlag(this.flags,z)}getRotationMatrix(e){let t=e?.get(this.data.id)?.rotation;void 0===t&&(t=this.rotation);return 0===t?pa:getRotationMatrix(t,this.width,this.height)}getBorderAndBackgroundAppearances(e){let t=e?.get(this.data.id)?.rotation;void 0===t&&(t=this.rotation);if(!this.backgroundColor&&!this.borderColor)return"";const a=0===t||180===t?`0 0 ${this.width} ${this.height} re`:`0 0 ${this.height} ${this.width} re`;let n="";this.backgroundColor&&(n=`${getPdfColor(this.backgroundColor,!0)} ${a} f `);if(this.borderColor){n+=`${this.borderStyle.width||1} w ${getPdfColor(this.borderColor,!1)} ${a} S `}return n}async getOperatorList(e,t,a,n){if(a&h&&!(this instanceof SignatureWidgetAnnotation)&&!this.data.noHTML&&!this.data.hasOwnCanvas)return{opList:new OperatorList,separateForm:!0,separateCanvas:!1};if(!this._hasText)return super.getOperatorList(e,t,a,n);const s=await this._getAppearance(e,t,a,n);if(this.appearance&&null===s)return super.getOperatorList(e,t,a,n);const r=new OperatorList;if(!this._defaultAppearance||null===s)return{opList:r,separateForm:!1,separateCanvas:!1};const i=!!(this.data.hasOwnCanvas&&a&l),o=[0,0,this.width,this.height],f=getTransformMatrix(this.data.rect,o,[1,0,0,1,0,0]);let c;this.oc&&(c=await e.parseMarkedContentProps(this.oc,null));void 0!==c&&r.addOp(xt,["OC",c]);r.addOp(Bt,[this.data.id,this.data.rect,f,this.getRotationMatrix(n),i]);const u=new StringStream(s);await e.getOperatorList({stream:u,task:t,resources:this._fieldResources.mergedResources,operatorList:r});r.addOp(Dt,[]);void 0!==c&&r.addOp(Ct,[]);return{opList:r,separateForm:!1,separateCanvas:i}}_getMKDict(e){const t=new Dict(null);e&&t.set("R",e);t.setIfArray("BC",getPdfColorArray(this.borderColor));t.setIfArray("BG",getPdfColorArray(this.backgroundColor));return t.size>0?t:null}amendSavedDict(e,t){}setValue(e,t,a,n){const{dict:s,ref:r}=function getParentToUpdate(e,t,a){const n=new RefSet,s=e,r={dict:null,ref:null};for(;e instanceof Dict&&!n.has(t);){n.put(t);if(e.has("T"))break;if(!((t=e.getRaw("Parent"))instanceof Ref))return r;e=a.fetch(t)}if(e instanceof Dict&&e!==s){r.dict=e;r.ref=t}return r}(e,this.ref,a);if(s){if(!n.has(r)){const e=s.clone();e.set("V",t);n.put(r,{data:e});return e}}else e.set("V",t);return null}async save(e,t,a,n){const s=a?.get(this.data.id),r=this._buildFlags(s?.noView,s?.noPrint);let i=s?.value,o=s?.rotation;if(i===this.data.fieldValue||void 0===i){if(!this._hasValueFromXFA&&void 0===o&&void 0===r)return;i||=this.data.fieldValue}if(void 0===o&&!this._hasValueFromXFA&&Array.isArray(i)&&Array.isArray(this.data.fieldValue)&&isArrayEqual(i,this.data.fieldValue)&&void 0===r)return;void 0===o&&(o=this.rotation);let l=null;if(!this._needAppearances){l=await this._getAppearance(e,t,c,a);if(null===l&&void 0===r)return}let f=!1;if(l?.needAppearances){f=!0;l=null}const{xref:h}=e,u=h.fetchIfRef(this.ref);if(!(u instanceof Dict))return;const m=new Dict(h);for(const[e,t]of u.getRawEntries())"AP"!==e&&m.set(e,t);if(void 0!==r){m.set("F",r);if(null===l&&!f){const e=u.getRaw("AP");e&&m.set("AP",e)}}const p={path:this.data.fieldName,value:i},d=this.setValue(m,Array.isArray(i)?i.map(stringToAsciiOrUTF16BE):stringToAsciiOrUTF16BE(i),h,n);this.amendSavedDict(a,d||m);const g=this._getMKDict(o);g&&m.set("MK",g);n.put(this.ref,{data:m,xfa:p,needAppearances:f});if(null!==l){const e=h.getNewTemporaryRef(),t=new Dict(h);m.set("AP",t);t.set("N",e);const s=this._getSaveFieldResources(h),r=new StringStream(l),i=r.dict=new Dict(h);i.setIfName("Subtype","Form");i.set("Resources",s);const f=o%180==0?[0,0,this.width,this.height]:[0,0,this.height,this.width];i.set("BBox",f);const c=this.getRotationMatrix(a);c!==pa&&i.set("Matrix",c);n.put(e,{data:r,xfa:null,needAppearances:!1})}m.set("M",`D:${getModificationDate()}`)}async _getAppearance(e,t,a,n){if(this.data.password)return null;const s=n?.get(this.data.id);let r,o;if(s){r=s.formattedValue||s.value;o=s.rotation}if(void 0===o&&void 0===r&&!this._needAppearances&&(!this._hasValueFromXFA||this.appearance))return null;const l=this.getBorderAndBackgroundAppearances(n);if(void 0===r){r=this.data.fieldValue;if(!r)return`/Tx BMC q ${l}Q EMC`}Array.isArray(r)&&1===r.length&&(r=r[0]);assert("string"==typeof r,"Expected `value` to be a string.");r=r.trimEnd();if(this.data.combo){const e=this.data.options.find(({exportValue:e})=>r===e);r=e?.displayValue||r}if(""===r)return`/Tx BMC q ${l}Q EMC`;void 0===o&&(o=this.rotation);let f,h=-1;if(this.data.multiLine){f=r.split(/\r\n?|\n/).map(e=>e.normalize("NFC"));h=f.length}else f=[r.replace(/\r\n?|\n/,"").normalize("NFC")];let{width:u,height:m}=this;90!==o&&270!==o||([u,m]=[m,u]);this._defaultAppearance||(this.data.defaultAppearanceData=parseDefaultAppearance(this._defaultAppearance="/Helvetica 0 Tf 0 g"));let p,d,g,b=await WidgetAnnotation._getFontData(e,t,this.data.defaultAppearanceData,this._fieldResources.mergedResources);const w=[];let j=!1;for(const e of f){const t=b.encodeString(e);t.length>1&&(j=!0);w.push(t.join(""))}if(j&&a&c)return{needAppearances:!0};if(j&&this._isOffscreenCanvasSupported){const a=this.data.comb?"monospace":"sans-serif",n=new FakeUnicodeFont(e.xref,a),s=n.createFontResources(f.join("")),i=s.getRaw("Font");if(this._fieldResources.mergedResources.has("Font")){const e=this._fieldResources.mergedResources.get("Font");for(const[t,a]of i.getRawEntries())e.set(t,a)}else this._fieldResources.mergedResources.set("Font",i);const o=n.fontName.name;b=await WidgetAnnotation._getFontData(e,t,{fontName:o,fontSize:0},s);for(let e=0,t=w.length;e2)return`/Tx BMC q ${l}BT `+p+` 1 0 0 1 ${numberToString(2)} ${numberToString(v)} Tm (${escapeString(w[0])}) Tj ET Q EMC`;return`/Tx BMC q ${l}BT `+p+` 1 0 0 1 0 0 Tm ${this._renderText(w[0],b,d,u,q,{shift:0},2,v)} ET Q EMC`}static async _getFontData(e,t,a,n){const s=new OperatorList,r={font:null,clone(){return this}},{fontName:i,fontSize:o}=a;await e.handleSetFont(n,[i&&Name.get(i),o],null,s,t,r,null);return r.font}_getTextWidth(e,t){return Math.sumPrecise(t.charsToGlyphs(e).map(e=>e.width))/1e3}_computeFontSize(e,t,a,n,r){let{fontSize:i}=this.data.defaultAppearanceData,o=(i||12)*s,l=Math.round(e/o);if(!i){const roundWithTwoDigits=e=>Math.floor(100*e)/100;if(-1===r){const r=this._getTextWidth(a,n);i=roundWithTwoDigits(Math.min(e/s,t/r));l=1}else{const f=a.split(/\r\n?|\n/),c=[];for(const e of f){const t=n.encodeString(e).join(""),a=n.charsToGlyphs(t),s=n.getCharPositions(t);c.push({line:t,glyphs:a,positions:s})}const isTooBig=a=>{let s=0;for(const r of c){s+=this._splitLine(null,n,a,t,r).length*a;if(s>e)return!0}return!1};l=Math.max(l,r);for(;;){o=e/l;i=roundWithTwoDigits(o/s);if(!isTooBig(i))break;l++}}const{fontName:f,fontColor:c}=this.data.defaultAppearanceData;this._defaultAppearance=function createDefaultAppearance({fontSize:e,fontName:t,fontColor:a}){return`/${escapePDFName(t)} ${e} Tf ${getPdfColor(a,!0)}`}({fontSize:i,fontName:f,fontColor:c})}return[this._defaultAppearance,i,e/l]}_renderText(e,t,a,n,s,r,i,o){let l;if(1===s){l=(n-this._getTextWidth(e,t)*a)/2}else if(2===s){l=n-this._getTextWidth(e,t)*a-i}else l=i;const f=numberToString(l-r.shift);r.shift=l;return`${f} ${o=numberToString(o)} Td (${escapeString(e)}) Tj`}_getSaveFieldResources(e){const{localResources:t,appearanceResources:a,acroFormResources:n}=this._fieldResources,s=this.data.defaultAppearanceData?.fontName;if(!s)return t||Dict.empty;for(const e of[t,a])if(e instanceof Dict){const t=e.get("Font");if(t instanceof Dict&&t.has(s))return e}if(n instanceof Dict){const a=n.get("Font");if(a instanceof Dict&&a.has(s)){const n=new Dict(e);n.set(s,a.getRaw(s));const r=new Dict(e);r.set("Font",n);return Dict.merge({xref:e,dictArray:[r,t],mergeSubDicts:!0})}}return t||Dict.empty}getFieldObject(){return null}}class TextWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);const{dict:t}=e;if(t.has("PMD")){this.flags|=N;this.data.hidden=!0;warn("Barcodes are not supported")}this.data.hasOwnCanvas=this.data.readOnly&&!this.data.noHTML;this._hasText=!0;"string"!=typeof this.data.fieldValue&&(this.data.fieldValue="");let a=getInheritableProperty({dict:t,key:"Q"});(!Number.isInteger(a)||a<0||a>2)&&(a=null);this.data.textAlignment=a;let n=getInheritableProperty({dict:t,key:"MaxLen"});(!Number.isInteger(n)||n<0)&&(n=0);this.data.maxLen=n;this.data.multiLine=this.hasFieldFlag(K);this.data.comb=this.hasFieldFlag(ee)&&!this.data.multiLine&&!this.data.password&&!this.hasFieldFlag(J)&&0!==this.data.maxLen;this.data.doNotScroll=this.hasFieldFlag(Z);const{data:{actions:s}}=this;if(!s)return;const r=/^AF(Date|Time)_(?:Keystroke|Format)(?:Ex)?\(['"]?([^'"]+)['"]?\);$/;let i=!1;(1===s.Format?.length&&1===s.Keystroke?.length&&r.test(s.Format[0])&&r.test(s.Keystroke[0])||0===s.Format?.length&&1===s.Keystroke?.length&&r.test(s.Keystroke[0])||0===s.Keystroke?.length&&1===s.Format?.length&&r.test(s.Format[0]))&&(i=!0);const o=[];s.Format&&o.push(...s.Format);s.Keystroke&&o.push(...s.Keystroke);if(i){delete s.Keystroke;s.Format=o}for(const e of o){const t=e.match(r);if(!t)continue;const a="Date"===t[1];let n=t[2];const s=parseInt(n,10);isNaN(s)||Math.floor(Math.log10(s))+1!==t[2].length||(n=(a?Ri:Hi)[s]??n);this.data.datetimeFormat=n;if(!i)break;if(a){if(/HH|MM|ss|h/.test(n)){this.data.datetimeType="datetime-local";this.data.timeStep=/ss/.test(n)?1:60}else this.data.datetimeType="date";break}this.data.datetimeType="time";this.data.timeStep=/ss/.test(n)?1:60;break}}get hasTextContent(){return!!this.appearance&&!this._needAppearances}_getCombAppearance(e,t,a,n,s,r,i,o,l,f,c,h,u){const m=s/this.data.maxLen,p=this.getBorderAndBackgroundAppearances(u),d=[],g=t.getCharPositions(a);for(const[e,t]of g)d.push(`(${escapeString(a.substring(e,t))}) Tj`);h&&d.reverse();const b=m*g.length;let w=i;1===c?w+=Math.floor((s-b)/(2*m))*m:2===c&&(w+=s-b);const j=d.join(` ${numberToString(m)} 0 Td `);return`/Tx BMC q ${p}BT `+e+` 1 0 0 1 ${numberToString(w)} ${numberToString(o+l)} Tm ${j} ET Q EMC`}_getMultilineAppearance(e,t,a,n,s,r,i,o,l,f,c,h){const u=[],m=s-2*o,p={shift:0};for(let e=0,r=t.length;en){l.push(e.substring(u,a));u=a;m=d;f=-1;h=-1}else{m+=d;f=a;c=s;h=t}else if(m+d>n)if(-1!==f){l.push(e.substring(u,c));u=c;t=h+1;f=-1;m=0}else{l.push(e.substring(u,a));u=a;m=d}else m+=d}ut?`\\${t}`:"\\s+");new RegExp(`^\\s*${r}\\s*$`).test(this.data.fieldValue)&&(this.data.textContent=this.data.fieldValue.split("\n"))}getFieldObject(){return{id:this.data.id,value:this.data.fieldValue,defaultValue:this.data.defaultFieldValue||"",multiline:this.data.multiLine,password:this.data.password,charLimit:this.data.maxLen,comb:this.data.comb,editable:!this.data.readOnly,hidden:this.data.hidden,name:this.data.fieldName,rect:this.data.rect,actions:this.data.actions,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,datetimeFormat:this.data.datetimeFormat,hasDatetimeHTML:!!this.data.datetimeType,type:"text"}}}class ButtonWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);this.checkedAppearance=null;this.uncheckedAppearance=null;const t=this.hasFieldFlag(V),a=this.hasFieldFlag($);this.data.checkBox=!t&&!a;this.data.radioButton=t&&!a;this.data.pushButton=a;this.data.isTooltipOnly=!1;if(this.data.checkBox)this._processCheckBox(e);else if(this.data.radioButton)this._processRadioButton(e);else if(this.data.pushButton){this.data.hasOwnCanvas=!0;this.data.noHTML=!1;this._processPushButton(e)}else warn("Invalid field flags for button widget annotation")}async getOperatorList(e,t,a,n){if(this.data.pushButton)return super.getOperatorList(e,t,a,!1,n);let s=null,r=null;if(n){const e=n.get(this.data.id);s=e?e.value:null;r=e?e.rotation:null}if(null===s&&this.appearance)return super.getOperatorList(e,t,a,n);null==s&&(s=this.data.checkBox?this.data.fieldValue===this.data.exportValue:this.data.fieldValue===this.data.buttonValue);const i=s?this.checkedAppearance:this.uncheckedAppearance;if(i){const s=this.appearance,o=lookupMatrix(i.dict.getArray("Matrix"),pa);r&&i.dict.set("Matrix",this.getRotationMatrix(n));this.appearance=i;const l=super.getOperatorList(e,t,a,n);this.appearance=s;i.dict.set("Matrix",o);return l}return{opList:new OperatorList,separateForm:!1,separateCanvas:!1}}async save(e,t,a,n){this.data.checkBox?this._saveCheckbox(e,t,a,n):this.data.radioButton&&this._saveRadioButton(e,t,a,n)}async _saveCheckbox(e,t,a,n){if(!a)return;const s=a.get(this.data.id),r=this._buildFlags(s?.noView,s?.noPrint);let i=s?.rotation,o=s?.value;if(void 0===i&&void 0===r){if(void 0===o)return;if(this.data.fieldValue===this.data.exportValue===o)return}let l=e.xref.fetchIfRef(this.ref);if(!(l instanceof Dict))return;l=l.clone();void 0===i&&(i=this.rotation);void 0===o&&(o=this.data.fieldValue===this.data.exportValue);const f={path:this.data.fieldName,value:o?this.data.exportValue:""},c=Name.get(o?this.data.exportValue:"Off");this.setValue(l,c,e.xref,n);l.set("AS",c);l.set("M",`D:${getModificationDate()}`);void 0!==r&&l.set("F",r);const h=this._getMKDict(i);h&&l.set("MK",h);n.put(this.ref,{data:l,xfa:f,needAppearances:!1})}async _saveRadioButton(e,t,a,n){if(!a)return;const s=a.get(this.data.id),r=this._buildFlags(s?.noView,s?.noPrint);let i=s?.rotation,o=s?.value;if(void 0===i&&void 0===r){if(void 0===o)return;if(this.data.fieldValue===this.data.buttonValue===o)return}let l=e.xref.fetchIfRef(this.ref);if(!(l instanceof Dict))return;l=l.clone();void 0===o&&(o=this.data.fieldValue===this.data.buttonValue);void 0===i&&(i=this.rotation);const f={path:this.data.fieldName,value:o?this.data.buttonValue:""},c=Name.get(o?this.data.buttonValue:"Off");o&&this.setValue(l,c,e.xref,n);l.set("AS",c);l.set("M",`D:${getModificationDate()}`);void 0!==r&&l.set("F",r);const h=this._getMKDict(i);h&&l.set("MK",h);n.put(this.ref,{data:l,xfa:f,needAppearances:!1})}_getDefaultCheckedAppearance(e,t){const{width:a,height:n}=this,s=[0,0,a,n],r=.8*Math.min(a,n);let i,o;if("check"===t){i={width:.755*r,height:.705*r};o="3"}else if("disc"===t){i={width:.791*r,height:.705*r};o="l"}else unreachable(`_getDefaultCheckedAppearance - unsupported type: ${t}`);const l=`q BT /PdfJsZaDb ${r} Tf 0 g ${numberToString((a-i.width)/2)} ${numberToString((n-i.height)/2)} Td (${o}) Tj ET Q`,f=new Dict(e.xref);f.set("FormType",1);f.setIfName("Subtype","Form");f.setIfName("Type","XObject");f.set("BBox",s);f.set("Matrix",[1,0,0,1,0,0]);f.set("Length",l.length);const c=new Dict(e.xref),h=new Dict(e.xref);h.set("PdfJsZaDb",this.fallbackFontDict);c.set("Font",h);f.set("Resources",c);this.checkedAppearance=new StringStream(l);this.checkedAppearance.dict=f;this._streams.push(this.checkedAppearance)}_processCheckBox(e){const t=e.dict.get("AP");if(!(t instanceof Dict))return;const a=t.get("N");if(!(a instanceof Dict))return;const n=this._decodeFormValue(e.dict.get("AS"));"string"==typeof n&&(this.data.fieldValue=n);const s=null!==this.data.fieldValue&&"Off"!==this.data.fieldValue?this.data.fieldValue:"Yes",r=[...a.getKeys()];if(0===r.length)r.push("Off",s);else if(1===r.length)"Off"===r[0]?r.push(s):r.unshift("Off");else if(r.includes(s)){r.length=0;r.push("Off",s)}else{const e=r.find(e=>"Off"!==e);r.length=0;r.push("Off",e)}r.includes(this.data.fieldValue)||(this.data.fieldValue="Off");this.data.exportValue=r[1];const i=a.get(this.data.exportValue);this.checkedAppearance=i instanceof BaseStream?i:null;const o=a.get("Off");this.uncheckedAppearance=o instanceof BaseStream?o:null;this.checkedAppearance?this._streams.push(this.checkedAppearance):this._getDefaultCheckedAppearance(e,"check");this.uncheckedAppearance&&this._streams.push(this.uncheckedAppearance);this._fallbackFontDict=this.fallbackFontDict;null===this.data.defaultFieldValue&&(this.data.defaultFieldValue="Off")}_processRadioButton(e){this.data.buttonValue=null;const t=e.dict.get("Parent");if(t instanceof Dict){this.parent=e.dict.getRaw("Parent");const a=t.get("V");a instanceof Name&&(this.data.fieldValue=this._decodeFormValue(a))}const a=e.dict.get("AP");if(!(a instanceof Dict))return;const n=a.get("N");if(!(n instanceof Dict))return;for(const e of n.getKeys())if("Off"!==e){this.data.buttonValue=e;break}const s=n.get(this.data.buttonValue);this.checkedAppearance=s instanceof BaseStream?s:null;const r=n.get("Off");this.uncheckedAppearance=r instanceof BaseStream?r:null;this.checkedAppearance?this._streams.push(this.checkedAppearance):this._getDefaultCheckedAppearance(e,"disc");this.uncheckedAppearance&&this._streams.push(this.uncheckedAppearance);this._fallbackFontDict=this.fallbackFontDict;null===this.data.defaultFieldValue&&(this.data.defaultFieldValue="Off")}_processPushButton(e){const{dict:t,annotationGlobals:a}=e;if(t.has("A")||t.has("AA")||this.data.alternativeText){this.data.isTooltipOnly=!t.has("A")&&!t.has("AA");Catalog.parseDestDictionary({destDict:t,resultObj:this.data,docBaseUrl:a.baseUrl,docAttachments:a.attachments})}else warn("Push buttons without action dictionaries are not supported")}getFieldObject(){let e,t="button";if(this.data.checkBox){t="checkbox";e=this.data.exportValue}else if(this.data.radioButton){t="radiobutton";e=this.data.buttonValue}return{id:this.data.id,value:this.data.fieldValue||"Off",defaultValue:this.data.defaultFieldValue,exportValues:e,editable:!this.data.readOnly,name:this.data.fieldName,rect:this.data.rect,hidden:this.data.hidden,actions:this.data.actions,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,type:t}}get fallbackFontDict(){const e=new Dict;e.setIfName("BaseFont","ZapfDingbats");e.setIfName("Type","FallbackType");e.setIfName("Subtype","FallbackType");e.setIfName("Encoding","ZapfDingbatsEncoding");return shadow(this,"fallbackFontDict",e)}}class ChoiceWidgetAnnotation extends WidgetAnnotation{constructor(e){super(e);const{dict:t,xref:a}=e;this.indices=t.getArray("I");this.hasIndices=Array.isArray(this.indices)&&this.indices.length>0;this.data.options=[];const n=getInheritableProperty({dict:t,key:"Opt"});if(Array.isArray(n))for(let e=0,t=n.length;e=0&&t0&&(this.data.options=this.data.fieldValue.map(e=>({exportValue:e,displayValue:e})));this.data.combo=this.hasFieldFlag(Y);this.data.multiSelect=this.hasFieldFlag(Q);this._hasText=!0}getFieldObject(){const e=this.data.combo?"combobox":"listbox",t=this.data.fieldValue.length>0?this.data.fieldValue[0]:null;return{id:this.data.id,value:t,defaultValue:this.data.defaultFieldValue,editable:!this.data.readOnly,name:this.data.fieldName,rect:this.data.rect,numItems:this.data.fieldValue.length,multipleSelection:this.data.multiSelect,hidden:this.data.hidden,actions:this.data.actions,items:this.data.options,page:this.data.pageIndex,strokeColor:this.data.borderColor,fillColor:this.data.backgroundColor,rotation:this.rotation,type:e}}amendSavedDict(e,t){if(!this.hasIndices)return;let a=e?.get(this.data.id)?.value;Array.isArray(a)||(a=[a]);const n=[],{options:s}=this.data;for(let e=0,t=0,r=s.length;ea){a=n;t=e}}[m,p]=this._computeFontSize(e,l-4,t,u,-1)}const d=p*s,g=(d-p)/2,b=Math.floor(f/d);let w=0;if(h.length>0){const e=Math.min(...h),t=Math.max(...h);w=Math.max(0,t-b+1);w>e&&(w=e)}const j=Math.min(w+b+1,c),k=["/Tx BMC q",`1 1 ${l} ${f} re W n`];if(h.length){k.push("0.600006 0.756866 0.854904 rg");for(const e of h)w<=e&&ee.trimEnd());const{coords:e,bbox:t,matrix:a}=FakeUnicodeFont.getFirstPositionInfo(this.rectangle,this.rotation,n);this.data.textPosition=this._transformPoint(e,t,a)}if(this._isOffscreenCanvasSupported){const s=e.dict.get("CA"),r=new FakeUnicodeFont(a,"sans-serif");this.appearance=r.createAppearance(this._contents.str,this.rectangle,this.rotation,n,t,s);this._streams.push(this.appearance)}else warn("FreeTextAnnotation: OffscreenCanvas is not supported, annotation may not render correctly.")}}get hasTextContent(){return this._hasAppearance}static createNewDict(e,t,{apRef:a,ap:n}){const{color:s,date:r,fontSize:i,oldAnnotation:o,rect:l,rotation:f,user:c,value:h}=e,u=o||new Dict(t);u.setIfNotExists("Type",Name.get("Annot"));u.setIfNotExists("Subtype",Name.get("FreeText"));u.set(o?"M":"CreationDate",`D:${getModificationDate(r)}`);o&&u.delete("RC");u.setIfArray("Rect",l);const m=`/Helv ${i} Tf ${getPdfColor(s,!0)}`;u.set("DA",m);u.setIfDefined("Contents",stringToAsciiOrUTF16BE(h));u.setIfNotExists("F",4);u.setIfNotExists("Border",[0,0,0]);u.setIfNumber("Rotate",f);u.setIfDefined("T",stringToAsciiOrUTF16BE(c));if(a||n){const e=new Dict(t);u.set("AP",e);e.set("N",a||n)}return u}static async createNewAppearanceStream(e,t,a){const{baseFontRef:n,evaluator:r,task:i}=a,{color:o,fontSize:l,rect:f,rotation:c,value:h}=e;if(!o)return null;const u=new Dict(t),m=new Dict(t);if(n)m.set("Helv",n);else{const e=new Dict(t);e.setIfName("BaseFont","Helvetica");e.setIfName("Type","Font");e.setIfName("Subtype","Type1");e.setIfName("Encoding","WinAnsiEncoding");m.set("Helv",e)}u.set("Font",m);const p=await WidgetAnnotation._getFontData(r,i,{fontName:"Helv",fontSize:l},u),[d,g,b,w]=f;let j=b-d,k=w-g;c%180!=0&&([j,k]=[k,j]);const y=h.split("\n"),q=l/1e3;let v=-1/0;const S=[];for(let e of y){const t=p.encodeString(e);if(t.length>1)return null;e=t.join("");S.push(e);let a=0;const n=p.charsToGlyphs(e);for(const e of n)a+=e.width*q;v=Math.max(v,a)}let x=1;v>j&&(x=j/v);let C=1;const F=s*l,T=1*l,O=F*y.length;O>k&&(C=k/O);const R=l*Math.min(x,C);let H,D,M;switch(c){case 0:M=[1,0,0,1];D=[f[0],f[1],j,k];H=[f[0],f[3]-T];break;case 90:M=[0,1,-1,0];D=[f[1],-f[2],j,k];H=[f[1],-f[0]-T];break;case 180:M=[-1,0,0,-1];D=[-f[2],-f[3],j,k];H=[-f[2],-f[1]-T];break;case 270:M=[0,-1,1,0];D=[-f[3],f[0],j,k];H=[-f[3],f[2]-T]}const N=["q",`${M.join(" ")} 0 0 cm`,`${D.join(" ")} re W n`,"BT",`${getPdfColor(o,!0)}`,`0 Tc /Helv ${numberToString(R)} Tf`];N.push(`${H.join(" ")} Td (${escapeString(S[0])}) Tj`);const E=numberToString(F);for(let e=1,t=S.length;e{e.push(`${n[0]} ${n[1]} m`,`${n[2]} ${n[3]} l`,"S");return[t[0]-o,t[7]-o,t[2]+o,t[3]+o]}})}}}class SquareAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:a}=e;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;if(!this.appearance){const e=getPdfColorArray(this.color,[0,0,0]),n=t.get("CA"),s=getPdfColorArray(getRgbColor(t.getArray("IC"),null)),r=s?n:null;if(0===this.borderStyle.width&&!s)return;this._setDefaultAppearance({xref:a,extra:`${this.borderStyle.width} w`,strokeColor:e,fillColor:s,strokeAlpha:n,fillAlpha:r,pointsCallback:(e,t)=>{const a=t[4]+this.borderStyle.width/2,n=t[5]+this.borderStyle.width/2,r=t[6]-t[4]-this.borderStyle.width,i=t[3]-t[7]-this.borderStyle.width;e.push(`${a} ${n} ${r} ${i} re`);s?e.push("B"):e.push("S");return[t[0],t[7],t[2],t[3]]}})}}}class CircleAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:a}=e;if(!this.appearance){const e=getPdfColorArray(this.color,[0,0,0]),n=t.get("CA"),s=getPdfColorArray(getRgbColor(t.getArray("IC"),null)),r=s?n:null;if(0===this.borderStyle.width&&!s)return;const i=4/3*Math.tan(Math.PI/8);this._setDefaultAppearance({xref:a,extra:`${this.borderStyle.width} w`,strokeColor:e,fillColor:s,strokeAlpha:n,fillAlpha:r,pointsCallback:(e,t)=>{const a=t[0]+this.borderStyle.width/2,n=t[1]-this.borderStyle.width/2,r=t[6]-this.borderStyle.width/2,o=t[7]+this.borderStyle.width/2,l=a+(r-a)/2,f=n+(o-n)/2,c=(r-a)/2*i,h=(o-n)/2*i;e.push(`${l} ${o} m`,`${l+c} ${o} ${r} ${f+h} ${r} ${f} c`,`${r} ${f-h} ${l+c} ${n} ${l} ${n} c`,`${l-c} ${n} ${a} ${f-h} ${a} ${f} c`,`${a} ${f+h} ${l-c} ${o} ${l} ${o} c`,"h");s?e.push("B"):e.push("S");return[t[0],t[7],t[2],t[3]]}})}}}class PolylineAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:a,xref:n}=e;this.data.hasOwnCanvas=this.data.noRotate;this.data.noHTML=!1;this.data.vertices=null;if(!(this instanceof PolygonAnnotation)){this.setLineEndings(a.getArray("LE"));this.data.lineEndings=this.lineEndings}const s=a.getArray("Vertices");if(!isNumberArray(s,null))return;const r=this.data.vertices=Float32Array.from(s);if(!this.appearance){const e=getPdfColorArray(this.color,[0,0,0]),s=a.get("CA");let i,o=getRgbColor(a.getArray("IC"),null);o&&(o=getPdfColorArray(o));i=o?this.color?o.every((t,a)=>t===e[a])?"f":"B":"f":"S";const l=this.borderStyle.width||1,f=2*l,c=t.slice();for(let e=0,t=r.length;e{for(let t=0,a=r.length;t{for(const t of this.data.inkLists){for(let a=0,n=t.length;a0){const e=new Dict(t);p.set("BS",e);e.set("W",u)}p.setIfArray("C",getPdfColorArray(r));p.setIfNumber("CA",o);if(n||a){const e=new Dict(t);p.set("AP",e);e.set("N",a||n)}return p}static async createNewAppearanceStream(e,t,a){if(e.outlines)return this.createNewAppearanceStreamForHighlight(e,t,a);const{color:n,rect:s,paths:r,thickness:i,opacity:o}=e;if(!n)return null;const l=[`${i} w 1 J 1 j`,`${getPdfColor(n,!1)}`];1!==o&&l.push("/R0 gs");for(const e of r.lines){l.push(`${numberToString(e[4])} ${numberToString(e[5])} m`);for(let t=6,a=e.length;t{e.push(`${t[0]} ${t[1]} m`,`${t[2]} ${t[3]} l`,`${t[6]} ${t[7]} l`,`${t[4]} ${t[5]} l`,"f");return[t[0],t[7],t[2],t[3]]}})}}else this.data.popupRef=null}get overlaysTextContent(){return!0}static createNewDict(e,t,{apRef:a,ap:n}){const{color:s,date:r,oldAnnotation:i,opacity:o,rect:l,rotation:f,user:c,quadPoints:h}=e,u=i||new Dict(t);u.setIfNotExists("Type",Name.get("Annot"));u.setIfNotExists("Subtype",Name.get("Highlight"));u.set(i?"M":"CreationDate",`D:${getModificationDate(r)}`);u.setIfArray("Rect",l);u.setIfNotExists("F",4);u.setIfNotExists("Border",[0,0,0]);u.setIfNumber("Rotate",f);u.setIfArray("QuadPoints",h);u.setIfArray("C",getPdfColorArray(s));u.setIfNumber("CA",o);u.setIfDefined("T",stringToAsciiOrUTF16BE(c));if(a||n){const e=new Dict(t);u.set("AP",e);e.set("N",a||n)}return u}static async createNewAppearanceStream(e,t,a){const{color:n,rect:s,outlines:r,opacity:i}=e;if(!n)return null;const o=[`${getPdfColor(n,!0)}`,"/R0 gs"],l=[];for(const e of r){l.length=0;l.push(`${numberToString(e[0])} ${numberToString(e[1])} m`);for(let t=2,a=e.length;t{e.push(`${t[4]} ${t[5]+1.3} m`,`${t[6]} ${t[7]+1.3} l`,"S");return[t[0],t[7],t[2],t[3]]}})}}else this.data.popupRef=null}get overlaysTextContent(){return!0}}class SquigglyAnnotation extends MarkupAnnotation{constructor(e){super(e);const{dict:t,xref:a}=e;if(this.data.quadPoints=getQuadPoints(t,null)){if(!this.appearance){const e=getPdfColorArray(this.color,[0,0,0]),n=t.get("CA");this._setDefaultAppearance({xref:a,extra:"[] 0 d 1 w",strokeColor:e,strokeAlpha:n,pointsCallback:(e,t)=>{const a=(t[1]-t[5])/6;let n=a,s=t[4];const r=t[5],i=t[6];e.push(`${s} ${r+n} m`);do{s+=2;n=0===n?a:0;e.push(`${s} ${r+n} l`)}while(s{e.push((t[0]+t[4])/2+" "+(t[1]+t[5])/2+" m",(t[2]+t[6])/2+" "+(t[3]+t[7])/2+" l","S");return[t[0],t[7],t[2],t[3]]}})}}else this.data.popupRef=null}get overlaysTextContent(){return!0}}class StampAnnotation extends MarkupAnnotation{#ot=null;constructor(e){super(e);this.data.hasOwnCanvas=this.data.noRotate;this.data.isEditable=!this.data.noHTML;this.data.noHTML=!1}mustBeViewedWhenEditing(e,t=null){if(e){if(!this.data.isEditable)return!0;this.#ot??=this.data.hasOwnCanvas;this.data.hasOwnCanvas=!0;return!0}if(null!==this.#ot){this.data.hasOwnCanvas=this.#ot;this.#ot=null}return!t?.has(this.data.id)}static async createImage(e,t){const{width:a,height:n}=e,s=new OffscreenCanvas(a,n),r=s.getContext("2d",{alpha:!0});r.drawImage(e,0,0);const i=r.getImageData(0,0,a,n).data,o=new Uint32Array(i.buffer),l=o.some(FeatureTest.isLittleEndian?e=>e>>>24!=255:e=>!!(255&~e));if(l){r.fillStyle="white";r.fillRect(0,0,a,n);r.drawImage(e,0,0)}const f=s.convertToBlob({type:"image/jpeg",quality:1}).then(e=>e.bytes()),c=Name.get("XObject"),h=Name.get("Image"),u=new Dict(t);u.set("Type",c);u.set("Subtype",h);u.set("BitsPerComponent",8);u.setIfName("ColorSpace","DeviceRGB");u.setIfName("Filter","DCTDecode");u.set("BBox",[0,0,a,n]);u.set("Width",a);u.set("Height",n);let m=null;if(l){const e=new Uint8Array(o.length);if(FeatureTest.isLittleEndian)for(let t=0,a=o.length;t>>24;else for(let t=0,a=o.length;t=0&&s<=1?s:null}}const df={get r(){return shadow(this,"r",new Uint8Array([7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21]))},get k(){return shadow(this,"k",new Int32Array([-680876936,-389564586,606105819,-1044525330,-176418897,1200080426,-1473231341,-45705983,1770035416,-1958414417,-42063,-1990404162,1804603682,-40341101,-1502002290,1236535329,-165796510,-1069501632,643717713,-373897302,-701558691,38016083,-660478335,-405537848,568446438,-1019803690,-187363961,1163531501,-1444681467,-51403784,1735328473,-1926607734,-378558,-2022574463,1839030562,-35309556,-1530992060,1272893353,-155497632,-1094730640,681279174,-358537222,-722521979,76029189,-640364487,-421815835,530742520,-995338651,-198630844,1126891415,-1416354905,-57434055,1700485571,-1894986606,-1051523,-2054922799,1873313359,-30611744,-1560198380,1309151649,-145523070,-1120210379,718787259,-343485551]))}};function calculateMD5(e,t,a){let n=1732584193,s=-271733879,r=-1732584194,i=271733878;const o=a+72&-64,l=new Uint8Array(o);let f,c;for(f=0;f>5&255;l[f++]=a>>13&255;l[f++]=a>>21&255;l[f++]=a>>>29&255;f+=3;const u=new Int32Array(16),{k:m,r:p}=df;for(f=0;f>>32-r)|0;a=n}n=n+a|0;s=s+o|0;r=r+h|0;i=i+d|0}return new Uint8Array([255&n,n>>8&255,n>>16&255,n>>>24&255,255&s,s>>8&255,s>>16&255,s>>>24&255,255&r,r>>8&255,r>>16&255,r>>>24&255,255&i,i>>8&255,i>>16&255,i>>>24&255])}function decodeString(e){try{return stringToUTF8String(e)}catch(t){warn(`UTF-8 decoding failed: "${t}".`);return e}}class DatasetXMLParser extends SimpleXMLParser{node=null;onEndElement(e){const t=super.onEndElement(e);if(t&&"xfa:datasets"===e){this.node=t;throw new Error("Aborting DatasetXMLParser.")}}}class DatasetReader{constructor(e){if(e.datasets)this.node=new SimpleXMLParser({hasAttributes:!0}).parseFromString(e.datasets).documentElement;else{const t=new DatasetXMLParser({hasAttributes:!0});try{t.parseFromString(e["xdp:xdp"])}catch{}this.node=t.node}}getValue(e){if(!this.node||!e)return"";const t=this.node.searchNode(parseXFAPath(e),0);if(!t)return"";const a=t.firstChild;return"value"===a?.nodeName?t.children.map(e=>decodeString(e.textContent)):decodeString(t.textContent)}}class SingleIntersector{#ft;minX=1/0;minY=1/0;maxX=-1/0;maxY=-1/0;#ct=null;#ht=[];#ut=[];#mt=-1;#pt=!1;constructor(e){this.#ft=e;const t=e.data.quadPoints;if(t){for(let e=0,a=t.length;e8&&(this.#ct=t)}else[this.minX,this.minY,this.maxX,this.maxY]=e.data.rect}#dt(e,t){if(this.minX>=e||this.maxX<=e||this.minY>=t||this.maxY<=t)return!1;const a=this.#ct;if(!a)return!0;if(this.#mt>=0){const n=this.#mt;if(!(a[n]>=e||a[n+2]<=e||a[n+5]>=t||a[n+1]<=t))return!0;this.#mt=-1}for(let n=0,s=a.length;n=e||a[n+2]<=e||a[n+5]>=t||a[n+1]<=t)){this.#mt=n;return!0}return!1}addGlyph(e,t,a){if(!this.#dt(e,t)){this.disableExtraChars();return!1}if(this.#ut.length>0){this.#ht.push(this.#ut.join(""));this.#ut.length=0}this.#ht.push(a);this.#pt=!0;return!0}addExtraChar(e){this.#pt&&this.#ut.push(e)}disableExtraChars(){if(this.#pt){this.#pt=!1;this.#ut.length=0}}setText(){this.#ft.data.overlaidText=this.#ht.join("")}}const gf=64;class Intersector{#gt=[];#bt=[];#wt;#jt;#kt;#yt;#qt;#vt;constructor(e){let t=1/0,a=1/0,n=-1/0,s=-1/0;const r=this.#gt;for(const i of e){if(!i.data.quadPoints&&!i.data.rect)continue;const e=new SingleIntersector(i);r.push(e);t=Math.min(t,e.minX);a=Math.min(a,e.minY);n=Math.max(n,e.maxX);s=Math.max(s,e.maxY)}this.#wt=t;this.#kt=a;this.#jt=n;this.#yt=s;this.#qt=63/(n-t);this.#vt=63/(s-a);for(const e of r){const t=this.#St(e.minX,e.minY),a=this.#St(e.maxX,e.maxY),n=(a-t)%gf,s=Math.floor((a-t)/gf);for(let a=t;a<=t+s*gf;a+=gf)for(let t=0;t<=n;t++){let n=this.#bt[a+t];n||(this.#bt[a+t]=n=[]);n.push(e)}}}#St(e,t){return Math.floor((e-this.#wt)*this.#qt)+Math.floor((t-this.#kt)*this.#vt)*gf}addGlyph(e,t,a,n){const s=e[4]+t/2,r=e[5]+a/2;if(sthis.#jt||r>this.#yt)return;const i=this.#bt[this.#St(s,r)];if(i)for(const e of i)e.addGlyph(s,r,n)}addExtraChar(e){for(const t of this.#gt)t.addExtraChar(e)}setText(){for(const e of this.#gt)e.setText()}}class Word64{constructor(e,t){this.high=0|e;this.low=0|t}and(e){this.high&=e.high;this.low&=e.low}xor(e){this.high^=e.high;this.low^=e.low}shiftRight(e){if(e>=32){this.low=this.high>>>e-32|0;this.high=0}else{this.low=this.low>>>e|this.high<<32-e;this.high=this.high>>>e|0}}rotateRight(e){let t,a;if(32&e){a=this.low;t=this.high}else{t=this.low;a=this.high}e&=31;this.low=t>>>e|a<<32-e;this.high=a>>>e|t<<32-e}not(){this.high=~this.high;this.low=~this.low}add(e){const t=(this.low>>>0)+(e.low>>>0);let a=(this.high>>>0)+(e.high>>>0);t>4294967295&&(a+=1);this.low=0|t;this.high=0|a}copyTo(e,t){e[t]=this.high>>>24&255;e[t+1]=this.high>>16&255;e[t+2]=this.high>>8&255;e[t+3]=255&this.high;e[t+4]=this.low>>>24&255;e[t+5]=this.low>>16&255;e[t+6]=this.low>>8&255;e[t+7]=255&this.low}assign(e){this.high=e.high;this.low=e.low}}const bf={get k(){return shadow(this,"k",[new Word64(1116352408,3609767458),new Word64(1899447441,602891725),new Word64(3049323471,3964484399),new Word64(3921009573,2173295548),new Word64(961987163,4081628472),new Word64(1508970993,3053834265),new Word64(2453635748,2937671579),new Word64(2870763221,3664609560),new Word64(3624381080,2734883394),new Word64(310598401,1164996542),new Word64(607225278,1323610764),new Word64(1426881987,3590304994),new Word64(1925078388,4068182383),new Word64(2162078206,991336113),new Word64(2614888103,633803317),new Word64(3248222580,3479774868),new Word64(3835390401,2666613458),new Word64(4022224774,944711139),new Word64(264347078,2341262773),new Word64(604807628,2007800933),new Word64(770255983,1495990901),new Word64(1249150122,1856431235),new Word64(1555081692,3175218132),new Word64(1996064986,2198950837),new Word64(2554220882,3999719339),new Word64(2821834349,766784016),new Word64(2952996808,2566594879),new Word64(3210313671,3203337956),new Word64(3336571891,1034457026),new Word64(3584528711,2466948901),new Word64(113926993,3758326383),new Word64(338241895,168717936),new Word64(666307205,1188179964),new Word64(773529912,1546045734),new Word64(1294757372,1522805485),new Word64(1396182291,2643833823),new Word64(1695183700,2343527390),new Word64(1986661051,1014477480),new Word64(2177026350,1206759142),new Word64(2456956037,344077627),new Word64(2730485921,1290863460),new Word64(2820302411,3158454273),new Word64(3259730800,3505952657),new Word64(3345764771,106217008),new Word64(3516065817,3606008344),new Word64(3600352804,1432725776),new Word64(4094571909,1467031594),new Word64(275423344,851169720),new Word64(430227734,3100823752),new Word64(506948616,1363258195),new Word64(659060556,3750685593),new Word64(883997877,3785050280),new Word64(958139571,3318307427),new Word64(1322822218,3812723403),new Word64(1537002063,2003034995),new Word64(1747873779,3602036899),new Word64(1955562222,1575990012),new Word64(2024104815,1125592928),new Word64(2227730452,2716904306),new Word64(2361852424,442776044),new Word64(2428436474,593698344),new Word64(2756734187,3733110249),new Word64(3204031479,2999351573),new Word64(3329325298,3815920427),new Word64(3391569614,3928383900),new Word64(3515267271,566280711),new Word64(3940187606,3454069534),new Word64(4118630271,4000239992),new Word64(116418474,1914138554),new Word64(174292421,2731055270),new Word64(289380356,3203993006),new Word64(460393269,320620315),new Word64(685471733,587496836),new Word64(852142971,1086792851),new Word64(1017036298,365543100),new Word64(1126000580,2618297676),new Word64(1288033470,3409855158),new Word64(1501505948,4234509866),new Word64(1607167915,987167468),new Word64(1816402316,1246189591)])}};function ch(e,t,a,n,s){e.assign(t);e.and(a);s.assign(t);s.not();s.and(n);e.xor(s)}function maj(e,t,a,n,s){e.assign(t);e.and(a);s.assign(t);s.and(n);e.xor(s);s.assign(a);s.and(n);e.xor(s)}function sigma(e,t,a){e.assign(t);e.rotateRight(28);a.assign(t);a.rotateRight(34);e.xor(a);a.assign(t);a.rotateRight(39);e.xor(a)}function sigmaPrime(e,t,a){e.assign(t);e.rotateRight(14);a.assign(t);a.rotateRight(18);e.xor(a);a.assign(t);a.rotateRight(41);e.xor(a)}function littleSigma(e,t,a){e.assign(t);e.rotateRight(1);a.assign(t);a.rotateRight(8);e.xor(a);a.assign(t);a.shiftRight(7);e.xor(a)}function littleSigmaPrime(e,t,a){e.assign(t);e.rotateRight(19);a.assign(t);a.rotateRight(61);e.xor(a);a.assign(t);a.shiftRight(6);e.xor(a)}function calculateSHA512(e,t,a,n=!1){let s,r,i,o,l,f,c,h;if(n){s=new Word64(3418070365,3238371032);r=new Word64(1654270250,914150663);i=new Word64(2438529370,812702999);o=new Word64(355462360,4144912697);l=new Word64(1731405415,4290775857);f=new Word64(2394180231,1750603025);c=new Word64(3675008525,1694076839);h=new Word64(1203062813,3204075428)}else{s=new Word64(1779033703,4089235720);r=new Word64(3144134277,2227873595);i=new Word64(1013904242,4271175723);o=new Word64(2773480762,1595750129);l=new Word64(1359893119,2917565137);f=new Word64(2600822924,725511199);c=new Word64(528734635,4215389547);h=new Word64(1541459225,327033209)}const u=128*Math.ceil((a+17)/128),m=new Uint8Array(u);let p,d;for(p=0;p>>29&255;m[p++]=a>>21&255;m[p++]=a>>13&255;m[p++]=a>>5&255;m[p++]=a<<3&255;const b=new Array(80);for(p=0;p<80;p++)b[p]=new Word64(0,0);const{k:w}=bf;let j=new Word64(0,0),k=new Word64(0,0),y=new Word64(0,0),q=new Word64(0,0),v=new Word64(0,0),S=new Word64(0,0),x=new Word64(0,0),C=new Word64(0,0);const F=new Word64(0,0),T=new Word64(0,0),O=new Word64(0,0),R=new Word64(0,0);let H,D;for(p=0;p>>t|e<<32-t}function calculate_sha256_ch(e,t,a){return e&t^~e&a}function calculate_sha256_maj(e,t,a){return e&t^e&a^t&a}function calculate_sha256_sigma(e){return rotr(e,2)^rotr(e,13)^rotr(e,22)}function calculate_sha256_sigmaPrime(e){return rotr(e,6)^rotr(e,11)^rotr(e,25)}function calculate_sha256_littleSigma(e){return rotr(e,7)^rotr(e,18)^e>>>3}function calculate_sha256_littleSigmaPrime(e){return rotr(e,17)^rotr(e,19)^e>>>10}function calculateSHA256(e,t,a){let n=1779033703,s=3144134277,r=1013904242,i=2773480762,o=1359893119,l=2600822924,f=528734635,c=1541459225;const h=64*Math.ceil((a+9)/64),u=new Uint8Array(h);let m,p;for(m=0;m>>29&255;u[m++]=a>>21&255;u[m++]=a>>13&255;u[m++]=a>>5&255;u[m++]=a<<3&255;const g=new Uint32Array(64),{k:b}=wf;for(m=0;m>24&255,n>>16&255,n>>8&255,255&n,s>>24&255,s>>16&255,s>>8&255,255&s,r>>24&255,r>>16&255,r>>8&255,255&r,i>>24&255,i>>16&255,i>>8&255,255&i,o>>24&255,o>>16&255,o>>8&255,255&o,l>>24&255,l>>16&255,l>>8&255,255&l,f>>24&255,f>>16&255,f>>8&255,255&f,c>>24&255,c>>16&255,c>>8&255,255&c])}class DecryptStream extends DecodeStream{constructor(e,t,a){super(t);this.stream=e;this.dict=e.dict;this.decrypt=a;this.nextChunk=null;this.initialized=!1}readBlock(){let e;if(this.initialized)e=this.nextChunk;else{e=this.stream.getBytes(512);this.initialized=!0}if(!e?.length){this.eof=!0;return}this.nextChunk=this.stream.getBytes(512);const t=this.nextChunk?.length>0;e=(0,this.decrypt)(e,!t);const a=this.bufferLength,n=a+e.length;this.ensureBuffer(n).set(e,a);this.bufferLength=n}getOriginalStream(){return this}}class ARCFourCipher{a=0;b=0;constructor(e){const t=new Uint8Array(256),a=e.length;for(let e=0;e<256;++e)t[e]=e;for(let n=0,s=0;n<256;++n){const r=t[n];s=s+r+e[n%a]&255;t[n]=t[s];t[s]=r}this.s=t}encryptBlock(e){let t=this.a,a=this.b;const n=this.s,s=e.length,r=new Uint8Array(s);for(let i=0;it<128?t<<1:t<<1^27);constructor(){this.buffer=new Uint8Array(16);this.bufferPosition=0}_expandKey(e){unreachable("Cannot call `_expandKey` on the base class")}_decrypt(e,t){let a,n,s;const r=new Uint8Array(16);r.set(e);for(let e=0,a=this._keySize;e<16;++e,++a)r[e]^=t[a];for(let e=this._cyclesOfRepetition-1;e>=1;--e){a=r[13];r[13]=r[9];r[9]=r[5];r[5]=r[1];r[1]=a;a=r[14];n=r[10];r[14]=r[6];r[10]=r[2];r[6]=a;r[2]=n;a=r[15];n=r[11];s=r[7];r[15]=r[3];r[11]=a;r[7]=n;r[3]=s;for(let e=0;e<16;++e)r[e]=this._inv_s[r[e]];for(let a=0,n=16*e;a<16;++a,++n)r[a]^=t[n];for(let e=0;e<16;e+=4){const t=this._mix[r[e]],n=this._mix[r[e+1]],s=this._mix[r[e+2]],i=this._mix[r[e+3]];a=t^n>>>8^n<<24^s>>>16^s<<16^i>>>24^i<<8;r[e]=a>>>24&255;r[e+1]=a>>16&255;r[e+2]=a>>8&255;r[e+3]=255&a}}a=r[13];r[13]=r[9];r[9]=r[5];r[5]=r[1];r[1]=a;a=r[14];n=r[10];r[14]=r[6];r[10]=r[2];r[6]=a;r[2]=n;a=r[15];n=r[11];s=r[7];r[15]=r[3];r[11]=a;r[7]=n;r[3]=s;for(let e=0;e<16;++e){r[e]=this._inv_s[r[e]];r[e]^=t[e]}return r}_encrypt(e,t){const a=this._s;let n,s,r;const i=new Uint8Array(16);i.set(e);for(let e=0;e<16;++e)i[e]^=t[e];for(let e=1;e=n;--a)if(e[a]!==t){t=0;break}o-=t;r[r.length-1]=e.subarray(0,16-t)}}const l=new Uint8Array(o);for(let e=0,t=0,a=r.length;e=256&&(o=255&(27^o))}for(let t=0;t<4;++t){a[e]=n^=a[e-32];e++;a[e]=s^=a[e-32];e++;a[e]=r^=a[e-32];e++;a[e]=i^=a[e-32];e++}}return a}}class PDFBase{_hash(e,t,a){unreachable("Abstract method `_hash` called")}checkOwnerPassword(e,t,a,n){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(a,e.length+t.length);return isArrayEqual(this._hash(e,s,a),n)}checkUserPassword(e,t,a){const n=new Uint8Array(e.length+8);n.set(e,0);n.set(t,e.length);return isArrayEqual(this._hash(e,n,[]),a)}getOwnerKey(e,t,a,n){const s=new Uint8Array(e.length+56);s.set(e,0);s.set(t,e.length);s.set(a,e.length+t.length);const r=this._hash(e,s,a);return new AES256Cipher(r).decryptBlock(n,!1,new Uint8Array(16))}getUserKey(e,t,a){const n=new Uint8Array(e.length+8);n.set(e,0);n.set(t,e.length);const s=this._hash(e,n,[]);return new AES256Cipher(s).decryptBlock(a,!1,new Uint8Array(16))}}class PDF17 extends PDFBase{_hash(e,t,a){return calculateSHA256(t,0,t.length)}}class PDF20 extends PDFBase{_hash(e,t,a){let n=calculateSHA256(t,0,t.length).subarray(0,32),s=[0],r=0;for(;r<64||s.at(-1)>r-32;){const t=e.length+n.length+a.length,i=new Uint8Array(t);let o=0;i.set(e,o);o+=e.length;i.set(n,o);o+=n.length;i.set(a,o);const l=new Uint8Array(64*t);for(let e=0,a=0;e<64;e++,a+=t)l.set(i,a);s=new AES128Cipher(n.subarray(0,16)).encrypt(l,n.subarray(16,32));const f=Math.sumPrecise(s.slice(0,16))%3;0===f?n=calculateSHA256(s,0,s.length):1===f?n=calculateSHA384(s,0,s.length):2===f&&(n=calculateSHA512(s,0,s.length));r++}return n.subarray(0,32)}}class CipherTransform{constructor(e,t){this.StringCipherConstructor=e;this.StreamCipherConstructor=t}createStream(e,t){const a=new this.StreamCipherConstructor;return new DecryptStream(e,t,function cipherTransformDecryptStream(e,t){return a.decryptBlock(e,t)})}decryptString(e){const t=new this.StringCipherConstructor;let a=stringToBytes(e);a=t.decryptBlock(a,!0);return bytesToString(a)}encryptString(e){const t=new this.StringCipherConstructor;if(t instanceof AESBaseCipher){const a=16-e.length%16;e+=String.fromCharCode(a).repeat(a);const n=new Uint8Array(16);crypto.getRandomValues(n);let s=stringToBytes(e);s=t.encrypt(s,n);const r=new Uint8Array(16+s.length);r.set(n);r.set(s,16);return bytesToString(r)}let a=stringToBytes(e);a=t.encrypt(a);return bytesToString(a)}}class CipherTransformFactory{static get _defaultPasswordBytes(){return shadow(this,"_defaultPasswordBytes",new Uint8Array([40,191,78,94,78,117,138,65,100,0,78,86,255,250,1,8,46,46,0,182,208,104,62,128,47,12,169,254,100,83,105,122]))}#At(e,t,a,n,s,r,i,o,l,f,c,h){if(t){const e=Math.min(127,t.length);t=t.subarray(0,e)}else t=[];const u=6===e?new PDF20:new PDF17;return u.checkUserPassword(t,o,i)?u.getUserKey(t,l,c):t.length&&u.checkOwnerPassword(t,n,r,a)?u.getOwnerKey(t,s,r,f):null}#xt(e,t,a,n,s,r,i,o){const l=40+a.length+e.length,f=new Uint8Array(l);let c,h,u=0;if(t){h=Math.min(32,t.length);for(;u>8&255;f[u++]=s>>16&255;f[u++]=s>>>24&255;f.set(e,u);u+=e.length;if(r>=4&&!o){f.fill(255,u,u+4);u+=4}let m=calculateMD5(f,0,u);const p=i>>3;if(r>=3)for(c=0;c<50;++c)m=calculateMD5(m,0,p);const d=m.subarray(0,p);let g,b;if(r>=3){u=0;f.set(CipherTransformFactory._defaultPasswordBytes,u);u+=32;f.set(e,u);u+=e.length;g=new ARCFourCipher(d);b=g.encryptBlock(calculateMD5(f,0,u));h=d.length;const t=new Uint8Array(h);for(c=1;c<=19;++c){for(let e=0;en[t]===e)?d:null}#Ct(e,t,a,n){const s=new Uint8Array(32);let r=0;const i=Math.min(32,e.length);for(;r>3;if(a>=3)for(o=0;o<50;++o)l=calculateMD5(l,0,l.length);let c,h;if(a>=3){h=t;const e=new Uint8Array(f);for(o=19;o>=0;o--){for(let t=0;t>8&255;r[i++]=e>>16&255;r[i++]=255&t;r[i++]=t>>8&255;if(n){r[i++]=115;r[i++]=65;r[i++]=108;r[i++]=84}return calculateMD5(r,0,i).subarray(0,Math.min(s+5,16))}#Ft(e,t,a,n,s){if(!(t instanceof Name))throw new FormatError("Invalid crypt filter name.");const r=this,i=e.get(t.name),o=i?.get("CFM");if(!o||"None"===o.name)return function(){return new NullCipher};if("V2"===o.name)return function(){return new ARCFourCipher(r.#It(a,n,s,!1))};if("AESV2"===o.name)return function(){return new AES128Cipher(r.#It(a,n,s,!0))};if("AESV3"===o.name)return function(){return new AES256Cipher(s)};throw new FormatError("Unknown crypto method")}constructor(e,t,a){const n=e.get("Filter");if(!isName(n,"Standard"))throw new FormatError("unknown encryption method");this.filterName=n.name;this.dict=e;const s=e.get("V");if(!Number.isInteger(s)||1!==s&&2!==s&&4!==s&&5!==s)throw new FormatError("unsupported encryption algorithm");this.algorithm=s;let r=e.get("Length");if(!r)if(s<=3)r=40;else{const t=e.get("CF"),a=e.get("StmF");if(t instanceof Dict&&a instanceof Name){t.suppressEncryption=!0;const e=t.get(a.name);r=e?.get("Length")||128;r<40&&(r<<=3)}}if(!Number.isInteger(r)||r<40||r%8!=0)throw new FormatError("invalid key length");const i=stringToBytes(e.get("O")),o=stringToBytes(e.get("U")),l=i.subarray(0,32),f=o.subarray(0,32),c=e.get("P"),h=e.get("R"),u=(4===s||5===s)&&!1!==e.get("EncryptMetadata");this.encryptMetadata=u;const m=stringToBytes(t);let p,d;if(a){if(6===h)try{a=utf8StringToString(a)}catch{warn("CipherTransformFactory: Unable to convert UTF8 encoded password.")}p=stringToBytes(a)}if(5!==s)d=this.#xt(m,p,l,f,c,h,r,u);else{const t=i.subarray(32,40),a=i.subarray(40,48),n=o.subarray(0,48),s=o.subarray(32,40),r=o.subarray(40,48),c=stringToBytes(e.get("OE")),u=stringToBytes(e.get("UE")),m=stringToBytes(e.get("Perms"));d=this.#At(h,p,l,t,a,n,f,s,r,c,u,m)}if(!d){if(!a)throw new PasswordException("No password given",Zt);const e=this.#Ct(p,l,h,r);d=this.#xt(m,e,l,f,c,h,r,u)}if(!d)throw new PasswordException("Incorrect Password",ea);if(4===s&&d.length<16){this.encryptionKey=new Uint8Array(16);this.encryptionKey.set(d)}else this.encryptionKey=d;if(s>=4){const t=e.get("CF");t instanceof Dict&&(t.suppressEncryption=!0);this.cf=t;this.stmf=e.get("StmF")||Name.get("Identity");this.strf=e.get("StrF")||Name.get("Identity");this.eff=e.get("EFF")||this.stmf}}createCipherTransform(e,t){if(4===this.algorithm||5===this.algorithm)return new CipherTransform(this.#Ft(this.cf,this.strf,e,t,this.encryptionKey),this.#Ft(this.cf,this.stmf,e,t,this.encryptionKey));const a=this.#It(e,t,this.encryptionKey,!1),cipherConstructor=function(){return new ARCFourCipher(a)};return new CipherTransform(cipherConstructor,cipherConstructor)}}class XRef{constructor(e,t){this.stream=e;this.pdfManager=t;this.entries=[];this._xrefStms=new Set;this._cacheMap=new Map;this._pendingRefs=new RefSet;this._newPersistentRefNum=null;this._newTemporaryRefNum=null;this._persistentRefsCache=null}getNewPersistentRef(e){null===this._newPersistentRefNum&&(this._newPersistentRefNum=this.entries.length||1);const t=this._newPersistentRefNum++;this._cacheMap.set(t,e);return Ref.get(t,0)}getNewTemporaryRef(){if(null===this._newTemporaryRefNum){this._newTemporaryRefNum=this.entries.length||1;if(this._newPersistentRefNum){this._persistentRefsCache=new Map;for(let e=this._newTemporaryRefNum;e0;){const[i,o]=r;if(!Number.isInteger(i)||!Number.isInteger(o))throw new FormatError(`Invalid XRef range fields: ${i}, ${o}`);if(!Number.isInteger(a)||!Number.isInteger(n)||!Number.isInteger(s))throw new FormatError(`Invalid XRef entry fields length: ${i}, ${o}`);for(let r=t.entryNum;r=e.length);){a+=String.fromCharCode(n);n=e[t]}return a}function skipUntil(e,t,a){const n=a.length,s=e.length;let r=0;for(;t=n)break;t++;r++}return r}const e=/\b(endobj|\d+\s+\d+\s+obj|xref|trailer\s*<<)\b/g,t=/\b(startxref|\d+\s+\d+\s+obj)\b/g,a=/^(\d+)\s+(\d+)\s+obj\b/,n=new Uint8Array([116,114,97,105,108,101,114]),s=new Uint8Array([115,116,97,114,116,120,114,101,102]),r=new Uint8Array([47,88,82,101,102]);this.entries.length=0;this._cacheMap.clear();const i=this.stream;i.pos=0;const o=i.getBytes(),l=bytesToString(o),f=o.length;let c=i.start;const h=[],u=[];for(;c=f)break;m=o[c]}while(10!==m&&13!==m);continue}const p=readToken(o,c);let d;if(p.startsWith("xref")&&(4===p.length||/\s/.test(p[4]))){c+=skipUntil(o,c,n);h.push(c);c+=skipUntil(o,c,s)}else if(d=a.exec(p)){const t=0|d[1],a=0|d[2],n=c+p.length;let s,h=!1;if(this.entries[t]){if(this.entries[t].gen===a)try{new Parser({lexer:new Lexer(i.makeSubStream(n))}).getObj();h=!0}catch(e){e instanceof ParserEOFException?warn(`indexObjects -- checking object (${p}): "${e}".`):h=!0}}else h=!0;h&&(this.entries[t]={offset:c-i.start,gen:a,uncompressed:!0});e.lastIndex=n;const m=e.exec(l);if(m){s=e.lastIndex+1-c;if("endobj"!==m[1]){warn(`indexObjects: Found "${m[1]}" inside of another "obj", caused by missing "endobj" -- trying to recover.`);s-=m[1].length+1}}else s=f-c;const g=o.subarray(c,c+s),b=skipUntil(g,0,r);if(b0&&t[3]-t[1]>0)return t;warn(`Empty, or invalid, /${e} entry.`)}return null}get mediaBox(){return shadow(this,"mediaBox",this.getBoundingBox("MediaBox")||jf)}get cropBox(){return shadow(this,"cropBox",this.getBoundingBox("CropBox")||this.mediaBox)}get userUnit(){const e=this.pageDict.get("UserUnit");return shadow(this,"userUnit","number"==typeof e&&e>0?e:1)}get view(){const{cropBox:e,mediaBox:t}=this;if(e!==t&&!isArrayEqual(e,t)){const a=Util.intersect(e,t);if(a&&a[2]-a[0]>0&&a[3]-a[1]>0)return shadow(this,"view",a);warn("Empty /CropBox and /MediaBox intersection.")}return shadow(this,"view",t)}get rotate(){let e=this.#Rt("Rotate")||0;e%90!=0?e=0:e>=360?e%=360:e<0&&(e=(e%360+360)%360);return shadow(this,"rotate",e)}#Ht(e,t){if(!this.evaluatorOptions.ignoreErrors)throw e;warn(`getContentStream - ignoring sub-stream (${t}): "${e}".`)}async getContentStream(){const e=await this.pdfManager.ensure(this,"content");if(e instanceof BaseStream&&!e.isImageStream){if(e.isAsync){const t=await e.asyncGetBytes();if(t)return new Stream(t,0,t.length,e.dict)}return e}if(Array.isArray(e)){const t=[];for(let a=0,n=e.length;a{t&&(e[a]=new Stream(t,0,t.length,n.dict))}))}t.length>0&&await Promise.all(t);return new StreamsSequenceStream(e,this.#Ht.bind(this))}return new NullStream}get xfaData(){return shadow(this,"xfaData",this.xfaFactory?{bbox:this.xfaFactory.getBoundingBox(this.pageIndex)}:null)}async#Bt(e,t,a){const n=[];for(const s of e)if(s.id){const e=Ref.fromString(s.id);if(!e){warn(`A non-linked annotation cannot be modified: ${s.id}`);continue}if(s.deleted){t.put(e,e);if(s.popupRef){const e=Ref.fromString(s.popupRef);e&&t.put(e,e)}continue}if(s.popup?.deleted){const e=Ref.fromString(s.popupRef);e&&t.put(e,e)}a?.put(e);s.ref=e;n.push(this.xref.fetchAsync(e).then(e=>{e instanceof Dict&&(s.oldAnnotation=e.clone())},()=>{warn(`Cannot fetch \`oldAnnotation\` for: ${e}.`)}));delete s.id}await Promise.all(n)}async saveNewAnnotations(e,t,a,n,s){if(this.xfaFactory)throw new Error("XFA: Cannot save new annotations.");const r=this.#Ot(e),i=new RefSetCache,o=new RefSet;await this.#Bt(a,i,o);const l=this.pageDict,f=this.annotations.filter(e=>!(e instanceof Ref&&i.has(e))),c=await AnnotationFactory.saveNewAnnotations(r,this.xref,t,a,n,s);for(const{ref:e}of c.annotations)e instanceof Ref&&!o.has(e)&&f.push(e);const h=l.clone();h.set("Annots",f);s.put(this.ref,{data:h});for(const e of i)s.put(e,{data:null})}async save(e,t,a,n){const s=this.#Ot(e),r=await this._parsedAnnotations,i=[];for(const e of r)i.push(e.save(s,t,a,n).catch(function(e){warn(`save - ignoring annotation data during "${t.name}" task: "${e}".`);return null}));return Promise.all(i)}async loadResources(e){await(this.#Tt??=this.pdfManager.ensure(this,"resources"));await ObjectLoader.load(this.resources,e,this.xref)}async#Dt(e,t){const a=e?.get("Resources");if(!(a instanceof Dict&&a.size))return this.resources;await ObjectLoader.load(a,t,this.xref);return Dict.merge({xref:this.xref,dictArray:[a,this.resources],mergeSubDicts:!0})}async getOperatorList({handler:e,sink:t,task:a,intent:n,cacheKey:s,pageIndex:r=this.pageIndex,annotationStorage:i=null,modifiedIds:c=null}){const p=this.getContentStream(),g=this.loadResources(da),b=this.#Ot(e,r),w=this.xfaFactory?null:getNewAnnotationsMap(i),j=w?.get(this.pageIndex);let k=Promise.resolve(null),y=null;if(j){const e=this.pdfManager.ensureDoc("annotationGlobals");let t;const n=new Set;for(const{bitmapId:e,bitmap:t}of j)!e||t||n.has(e)||n.add(e);const{isOffscreenCanvasSupported:s}=this.evaluatorOptions;if(n.size>0){const e=j.slice();for(const[t,a]of i)t.startsWith(d)&&a.bitmap&&n.has(a.bitmapId)&&e.push(a);t=AnnotationFactory.generateImages(e,this.xref,s)}else t=AnnotationFactory.generateImages(j,this.xref,s);y=new RefSet;k=Promise.all([e,this.#Bt(j,y,null)]).then(([e])=>e?AnnotationFactory.printNewAnnotations(e,b,a,j,t):null)}const q=Promise.all([p,g]).then(async([i])=>{const o=await this.#Dt(i.dict,da),l=new OperatorList(n,t);e.send("StartRenderPage",{transparency:b.hasBlendModes(o,this.nonBlendModesSet),pageIndex:r,cacheKey:s});await b.getOperatorList({stream:i,task:a,resources:o,operatorList:l});return l});let[v,S,x]=await Promise.all([q,this._parsedAnnotations,k]);if(x){S=S.filter(e=>!(e.ref&&y.has(e.ref)));for(let e=0,t=x.length;ee.ref&&isRefsEqual(e.ref,a.refToReplace));if(n>=0){S.splice(n,1,a);x.splice(e--,1);t--}}}S=S.concat(x)}if(0===S.length||n&u){v.flush(!0);return{length:v.totalLength}}const C=!!(n&h),F=!!(n&m),T=!!(n&o),O=!!(n&l),R=!!(n&f),H=[];for(const e of S)(T||O&&e.mustBeViewed(i,C)&&e.mustBeViewedWhenEditing(F,c)||R&&e.mustBePrinted(i))&&H.push(e.getOperatorList(b,a,n,i).catch(function(e){warn(`getOperatorList - ignoring annotation data during "${a.name}" task: "${e}".`);return{opList:null,separateForm:!1,separateCanvas:!1}}));const D=await Promise.all(H);let M=!1,N=!1;for(const{opList:e,separateForm:t,separateCanvas:a}of D){v.addOpList(e);M||=t;N||=a}v.flush(!0,{form:M,canvas:N});return{length:v.totalLength}}async extractTextContent({handler:e,task:t,includeMarkedContent:a,disableNormalization:n,sink:s,intersector:r=null}){const i=this.getContentStream(),o=this.loadResources(ga),l=this.pdfManager.ensureCatalog("lang"),[f,,c]=await Promise.all([i,o,l]),h=await this.#Dt(f.dict,ga);return this.#Ot(e).getTextContent({stream:f,task:t,resources:h,includeMarkedContent:a,disableNormalization:n,sink:s,viewBox:this.view,lang:c,intersector:r})}async getStructTree(){const e=await this.pdfManager.ensureCatalog("structTreeRoot");if(!e)return null;await this._parsedAnnotations;try{const t=await this.pdfManager.ensure(this,"_parseStructTree",[e]);return await this.pdfManager.ensure(t,"serializable")}catch(e){warn(`getStructTree: "${e}".`);return null}}_parseStructTree(e){const t=new StructTreePage(e,this.pageDict);t.parse(this.ref);return t}async getAnnotationsData(e,t,a){const n=await this._parsedAnnotations;if(0===n.length)return n;const s=[],r=[];let i;const c=!!(a&o),h=!!(a&l),u=!!(a&f),m=[];for(const a of n){const n=c||h&&a.viewable;(n||u&&a.printable)&&s.push(a.data);if(a.hasTextContent&&n){i??=this.#Ot(e);r.push(a.extractTextContent(i,t,[-1/0,-1/0,1/0,1/0]).catch(function(e){warn(`getAnnotationsData - ignoring textContent during "${t.name}" task: "${e}".`)}))}else a.overlaysTextContent&&n&&m.push(a)}if(m.length>0){const a=new Intersector(m);r.push(this.extractTextContent({handler:e,task:t,includeMarkedContent:!1,disableNormalization:!1,sink:null,viewBox:this.view,lang:null,intersector:a}).then(()=>{a.setText()}))}await Promise.all(r);return s}get annotations(){const e=this.#Rt("Annots");return shadow(this,"annotations",Array.isArray(e)?e:[])}get _parsedAnnotations(){return shadow(this,"_parsedAnnotations",this.pdfManager.ensure(this,"annotations").then(async e=>{if(0===e.length)return e;const[t,a]=await Promise.all([this.pdfManager.ensureDoc("annotationGlobals"),this.pdfManager.ensureDoc("fieldObjects")]);if(!t)return[];const n=a?.orphanFields,s=[];for(const a of e)s.push(AnnotationFactory.create(this.xref,a,t,this._localIdFactory,!1,n,null,this.ref).catch(function(e){warn(`_parsedAnnotations: "${e}".`);return null}));const r=[];let i,o;for(const e of await Promise.all(s))e&&(e instanceof WidgetAnnotation?(o||=[]).push(e):e instanceof PopupAnnotation?(i||=[]).push(e):r.push(e));o&&r.push(...o);i&&r.push(...i);return r}))}get jsActions(){return shadow(this,"jsActions",collectActions(this.xref,this.pageDict,le))}async collectAnnotationsByType(e,t,a,n,s){const{pageIndex:r}=this;if(Object.hasOwn(this,"_parsedAnnotations")){const e=await this._parsedAnnotations;for(const{data:t}of e)if(!a||a.has(t.annotationType)){t.pageIndex=r;n.push(Promise.resolve(t))}return}const i=await this.pdfManager.ensure(this,"annotations");let o;for(const l of i)n.push(AnnotationFactory.create(this.xref,l,s,this._localIdFactory,!1,null,a,this.ref).then(async a=>{if(!a)return null;a.data.pageIndex=r;if(a.hasTextContent&&a.viewable){o??=this.#Ot(e);await a.extractTextContent(o,t,[-1/0,-1/0,1/0,1/0])}return a.data}).catch(function(e){warn(`collectAnnotationsByType: "${e}".`);return null}))}}const kf=new Uint8Array([37,80,68,70,45]),yf=new Uint8Array([115,116,97,114,116,120,114,101,102]),qf=new Uint8Array([101,110,100,111,98,106]);function find(e,t,a=1024,n=!1){const s=t.length,r=e.peekBytes(a),i=r.length-s;if(i<=0)return!1;if(n){const a=s-1;let n=r.length-1;for(;n>=a;){let i=0;for(;i=s){e.pos+=n-a;return!0}n--}}else{let a=0;for(;a<=i;){let n=0;for(;n=s){e.pos+=a;return!0}a++}}return!1}class PDFDocument{#Mt=new Map;#Nt=null;constructor(e,t){if(t.length<=0)throw new InvalidPDFException("The PDF file is empty, i.e. its size is zero bytes.");this.pdfManager=e;this.stream=t;this.xref=new XRef(t,e);const a={font:0};this._globalIdFactory=class{static getDocId(){return`g_${e.docId}`}static createFontId(){return"f"+ ++a.font}static createObjId(){unreachable("Abstract method `createObjId` called.")}static getPageObjId(){unreachable("Abstract method `getPageObjId` called.")}}}parse(e){this.xref.parse(e);this.catalog=new Catalog(this.pdfManager,this.xref)}get linearization(){let e=null;try{e=Linearization.create(this.stream)}catch(e){if(e instanceof MissingDataException)throw e;info(e)}return shadow(this,"linearization",e)}get startXRef(){const e=this.stream;let t=0;if(this.linearization){e.reset();if(find(e,qf)){e.skip(6);let a=e.peekByte();for(;isWhiteSpace(a);){e.pos++;a=e.peekByte()}t=e.pos-e.start}}else{const a=1024,n=yf.length;let s=!1,r=e.end;for(;!s&&r>0;){r-=a-n;r<0&&(r=0);e.pos=r;s=find(e,yf,a,!0)}if(s){e.skip(9);let a;do{a=e.getByte()}while(isWhiteSpace(a));let n="";for(;a>=32&&a<=57;){n+=String.fromCharCode(a);a=e.getByte()}t=parseInt(n,10);isNaN(t)&&(t=0)}}return shadow(this,"startXRef",t)}checkHeader(){const e=this.stream;e.reset();if(!find(e,kf))return;e.moveStart();e.skip(kf.length);let t,a="";for(;(t=e.getByte())>32&&a.length<7;)a+=String.fromCharCode(t);ua.test(a)?this.#Nt=a:warn(`Invalid PDF header version: ${a}`)}parseStartXRef(){this.xref.setStartXRef(this.startXRef)}get numPages(){let e=0;e=this.catalog.hasActualNumPages?this.catalog.numPages:this.xfaFactory?this.xfaFactory.getNumPages():this.linearization?this.linearization.numPages:this.catalog.numPages;return shadow(this,"numPages",e)}#Pt(e,t=0){return!!Array.isArray(e)&&e.every(e=>{if(!((e=this.xref.fetchIfRef(e))instanceof Dict))return!1;if(e.has("Kids")){if(++t>10){warn("#hasOnlyDocumentSignatures: maximum recursion depth reached");return!1}return this.#Pt(e.get("Kids"),t)}const a=isName(e.get("FT"),"Sig"),n=e.get("Rect"),s=Array.isArray(n)&&n.every(e=>0===e);return a&&s})}get _xfaStreams(){const{acroForm:e}=this.catalog;if(!e)return null;const t=e.get("XFA"),a=new Map(["xdp:xdp","template","datasets","config","connectionSet","localeSet","stylesheet","/xdp:xdp"].map(e=>[e,null]));if(t instanceof BaseStream&&!t.isEmpty){a.set("xdp:xdp",t);return a}if(!Array.isArray(t)||0===t.length)return null;for(let e=0,n=t.length;ef.handleSetFont(n,[Name.get(e),1],null,c,t,u,a,s).catch(e=>{warn(`loadXfaFonts: "${e}".`);return null}),m=[];for(const[e,t]of s){const a=t.get("FontDescriptor");if(!(a instanceof Dict))continue;let n=a.get("FontFamily");n=n.replaceAll(/[ ]+(\d)/g,"$1");const s={fontFamily:n,fontWeight:a.get("FontWeight"),italicAngle:-a.get("ItalicAngle")};validateCSSFont(s)&&m.push(parseFont(e,null,s))}await Promise.all(m);const p=this.xfaFactory.setFonts(h);if(!p)return;r.ignoreErrors=!0;m.length=0;h.length=0;const d=new Set;for(const e of p)getXfaFontName(`${e}-Regular`)||d.add(e);d.size&&p.push("PdfJS-Fallback");for(const e of p)if(!d.has(e))for(const t of[{name:"Regular",fontWeight:400,italicAngle:0},{name:"Bold",fontWeight:700,italicAngle:0},{name:"Italic",fontWeight:400,italicAngle:12},{name:"BoldItalic",fontWeight:700,italicAngle:12}]){const a=`${e}-${t.name}`;m.push(parseFont(a,getXfaFontDict(a),{fontFamily:e,fontWeight:t.fontWeight,italicAngle:t.italicAngle}))}await Promise.all(m);this.xfaFactory.appendFonts(h,d)}loadXfaResources(e,t){return Promise.all([this.#_t(e,t).catch(()=>{}),this.#Et()])}serializeXfaData(e){return this.xfaFactory?this.xfaFactory.serializeData(e):null}get version(){return this.catalog.version||this.#Nt}get formInfo(){const e={hasFields:!1,hasAcroForm:!1,hasXfa:!1,hasSignatures:!1},{acroForm:t}=this.catalog;if(!t)return shadow(this,"formInfo",e);try{const a=t.get("Fields"),n=Array.isArray(a)&&a.length>0;e.hasFields=n;const s=t.get("XFA");e.hasXfa=Array.isArray(s)&&s.length>0||s instanceof BaseStream&&!s.isEmpty;const r=!!(1&t.get("SigFlags")),i=r&&this.#Pt(a);e.hasAcroForm=n&&!i;e.hasSignatures=r}catch(e){if(e instanceof MissingDataException)throw e;warn(`Cannot fetch form information: "${e}".`)}return shadow(this,"formInfo",e)}get documentInfo(){const{catalog:e,formInfo:t,xref:a}=this,n={PDFFormatVersion:this.version,Language:e.lang,EncryptFilterName:a.encrypt?.filterName??null,IsLinearized:!!this.linearization,IsAcroFormPresent:t.hasAcroForm,IsXFAPresent:t.hasXfa,IsCollectionPresent:!!e.collection,IsSignaturesPresent:t.hasSignatures};let s;try{s=a.trailer.get("Info")}catch(e){if(e instanceof MissingDataException)throw e;info("The document information dictionary is invalid.")}if(!(s instanceof Dict))return shadow(this,"documentInfo",n);for(const[e,t]of s){switch(e){case"Title":case"Author":case"Subject":case"Keywords":case"Creator":case"Producer":case"CreationDate":case"ModDate":if("string"==typeof t){n[e]=stringToPDFString(t);continue}break;case"Trapped":if(t instanceof Name){n[e]=t;continue}break;default:let a;switch(typeof t){case"string":a=stringToPDFString(t);break;case"number":case"boolean":a=t;break;default:t instanceof Name&&(a=t)}if(void 0===a){warn(`Bad value, for custom key "${e}", in Info: ${t}.`);continue}n.Custom??=Object.create(null);n.Custom[e]=a;continue}warn(`Bad value, for key "${e}", in Info: ${t}.`)}return shadow(this,"documentInfo",n)}get fingerprints(){const e="\0".repeat(16);function validate(t){return"string"==typeof t&&16===t.length&&t!==e}const t=this.xref.trailer.get("ID");let a,n;if(Array.isArray(t)&&validate(t[0])){a=stringToBytes(t[0]);t[1]!==t[0]&&validate(t[1])&&(n=stringToBytes(t[1]))}else a=calculateMD5(this.stream.getByteRange(0,1024),0,1024);return shadow(this,"fingerprints",[a.toHex(),n?.toHex()??null])}async#zt(e){const{catalog:t,linearization:a,xref:n}=this,s=Ref.get(a.objectNumberFirst,0);try{const e=await n.fetchAsync(s);if(e instanceof Dict){let a=e.getRaw("Type");a instanceof Ref&&(a=await n.fetchAsync(a));if(isName(a,"Page")||!e.has("Type")&&!e.has("Kids")&&e.has("Contents")){t.pageKidsCountCache.has(s)||t.pageKidsCountCache.put(s,1);t.pageIndexCache.has(s)||t.pageIndexCache.put(s,0);return[e,s]}}throw new FormatError("The Linearization dictionary doesn't point to a valid Page dictionary.")}catch(a){warn(`_getLinearizationPage: "${a.message}".`);return t.getPageDict(e)}}getPage(e){const t=this.#Mt.get(e);if(t)return t;const{catalog:a,linearization:n,xfaFactory:s}=this;let r;r=s?Promise.resolve([Dict.empty,null]):n?.pageFirst===e?this.#zt(e):a.getPageDict(e);r=r.then(([t,n])=>new Page({pdfManager:this.pdfManager,xref:this.xref,pageIndex:e,pageDict:t,ref:n,globalIdFactory:this._globalIdFactory,fontCache:a.fontCache,builtInCMapCache:a.builtInCMapCache,standardFontDataCache:a.standardFontDataCache,globalColorSpaceCache:a.globalColorSpaceCache,globalImageCache:a.globalImageCache,systemFontCache:a.systemFontCache,nonBlendModesSet:a.nonBlendModesSet,xfaFactory:s}));this.#Mt.set(e,r);return r}async checkFirstPage(e=!1){if(!e)try{await this.getPage(0)}catch(e){if(e instanceof XRefEntryException){this.#Mt.delete(0);await this.cleanup();throw new XRefParseException}}}async checkLastPage(e=!1){const{catalog:t,pdfManager:a}=this;t.setActualNumPages();let n;try{await Promise.all([a.ensureDoc("xfaFactory"),a.ensureDoc("linearization"),a.ensureCatalog("numPages")]);if(this.xfaFactory)return;n=this.linearization?this.linearization.numPages:t.numPages;if(!Number.isInteger(n))throw new FormatError("Page count is not an integer.");if(n<=1)return;await this.getPage(n-1)}catch(s){this.#Mt.delete(n-1);await this.cleanup();if(s instanceof XRefEntryException&&!e)throw new XRefParseException;warn(`checkLastPage - invalid /Pages tree /Count: ${n}.`);let r;try{r=await t.getAllPageDicts(e)}catch(a){if(a instanceof XRefEntryException&&!e)throw new XRefParseException;t.setActualNumPages(1);return}for(const[e,[n,s]]of r){let r;if(n instanceof Error){r=Promise.reject(n);r.catch(()=>{})}else r=Promise.resolve(new Page({pdfManager:a,xref:this.xref,pageIndex:e,pageDict:n,ref:s,globalIdFactory:this._globalIdFactory,fontCache:t.fontCache,builtInCMapCache:t.builtInCMapCache,standardFontDataCache:t.standardFontDataCache,globalColorSpaceCache:this.globalColorSpaceCache,globalImageCache:t.globalImageCache,systemFontCache:t.systemFontCache,nonBlendModesSet:t.nonBlendModesSet,xfaFactory:null}));this.#Mt.set(e,r)}t.setActualNumPages(r.size)}}async fontFallback(e,t){const{catalog:a,pdfManager:n}=this;for(const s of await Promise.all(a.fontCache))if(s.loadedName===e){s.fallback(t,n.evaluatorOptions);return}}async cleanup(e=!1){return this.catalog?this.catalog.cleanup(e):clearGlobalCaches()}async#Lt(e,t,a,n,s,r,i){const{xref:o}=this;if(!(a instanceof Ref)||r.has(a))return;r.put(a);const l=await o.fetchAsync(a);if(!(l instanceof Dict))return;let f=await l.getAsync("Subtype");f=f instanceof Name?f.name:null;if("Link"===f)return;if(l.has("T")){const t=stringToPDFString(await l.getAsync("T"));e=""===e?t:`${e}.${t}`}else{let a=l;for(;;){a=a.getRaw("Parent")||t;if(a instanceof Ref){if(r.has(a))break;a=await o.fetchAsync(a)}if(!(a instanceof Dict))break;if(a.has("T")){const t=stringToPDFString(await a.getAsync("T"));e=""===e?t:`${e}.${t}`;break}}}t&&!l.has("Parent")&&isName(l.get("Subtype"),"Widget")&&i.put(a,t);n.getOrInsertComputed(e,makeArr).push(AnnotationFactory.create(o,a,s,null,!0,i,null,null).then(e=>e?.getFieldObject()).catch(function(e){warn(`#collectFieldObjects: "${e}".`);return null}));if(!l.has("Kids"))return;const c=await l.getAsync("Kids");if(Array.isArray(c))for(const t of c)await this.#Lt(e,a,t,n,s,r,i)}get fieldObjects(){return shadow(this,"fieldObjects",this.pdfManager.ensureDoc("formInfo").then(async e=>{if(!e.hasFields)return null;const t=await this.annotationGlobals;if(!t)return null;const{acroForm:a}=t,n=new RefSet,s=Object.create(null),r=new Map,i=new RefSetCache;for(const e of a.get("Fields"))await this.#Lt("",null,e,r,t,n,i);const o=[];for(const[e,t]of r)o.push(Promise.all(t).then(t=>{(t=t.filter(e=>!!e)).length>0&&(s[e]=t)}));await Promise.all(o);return{allFields:objectSize(s)>0?s:null,orphanFields:i}}))}get hasJSActions(){return shadow(this,"hasJSActions",this.pdfManager.ensureDoc("_parseHasJSActions"))}async _parseHasJSActions(){const[e,t]=await Promise.all([this.pdfManager.ensureCatalog("jsActions"),this.pdfManager.ensureDoc("fieldObjects")]);return!!e||!!t?.allFields&&Object.values(t.allFields).some(e=>e.some(e=>null!==e.actions))}get calculationOrderIds(){const e=this.catalog.acroForm?.get("CO");if(!Array.isArray(e)||0===e.length)return shadow(this,"calculationOrderIds",null);const t=[];for(const a of e)a instanceof Ref&&t.push(a.toString());return shadow(this,"calculationOrderIds",t.length?t:null)}get annotationGlobals(){return shadow(this,"annotationGlobals",AnnotationFactory.createGlobals(this.pdfManager))}async toJSObject(e,t=!0){throw new Error("Not implemented: toJSObject")}}class BasePdfManager{constructor({docBaseUrl:e,docId:t,enableXfa:a,evaluatorOptions:n,handler:s,password:r}){this._docBaseUrl=function parseDocBaseUrl(e){if(e){const t=createValidAbsoluteUrl(e);if(t)return t.href;warn(`Invalid absolute docBaseUrl: "${e}".`)}return null}(e);this._docId=t;this._password=r;this.enableXfa=a;n.isOffscreenCanvasSupported&&=FeatureTest.isOffscreenCanvasSupported;n.isImageDecoderSupported&&=FeatureTest.isImageDecoderSupported;this.evaluatorOptions=Object.freeze(n);ImageResizer.setOptions(n);JpegStream.setOptions(n);OperatorList.setOptions(n);const i={...n,handler:s};JpxImage.setOptions(i);IccColorSpace.setOptions(i);CmykICCBasedCS.setOptions(i);JBig2CCITTFaxImage.setOptions(i);PDFFunctionFactory.setOptions(i);Pattern.setOptions(i)}get docId(){return this._docId}get password(){return this._password}get docBaseUrl(){return this._docBaseUrl}ensureDoc(e,t){return this.ensure(this.pdfDocument,e,t)}ensureXRef(e,t){return this.ensure(this.pdfDocument.xref,e,t)}ensureCatalog(e,t){return this.ensure(this.pdfDocument.catalog,e,t)}getPage(e){return this.pdfDocument.getPage(e)}fontFallback(e,t){return this.pdfDocument.fontFallback(e,t)}cleanup(e=!1){return this.pdfDocument.cleanup(e)}async ensure(e,t,a){unreachable("Abstract method `ensure` called")}requestRange(e,t){unreachable("Abstract method `requestRange` called")}requestLoadedStream(e=!1){unreachable("Abstract method `requestLoadedStream` called")}sendProgressiveData(e){unreachable("Abstract method `sendProgressiveData` called")}updatePassword(e){this._password=e}terminate(e){unreachable("Abstract method `terminate` called")}}class LocalPdfManager extends BasePdfManager{constructor(e){super(e);const t=new Stream(e.source);this.pdfDocument=new PDFDocument(this,t);this._loadedStreamPromise=Promise.resolve(t)}async ensure(e,t,a){const n=e[t];return"function"==typeof n?n.apply(e,a):n}requestRange(e,t){return Promise.resolve()}requestLoadedStream(e=!1){return this._loadedStreamPromise}terminate(e){}}class NetworkPdfManager extends BasePdfManager{constructor(e){super(e);this.streamManager=new ChunkedStreamManager(e.source,{msgHandler:e.handler,length:e.length,disableAutoFetch:e.disableAutoFetch,rangeChunkSize:e.rangeChunkSize});this.pdfDocument=new PDFDocument(this,this.streamManager.getStream())}async ensure(e,t,a){try{const n=e[t];return"function"==typeof n?await n.apply(e,a):n}catch(n){if(!(n instanceof MissingDataException))throw n;await this.requestRange(n.begin,n.end);return this.ensure(e,t,a)}}requestRange(e,t){return this.streamManager.requestRange(e,t)}requestLoadedStream(e=!1){return this.streamManager.requestAllChunks(e)}sendProgressiveData(e){this.streamManager.onReceiveData({chunk:e})}terminate(e){this.streamManager.abort(e)}}const vf=1,Sf=2,Af=1,xf=2,Cf=3,If=4,Ff=5,Tf=6,Of=7,Rf=8;function onFn(){}function wrapReason(e){if(e instanceof AbortException||e instanceof InvalidPDFException||e instanceof PasswordException||e instanceof ResponseException||e instanceof UnknownErrorException)return e;e instanceof Error||"object"==typeof e&&null!==e||unreachable('wrapReason: Expected "reason" to be a (possibly cloned) Error.');switch(e.name){case"AbortException":return new AbortException(e.message);case"InvalidPDFException":return new InvalidPDFException(e.message);case"PasswordException":return new PasswordException(e.message,e.code);case"ResponseException":return new ResponseException(e.message,e.status,e.missing);case"UnknownErrorException":return new UnknownErrorException(e.message,e.details)}return new UnknownErrorException(e.message,e.toString())}class MessageHandler{#Ut=new AbortController;constructor(e,t,a){this.sourceName=e;this.targetName=t;this.comObj=a;this.callbackId=1;this.streamId=1;this.streamSinks=Object.create(null);this.streamControllers=Object.create(null);this.callbackCapabilities=Object.create(null);this.actionHandler=Object.create(null);a.addEventListener("message",this.#Xt.bind(this),{signal:this.#Ut.signal})}#Xt({data:e}){if(e.targetName!==this.sourceName)return;if(e.stream){this.#Wt(e);return}if(e.callback){const t=e.callbackId,a=this.callbackCapabilities[t];if(!a)throw new Error(`Cannot resolve callback ${t}`);delete this.callbackCapabilities[t];if(e.callback===vf)a.resolve(e.data);else{if(e.callback!==Sf)throw new Error("Unexpected callback case");a.reject(wrapReason(e.reason))}return}const t=this.actionHandler[e.action];if(!t)throw new Error(`Unknown action from worker: ${e.action}`);if(e.callbackId){const a=this.sourceName,n=e.sourceName,s=this.comObj;Promise.try(t,e.data).then(function(t){s.postMessage({sourceName:a,targetName:n,callback:vf,callbackId:e.callbackId,data:t})},function(t){s.postMessage({sourceName:a,targetName:n,callback:Sf,callbackId:e.callbackId,reason:wrapReason(t)})});return}e.streamId?this.#Kt(e):t(e.data)}on(e,t){const a=this.actionHandler;if(a[e])throw new Error(`There is already an actionName called "${e}"`);a[e]=t}send(e,t,a){this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,data:t},a)}sendWithPromise(e,t,a){const n=this.callbackId++,s=Promise.withResolvers();this.callbackCapabilities[n]=s;try{this.comObj.postMessage({sourceName:this.sourceName,targetName:this.targetName,action:e,callbackId:n,data:t},a)}catch(e){s.reject(e)}return s.promise}sendWithStream(e,t,a,n){const s=this.streamId++,r=this.sourceName,i=this.targetName,o=this.comObj;return new ReadableStream({start:a=>{const l=Promise.withResolvers();this.streamControllers[s]={controller:a,startCall:l,pullCall:null,cancelCall:null,isClosed:!1};o.postMessage({sourceName:r,targetName:i,action:e,streamId:s,data:t,desiredSize:a.desiredSize},n);return l.promise},pull:e=>{const t=Promise.withResolvers();this.streamControllers[s].pullCall=t;o.postMessage({sourceName:r,targetName:i,stream:Tf,streamId:s,desiredSize:e.desiredSize});return t.promise},cancel:e=>{assert(e instanceof Error,"cancel must have a valid reason");const t=Promise.withResolvers();this.streamControllers[s].cancelCall=t;this.streamControllers[s].isClosed=!0;o.postMessage({sourceName:r,targetName:i,stream:Af,streamId:s,reason:wrapReason(e)});return t.promise}},a)}#Kt(e){const t=e.streamId,a=this.sourceName,n=e.sourceName,s=this.comObj,r=this,i=this.actionHandler[e.action],o={enqueue(e,r=1,i){if(this.isCancelled)return;const o=this.desiredSize;this.desiredSize-=r;if(o>0&&this.desiredSize<=0){this.sinkCapability=Promise.withResolvers();this.ready=this.sinkCapability.promise}s.postMessage({sourceName:a,targetName:n,stream:If,streamId:t,chunk:e},i)},close(){if(!this.isCancelled){this.isCancelled=!0;s.postMessage({sourceName:a,targetName:n,stream:Cf,streamId:t});delete r.streamSinks[t]}},error(e){assert(e instanceof Error,"error must have a valid reason");if(!this.isCancelled){this.isCancelled=!0;s.postMessage({sourceName:a,targetName:n,stream:Ff,streamId:t,reason:wrapReason(e)})}},sinkCapability:Promise.withResolvers(),onPull:null,onCancel:null,isCancelled:!1,desiredSize:e.desiredSize,ready:null};o.sinkCapability.resolve();o.ready=o.sinkCapability.promise;this.streamSinks[t]=o;Promise.try(i,e.data,o).then(function(){s.postMessage({sourceName:a,targetName:n,stream:Rf,streamId:t,success:!0})},function(e){s.postMessage({sourceName:a,targetName:n,stream:Rf,streamId:t,reason:wrapReason(e)})})}#Wt(e){const t=e.streamId,a=this.sourceName,n=e.sourceName,s=this.comObj,r=this.streamControllers[t],i=this.streamSinks[t];switch(e.stream){case Rf:e.success?r.startCall.resolve():r.startCall.reject(wrapReason(e.reason));break;case Of:e.success?r.pullCall.resolve():r.pullCall.reject(wrapReason(e.reason));break;case Tf:if(!i){s.postMessage({sourceName:a,targetName:n,stream:Of,streamId:t,success:!0});break}i.desiredSize<=0&&e.desiredSize>0&&i.sinkCapability.resolve();i.desiredSize=e.desiredSize;Promise.try(i.onPull||onFn).then(function(){s.postMessage({sourceName:a,targetName:n,stream:Of,streamId:t,success:!0})},function(e){s.postMessage({sourceName:a,targetName:n,stream:Of,streamId:t,reason:wrapReason(e)})});break;case If:assert(r,"enqueue should have stream controller");if(r.isClosed)break;r.controller.enqueue(e.chunk);break;case Cf:assert(r,"close should have stream controller");if(r.isClosed)break;r.isClosed=!0;r.controller.close();this.#Gt(r,t);break;case Ff:assert(r,"error should have stream controller");r.controller.error(wrapReason(e.reason));this.#Gt(r,t);break;case xf:e.success?r.cancelCall.resolve():r.cancelCall.reject(wrapReason(e.reason));this.#Gt(r,t);break;case Af:if(!i)break;const o=wrapReason(e.reason);Promise.try(i.onCancel||onFn,o).then(function(){s.postMessage({sourceName:a,targetName:n,stream:xf,streamId:t,success:!0})},function(e){s.postMessage({sourceName:a,targetName:n,stream:xf,streamId:t,reason:wrapReason(e)})});i.sinkCapability.reject(o);i.isCancelled=!0;delete this.streamSinks[t];break;default:throw new Error("Unexpected stream case")}}async#Gt(e,t){await Promise.allSettled([e.startCall?.promise,e.pullCall?.promise,e.cancelCall?.promise]);delete this.streamControllers[t]}destroy(){this.#Ut?.abort();this.#Ut=null}}async function writeObject(e,t,a,{encrypt:n=null,encryptRef:s=null}){const r=n&&s!==e?n.createCipherTransform(e.num,e.gen):null;a.push(`${e.num} ${e.gen} obj\n`);await writeValue(t,a,r);a.push("\nendobj\n")}async function writeDict(e,t,a){t.push("<<");for(const[n,s]of e.getRawEntries()){t.push(` /${escapePDFName(n)} `);await writeValue(s,t,a)}t.push(">>")}async function writeValue(e,t,a){if(e instanceof Name)t.push(`/${escapePDFName(e.name)}`);else if(e instanceof Ref)t.push(`${e.num} ${e.gen} R`);else if(Array.isArray(e)||ArrayBuffer.isView(e))await async function writeArray(e,t,a){t.push("[");for(let n=0,s=e.length;n=256&&!o)try{const e=new CompressionStream("deflate"),t=e.writable.getWriter();await t.ready;t.write(n).then(async()=>{await t.ready;await t.close()}).catch(()=>{});n=await new Response(e.readable).bytes();let a,l;if(r){if(!o){a=Array.isArray(r)?[Name.get("FlateDecode"),...r]:[Name.get("FlateDecode"),r];i&&(l=Array.isArray(i)?[null,...i]:[null,i])}}else a=Name.get("FlateDecode");a&&s.set("Filter",a);l&&s.set("DecodeParms",l)}catch(e){info(`writeStream - cannot compress data: "${e}".`)}let l=bytesToString(n);a&&(l=a.encryptString(l));s.set("Length",l.length);await writeDict(s,t,a);t.push(" stream\n",l,"\nendstream")}(e,t,a):null===e?t.push("null"):warn(`Unhandled value in writer: ${typeof e}, please file a bug.`)}function writeInt(e,t,a,n){for(let s=t+a-1;s>a-1;s--){n[s]=255&e;e>>=8}return a+t}function writeString(e,t,a){const n=e.length;for(let s=0;s1&&(r=a.documentElement.searchNode([s.at(-1)],0));r?r.childNodes=Array.isArray(n)?n.map(e=>new SimpleDOMNode("value",e)):[new SimpleDOMNode("#text",n)]:warn(`Node not found for path: ${t}`)}const n=[];a.documentElement.dump(n);return n.join("")}(n.fetchIfRef(t).getString(),a)}const s=new StringStream(e);s.dict=new Dict(n);s.dict.setIfName("Type","EmbeddedFile");a.put(t,{data:s})}function getIndexes(e){const t=[];for(const{ref:a}of e)a.num===t.at(-2)+t.at(-1)?t[t.length-1]+=1:t.push(a.num,1);return t}function computeIDs(e,t,a){if(Array.isArray(t.fileIds)&&t.fileIds.length>0){const n=function computeMD5(e,t){const a=Math.floor(Date.now()/1e3),n=t.filename||"",s=[a.toString(),n,e.toString(),...t.infoMap.values()],r=Math.sumPrecise(s.map(e=>e.length)),i=new Uint8Array(r);let o=0;for(const e of s)o=writeString(e,o,i);return bytesToString(calculateMD5(i,0,i.length))}(e,t);a.set("ID",[t.fileIds[0]||n,n])}}async function incrementalUpdate({originalData:e,xrefInfo:t,changes:a,xref:n=null,hasXfa:s=!1,xfaDatasetsRef:r=null,hasXfaDatasetsEntry:i=!1,needAppearances:o,acroFormRef:l=null,acroForm:f=null,xfaData:c=null,useXrefStream:h=!1}){await async function updateAcroform({xref:e,acroForm:t,acroFormRef:a,hasXfa:n,hasXfaDatasetsEntry:s,xfaDatasetsRef:r,needAppearances:i,changes:o}){!n||s||r||warn("XFA - Cannot save it");if(!i&&(!n||!r||s))return;const l=t.clone();if(n&&!s){const e=t.get("XFA").slice();e.splice(2,0,"datasets");e.splice(3,0,r);l.set("XFA",e)}i&&l.set("NeedAppearances",!0);o.put(a,{data:l})}({xref:n,acroForm:f,acroFormRef:l,hasXfa:s,hasXfaDatasetsEntry:i,xfaDatasetsRef:r,needAppearances:o,changes:a});s&&updateXFA({xfaData:c,xfaDatasetsRef:r,changes:a,xref:n});const u=function getTrailerDict(e,t,a){const n=new Dict(null);n.setIfDefined("Prev",e?.startXRef);const s=e.newRef;if(a){t.put(s,{data:""});n.set("Size",s.num+1);n.setIfName("Type","XRef")}else n.set("Size",s.num);n.setIfDefined("Root",e?.rootRef);n.setIfDefined("Info",e?.infoRef);n.setIfDefined("Encrypt",e?.encryptRef);return n}(t,a,h),m=[],p=await async function writeChanges(e,t,a=[]){const n=[];for(const[s,{data:r,objStreamRef:i,index:o}]of e.items())if(i)n.push({ref:s,data:r,objStreamRef:i,index:o});else if(null!==r&&"string"!=typeof r){await writeObject(s,r,a,t);n.push({ref:s,data:a.join("")});a.length=0}else n.push({ref:s,data:r});return n.sort((e,t)=>e.ref.num-t.ref.num)}(a,n,m);let d=e.length;const g=e.at(-1);if(10!==g&&13!==g){m.push("\n");d+=1}for(const{data:e}of p)null!==e&&m.push(e);await(h?async function getXRefStreamTable(e,t,a,n,s){const r=[];let i=0,o=0;for(const{ref:e,data:n,objStreamRef:s,index:l}of a){let a;i=Math.max(i,t);if(s){a=l;r.push([2,s.num,a])}else if(null!==n){a=Math.min(e.gen,65535);r.push([1,t,a]);t+=n.length}else{a=Math.min(e.gen+1,65535);r.push([0,0,a])}o=Math.max(o,a)}n.set("Index",getIndexes(a));const l=[1,getSizeInBytes(i),getSizeInBytes(o)];n.set("W",l);computeIDs(t,e,n);const f=Math.sumPrecise(l),c=new Uint8Array(f*r.length),h=new Stream(c);h.dict=n;let u=0;for(const[e,t,a]of r){u=writeInt(e,l[0],u,c);u=writeInt(t,l[1],u,c);u=writeInt(a,l[2],u,c)}await writeObject(e.newRef,h,s,{});s.push("startxref\n",t.toString(),"\n%%EOF\n")}(t,d,p,u,m):async function getXRefTable(e,t,a,n,s){s.push("xref\n");const r=getIndexes(a);let i=0;for(const{ref:e,data:n}of a){if(e.num===r[i]){s.push(`${r[i]} ${r[i+1]}\n`);i+=2}if(null!==n){s.push(`${t.toString().padStart(10,"0")} ${Math.min(e.gen,65535).toString().padStart(5,"0")} n\r\n`);t+=n.length}else s.push(`0000000000 ${Math.min(e.gen+1,65535).toString().padStart(5,"0")} f\r\n`)}computeIDs(t,e,n);s.push("trailer\n");await writeDict(n,s,null);s.push("\nstartxref\n",t.toString(),"\n%%EOF\n")}(t,d,p,u,m));const b=e.length+Math.sumPrecise(m.map(e=>e.length)),w=new Uint8Array(b);w.set(e);let j=e.length;for(const e of m)j=writeString(e,j,w);return w}class PageData{constructor(e,t){this.page=e;this.documentData=t;this.annotations=null;this.pointingNamedDestinations=null;t.pagesMap.put(e.ref,this)}}class DocumentData{constructor(e){this.document=e;this.destinations=null;this.pageLabels=null;this.pagesMap=new RefSetCache;this.oldRefMapping=new RefSetCache;this.dedupNamedDestinations=new Map;this.usedNamedDestinations=new Set;this.postponedRefCopies=new RefSetCache;this.usedStructParents=new Set;this.oldStructParentMapping=new Map;this.structTreeRoot=null;this.parentTree=null;this.idTree=null;this.roleMap=null;this.classMap=null;this.namespaces=null;this.structTreeAF=null;this.structTreePronunciationLexicon=[];this.acroForm=null;this.acroFormDefaultAppearance="";this.acroFormDefaultResources=null;this.acroFormQ=0;this.hasSignatureAnnotations=!1;this.fieldToParent=new RefSetCache;this.outline=null;this.embeddedFiles=null}}class XRefWrapper{constructor(e,t){this.entries=e;this._getNewRef=t}fetch(e){return e instanceof Ref?this.entries[e.num]:e}fetchIfRefAsync(e){return Promise.resolve(this.fetch(e))}fetchIfRef(e){return this.fetch(e)}fetchAsync(e){return Promise.resolve(this.fetch(e))}getNewTemporaryRef(){return this._getNewRef()}}class PDFEditor{hasSingleFile=!1;isSingleFile=!1;#Vt=null;currentDocument=null;oldPages=[];newPages=[];xref=[null];xrefWrapper=new XRefWrapper(this.xref,()=>this.newRef);newRefCount=1;namesDict=null;version="1.7";pageLabels=null;namedDestinations=new Map;parentTree=new Map;structTreeKids=[];idTree=new Map;classMap=new Dict;roleMap=new Dict;namespaces=new Map;structTreeAF=[];structTreePronunciationLexicon=[];fields=[];acroFormDefaultAppearance="";acroFormDefaultResources=null;acroFormNeedAppearances=!1;acroFormSigFlags=0;acroFormCalculationOrder=null;acroFormQ=0;outlineItems=null;embeddedFiles=new Map;constructor({useObjectStreams:e=!0,title:t="",author:a=""}={}){[this.rootRef,this.rootDict]=this.newDict;[this.infoRef,this.infoDict]=this.newDict;[this.pagesRef,this.pagesDict]=this.newDict;this.useObjectStreams=e;this.objStreamRefs=e?new Set:null;this.title=t;this.author=a}get newRef(){return Ref.get(this.newRefCount++,0)}get newDict(){const e=this.newRef;return[e,this.xref[e.num]=new Dict]}async#$t(e,t){const a=this.newRef;this.xref[a.num]=await this.#Yt(e,!0,t);return a}cloneDict(e){const t=e.clone();t.xref=this.xrefWrapper;return t}async#Yt(e,t,a){if(e instanceof Ref){const{currentDocument:{oldRefMapping:t}}=this;let n=t.get(e);if(n)return n;const s=e;if("number"==typeof(e=await a.fetchAsync(s)))return e;n=this.newRef;t.put(s,n);this.xref[n.num]=await this.#Yt(e,!0,a);return n}const n=[],{currentDocument:{postponedRefCopies:s}}=this;if(Array.isArray(e)){t&&(e=e.slice());for(let t=0,r=e.length;te[t]=a):n.push(this.#Yt(e[t],!0,a).then(a=>e[t]=a))}await Promise.all(n);return e}let r;if(e instanceof BaseStream){({dict:r}=e=e.getOriginalStream().clone());r.xref=this.xrefWrapper}else if(e instanceof Dict){t&&((e=e.clone()).xref=this.xrefWrapper);r=e}if(r){for(const[e,t]of r.getRawEntries()){const i=t instanceof Ref&&s.get(t);i?i.push(t=>r.set(e,t)):n.push(this.#Yt(t,!0,a).then(t=>r.set(e,t)))}await Promise.all(n)}return e}async#Jt(e,t,a,n,s,r,i,o=new RefSet){const{currentDocument:{pagesMap:l,oldRefMapping:f}}=this,c=t.getRaw("Pg");if(c instanceof Ref&&!l.has(c))return null;let h;const u=h=t.getRaw("K");if(u instanceof Ref){if(o.has(u))return null;h=await a.fetchAsync(u);Array.isArray(h)||(h=[u])}h=Array.isArray(h)?h:[h];const m=[],p=[];for(let t of h){const c=t instanceof Ref?t:null;if(c){if(o.has(c))continue;o.put(c);t=await a.fetchAsync(c)}if("number"==typeof t){m.push(t);continue}if(!(t instanceof Dict))continue;const h=t.getRaw("Pg");if(h instanceof Ref&&!l.has(h))continue;const u=t.get("Type");if(!u||isName(u,"StructElem")){let e=!1;if(c&&n.has(c)){if(!isName(t.get("S"),"Link"))continue;e=!0}const l=await this.#Jt(c,t,a,n,s,r,i,o);if(l){p.push(m.length);m.push(l);c&&f.put(c,l);e&&this.xref[l.num].setIfName("S","Span")}continue}if(isName(u,"OBJR")){if(!c)continue;const t=f.get(c);if(!t)continue;const a=this.xref[t.num].getRaw("Obj");if(a instanceof Ref){const t=this.xref[a.num];if(t instanceof Dict&&!t.has("StructParent")&&e){const a=this.parentTree.size;this.parentTree.set(a,[f,e]);t.set("StructParent",a)}}m.push(t);continue}if(isName(u,"MCR")){const e=await this.#Yt(c||t,!0,a);m.push(e);continue}if(c){const e=await this.#Yt(c,!0,a);m.push(e)}}if(0!==h.length&&0===m.length)return null;const d=this.newRef,g=this.xref[d.num]=this.cloneDict(t);g.delete("ID");g.delete("C");g.delete("K");g.delete("P");g.delete("S");await this.#Yt(g,!1,a);const b=t.get("C");if(b instanceof Name){const e=r.get(b.name);e?g.set("C",Name.get(e)):g.set("C",b)}else if(Array.isArray(b)){const e=[];for(const t of b)if(t instanceof Name){const a=r.get(t.name);a?e.push(Name.get(a)):e.push(t)}g.set("C",e)}const w=t.get("S");if(w instanceof Name){const e=i.get(w.name);e?g.set("S",Name.get(e)):g.set("S",w)}const j=t.get("ID");if("string"==typeof j){const e=stringToPDFString(j,!1),t=s.get(e);t?g.set("ID",stringToAsciiOrUTF16BE(t)):g.set("ID",j)}let k=g.get("A");if(k){Array.isArray(k)||(k=[k]);for(let e of k){e=this.xrefWrapper.fetch(e);if(isName(e.get("O"),"Table")&&e.has("Headers")){const t=this.xrefWrapper.fetch(e.getRaw("Headers"));if(Array.isArray(t))for(let e=0,a=t.length;e1&&g.set("K",m);return d}#Qt({document:e,includePages:t,excludePages:a}){if(!e)return[];let n,s,r,i;for(const e of t||[])Array.isArray(e)?(s||=[]).push(e):(n||=new Set).add(e);for(const e of a||[])Array.isArray(e)?(i||=[]).push(e):(r||=new Set).add(e);const o=[];for(let t=0,a=e.numPages;t=a&&t<=n){e=!0;break}if(e)continue}let e=!1;n&&(e=n.has(t));if(!e&&s)for(const[a,n]of s)if(t>=a&&t<=n){e=!0;break}e||n||s||(e=!0);e&&o.push(t)}return o}#Zt(e){const t=[],a=[];for(let n=0;ne.insertAfter-t.insertAfter);if(a.length>0)for(const t of e){if(!t.document||!t.pageIndices)continue;const e=this.#Qt(t).length;if(t.pageIndices.length0&&e.some(e=>e.document&&e.pageIndices);if(0===t.length&&n){const t=e.slice();let n=-1;for(const t of e)if(t.document&&t.pageIndices)for(const e of t.pageIndices)e>n&&(n=e);let s=0;for(const{i:e,insertAfter:r,count:i}of a){const a=Math.min(Math.max(r,-1)+s,n);for(let e=0;ee<=a)&&(t[e]={...n,pageIndices:n.pageIndices.map(e=>e>a?e+i:e)})}const o=[];for(let e=0;e{if(!e.document||e.pageIndices)return e;const a={...e,pageIndices:r[t]||[]};delete a.insertAfter;return a})}async extractPages(e,t,a,n){e.some(e=>void 0!==e.insertAfter)&&(e=this.#Zt(e));const s=[];let r=0;this.isSingleFile=1===e.length||e.every(t=>t.document===e[0].document);this.hasSingleFile=1===e.length;const i=[];t&&(this.#Vt={handler:a,task:n,newAnnotationsByPage:getNewAnnotationsMap(t),imagesPromises:AnnotationFactory.generateImages(t.values(),this.xrefWrapper,!0)});for(const{document:t,includePages:a,excludePages:n,pageIndices:o}of e){if(!t)continue;o&&(r=-1);const e=new DocumentData(t);i.push(e);s.push(this.#ea(e));let l=0;for(const i of this.#Qt({document:t,includePages:a,excludePages:n})){let a;o&&(a=o[l++]);if(void 0===a)if(-1!==r)a=r++;else for(a=0;void 0!==this.oldPages[a];a++);this.oldPages[a]=null;s.push(t.getPage(i).then(t=>{this.oldPages[a]=new PageData(t,e)}))}}await Promise.all(s);s.length=0;this.#ta(i);this.#aa(i);this.#na();for(const e of this.oldPages)s.push(this.#sa(e));await Promise.all(s);this.#ra();this.#ia(i);for(let e=0,t=this.oldPages.length;ee.destinations=t),t.ensureCatalog("rawPageLabels").then(t=>e.pageLabels=t),t.ensureCatalog("structTreeRoot").then(t=>e.structTreeRoot=t),t.ensureCatalog("acroForm").then(t=>e.acroForm=t),t.ensureCatalog("documentOutlineForEditor").then(t=>e.outline=t),t.ensureCatalog("rawEmbeddedFiles").then(t=>e.embeddedFiles=t)]);const n=e.structTreeRoot;if(n){const t=n.dict,s=t.get("ParentTree");if(s){const t=new NumberTree(s,a);e.parentTree=t.getAll(!0)}const r=t.get("IDTree");if(r){const t=new NameTree(r,a);e.idTree=t.getAll(!0)}e.roleMap=t.get("RoleMap")||null;e.classMap=t.get("ClassMap")||null;let i=t.get("Namespaces")||null;i&&!Array.isArray(i)&&(i=[i]);e.namespaces=i;e.structTreeAF=t.get("AF")||null;e.structTreePronunciationLexicon=t.get("PronunciationLexicon")||null}}async#sa(e){const{page:{xref:t,annotations:a},documentData:{pagesMap:n,destinations:s,usedNamedDestinations:r,fieldToParent:i}}=e;if(!a)return;const o=[];let l=[],f=0,{hasSignatureAnnotations:c}=e.documentData;for(const e of a){const a=f++;o.push(t.fetchIfRefAsync(e).then(async t=>{if(!isName(t.get("Subtype"),"Link")){if(isName(t.get("Subtype"),"Widget")){c||=isName(t.get("FT"),"Sig");const a=t.get("Parent")||null;t.delete("Parent");i.put(e,a)}l[a]=e;return}const o=t.get("A"),f=o instanceof Dict?o.get("D"):t.get("Dest");if(f&&(!Array.isArray(f)||f[0]instanceof Ref&&!n.has(f[0]))){if("string"==typeof f){const t=stringToPDFString(f,!0);if(s.has(t)){l[a]=e;r.add(t)}}}else l[a]=e}))}await Promise.all(o);l=l.filter(e=>!!e);e.annotations=l.length>0?l:null;e.documentData.hasSignatureAnnotations||=c}#ia(e){for(const{postponedRefCopies:t,pagesMap:a}of e)for(const e of a.keys())t.put(e,[])}#la(e){for(const{postponedRefCopies:t,oldRefMapping:a}of e){for(const[e,n]of t.items()){const t=a.get(e);for(const e of n)e(t)}t.clear()}}#ma(e,t,a=new RefSet){if(e instanceof Ref){if(!a.has(e)){a.put(e);this.#ma(this.xref[e.num],t,a)}return}if(Array.isArray(e)){for(const n of e)this.#ma(n,t,a);return}let n;e instanceof BaseStream?({dict:n}=e):e instanceof Dict&&(n=e);if(n){t(n);for(const e of n.getRawValues())this.#ma(e,t,a)}}async#fa(e){let t=0;const{parentTree:a}=this;for(let e=0,n=this.newPages.length;e{const l=e.get("StructParent")??e.get("StructParents");if("number"!=typeof l)return;i.add(l);let f=n.get(l);const c=f instanceof Ref?f:null;if(c){const e=o.fetch(c);Array.isArray(e)&&(f=e)}Array.isArray(f)&&f.every(e=>null===e)&&(f=null);if(!f){e.has("StructParent")?e.delete("StructParent"):e.delete("StructParents");return}let h=r.get(l);if(void 0===h){h=t++;r.set(l,h);a.set(h,[s,f])}e.has("StructParent")?e.set("StructParent",h):e.set("StructParents",h)},c)}const{structTreeKids:n,idTree:s,classMap:r,roleMap:i,namespaces:o,structTreeAF:l,structTreePronunciationLexicon:f}=this;for(const t of e){const{document:{xref:e},oldRefMapping:a,parentTree:c,usedStructParents:h,structTreeRoot:u,idTree:m,classMap:p,roleMap:d,namespaces:g,structTreeAF:b,structTreePronunciationLexicon:w}=t;if(!u)continue;this.currentDocument=t;const j=new RefSet;for(const[e,t]of c||[])!h.has(e)&&t instanceof Ref&&j.put(t);const k=new Map;for(const[e,t]of m||[]){let a=e;if(s.has(e))for(let t=1;;t++){const n=`${e}_${t}`;if(!s.has(n)){k.set(e,n);a=n;break}}s.set(a,t)}const y=new Map;if(p?.size>0)for(let[t,a]of p){a=await this.#Yt(a,!0,e);if(r.has(t))for(let e=1;;e++){const a=`${t}_${e}`;if(!r.has(a)){y.set(t,a);t=a;break}}r.set(t,a)}const q=new Map;if(d?.size>0)for(const[e,t]of d){const a=i.get(e);if(a){if(a!==t)for(let a=1;;a++){const n=`${e}_${a}`;if(!i.has(n)){q.set(e,n);i.set(n,t);break}}}else i.set(e,t)}if(g?.length>0)for(const t of g){const a=await e.fetchIfRefAsync(t);let n=a.get("NS");if(!n||o.has(n))continue;n=stringToPDFString(n,!1);const s=await this.#Yt(a,!0,e);o.set(n,s)}if(b)for(const t of b)l.push(await this.#Yt(t,!0,e));if(w)for(const t of w)f.push(await this.#Yt(t,!0,e));let v=u.dict.get("K");if(v){v=Array.isArray(v)?v:[v];for(let t of v){const a=t instanceof Ref?t:null;if(a&&j.has(a))continue;t=await e.fetchIfRefAsync(t);const s=await this.#Jt(a,t,e,j,k,y,q);s&&n.push(s)}for(const[e,t]of m||[]){const n=t instanceof Ref&&a.get(t),r=k.get(e)||e;n?s.set(r,n):s.delete(r)}}}for(const[e,[t,n]]of a){if(!n){a.delete(e);continue}if(!Array.isArray(n)){const s=t.get(n);void 0===s?a.delete(e):a.set(e,s);continue}const s=n.map(e=>e instanceof Ref&&t.get(e)||null);0===s.length||s.every(e=>null===e)?a.delete(e):a.set(e,s)}this.currentDocument=null}#ta(e){for(const t of e){if(!t.destinations)continue;const{destinations:e,pagesMap:a}=t,n=t.destinations=new Map;for(const[t,s]of Object.entries(e)){const e=s[0],r=e instanceof Ref&&a.get(e);if(r){(r.pointingNamedDestinations||=new Set).add(t);n.set(t,s)}}}}#ra(){const{namedDestinations:e}=this,getUniqueDestinationName=t=>{if(!e.has(t))return t;for(let a=1;;a++){const n=`${t}_${a}`;if(!e.has(n))return n}};for(let t=0,a=this.oldPages.length;t{"string"==typeof n&&e.set(a,t.get(stringToPDFString(n,!0))||n)};for(const t of e){const e=this.xref[t.num];if(!isName(e.get("Subtype"),"Link"))continue;const a=e.get("A");if(a instanceof Dict&&a.has("D")){const e=a.get("D");fixDestination(a,"D",e);continue}const n=e.get("Dest");fixDestination(e,"Dest",n)}}#aa(e){const collect=(e,t,a)=>{for(const n of e){"string"==typeof n.dest&&t?.has(n.dest)&&a.add(n.dest);n.items.length>0&&collect(n.items,t,a)}};for(const t of e){const{outline:e,destinations:a,usedNamedDestinations:n}=t;e?.length&&collect(e,a,n)}}#da(e,t){const{dest:a,action:n,url:s,unsafeUrl:r,attachment:i,setOCGState:o}=e;if(n||s||r||i||o)return!0;if(!a)return!1;if("string"==typeof a){const e=t.dedupNamedDestinations.get(a)||a;return this.namedDestinations.has(e)}return!!(Array.isArray(a)&&a[0]instanceof Ref)&&!!t.oldRefMapping.get(a[0])}#ga(e,t){const a=[];for(const n of e){const e=this.#ga(n.items,t),s=this.#da(n,t);(s||e.length>0)&&a.push({...n,dest:s?n.dest:null,rawDict:s?n.rawDict:null,items:e,_documentData:t})}return a}#ha(e){const t=[];for(const a of e){const{outline:e}=a;e?.length&&t.push(...this.#ga(e,a))}this.outlineItems=t.length>0?t:null}async#ba(e,t){const{dest:a,rawDict:n}=t,s=t._documentData;if(a){if("string"==typeof a){const t=s.dedupNamedDestinations.get(a)||a;e.set("Dest",stringToAsciiOrUTF16BE(t))}else if(Array.isArray(a)){const t=a.slice();t[0]instanceof Ref&&(t[0]=s.oldRefMapping.get(t[0])||t[0]);e.set("Dest",t)}return}const r=n?.get("A");if(r instanceof Dict){this.currentDocument=s;const t=await this.#$t(r,s.document.xref);this.currentDocument=null;e.set("A",t)}}async#wa(){const{outlineItems:e}=this;if(!e?.length)return;const[t,a]=this.newDict;a.setIfName("Type","Outlines");const assignRefs=e=>{for(const t of e){[t._ref]=this.newDict;t.items.length>0&&assignRefs(t.items)}};assignRefs(e);const fillItems=async(e,t)=>{let a=0;for(let n=0;n0&&r.set("Prev",e[n-1]._ref);n0){r.set("First",s.items[0]._ref);r.set("Last",s.items.at(-1)._ref);const e=await fillItems(s.items,s._ref);void 0!==s.count&&r.set("Count",s.count<0?-e:e);a+=void 0!==s.count&&s.count<0?1:e+1}else a+=1;await this.#ba(r,s);const i=(s.bold?2:0)|(s.italic?1:0);0!==i&&r.set("F",i);!s.color||0===s.color[0]&&0===s.color[1]&&0===s.color[2]||r.set("C",[s.color[0]/255,s.color[1]/255,s.color[2]/255])}return a},n=await fillItems(e,t);a.set("First",e[0]._ref);a.set("Last",e.at(-1)._ref);a.set("Count",n);this.rootDict.set("Outlines",t)}async#ca(e){this.#ja(e);this.#ka(e);this.#ya(e);await this.#qa(e);const t=this.fields;for(const a of e){let e=a.acroForm?.get("Fields")||null;!e&&a.fieldToParent.size>0&&(e=this.#va(a.fieldToParent,a.document.xref));if(Array.isArray(e)&&e.length>0){this.currentDocument=a;await this.#Sa(t,e);this.currentDocument=null}}this.#Aa(e)}#ya(e){let t=0,a=null;for(const n of e){const e=n.acroForm?.get("Q");if("number"==typeof e&&0!==e)if(a?.acroFormQ>0)n.acroFormQ=e;else if(0!==t){if(e!==t){a.acroFormQ||=t;n.acroFormQ=e;t=0}}else{t=e;a=n}}t>0&&(this.acroFormQ=t)}#ja(e){let t=0,a=!1;for(const n of e){if(!n.acroForm)continue;const e=n.acroForm.get("SigFlags");"number"==typeof e&&n.hasSignatureAnnotations&&(t|=e);!0===n.acroForm.get("NeedAppearances")&&(a=!0)}this.acroFormSigFlags=t;this.acroFormNeedAppearances=a}#Aa(e){const t=[];for(const a of e){const e=a.acroForm?.get("CO")||null;if(!Array.isArray(e))continue;const{oldRefMapping:n}=a;for(const a of e){const e=a instanceof Ref&&n.get(a);e&&t.push(e)}}this.acroFormCalculationOrder=t.length>0?t:null}#ka(e){let t=null,a=null;for(const n of e){const e=n.acroForm?.get("DA")||null;if(e&&"string"==typeof e)if(a?.acroFormDefaultAppearance)n.acroFormDefaultAppearance=e;else if(t){if(e!==t){a.acroFormDefaultAppearance||=t;n.acroFormDefaultAppearance=e;t=null}}else{t=e;a=n}}t&&(this.acroFormDefaultAppearance=t)}async#qa(e){let t=null,a=null,n=null;for(const s of e){const e=s.acroForm?.get("DR")||null;if(e&&e instanceof Dict)if(n?.acroFormDefaultResources)s.acroFormDefaultResources=e;else if(t){if(!deepCompare(t,e)){n.acroFormDefaultResources||=t;s.acroFormDefaultResources=e;t=null;a=null}}else{t=e;a=s.acroForm.getRaw("DR");n=s}}if(t){this.currentDocument=n;this.acroFormDefaultResources=await this.#Yt(a,!0,n.document.xref);this.currentDocument=null}}#va(e,t){const a=[],n=new RefSet;for(const[s,r]of e){if(!r){a.push(s);continue}let e=r,i=r;for(;;){e=t.fetchIfRef(e)?.getRaw("Parent")||null;if(!e)break;i=e}if(i instanceof Ref&&!n.has(i)){a.push(i);n.put(i)}}return a}async#Sa(e,t){const a=new RefSet,n=[{kids:t,newKids:e,pos:0,oldParentRef:null,parentRef:null,parent:null}],{document:{xref:s},oldRefMapping:r,fieldToParent:i,acroFormDefaultAppearance:o,acroFormDefaultResources:l,acroFormQ:f}=this.currentDocument,c=[],h=[];for(;n.length>0;){const e=n.at(-1),{kids:t,newKids:u,parent:m,pos:p}=e;if(p===t.length){n.pop();if(0===u.length||!m)continue;const t=this.xref[e.parentRef.num]=this.cloneDict(m);t.delete("Parent");t.delete("Kids");await this.#Yt(t,!1,s);t.set("Kids",u);if(n.length>0){const a=n.at(-1);if(!a.parentRef&&a.oldParentRef){const e=a.parentRef=this.newRef;t.set("Parent",e);r.put(a.oldParentRef,e)}a.newKids.push(e.parentRef)}continue}const d=t[e.pos++];if(!(d instanceof Ref)||a.has(d))continue;a.put(d);const g=s.fetchIfRef(d);if(g.has("Kids")){const e=g.get("Kids");if(!Array.isArray(e))continue;n.push({kids:e,newKids:[],pos:0,oldParentRef:d,parentRef:null,parent:g});continue}if(!i.has(d))continue;const b=r.get(d);if(!b)continue;u.push(b);if(!e.parentRef&&e.oldParentRef){e.parentRef=this.newRef;r.put(e.oldParentRef,e.parentRef)}const w=this.xref[b.num];e.parentRef&&w.set("Parent",e.parentRef);o&&isName(w.get("FT"),"Tx")&&!w.has("DA")&&c.push(w);l&&!w.has("Kids")&&w.get("AP")instanceof Dict&&h.push(w);f&&!w.has("Q")&&w.set("Q",f)}for(const e of c){getInheritableProperty({dict:e,key:"DA"})||e.set("DA",o)}const u=new Map;for(const e of h){const t=e.get("AP");for(const[,e]of t){if(!(e instanceof BaseStream))continue;let t=e.dict.getRaw("Resources");if(!t){const t=await u.getOrInsertComputed(l,()=>this.#$t(l,s));e.dict.set("Resources",t);continue}t=s.fetchIfRef(t);for(const[e,a]of l.getRawEntries())if(!t.has(e)){let n=a;a instanceof Ref?n=await this.#Yt(a,!0,s):(a instanceof Dict||a instanceof BaseStream||Array.isArray(a))&&(n=await u.getOrInsertComputed(a,()=>this.#$t(a,s)));t.set(e,n)}}}}async#na(){if(!this.hasSingleFile)return;const{documentData:{document:e,pageLabels:t}}=this.oldPages[0];if(!t)return;const a=e.numPages,n=[],s=new Set(this.oldPages.map(({page:{pageIndex:e}})=>e));let r=null,i=-1;for(let e=0;ee!==f[t])&&m.set(e,a)}const d=t.userUnit;1!==d&&m.set("UserUnit",d);m.setIfDict("Resources",await this.#Yt(c,!0,o));let g=null;if(n){const e=await this.#Yt(n,!0,o);this.#pa(e,r);Array.isArray(e)&&e.length>0&&(g=e)}const b=this.#Vt?.newAnnotationsByPage?.get(e);if(b){const{handler:e,task:a,imagesPromises:n}=this.#Vt,s=new RefSetCache,r=await AnnotationFactory.saveNewAnnotations(t.createAnnotationEvaluator(e),this.xrefWrapper,a,b,n,s);for(const[e,{data:t}]of s.items())this.xref[e.num]=t;g||=[];for(const{ref:e}of r.annotations)g.push(e)}m.setIfArray("Annots",g);if(this.useObjectStreams){const e=this.newRefCount,t=[];for(let a=p;a0;){const{dict:e,kids:t,parentRef:a}=s.pop();if(t.length<=16){e.set("Kids",t);for(const e of t)this.xref[e.num].set("Parent",a);continue}const n=Math.max(16,Math.ceil(t.length/16)),r=[];for(let e=0;ee.localeCompare(t):([e],[t])=>e-t),[n,s]=this.newDict,r=[{dict:s,entries:a,isRoot:!0}],i=t?"Names":"Nums";for(;r.length>0;){const{dict:e,entries:t,isRoot:a}=r.pop();if(t.length<=64){a||e.set("Limits",[t[0][0],t.at(-1)[0]]);e.set(i,t.flat());continue}const n=[],s=Math.max(64,Math.ceil(t.length/64));for(let e=0;e0){const e=this.#Ca(Array.from(this.parentTree.entries()),!1);this.xref[e.num].setIfName("Type","ParentTree");n.set("ParentTree",e);n.set("ParentTreeNextKey",this.parentTree.size)}if(this.idTree.size>0){const e=this.#Ca(Array.from(this.idTree.entries()),!0);this.xref[e.num].setIfName("Type","IDTree");n.set("IDTree",e)}if(this.classMap.size>0){const e=this.newRef;this.xref[e.num]=this.classMap;n.set("ClassMap",e)}if(this.roleMap.size>0){const e=this.newRef;this.xref[e.num]=this.roleMap;n.set("RoleMap",e)}if(this.namespaces.size>0){const e=this.newRef;this.xref[e.num]=Array.from(this.namespaces.values());n.set("Namespaces",e)}if(this.structTreeAF.length>0){const e=this.newRef;this.xref[e.num]=this.structTreeAF;n.set("AF",e)}if(this.structTreePronunciationLexicon.length>0){const e=this.newRef;this.xref[e.num]=this.structTreePronunciationLexicon;n.set("PronunciationLexicon",e)}t.set("StructTreeRoot",a)}#Ra(){if(0===this.fields.length)return;const{rootDict:e}=this,t=this.newRef,a=this.xref[t.num]=new Dict;e.set("AcroForm",t);a.set("Fields",this.fields);this.acroFormNeedAppearances&&a.set("NeedAppearances",!0);this.acroFormSigFlags>0&&a.set("SigFlags",this.acroFormSigFlags);a.setIfArray("CO",this.acroFormCalculationOrder);a.setIfDict("DR",this.acroFormDefaultResources);this.acroFormDefaultAppearance&&a.set("DA",this.acroFormDefaultAppearance);this.acroFormQ>0&&a.set("Q",this.acroFormQ)}async#Ha(){const{rootDict:e}=this;e.setIfName("Type","Catalog");e.setIfName("Version",this.version);this.#Ra();this.#xa();this.#Ia();this.#Fa();this.#Ta();this.#Oa();await this.#wa()}#Ba(){const e=new Map;if(this.isSingleFile){const{xref:{trailer:t}}=this.oldPages[0].documentData.document,a=t.get("Info");for(const[t,n]of a||[])"string"==typeof n&&e.set(t,stringToPDFString(n))}e.delete("ModDate");e.set("CreationDate",getModificationDate());e.set("Creator","PDF.js");e.set("Producer","Firefox");this.author&&e.set("Author",this.author);this.title&&e.set("Title",this.title);for(const[t,a]of e)this.infoDict.set(t,stringToAsciiOrUTF16BE(a));return e}async#Da(){if(!this.isSingleFile)return[null,null,null];const{documentData:e}=this.oldPages[0],{document:{xref:{trailer:t,encrypt:a}}}=e;if(!t.has("Encrypt"))return[null,null,null];const n=t.get("Encrypt");if(!(n instanceof Dict))return[null,null,null];this.currentDocument=e;const s=[await this.#$t(n,t.xref),a,t.get("ID")];this.currentDocument=null;return s}async#Ma(){const e=new RefSetCache;e.put(Ref.get(0,65535),{data:null});for(let t=1,a=this.xref.length;t{this._contentLength=e.contentLength;this._isStreamingSupported=e.isStreamingSupported;this._isRangeSupported=e.isRangeSupported;this._headersCapability.resolve()},this._headersCapability.reject)}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class PDFWorkerStreamRangeReader extends BasePDFStreamRangeReader{_reader=null;constructor(e,t,a){super(e,t,a);const{msgHandler:n}=e._source,s=n.sendWithStream("GetRangeReader",{begin:t,end:a});this._reader=s.getReader()}async read(){const{value:e,done:t}=await this._reader.read();return t?{value:void 0,done:!0}:{value:e.buffer,done:!1}}cancel(e){this._reader.cancel(e)}}class WorkerTask{constructor(e){this.name=e;this.terminated=!1;this._capability=Promise.withResolvers()}get finished(){return this._capability.promise}finish(){this._capability.resolve()}terminate(){this.terminated=!0}ensureNotTerminated(){if(this.terminated)throw new Error("Worker task was terminated")}}class WorkerMessageHandler{static{"undefined"==typeof window&&!e&&"undefined"!=typeof self&&"function"==typeof self.postMessage&&"onmessage"in self&&this.initializeFromPort(self)}static setup(e,t){let a=!1;e.on("test",t=>{if(!a){a=!0;e.send("test",t instanceof Uint8Array)}});e.on("configure",e=>{!function setVerbosityLevel(e){Number.isInteger(e)&&(ta=e)}(e.verbosity)});e.on("GetDocRequest",e=>this.createDocumentHandler(e,t))}static createDocumentHandler(e,t){let a,n=!1,s=null;const r=new Set,i=getVerbosityLevel(),{docId:o,apiVersion:l}=e,f="5.7.284";if(l!==f)throw new Error(`The API version "${l}" does not match the Worker version "${f}".`);const buildMsg=(e,t)=>`The \`${e}.prototype\` contains unexpected enumerable property "${t}", thus breaking e.g. \`for...in\` iteration of ${e}s.`;for(const e in{})throw new Error(buildMsg("Object",e));for(const e in[])throw new Error(buildMsg("Array",e));const c=o+"_worker";let h=new MessageHandler(c,o,t);function ensureNotTerminated(){if(n)throw new Error("Worker was terminated")}function startWorkerTask(e){r.add(e)}function finishWorkerTask(e){e.finish();r.delete(e)}async function loadDocument(e){await a.ensureDoc("checkHeader");await a.ensureDoc("parseStartXRef");await a.ensureDoc("parse",[e]);await a.ensureDoc("checkFirstPage",[e]);await a.ensureDoc("checkLastPage",[e]);const t=await a.ensureDoc("isPureXfa");if(t){const e=new WorkerTask("loadXfaResources");startWorkerTask(e);await a.ensureDoc("loadXfaResources",[h,e]);finishWorkerTask(e)}const[n,s]=await Promise.all([a.ensureDoc("numPages"),a.ensureDoc("fingerprints")]);return{numPages:n,fingerprints:s,htmlForXfa:t?await a.ensureDoc("htmlForXfa"):null}}function setupDoc(e){function onSuccess(e){ensureNotTerminated();h.send("GetDoc",{pdfInfo:e})}function onFailure(e){if(!n)if(e instanceof PasswordException){const t=new WorkerTask(`PasswordException: response ${e.code}`);startWorkerTask(t);h.sendWithPromise("PasswordRequest",e).then(function({password:e}){finishWorkerTask(t);a.updatePassword(e);pdfManagerReady()}).catch(function(){finishWorkerTask(t);h.send("DocException",e)})}else h.send("DocException",wrapReason(e))}function pdfManagerReady(){ensureNotTerminated();loadDocument(!1).then(onSuccess,function(e){ensureNotTerminated();e instanceof XRefParseException?a.requestLoadedStream().then(function(){ensureNotTerminated();loadDocument(!0).then(onSuccess,onFailure)}):onFailure(e)})}ensureNotTerminated();(async function getPdfManager({data:e,password:t,disableAutoFetch:a,rangeChunkSize:n,docBaseUrl:r,enableXfa:i,evaluatorOptions:l}){const f={source:null,disableAutoFetch:a,docBaseUrl:r,docId:o,enableXfa:i,evaluatorOptions:l,handler:h,length:0,password:t,rangeChunkSize:n};if(e){f.source=e;return new LocalPdfManager(f)}const c=new PDFWorkerStream({msgHandler:h}),u=c.getFullReader(),{promise:m,resolve:p,reject:d}=Promise.withResolvers();let g,b=[];s=e=>c.cancelAllRequests(e);u.headersReady.then(()=>{if(u.isRangeSupported){f.source=c;f.length=u.contentLength;f.disableAutoFetch||=u.isStreamingSupported;g=new NetworkPdfManager(f);for(const e of b)g.sendProgressiveData(e);b=null;p(g);s=null}}).catch(e=>{d(e);s=null});(async function readData(){let e=0;for(;;){const{value:t,done:a}=await u.read();ensureNotTerminated();if(a)break;e+=t.byteLength;u.isStreamingSupported||h.send("DocProgress",{loaded:e,total:u.contentLength});g?g.sendProgressiveData(t):b.push(t)}if(!g){f.source=arrayBuffersToBytes(b);b=null;g=new LocalPdfManager(f);p(g)}s=null})().catch(e=>{d(e);s=null});return m})(e).then(function(e){if(n){e.terminate(new AbortException("Worker was terminated."));throw new Error("Worker was terminated")}a=e;a.requestLoadedStream(!0).then(e=>{h.send("DataLoaded",{length:e.bytes.byteLength})})}).then(pdfManagerReady,onFailure)}h.on("GetPage",function(e){return a.getPage(e.pageIndex).then(function(e){return Promise.all([a.ensure(e,"rotate"),a.ensure(e,"ref"),a.ensure(e,"userUnit"),a.ensure(e,"view")]).then(function([e,t,a,n]){return{rotate:e,ref:t,refStr:t?.toString()??null,userUnit:a,view:n}})})});h.on("GetPageIndex",function(e){const t=Ref.get(e.num,e.gen);return a.ensureCatalog("getPageIndex",[t])});h.on("GetDestinations",function(e){return a.ensureCatalog("destinations")});h.on("GetDestination",function(e){return a.ensureCatalog("getDestination",[e.id])});h.on("GetPageLabels",function(e){return a.ensureCatalog("pageLabels")});h.on("GetPageLayout",function(e){return a.ensureCatalog("pageLayout")});h.on("GetPageMode",function(e){return a.ensureCatalog("pageMode")});h.on("GetViewerPreferences",function(e){return a.ensureCatalog("viewerPreferences")});h.on("GetOpenAction",function(e){return a.ensureCatalog("openAction")});h.on("GetAttachments",function(e){return a.ensureCatalog("attachments")});h.on("GetDocJSActions",function(e){return a.ensureCatalog("jsActions")});h.on("GetPageJSActions",function({pageIndex:e}){return a.getPage(e).then(e=>a.ensure(e,"jsActions"))});h.on("GetAnnotationsByType",async function({types:e,pageIndexesToSkip:t}){const[n,s]=await Promise.all([a.ensureDoc("numPages"),a.ensureDoc("annotationGlobals")]);if(!s)return null;const r=[],i=[];let o=null;try{for(let l=0,f=n;lt&&t.collectAnnotationsByType(h,o,e,i,s)||[]))}await Promise.all(r);return(await Promise.all(i)).filter(e=>!!e)}finally{o&&finishWorkerTask(o)}});h.on("GetOutline",function(e){return a.ensureCatalog("documentOutline")});h.on("GetOptionalContentConfig",function(e){return a.ensureCatalog("optionalContentConfig")});h.on("GetPermissions",function(e){return a.ensureCatalog("permissions")});h.on("GetMetadata",function(e){return Promise.all([a.ensureDoc("documentInfo"),a.ensureCatalog("metadata"),a.ensureCatalog("hasStructTree")])});h.on("GetMarkInfo",function(e){return a.ensureCatalog("markInfo")});h.on("GetData",function(e){return a.requestLoadedStream().then(e=>e.bytes)});h.on("GetAnnotations",function({pageIndex:e,intent:t}){return a.getPage(e).then(function(a){const n=new WorkerTask(`GetAnnotations: page ${e}`);startWorkerTask(n);return a.getAnnotationsData(h,n,t).then(e=>{finishWorkerTask(n);return e},e=>{finishWorkerTask(n);throw e})})});h.on("GetFieldObjects",function(e){return a.ensureDoc("fieldObjects").then(e=>e?.allFields||null)});h.on("HasJSActions",function(e){return a.ensureDoc("hasJSActions")});h.on("GetCalculationOrderIds",function(e){return a.ensureDoc("calculationOrderIds")});h.on("ExtractPages",async function({pageInfos:e,annotationStorage:t}){if(!e){warn("extractPages: nothing to extract.");return null}Array.isArray(e)||(e=[e]);let n,s=0;for(const t of e)if(null===t.document)t.document=a.pdfDocument;else if(ArrayBuffer.isView(t.document)){const e=new LocalPdfManager({source:t.document,docId:`${o}_extractPages_${s++}`,handler:h,password:t.password??null,evaluatorOptions:Object.assign({},a.evaluatorOptions)});let n=!1,r=!0;for(;;)try{await e.requestLoadedStream();await e.ensureDoc("checkHeader");await e.ensureDoc("parseStartXRef");await e.ensureDoc("parse",[n]);break}catch(t){if(t instanceof XRefParseException){if(!1===n){n=!0;continue}r=!1;warn("extractPages: XRefParseException.")}else if(t instanceof PasswordException){const a=new WorkerTask(`PasswordException: response ${t.code}`);startWorkerTask(a);try{const{password:a}=await h.sendWithPromise("PasswordRequest",t);e.updatePassword(a)}catch{r=!1;warn("extractPages: invalid password.")}finally{finishWorkerTask(a)}}else{r=!1;warn("extractPages: invalid document.")}if(!r)break}r||(t.document=null);if(await e.ensureDoc("isPureXfa")){t.document=null;warn("extractPages does not support pure XFA documents.")}else t.document=e.pdfDocument}else warn("extractPages: invalid document.");try{const a=new PDFEditor;n=new WorkerTask(`ExtractPages: ${e.length} page(s)`);startWorkerTask(n);return await a.extractPages(e,t,h,n)}catch(e){warn(`extractPages: "${e}".`);return null}finally{n&&finishWorkerTask(n)}});h.on("SaveDocument",async function({isPureXfa:e,numPages:t,annotationStorage:n,filename:s}){const r=[a.requestLoadedStream(),a.ensureCatalog("acroForm"),a.ensureCatalog("acroFormRef"),a.ensureDoc("startXRef"),a.ensureDoc("xref"),a.ensureCatalog("structTreeRoot")],i=new RefSetCache,o=[],l=e?null:getNewAnnotationsMap(n),[f,c,u,m,p,d]=await Promise.all(r),g=p.trailer.getRaw("Root")||null;let b;if(l){d?await d.canUpdateStructTree({pdfManager:a,newAnnotationsByPage:l})&&(b=d):await StructTreeRoot.canCreateStructureTree({catalogRef:g,pdfManager:a,newAnnotationsByPage:l})&&(b=null);const e=AnnotationFactory.generateImages(n.values(),p,a.evaluatorOptions.isOffscreenCanvasSupported),t=void 0===b?o:[];for(const[n,s]of l)t.push(a.getPage(n).then(t=>{const a=new WorkerTask(`Save (editor): page ${n}`);startWorkerTask(a);return t.saveNewAnnotations(h,a,s,e,i).finally(function(){finishWorkerTask(a)})}));null===b?o.push(Promise.all(t).then(async()=>{await StructTreeRoot.createStructureTree({newAnnotationsByPage:l,xref:p,catalogRef:g,pdfManager:a,changes:i})})):b&&o.push(Promise.all(t).then(async()=>{await b.updateStructureTree({newAnnotationsByPage:l,pdfManager:a,changes:i})}))}if(e)o.push(a.ensureDoc("serializeXfaData",[n]));else for(let e=0;ee.needAppearances),y=c instanceof Dict&&c.get("XFA")||null;let q=null,v=!1;if(Array.isArray(y)){for(let e=0,t=y.length;e{p.resetNewTemporaryRef()})});h.on("GetOperatorList",function(e,t){const{pageId:n,pageIndex:s}=e;a.getPage(n).then(function(a){const n=new WorkerTask(`GetOperatorList: page ${s}`);startWorkerTask(n);const r=i>=ce?Date.now():0;a.getOperatorList({handler:h,sink:t,task:n,intent:e.intent,cacheKey:e.cacheKey,annotationStorage:e.annotationStorage,modifiedIds:e.modifiedIds,pageIndex:s}).then(function(e){finishWorkerTask(n);r&&info(`page=${s+1} - getOperatorList: time=${Date.now()-r}ms, len=${e.length}`);t.close()},function(e){finishWorkerTask(n);n.terminated||t.error(e)})})});h.on("GetTextContent",function(e,t){const{pageId:n,pageIndex:s,includeMarkedContent:r,disableNormalization:o}=e;a.getPage(n).then(function(e){const a=new WorkerTask("GetTextContent: page "+s);startWorkerTask(a);const n=i>=ce?Date.now():0;e.extractTextContent({handler:h,task:a,sink:t,includeMarkedContent:r,disableNormalization:o}).then(function(){finishWorkerTask(a);n&&info(`page=${s+1} - getTextContent: time=`+(Date.now()-n)+"ms");t.close()},function(e){finishWorkerTask(a);a.terminated||t.error(e)})})});h.on("GetStructTree",function(e){return a.getPage(e.pageIndex).then(e=>a.ensure(e,"getStructTree"))});h.on("FontFallback",function(e){return a.fontFallback(e.id,h)});h.on("Cleanup",function(e){return a.cleanup(!0)});h.on("Terminate",async function(e){n=!0;const t=[];if(a){a.terminate(new AbortException("Worker was terminated."));const e=a.cleanup();t.push(e);a=null}else clearGlobalCaches();s?.(new AbortException("Worker was terminated."));for(const e of r){t.push(e.finished);e.terminate()}await Promise.all(t);h.destroy();h=null});h.on("Ready",function(t){setupDoc(e);e=null});return c}static initializeFromPort(e){const t=new MessageHandler("worker","main",e);this.setup(t,e);t.send("ready",null)}}globalThis.pdfjsWorker={WorkerMessageHandler};export{WorkerMessageHandler}; \ No newline at end of file diff --git a/src/assets/shapes.svg b/src/assets/shapes.svg new file mode 100644 index 0000000..d370b4d --- /dev/null +++ b/src/assets/shapes.svg @@ -0,0 +1 @@ + diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 0000000..04b84d5 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,7 @@ +export const environment = { + production: true, + contactEmail: 'info@canticristiani.it', + appName: 'CantiCristiani', + apiAuthUser: 'canti', + apiAuthPass: 'antani2026' +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..9c277a7 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,20 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, + contactEmail: 'info@canticristiani.it', + appName: 'CantiCristiani', + apiAuthUser: 'canti', + apiAuthPass: 'antani2026' +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. diff --git a/src/global.scss b/src/global.scss new file mode 100644 index 0000000..bdd8598 --- /dev/null +++ b/src/global.scss @@ -0,0 +1,528 @@ +/* + * App Global CSS + * ---------------------------------------------------------------------------- + * Put style rules here that you want to apply globally. These styles are for + * the entire app and not just one component. Additionally, this file can be + * used as an entry point to import other CSS/Sass files to be included in the + * output CSS. + * For more information on global stylesheets, visit the documentation: + * https://ionicframework.com/docs/layout/global-stylesheets + */ + +/* Core CSS required for Ionic components to work properly */ +@import "@ionic/angular/css/core.css"; + +/* Basic CSS for apps built with Ionic */ +@import "@ionic/angular/css/normalize.css"; +@import "@ionic/angular/css/structure.css"; +@import "@ionic/angular/css/typography.css"; +@import "@ionic/angular/css/display.css"; + +/* Optional CSS utils that can be commented out */ +@import "@ionic/angular/css/padding.css"; +@import "@ionic/angular/css/float-elements.css"; +@import "@ionic/angular/css/text-alignment.css"; +@import "@ionic/angular/css/text-transformation.css"; +@import "@ionic/angular/css/flex-utils.css"; + +/** + * Ionic Dark Mode + * ----------------------------------------------------- + * For more info, please see: + * https://ionicframework.com/docs/theming/dark-mode + */ + +/* @import "@ionic/angular/css/palettes/dark.always.css"; */ +/* @import "@ionic/angular/css/palettes/dark.system.css"; */ +@import "@ionic/angular/css/palettes/dark.class.css"; + +ion-header { + border: none !important; + --border-width: 0 !important; + box-shadow: none !important; + --box-shadow: none !important; + background: #121212 !important; +} + +ion-header::after, ion-header::before { + display: none !important; +} + +ion-toolbar { + --border-style: none !important; + border: none !important; + --border-width: 0 !important; + --box-shadow: none !important; + box-shadow: none !important; + --background: transparent !important; +} + +ion-toolbar::part(container) { + border: none !important; +} + +ion-app { + background: #121212 !important; +} + +/* High Contrast Mode Overrides */ +html.high-contrast, body.high-contrast { + color-scheme: light !important; +} + +body.high-contrast { + --ion-background-color: #ffffff; + --ion-background-color-rgb: 255, 255, 255; + --ion-text-color: #000000; + --ion-text-color-rgb: 0, 0, 0; + + /* Primary color - complete set for shadow DOM components */ + --ion-color-primary: #000000; + --ion-color-primary-rgb: 0, 0, 0; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #000000; + --ion-color-primary-tint: #1a1a1a; + + /* Secondary color - complete set for shadow DOM components */ + --ion-color-secondary: #e67e22; + --ion-color-secondary-rgb: 230, 126, 34; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #cb6f1e; + --ion-color-secondary-tint: #e98b38; + + /* Medium color - used by filter chips */ + --ion-color-medium: #92949c; + --ion-color-medium-rgb: 146, 148, 156; + --ion-color-medium-contrast: #ffffff; + --ion-color-medium-contrast-rgb: 255, 255, 255; + --ion-color-medium-shade: #808289; + --ion-color-medium-tint: #9d9fa6; + + /* Light color */ + --ion-color-light: #f4f5f8; + --ion-color-light-rgb: 244, 245, 248; + --ion-color-light-contrast: #000000; + --ion-color-light-contrast-rgb: 0, 0, 0; + --ion-color-light-shade: #d7d8da; + --ion-color-light-tint: #f5f6f9; + + /* Dark color */ + --ion-color-dark: #222428; + --ion-color-dark-rgb: 34, 36, 40; + --ion-color-dark-contrast: #ffffff; + --ion-color-dark-contrast-rgb: 255, 255, 255; + --ion-color-dark-shade: #1e2023; + --ion-color-dark-tint: #383a3e; + + /* Light mode background step variables (light → dark) */ + --ion-background-color-step-50: #f2f2f2; + --ion-background-color-step-100: #e6e6e6; + --ion-background-color-step-150: #d9d9d9; + --ion-background-color-step-200: #cccccc; + --ion-background-color-step-250: #bfbfbf; + --ion-background-color-step-300: #b3b3b3; + --ion-background-color-step-350: #a6a6a6; + --ion-background-color-step-400: #999999; + --ion-background-color-step-450: #8c8c8c; + --ion-background-color-step-500: #808080; + --ion-background-color-step-550: #737373; + --ion-background-color-step-600: #666666; + --ion-background-color-step-650: #595959; + --ion-background-color-step-700: #4d4d4d; + --ion-background-color-step-750: #404040; + --ion-background-color-step-800: #333333; + --ion-background-color-step-850: #262626; + --ion-background-color-step-900: #1a1a1a; + --ion-background-color-step-950: #0d0d0d; + + /* Light mode text step variables (dark → light) */ + --ion-text-color-step-50: #0d0d0d; + --ion-text-color-step-100: #1a1a1a; + --ion-text-color-step-150: #262626; + --ion-text-color-step-200: #333333; + --ion-text-color-step-250: #404040; + --ion-text-color-step-300: #4d4d4d; + --ion-text-color-step-350: #595959; + --ion-text-color-step-400: #666666; + --ion-text-color-step-450: #737373; + --ion-text-color-step-500: #808080; + --ion-text-color-step-550: #8c8c8c; + --ion-text-color-step-600: #999999; + --ion-text-color-step-650: #a6a6a6; + --ion-text-color-step-700: #b3b3b3; + --ion-text-color-step-750: #bfbfbf; + --ion-text-color-step-800: #cccccc; + --ion-text-color-step-850: #d9d9d9; + --ion-text-color-step-900: #e6e6e6; + --ion-text-color-step-950: #f2f2f2; + + /* Legacy step variables (for older Ionic components) */ + --ion-color-step-50: #f4f5f8; + --ion-color-step-100: #e0e0e0; + --ion-color-step-150: #dcdcdc; + --ion-color-step-200: #cccccc; + --ion-color-step-250: #bfbfbf; + --ion-color-step-300: #b3b3b3; + --ion-color-step-350: #a6a6a6; + --ion-color-step-400: #999999; + --ion-color-step-450: #8c8c8c; + --ion-color-step-500: #808080; + --ion-color-step-550: #737373; + --ion-color-step-600: #666666; + --ion-color-step-650: #595959; + --ion-color-step-700: #4d4d4d; + --ion-color-step-750: #404040; + --ion-color-step-800: #333333; + --ion-color-step-850: #262626; + --ion-color-step-900: #191919; + --ion-color-step-950: #0d0d0d; + + /* Reset component-specific dark mode variables */ + --ion-item-background: #ffffff; + --ion-card-background: #ffffff; + --ion-toolbar-background: #ffffff; + --ion-tab-bar-background: #ffffff; + + .bg-gradient { + background: #ffffff !important; + } + + .glass { + background: rgba(0, 0, 0, 0.05) !important; + border-color: rgba(0, 0, 0, 0.2) !important; + box-shadow: none !important; + } + + ion-item.glass { + --background: rgba(0, 0, 0, 0.05); + h2 { color: #000000 !important; } + p { color: rgba(0, 0, 0, 0.7) !important; } + } + + .canto-number { + background: rgba(0, 0, 0, 0.1) !important; + color: #000000 !important; + border-color: rgba(0, 0, 0, 0.3) !important; + } + + .custom-searchbar { + --background: rgba(0, 0, 0, 0.05); + --color: #000000; + --placeholder-color: rgba(0, 0, 0, 0.4); + --icon-color: #000000; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 12px; + } + + .filter-btn { + background: #ffffff !important; + color: #000000 !important; + border-color: rgba(0, 0, 0, 0.2) !important; + + ion-icon { + color: #000000 !important; + } + + &.active-btn { + background: rgba(0, 0, 0, 0.1) !important; + color: #000000 !important; + border-color: #000000 !important; + } + + &.is-filtered { + background: rgba(230, 126, 34, 0.1) !important; + border-color: #e67e22 !important; + color: #e67e22 !important; + } + } + + .momento-chip { + background: #ffffff !important; + color: #000000 !important; + border-color: rgba(0, 0, 0, 0.2) !important; + opacity: 1 !important; + + &.active { + background: #e67e22 !important; + color: #ffffff !important; + border-color: #e67e22 !important; + } + } + + ion-toolbar, ion-header, ion-content, .bg-gradient, .lyrics-view, .lyrics-container { + --background: #ffffff !important; + background: #ffffff !important; + --color: #000000 !important; + color: #000000 !important; + } + + ion-header::after { + display: none !important; + } + + ion-toolbar { + --border-style: none !important; + border: none !important; + } + + ion-toolbar { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + + ion-title { + color: #000000 !important; + } + } + + .canto-number { + background: rgba(0, 0, 0, 0.08) !important; + color: #000000 !important; + border: 1px solid rgba(0, 0, 0, 0.3) !important; + } + + .section.chorus { + background: rgba(230, 126, 34, 0.08) !important; + border-left-color: #e67e22 !important; + } + + .section-label, .verse-num-label { + color: #000000 !important; + opacity: 0.7 !important; + } + + .lyric-line { + color: #000000 !important; + &.active { + background: rgba(0, 0, 0, 0.1) !important; + color: #000000 !important; + text-shadow: none !important; + font-weight: 900 !important; + } + } + + .chord { + color: #b03a2e !important; + font-weight: 900 !important; + } + + ion-footer { + --background: #ffffff !important; + background: #ffffff !important; + border-top: 1px solid rgba(0, 0, 0, 0.2) !important; + } + + .slim-controls .group { + background: #f0f0f0 !important; + border: 1px solid #cccccc !important; + + ion-icon, .page-indicator { + color: #000000 !important; + } + } + + .global-player-toolbar { + --background: #ffffff !important; + background: #ffffff !important; + border-top: 1px solid rgba(0, 0, 0, 0.1) !important; + border-radius: 0 !important; + box-shadow: none !important; + margin: 0 !important; + + &.glass { + background: #ffffff !important; + backdrop-filter: none !important; + border-radius: 0 !important; + box-shadow: none !important; + border-left: none !important; + border-right: none !important; + border-bottom: none !important; + } + + .controls-row ion-button { + --color: #000000 !important; + } + } + + .transpose-indicator .val { + color: #d35400 !important; + font-weight: 900 !important; + } + + .landscape-side-controls { + background: #f8f8f8 !important; + border-left: 2px solid #000000 !important; + + ion-icon, .side-indicator { + color: #000000 !important; + } + } + + .version-badge { + color: #000000 !important; + background: transparent !important; + font-weight: 400 !important; + padding: 0 !important; + } + + .special-list-banner { + --background: #f8f8f8 !important; + border-bottom: 2px solid #000000 !important; + + .banner-text { + color: #000000 !important; + } + } + + /* Prevent button color/background issues in active/focus/hover states in high contrast */ + ion-button { + --color-activated: var(--color) !important; + --color-focused: var(--color) !important; + --color-hover: var(--color) !important; + + &[fill="clear"], &[fill="outline"] { + --background-activated: rgba(0, 0, 0, 0.1) !important; + --background-focused: rgba(0, 0, 0, 0.08) !important; + --background-hover: rgba(0, 0, 0, 0.05) !important; + } + } +} + +.offline-badge-header { + display: flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.1); + padding: 6px; + border-radius: 50%; + color: rgba(255, 255, 255, 0.6); + margin-right: 8px; + + ion-icon { + font-size: 1.4rem; + } +} + +body.high-contrast .offline-badge-header { + background: rgba(0, 0, 0, 0.05); + color: #000000; + border: 1px solid rgba(0, 0, 0, 0.2); + padding: 6px; + border-radius: 50%; +} + +body.high-contrast .offline-thumb { + background: rgba(0, 0, 0, 0.05) !important; + color: #000000 !important; + border: 1px solid rgba(0, 0, 0, 0.1); + + ion-icon { + color: #000000 !important; + } + span { + color: #000000 !important; + } +} + +.glass { + background: rgba(255, 255, 255, 0.05); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} + +.filter-buttons { + display: flex; + gap: 8px; + + .filter-btn { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + border-radius: 10px; + font-size: 0.8rem; + color: rgba(255, 255, 255, 0.6); + cursor: pointer; + transition: all 0.2s ease; + border: 1px solid rgba(255, 255, 255, 0.1); + + ion-icon { + font-size: 0.9rem; + } + + &.active-btn { + background: rgba(var(--ion-color-secondary-rgb), 0.15) !important; + color: var(--ion-color-secondary); + border-color: var(--ion-color-secondary); + font-weight: 600; + } + + &.is-filtered { + color: var(--ion-color-secondary); + border-color: rgba(var(--ion-color-secondary-rgb), 0.5); + background: rgba(var(--ion-color-secondary-rgb), 0.05); + } + + &:active { + transform: scale(0.95); + } + } +} + +.bg-gradient { + --background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); + background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); +} + +.outfit-font { + font-family: 'Outfit', sans-serif; +} + +/* Ensure high visibility of Action Sheet options in Dark Mode and High Contrast */ +ion-action-sheet { + --background: #1e1e1e !important; + --color: #ffffff !important; + + button { + color: #ffffff !important; + --color: #ffffff !important; + } + + .action-sheet-button { + color: #ffffff !important; + --color: #ffffff !important; + + &.action-sheet-selected { + color: var(--ion-color-secondary) !important; + --color: var(--ion-color-secondary) !important; + } + } + + .action-sheet-title { + color: rgba(255, 255, 255, 0.7) !important; + } +} + +body.high-contrast ion-action-sheet { + --background: #ffffff !important; + --color: #000000 !important; + + button { + color: #000000 !important; + --color: #000000 !important; + } + + .action-sheet-button { + color: #000000 !important; + --color: #000000 !important; + + &.action-sheet-selected { + color: #e67e22 !important; + --color: #e67e22 !important; + } + } + + .action-sheet-title { + color: rgba(0, 0, 0, 0.7) !important; + } +} diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..1d10345 --- /dev/null +++ b/src/index.html @@ -0,0 +1,206 @@ + + + + + + + CantiCristiani + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ CantiCristiani +
+

Avvio in corso

+

Caricamento dei componenti dell'applicazione...

+
Ricerca versione...
+
Fase: Avvio
+
+
+
+
0%
+
+
+ + + + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..306d1d0 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,34 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +// Patch window.fetch to automatically inject basic auth header for api.canticristiani.it +const originalFetch = window.fetch; +window.fetch = function(input: RequestInfo | URL, init?: RequestInit) { + const url = typeof input === 'string' ? input : (input instanceof URL ? input.href : input.url); + if (url.includes('api.canticristiani.it')) { + init = init || {}; + init.headers = init.headers || {}; + const authHeader = 'Basic ' + btoa(`${environment.apiAuthUser}:${environment.apiAuthPass}`); + if (init.headers instanceof Headers) { + init.headers.set('Authorization', authHeader); + } else if (Array.isArray(init.headers)) { + const hasAuth = init.headers.some(([key]) => key.toLowerCase() === 'authorization'); + if (!hasAuth) { + init.headers.push(['Authorization', authHeader]); + } + } else { + (init.headers as Record)['Authorization'] = authHeader; + } + } + return originalFetch(input, init); +}; + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.log(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 0000000..394705a --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,55 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes recent versions of Safari, Chrome (including + * Opera), Edge on the desktop, and iOS and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +import './zone-flags'; + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..51bb020 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,14 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting(), +); diff --git a/src/theme/variables.scss b/src/theme/variables.scss new file mode 100644 index 0000000..4baaac1 --- /dev/null +++ b/src/theme/variables.scss @@ -0,0 +1,51 @@ +:root { + /** Primary - Deep Violet **/ + --ion-color-primary: #6c5ce7; + --ion-color-primary-rgb: 108, 92, 231; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #5f51cb; + --ion-color-primary-tint: #7b6ce9; + + /** Secondary - Amber/Gold **/ + --ion-color-secondary: #fdcb6e; + --ion-color-secondary-rgb: 253, 203, 110; + --ion-color-secondary-contrast: #000000; + --ion-color-secondary-contrast-rgb: 0, 0, 0; + --ion-color-secondary-shade: #dfb261; + --ion-color-secondary-tint: #fdd07d; + + /** Backgrounds **/ + --ion-background-color: #121212; + --ion-background-color-rgb: 18, 18, 18; + --ion-text-color: #f5f5f5; + --ion-text-color-rgb: 245, 245, 245; + + /** Fonts **/ + --ion-font-family: 'Outfit', sans-serif; +} + +body { + font-family: 'Inter', sans-serif; + --ion-font-family: 'Outfit', sans-serif; + background-color: #121212; +} + +h1, h2, h3, h4, h5, h6 { + font-family: 'Outfit', sans-serif; +} + +/* Glassmorphism utility */ +.glass { + background: rgba(255, 255, 255, 0.05); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 16px; +} + +/* Premium Gradient */ +.bg-gradient { + --background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); + background: radial-gradient(circle at top left, #2d3436 0%, #121212 100%); +} diff --git a/src/zone-flags.ts b/src/zone-flags.ts new file mode 100644 index 0000000..c84245f --- /dev/null +++ b/src/zone-flags.ts @@ -0,0 +1,6 @@ +/** + * Prevents Angular change detection from + * running with certain Web Component callbacks + */ +// eslint-disable-next-line no-underscore-dangle +(window as any).__Zone_disable_customElements = true; diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..82d91dc --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..382934a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,34 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "sourceMap": true, + "declaration": false, + "downlevelIteration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "target": "es2022", + "module": "es2020", + "lib": [ + "es2018", + "dom" + ], + "skipLibCheck": true, + "useDefineForClassFields": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000..092345b --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,18 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "files": [ + "src/test.ts", + "src/polyfills.ts" + ], + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +}