commit de5bdb24ca6ee76a677221501f74f6cc94a173bc Author: Rene Fichtmueller Date: Tue Mar 31 08:11:49 2026 +0200 Initial TIP foundation: schema, seed data, crawlers, API, MCP server - PostgreSQL 17 + TimescaleDB schema with 12 tables - 48 standards (IEEE, SFF, ITU-T, OIF, MSA) - 33 form factors (SFP through OSFP-XD/CPO) - 85+ vendors (OEM, compatible, manufacturers, marketplaces) - 80+ seed transceivers (1G-1.6T, CWDM, BiDi, DAC, AOC, FC, PON) - 60+ network devices (Cisco, Juniper, Arista, HPE, Dell, etc.) - Crawler framework with fs.com and eBay crawlers - REST API (15 endpoints) on port 3200 - MCP server (12 tools) on port 3201 - PM2 ecosystem for production deployment on Erik (.82) diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2547ff0 --- /dev/null +++ b/.env.example @@ -0,0 +1,30 @@ +# PostgreSQL (Erik .82) +DATABASE_URL=postgresql://tip:password@192.168.178.82:5432/transceiver_db + +# Qdrant (Erik .82) +QDRANT_URL=http://192.168.178.82:6333 +QDRANT_COLLECTION=transceivers + +# Ollama (.213) +OLLAMA_URL=http://192.168.178.213:11434 + +# Cloudflare R2 +R2_ACCOUNT_ID= +R2_ACCESS_KEY_ID= +R2_SECRET_ACCESS_KEY= +R2_BUCKET=tip-documents + +# eBay API +EBAY_APP_ID= +EBAY_CERT_ID= + +# Amazon PA-API +AMAZON_ACCESS_KEY= +AMAZON_SECRET_KEY= +AMAZON_PARTNER_TAG= + +# API Server +PORT=3200 +HOST=0.0.0.0 +NODE_ENV=development +LOG_LEVEL=info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d37ac32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +node_modules/ +dist/ +.env +.env.* +!.env.example +.dev.vars +wrangler.toml +*.local +storage/ +crawl-data/ +.crawlee/ +playwright-report/ +test-results/ +*.log +.DS_Store diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md new file mode 100644 index 0000000..aa63b8b --- /dev/null +++ b/CHANGELOG_PENDING.md @@ -0,0 +1,11 @@ +# Changelog (Pending) + +```json +{"d":"2026-03-31","t":"FEAT","m":"TIP project foundation: schema, 48 standards, 33 form factors, 85+ vendors, 80+ transceivers, 60+ network devices"} +{"d":"2026-03-31","t":"FEAT","m":"Crawler framework with fs.com (Playwright) and eBay (Cheerio) crawlers"} +{"d":"2026-03-31","t":"FEAT","m":"REST API with 15 endpoints: search, pricing, compatibility, stats, form factors, vendors, devices"} +{"d":"2026-03-31","t":"FEAT","m":"MCP server with 12 tools for AI/LLM integration via SSE protocol"} +{"d":"2026-03-31","t":"DATA","m":"Seed data: Cisco, Juniper, Arista, HPE, Dell + 60 compatible vendors, all from 1G to 1.6T"} +{"d":"2026-03-31","t":"DATA","m":"Complete CWDM spectrum (1270-1610nm), BiDi, DAC, AOC, Fibre Channel, GPON/XGS-PON"} +{"d":"2026-03-31","t":"DATA","m":"Network devices: Nexus 9000, Catalyst 9300/9500, QFX5120/5130, DCS-7050/7060, Spectrum-4"} +``` diff --git a/ecosystem.config.cjs b/ecosystem.config.cjs new file mode 100644 index 0000000..0148e64 --- /dev/null +++ b/ecosystem.config.cjs @@ -0,0 +1,32 @@ +module.exports = { + apps: [ + { + name: 'tip-api', + script: 'dist/api/server.js', + cwd: '/opt/transceiver-db', + instances: 1, + exec_mode: 'fork', + env: { + NODE_ENV: 'production', + PORT: 3200, + }, + env_file: '.env', + max_memory_restart: '512M', + log_date_format: 'YYYY-MM-DD HH:mm:ss', + }, + { + name: 'tip-mcp', + script: 'dist/mcp/server.js', + cwd: '/opt/transceiver-db', + instances: 1, + exec_mode: 'fork', + env: { + NODE_ENV: 'production', + MCP_PORT: 3201, + }, + env_file: '.env', + max_memory_restart: '256M', + log_date_format: 'YYYY-MM-DD HH:mm:ss', + }, + ], +}; diff --git a/migrations/001_foundation.sql b/migrations/001_foundation.sql new file mode 100644 index 0000000..786345e --- /dev/null +++ b/migrations/001_foundation.sql @@ -0,0 +1,454 @@ +-- TIP Foundation Schema +-- PostgreSQL 17 + TimescaleDB + +-- Enable extensions +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- fuzzy text search +CREATE EXTENSION IF NOT EXISTS "btree_gin"; -- GIN index support + +-- ============================================================ +-- ENUMS +-- ============================================================ + +CREATE TYPE transceiver_status AS ENUM ('active', 'eol', 'pre_release', 'nrnd', 'unknown'); +CREATE TYPE data_rate_unit AS ENUM ('Mbps', 'Gbps', 'Tbps'); +CREATE TYPE reach_unit AS ENUM ('m', 'km'); +CREATE TYPE temperature_range AS ENUM ('commercial', 'extended', 'industrial'); +CREATE TYPE dom_type AS ENUM ('none', 'ddm', 'ddmi', 'cmis', 'sff8472', 'sff8636'); +CREATE TYPE connector_type AS ENUM ( + 'LC', 'SC', 'MPO-12', 'MPO-16', 'MPO-24', 'CS', 'SN', + 'FC', 'ST', 'MTRJ', 'E2000', 'copper_rj45', 'cx4', + 'dac_passive', 'dac_active', 'aoc', 'none', 'other' +); +CREATE TYPE fiber_type AS ENUM ( + 'smf', 'mmf_om1', 'mmf_om2', 'mmf_om3', 'mmf_om4', 'mmf_om5', + 'copper', 'dac', 'aoc', 'free_space', 'other' +); +CREATE TYPE wavelength_band AS ENUM ( + 'O', 'E', 'S', 'C', 'L', 'U', 'visible', 'cwdm', 'dwdm', 'lwdm', 'swdm', 'other' +); +CREATE TYPE vendor_type AS ENUM ( + 'oem', 'compatible', 'distributor', 'manufacturer', 'marketplace', 'refurbished' +); +CREATE TYPE price_currency AS ENUM ( + 'USD', 'EUR', 'GBP', 'CNY', 'JPY', 'KRW', 'TWD', 'THB', 'INR', 'CAD', 'AUD' +); +CREATE TYPE hype_phase AS ENUM ( + 'innovation_trigger', 'peak_inflated', 'trough_disillusionment', + 'slope_enlightenment', 'plateau_productivity', 'decline' +); +CREATE TYPE crawl_status AS ENUM ('pending', 'running', 'success', 'failed', 'rate_limited'); +CREATE TYPE media_type AS ENUM ('image', 'datasheet', 'manual', 'diagram', 'video', 'certificate'); + +-- ============================================================ +-- CORE TABLES +-- ============================================================ + +-- Standards (IEEE, SFF, ITU-T, OIF, etc.) +CREATE TABLE standards ( + id SERIAL PRIMARY KEY, + name VARCHAR(100) NOT NULL UNIQUE, + body VARCHAR(50) NOT NULL, -- IEEE, SNIA/SFF, ITU-T, OIF, MSA + version VARCHAR(50), + year INT, + url TEXT, + description TEXT, + superseded_by INT REFERENCES standards(id), + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Form Factors +CREATE TABLE form_factors ( + id SERIAL PRIMARY KEY, + name VARCHAR(50) NOT NULL UNIQUE, + full_name VARCHAR(200), + standard_id INT REFERENCES standards(id), + lanes INT, -- electrical lanes + max_data_rate DECIMAL(10,2), + data_rate_unit data_rate_unit DEFAULT 'Gbps', + width_mm DECIMAL(6,2), + height_mm DECIMAL(6,2), + depth_mm DECIMAL(6,2), + power_max_w DECIMAL(6,2), + generation INT, -- for hype cycle + release_year INT, + eol_year INT, + description TEXT, + image_url TEXT, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Vendors / Manufacturers / Sellers +CREATE TABLE vendors ( + id SERIAL PRIMARY KEY, + name VARCHAR(200) NOT NULL, + slug VARCHAR(200) NOT NULL UNIQUE, + vendor_type vendor_type NOT NULL DEFAULT 'compatible', + website TEXT, + logo_url TEXT, + country VARCHAR(3), -- ISO 3166-1 alpha-3 + founded_year INT, + description TEXT, + is_oem BOOLEAN DEFAULT FALSE, -- Cisco, Juniper, Arista, etc. + is_factory BOOLEAN DEFAULT FALSE, -- Hisense, Innolight, etc. + aliases TEXT[], -- alternative names + scrape_url TEXT, -- catalog base URL + scrape_enabled BOOLEAN DEFAULT FALSE, + scrape_interval INT DEFAULT 86400, -- seconds + last_scraped_at TIMESTAMPTZ, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Core Transceiver Table +CREATE TABLE transceivers ( + id SERIAL PRIMARY KEY, + part_number VARCHAR(200) NOT NULL, + vendor_id INT NOT NULL REFERENCES vendors(id), + form_factor_id INT REFERENCES form_factors(id), + + -- Classification + name VARCHAR(500), + description TEXT, + category VARCHAR(100), -- SFP, SFP+, QSFP28, QSFP-DD, OSFP, etc. + subcategory VARCHAR(100), -- SR, LR, ER, ZR, BiDi, CWDM, DWDM, DAC, AOC + + -- Performance + data_rate DECIMAL(10,2), + data_rate_unit data_rate_unit DEFAULT 'Gbps', + max_reach DECIMAL(10,2), + reach_unit reach_unit DEFAULT 'km', + + -- Optical + wavelength_nm DECIMAL(8,2), -- TX wavelength + wavelength_rx DECIMAL(8,2), -- RX wavelength (BiDi) + wavelengths DECIMAL(8,2)[], -- CWDM/DWDM channels + wavelength_band wavelength_band, + tx_power_min DECIMAL(6,2), -- dBm + tx_power_max DECIMAL(6,2), + rx_sensitivity DECIMAL(6,2), -- dBm + link_budget_db DECIMAL(6,2), + + -- Physical + connector connector_type, + fiber_type fiber_type, + duplex BOOLEAN DEFAULT TRUE, + breakout VARCHAR(50), -- e.g. "4x25G", "8x50G" + + -- Environmental + temp_range temperature_range DEFAULT 'commercial', + temp_min_c DECIMAL(5,1), + temp_max_c DECIMAL(5,1), + power_consumption_w DECIMAL(6,2), + + -- Monitoring + dom_support dom_type DEFAULT 'none', + + -- OEM Cross-Reference + oem_part_number VARCHAR(200), -- original OEM part number + oem_vendor_id INT REFERENCES vendors(id), + + -- Status + status transceiver_status DEFAULT 'active', + release_date DATE, + eol_date DATE, + + -- Media + image_url TEXT, + datasheet_url TEXT, + product_url TEXT, + + -- Metadata + tags TEXT[], + raw_specs JSONB, -- original scraped data + source VARCHAR(100), -- where this data came from + source_url TEXT, + last_verified TIMESTAMPTZ, + + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW(), + + UNIQUE(part_number, vendor_id) +); + +-- ============================================================ +-- PRICING (TimescaleDB hypertable) +-- ============================================================ + +CREATE TABLE prices ( + time TIMESTAMPTZ NOT NULL, + transceiver_id INT NOT NULL REFERENCES transceivers(id), + vendor_id INT NOT NULL REFERENCES vendors(id), + + price DECIMAL(12,4) NOT NULL, + currency price_currency DEFAULT 'USD', + price_usd DECIMAL(12,4), -- normalized to USD + + quantity_min INT DEFAULT 1, + quantity_max INT, + in_stock BOOLEAN, + stock_quantity INT, + lead_time_days INT, + + condition VARCHAR(20) DEFAULT 'new', -- new, refurbished, used + url TEXT, + source VARCHAR(100), + + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Make prices a TimescaleDB hypertable +SELECT create_hypertable('prices', 'time', if_not_exists => TRUE); + +-- ============================================================ +-- COMPATIBILITY +-- ============================================================ + +-- Switch/Router models +CREATE TABLE network_devices ( + id SERIAL PRIMARY KEY, + vendor_id INT NOT NULL REFERENCES vendors(id), + model VARCHAR(200) NOT NULL, + series VARCHAR(100), -- Catalyst 9300, EX4400, etc. + device_type VARCHAR(50), -- switch, router, firewall, olt, media_converter + + ports_sfp INT DEFAULT 0, + ports_sfp_plus INT DEFAULT 0, + ports_sfp28 INT DEFAULT 0, + ports_qsfp_plus INT DEFAULT 0, + ports_qsfp28 INT DEFAULT 0, + ports_qsfp_dd INT DEFAULT 0, + ports_osfp INT DEFAULT 0, + ports_cfp INT DEFAULT 0, + ports_rj45 INT DEFAULT 0, + + max_throughput VARCHAR(50), + release_year INT, + eol_date DATE, + status VARCHAR(20) DEFAULT 'active', + + image_url TEXT, + product_url TEXT, + manual_url TEXT, + + raw_specs JSONB, + source VARCHAR(100), + + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW(), + + UNIQUE(vendor_id, model) +); + +-- Compatibility matrix +CREATE TABLE compatibility ( + id SERIAL PRIMARY KEY, + transceiver_id INT NOT NULL REFERENCES transceivers(id), + device_id INT NOT NULL REFERENCES network_devices(id), + + verified BOOLEAN DEFAULT FALSE, -- vendor-verified or community-tested + verified_by VARCHAR(100), -- vendor, community, lab + firmware_min VARCHAR(50), + firmware_max VARCHAR(50), + notes TEXT, + + source VARCHAR(100), -- cisco_tmg, juniper_hct, community, etc. + source_url TEXT, + verified_at TIMESTAMPTZ, + + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW(), + + UNIQUE(transceiver_id, device_id) +); + +-- ============================================================ +-- KNOWLEDGE BASE +-- ============================================================ + +CREATE TABLE faq_articles ( + id SERIAL PRIMARY KEY, + title VARCHAR(500) NOT NULL, + slug VARCHAR(500) NOT NULL UNIQUE, + content TEXT NOT NULL, + summary TEXT, + category VARCHAR(100), + tags TEXT[], + + related_transceivers INT[], + related_devices INT[], + + view_count INT DEFAULT 0, + helpful_count INT DEFAULT 0, + + source VARCHAR(100), + source_url TEXT, + embedding_id VARCHAR(100), -- Qdrant point ID + + published BOOLEAN DEFAULT TRUE, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- ============================================================ +-- HYPE CYCLE ENGINE +-- ============================================================ + +CREATE TABLE hype_cycles ( + id SERIAL PRIMARY KEY, + technology VARCHAR(200) NOT NULL, -- e.g. "QSFP-DD 400G", "Silicon Photonics" + form_factor_id INT REFERENCES form_factors(id), + + -- Bass Model Parameters + bass_p DECIMAL(10,6), -- innovation coefficient + bass_q DECIMAL(10,6), -- imitation coefficient + bass_m BIGINT, -- market potential + + current_phase hype_phase, + phase_started DATE, + predicted_peak DATE, + predicted_trough DATE, + predicted_plateau DATE, + + -- Signals + adoption_units BIGINT, + market_size_usd BIGINT, + search_trend DECIMAL(5,2), -- Google Trends 0-100 + patent_count INT, + paper_count INT, + news_sentiment DECIMAL(5,2), -- -1.0 to 1.0 + + confidence DECIMAL(5,2), -- model confidence 0-1 + + data_points JSONB, -- time series data + model_output JSONB, -- full model results + + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- ============================================================ +-- MEDIA / DOCUMENTS +-- ============================================================ + +CREATE TABLE media ( + id SERIAL PRIMARY KEY, + transceiver_id INT REFERENCES transceivers(id), + device_id INT REFERENCES network_devices(id), + vendor_id INT REFERENCES vendors(id), + + media_type media_type NOT NULL, + title VARCHAR(500), + url TEXT NOT NULL, -- original URL + r2_key VARCHAR(500), -- Cloudflare R2 key + r2_url TEXT, -- R2 public URL + + mime_type VARCHAR(100), + file_size_bytes BIGINT, + width_px INT, + height_px INT, + + ocr_text TEXT, -- extracted text (Docling) + embedding_id VARCHAR(100), -- Qdrant point ID + + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- ============================================================ +-- CRAWL TRACKING +-- ============================================================ + +CREATE TABLE crawl_jobs ( + id SERIAL PRIMARY KEY, + crawler VARCHAR(100) NOT NULL, -- fscom, cisco_tmg, ebay, etc. + status crawl_status DEFAULT 'pending', + + urls_total INT DEFAULT 0, + urls_processed INT DEFAULT 0, + urls_failed INT DEFAULT 0, + items_found INT DEFAULT 0, + items_new INT DEFAULT 0, + items_updated INT DEFAULT 0, + + error_message TEXT, + duration_ms INT, + + started_at TIMESTAMPTZ, + finished_at TIMESTAMPTZ, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE TABLE crawl_errors ( + id SERIAL PRIMARY KEY, + job_id INT REFERENCES crawl_jobs(id), + url TEXT, + error_code VARCHAR(20), + error_message TEXT, + retry_count INT DEFAULT 0, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- ============================================================ +-- NEWS / BLOG +-- ============================================================ + +CREATE TABLE news_articles ( + id SERIAL PRIMARY KEY, + title VARCHAR(500) NOT NULL, + url TEXT NOT NULL UNIQUE, + source VARCHAR(100), + author VARCHAR(200), + + content TEXT, + summary TEXT, + + tags TEXT[], + mentioned_technologies TEXT[], + sentiment DECIMAL(5,2), + + published_at TIMESTAMPTZ, + scraped_at TIMESTAMPTZ DEFAULT NOW(), + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- ============================================================ +-- INDEXES +-- ============================================================ + +-- Transceivers +CREATE INDEX idx_transceivers_vendor ON transceivers(vendor_id); +CREATE INDEX idx_transceivers_form_factor ON transceivers(form_factor_id); +CREATE INDEX idx_transceivers_category ON transceivers(category); +CREATE INDEX idx_transceivers_data_rate ON transceivers(data_rate); +CREATE INDEX idx_transceivers_wavelength ON transceivers(wavelength_nm); +CREATE INDEX idx_transceivers_status ON transceivers(status); +CREATE INDEX idx_transceivers_part_number_gin ON transceivers USING gin(part_number gin_trgm_ops); +CREATE INDEX idx_transceivers_name_gin ON transceivers USING gin(name gin_trgm_ops); +CREATE INDEX idx_transceivers_tags ON transceivers USING gin(tags); +CREATE INDEX idx_transceivers_oem ON transceivers(oem_part_number) WHERE oem_part_number IS NOT NULL; + +-- Prices +CREATE INDEX idx_prices_transceiver ON prices(transceiver_id, time DESC); +CREATE INDEX idx_prices_vendor ON prices(vendor_id, time DESC); + +-- Compatibility +CREATE INDEX idx_compat_transceiver ON compatibility(transceiver_id); +CREATE INDEX idx_compat_device ON compatibility(device_id); + +-- Devices +CREATE INDEX idx_devices_vendor ON network_devices(vendor_id); +CREATE INDEX idx_devices_model_gin ON network_devices USING gin(model gin_trgm_ops); + +-- FAQ +CREATE INDEX idx_faq_tags ON faq_articles USING gin(tags); +CREATE INDEX idx_faq_content_gin ON faq_articles USING gin(content gin_trgm_ops); + +-- Media +CREATE INDEX idx_media_transceiver ON media(transceiver_id); +CREATE INDEX idx_media_type ON media(media_type); + +-- Crawl +CREATE INDEX idx_crawl_jobs_status ON crawl_jobs(status); +CREATE INDEX idx_crawl_jobs_crawler ON crawl_jobs(crawler); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..76fcbcf --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9049 @@ +{ + "name": "transceiver-intelligence-platform", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "transceiver-intelligence-platform", + "version": "0.1.0", + "dependencies": { + "cheerio": "^1.0.0", + "compression": "^1.7.5", + "cors": "^2.8.5", + "crawlee": "^3.12.0", + "cron": "^3.1.0", + "dotenv": "^16.4.0", + "express": "^4.21.0", + "helmet": "^8.0.0", + "p-queue": "^8.0.1", + "p-retry": "^6.2.0", + "pg": "^8.13.0", + "pg-boss": "^10.1.0", + "pino": "^9.5.0", + "pino-pretty": "^11.3.0", + "playwright": "^1.48.0", + "tsx": "^4.19.0", + "undici": "^7.0.0", + "zod": "^3.23.0" + }, + "devDependencies": { + "@types/compression": "^1.7.5", + "@types/cors": "^2.8.17", + "@types/express": "^5.0.0", + "@types/node": "^22.0.0", + "@types/pg": "^8.11.0", + "eslint": "^9.0.0", + "tsup": "^8.3.0", + "typescript": "^5.6.0", + "vitest": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@apify/consts": { + "version": "2.51.1", + "resolved": "https://registry.npmjs.org/@apify/consts/-/consts-2.51.1.tgz", + "integrity": "sha512-QV16f41BjmE7uYQgB+JeS5bhbEdFvP8eF1R5LiKlvGkERckSlMl1JIIaW1b/XwJdp3bEBKBGPtNlvYa06wyhwg==", + "license": "Apache-2.0" + }, + "node_modules/@apify/datastructures": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@apify/datastructures/-/datastructures-2.0.3.tgz", + "integrity": "sha512-E6yQyc/XZDqJopbaGmhzZXMJqwGf96ELtDANZa0t68jcOAJZS+pF7YUfQOLszXq6JQAdnRvTH2caotL6urX7HA==", + "license": "Apache-2.0" + }, + "node_modules/@apify/log": { + "version": "2.5.33", + "resolved": "https://registry.npmjs.org/@apify/log/-/log-2.5.33.tgz", + "integrity": "sha512-rD+RY/Lvgy2ZAQD6QHbzoGHKvqILSXHZggTv2PN80ZZl7JMVQ22pYpoysYITHl4eGuievCiwrhkvdbNqTHqoPQ==", + "license": "Apache-2.0", + "dependencies": { + "@apify/consts": "^2.51.1", + "ansi-colors": "^4.1.1" + } + }, + "node_modules/@apify/ps-tree": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@apify/ps-tree/-/ps-tree-1.2.0.tgz", + "integrity": "sha512-VHIswI7rD/R4bToeIDuJ9WJXt+qr5SdhfoZ9RzdjmCs9mgy7l0P4RugQEUCcU+WB4sfImbd4CKwzXcn0uYx1yw==", + "license": "MIT", + "dependencies": { + "event-stream": "3.3.4" + }, + "bin": { + "ps-tree": "bin/ps-tree.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@apify/pseudo_url": { + "version": "2.0.74", + "resolved": "https://registry.npmjs.org/@apify/pseudo_url/-/pseudo_url-2.0.74.tgz", + "integrity": "sha512-iMa7MzKn/5dWwSmOj3jZ+33NCRUdbyKsOTZytlowQgblV3yL8YFLziWcA1GlH6spIHG8073gIQMOecXvQYpvNA==", + "license": "Apache-2.0", + "dependencies": { + "@apify/log": "^2.5.33" + } + }, + "node_modules/@apify/timeout": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@apify/timeout/-/timeout-0.3.2.tgz", + "integrity": "sha512-JnOLIOpqfm366q7opKrA6HrL0iYRpYYDn8Mi77sMR2GZ1fPbwMWCVzN23LJWfJV7izetZbCMrqRUXsR1etZ7dA==", + "license": "Apache-2.0" + }, + "node_modules/@apify/utilities": { + "version": "2.25.5", + "resolved": "https://registry.npmjs.org/@apify/utilities/-/utilities-2.25.5.tgz", + "integrity": "sha512-I53XgSbNw2mYHPbPTIM7CjooHBHapWzvW6eKxpzt5IO9zB3OIzWOk2xRCodi1pAt3+A+BGiJJyddF/cQYGJenA==", + "license": "Apache-2.0", + "dependencies": { + "@apify/consts": "^2.51.1", + "@apify/log": "^2.5.33" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@crawlee/basic": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/basic/-/basic-3.16.0.tgz", + "integrity": "sha512-dcqeDkYk6NoXHSBEkALD4orb7k6yTDkwZp8RtcvlmMmVZKVQTVVHh78NFInzxRkjFVmStFWE2LRHBZpe518E0Q==", + "license": "Apache-2.0", + "dependencies": { + "@apify/log": "^2.4.0", + "@apify/timeout": "^0.3.0", + "@apify/utilities": "^2.7.10", + "@crawlee/core": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "csv-stringify": "^6.2.0", + "fs-extra": "^11.0.0", + "got-scraping": "^4.0.0", + "ow": "^0.28.1", + "tldts": "^7.0.0", + "tslib": "^2.4.0", + "type-fest": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/browser": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/browser/-/browser-3.16.0.tgz", + "integrity": "sha512-7AJeJ5328qsgFhyITNt0V4YVtA5+t/yRtkiHIN5af4Ht/WlYaVTkY4Qs5a8c6x1NU9+bt14umEFcCAu2hGJMzw==", + "license": "Apache-2.0", + "dependencies": { + "@apify/timeout": "^0.3.0", + "@crawlee/basic": "3.16.0", + "@crawlee/browser-pool": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "ow": "^0.28.1", + "tslib": "^2.4.0", + "type-fest": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "playwright": "*", + "puppeteer": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + } + } + }, + "node_modules/@crawlee/browser-pool": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/browser-pool/-/browser-pool-3.16.0.tgz", + "integrity": "sha512-o9RK/TcDwxXF2wa5Ij6oG8JeS/aBTp/Xi4Rj8waQ/NKVfhF4DcOAlqiL/ed1YUgFUZx+P/VL/AIQKWbKAWnQlw==", + "license": "Apache-2.0", + "dependencies": { + "@apify/log": "^2.4.0", + "@apify/timeout": "^0.3.0", + "@crawlee/core": "3.16.0", + "@crawlee/types": "3.16.0", + "fingerprint-generator": "^2.1.68", + "fingerprint-injector": "^2.1.68", + "lodash.merge": "^4.6.2", + "nanoid": "^3.3.4", + "ow": "^0.28.1", + "p-limit": "^3.1.0", + "proxy-chain": "^2.0.1", + "quick-lru": "^5.1.1", + "tiny-typed-emitter": "^2.1.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "playwright": "*", + "puppeteer": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + } + } + }, + "node_modules/@crawlee/cheerio": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/cheerio/-/cheerio-3.16.0.tgz", + "integrity": "sha512-eyiWyHBuYZ0Ay5Q8wRD05RAAfgINxngUtlmUrV8r98Jpx9ibvm4UOS5yiqrZfGN2aoA31vasomCpgIcigacf8Q==", + "license": "Apache-2.0", + "dependencies": { + "@crawlee/http": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "cheerio": "1.0.0-rc.12", + "htmlparser2": "^9.0.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/cheerio/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/cheerio/node_modules/cheerio/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@crawlee/cheerio/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "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.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/@crawlee/cli": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/cli/-/cli-3.16.0.tgz", + "integrity": "sha512-oZW2TEpcCYZmRvTtdeC57B7kgenvDbKf4GclDRZ/IH0aUnK7Zy0voTIEoqemyQdvbVN0NK43ylmZMz6KVdVygw==", + "license": "Apache-2.0", + "dependencies": { + "@crawlee/templates": "3.16.0", + "ansi-colors": "^4.1.3", + "fs-extra": "^11.0.0", + "inquirer": "^8.2.4", + "tslib": "^2.4.0", + "yargonaut": "^1.1.4", + "yargs": "^17.5.1" + }, + "bin": { + "crawlee": "index.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/core": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/core/-/core-3.16.0.tgz", + "integrity": "sha512-Yn32E5IdmENLITg36XN1ty4OLPMcqzDjkEvSdZ0dRV5jcJR89sKi47FOs2eXpW+n7IGhbzPDkGKUirPPRrRkjg==", + "license": "Apache-2.0", + "dependencies": { + "@apify/consts": "^2.20.0", + "@apify/datastructures": "^2.0.0", + "@apify/log": "^2.4.0", + "@apify/pseudo_url": "^2.0.30", + "@apify/timeout": "^0.3.0", + "@apify/utilities": "^2.7.10", + "@crawlee/memory-storage": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "@sapphire/async-queue": "^1.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "csv-stringify": "^6.2.0", + "fs-extra": "^11.0.0", + "got-scraping": "^4.0.0", + "json5": "^2.2.3", + "minimatch": "^9.0.0", + "ow": "^0.28.1", + "stream-json": "^1.8.0", + "tldts": "^7.0.0", + "tough-cookie": "^6.0.0", + "tslib": "^2.4.0", + "type-fest": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/http": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/http/-/http-3.16.0.tgz", + "integrity": "sha512-adp8fuQyW32kVKKJNPOA/HEF893ddPqldlIOcO+CdCa4EkeKTPOx74VGLVZyO4f0Zxs0QwvDL1W5O7ckD82MFQ==", + "license": "Apache-2.0", + "dependencies": { + "@apify/timeout": "^0.3.0", + "@apify/utilities": "^2.7.10", + "@crawlee/basic": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "@types/content-type": "^1.1.5", + "cheerio": "1.0.0-rc.12", + "content-type": "^1.0.4", + "got-scraping": "^4.0.0", + "iconv-lite": "^0.7.0", + "mime-types": "^2.1.35", + "ow": "^0.28.1", + "tslib": "^2.4.0", + "type-fest": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/http/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/http/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@crawlee/jsdom": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/jsdom/-/jsdom-3.16.0.tgz", + "integrity": "sha512-dL+uOQrA7BGJN6PnqXe1Kcp76KyoLm5DSNkytZzeJm6ZphC/aOZUrC2a6SKU4XUnxVipnM6Nase/F+a1aNez1g==", + "license": "Apache-2.0", + "dependencies": { + "@apify/timeout": "^0.3.0", + "@apify/utilities": "^2.7.10", + "@crawlee/http": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "@types/jsdom": "^21.0.0", + "cheerio": "1.0.0-rc.12", + "jsdom": "^26.0.0", + "ow": "^0.28.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/jsdom/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/jsdom/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@crawlee/linkedom": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/linkedom/-/linkedom-3.16.0.tgz", + "integrity": "sha512-AkpqiAqddk35gl2lNqDySuN5Raam1y3bQs49Y2NALc/TEnodXnnRO0rEEOh1P/wHNh4cm1jgY9rxmt/SHf3SLg==", + "license": "Apache-2.0", + "dependencies": { + "@apify/timeout": "^0.3.0", + "@apify/utilities": "^2.7.10", + "@crawlee/http": "3.16.0", + "@crawlee/types": "3.16.0", + "linkedom": "^0.18.0", + "ow": "^0.28.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/memory-storage": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/memory-storage/-/memory-storage-3.16.0.tgz", + "integrity": "sha512-ol1PSWj5LL1ALjEZ+zJdLaZx4bGPIP6vXly4AmbtyFg2iq+m1BudtXL+dWFdv/qN8f+N8ljPF5VwKAVxg2uy3Q==", + "license": "Apache-2.0", + "dependencies": { + "@apify/log": "^2.4.0", + "@crawlee/types": "3.16.0", + "@sapphire/async-queue": "^1.5.0", + "@sapphire/shapeshift": "^3.0.0", + "content-type": "^1.0.4", + "fs-extra": "^11.0.0", + "json5": "^2.2.3", + "mime-types": "^2.1.35", + "proper-lockfile": "^4.1.2", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/@crawlee/playwright": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/playwright/-/playwright-3.16.0.tgz", + "integrity": "sha512-Oa7emJBmcqOcw/3iMc6KjfZUFAV2jmbvEv9jZQcMWPuVlmDVxV5Q67q0PF4/YDMesx0RBHLK0LRBcqO5jgtjFg==", + "license": "Apache-2.0", + "dependencies": { + "@apify/datastructures": "^2.0.0", + "@apify/log": "^2.4.0", + "@apify/timeout": "^0.3.1", + "@crawlee/browser": "3.16.0", + "@crawlee/browser-pool": "3.16.0", + "@crawlee/core": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "cheerio": "1.0.0-rc.12", + "jquery": "^3.6.0", + "lodash.isequal": "^4.5.0", + "ml-logistic-regression": "^2.0.0", + "ml-matrix": "^6.11.0", + "ow": "^0.28.1", + "string-comparison": "^1.3.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "idcac-playwright": "^0.2.0", + "playwright": "*" + }, + "peerDependenciesMeta": { + "idcac-playwright": { + "optional": true + }, + "playwright": { + "optional": true + } + } + }, + "node_modules/@crawlee/playwright/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/playwright/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@crawlee/puppeteer": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/puppeteer/-/puppeteer-3.16.0.tgz", + "integrity": "sha512-7qrh684m9bx1y7d+SRILlKelLk8FMML5lekMgiMzEQ7rjzrgXwWo3A9mkL9zQeC931pAMnWMZuGESloOYM2SxA==", + "license": "Apache-2.0", + "dependencies": { + "@apify/datastructures": "^2.0.0", + "@apify/log": "^2.4.0", + "@crawlee/browser": "3.16.0", + "@crawlee/browser-pool": "3.16.0", + "@crawlee/types": "3.16.0", + "@crawlee/utils": "3.16.0", + "cheerio": "1.0.0-rc.12", + "devtools-protocol": "*", + "idcac-playwright": "^0.2.0", + "jquery": "^3.6.0", + "ow": "^0.28.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "idcac-playwright": "^0.2.0", + "puppeteer": "*" + }, + "peerDependenciesMeta": { + "idcac-playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + } + } + }, + "node_modules/@crawlee/puppeteer/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/puppeteer/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@crawlee/templates": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/templates/-/templates-3.16.0.tgz", + "integrity": "sha512-zDfRWDrqe75WEPtoUXGKA/iGmG+EHlepd0jc64AO1mUpZkOUVCNgSMxvMjxQV6zUMChsbPPvhOV6bHnY8/bEHA==", + "license": "Apache-2.0", + "dependencies": { + "ansi-colors": "^4.1.3", + "inquirer": "^9.0.0", + "tslib": "^2.4.0", + "yargonaut": "^1.1.4", + "yargs": "^17.5.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/templates/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==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@crawlee/templates/node_modules/inquirer": { + "version": "9.3.8", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.3.8.tgz", + "integrity": "sha512-pFGGdaHrmRKMh4WoDDSowddgjT1Vkl90atobmTeSmcPGdYiwikch/m/Ef5wRaiamHejtw0cUUMMerzDUXCci2w==", + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.2", + "@inquirer/figures": "^1.0.3", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "1.0.0", + "ora": "^5.4.1", + "run-async": "^3.0.0", + "rxjs": "^7.8.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@crawlee/templates/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@crawlee/templates/node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@crawlee/types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/types/-/types-3.16.0.tgz", + "integrity": "sha512-CcIM+JDVx4gzQzMPl+9RJiEeqdzTrx2RLPA7y4IMJSyfZm3J/VrEunielKA3NQrk095j9OuvS/rQL2y8mBV1qw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/utils": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@crawlee/utils/-/utils-3.16.0.tgz", + "integrity": "sha512-rfVx/3hsFZjiD4AwT8IoQsuNLiawrsdhc893Nha22mWQMxJ0Z/KUzh8FyJDnNOHuxWGIJP96I7nBikxYeSdw5A==", + "license": "Apache-2.0", + "dependencies": { + "@apify/log": "^2.4.0", + "@apify/ps-tree": "^1.2.0", + "@crawlee/types": "3.16.0", + "@types/sax": "^1.2.7", + "cheerio": "1.0.0-rc.12", + "file-type": "^20.0.0", + "got-scraping": "^4.0.3", + "ow": "^0.28.1", + "robots-parser": "^3.0.1", + "sax": "^1.4.1", + "tslib": "^2.4.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@crawlee/utils/node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@crawlee/utils/node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "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.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz", + "integrity": "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.4.tgz", + "integrity": "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz", + "integrity": "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.4.tgz", + "integrity": "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz", + "integrity": "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz", + "integrity": "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz", + "integrity": "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz", + "integrity": "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz", + "integrity": "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz", + "integrity": "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz", + "integrity": "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz", + "integrity": "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz", + "integrity": "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz", + "integrity": "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz", + "integrity": "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz", + "integrity": "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz", + "integrity": "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz", + "integrity": "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz", + "integrity": "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz", + "integrity": "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz", + "integrity": "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz", + "integrity": "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz", + "integrity": "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz", + "integrity": "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz", + "integrity": "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz", + "integrity": "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==", + "cpu": [ + "x64" + ], + "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/eslint-utils/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-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/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/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/@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-array/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/@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/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/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/@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/eslintrc/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/@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/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.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/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "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==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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/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/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", + "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", + "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", + "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", + "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", + "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", + "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", + "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", + "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", + "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", + "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", + "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", + "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", + "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", + "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", + "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", + "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", + "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", + "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", + "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", + "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", + "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", + "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", + "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", + "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", + "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sapphire/async-queue": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz", + "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@sapphire/shapeshift": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz", + "integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v16" + } + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/inflate/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@tokenizer/inflate/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==", + "license": "MIT" + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "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/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@types/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@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/content-type": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@types/content-type/-/content-type-1.1.9.tgz", + "integrity": "sha512-Hq9IMnfekuOCsEmYl4QX2HBrT+XsfXiupfrLLY8Dcf3Puf4BkBOxSbWYTITSOQAhJoYPBez+b4MJRpIYL65z8A==", + "license": "MIT" + }, + "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/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/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "license": "MIT" + }, + "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/jsdom": { + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/luxon": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.4.2.tgz", + "integrity": "sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/pg": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==", + "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==", + "license": "MIT" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vladfrangu/async_event_emitter": { + "version": "2.4.7", + "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.7.tgz", + "integrity": "sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==", + "license": "MIT", + "engines": { + "node": ">=v14.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/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==", + "license": "MIT", + "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-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/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "license": "MIT", + "engines": { + "node": ">=12.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==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "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/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==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "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/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "license": "MIT" + }, + "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/baseline-browser-mapping": { + "version": "2.10.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.12.tgz", + "integrity": "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "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.14.0", + "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/body-parser/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==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", + "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/byte-counter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/byte-counter/-/byte-counter-0.1.0.tgz", + "integrity": "sha512-jheRLVMeUKrDBjVw2O5+k4EvR4t9wtxHL+bo/LxfkxsVeuGMy3a5SEGgXdAFA4FSzTrU8rQXQIrsZ3oBq5a0pQ==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "13.0.18", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-13.0.18.tgz", + "integrity": "sha512-rFWadDRKJs3s2eYdXlGggnBZKG7MTblkFBB0YllFds+UYnfogDp2wcR6JN97FhRkHTvq59n2vhNoHNZn29dh/Q==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.4", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.2.0", + "keyv": "^5.5.5", + "mimic-response": "^4.0.0", + "normalize-url": "^8.1.1", + "responselike": "^4.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacheable-request/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "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==", + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001782", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001782.tgz", + "integrity": "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==", + "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/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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==", + "license": "MIT" + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "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/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/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==", + "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/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "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==", + "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/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/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/crawlee": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/crawlee/-/crawlee-3.16.0.tgz", + "integrity": "sha512-j7wBS81zU+z7MNIKUqJuYRDbKJHwn5sWkki08glAXj6+Ka7HgU6IONHmrv9qtUmb/0p0m5tcMNqItMfnvh6bHA==", + "license": "Apache-2.0", + "dependencies": { + "@crawlee/basic": "3.16.0", + "@crawlee/browser": "3.16.0", + "@crawlee/browser-pool": "3.16.0", + "@crawlee/cheerio": "3.16.0", + "@crawlee/cli": "3.16.0", + "@crawlee/core": "3.16.0", + "@crawlee/http": "3.16.0", + "@crawlee/jsdom": "3.16.0", + "@crawlee/linkedom": "3.16.0", + "@crawlee/playwright": "3.16.0", + "@crawlee/puppeteer": "3.16.0", + "@crawlee/utils": "3.16.0", + "import-local": "^3.1.0", + "tslib": "^2.4.0" + }, + "bin": { + "crawlee": "cli.js" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "idcac-playwright": "*", + "playwright": "*", + "puppeteer": "*" + }, + "peerDependenciesMeta": { + "idcac-playwright": { + "optional": true + }, + "playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + } + } + }, + "node_modules/cron": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-3.5.0.tgz", + "integrity": "sha512-0eYZqCnapmxYcV06uktql93wNWdlTmmBFP2iYz+JPVcQqlyFYcn1lFuIk4R54pkOmE7mcldTAPZv6X5XA4Q46A==", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.4.0", + "luxon": "~3.5.0" + } + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/csv-stringify": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.7.0.tgz", + "integrity": "sha512-UdtziYp5HuTz7e5j8Nvq+a/3HQo+2/aJZ9xntNTpmRRIg/3YYqDVgiS9fvAhtNbnyfbv2ZBe0bqCHqzhE7FqWQ==", + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/decompress-response": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-10.0.0.tgz", + "integrity": "sha512-oj7KWToJuuxlPr7VV0vabvxEIiqNMo+q0NueIiL3XhtwC6FVOX7Hr1c0C4eD0bmf7Zr+S/dSf2xvkH3Ad6sU3Q==", + "license": "MIT", + "dependencies": { + "mimic-response": "^4.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1604597", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1604597.tgz", + "integrity": "sha512-7DH4+FDIwg5AxeW+kvFb5qxJuDLSNK2S9FurqLpggMrUxS3tlvN/J2kP6uOghn584shRnvKheKSSvS4bgnzWYA==", + "license": "BSD-3-Clause" + }, + "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==", + "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==", + "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==", + "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==", + "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/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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==", + "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/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.329", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.329.tgz", + "integrity": "sha512-/4t+AS1l4S3ZC0Ja7PHFIWeBIxGA3QGqV8/yKsP36v7NcyUCl+bIcmw6s5zVuMIECWwBrAK/6QLzTmbJChBboQ==", + "license": "ISC" + }, + "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/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/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==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "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==", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.4.tgz", + "integrity": "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.4", + "@esbuild/android-arm": "0.27.4", + "@esbuild/android-arm64": "0.27.4", + "@esbuild/android-x64": "0.27.4", + "@esbuild/darwin-arm64": "0.27.4", + "@esbuild/darwin-x64": "0.27.4", + "@esbuild/freebsd-arm64": "0.27.4", + "@esbuild/freebsd-x64": "0.27.4", + "@esbuild/linux-arm": "0.27.4", + "@esbuild/linux-arm64": "0.27.4", + "@esbuild/linux-ia32": "0.27.4", + "@esbuild/linux-loong64": "0.27.4", + "@esbuild/linux-mips64el": "0.27.4", + "@esbuild/linux-ppc64": "0.27.4", + "@esbuild/linux-riscv64": "0.27.4", + "@esbuild/linux-s390x": "0.27.4", + "@esbuild/linux-x64": "0.27.4", + "@esbuild/netbsd-arm64": "0.27.4", + "@esbuild/netbsd-x64": "0.27.4", + "@esbuild/openbsd-arm64": "0.27.4", + "@esbuild/openbsd-x64": "0.27.4", + "@esbuild/openharmony-arm64": "0.27.4", + "@esbuild/sunos-x64": "0.27.4", + "@esbuild/win32-arm64": "0.27.4", + "@esbuild/win32-ia32": "0.27.4", + "@esbuild/win32-x64": "0.27.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "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==", + "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-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-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/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/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/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/eslint/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/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/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/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", + "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "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/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "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==", + "license": "MIT" + }, + "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-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "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/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/figlet": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.11.0.tgz", + "integrity": "sha512-EEx3OS/l2bFqcUNN2NM9FPJp8vAMrgbCxsbl2hbcJNNxOEwVe3mEzrhan7TbJQViZa8mMqhihlbCaqD+LyYKTQ==", + "license": "MIT", + "dependencies": { + "commander": "^14.0.0" + }, + "bin": { + "figlet": "bin/index.js" + }, + "engines": { + "node": ">= 17.0.0" + } + }, + "node_modules/figlet/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "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/file-type": { + "version": "20.5.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.5.0.tgz", + "integrity": "sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.6", + "strtok3": "^10.2.0", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "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/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/fingerprint-generator": { + "version": "2.1.81", + "resolved": "https://registry.npmjs.org/fingerprint-generator/-/fingerprint-generator-2.1.81.tgz", + "integrity": "sha512-R8Cgnv9AhsTG8MN+DCuFolq2cJPdTNDKOM11EaRSCfRBnBGsPWTTm9e3INld1rzU+bMITvqAcghlCjXOVCrYUA==", + "license": "Apache-2.0", + "dependencies": { + "generative-bayesian-network": "^2.1.81", + "header-generator": "^2.1.81", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fingerprint-injector": { + "version": "2.1.81", + "resolved": "https://registry.npmjs.org/fingerprint-injector/-/fingerprint-injector-2.1.81.tgz", + "integrity": "sha512-/HlE+pDTety9ygiYHdlh+7lDhrm5sxOB7ThWdhDwDVqSr7zI4D/Ruqhg7iDmxMLVWTcUCXsiA9h9tgQgSiPolw==", + "license": "Apache-2.0", + "dependencies": { + "fingerprint-generator": "^2.1.81", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "playwright": "^1.22.2", + "puppeteer": ">= 9.x" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "puppeteer": { + "optional": true + } + } + }, + "node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", + "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "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/form-data-encoder": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.1.0.tgz", + "integrity": "sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==", + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generative-bayesian-network": { + "version": "2.1.81", + "resolved": "https://registry.npmjs.org/generative-bayesian-network/-/generative-bayesian-network-2.1.81.tgz", + "integrity": "sha512-LrYK+CY5n21p437oahz8jRqTgw0i+S08H+ypag1sgZilfCj33k8Tp8kcFtPiWKsEEJ6niN9gRFP12+r06xB4rQ==", + "license": "Apache-2.0", + "dependencies": { + "adm-zip": "^0.5.9", + "tslib": "^2.4.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-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "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==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "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/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/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "14.6.6", + "resolved": "https://registry.npmjs.org/got/-/got-14.6.6.tgz", + "integrity": "sha512-QLV1qeYSo5l13mQzWgP/y0LbMr5Plr5fJilgAIwgnwseproEbtNym8xpLsDzeZ6MWXgNE6kdWGBjdh3zT/Qerg==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^7.0.1", + "byte-counter": "^0.1.0", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^13.0.12", + "decompress-response": "^10.0.0", + "form-data-encoder": "^4.0.2", + "http2-wrapper": "^2.2.1", + "keyv": "^5.5.3", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^4.0.1", + "responselike": "^4.0.2", + "type-fest": "^4.26.1" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got-scraping": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/got-scraping/-/got-scraping-4.2.1.tgz", + "integrity": "sha512-rhOlO1L4H4Cm31smHJqPtAaXOUrhSKsiTrbZSHKFQW1E/mkTDopnHHpRnXJpqzE0faj+zPsVQnyifIqO+K+cLQ==", + "license": "Apache-2.0", + "dependencies": { + "got": "^14.2.1", + "header-generator": "^2.1.41", + "http2-wrapper": "^2.2.0", + "mimic-response": "^4.0.0", + "ow": "^1.1.1", + "quick-lru": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/got-scraping/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/got-scraping/node_modules/callsites": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.2.0.tgz", + "integrity": "sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got-scraping/node_modules/dot-prop": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-7.2.0.tgz", + "integrity": "sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==", + "license": "MIT", + "dependencies": { + "type-fest": "^2.11.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got-scraping/node_modules/ow": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ow/-/ow-1.1.1.tgz", + "integrity": "sha512-sJBRCbS5vh1Jp9EOgwp1Ws3c16lJrUkJYlvWTYC03oyiYVwS/ns7lKRWow4w4XjDyTrA2pplQv4B2naWSR6yDA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.3.0", + "callsites": "^4.0.0", + "dot-prop": "^7.2.0", + "lodash.isequal": "^4.5.0", + "vali-date": "^1.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got-scraping/node_modules/quick-lru": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.3.0.tgz", + "integrity": "sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got-scraping/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "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==", + "license": "ISC" + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/header-generator": { + "version": "2.1.81", + "resolved": "https://registry.npmjs.org/header-generator/-/header-generator-2.1.81.tgz", + "integrity": "sha512-6+27UuqCHFx4xrTWIgcSF/x2WJ+PuVLxziXfPaVLRXi1lXIbTkXO+ffHJefVrdRT5/XEeWfJHrSIE2m1hAdWxw==", + "license": "Apache-2.0", + "dependencies": { + "browserslist": "^4.21.1", + "generative-bayesian-network": "^2.1.81", + "ow": "^0.28.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/helmet": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-8.1.0.tgz", + "integrity": "sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "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==", + "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==", + "license": "BSD-2-Clause" + }, + "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==", + "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-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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/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==", + "license": "MIT" + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/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==", + "license": "MIT" + }, + "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==", + "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/idcac-playwright": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/idcac-playwright/-/idcac-playwright-0.2.0.tgz", + "integrity": "sha512-qJH7vQgq3TKnhea/3Z3jlEJL7NC9vK9BkLClAzQHVRepBtq1fWfSI4fSuMKcPq7nDUTTlIEIS+vU+GRwwR1BXw==", + "license": "GPL-3.0-only" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.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/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/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "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/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/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-any-array": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-2.0.1.tgz", + "integrity": "sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==", + "license": "MIT" + }, + "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-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/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-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "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/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "license": "MIT", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/jsdom/node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "license": "MIT" + }, + "node_modules/jsdom/node_modules/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "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-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/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==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "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/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/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "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/linkedom": { + "version": "0.18.12", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.18.12.tgz", + "integrity": "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==", + "license": "ISC", + "dependencies": { + "css-select": "^5.1.0", + "cssom": "^0.5.0", + "html-escaper": "^3.0.3", + "htmlparser2": "^10.0.0", + "uhyphen": "^0.2.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": ">= 2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", + "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "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.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "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==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/luxon": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ml-array-max": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.4.tgz", + "integrity": "sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0" + } + }, + "node_modules/ml-array-min": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.3.tgz", + "integrity": "sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0" + } + }, + "node_modules/ml-array-rescale": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz", + "integrity": "sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0", + "ml-array-max": "^1.2.4", + "ml-array-min": "^1.2.3" + } + }, + "node_modules/ml-logistic-regression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ml-logistic-regression/-/ml-logistic-regression-2.0.0.tgz", + "integrity": "sha512-xHhB91ut8GRRbJyB1ZQfKsl1MHmE1PqMeRjxhks96M5BGvCbC9eEojf4KgRMKM2LxFblhVUcVzweAoPB48Nt0A==", + "license": "MIT", + "dependencies": { + "ml-matrix": "^6.5.0" + } + }, + "node_modules/ml-matrix": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.12.1.tgz", + "integrity": "sha512-TJ+8eOFdp+INvzR4zAuwBQJznDUfktMtOB6g/hUcGh3rcyjxbz4Te57Pgri8Q9bhSQ7Zys4IYOGhFdnlgeB6Lw==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.1", + "ml-array-rescale": "^1.3.7" + } + }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/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/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "license": "MIT" + }, + "node_modules/normalize-url": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", + "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "license": "MIT" + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "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==", + "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==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ow": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.28.2.tgz", + "integrity": "sha512-dD4UpyBh/9m4X2NVjA+73/ZPBRF+uF4zIMFvvQsabMiEK8x41L3rQ8EENOi35kyyoaJwNxEeJcP6Fj1H4U409Q==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.2.0", + "callsites": "^3.1.0", + "dot-prop": "^6.0.1", + "lodash.isequal": "^4.5.0", + "vali-date": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ow/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/p-cancelable": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", + "integrity": "sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + } + }, + "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==", + "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-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "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==", + "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-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/parent-require": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", + "integrity": "sha512-2MXDNZC4aXdkkap+rBBMv0lUsfJqvX5/2FiYYnfCnorZt3Pk06/IOR5KeaoghgS2w07MLWgjbsnyaq6PdHn2LQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "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==", + "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-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-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==", + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/pg": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-boss": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/pg-boss/-/pg-boss-10.4.2.tgz", + "integrity": "sha512-AttEWOtSzn53av8OnCMWEanwRBvjkZCE1y5nLrZnwvkkMnlZ5XpWDpZ7sKI/BYjvi2OVieMX37arD2ACgJ750w==", + "license": "MIT", + "dependencies": { + "cron-parser": "^4.9.0", + "pg": "^8.16.3", + "serialize-error": "^8.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "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/pino": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.3.0.tgz", + "integrity": "sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pump": "^3.0.0", + "readable-stream": "^4.0.0", + "secure-json-parse": "^2.4.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-pretty/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/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/pkg-dir/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/pkg-dir/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/pkg-dir/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/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "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-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proper-lockfile/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-chain": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/proxy-chain/-/proxy-chain-2.7.1.tgz", + "integrity": "sha512-LtXu0miohJYrHWJxv8wA6EoGreRcX1hxKb7qlE1pMFH+BXE7bqMvpyhzR/JvR6M5SzYKzyHFpvfmYJrZeMtwAg==", + "license": "Apache-2.0", + "dependencies": { + "socks": "^2.8.3", + "socks-proxy-agent": "^8.0.3", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "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/raw-body/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==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "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/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "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/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/responselike": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-4.0.2.tgz", + "integrity": "sha512-cGk8IbWEAnaCpdAt1BHzJ3Ahz5ewDJa0KseTsE3qIRMJ3C698W8psM7byCeWVpd/Ha7FUYzuRVzXoKoM6nRUbA==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/robots-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/robots-parser/-/robots-parser-3.0.1.tgz", + "integrity": "sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/rollup": { + "version": "4.60.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", + "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", + "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.60.1", + "@rollup/rollup-android-arm64": "4.60.1", + "@rollup/rollup-darwin-arm64": "4.60.1", + "@rollup/rollup-darwin-x64": "4.60.1", + "@rollup/rollup-freebsd-arm64": "4.60.1", + "@rollup/rollup-freebsd-x64": "4.60.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", + "@rollup/rollup-linux-arm-musleabihf": "4.60.1", + "@rollup/rollup-linux-arm64-gnu": "4.60.1", + "@rollup/rollup-linux-arm64-musl": "4.60.1", + "@rollup/rollup-linux-loong64-gnu": "4.60.1", + "@rollup/rollup-linux-loong64-musl": "4.60.1", + "@rollup/rollup-linux-ppc64-gnu": "4.60.1", + "@rollup/rollup-linux-ppc64-musl": "4.60.1", + "@rollup/rollup-linux-riscv64-gnu": "4.60.1", + "@rollup/rollup-linux-riscv64-musl": "4.60.1", + "@rollup/rollup-linux-s390x-gnu": "4.60.1", + "@rollup/rollup-linux-x64-gnu": "4.60.1", + "@rollup/rollup-linux-x64-musl": "4.60.1", + "@rollup/rollup-openbsd-x64": "4.60.1", + "@rollup/rollup-openharmony-arm64": "4.60.1", + "@rollup/rollup-win32-arm64-msvc": "4.60.1", + "@rollup/rollup-win32-ia32-msvc": "4.60.1", + "@rollup/rollup-win32-x64-gnu": "4.60.1", + "@rollup/rollup-win32-x64-msvc": "4.60.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "license": "MIT" + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "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-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/secure-json-parse": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", + "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", + "license": "BSD-3-Clause" + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "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/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "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/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "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/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==", + "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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "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==", + "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==", + "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/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "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==", + "license": "ISC" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.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==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/socks-proxy-agent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socks-proxy-agent/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==", + "license": "MIT" + }, + "node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "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/split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", + "license": "BSD-3-Clause" + }, + "node_modules/stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1" + } + }, + "node_modules/stream-json": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", + "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", + "license": "BSD-3-Clause", + "dependencies": { + "stream-chain": "^2.2.5" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-comparison": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string-comparison/-/string-comparison-1.3.0.tgz", + "integrity": "sha512-46aD+slEwybxAMPRII83ATbgMgTiz5P8mVd7Z6VJsCzSHFjdt1hkAVLeFxPIyEb11tc6ihpJTlIqoO0MCF6NPw==", + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + } + }, + "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/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/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==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strtok3": { + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", + "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.27.tgz", + "integrity": "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.27" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.27.tgz", + "integrity": "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "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-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "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/tsup": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.1.tgz", + "integrity": "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tsup/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/tsup/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/tsup/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.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-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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/ufo": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", + "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/uhyphen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.2.0.tgz", + "integrity": "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==", + "license": "ISC" + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.6.tgz", + "integrity": "sha512-Xi4agocCbRzt0yYMZGMA6ApD7gvtUFaxm4ZmeacWI4cZxaF6C+8I8QfofC20NAePiB/IcvZmzkJ7XPa471AEtA==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.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==", + "license": "MIT", + "engines": { + "node": ">= 0.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==", + "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/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==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg==", + "license": "MIT", + "engines": { + "node": ">=0.10.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==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/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/vite-node/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/vite-node/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vite/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/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/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/vitest/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/vitest/node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/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==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "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/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargonaut": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", + "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", + "license": "Apache-2.0", + "dependencies": { + "chalk": "^1.1.1", + "figlet": "^1.1.1", + "parent-require": "^1.0.0" + } + }, + "node_modules/yargonaut/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/yargonaut/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargonaut/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..03ac0d4 --- /dev/null +++ b/package.json @@ -0,0 +1,59 @@ +{ + "name": "transceiver-intelligence-platform", + "version": "0.1.0", + "description": "The Octopart for Optical Transceivers — real-time pricing, compatibility, hype cycle engine", + "private": true, + "type": "module", + "engines": { + "node": ">=20.0.0" + }, + "scripts": { + "dev": "tsx watch src/api/server.ts", + "start": "node dist/api/server.js", + "build": "tsup src/api/server.ts src/mcp/server.ts --format esm --dts", + "migrate": "node --import tsx scripts/migrate.ts", + "seed": "node --import tsx scripts/seed.ts", + "crawl": "node --import tsx scripts/crawl.ts", + "crawl:fs": "node --import tsx src/crawlers/fscom.ts", + "crawl:10gtek": "node --import tsx src/crawlers/tengtek.ts", + "crawl:ebay": "node --import tsx src/crawlers/ebay.ts", + "crawl:cisco-tmg": "node --import tsx src/crawlers/cisco-tmg.ts", + "crawl:axiom": "node --import tsx src/crawlers/axiom.ts", + "crawl:prolabs": "node --import tsx src/crawlers/prolabs.ts", + "mcp": "node --import tsx src/mcp/server.ts", + "test": "vitest", + "lint": "eslint src/", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "pg": "^8.13.0", + "express": "^4.21.0", + "cors": "^2.8.5", + "helmet": "^8.0.0", + "compression": "^1.7.5", + "crawlee": "^3.12.0", + "playwright": "^1.48.0", + "cheerio": "^1.0.0", + "pg-boss": "^10.1.0", + "pino": "^9.5.0", + "pino-pretty": "^11.3.0", + "zod": "^3.23.0", + "dotenv": "^16.4.0", + "p-queue": "^8.0.1", + "p-retry": "^6.2.0", + "cron": "^3.1.0", + "tsx": "^4.19.0", + "undici": "^7.0.0" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "@types/express": "^5.0.0", + "@types/pg": "^8.11.0", + "@types/cors": "^2.8.17", + "@types/compression": "^1.7.5", + "typescript": "^5.6.0", + "tsup": "^8.3.0", + "vitest": "^2.1.0", + "eslint": "^9.0.0" + } +} diff --git a/scripts/crawl.ts b/scripts/crawl.ts new file mode 100644 index 0000000..da79eaf --- /dev/null +++ b/scripts/crawl.ts @@ -0,0 +1,40 @@ +import 'dotenv/config'; +import { pino } from 'pino'; +import { FsComCrawler } from '../src/crawlers/fscom.js'; +import { EbayCrawler } from '../src/crawlers/ebay.js'; + +const log = pino({ name: 'crawl-orchestrator' }); + +const CRAWLERS: Record { run: () => Promise }> = { + fscom: () => new FsComCrawler(), + ebay: () => new EbayCrawler(), +}; + +async function main() { + const target = process.argv[2]; + + if (target && CRAWLERS[target]) { + log.info({ crawler: target }, 'Running single crawler'); + const crawler = CRAWLERS[target]!(); + await crawler.run(); + } else if (target === 'all' || !target) { + log.info('Running all crawlers sequentially'); + for (const [name, factory] of Object.entries(CRAWLERS)) { + log.info({ crawler: name }, 'Starting crawler'); + try { + const crawler = factory(); + await crawler.run(); + } catch (err) { + log.error({ err, crawler: name }, 'Crawler failed'); + } + } + } else { + log.error(`Unknown crawler: ${target}. Available: ${Object.keys(CRAWLERS).join(', ')}`); + process.exit(1); + } + + log.info('Crawl orchestration complete'); + process.exit(0); +} + +main(); diff --git a/scripts/migrate.ts b/scripts/migrate.ts new file mode 100644 index 0000000..b24a815 --- /dev/null +++ b/scripts/migrate.ts @@ -0,0 +1,55 @@ +import 'dotenv/config'; +import { readFileSync, readdirSync } from 'fs'; +import { join } from 'path'; +import { query, pool } from '../src/utils/db.js'; +import { pino } from 'pino'; + +const log = pino({ name: 'migrate' }); + +async function main() { + log.info('Running migrations...'); + + // Create migrations tracking table + await query(` + CREATE TABLE IF NOT EXISTS _migrations ( + id SERIAL PRIMARY KEY, + name VARCHAR(200) NOT NULL UNIQUE, + applied_at TIMESTAMPTZ DEFAULT NOW() + ) + `); + + // Get applied migrations + const applied = await query('SELECT name FROM _migrations ORDER BY id'); + const appliedSet = new Set(applied.rows.map(r => r.name)); + + // Read migration files + const migrationsDir = join(import.meta.dirname ?? '.', '..', 'migrations'); + const files = readdirSync(migrationsDir) + .filter(f => f.endsWith('.sql')) + .sort(); + + for (const file of files) { + if (appliedSet.has(file)) { + log.info(`Skip (already applied): ${file}`); + continue; + } + + log.info(`Applying: ${file}`); + const sql = readFileSync(join(migrationsDir, file), 'utf-8'); + + try { + await query(sql); + await query('INSERT INTO _migrations (name) VALUES ($1)', [file]); + log.info(`Applied: ${file}`); + } catch (err) { + log.error({ err, file }, 'Migration failed'); + process.exit(1); + } + } + + log.info('All migrations applied'); + await pool.end(); + process.exit(0); +} + +main(); diff --git a/scripts/seed.ts b/scripts/seed.ts new file mode 100644 index 0000000..8adb8d2 --- /dev/null +++ b/scripts/seed.ts @@ -0,0 +1,142 @@ +import 'dotenv/config'; +import { query, transaction } from '../src/utils/db.js'; +import { standards } from '../seed/standards.js'; +import { formFactors } from '../seed/form-factors.js'; +import { vendors } from '../seed/vendors.js'; +import { transceivers } from '../seed/transceivers.js'; +import { networkDevices } from '../seed/network-devices.js'; +import { pino } from 'pino'; + +const log = pino({ name: 'seed' }); + +async function seedStandards() { + log.info(`Seeding ${standards.length} standards...`); + for (const s of standards) { + await query( + `INSERT INTO standards (name, body, version, year, url, description) + VALUES ($1, $2, $3, $4, $5, $6) + ON CONFLICT (name) DO UPDATE SET version = $3, year = $4, url = $5, description = $6, updated_at = NOW()`, + [s.name, s.body, s.version ?? null, s.year ?? null, s.url ?? null, s.description ?? null] + ); + } + log.info('Standards seeded'); +} + +async function seedFormFactors() { + log.info(`Seeding ${formFactors.length} form factors...`); + for (const ff of formFactors) { + await query( + `INSERT INTO form_factors (name, full_name, lanes, max_data_rate, data_rate_unit, width_mm, height_mm, depth_mm, power_max_w, generation, release_year, eol_year, description, image_url) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + ON CONFLICT (name) DO UPDATE SET full_name = $2, lanes = $3, max_data_rate = $4, power_max_w = $9, updated_at = NOW()`, + [ff.name, ff.full_name ?? null, ff.lanes ?? null, ff.max_data_rate ?? null, ff.data_rate_unit ?? 'Gbps', + ff.width_mm ?? null, ff.height_mm ?? null, ff.depth_mm ?? null, ff.power_max_w ?? null, + ff.generation ?? null, ff.release_year ?? null, ff.eol_year ?? null, ff.description ?? null, ff.image_url ?? null] + ); + } + log.info('Form factors seeded'); +} + +async function seedVendors() { + log.info(`Seeding ${vendors.length} vendors...`); + for (const v of vendors) { + await query( + `INSERT INTO vendors (name, slug, vendor_type, website, logo_url, country, founded_year, description, is_oem, is_factory, aliases, scrape_url, scrape_enabled) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + ON CONFLICT (slug) DO UPDATE SET name = $1, website = $4, description = $8, scrape_url = $12, scrape_enabled = $13, updated_at = NOW()`, + [v.name, v.slug, v.vendor_type, v.website ?? null, v.logo_url ?? null, + v.country ?? null, v.founded_year ?? null, v.description ?? null, + v.is_oem ?? false, v.is_factory ?? false, v.aliases ?? null, + v.scrape_url ?? null, v.scrape_enabled ?? false] + ); + } + log.info('Vendors seeded'); +} + +async function seedTransceivers() { + log.info(`Seeding ${transceivers.length} transceivers...`); + + // Build lookup maps + const vendorRows = await query('SELECT id, slug FROM vendors'); + const vendorMap = new Map(vendorRows.rows.map(r => [r.slug, r.id])); + + const ffRows = await query('SELECT id, name FROM form_factors'); + const ffMap = new Map(ffRows.rows.map(r => [r.name, r.id])); + + for (const t of transceivers) { + const vendorId = vendorMap.get(t.vendor_slug); + if (!vendorId) { log.warn(`Vendor not found: ${t.vendor_slug}`); continue; } + + const ffId = ffMap.get(t.form_factor) ?? null; + const oemVendorId = t.oem_vendor_slug ? vendorMap.get(t.oem_vendor_slug) ?? null : null; + + await query( + `INSERT INTO transceivers (part_number, vendor_id, form_factor_id, name, category, subcategory, + data_rate, data_rate_unit, max_reach, reach_unit, wavelength_nm, wavelength_rx, + connector, fiber_type, duplex, temp_range, dom_support, + oem_part_number, oem_vendor_id, description, tags, status, source) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, 'seed') + ON CONFLICT (part_number, vendor_id) DO UPDATE SET + name = $4, category = $5, subcategory = $6, data_rate = $7, max_reach = $9, + wavelength_nm = $11, tags = $21, updated_at = NOW()`, + [ + t.part_number, vendorId, ffId, t.name, t.category, t.subcategory, + t.data_rate, t.data_rate_unit, t.max_reach, t.reach_unit, + t.wavelength_nm, t.wavelength_rx ?? null, + t.connector, t.fiber_type, t.duplex, t.temp_range, t.dom_support, + t.oem_part_number ?? null, oemVendorId, t.description ?? null, + t.tags, t.status + ] + ); + } + log.info('Transceivers seeded'); +} + +async function seedNetworkDevices() { + log.info(`Seeding ${networkDevices.length} network devices...`); + + const vendorRows = await query('SELECT id, slug FROM vendors'); + const vendorMap = new Map(vendorRows.rows.map(r => [r.slug, r.id])); + + for (const d of networkDevices) { + const vendorId = vendorMap.get(d.vendor_slug); + if (!vendorId) { log.warn(`Vendor not found: ${d.vendor_slug}`); continue; } + + await query( + `INSERT INTO network_devices (vendor_id, model, series, device_type, + ports_sfp, ports_sfp_plus, ports_sfp28, ports_qsfp_plus, ports_qsfp28, ports_qsfp_dd, ports_osfp, ports_rj45, + max_throughput, release_year, status) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) + ON CONFLICT (vendor_id, model) DO UPDATE SET + series = $3, max_throughput = $13, updated_at = NOW()`, + [ + vendorId, d.model, d.series, d.device_type, + d.ports_sfp ?? 0, d.ports_sfp_plus ?? 0, d.ports_sfp28 ?? 0, + d.ports_qsfp_plus ?? 0, d.ports_qsfp28 ?? 0, d.ports_qsfp_dd ?? 0, + d.ports_osfp ?? 0, d.ports_rj45 ?? 0, + d.max_throughput ?? null, d.release_year ?? null, d.status + ] + ); + } + log.info('Network devices seeded'); +} + +async function main() { + log.info('Starting TIP seed...'); + const start = Date.now(); + + await seedStandards(); + await seedFormFactors(); + await seedVendors(); + await seedTransceivers(); + await seedNetworkDevices(); + + const duration = ((Date.now() - start) / 1000).toFixed(1); + log.info(`Seed complete in ${duration}s`); + process.exit(0); +} + +main().catch(err => { + log.error({ err }, 'Seed failed'); + process.exit(1); +}); diff --git a/seed/form-factors.ts b/seed/form-factors.ts new file mode 100644 index 0000000..9ef3a03 --- /dev/null +++ b/seed/form-factors.ts @@ -0,0 +1,234 @@ +import type { FormFactor } from '../src/types/index.js'; + +export const formFactors: FormFactor[] = [ + // SFP Family + { + name: 'SFP', full_name: 'Small Form-factor Pluggable', + lanes: 1, max_data_rate: 4.25, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 56.5, power_max_w: 1.0, + generation: 1, release_year: 2001, + description: 'Standard SFP for 100M/1G/2.5G/4G FC applications' + }, + { + name: 'SFP+', full_name: 'Enhanced Small Form-factor Pluggable', + lanes: 1, max_data_rate: 16, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 56.5, power_max_w: 1.5, + generation: 2, release_year: 2006, + description: '10G SFP form factor, backward compatible with SFP' + }, + { + name: 'SFP28', full_name: 'SFP28 (28 Gbaud)', + lanes: 1, max_data_rate: 25, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 56.5, power_max_w: 1.5, + generation: 3, release_year: 2014, + description: '25G SFP form factor, same cage as SFP/SFP+' + }, + { + name: 'SFP56', full_name: 'SFP56 (56 Gbaud PAM4)', + lanes: 1, max_data_rate: 50, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 56.5, power_max_w: 2.0, + generation: 4, release_year: 2019, + description: '50G SFP using PAM4 modulation' + }, + { + name: 'SFP-DD', full_name: 'SFP Double Density', + lanes: 2, max_data_rate: 100, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 67.6, power_max_w: 3.5, + generation: 5, release_year: 2019, + description: '100G dual-lane SFP, backward compatible with SFP' + }, + { + name: 'SFP112', full_name: 'SFP112 (112 Gbaud)', + lanes: 1, max_data_rate: 100, data_rate_unit: 'Gbps', + width_mm: 13.4, height_mm: 8.5, depth_mm: 56.5, power_max_w: 2.5, + generation: 6, release_year: 2024, + description: '100G single-lane SFP with 112G SerDes' + }, + + // QSFP Family + { + name: 'QSFP+', full_name: 'Quad Small Form-factor Pluggable Plus', + lanes: 4, max_data_rate: 40, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 8.5, depth_mm: 72.4, power_max_w: 3.5, + generation: 2, release_year: 2009, + description: '40G QSFP (4x10G), widely deployed in data centers' + }, + { + name: 'QSFP28', full_name: 'QSFP28 (28 Gbaud)', + lanes: 4, max_data_rate: 100, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 8.5, depth_mm: 72.4, power_max_w: 3.5, + generation: 3, release_year: 2014, + description: '100G QSFP (4x25G), most popular 100G form factor' + }, + { + name: 'QSFP56', full_name: 'QSFP56 (56 Gbaud PAM4)', + lanes: 4, max_data_rate: 200, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 8.5, depth_mm: 72.4, power_max_w: 5.0, + generation: 4, release_year: 2019, + description: '200G QSFP (4x50G PAM4)' + }, + { + name: 'QSFP-DD', full_name: 'QSFP Double Density', + lanes: 8, max_data_rate: 400, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 9.5, depth_mm: 89.4, power_max_w: 12.0, + generation: 5, release_year: 2019, + description: '400G QSFP-DD (8x50G), backward compatible with QSFP28' + }, + { + name: 'QSFP-DD800', full_name: 'QSFP-DD800 (112 Gbaud)', + lanes: 8, max_data_rate: 800, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 9.5, depth_mm: 89.4, power_max_w: 18.0, + generation: 6, release_year: 2023, + description: '800G QSFP-DD (8x100G), next-gen data center interconnect' + }, + + // OSFP Family + { + name: 'OSFP', full_name: 'Octal Small Form-factor Pluggable', + lanes: 8, max_data_rate: 400, data_rate_unit: 'Gbps', + width_mm: 22.58, height_mm: 13.0, depth_mm: 107.8, power_max_w: 15.0, + generation: 5, release_year: 2019, + description: '400G OSFP (8x50G), larger than QSFP-DD for better thermal' + }, + { + name: 'OSFP-XD', full_name: 'OSFP Extra Density', + lanes: 16, max_data_rate: 1600, data_rate_unit: 'Gbps', + width_mm: 22.58, height_mm: 13.0, depth_mm: 107.8, power_max_w: 30.0, + generation: 7, release_year: 2024, + description: '1.6T OSFP (16x100G), designed for AI/ML clusters' + }, + + // CFP Family + { + name: 'CFP', full_name: 'C Form-factor Pluggable', + lanes: 10, max_data_rate: 100, data_rate_unit: 'Gbps', + width_mm: 82.0, height_mm: 12.4, depth_mm: 144.75, power_max_w: 24.0, + generation: 1, release_year: 2010, + description: 'First 100G pluggable, large form factor' + }, + { + name: 'CFP2', full_name: 'CFP2', + lanes: 8, max_data_rate: 200, data_rate_unit: 'Gbps', + width_mm: 41.5, height_mm: 12.4, depth_mm: 108.0, power_max_w: 12.0, + generation: 2, release_year: 2013, + description: 'Half-width CFP, popular for 100G coherent' + }, + { + name: 'CFP2-DCO', full_name: 'CFP2 Digital Coherent Optics', + lanes: 4, max_data_rate: 400, data_rate_unit: 'Gbps', + width_mm: 41.5, height_mm: 12.4, depth_mm: 108.0, power_max_w: 20.0, + generation: 3, release_year: 2018, + description: 'CFP2 with integrated DSP for coherent applications' + }, + { + name: 'CFP4', full_name: 'CFP4', + lanes: 4, max_data_rate: 100, data_rate_unit: 'Gbps', + width_mm: 21.5, height_mm: 9.5, depth_mm: 92.0, power_max_w: 6.0, + generation: 3, release_year: 2014, + description: 'Quarter-width CFP, compact 100G' + }, + { + name: 'CFP8', full_name: 'CFP8', + lanes: 8, max_data_rate: 400, data_rate_unit: 'Gbps', + width_mm: 40.0, height_mm: 9.5, depth_mm: 102.0, power_max_w: 12.0, + generation: 4, release_year: 2017, + description: 'CFP8 for 400G applications' + }, + + // XFP + { + name: 'XFP', full_name: '10 Gigabit Small Form Factor Pluggable', + lanes: 1, max_data_rate: 11.1, data_rate_unit: 'Gbps', + width_mm: 18.35, height_mm: 8.5, depth_mm: 78.0, power_max_w: 3.5, + generation: 1, release_year: 2002, eol_year: 2020, + description: 'First 10G pluggable, superseded by SFP+' + }, + + // GBIC + { + name: 'GBIC', full_name: 'Gigabit Interface Converter', + lanes: 1, max_data_rate: 1.25, data_rate_unit: 'Gbps', + width_mm: 30.0, height_mm: 12.7, depth_mm: 65.0, power_max_w: 2.0, + generation: 0, release_year: 1995, eol_year: 2010, + description: 'Original pluggable transceiver, superseded by SFP' + }, + + // X2 / XENPAK + { + name: 'X2', full_name: 'X2 10 Gigabit Transceiver', + lanes: 4, max_data_rate: 10, data_rate_unit: 'Gbps', + width_mm: 35.0, height_mm: 13.0, depth_mm: 64.4, power_max_w: 5.0, + generation: 1, release_year: 2004, eol_year: 2015, + description: 'Compact 10G, superseded by SFP+' + }, + { + name: 'XENPAK', full_name: 'XENPAK 10 Gigabit Transceiver', + lanes: 4, max_data_rate: 10, data_rate_unit: 'Gbps', + width_mm: 35.0, height_mm: 13.5, depth_mm: 131.0, power_max_w: 8.0, + generation: 0, release_year: 2002, eol_year: 2012, + description: 'Early 10G form factor, superseded by XFP/SFP+' + }, + + // CXP + { + name: 'CXP', full_name: 'CXP 12x QDR InfiniBand', + lanes: 12, max_data_rate: 120, data_rate_unit: 'Gbps', + width_mm: 45.0, height_mm: 12.0, depth_mm: 104.0, power_max_w: 6.0, + generation: 2, release_year: 2010, eol_year: 2018, + description: '120G parallel optics for InfiniBand' + }, + + // Copper/DAC form factors + { + name: 'QSFP28-DAC', full_name: 'QSFP28 Direct Attach Copper', + lanes: 4, max_data_rate: 100, data_rate_unit: 'Gbps', + generation: 3, release_year: 2015, + description: '100G passive/active copper cable assembly' + }, + { + name: 'QSFP-DD-DAC', full_name: 'QSFP-DD Direct Attach Copper', + lanes: 8, max_data_rate: 400, data_rate_unit: 'Gbps', + generation: 5, release_year: 2020, + description: '400G DAC cable assembly' + }, + { + name: 'SFP28-DAC', full_name: 'SFP28 Direct Attach Copper', + lanes: 1, max_data_rate: 25, data_rate_unit: 'Gbps', + generation: 3, release_year: 2015, + description: '25G DAC cable assembly' + }, + { + name: 'SFP+-DAC', full_name: 'SFP+ Direct Attach Copper', + lanes: 1, max_data_rate: 10, data_rate_unit: 'Gbps', + generation: 2, release_year: 2008, + description: '10G DAC cable assembly' + }, + + // AOC + { + name: 'QSFP28-AOC', full_name: 'QSFP28 Active Optical Cable', + lanes: 4, max_data_rate: 100, data_rate_unit: 'Gbps', + generation: 3, release_year: 2015, + description: '100G AOC cable assembly' + }, + { + name: 'QSFP-DD-AOC', full_name: 'QSFP-DD Active Optical Cable', + lanes: 8, max_data_rate: 400, data_rate_unit: 'Gbps', + generation: 5, release_year: 2020, + description: '400G AOC cable assembly' + }, + + // Emerging + { + name: 'CPO', full_name: 'Co-Packaged Optics', + lanes: 32, max_data_rate: 3200, data_rate_unit: 'Gbps', + power_max_w: 50.0, generation: 8, release_year: 2027, + description: 'Optics co-packaged with switch ASIC (Broadcom/Intel roadmap)' + }, + { + name: 'LPO', full_name: 'Linear-drive Pluggable Optics', + lanes: 8, max_data_rate: 800, data_rate_unit: 'Gbps', + power_max_w: 10.0, generation: 7, release_year: 2025, + description: 'Linear-drive optics eliminating DSP for lower power' + }, +]; diff --git a/seed/network-devices.ts b/seed/network-devices.ts new file mode 100644 index 0000000..308fde7 --- /dev/null +++ b/seed/network-devices.ts @@ -0,0 +1,126 @@ +// Network Switch/Router Seed Data — Major Series with Port Configurations + +interface SeedDevice { + vendor_slug: string; + model: string; + series: string; + device_type: string; + ports_sfp?: number; + ports_sfp_plus?: number; + ports_sfp28?: number; + ports_qsfp_plus?: number; + ports_qsfp28?: number; + ports_qsfp_dd?: number; + ports_osfp?: number; + ports_rj45?: number; + max_throughput?: string; + release_year?: number; + status: string; +} + +export const networkDevices: SeedDevice[] = [ + // ============================================================ + // CISCO + // ============================================================ + // Catalyst 9300 + { vendor_slug: 'cisco', model: 'C9300-24T', series: 'Catalyst 9300', device_type: 'switch', ports_rj45: 24, ports_sfp_plus: 4, max_throughput: '480 Gbps', release_year: 2017, status: 'active' }, + { vendor_slug: 'cisco', model: 'C9300-48P', series: 'Catalyst 9300', device_type: 'switch', ports_rj45: 48, ports_sfp_plus: 4, max_throughput: '480 Gbps', release_year: 2017, status: 'active' }, + { vendor_slug: 'cisco', model: 'C9300-24UX', series: 'Catalyst 9300', device_type: 'switch', ports_sfp_plus: 24, ports_qsfp28: 2, max_throughput: '480 Gbps', release_year: 2018, status: 'active' }, + { vendor_slug: 'cisco', model: 'C9300L-48T-4X', series: 'Catalyst 9300L', device_type: 'switch', ports_rj45: 48, ports_sfp_plus: 4, max_throughput: '240 Gbps', release_year: 2019, status: 'active' }, + // Catalyst 9400 + { vendor_slug: 'cisco', model: 'C9400-SUP-1', series: 'Catalyst 9400', device_type: 'switch', max_throughput: '9 Tbps', release_year: 2017, status: 'active' }, + // Catalyst 9500 + { vendor_slug: 'cisco', model: 'C9500-24Y4C', series: 'Catalyst 9500', device_type: 'switch', ports_sfp28: 24, ports_qsfp28: 4, max_throughput: '3.6 Tbps', release_year: 2018, status: 'active' }, + { vendor_slug: 'cisco', model: 'C9500-48Y4C', series: 'Catalyst 9500', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 4, max_throughput: '6.4 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'cisco', model: 'C9500-32C', series: 'Catalyst 9500', device_type: 'switch', ports_qsfp28: 32, max_throughput: '6.4 Tbps', release_year: 2019, status: 'active' }, + // Nexus 9000 + { vendor_slug: 'cisco', model: 'N9K-C9336C-FX2', series: 'Nexus 9300', device_type: 'switch', ports_qsfp28: 36, max_throughput: '7.2 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'cisco', model: 'N9K-C93180YC-FX', series: 'Nexus 9300', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 6, max_throughput: '3.6 Tbps', release_year: 2018, status: 'active' }, + { vendor_slug: 'cisco', model: 'N9K-C9364D-GX2A', series: 'Nexus 9300', device_type: 'switch', ports_qsfp_dd: 64, max_throughput: '25.6 Tbps', release_year: 2022, status: 'active' }, + { vendor_slug: 'cisco', model: 'N9K-C9332D-GX2B', series: 'Nexus 9300', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2022, status: 'active' }, + { vendor_slug: 'cisco', model: 'N9K-C9508', series: 'Nexus 9500', device_type: 'switch', max_throughput: '172.8 Tbps', release_year: 2013, status: 'active' }, + // NCS 5500 + { vendor_slug: 'cisco', model: 'NCS-5501-SE', series: 'NCS 5500', device_type: 'router', ports_sfp28: 40, ports_qsfp28: 4, max_throughput: '4 Tbps', release_year: 2017, status: 'active' }, + { vendor_slug: 'cisco', model: 'NCS-5504', series: 'NCS 5500', device_type: 'router', max_throughput: '64 Tbps', release_year: 2016, status: 'active' }, + // ASR 9000 + { vendor_slug: 'cisco', model: 'ASR-9901', series: 'ASR 9000', device_type: 'router', ports_sfp_plus: 20, ports_qsfp_plus: 4, max_throughput: '480 Gbps', release_year: 2015, status: 'active' }, + { vendor_slug: 'cisco', model: 'ASR-9006', series: 'ASR 9000', device_type: 'router', max_throughput: '19.2 Tbps', release_year: 2010, status: 'active' }, + // Cisco 8000 + { vendor_slug: 'cisco', model: '8201-32FH', series: 'Cisco 8000', device_type: 'router', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'cisco', model: '8111-32EH', series: 'Cisco 8000', device_type: 'router', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2023, status: 'active' }, + + // ============================================================ + // JUNIPER + // ============================================================ + { vendor_slug: 'juniper', model: 'QFX5120-48T', series: 'QFX5120', device_type: 'switch', ports_rj45: 48, ports_sfp28: 4, ports_qsfp28: 2, max_throughput: '1.76 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'juniper', model: 'QFX5120-48Y', series: 'QFX5120', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 8, max_throughput: '3.6 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'juniper', model: 'QFX5130-32CD', series: 'QFX5130', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2022, status: 'active' }, + { vendor_slug: 'juniper', model: 'QFX5220-32CD', series: 'QFX5220', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'juniper', model: 'QFX5700-96S', series: 'QFX5700', device_type: 'switch', ports_sfp28: 96, ports_qsfp28: 8, max_throughput: '6.4 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'juniper', model: 'EX4400-48T', series: 'EX4400', device_type: 'switch', ports_rj45: 48, ports_sfp28: 4, max_throughput: '1.04 Tbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'juniper', model: 'EX4400-24P', series: 'EX4400', device_type: 'switch', ports_rj45: 24, ports_sfp28: 4, max_throughput: '520 Gbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'juniper', model: 'EX4650-48Y-AFO', series: 'EX4650', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 8, max_throughput: '3.2 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'juniper', model: 'MX204', series: 'MX Series', device_type: 'router', ports_sfp28: 4, ports_qsfp28: 8, max_throughput: '400 Gbps', release_year: 2017, status: 'active' }, + { vendor_slug: 'juniper', model: 'MX304', series: 'MX Series', device_type: 'router', max_throughput: '4.8 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'juniper', model: 'PTX10001-36MR', series: 'PTX10000', device_type: 'router', ports_qsfp_dd: 36, max_throughput: '14.4 Tbps', release_year: 2021, status: 'active' }, + + // ============================================================ + // ARISTA + // ============================================================ + { vendor_slug: 'arista', model: 'DCS-7050CX3-32S', series: '7050X3', device_type: 'switch', ports_sfp28: 32, ports_qsfp28: 2, max_throughput: '3.2 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7050SX3-48YC12', series: '7050X3', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 12, max_throughput: '6.4 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7060DX5-32', series: '7060X5', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '25.6 Tbps', release_year: 2023, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7060DX5-64S', series: '7060X5', device_type: 'switch', ports_qsfp_dd: 64, max_throughput: '51.2 Tbps', release_year: 2023, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7280CR3-32P4', series: '7280R3', device_type: 'switch', ports_qsfp28: 32, ports_qsfp_dd: 4, max_throughput: '6.4 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7280DR3-24', series: '7280R3', device_type: 'switch', ports_qsfp_dd: 24, max_throughput: '9.6 Tbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7800R3-36D', series: '7800R3', device_type: 'switch', ports_qsfp_dd: 36, max_throughput: '460.8 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'arista', model: 'DCS-7170-64C', series: '7170', device_type: 'switch', ports_qsfp28: 64, max_throughput: '6.4 Tbps', release_year: 2018, status: 'active' }, + + // ============================================================ + // HPE / ARUBA + // ============================================================ + { vendor_slug: 'hpe', model: 'JL661A', series: 'Aruba 6300M', device_type: 'switch', ports_rj45: 48, ports_sfp_plus: 4, max_throughput: '296 Gbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'hpe', model: 'JL658A', series: 'Aruba 6300F', device_type: 'switch', ports_sfp_plus: 48, ports_sfp28: 4, max_throughput: '960 Gbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'hpe', model: 'R8S89A', series: 'Aruba CX 10000', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 8, max_throughput: '3.6 Tbps', release_year: 2022, status: 'active' }, + + // ============================================================ + // DELL + // ============================================================ + { vendor_slug: 'dell', model: 'S5248F-ON', series: 'PowerSwitch S5200', device_type: 'switch', ports_sfp28: 48, ports_qsfp28: 4, ports_qsfp_dd: 2, max_throughput: '3.6 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'dell', model: 'S5296F-ON', series: 'PowerSwitch S5200', device_type: 'switch', ports_sfp28: 96, ports_qsfp28: 8, max_throughput: '6.4 Tbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'dell', model: 'Z9664F-ON', series: 'PowerSwitch Z9664', device_type: 'switch', ports_qsfp_dd: 64, max_throughput: '51.2 Tbps', release_year: 2023, status: 'active' }, + + // ============================================================ + // EDGECORE (WHITE-BOX) + // ============================================================ + { vendor_slug: 'edgecore', model: 'AS7726-32X', series: 'AS7726', device_type: 'switch', ports_qsfp28: 32, ports_sfp_plus: 2, max_throughput: '6.4 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'edgecore', model: 'AS9516-32D', series: 'AS9516', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'edgecore', model: 'AS7946-74XKSB', series: 'AS7946', device_type: 'switch', ports_osfp: 74, max_throughput: '51.2 Tbps', release_year: 2024, status: 'active' }, + + // ============================================================ + // MIKROTIK + // ============================================================ + { vendor_slug: 'mikrotik', model: 'CRS326-24G-2S+IN', series: 'CRS326', device_type: 'switch', ports_rj45: 24, ports_sfp_plus: 2, max_throughput: '68 Gbps', release_year: 2018, status: 'active' }, + { vendor_slug: 'mikrotik', model: 'CRS354-48G-4S+2Q+', series: 'CRS354', device_type: 'switch', ports_rj45: 48, ports_sfp_plus: 4, ports_qsfp_plus: 2, max_throughput: '336 Gbps', release_year: 2020, status: 'active' }, + { vendor_slug: 'mikrotik', model: 'CCR2216-1G-12XS-2XQ', series: 'CCR2216', device_type: 'router', ports_rj45: 1, ports_sfp28: 12, ports_qsfp28: 2, max_throughput: '600 Gbps', release_year: 2022, status: 'active' }, + + // ============================================================ + // FORTINET + // ============================================================ + { vendor_slug: 'fortinet', model: 'FG-600F', series: 'FortiGate 600F', device_type: 'firewall', ports_rj45: 16, ports_sfp_plus: 8, ports_sfp28: 4, max_throughput: '600 Gbps', release_year: 2022, status: 'active' }, + { vendor_slug: 'fortinet', model: 'FG-3700F', series: 'FortiGate 3700F', device_type: 'firewall', ports_rj45: 4, ports_sfp28: 16, ports_qsfp28: 8, max_throughput: '1.2 Tbps', release_year: 2022, status: 'active' }, + + // ============================================================ + // PALO ALTO + // ============================================================ + { vendor_slug: 'paloalto', model: 'PA-5450', series: 'PA-5400', device_type: 'firewall', ports_rj45: 2, ports_sfp_plus: 8, ports_qsfp28: 4, max_throughput: '150 Gbps', release_year: 2022, status: 'active' }, + { vendor_slug: 'paloalto', model: 'PA-7500', series: 'PA-7500', device_type: 'firewall', ports_qsfp_dd: 24, max_throughput: '1.5 Tbps', release_year: 2024, status: 'active' }, + + // ============================================================ + // NVIDIA / MELLANOX + // ============================================================ + { vendor_slug: 'mellanox', model: 'SN5600', series: 'Spectrum-4', device_type: 'switch', ports_osfp: 64, max_throughput: '51.2 Tbps', release_year: 2023, status: 'active' }, + { vendor_slug: 'mellanox', model: 'SN4700', series: 'Spectrum-3', device_type: 'switch', ports_qsfp_dd: 32, max_throughput: '12.8 Tbps', release_year: 2021, status: 'active' }, + { vendor_slug: 'mellanox', model: 'SN3700', series: 'Spectrum-2', device_type: 'switch', ports_qsfp28: 32, max_throughput: '6.4 Tbps', release_year: 2019, status: 'active' }, + { vendor_slug: 'mellanox', model: 'QM9700', series: 'Quantum-2', device_type: 'switch', ports_osfp: 64, max_throughput: '51.2 Tbps', release_year: 2023, status: 'active' }, +]; diff --git a/seed/standards.ts b/seed/standards.ts new file mode 100644 index 0000000..be1e9d5 --- /dev/null +++ b/seed/standards.ts @@ -0,0 +1,68 @@ +import type { Standard } from '../src/types/index.js'; + +export const standards: Standard[] = [ + // IEEE 802.3 Standards + { name: 'IEEE 802.3z', body: 'IEEE', version: '1998', year: 1998, description: 'Gigabit Ethernet over fiber (1000BASE-SX/LX/CX)' }, + { name: 'IEEE 802.3ae', body: 'IEEE', version: '2002', year: 2002, description: '10 Gigabit Ethernet (10GBASE-SR/LR/ER/SW/LW/EW)' }, + { name: 'IEEE 802.3ak', body: 'IEEE', version: '2004', year: 2004, description: '10GBASE-CX4 copper' }, + { name: 'IEEE 802.3an', body: 'IEEE', version: '2006', year: 2006, description: '10GBASE-T copper' }, + { name: 'IEEE 802.3aq', body: 'IEEE', version: '2006', year: 2006, description: '10GBASE-LRM (long reach multimode)' }, + { name: 'IEEE 802.3ba', body: 'IEEE', version: '2010', year: 2010, description: '40 Gigabit and 100 Gigabit Ethernet' }, + { name: 'IEEE 802.3bj', body: 'IEEE', version: '2014', year: 2014, description: '100GBASE-CR4/KR4/SR4' }, + { name: 'IEEE 802.3bm', body: 'IEEE', version: '2015', year: 2015, description: '40GBASE-ER4, 100GBASE-SR4 (improved)' }, + { name: 'IEEE 802.3by', body: 'IEEE', version: '2016', year: 2016, description: '25 Gigabit Ethernet' }, + { name: 'IEEE 802.3bs', body: 'IEEE', version: '2017', year: 2017, description: '200 Gigabit and 400 Gigabit Ethernet' }, + { name: 'IEEE 802.3cd', body: 'IEEE', version: '2018', year: 2018, description: '50 Gbps per lane, 50/100/200 GbE' }, + { name: 'IEEE 802.3cm', body: 'IEEE', version: '2020', year: 2020, description: '400GBASE-SR4.2 (multimode)' }, + { name: 'IEEE 802.3cn', body: 'IEEE', version: '2019', year: 2019, description: '50/100/200GBASE-ER (extended reach)' }, + { name: 'IEEE 802.3ct', body: 'IEEE', version: '2021', year: 2021, description: '100GBASE-ZR (coherent, 80km)' }, + { name: 'IEEE 802.3cu', body: 'IEEE', version: '2021', year: 2021, description: '100/400GBASE-FR/LR single-lambda' }, + { name: 'IEEE 802.3cw', body: 'IEEE', version: '2023', year: 2023, description: '400GBASE-ZR (coherent, 80km)' }, + { name: 'IEEE 802.3db', body: 'IEEE', version: '2022', year: 2022, description: '100G/200G/400G short reach over multimode' }, + { name: 'IEEE 802.3df', body: 'IEEE', version: '2024', year: 2024, description: '800GbE and 1.6TbE (200G per lane)' }, + + // SFF / SNIA Standards + { name: 'SFF-8024', body: 'SNIA/SFF', version: 'Rev 4.11', year: 2023, description: 'SFF Cross-Reference to Industry Products (transceiver type codes)', url: 'https://www.snia.org/technology-communities/sff/specifications' }, + { name: 'SFF-8431', body: 'SNIA/SFF', version: 'Rev 4.1', year: 2009, description: 'SFP+ electrical specification' }, + { name: 'SFF-8432', body: 'SNIA/SFF', version: 'Rev 5.0', year: 2007, description: 'SFP+ mechanical specification' }, + { name: 'SFF-8436', body: 'SNIA/SFF', version: 'Rev 4.1', year: 2013, description: 'QSFP+ specification' }, + { name: 'SFF-8472', body: 'SNIA/SFF', version: 'Rev 12.4', year: 2021, description: 'SFP/SFP+ Digital Diagnostic Monitoring (DDM)' }, + { name: 'SFF-8636', body: 'SNIA/SFF', version: 'Rev 2.11', year: 2019, description: 'QSFP+/QSFP28 management interface' }, + { name: 'SFF-8665', body: 'SNIA/SFF', version: 'Rev 2.0', year: 2016, description: 'QSFP+ 28 Gbps 4X specification' }, + { name: 'INF-8074i', body: 'SNIA/SFF', version: 'Rev 1.0', year: 2001, description: 'SFP Transceiver specification' }, + + // CMIS + { name: 'CMIS 4.0', body: 'OSFP-MSA', version: '4.0', year: 2019, description: 'Common Management Interface Specification (QSFP-DD/OSFP)' }, + { name: 'CMIS 5.0', body: 'OSFP-MSA', version: '5.0', year: 2021, description: 'CMIS with CDB, VDM, CMIS 5.0' }, + { name: 'CMIS 5.2', body: 'OSFP-MSA', version: '5.2', year: 2023, description: 'Latest CMIS with improved thermal management' }, + + // MSA Standards + { name: 'QSFP-DD MSA', body: 'QSFP-DD MSA', version: '6.01', year: 2022, description: 'QSFP-DD hardware specification', url: 'https://www.qsfp-dd.com' }, + { name: 'OSFP MSA', body: 'OSFP-MSA', version: '4.0', year: 2022, description: 'Octal SFP hardware specification', url: 'https://osfpmsa.org' }, + { name: 'QSFP28 MSA', body: 'QSFP-MSA', version: '2.0', year: 2015, description: 'QSFP28 100G hardware specification' }, + { name: 'CFP MSA', body: 'CFP-MSA', version: '2.0', year: 2010, description: 'C Form-factor Pluggable', url: 'https://www.cfp-msa.org' }, + { name: 'CFP2 MSA', body: 'CFP-MSA', version: '1.0', year: 2013, description: 'CFP2 form factor specification' }, + { name: 'CFP4 MSA', body: 'CFP-MSA', version: '1.0', year: 2014, description: 'CFP4 form factor specification' }, + { name: 'SFP-DD MSA', body: 'SFP-DD MSA', version: '1.0', year: 2019, description: 'SFP-DD dual-density specification' }, + + // ITU-T + { name: 'ITU-T G.694.1', body: 'ITU-T', version: '2020', year: 2020, description: 'DWDM frequency grid (spectral grids for WDM)', url: 'https://www.itu.int/rec/T-REC-G.694.1' }, + { name: 'ITU-T G.694.2', body: 'ITU-T', version: '2003', year: 2003, description: 'CWDM wavelength grid' }, + { name: 'ITU-T G.698.2', body: 'ITU-T', version: '2018', year: 2018, description: 'Amplified multichannel DWDM applications' }, + { name: 'ITU-T G.709', body: 'ITU-T', version: '2020', year: 2020, description: 'OTN (Optical Transport Network) interfaces' }, + { name: 'ITU-T G.652', body: 'ITU-T', version: '2016', year: 2016, description: 'Standard single-mode fiber' }, + { name: 'ITU-T G.655', body: 'ITU-T', version: '2009', year: 2009, description: 'Non-zero dispersion-shifted fiber' }, + { name: 'ITU-T G.657', body: 'ITU-T', version: '2016', year: 2016, description: 'Bend-insensitive single-mode fiber' }, + + // OIF + { name: 'OIF-400ZR', body: 'OIF', version: '1.0', year: 2020, description: '400G ZR coherent DWDM pluggable (DP-16QAM)', url: 'https://www.oiforum.com/technical-work/hot-topics/400zr/' }, + { name: 'OIF-800ZR', body: 'OIF', version: '0.6', year: 2024, description: '800G ZR coherent (draft, expected 2025)' }, + { name: 'OIF-CEI-112G', body: 'OIF', version: '1.0', year: 2023, description: '112 Gbps per lane electrical interface' }, + + // OpenZR+ + { name: 'OpenZR+', body: 'OpenZR+ MSA', version: '2.0', year: 2022, description: 'Extended reach coherent (400ZR+ to 1000km+)', url: 'https://openzrplus.org' }, + + // CWDM/SWDM + { name: 'CWDM4 MSA', body: 'CWDM4 MSA', version: '2.0', year: 2015, description: '100G CWDM4 (4x25G, 2km SMF)' }, + { name: 'SWDM Alliance', body: 'SWDM', version: '1.0', year: 2017, description: 'Short Wavelength Division Multiplexing (MMF)' }, +]; diff --git a/seed/transceivers.ts b/seed/transceivers.ts new file mode 100644 index 0000000..fa6b9d5 --- /dev/null +++ b/seed/transceivers.ts @@ -0,0 +1,243 @@ +// Comprehensive Transceiver Seed Data +// Covers all major categories: SFP, SFP+, SFP28, QSFP+, QSFP28, QSFP-DD, OSFP, CWDM, DWDM, DAC, AOC, BiDi, Coherent +// Vendor references use slugs (resolved at seed time) + +interface SeedTransceiver { + part_number: string; + vendor_slug: string; + form_factor: string; + name: string; + category: string; + subcategory: string; + data_rate: number; + data_rate_unit: 'Mbps' | 'Gbps' | 'Tbps'; + max_reach: number; + reach_unit: 'm' | 'km'; + wavelength_nm: number; + wavelength_rx?: number; + connector: string; + fiber_type: string; + duplex: boolean; + temp_range: string; + dom_support: string; + oem_part_number?: string; + oem_vendor_slug?: string; + description?: string; + tags: string[]; + status: string; +} + +export const transceivers: SeedTransceiver[] = [ + // ============================================================ + // 1G SFP — COPPER + // ============================================================ + { part_number: 'GLC-T', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1000BASE-T SFP', category: 'SFP', subcategory: 'T', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 0, connector: 'copper_rj45', fiber_type: 'copper', duplex: true, temp_range: 'commercial', dom_support: 'none', description: '1G copper SFP for Cat5e/6', tags: ['1g', 'copper', 'rj45'], status: 'active' }, + { part_number: 'GLC-TE', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1000BASE-T SFP (extended temp)', category: 'SFP', subcategory: 'T', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 0, connector: 'copper_rj45', fiber_type: 'copper', duplex: true, temp_range: 'extended', dom_support: 'none', tags: ['1g', 'copper', 'rj45', 'extended-temp'], status: 'active' }, + { part_number: 'SFP-GE-T', vendor_slug: 'juniper', form_factor: 'SFP', name: 'Juniper 1000BASE-T SFP', category: 'SFP', subcategory: 'T', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 0, connector: 'copper_rj45', fiber_type: 'copper', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['1g', 'copper'], status: 'active' }, + { part_number: 'J8177C', vendor_slug: 'hpe', form_factor: 'SFP', name: 'HPE 1000BASE-T SFP', category: 'SFP', subcategory: 'T', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 0, connector: 'copper_rj45', fiber_type: 'copper', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['1g', 'copper'], status: 'active' }, + + // ============================================================ + // 1G SFP — FIBER + // ============================================================ + // SX (850nm, MMF) + { part_number: 'GLC-SX-MMD', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1000BASE-SX SFP', category: 'SFP', subcategory: 'SX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 550, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'sx', 'multimode'], status: 'active' }, + { part_number: 'EX-SFP-1GE-SX', vendor_slug: 'juniper', form_factor: 'SFP', name: 'Juniper 1000BASE-SX SFP', category: 'SFP', subcategory: 'SX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 550, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'sx', 'multimode'], status: 'active' }, + { part_number: 'SFP-1G-SX', vendor_slug: 'arista', form_factor: 'SFP', name: 'Arista 1000BASE-SX SFP', category: 'SFP', subcategory: 'SX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 550, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'sx', 'multimode'], status: 'active' }, + + // LX (1310nm, SMF) + { part_number: 'GLC-LH-SMD', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1000BASE-LX/LH SFP', category: 'SFP', subcategory: 'LX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'lx', 'singlemode'], status: 'active' }, + { part_number: 'EX-SFP-1GE-LX', vendor_slug: 'juniper', form_factor: 'SFP', name: 'Juniper 1000BASE-LX SFP', category: 'SFP', subcategory: 'LX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'lx', 'singlemode'], status: 'active' }, + + // ZX (1550nm, SMF, 80km) + { part_number: 'GLC-ZX-SMD', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1000BASE-ZX SFP', category: 'SFP', subcategory: 'ZX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'zx', 'long-reach'], status: 'active' }, + { part_number: 'EX-SFP-1GE-LX40K', vendor_slug: 'juniper', form_factor: 'SFP', name: 'Juniper 1000BASE-LX40K SFP', category: 'SFP', subcategory: 'EX', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'ddm', tags: ['1g', 'extended-reach'], status: 'active' }, + + // ============================================================ + // 10G SFP+ + // ============================================================ + // SR (850nm, MMF) + { part_number: 'SFP-10G-SR', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10GBASE-SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 400, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'sr', 'multimode', 'datacenter'], status: 'active' }, + { part_number: 'EX-SFP-10GE-SR', vendor_slug: 'juniper', form_factor: 'SFP+', name: 'Juniper 10GBASE-SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 400, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'sr', 'multimode'], status: 'active' }, + { part_number: 'SFP-10G-SR', vendor_slug: 'arista', form_factor: 'SFP+', name: 'Arista 10GBASE-SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 400, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'sr', 'multimode'], status: 'active' }, + + // LR (1310nm, SMF, 10km) + { part_number: 'SFP-10G-LR', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10GBASE-LR SFP+', category: 'SFP+', subcategory: 'LR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'lr', 'singlemode'], status: 'active' }, + { part_number: 'EX-SFP-10GE-LR', vendor_slug: 'juniper', form_factor: 'SFP+', name: 'Juniper 10GBASE-LR SFP+', category: 'SFP+', subcategory: 'LR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'lr', 'singlemode'], status: 'active' }, + { part_number: 'SFP-10G-LR', vendor_slug: 'arista', form_factor: 'SFP+', name: 'Arista 10GBASE-LR SFP+', category: 'SFP+', subcategory: 'LR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'lr', 'singlemode'], status: 'active' }, + + // ER (1550nm, SMF, 40km) + { part_number: 'SFP-10G-ER', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10GBASE-ER SFP+', category: 'SFP+', subcategory: 'ER', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'er', 'extended-reach'], status: 'active' }, + + // ZR (1550nm, SMF, 80km) + { part_number: 'SFP-10G-ZR', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10GBASE-ZR SFP+', category: 'SFP+', subcategory: 'ZR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'zr', 'long-reach'], status: 'active' }, + + // 10G Copper + { part_number: 'SFP-10G-T', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10GBASE-T SFP+', category: 'SFP+', subcategory: 'T', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 30, reach_unit: 'm', wavelength_nm: 0, connector: 'copper_rj45', fiber_type: 'copper', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['10g', 'copper', 'rj45'], status: 'active' }, + + // ============================================================ + // 25G SFP28 + // ============================================================ + { part_number: 'SFP-25G-SR-S', vendor_slug: 'cisco', form_factor: 'SFP28', name: 'Cisco 25GBASE-SR SFP28', category: 'SFP28', subcategory: 'SR', data_rate: 25, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['25g', 'sr', 'multimode', 'datacenter'], status: 'active' }, + { part_number: 'SFP-25G-LR-S', vendor_slug: 'cisco', form_factor: 'SFP28', name: 'Cisco 25GBASE-LR SFP28', category: 'SFP28', subcategory: 'LR', data_rate: 25, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['25g', 'lr', 'singlemode'], status: 'active' }, + { part_number: 'SFP-25G-SR', vendor_slug: 'arista', form_factor: 'SFP28', name: 'Arista 25GBASE-SR SFP28', category: 'SFP28', subcategory: 'SR', data_rate: 25, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['25g', 'sr'], status: 'active' }, + + // ============================================================ + // 40G QSFP+ + // ============================================================ + { part_number: 'QSFP-40G-SR4', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40GBASE-SR4 QSFP+', category: 'QSFP+', subcategory: 'SR4', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 150, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'sff8636', description: '4x10G SR, MPO-12 connector', tags: ['40g', 'sr4', 'parallel-optics', 'mpo'], status: 'active' }, + { part_number: 'QSFP-40G-LR4', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40GBASE-LR4 QSFP+', category: 'QSFP+', subcategory: 'LR4', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8636', description: '4x10G LAN-WDM over SMF', tags: ['40g', 'lr4', 'wdm', 'singlemode'], status: 'active' }, + { part_number: 'QSFP-40G-SR-BD', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40GBASE-SR-BD QSFP+ (BiDi)', category: 'QSFP+', subcategory: 'BiDi', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 150, reach_unit: 'm', wavelength_nm: 850, wavelength_rx: 900, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8636', description: '40G BiDi over LC duplex MMF', tags: ['40g', 'bidi', 'multimode', 'lc'], status: 'active' }, + { part_number: 'JNP-QSFP-40G-LX4', vendor_slug: 'juniper', form_factor: 'QSFP+', name: 'Juniper 40GBASE-LX4 QSFP+', category: 'QSFP+', subcategory: 'LX4', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8636', tags: ['40g', 'lx4', 'wdm'], status: 'active' }, + + // ============================================================ + // 100G QSFP28 + // ============================================================ + // SR4 + { part_number: 'QSFP-100G-SR4-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100GBASE-SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '4x25G SR over MPO-12 (OM4)', tags: ['100g', 'sr4', 'parallel-optics', 'datacenter'], status: 'active' }, + { part_number: 'JNP-QSFP-100G-SR4', vendor_slug: 'juniper', form_factor: 'QSFP28', name: 'Juniper 100GBASE-SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'sr4'], status: 'active' }, + { part_number: 'QSFP-100G-SR4', vendor_slug: 'arista', form_factor: 'QSFP28', name: 'Arista 100GBASE-SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'sr4'], status: 'active' }, + + // LR4 + { part_number: 'QSFP-100G-LR4-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100GBASE-LR4 QSFP28', category: 'QSFP28', subcategory: 'LR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '4x25G LAN-WDM over SMF', tags: ['100g', 'lr4', 'wdm', 'singlemode'], status: 'active' }, + { part_number: 'JNP-QSFP-100G-LR4', vendor_slug: 'juniper', form_factor: 'QSFP28', name: 'Juniper 100GBASE-LR4 QSFP28', category: 'QSFP28', subcategory: 'LR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'lr4'], status: 'active' }, + + // CWDM4 + { part_number: 'QSFP-100G-CWDM4-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100G CWDM4 QSFP28', category: 'QSFP28', subcategory: 'CWDM4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '100G CWDM4 (4x25G, 2km)', tags: ['100g', 'cwdm4', 'wdm'], status: 'active' }, + + // PSM4 + { part_number: 'QSFP-100G-PSM4-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100G PSM4 QSFP28', category: 'QSFP28', subcategory: 'PSM4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '100G PSM4 parallel SMF', tags: ['100g', 'psm4', 'parallel-optics'], status: 'active' }, + + // DR (single lambda 100G) + { part_number: 'QSFP-100G-DR-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100GBASE-DR QSFP28', category: 'QSFP28', subcategory: 'DR', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: 'Single lambda 100G (IEEE 802.3cu)', tags: ['100g', 'dr', 'single-lambda'], status: 'active' }, + + // FR (single lambda 100G, 2km) + { part_number: 'QSFP-100G-FR-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100GBASE-FR QSFP28', category: 'QSFP28', subcategory: 'FR', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'fr', 'single-lambda'], status: 'active' }, + + // ZR (coherent, 80km) + { part_number: 'QDD-100G-ZR-S', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100GBASE-ZR QSFP28', category: 'QSFP28', subcategory: 'ZR', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '100G coherent ZR (IEEE 802.3ct)', tags: ['100g', 'zr', 'coherent', 'dwdm'], status: 'active' }, + + // ============================================================ + // 200G QSFP56 + // ============================================================ + { part_number: 'QDD-200G-FR4-S', vendor_slug: 'cisco', form_factor: 'QSFP56', name: 'Cisco 200G FR4 QSFP56', category: 'QSFP56', subcategory: 'FR4', data_rate: 200, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['200g', 'fr4', 'wdm'], status: 'active' }, + { part_number: 'QDD-200G-SR4', vendor_slug: 'cisco', form_factor: 'QSFP56', name: 'Cisco 200G SR4 QSFP56', category: 'QSFP56', subcategory: 'SR4', data_rate: 200, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['200g', 'sr4', 'parallel-optics'], status: 'active' }, + + // ============================================================ + // 400G QSFP-DD + // ============================================================ + // DR4 + { part_number: 'QDD-400G-DR4-S', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400GBASE-DR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'DR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '4x100G DR over parallel SMF', tags: ['400g', 'dr4', 'parallel-optics', 'datacenter'], status: 'active' }, + { part_number: 'JNP-QSFP-DD-400G-DR4', vendor_slug: 'juniper', form_factor: 'QSFP-DD', name: 'Juniper 400GBASE-DR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'DR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'dr4'], status: 'active' }, + { part_number: 'QDD-400G-DR4', vendor_slug: 'arista', form_factor: 'QSFP-DD', name: 'Arista 400GBASE-DR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'DR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'dr4'], status: 'active' }, + + // FR4 + { part_number: 'QDD-400G-FR4-S', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400GBASE-FR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'FR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '4x100G FR, 2km SMF', tags: ['400g', 'fr4', 'wdm'], status: 'active' }, + + // LR4 + { part_number: 'QDD-400G-LR4-S', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400GBASE-LR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'LR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'lr4', 'wdm'], status: 'active' }, + + // SR4.2 + { part_number: 'QDD-400G-SR4.2', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400GBASE-SR4.2 QSFP-DD', category: 'QSFP-DD', subcategory: 'SR4.2', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '400G over multimode (IEEE 802.3cm)', tags: ['400g', 'sr4.2', 'multimode'], status: 'active' }, + + // ZR (coherent, OIF 400ZR) + { part_number: 'QDD-400G-ZR-S', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400G ZR QSFP-DD', category: 'QSFP-DD', subcategory: 'ZR', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '400G coherent ZR (OIF 400ZR, DP-16QAM)', tags: ['400g', 'zr', 'coherent', 'dwdm', 'dci'], status: 'active' }, + + // ZR+ (OpenZR+) + { part_number: 'QDD-400G-ZRP-S', vendor_slug: 'cisco', form_factor: 'QSFP-DD', name: 'Cisco 400G ZR+ QSFP-DD', category: 'QSFP-DD', subcategory: 'ZR+', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 1000, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '400G OpenZR+ coherent (1000km+)', tags: ['400g', 'zr+', 'coherent', 'dwdm', 'long-haul'], status: 'active' }, + + // ============================================================ + // 400G OSFP + // ============================================================ + { part_number: 'OSFP-400G-DR4', vendor_slug: 'arista', form_factor: 'OSFP', name: 'Arista 400G DR4 OSFP', category: 'OSFP', subcategory: 'DR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'dr4', 'osfp'], status: 'active' }, + { part_number: 'OSFP-400G-FR4', vendor_slug: 'arista', form_factor: 'OSFP', name: 'Arista 400G FR4 OSFP', category: 'OSFP', subcategory: 'FR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'fr4', 'osfp'], status: 'active' }, + + // ============================================================ + // 800G QSFP-DD800 / OSFP + // ============================================================ + { part_number: 'QDD-800G-DR8', vendor_slug: 'cisco', form_factor: 'QSFP-DD800', name: 'Cisco 800G DR8 QSFP-DD800', category: 'QSFP-DD800', subcategory: 'DR8', data_rate: 800, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-16', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '8x100G DR parallel SMF', tags: ['800g', 'dr8', 'ai', 'next-gen'], status: 'active' }, + { part_number: 'QDD-800G-DR4', vendor_slug: 'cisco', form_factor: 'QSFP-DD800', name: 'Cisco 800G DR4 QSFP-DD800', category: 'QSFP-DD800', subcategory: 'DR4', data_rate: 800, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '4x200G DR (200G per lane)', tags: ['800g', 'dr4', 'ai'], status: 'pre_release' }, + { part_number: 'OSFP-800G-DR8', vendor_slug: 'arista', form_factor: 'OSFP', name: 'Arista 800G DR8 OSFP', category: 'OSFP', subcategory: 'DR8', data_rate: 800, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-16', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['800g', 'dr8', 'osfp', 'ai'], status: 'active' }, + { part_number: 'QDD-800G-ZR', vendor_slug: 'cisco', form_factor: 'QSFP-DD800', name: 'Cisco 800G ZR QSFP-DD800', category: 'QSFP-DD800', subcategory: 'ZR', data_rate: 800, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', description: '800G coherent ZR (OIF 800ZR)', tags: ['800g', 'zr', 'coherent', 'dci'], status: 'pre_release' }, + + // ============================================================ + // 1.6T OSFP-XD + // ============================================================ + { part_number: 'OSFP-XD-1.6T-DR8', vendor_slug: 'cisco', form_factor: 'OSFP-XD', name: 'Cisco 1.6T DR8 OSFP-XD', category: 'OSFP-XD', subcategory: 'DR8', data_rate: 1.6, data_rate_unit: 'Tbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-16', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', description: '8x200G DR (IEEE 802.3df)', tags: ['1.6t', 'dr8', 'ai', 'next-gen'], status: 'pre_release' }, + { part_number: 'OSFP-XD-1.6T-FR8', vendor_slug: 'arista', form_factor: 'OSFP-XD', name: 'Arista 1.6T FR8 OSFP-XD', category: 'OSFP-XD', subcategory: 'FR8', data_rate: 1.6, data_rate_unit: 'Tbps', max_reach: 2, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['1.6t', 'fr8', 'ai'], status: 'pre_release' }, + + // ============================================================ + // CWDM SFP/SFP+ (1270-1610nm) + // ============================================================ + { part_number: 'CWDM-SFP10G-1270', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1270nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1270, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1270nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1290', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1290nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1290, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1290nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1310', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1310nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1310nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1330', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1330nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 40, reach_unit: 'km', wavelength_nm: 1330, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1330nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1470', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1470nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1470, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1470nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1490', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1490nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1490, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1490nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1510', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1510nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1510, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1510nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1550', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1550nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1550, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1550nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1570', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1570nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1570, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1570nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1590', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1590nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1590, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1590nm'], status: 'active' }, + { part_number: 'CWDM-SFP10G-1610', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G CWDM SFP+ 1610nm', category: 'SFP+', subcategory: 'CWDM', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 80, reach_unit: 'km', wavelength_nm: 1610, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'cwdm', '1610nm'], status: 'active' }, + + // ============================================================ + // BiDi SFP / SFP+ + // ============================================================ + { part_number: 'GLC-BX-D', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1G BiDi SFP (downstream)', category: 'SFP', subcategory: 'BiDi', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1490, wavelength_rx: 1310, connector: 'LC', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'ddm', description: 'TX:1490nm / RX:1310nm, single fiber', tags: ['1g', 'bidi', 'single-fiber'], status: 'active' }, + { part_number: 'GLC-BX-U', vendor_slug: 'cisco', form_factor: 'SFP', name: 'Cisco 1G BiDi SFP (upstream)', category: 'SFP', subcategory: 'BiDi', data_rate: 1, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, wavelength_rx: 1490, connector: 'LC', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'ddm', description: 'TX:1310nm / RX:1490nm, single fiber', tags: ['1g', 'bidi', 'single-fiber'], status: 'active' }, + { part_number: 'SFP-10G-BXD-I', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G BiDi SFP+ (downstream)', category: 'SFP+', subcategory: 'BiDi', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1330, wavelength_rx: 1270, connector: 'LC', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'bidi', 'single-fiber'], status: 'active' }, + { part_number: 'SFP-10G-BXU-I', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 10G BiDi SFP+ (upstream)', category: 'SFP+', subcategory: 'BiDi', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1270, wavelength_rx: 1330, connector: 'LC', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'bidi', 'single-fiber'], status: 'active' }, + + // ============================================================ + // COMPATIBLE VENDOR TRANSCEIVERS (Flexoptix, 10Gtek, FS.com) + // ============================================================ + // Flexoptix + { part_number: 'FL-SFP+SR', vendor_slug: 'flexoptix', form_factor: 'SFP+', name: 'Flexoptix 10G SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 400, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', oem_part_number: 'SFP-10G-SR', oem_vendor_slug: 'cisco', description: 'Flexoptix compatible, FlexBox codable', tags: ['10g', 'sr', 'compatible', 'flexbox'], status: 'active' }, + { part_number: 'FL-SFP+LR', vendor_slug: 'flexoptix', form_factor: 'SFP+', name: 'Flexoptix 10G LR SFP+', category: 'SFP+', subcategory: 'LR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', oem_part_number: 'SFP-10G-LR', oem_vendor_slug: 'cisco', tags: ['10g', 'lr', 'compatible', 'flexbox'], status: 'active' }, + { part_number: 'FL-QSFP28-SR4', vendor_slug: 'flexoptix', form_factor: 'QSFP28', name: 'Flexoptix 100G SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', oem_part_number: 'QSFP-100G-SR4-S', oem_vendor_slug: 'cisco', tags: ['100g', 'sr4', 'compatible', 'flexbox'], status: 'active' }, + + // FS.com + { part_number: 'SFP-10GSR-85', vendor_slug: 'fs-com', form_factor: 'SFP+', name: 'FS.com 10G SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 300, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'sr', 'compatible', 'budget'], status: 'active' }, + { part_number: 'SFP-10GLR-31', vendor_slug: 'fs-com', form_factor: 'SFP+', name: 'FS.com 10G LR SFP+', category: 'SFP+', subcategory: 'LR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'km', wavelength_nm: 1310, connector: 'LC', fiber_type: 'smf', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'lr', 'compatible', 'budget'], status: 'active' }, + { part_number: 'QSFP28-SR4-100G', vendor_slug: 'fs-com', form_factor: 'QSFP28', name: 'FS.com 100G SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'sr4', 'compatible', 'budget'], status: 'active' }, + { part_number: 'QSFP-DD-400G-DR4', vendor_slug: 'fs-com', form_factor: 'QSFP-DD', name: 'FS.com 400G DR4 QSFP-DD', category: 'QSFP-DD', subcategory: 'DR4', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 500, reach_unit: 'm', wavelength_nm: 1310, connector: 'MPO-12', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['400g', 'dr4', 'compatible', 'budget'], status: 'active' }, + + // 10Gtek + { part_number: 'SFP-10G-SR-TK', vendor_slug: '10gtek', form_factor: 'SFP+', name: '10Gtek 10G SR SFP+', category: 'SFP+', subcategory: 'SR', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 300, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['10g', 'sr', 'compatible', 'budget'], status: 'active' }, + { part_number: 'QSFP28-100G-SR4-TK', vendor_slug: '10gtek', form_factor: 'QSFP28', name: '10Gtek 100G SR4 QSFP28', category: 'QSFP28', subcategory: 'SR4', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'MPO-12', fiber_type: 'mmf_om4', duplex: false, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'sr4', 'compatible', 'budget'], status: 'active' }, + + // ============================================================ + // DAC (Direct Attach Copper) + // ============================================================ + { part_number: 'SFP-H10GB-CU1M', vendor_slug: 'cisco', form_factor: 'SFP+-DAC', name: 'Cisco 10G SFP+ DAC 1m', category: 'SFP+-DAC', subcategory: 'DAC', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['10g', 'dac', 'passive', '1m'], status: 'active' }, + { part_number: 'SFP-H10GB-CU3M', vendor_slug: 'cisco', form_factor: 'SFP+-DAC', name: 'Cisco 10G SFP+ DAC 3m', category: 'SFP+-DAC', subcategory: 'DAC', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 3, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['10g', 'dac', 'passive', '3m'], status: 'active' }, + { part_number: 'SFP-H10GB-CU5M', vendor_slug: 'cisco', form_factor: 'SFP+-DAC', name: 'Cisco 10G SFP+ DAC 5m', category: 'SFP+-DAC', subcategory: 'DAC', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 5, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['10g', 'dac', 'passive', '5m'], status: 'active' }, + { part_number: 'QSFP-H40G-CU1M', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40G QSFP+ DAC 1m', category: 'QSFP+', subcategory: 'DAC', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['40g', 'dac', 'passive'], status: 'active' }, + { part_number: 'QSFP-100G-CU1M', vendor_slug: 'cisco', form_factor: 'QSFP28-DAC', name: 'Cisco 100G QSFP28 DAC 1m', category: 'QSFP28-DAC', subcategory: 'DAC', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['100g', 'dac', 'passive'], status: 'active' }, + { part_number: 'QSFP-100G-CU3M', vendor_slug: 'cisco', form_factor: 'QSFP28-DAC', name: 'Cisco 100G QSFP28 DAC 3m', category: 'QSFP28-DAC', subcategory: 'DAC', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 3, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['100g', 'dac', 'passive'], status: 'active' }, + { part_number: 'QDD-400-CU1M', vendor_slug: 'cisco', form_factor: 'QSFP-DD-DAC', name: 'Cisco 400G QSFP-DD DAC 1m', category: 'QSFP-DD-DAC', subcategory: 'DAC', data_rate: 400, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', tags: ['400g', 'dac', 'passive'], status: 'active' }, + + // Breakout DACs + { part_number: 'QSFP-4SFP10G-CU1M', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40G→4x10G Breakout DAC 1m', category: 'QSFP+', subcategory: 'Breakout-DAC', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', description: 'QSFP+ to 4x SFP+ breakout', tags: ['40g', 'breakout', '4x10g', 'dac'], status: 'active' }, + { part_number: 'QSFP-4SFP25G-CU1M', vendor_slug: 'cisco', form_factor: 'QSFP28', name: 'Cisco 100G→4x25G Breakout DAC 1m', category: 'QSFP28', subcategory: 'Breakout-DAC', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 1, reach_unit: 'm', wavelength_nm: 0, connector: 'dac_passive', fiber_type: 'dac', duplex: true, temp_range: 'commercial', dom_support: 'none', description: 'QSFP28 to 4x SFP28 breakout', tags: ['100g', 'breakout', '4x25g', 'dac'], status: 'active' }, + + // ============================================================ + // AOC (Active Optical Cable) + // ============================================================ + { part_number: 'QSFP-H40G-AOC10M', vendor_slug: 'cisco', form_factor: 'QSFP+', name: 'Cisco 40G QSFP+ AOC 10m', category: 'QSFP+', subcategory: 'AOC', data_rate: 40, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'm', wavelength_nm: 850, connector: 'aoc', fiber_type: 'aoc', duplex: true, temp_range: 'commercial', dom_support: 'sff8636', tags: ['40g', 'aoc', '10m'], status: 'active' }, + { part_number: 'QSFP-100G-AOC10M', vendor_slug: 'cisco', form_factor: 'QSFP28-AOC', name: 'Cisco 100G QSFP28 AOC 10m', category: 'QSFP28-AOC', subcategory: 'AOC', data_rate: 100, data_rate_unit: 'Gbps', max_reach: 10, reach_unit: 'm', wavelength_nm: 850, connector: 'aoc', fiber_type: 'aoc', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['100g', 'aoc', '10m'], status: 'active' }, + + // ============================================================ + // FIBRE CHANNEL + // ============================================================ + { part_number: 'DS-SFP-FC8G-SW', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 8G FC SFP+ Shortwave', category: 'SFP+', subcategory: 'FC-SW', data_rate: 8, data_rate_unit: 'Gbps', max_reach: 190, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['8g-fc', 'fibre-channel', 'san'], status: 'active' }, + { part_number: 'DS-SFP-FC16G-SW', vendor_slug: 'cisco', form_factor: 'SFP+', name: 'Cisco 16G FC SFP+ Shortwave', category: 'SFP+', subcategory: 'FC-SW', data_rate: 16, data_rate_unit: 'Gbps', max_reach: 125, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om3', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['16g-fc', 'fibre-channel', 'san'], status: 'active' }, + { part_number: 'DS-SFP-FC32G-SW', vendor_slug: 'cisco', form_factor: 'SFP28', name: 'Cisco 32G FC SFP28 Shortwave', category: 'SFP28', subcategory: 'FC-SW', data_rate: 32, data_rate_unit: 'Gbps', max_reach: 100, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'sff8472', tags: ['32g-fc', 'fibre-channel', 'san'], status: 'active' }, + { part_number: 'DS-SFP-FC64G-SW', vendor_slug: 'cisco', form_factor: 'SFP56', name: 'Cisco 64G FC SFP56 Shortwave', category: 'SFP56', subcategory: 'FC-SW', data_rate: 64, data_rate_unit: 'Gbps', max_reach: 50, reach_unit: 'm', wavelength_nm: 850, connector: 'LC', fiber_type: 'mmf_om4', duplex: true, temp_range: 'commercial', dom_support: 'cmis', tags: ['64g-fc', 'fibre-channel', 'san'], status: 'active' }, + + // ============================================================ + // PON / ACCESS + // ============================================================ + { part_number: 'SFP-GE-LX-SM1310', vendor_slug: 'huawei', form_factor: 'SFP', name: 'Huawei GPON OLT SFP', category: 'SFP', subcategory: 'GPON', data_rate: 2.5, data_rate_unit: 'Gbps', max_reach: 20, reach_unit: 'km', wavelength_nm: 1490, wavelength_rx: 1310, connector: 'SC', fiber_type: 'smf', duplex: false, temp_range: 'commercial', dom_support: 'ddm', tags: ['gpon', 'olt', 'pon', 'ftth'], status: 'active' }, + { part_number: 'XGS-PON-OLT-C+', vendor_slug: 'huawei', form_factor: 'SFP+', name: 'Huawei XGS-PON OLT SFP+ Class C+', category: 'SFP+', subcategory: 'XGS-PON', data_rate: 10, data_rate_unit: 'Gbps', max_reach: 20, reach_unit: 'km', wavelength_nm: 1577, wavelength_rx: 1270, connector: 'SC', fiber_type: 'smf', duplex: false, temp_range: 'industrial', dom_support: 'ddm', tags: ['xgs-pon', 'olt', 'pon', 'ftth', '10g'], status: 'active' }, +]; diff --git a/seed/vendors.ts b/seed/vendors.ts new file mode 100644 index 0000000..b5e32b8 --- /dev/null +++ b/seed/vendors.ts @@ -0,0 +1,96 @@ +import type { Vendor } from '../src/types/index.js'; + +export const vendors: Vendor[] = [ + // ============================================================ + // OEM VENDORS (Original Equipment Manufacturers) + // ============================================================ + { name: 'Cisco', slug: 'cisco', vendor_type: 'oem', website: 'https://www.cisco.com', country: 'USA', founded_year: 1984, is_oem: true, description: 'Largest networking equipment vendor globally', scrape_url: 'https://tmgmatrix.cisco.com' }, + { name: 'Juniper Networks', slug: 'juniper', vendor_type: 'oem', website: 'https://www.juniper.net', country: 'USA', founded_year: 1996, is_oem: true, description: 'Enterprise and service provider networking', scrape_url: 'https://apps.juniper.net/hct/' }, + { name: 'Arista Networks', slug: 'arista', vendor_type: 'oem', website: 'https://www.arista.com', country: 'USA', founded_year: 2004, is_oem: true, description: 'Cloud networking and data center switches', aliases: ['Arista'] }, + { name: 'Hewlett Packard Enterprise', slug: 'hpe', vendor_type: 'oem', website: 'https://www.hpe.com', country: 'USA', founded_year: 2015, is_oem: true, description: 'Aruba networking, ProCurve switches', aliases: ['HPE', 'HP', 'HP Networking', 'Aruba', 'ProCurve'] }, + { name: 'Dell Technologies', slug: 'dell', vendor_type: 'oem', website: 'https://www.dell.com', country: 'USA', founded_year: 1984, is_oem: true, description: 'PowerSwitch/Force10 networking', aliases: ['Dell', 'Force10', 'Dell EMC'] }, + { name: 'Huawei', slug: 'huawei', vendor_type: 'oem', website: 'https://www.huawei.com', country: 'CHN', founded_year: 1987, is_oem: true, description: 'Largest telecom equipment vendor globally' }, + { name: 'Nokia', slug: 'nokia', vendor_type: 'oem', website: 'https://www.nokia.com', country: 'FIN', founded_year: 1865, is_oem: true, description: 'Telecom infrastructure, IP/MPLS routers', aliases: ['Nokia Networks', 'Alcatel-Lucent', 'ALU'] }, + { name: 'Ciena', slug: 'ciena', vendor_type: 'oem', website: 'https://www.ciena.com', country: 'USA', founded_year: 1992, is_oem: true, description: 'Optical networking and WaveServer coherent' }, + { name: 'ADTRAN', slug: 'adtran', vendor_type: 'oem', website: 'https://www.adtran.com', country: 'USA', founded_year: 1985, is_oem: true, description: 'Access networking equipment', aliases: ['ADVA', 'ADVA Optical'] }, + { name: 'Extreme Networks', slug: 'extreme', vendor_type: 'oem', website: 'https://www.extremenetworks.com', country: 'USA', founded_year: 1996, is_oem: true, description: 'Campus and data center networking', aliases: ['Extreme', 'Brocade', 'Enterasys'] }, + { name: 'MikroTik', slug: 'mikrotik', vendor_type: 'oem', website: 'https://mikrotik.com', country: 'LVA', founded_year: 1996, is_oem: true, description: 'Affordable routers and switches' }, + { name: 'Ubiquiti', slug: 'ubiquiti', vendor_type: 'oem', website: 'https://www.ui.com', country: 'USA', founded_year: 2005, is_oem: true, description: 'UniFi networking equipment', aliases: ['UBNT', 'UniFi'] }, + { name: 'FS.com', slug: 'fs-com', vendor_type: 'oem', website: 'https://www.fs.com', country: 'CHN', founded_year: 2009, is_oem: true, description: 'Direct-to-customer networking equipment and optics', scrape_url: 'https://www.fs.com/c/transceivers-702', scrape_enabled: true }, + { name: 'Mellanox', slug: 'mellanox', vendor_type: 'oem', website: 'https://www.nvidia.com/networking', country: 'USA', founded_year: 1999, is_oem: true, description: 'InfiniBand and Ethernet NICs (now NVIDIA)', aliases: ['NVIDIA Networking', 'NVIDIA Mellanox'] }, + { name: 'Broadcom', slug: 'broadcom', vendor_type: 'oem', website: 'https://www.broadcom.com', country: 'USA', founded_year: 1961, is_oem: true, description: 'Switch ASICs (Memory), NICs, optics', aliases: ['Avago', 'Brocade FC'] }, + { name: 'Intel', slug: 'intel', vendor_type: 'oem', website: 'https://www.intel.com', country: 'USA', founded_year: 1968, is_oem: true, description: 'Silicon Photonics, Ethernet NICs' }, + { name: 'Palo Alto Networks', slug: 'paloalto', vendor_type: 'oem', website: 'https://www.paloaltonetworks.com', country: 'USA', founded_year: 2005, is_oem: true, description: 'Next-gen firewalls requiring SFP+/QSFP28' }, + { name: 'Fortinet', slug: 'fortinet', vendor_type: 'oem', website: 'https://www.fortinet.com', country: 'USA', founded_year: 2000, is_oem: true, description: 'FortiGate firewalls with SFP/SFP+ ports' }, + { name: 'Check Point', slug: 'checkpoint', vendor_type: 'oem', website: 'https://www.checkpoint.com', country: 'ISR', founded_year: 1993, is_oem: true, description: 'Security gateways with optical ports' }, + { name: 'Calix', slug: 'calix', vendor_type: 'oem', website: 'https://www.calix.com', country: 'USA', founded_year: 1999, is_oem: true, description: 'Broadband access (GPON/XGS-PON OLT)' }, + { name: 'Edgecore Networks', slug: 'edgecore', vendor_type: 'oem', website: 'https://www.edge-core.com', country: 'TWN', founded_year: 2014, is_oem: true, description: 'Open networking (white-box) switches', aliases: ['Accton'] }, + { name: 'Celestica', slug: 'celestica', vendor_type: 'oem', website: 'https://www.celestica.com', country: 'CAN', founded_year: 1994, is_oem: true, description: 'White-box switches (DS3000/DS4000)' }, + { name: 'Supermicro', slug: 'supermicro', vendor_type: 'oem', website: 'https://www.supermicro.com', country: 'USA', founded_year: 1993, is_oem: true, description: 'Server and networking hardware' }, + { name: 'ZTE', slug: 'zte', vendor_type: 'oem', website: 'https://www.zte.com.cn', country: 'CHN', founded_year: 1985, is_oem: true, description: 'Telecom equipment, OLT/ONU' }, + { name: 'FiberHome', slug: 'fiberhome', vendor_type: 'oem', website: 'https://www.fiberhome.com', country: 'CHN', founded_year: 1999, is_oem: true, description: 'Chinese optical networking equipment' }, + { name: 'Allied Telesis', slug: 'allied-telesis', vendor_type: 'oem', website: 'https://www.alliedtelesis.com', country: 'JPN', founded_year: 1987, is_oem: true, description: 'Enterprise networking equipment' }, + { name: 'Netgear', slug: 'netgear', vendor_type: 'oem', website: 'https://www.netgear.com', country: 'USA', founded_year: 1996, is_oem: true, description: 'SMB networking equipment' }, + { name: 'D-Link', slug: 'dlink', vendor_type: 'oem', website: 'https://www.dlink.com', country: 'TWN', founded_year: 1986, is_oem: true, description: 'Consumer and SMB networking' }, + { name: 'TP-Link', slug: 'tplink', vendor_type: 'oem', website: 'https://www.tp-link.com', country: 'CHN', founded_year: 1996, is_oem: true, description: 'Consumer and SMB networking' }, + + // ============================================================ + // TRANSCEIVER MANUFACTURERS (Factories) + // ============================================================ + { name: 'II-VI / Coherent', slug: 'coherent', vendor_type: 'manufacturer', website: 'https://www.coherent.com', country: 'USA', founded_year: 1971, is_factory: true, description: 'Coherent optics, VCSELs, WDM filters', aliases: ['II-VI', 'Finisar', 'II-VI Finisar'] }, + { name: 'Lumentum', slug: 'lumentum', vendor_type: 'manufacturer', website: 'https://www.lumentum.com', country: 'USA', founded_year: 2015, is_factory: true, description: 'Lasers, ROADMs, coherent receivers', aliases: ['JDSU', 'JDS Uniphase'] }, + { name: 'InnoLight Technology', slug: 'innolight', vendor_type: 'manufacturer', website: 'https://www.innolight.com', country: 'CHN', founded_year: 2008, is_factory: true, description: 'Top 3 global transceiver manufacturer, AI/hyperscaler focus' }, + { name: 'Hisense Broadband', slug: 'hisense-broadband', vendor_type: 'manufacturer', website: 'https://www.hisense-broadband.com', country: 'CHN', founded_year: 2003, is_factory: true, description: 'High-volume transceiver factory', aliases: ['Hisense'] }, + { name: 'Source Photonics', slug: 'source-photonics', vendor_type: 'manufacturer', website: 'https://www.sourcephotonics.com', country: 'USA', founded_year: 2000, is_factory: true, description: 'Access and data center transceivers' }, + { name: 'Eoptolink Technology', slug: 'eoptolink', vendor_type: 'manufacturer', website: 'https://en.eoptolink.com', country: 'CHN', founded_year: 2002, is_factory: true, description: 'SFP/QSFP manufacturer in Chengdu' }, + { name: 'Zhongji Innolight', slug: 'zhongji', vendor_type: 'manufacturer', website: 'https://www.innolight.com', country: 'CHN', founded_year: 2008, is_factory: true, description: 'InnoLight parent entity' }, + { name: 'Accelink Technologies', slug: 'accelink', vendor_type: 'manufacturer', website: 'https://www.accelink.com', country: 'CHN', founded_year: 2001, is_factory: true, description: 'Optical components and modules (Wuhan)' }, + { name: 'Centera Photonics', slug: 'centera', vendor_type: 'manufacturer', website: 'https://www.centeraphotonics.com', country: 'TWN', founded_year: 2016, is_factory: true, description: 'Silicon Photonics transceivers' }, + { name: 'Marvell', slug: 'marvell', vendor_type: 'manufacturer', website: 'https://www.marvell.com', country: 'USA', founded_year: 1995, is_factory: true, description: 'DSP/retimer chips for coherent optics', aliases: ['Inphi'] }, + { name: 'Luxtera', slug: 'luxtera', vendor_type: 'manufacturer', website: 'https://www.cisco.com', country: 'USA', founded_year: 2001, is_factory: true, description: 'Silicon Photonics pioneer (acquired by Cisco 2019)' }, + { name: 'Sicoya', slug: 'sicoya', vendor_type: 'manufacturer', website: 'https://www.sicoya.com', country: 'DEU', founded_year: 2015, is_factory: true, description: 'German Silicon Photonics startup (Juniper acquired)' }, + { name: 'O-Net Technologies', slug: 'onet', vendor_type: 'manufacturer', website: 'https://www.o-netcom.com', country: 'CHN', founded_year: 2000, is_factory: true, description: 'Optical subsystems and modules' }, + { name: 'Cloud Light Technology', slug: 'cloud-light', vendor_type: 'manufacturer', website: 'https://www.cloud-light.com', country: 'CHN', founded_year: 2014, is_factory: true, description: 'High-speed optical transceivers' }, + { name: 'Broadex Technologies', slug: 'broadex', vendor_type: 'manufacturer', website: 'https://www.broadex-tech.com', country: 'CHN', founded_year: 2014, is_factory: true, description: 'Silicon Photonics transceivers' }, + + // ============================================================ + // COMPATIBLE TRANSCEIVER VENDORS + // ============================================================ + { name: 'Flexoptix', slug: 'flexoptix', vendor_type: 'compatible', website: 'https://www.flexoptix.net', country: 'DEU', founded_year: 2009, description: 'German compatible transceiver vendor with FlexBox coding', aliases: ['FLEXOPTIX GmbH'], scrape_url: 'https://www.flexoptix.net/en/', scrape_enabled: true }, + { name: 'Axiom Memory Solutions', slug: 'axiom', vendor_type: 'compatible', website: 'https://www.axiommemory.com', country: 'USA', founded_year: 1990, description: 'Compatible transceivers with OEM cross-reference', scrape_url: 'https://www.axiommemory.com/category/transceivers', scrape_enabled: true }, + { name: 'ProLabs', slug: 'prolabs', vendor_type: 'compatible', website: 'https://www.prolabs.com', country: 'GBR', founded_year: 2005, description: 'UK compatible transceiver vendor with compatibility finder', scrape_url: 'https://www.prolabs.com/compatibility/', scrape_enabled: true }, + { name: 'AddOn Networks', slug: 'addon', vendor_type: 'compatible', website: 'https://www.addonnetworks.com', country: 'USA', founded_year: 2008, description: 'Compatible transceivers and cables' }, + { name: 'FluxLight', slug: 'fluxlight', vendor_type: 'compatible', website: 'https://www.fluxlight.com', country: 'USA', founded_year: 2014, description: 'Compatible transceivers with OEM mapping', scrape_url: 'https://www.fluxlight.com/transceivers/', scrape_enabled: true }, + { name: 'Approved Networks', slug: 'approved-networks', vendor_type: 'compatible', website: 'https://www.approvednetworks.com', country: 'USA', founded_year: 2008, description: 'Compatible optics with JSON-LD structured data' }, + { name: '10Gtek', slug: '10gtek', vendor_type: 'compatible', website: 'https://www.10gtek.com', country: 'CHN', founded_year: 2010, description: 'Chinese compatible transceiver vendor', scrape_url: 'https://www.10gtek.com', scrape_enabled: true }, + { name: 'Champion ONE', slug: 'champion-one', vendor_type: 'compatible', website: 'https://www.championone.com', country: 'USA', founded_year: 2006, description: 'Compatible transceivers and active optical cables' }, + { name: 'Proline (Legrand)', slug: 'proline', vendor_type: 'compatible', website: 'https://www.legrand.us', country: 'USA', description: 'Legrand/C2G compatible transceivers', aliases: ['C2G', 'Legrand'] }, + { name: 'Atgbics', slug: 'atgbics', vendor_type: 'compatible', website: 'https://www.atgbics.com', country: 'GBR', founded_year: 2009, description: 'UK compatible optics vendor' }, + { name: 'Fiberstore', slug: 'fiberstore', vendor_type: 'compatible', website: 'https://www.fs.com', country: 'CHN', description: 'FS.com compatible transceiver line' }, + { name: 'Starview', slug: 'starview', vendor_type: 'compatible', website: 'https://www.starview.com', country: 'USA', description: 'Compatible transceivers for enterprise' }, + { name: 'Optec', slug: 'optec', vendor_type: 'compatible', website: 'https://www.optec.de', country: 'DEU', description: 'German compatible optics vendor' }, + { name: 'Curvature', slug: 'curvature', vendor_type: 'compatible', website: 'https://www.curvature.com', country: 'USA', description: 'Third-party maintenance and compatible optics', aliases: ['Network Hardware Resale'] }, + { name: 'Transition Networks', slug: 'transition-networks', vendor_type: 'compatible', website: 'https://www.transition.com', country: 'USA', founded_year: 1987, description: 'Media converters and compatible transceivers' }, + { name: 'Opticin', slug: 'opticin', vendor_type: 'compatible', website: 'https://opticin.com', country: 'RUS', description: 'Russian compatible transceiver vendor' }, + { name: 'Fibertrade', slug: 'fibertrade', vendor_type: 'compatible', website: 'https://fibertrade.ru', country: 'RUS', description: 'Russian compatible transceivers' }, + { name: 'Linkway Communication', slug: 'linkway', vendor_type: 'compatible', website: 'https://www.linkwaycommunication.com', country: 'CHN', description: 'Chinese compatible optics vendor' }, + { name: 'Gigalight', slug: 'gigalight', vendor_type: 'compatible', website: 'https://www.gigalight.com', country: 'CHN', founded_year: 2006, description: 'Shenzhen-based optics manufacturer and compatible vendor' }, + { name: 'HTFuture', slug: 'htfuture', vendor_type: 'compatible', website: 'https://www.htfuture.com', country: 'CHN', description: 'Chinese compatible transceiver vendor' }, + { name: 'LODFIBER', slug: 'lodfiber', vendor_type: 'compatible', website: 'https://www.lodfiber.com', country: 'CHN', description: 'Shenzhen compatible transceiver vendor' }, + { name: 'Finisar', slug: 'finisar', vendor_type: 'compatible', website: 'https://www.coherent.com', country: 'USA', founded_year: 1988, description: 'Legacy brand (now Coherent), still referenced in part numbers' }, + { name: 'JDSU', slug: 'jdsu', vendor_type: 'compatible', website: 'https://www.lumentum.com', country: 'USA', description: 'Legacy brand (now Lumentum/Viavi)' }, + + // ============================================================ + // DISTRIBUTORS / MARKETPLACES + // ============================================================ + { name: 'Amazon', slug: 'amazon', vendor_type: 'marketplace', website: 'https://www.amazon.com', country: 'USA', founded_year: 1994, description: 'Online marketplace with transceiver listings' }, + { name: 'eBay', slug: 'ebay', vendor_type: 'marketplace', website: 'https://www.ebay.com', country: 'USA', founded_year: 1995, description: 'Auction/fixed-price marketplace for new and used optics', scrape_url: 'https://www.ebay.com/sch/i.html?_nkw=transceiver', scrape_enabled: true }, + { name: 'AliExpress', slug: 'aliexpress', vendor_type: 'marketplace', website: 'https://www.aliexpress.com', country: 'CHN', founded_year: 2010, description: 'Chinese marketplace with direct factory pricing' }, + { name: 'Mouser Electronics', slug: 'mouser', vendor_type: 'distributor', website: 'https://www.mouser.com', country: 'USA', founded_year: 1964, description: 'Electronic component distributor' }, + { name: 'Digi-Key', slug: 'digikey', vendor_type: 'distributor', website: 'https://www.digikey.com', country: 'USA', founded_year: 1972, description: 'Electronic component distributor' }, + { name: 'Arrow Electronics', slug: 'arrow', vendor_type: 'distributor', website: 'https://www.arrow.com', country: 'USA', founded_year: 1935, description: 'Electronic component distributor' }, + { name: 'Ingram Micro', slug: 'ingram', vendor_type: 'distributor', website: 'https://www.ingrammicro.com', country: 'USA', founded_year: 1979, description: 'IT distribution including networking' }, + { name: 'Hummingbird Networks', slug: 'hummingbird', vendor_type: 'distributor', website: 'https://www.hummingbirdnetworks.com', country: 'USA', description: 'Used and refurbished networking equipment' }, + { name: 'Park Place Technologies', slug: 'park-place', vendor_type: 'refurbished', website: 'https://www.parkplacetechnologies.com', country: 'USA', description: 'Third-party maintenance and refurbished optics' }, + { name: 'ITRenew', slug: 'itrenew', vendor_type: 'refurbished', website: 'https://www.itrenew.com', country: 'USA', description: 'Refurbished IT equipment including optics' }, +]; diff --git a/src/api/server.ts b/src/api/server.ts new file mode 100644 index 0000000..156c47c --- /dev/null +++ b/src/api/server.ts @@ -0,0 +1,271 @@ +import 'dotenv/config'; +import express from 'express'; +import cors from 'cors'; +import helmet from 'helmet'; +import compression from 'compression'; +import { pino } from 'pino'; +import { query } from '../utils/db.js'; + +const log = pino({ name: 'api' }); +const app = express(); +const PORT = parseInt(process.env.PORT ?? '3200'); + +app.use(cors()); +app.use(helmet()); +app.use(compression()); +app.use(express.json()); + +// Health check +app.get('/health', (_, res) => res.json({ status: 'ok', timestamp: new Date().toISOString() })); + +// ============================================================ +// TRANSCEIVERS +// ============================================================ + +// Search transceivers +app.get('/api/v1/transceivers', async (req, res) => { + try { + const { q, category, vendor, data_rate, wavelength, connector, status, limit = '50', offset = '0' } = req.query; + + let sql = ` + SELECT t.*, v.name AS vendor_name, v.slug AS vendor_slug, ff.name AS form_factor_name + FROM transceivers t + JOIN vendors v ON t.vendor_id = v.id + LEFT JOIN form_factors ff ON t.form_factor_id = ff.id + WHERE 1=1 + `; + const params: unknown[] = []; + let idx = 1; + + if (q) { + sql += ` AND (t.part_number ILIKE $${idx} OR t.name ILIKE $${idx} OR t.oem_part_number ILIKE $${idx})`; + params.push(`%${q}%`); + idx++; + } + if (category) { sql += ` AND t.category = $${idx}`; params.push(category); idx++; } + if (vendor) { sql += ` AND v.slug = $${idx}`; params.push(vendor); idx++; } + if (data_rate) { sql += ` AND t.data_rate = $${idx}`; params.push(parseFloat(data_rate as string)); idx++; } + if (wavelength) { sql += ` AND t.wavelength_nm = $${idx}`; params.push(parseFloat(wavelength as string)); idx++; } + if (connector) { sql += ` AND t.connector = $${idx}`; params.push(connector); idx++; } + if (status) { sql += ` AND t.status = $${idx}`; params.push(status); idx++; } + + sql += ` ORDER BY t.data_rate DESC, t.name ASC LIMIT $${idx} OFFSET $${idx + 1}`; + params.push(parseInt(limit as string), parseInt(offset as string)); + + const result = await query(sql, params); + + // Get total count + let countSql = sql.replace(/SELECT .+ FROM/, 'SELECT COUNT(*) FROM').replace(/ORDER BY.+/, ''); + const countResult = await query(countSql, params.slice(0, -2)); + + res.json({ + data: result.rows, + total: parseInt(countResult.rows[0]?.count ?? '0'), + limit: parseInt(limit as string), + offset: parseInt(offset as string), + }); + } catch (err) { + log.error({ err }, 'Search failed'); + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// Get single transceiver +app.get('/api/v1/transceivers/:id', async (req, res) => { + try { + const result = await query( + `SELECT t.*, v.name AS vendor_name, v.slug AS vendor_slug, ff.name AS form_factor_name, + ff.full_name AS form_factor_full_name, ff.lanes, ff.power_max_w + FROM transceivers t + JOIN vendors v ON t.vendor_id = v.id + LEFT JOIN form_factors ff ON t.form_factor_id = ff.id + WHERE t.id = $1`, + [req.params.id] + ); + if (!result.rows[0]) return res.status(404).json({ error: 'Not found' }); + res.json(result.rows[0]); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// Get prices for a transceiver +app.get('/api/v1/transceivers/:id/prices', async (req, res) => { + try { + const { days = '30' } = req.query; + const result = await query( + `SELECT p.*, v.name AS vendor_name + FROM prices p JOIN vendors v ON p.vendor_id = v.id + WHERE p.transceiver_id = $1 AND p.time > NOW() - INTERVAL '1 day' * $2 + ORDER BY p.time DESC LIMIT 500`, + [req.params.id, parseInt(days as string)] + ); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// Get compatibility for a transceiver +app.get('/api/v1/transceivers/:id/compatibility', async (req, res) => { + try { + const result = await query( + `SELECT c.*, d.model, d.series, d.device_type, v.name AS device_vendor + FROM compatibility c + JOIN network_devices d ON c.device_id = d.id + JOIN vendors v ON d.vendor_id = v.id + WHERE c.transceiver_id = $1 + ORDER BY v.name, d.model`, + [req.params.id] + ); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// VENDORS +// ============================================================ + +app.get('/api/v1/vendors', async (req, res) => { + try { + const { type } = req.query; + let sql = `SELECT v.*, (SELECT COUNT(*) FROM transceivers t WHERE t.vendor_id = v.id) AS transceiver_count FROM vendors v`; + const params: unknown[] = []; + if (type) { sql += ` WHERE v.vendor_type = $1`; params.push(type); } + sql += ' ORDER BY v.name'; + const result = await query(sql, params); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// NETWORK DEVICES +// ============================================================ + +app.get('/api/v1/devices', async (req, res) => { + try { + const { vendor, series, q, limit = '50', offset = '0' } = req.query; + let sql = `SELECT d.*, v.name AS vendor_name FROM network_devices d JOIN vendors v ON d.vendor_id = v.id WHERE 1=1`; + const params: unknown[] = []; + let idx = 1; + + if (vendor) { sql += ` AND v.slug = $${idx}`; params.push(vendor); idx++; } + if (series) { sql += ` AND d.series ILIKE $${idx}`; params.push(`%${series}%`); idx++; } + if (q) { sql += ` AND d.model ILIKE $${idx}`; params.push(`%${q}%`); idx++; } + + sql += ` ORDER BY v.name, d.model LIMIT $${idx} OFFSET $${idx + 1}`; + params.push(parseInt(limit as string), parseInt(offset as string)); + + const result = await query(sql, params); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// FORM FACTORS +// ============================================================ + +app.get('/api/v1/form-factors', async (_, res) => { + try { + const result = await query( + `SELECT ff.*, (SELECT COUNT(*) FROM transceivers t WHERE t.form_factor_id = ff.id) AS transceiver_count + FROM form_factors ff ORDER BY ff.generation, ff.release_year` + ); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// STANDARDS +// ============================================================ + +app.get('/api/v1/standards', async (_, res) => { + try { + const result = await query('SELECT * FROM standards ORDER BY body, year DESC'); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// HYPE CYCLES +// ============================================================ + +app.get('/api/v1/hype-cycles', async (_, res) => { + try { + const result = await query('SELECT * FROM hype_cycles ORDER BY current_phase, technology'); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// STATS +// ============================================================ + +app.get('/api/v1/stats', async (_, res) => { + try { + const [transceivers, vendors, devices, prices, compatibility] = await Promise.all([ + query('SELECT COUNT(*) FROM transceivers'), + query('SELECT COUNT(*) FROM vendors'), + query('SELECT COUNT(*) FROM network_devices'), + query('SELECT COUNT(*) FROM prices'), + query('SELECT COUNT(*) FROM compatibility'), + ]); + res.json({ + transceivers: parseInt(transceivers.rows[0]?.count ?? '0'), + vendors: parseInt(vendors.rows[0]?.count ?? '0'), + network_devices: parseInt(devices.rows[0]?.count ?? '0'), + price_points: parseInt(prices.rows[0]?.count ?? '0'), + compatibility_entries: parseInt(compatibility.rows[0]?.count ?? '0'), + }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// PRICE COMPARISON +// ============================================================ + +app.get('/api/v1/compare-prices', async (req, res) => { + try { + const { part_number } = req.query; + if (!part_number) return res.status(400).json({ error: 'part_number required' }); + + const result = await query( + `SELECT DISTINCT ON (v.slug) + t.part_number, t.name, v.name AS vendor_name, v.slug AS vendor_slug, v.vendor_type, + p.price, p.currency, p.price_usd, p.in_stock, p.condition, p.url, p.time + FROM prices p + JOIN transceivers t ON p.transceiver_id = t.id + JOIN vendors v ON p.vendor_id = v.id + WHERE t.part_number ILIKE $1 + ORDER BY v.slug, p.time DESC`, + [`%${part_number}%`] + ); + res.json({ data: result.rows }); + } catch (err) { + res.status(500).json({ error: 'Internal server error' }); + } +}); + +// ============================================================ +// START +// ============================================================ + +app.listen(PORT, '0.0.0.0', () => { + log.info({ port: PORT }, 'TIP API server started'); +}); + +export default app; diff --git a/src/crawlers/base.ts b/src/crawlers/base.ts new file mode 100644 index 0000000..345f039 --- /dev/null +++ b/src/crawlers/base.ts @@ -0,0 +1,162 @@ +import { query } from '../utils/db.js'; +import { pino } from 'pino'; +import type { CrawlerConfig } from '../types/index.js'; + +export abstract class BaseCrawler { + protected log; + protected config: CrawlerConfig; + protected jobId: number | null = null; + protected stats = { total: 0, processed: 0, failed: 0, newItems: 0, updated: 0 }; + + constructor(config: CrawlerConfig) { + this.config = config; + this.log = pino({ name: `crawler:${config.name}` }); + } + + async startJob(): Promise { + const result = await query( + `INSERT INTO crawl_jobs (crawler, status, started_at) VALUES ($1, 'running', NOW()) RETURNING id`, + [this.config.name] + ); + this.jobId = result.rows[0]!.id; + this.log.info({ jobId: this.jobId }, 'Crawl job started'); + return this.jobId; + } + + async finishJob(status: 'success' | 'failed', error?: string): Promise { + if (!this.jobId) return; + await query( + `UPDATE crawl_jobs SET status = $1, urls_total = $2, urls_processed = $3, urls_failed = $4, + items_new = $5, items_updated = $6, items_found = $7, error_message = $8, + finished_at = NOW(), duration_ms = EXTRACT(EPOCH FROM (NOW() - started_at)) * 1000 + WHERE id = $9`, + [status, this.stats.total, this.stats.processed, this.stats.failed, + this.stats.newItems, this.stats.updated, this.stats.newItems + this.stats.updated, + error ?? null, this.jobId] + ); + this.log.info({ jobId: this.jobId, status, stats: this.stats }, 'Crawl job finished'); + } + + async logError(url: string, code: string, message: string): Promise { + if (!this.jobId) return; + await query( + `INSERT INTO crawl_errors (job_id, url, error_code, error_message) VALUES ($1, $2, $3, $4)`, + [this.jobId, url, code, message] + ); + this.stats.failed++; + } + + protected async getVendorId(slug: string): Promise { + const result = await query('SELECT id FROM vendors WHERE slug = $1', [slug]); + return result.rows[0]?.id ?? null; + } + + protected async getFormFactorId(name: string): Promise { + const result = await query('SELECT id FROM form_factors WHERE name = $1', [name]); + return result.rows[0]?.id ?? null; + } + + protected async upsertTransceiver(data: { + part_number: string; + vendor_id: number; + form_factor_id?: number | null; + name?: string; + category?: string; + subcategory?: string; + data_rate?: number; + data_rate_unit?: string; + max_reach?: number; + reach_unit?: string; + wavelength_nm?: number; + connector?: string; + fiber_type?: string; + duplex?: boolean; + temp_range?: string; + dom_support?: string; + oem_part_number?: string; + status?: string; + image_url?: string; + datasheet_url?: string; + product_url?: string; + tags?: string[]; + raw_specs?: Record; + source: string; + source_url?: string; + }): Promise<{ id: number; isNew: boolean }> { + const result = await query( + `INSERT INTO transceivers ( + part_number, vendor_id, form_factor_id, name, category, subcategory, + data_rate, data_rate_unit, max_reach, reach_unit, wavelength_nm, + connector, fiber_type, duplex, temp_range, dom_support, + oem_part_number, status, image_url, datasheet_url, product_url, + tags, raw_specs, source, source_url, last_verified + ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,NOW()) + ON CONFLICT (part_number, vendor_id) DO UPDATE SET + name = COALESCE($4, transceivers.name), + image_url = COALESCE($19, transceivers.image_url), + datasheet_url = COALESCE($20, transceivers.datasheet_url), + product_url = COALESCE($21, transceivers.product_url), + raw_specs = COALESCE($23, transceivers.raw_specs), + last_verified = NOW(), + updated_at = NOW() + RETURNING id, (xmax = 0) AS is_new`, + [ + data.part_number, data.vendor_id, data.form_factor_id ?? null, + data.name ?? null, data.category ?? null, data.subcategory ?? null, + data.data_rate ?? null, data.data_rate_unit ?? 'Gbps', + data.max_reach ?? null, data.reach_unit ?? 'km', + data.wavelength_nm ?? null, data.connector ?? null, + data.fiber_type ?? null, data.duplex ?? true, + data.temp_range ?? 'commercial', data.dom_support ?? 'none', + data.oem_part_number ?? null, data.status ?? 'active', + data.image_url ?? null, data.datasheet_url ?? null, data.product_url ?? null, + data.tags ?? null, data.raw_specs ? JSON.stringify(data.raw_specs) : null, + data.source, data.source_url ?? null, + ] + ); + + const row = result.rows[0]!; + if (row.is_new) this.stats.newItems++; + else this.stats.updated++; + return { id: row.id, isNew: row.is_new }; + } + + protected async upsertPrice(data: { + transceiver_id: number; + vendor_id: number; + price: number; + currency?: string; + price_usd?: number; + in_stock?: boolean; + stock_quantity?: number; + condition?: string; + url?: string; + source: string; + }): Promise { + await query( + `INSERT INTO prices (time, transceiver_id, vendor_id, price, currency, price_usd, + in_stock, stock_quantity, condition, url, source) + VALUES (NOW(), $1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, + [ + data.transceiver_id, data.vendor_id, data.price, + data.currency ?? 'USD', data.price_usd ?? data.price, + data.in_stock ?? null, data.stock_quantity ?? null, + data.condition ?? 'new', data.url ?? null, data.source, + ] + ); + } + + abstract crawl(): Promise; + + async run(): Promise { + try { + await this.startJob(); + await this.crawl(); + await this.finishJob('success'); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + this.log.error({ err }, 'Crawl failed'); + await this.finishJob('failed', msg); + } + } +} diff --git a/src/crawlers/ebay.ts b/src/crawlers/ebay.ts new file mode 100644 index 0000000..d092cc7 --- /dev/null +++ b/src/crawlers/ebay.ts @@ -0,0 +1,183 @@ +import 'dotenv/config'; +import { CheerioCrawler } from 'crawlee'; +import { BaseCrawler } from './base.js'; + +/** + * eBay Transceiver Price Crawler + * Scrapes current Buy-It-Now listings and sold prices for transceivers + * Gives us real market pricing data + */ +export class EbayCrawler extends BaseCrawler { + // Search queries for different transceiver categories + private static QUERIES = [ + { q: 'SFP 1G transceiver -used -lot', category: 'SFP' }, + { q: 'SFP+ 10G transceiver', category: 'SFP+' }, + { q: 'SFP28 25G transceiver', category: 'SFP28' }, + { q: 'QSFP+ 40G transceiver', category: 'QSFP+' }, + { q: 'QSFP28 100G transceiver', category: 'QSFP28' }, + { q: 'QSFP-DD 400G transceiver', category: 'QSFP-DD' }, + { q: 'OSFP 400G 800G transceiver', category: 'OSFP' }, + { q: 'DAC cable 10G SFP+ direct attach', category: 'DAC' }, + { q: 'DAC cable 100G QSFP28', category: 'DAC' }, + ]; + + constructor() { + super({ + name: 'ebay', + baseUrl: 'https://www.ebay.com', + interval: 43200, // twice daily + maxConcurrency: 3, + maxRequestsPerMinute: 15, + usePlaywright: false, + }); + } + + async crawl(): Promise { + const ebayVendorId = await this.getVendorId('ebay'); + if (!ebayVendorId) throw new Error('Vendor ebay not found'); + + const crawler = new CheerioCrawler({ + maxConcurrency: this.config.maxConcurrency, + maxRequestsPerMinute: this.config.maxRequestsPerMinute, + + async requestHandler({ request, $, enqueueLinks }) { + const url = request.url; + const category = request.userData?.category as string; + + this.log.info({ url, category }, 'Processing eBay search page'); + + // Extract listings + const listings = $('li.s-item, div.s-item__wrapper').toArray(); + + for (const el of listings) { + try { + const $item = $(el); + const title = $item.find('.s-item__title span, .s-item__title').first().text().trim(); + const priceText = $item.find('.s-item__price').first().text().trim(); + const itemUrl = $item.find('.s-item__link').attr('href') ?? ''; + const condition = $item.find('.SECONDARY_INFO').text().trim(); + const imageUrl = $item.find('.s-item__image-img').attr('src') ?? ''; + + // Skip non-transceiver results + if (!title || title === 'Shop on eBay') continue; + + // Parse price + const priceMatch = priceText.match(/[\$€£]([\d,]+\.?\d*)/); + if (!priceMatch) continue; + const price = parseFloat(priceMatch[1]!.replace(',', '')); + if (price <= 0 || price > 50000) continue; + + // Detect currency + let currency = 'USD'; + if (priceText.includes('€')) currency = 'EUR'; + else if (priceText.includes('£')) currency = 'GBP'; + + // Try to extract part number from title + const partNumber = this.extractPartNumber(title); + if (!partNumber) continue; + + // Detect vendor from title + const vendorSlug = this.detectVendor(title); + const actualVendorId = vendorSlug ? (await this.getVendorId(vendorSlug)) ?? ebayVendorId : ebayVendorId; + + // Upsert transceiver + const result = await this.upsertTransceiver({ + part_number: partNumber, + vendor_id: actualVendorId, + name: title.slice(0, 500), + category, + image_url: imageUrl || undefined, + product_url: itemUrl, + tags: ['ebay', category.toLowerCase()], + source: 'ebay', + source_url: itemUrl, + }); + + // Always insert price (time-series) + await this.upsertPrice({ + transceiver_id: result.id, + vendor_id: ebayVendorId, + price, + currency: currency as any, + in_stock: true, + condition: condition.toLowerCase().includes('new') ? 'new' : condition.toLowerCase().includes('refurb') ? 'refurbished' : 'used', + url: itemUrl, + source: 'ebay', + }); + } catch (err) { + // Skip individual item errors + } + } + + // Follow pagination (first 5 pages) + const pageNum = parseInt(new URL(url).searchParams.get('_pgn') ?? '1'); + if (pageNum < 5) { + const nextUrl = new URL(url); + nextUrl.searchParams.set('_pgn', String(pageNum + 1)); + await enqueueLinks({ + urls: [nextUrl.href], + userData: { category }, + }); + } + + this.stats.total++; + this.stats.processed++; + }, + }); + + // Build initial search URLs + const requests = EbayCrawler.QUERIES.map(q => ({ + url: `${this.config.baseUrl}/sch/i.html?_nkw=${encodeURIComponent(q.q)}&_sacat=0&LH_BIN=1&_sop=15&_ipg=120`, + userData: { category: q.category }, + })); + + await crawler.run(requests); + } + + private extractPartNumber(title: string): string | null { + // Common OEM part number patterns + const patterns = [ + /\b(SFP-\d+G-[A-Z0-9-]+)\b/i, + /\b(GLC-[A-Z0-9-]+)\b/i, + /\b(QSFP-[A-Z0-9-]+)\b/i, + /\b(QDD-[A-Z0-9-]+)\b/i, + /\b(OSFP-[A-Z0-9-]+)\b/i, + /\b(EX-SFP-[A-Z0-9-]+)\b/i, + /\b(JNP-[A-Z0-9-]+)\b/i, + /\b(CWDM-[A-Z0-9-]+)\b/i, + /\b(DS-SFP-[A-Z0-9-]+)\b/i, + /\b([A-Z]{2,4}-\d+[A-Z]+-[A-Z0-9]+)\b/, // Generic pattern + ]; + + for (const pattern of patterns) { + const match = title.match(pattern); + if (match) return match[1]!; + } + + return null; + } + + private detectVendor(title: string): string | null { + const tl = title.toLowerCase(); + if (tl.includes('cisco')) return 'cisco'; + if (tl.includes('juniper')) return 'juniper'; + if (tl.includes('arista')) return 'arista'; + if (tl.includes('hpe') || tl.includes('hewlett')) return 'hpe'; + if (tl.includes('dell')) return 'dell'; + if (tl.includes('fs.com') || tl.includes('fiberstore')) return 'fs-com'; + if (tl.includes('10gtek')) return '10gtek'; + if (tl.includes('flexoptix')) return 'flexoptix'; + if (tl.includes('mellanox') || tl.includes('nvidia')) return 'mellanox'; + if (tl.includes('mikrotik')) return 'mikrotik'; + if (tl.includes('ubiquiti') || tl.includes('unifi')) return 'ubiquiti'; + if (tl.includes('intel')) return 'intel'; + if (tl.includes('huawei')) return 'huawei'; + if (tl.includes('fortinet')) return 'fortinet'; + return null; + } +} + +if (import.meta.url === `file://${process.argv[1]}`) { + const crawler = new EbayCrawler(); + crawler.run(); +} diff --git a/src/crawlers/fscom.ts b/src/crawlers/fscom.ts new file mode 100644 index 0000000..60a26e0 --- /dev/null +++ b/src/crawlers/fscom.ts @@ -0,0 +1,249 @@ +import 'dotenv/config'; +import { PlaywrightCrawler, Dataset } from 'crawlee'; +import { BaseCrawler } from './base.js'; + +/** + * FS.com Crawler + * Scrapes transceiver catalog from fs.com (~4000 SKUs) + * Uses Playwright because fs.com has Cloudflare protection + * + * Categories: + * - /c/sfp-702 (1G SFP) + * - /c/10g-sfp-756 (10G SFP+) + * - /c/25g-sfp28-702 (25G SFP28) + * - /c/40g-qsfp-702 (40G QSFP+) + * - /c/100g-qsfp28-702 (100G QSFP28) + * - /c/200g-qsfp56-702 (200G QSFP56) + * - /c/400g-qsfp-dd-702 (400G QSFP-DD) + * - /c/800g-osfp-702 (800G OSFP/QSFP-DD800) + * - /c/dac-702 (DAC cables) + * - /c/aoc-702 (AOC cables) + */ +export class FsComCrawler extends BaseCrawler { + private static CATEGORIES = [ + { url: '/c/sfp-702', category: 'SFP', formFactor: 'SFP' }, + { url: '/c/10g-sfp-756', category: 'SFP+', formFactor: 'SFP+' }, + { url: '/c/25g-sfp28-702', category: 'SFP28', formFactor: 'SFP28' }, + { url: '/c/40g-qsfp-702', category: 'QSFP+', formFactor: 'QSFP+' }, + { url: '/c/100g-qsfp28-702', category: 'QSFP28', formFactor: 'QSFP28' }, + { url: '/c/200g-qsfp56-702', category: 'QSFP56', formFactor: 'QSFP56' }, + { url: '/c/400g-qsfp-dd-702', category: 'QSFP-DD', formFactor: 'QSFP-DD' }, + { url: '/c/800g-osfp-702', category: 'OSFP', formFactor: 'OSFP' }, + ]; + + constructor() { + super({ + name: 'fscom', + baseUrl: 'https://www.fs.com', + interval: 86400, // daily + maxConcurrency: 2, + maxRequestsPerMinute: 10, + usePlaywright: true, + }); + } + + async crawl(): Promise { + const vendorId = await this.getVendorId('fs-com'); + if (!vendorId) throw new Error('Vendor fs-com not found'); + + const crawler = new PlaywrightCrawler({ + maxConcurrency: this.config.maxConcurrency, + maxRequestsPerMinute: this.config.maxRequestsPerMinute, + requestHandlerTimeoutSecs: 60, + + async requestHandler({ request, page, enqueueLinks }) { + const url = request.url; + + // Category listing page — enqueue product links + if (request.label === 'LIST') { + this.log.info({ url }, 'Processing category page'); + + // Wait for product grid to load + await page.waitForSelector('.prod-list-item, .product-item', { timeout: 15000 }).catch(() => {}); + + // Enqueue product detail pages + await enqueueLinks({ + selector: 'a.prod-list-item__title, a.product-item__title', + label: 'DETAIL', + }); + + // Follow pagination + await enqueueLinks({ + selector: 'a.page-next, a.pagination__next', + label: 'LIST', + }); + + this.stats.total++; + this.stats.processed++; + return; + } + + // Product detail page + if (request.label === 'DETAIL') { + this.log.info({ url }, 'Processing product page'); + + try { + await page.waitForSelector('.product-detail, .prod-detail', { timeout: 15000 }).catch(() => {}); + + // Extract product data from the page + const data = await page.evaluate(() => { + const getText = (sel: string) => document.querySelector(sel)?.textContent?.trim() ?? ''; + const getAttr = (sel: string, attr: string) => document.querySelector(sel)?.getAttribute(attr) ?? ''; + + // Spec table extraction + const specs: Record = {}; + document.querySelectorAll('.spec-table tr, .prod-spec tr, table.spec tr').forEach(row => { + const cells = row.querySelectorAll('td, th'); + if (cells.length >= 2) { + const key = cells[0]?.textContent?.trim() ?? ''; + const val = cells[1]?.textContent?.trim() ?? ''; + if (key && val) specs[key] = val; + } + }); + + return { + title: getText('h1') || getText('.product-title'), + partNumber: getText('.product-sku, .prod-sku, [itemprop="sku"]'), + price: getText('.product-price .price, .prod-price, [itemprop="price"]'), + currency: getAttr('[itemprop="priceCurrency"]', 'content') || 'USD', + inStock: !getText('.out-of-stock'), + image: getAttr('.product-image img, .prod-img img', 'src'), + datasheet: getAttr('a[href*="datasheet"], a[href*=".pdf"]', 'href'), + specs, + }; + }); + + if (!data.partNumber) { + this.log.warn({ url }, 'No part number found'); + return; + } + + // Determine category from URL/specs + const category = this.detectCategory(data.specs, url); + const ffId = await this.getFormFactorId(category.formFactor); + + // Parse specs + const parsed = this.parseSpecs(data.specs); + + const result = await this.upsertTransceiver({ + part_number: data.partNumber, + vendor_id: vendorId, + form_factor_id: ffId, + name: data.title, + category: category.category, + subcategory: parsed.subcategory, + data_rate: parsed.dataRate, + max_reach: parsed.maxReach, + reach_unit: parsed.reachUnit as any, + wavelength_nm: parsed.wavelength, + connector: parsed.connector as any, + fiber_type: parsed.fiberType as any, + image_url: data.image ? new URL(data.image, this.config.baseUrl).href : undefined, + datasheet_url: data.datasheet ? new URL(data.datasheet, this.config.baseUrl).href : undefined, + product_url: url, + tags: [category.category.toLowerCase(), 'fs.com'], + raw_specs: data.specs, + source: 'fscom', + source_url: url, + }); + + // Insert price if available + const price = parseFloat(data.price.replace(/[^0-9.]/g, '')); + if (price > 0) { + await this.upsertPrice({ + transceiver_id: result.id, + vendor_id: vendorId, + price, + currency: data.currency as any, + in_stock: data.inStock, + url, + source: 'fscom', + }); + } + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + await this.logError(url, 'PARSE', msg); + } + + this.stats.total++; + this.stats.processed++; + } + }, + }); + + // Start crawling from category pages + const requests = FsComCrawler.CATEGORIES.map(cat => ({ + url: `${this.config.baseUrl}${cat.url}`, + label: 'LIST', + userData: cat, + })); + + await crawler.run(requests); + } + + private detectCategory(specs: Record, url: string): { category: string; formFactor: string } { + const urlLower = url.toLowerCase(); + if (urlLower.includes('800g')) return { category: 'OSFP', formFactor: 'OSFP' }; + if (urlLower.includes('400g')) return { category: 'QSFP-DD', formFactor: 'QSFP-DD' }; + if (urlLower.includes('200g')) return { category: 'QSFP56', formFactor: 'QSFP56' }; + if (urlLower.includes('100g') || urlLower.includes('qsfp28')) return { category: 'QSFP28', formFactor: 'QSFP28' }; + if (urlLower.includes('40g') || urlLower.includes('qsfp')) return { category: 'QSFP+', formFactor: 'QSFP+' }; + if (urlLower.includes('25g') || urlLower.includes('sfp28')) return { category: 'SFP28', formFactor: 'SFP28' }; + if (urlLower.includes('10g') || urlLower.includes('sfp-plus')) return { category: 'SFP+', formFactor: 'SFP+' }; + return { category: 'SFP', formFactor: 'SFP' }; + } + + private parseSpecs(specs: Record): { + subcategory?: string; dataRate?: number; maxReach?: number; reachUnit?: string; + wavelength?: number; connector?: string; fiberType?: string; + } { + const result: any = {}; + for (const [key, val] of Object.entries(specs)) { + const kl = key.toLowerCase(); + if (kl.includes('data rate') || kl.includes('speed')) { + const match = val.match(/([\d.]+)\s*(Gbps|Mbps|Tbps)/i); + if (match) result.dataRate = parseFloat(match[1]!); + } + if (kl.includes('wavelength')) { + const match = val.match(/([\d.]+)\s*nm/i); + if (match) result.wavelength = parseFloat(match[1]!); + } + if (kl.includes('max') && (kl.includes('distance') || kl.includes('reach') || kl.includes('cable'))) { + const match = val.match(/([\d.]+)\s*(km|m)/i); + if (match) { + result.maxReach = parseFloat(match[1]!); + result.reachUnit = match[2]!.toLowerCase(); + } + } + if (kl.includes('connector')) { + if (val.includes('LC')) result.connector = 'LC'; + else if (val.includes('MPO-12')) result.connector = 'MPO-12'; + else if (val.includes('MPO')) result.connector = 'MPO-12'; + else if (val.includes('SC')) result.connector = 'SC'; + else if (val.includes('RJ45')) result.connector = 'copper_rj45'; + } + if (kl.includes('fiber') || kl.includes('cable')) { + if (val.includes('SMF') || val.includes('Single')) result.fiberType = 'smf'; + else if (val.includes('OM4')) result.fiberType = 'mmf_om4'; + else if (val.includes('OM3')) result.fiberType = 'mmf_om3'; + } + if (kl.includes('type') || kl.includes('application')) { + if (val.includes('SR')) result.subcategory = 'SR'; + else if (val.includes('LR')) result.subcategory = 'LR'; + else if (val.includes('ER')) result.subcategory = 'ER'; + else if (val.includes('ZR')) result.subcategory = 'ZR'; + else if (val.includes('DR')) result.subcategory = 'DR'; + else if (val.includes('FR')) result.subcategory = 'FR'; + else if (val.includes('CWDM')) result.subcategory = 'CWDM'; + else if (val.includes('BiDi')) result.subcategory = 'BiDi'; + } + } + return result; + } +} + +// Run standalone +if (import.meta.url === `file://${process.argv[1]}`) { + const crawler = new FsComCrawler(); + crawler.run(); +} diff --git a/src/mcp/server.ts b/src/mcp/server.ts new file mode 100644 index 0000000..71a3d68 --- /dev/null +++ b/src/mcp/server.ts @@ -0,0 +1,370 @@ +import 'dotenv/config'; +import { query } from '../utils/db.js'; +import { pino } from 'pino'; +import { createServer } from 'http'; + +const log = pino({ name: 'mcp' }); +const PORT = parseInt(process.env.MCP_PORT ?? '3201'); + +/** + * TIP MCP Server — 12 Tools for AI/LLM Integration + * Protocol: JSON-RPC 2.0 over SSE (Server-Sent Events) + * + * Tools: + * 1. search_transceivers — Find transceivers by specs, part number, vendor + * 2. get_transceiver — Get full details for a transceiver + * 3. compare_prices — Compare prices across vendors for a given part + * 4. check_compatibility — Check if transceiver works with a device + * 5. find_compatible_transceivers — Find all transceivers for a device + * 6. search_devices — Search switches/routers by vendor, model, ports + * 7. get_form_factor_info — Get details about a form factor + * 8. get_hype_cycle — Get technology hype cycle status + * 9. search_faq — Search knowledge base articles + * 10. get_vendor_catalog — List all transceivers from a vendor + * 11. suggest_alternative — Find compatible alternatives for a part + * 12. get_market_stats — Get market overview and statistics + */ + +interface MCPTool { + name: string; + description: string; + inputSchema: Record; +} + +const TOOLS: MCPTool[] = [ + { + name: 'search_transceivers', + description: 'Search for optical transceivers by part number, speed, wavelength, reach, connector, vendor, or form factor. Returns matching transceivers with specs and pricing.', + inputSchema: { + type: 'object', + properties: { + query: { type: 'string', description: 'Search text (part number, name, or description)' }, + category: { type: 'string', description: 'Form factor category (SFP, SFP+, SFP28, QSFP+, QSFP28, QSFP-DD, OSFP)' }, + data_rate: { type: 'number', description: 'Data rate in Gbps (1, 10, 25, 40, 100, 200, 400, 800)' }, + wavelength: { type: 'number', description: 'Wavelength in nm (850, 1310, 1550, etc.)' }, + max_reach_km: { type: 'number', description: 'Maximum reach in km' }, + connector: { type: 'string', description: 'Connector type (LC, SC, MPO-12, copper_rj45, etc.)' }, + vendor: { type: 'string', description: 'Vendor slug (cisco, juniper, arista, flexoptix, fs-com, etc.)' }, + limit: { type: 'number', description: 'Max results (default 20)', default: 20 }, + }, + }, + }, + { + name: 'get_transceiver', + description: 'Get full details for a specific transceiver by ID or part number, including specs, pricing history, and compatible devices.', + inputSchema: { + type: 'object', + properties: { + id: { type: 'number', description: 'Transceiver ID' }, + part_number: { type: 'string', description: 'Part number (e.g., SFP-10G-SR, QSFP-100G-LR4-S)' }, + }, + }, + }, + { + name: 'compare_prices', + description: 'Compare current prices across all vendors for a transceiver part number. Shows OEM vs compatible pricing.', + inputSchema: { + type: 'object', + properties: { + part_number: { type: 'string', description: 'Part number to compare prices for' }, + }, + required: ['part_number'], + }, + }, + { + name: 'check_compatibility', + description: 'Check if a specific transceiver is compatible with a specific network device (switch/router).', + inputSchema: { + type: 'object', + properties: { + transceiver_part: { type: 'string', description: 'Transceiver part number' }, + device_model: { type: 'string', description: 'Network device model (e.g., C9300-48P, QFX5120-48Y)' }, + }, + required: ['transceiver_part', 'device_model'], + }, + }, + { + name: 'find_compatible_transceivers', + description: 'Find all compatible transceivers for a given network device, optionally filtered by speed or type.', + inputSchema: { + type: 'object', + properties: { + device_model: { type: 'string', description: 'Device model' }, + category: { type: 'string', description: 'Filter by category (SFP+, QSFP28, etc.)' }, + data_rate: { type: 'number', description: 'Filter by data rate' }, + }, + required: ['device_model'], + }, + }, + { + name: 'search_devices', + description: 'Search network switches and routers by vendor, model series, or port configuration.', + inputSchema: { + type: 'object', + properties: { + query: { type: 'string', description: 'Search text (model number or series)' }, + vendor: { type: 'string', description: 'Vendor slug' }, + device_type: { type: 'string', description: 'Type: switch, router, firewall' }, + min_ports_qsfp_dd: { type: 'number', description: 'Minimum QSFP-DD ports' }, + }, + }, + }, + { + name: 'get_form_factor_info', + description: 'Get technical details about a transceiver form factor (dimensions, power, lanes, max speed, generation).', + inputSchema: { + type: 'object', + properties: { + name: { type: 'string', description: 'Form factor name (SFP+, QSFP-DD, OSFP, etc.)' }, + }, + required: ['name'], + }, + }, + { + name: 'get_hype_cycle', + description: 'Get the current hype cycle phase for a transceiver technology (e.g., 400G ZR, Silicon Photonics, LPO).', + inputSchema: { + type: 'object', + properties: { + technology: { type: 'string', description: 'Technology name' }, + }, + required: ['technology'], + }, + }, + { + name: 'search_faq', + description: 'Search the transceiver knowledge base for troubleshooting, compatibility guides, and technical articles.', + inputSchema: { + type: 'object', + properties: { + query: { type: 'string', description: 'Search text' }, + category: { type: 'string', description: 'Article category' }, + }, + required: ['query'], + }, + }, + { + name: 'get_vendor_catalog', + description: 'List all transceivers from a specific vendor, grouped by category.', + inputSchema: { + type: 'object', + properties: { + vendor: { type: 'string', description: 'Vendor slug (cisco, juniper, flexoptix, fs-com, etc.)' }, + category: { type: 'string', description: 'Filter by category' }, + }, + required: ['vendor'], + }, + }, + { + name: 'suggest_alternative', + description: 'Find compatible/cheaper alternatives for an OEM transceiver. Compares specs and prices.', + inputSchema: { + type: 'object', + properties: { + part_number: { type: 'string', description: 'OEM part number to find alternatives for' }, + }, + required: ['part_number'], + }, + }, + { + name: 'get_market_stats', + description: 'Get transceiver market overview: total products, vendors, pricing trends, popular categories.', + inputSchema: { + type: 'object', + properties: {}, + }, + }, +]; + +// Tool handlers +async function handleTool(name: string, args: Record): Promise { + switch (name) { + case 'search_transceivers': { + let sql = `SELECT t.id, t.part_number, t.name, t.category, t.subcategory, t.data_rate, t.data_rate_unit, + t.max_reach, t.reach_unit, t.wavelength_nm, t.connector, t.fiber_type, t.status, + v.name AS vendor_name, v.slug AS vendor_slug, ff.name AS form_factor + FROM transceivers t JOIN vendors v ON t.vendor_id = v.id LEFT JOIN form_factors ff ON t.form_factor_id = ff.id WHERE 1=1`; + const params: unknown[] = []; + let idx = 1; + + if (args.query) { sql += ` AND (t.part_number ILIKE $${idx} OR t.name ILIKE $${idx})`; params.push(`%${args.query}%`); idx++; } + if (args.category) { sql += ` AND t.category = $${idx}`; params.push(args.category); idx++; } + if (args.data_rate) { sql += ` AND t.data_rate = $${idx}`; params.push(args.data_rate); idx++; } + if (args.wavelength) { sql += ` AND t.wavelength_nm = $${idx}`; params.push(args.wavelength); idx++; } + if (args.connector) { sql += ` AND t.connector = $${idx}`; params.push(args.connector); idx++; } + if (args.vendor) { sql += ` AND v.slug = $${idx}`; params.push(args.vendor); idx++; } + + sql += ` ORDER BY t.data_rate DESC, t.name LIMIT $${idx}`; + params.push(args.limit ?? 20); + + const result = await query(sql, params); + return { transceivers: result.rows, count: result.rowCount }; + } + + case 'get_transceiver': { + let sql = `SELECT t.*, v.name AS vendor_name, v.slug AS vendor_slug, ff.name AS form_factor, ff.full_name AS form_factor_full_name + FROM transceivers t JOIN vendors v ON t.vendor_id = v.id LEFT JOIN form_factors ff ON t.form_factor_id = ff.id`; + const params: unknown[] = []; + + if (args.id) { sql += ` WHERE t.id = $1`; params.push(args.id); } + else if (args.part_number) { sql += ` WHERE t.part_number ILIKE $1`; params.push(args.part_number); } + else return { error: 'Provide id or part_number' }; + + const result = await query(sql, params); + if (!result.rows[0]) return { error: 'Transceiver not found' }; + + // Get latest prices + const prices = await query( + `SELECT DISTINCT ON (v.slug) p.price, p.currency, p.in_stock, v.name AS vendor_name, v.vendor_type, p.time + FROM prices p JOIN vendors v ON p.vendor_id = v.id + WHERE p.transceiver_id = $1 ORDER BY v.slug, p.time DESC`, + [result.rows[0].id] + ); + + return { ...result.rows[0], prices: prices.rows }; + } + + case 'compare_prices': { + const result = await query( + `SELECT DISTINCT ON (v.slug) t.part_number, t.name, v.name AS vendor, v.vendor_type, + p.price, p.currency, p.price_usd, p.in_stock, p.condition, p.url, p.time + FROM prices p JOIN transceivers t ON p.transceiver_id = t.id JOIN vendors v ON p.vendor_id = v.id + WHERE t.part_number ILIKE $1 ORDER BY v.slug, p.time DESC`, + [`%${args.part_number}%`] + ); + return { prices: result.rows, count: result.rowCount }; + } + + case 'get_form_factor_info': { + const result = await query( + `SELECT ff.*, (SELECT COUNT(*) FROM transceivers t WHERE t.form_factor_id = ff.id) AS total_transceivers + FROM form_factors ff WHERE ff.name ILIKE $1`, + [args.name] + ); + return result.rows[0] ?? { error: 'Form factor not found' }; + } + + case 'get_vendor_catalog': { + const result = await query( + `SELECT t.part_number, t.name, t.category, t.subcategory, t.data_rate, t.data_rate_unit, t.status + FROM transceivers t JOIN vendors v ON t.vendor_id = v.id + WHERE v.slug = $1 ${args.category ? 'AND t.category = $2' : ''} + ORDER BY t.category, t.data_rate DESC`, + args.category ? [args.vendor, args.category] : [args.vendor] + ); + return { vendor: args.vendor, transceivers: result.rows, count: result.rowCount }; + } + + case 'suggest_alternative': { + // Find the original transceiver + const orig = await query( + `SELECT t.*, v.vendor_type FROM transceivers t JOIN vendors v ON t.vendor_id = v.id + WHERE t.part_number ILIKE $1 LIMIT 1`, + [args.part_number] + ); + if (!orig.rows[0]) return { error: 'Original transceiver not found' }; + const o = orig.rows[0]; + + // Find alternatives with matching specs + const alts = await query( + `SELECT t.part_number, t.name, v.name AS vendor_name, v.vendor_type, + t.data_rate, t.max_reach, t.wavelength_nm, t.connector + FROM transceivers t JOIN vendors v ON t.vendor_id = v.id + WHERE t.category = $1 AND t.data_rate = $2 AND t.wavelength_nm = $3 + AND t.id != $4 + ORDER BY v.vendor_type, v.name LIMIT 20`, + [o.category, o.data_rate, o.wavelength_nm, o.id] + ); + return { original: { part_number: o.part_number, vendor_type: o.vendor_type }, alternatives: alts.rows }; + } + + case 'get_market_stats': { + const [total, byCategory, byVendorType, recentPrices] = await Promise.all([ + query('SELECT COUNT(*) AS total FROM transceivers'), + query('SELECT category, COUNT(*) AS count FROM transceivers GROUP BY category ORDER BY count DESC'), + query('SELECT v.vendor_type, COUNT(*) AS count FROM transceivers t JOIN vendors v ON t.vendor_id = v.id GROUP BY v.vendor_type'), + query(`SELECT COUNT(*) AS count, AVG(price_usd) AS avg_price FROM prices WHERE time > NOW() - INTERVAL '7 days'`), + ]); + return { + total_transceivers: parseInt(total.rows[0]?.total ?? '0'), + by_category: byCategory.rows, + by_vendor_type: byVendorType.rows, + recent_prices: recentPrices.rows[0], + }; + } + + default: + return { error: `Unknown tool: ${name}` }; + } +} + +// SSE MCP Protocol +const server = createServer(async (req, res) => { + const url = new URL(req.url ?? '/', `http://localhost:${PORT}`); + + if (url.pathname === '/sse') { + // SSE endpoint + res.writeHead(200, { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + Connection: 'keep-alive', + 'Access-Control-Allow-Origin': '*', + }); + + // Send server info + const serverInfo = { + jsonrpc: '2.0', + method: 'notifications/initialized', + params: { + protocolVersion: '2024-11-05', + serverInfo: { name: 'transceiver-intelligence-platform', version: '0.1.0' }, + capabilities: { tools: { listChanged: false } }, + }, + }; + res.write(`data: ${JSON.stringify(serverInfo)}\n\n`); + + // Keep alive + const keepAlive = setInterval(() => { res.write(':keepalive\n\n'); }, 30000); + req.on('close', () => clearInterval(keepAlive)); + return; + } + + if (url.pathname === '/message' && req.method === 'POST') { + let body = ''; + for await (const chunk of req) body += chunk; + const msg = JSON.parse(body); + + let response: unknown; + + if (msg.method === 'tools/list') { + response = { jsonrpc: '2.0', id: msg.id, result: { tools: TOOLS } }; + } else if (msg.method === 'tools/call') { + try { + const result = await handleTool(msg.params.name, msg.params.arguments ?? {}); + response = { + jsonrpc: '2.0', id: msg.id, + result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }, + }; + } catch (err) { + response = { + jsonrpc: '2.0', id: msg.id, + error: { code: -32603, message: err instanceof Error ? err.message : 'Internal error' }, + }; + } + } else { + response = { jsonrpc: '2.0', id: msg.id, error: { code: -32601, message: 'Method not found' } }; + } + + res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }); + res.end(JSON.stringify(response)); + return; + } + + // Default + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ name: 'TIP MCP Server', version: '0.1.0', tools: TOOLS.length })); +}); + +server.listen(PORT, '0.0.0.0', () => { + log.info({ port: PORT }, 'TIP MCP server started'); +}); diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..9d1cbac --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,164 @@ +// Transceiver Intelligence Platform — Core Types + +export type TransceiverStatus = 'active' | 'eol' | 'pre_release' | 'nrnd' | 'unknown'; +export type DataRateUnit = 'Mbps' | 'Gbps' | 'Tbps'; +export type ReachUnit = 'm' | 'km'; +export type TemperatureRange = 'commercial' | 'extended' | 'industrial'; +export type DOMType = 'none' | 'ddm' | 'ddmi' | 'cmis' | 'sff8472' | 'sff8636'; +export type ConnectorType = + | 'LC' | 'SC' | 'MPO-12' | 'MPO-16' | 'MPO-24' | 'CS' | 'SN' + | 'FC' | 'ST' | 'MTRJ' | 'E2000' | 'copper_rj45' | 'cx4' + | 'dac_passive' | 'dac_active' | 'aoc' | 'none' | 'other'; +export type FiberType = + | 'smf' | 'mmf_om1' | 'mmf_om2' | 'mmf_om3' | 'mmf_om4' | 'mmf_om5' + | 'copper' | 'dac' | 'aoc' | 'free_space' | 'other'; +export type WavelengthBand = + | 'O' | 'E' | 'S' | 'C' | 'L' | 'U' | 'visible' + | 'cwdm' | 'dwdm' | 'lwdm' | 'swdm' | 'other'; +export type VendorType = 'oem' | 'compatible' | 'distributor' | 'manufacturer' | 'marketplace' | 'refurbished'; +export type PriceCurrency = 'USD' | 'EUR' | 'GBP' | 'CNY' | 'JPY' | 'KRW' | 'TWD' | 'THB' | 'INR' | 'CAD' | 'AUD'; +export type HypePhase = + | 'innovation_trigger' | 'peak_inflated' | 'trough_disillusionment' + | 'slope_enlightenment' | 'plateau_productivity' | 'decline'; +export type CrawlStatus = 'pending' | 'running' | 'success' | 'failed' | 'rate_limited'; +export type MediaType = 'image' | 'datasheet' | 'manual' | 'diagram' | 'video' | 'certificate'; + +export interface Standard { + id?: number; + name: string; + body: string; + version?: string; + year?: number; + url?: string; + description?: string; +} + +export interface FormFactor { + id?: number; + name: string; + full_name?: string; + standard_id?: number; + lanes?: number; + max_data_rate?: number; + data_rate_unit?: DataRateUnit; + width_mm?: number; + height_mm?: number; + depth_mm?: number; + power_max_w?: number; + generation?: number; + release_year?: number; + eol_year?: number; + description?: string; + image_url?: string; +} + +export interface Vendor { + id?: number; + name: string; + slug: string; + vendor_type: VendorType; + website?: string; + logo_url?: string; + country?: string; + founded_year?: number; + description?: string; + is_oem?: boolean; + is_factory?: boolean; + aliases?: string[]; + scrape_url?: string; + scrape_enabled?: boolean; +} + +export interface Transceiver { + id?: number; + part_number: string; + vendor_id: number; + form_factor_id?: number; + name?: string; + description?: string; + category?: string; + subcategory?: string; + data_rate?: number; + data_rate_unit?: DataRateUnit; + max_reach?: number; + reach_unit?: ReachUnit; + wavelength_nm?: number; + wavelength_rx?: number; + wavelengths?: number[]; + wavelength_band?: WavelengthBand; + tx_power_min?: number; + tx_power_max?: number; + rx_sensitivity?: number; + link_budget_db?: number; + connector?: ConnectorType; + fiber_type?: FiberType; + duplex?: boolean; + breakout?: string; + temp_range?: TemperatureRange; + temp_min_c?: number; + temp_max_c?: number; + power_consumption_w?: number; + dom_support?: DOMType; + oem_part_number?: string; + oem_vendor_id?: number; + status?: TransceiverStatus; + release_date?: string; + eol_date?: string; + image_url?: string; + datasheet_url?: string; + product_url?: string; + tags?: string[]; + raw_specs?: Record; + source?: string; + source_url?: string; +} + +export interface NetworkDevice { + id?: number; + vendor_id: number; + model: string; + series?: string; + device_type?: string; + ports_sfp?: number; + ports_sfp_plus?: number; + ports_sfp28?: number; + ports_qsfp_plus?: number; + ports_qsfp28?: number; + ports_qsfp_dd?: number; + ports_osfp?: number; + ports_cfp?: number; + ports_rj45?: number; + max_throughput?: string; + release_year?: number; + eol_date?: string; + status?: string; + image_url?: string; + product_url?: string; + manual_url?: string; +} + +export interface Price { + time?: string; + transceiver_id: number; + vendor_id: number; + price: number; + currency?: PriceCurrency; + price_usd?: number; + quantity_min?: number; + quantity_max?: number; + in_stock?: boolean; + stock_quantity?: number; + lead_time_days?: number; + condition?: string; + url?: string; + source?: string; +} + +export interface CrawlerConfig { + name: string; + baseUrl: string; + interval: number; + maxConcurrency: number; + maxRequestsPerMinute: number; + usePlaywright: boolean; +} diff --git a/src/utils/db.ts b/src/utils/db.ts new file mode 100644 index 0000000..bd34d42 --- /dev/null +++ b/src/utils/db.ts @@ -0,0 +1,88 @@ +import pg from 'pg'; +import { pino } from 'pino'; + +const log = pino({ name: 'db' }); + +const pool = new pg.Pool({ + connectionString: process.env.DATABASE_URL, + max: 20, + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 5000, +}); + +pool.on('error', (err) => { + log.error({ err }, 'Unexpected pool error'); +}); + +export async function query( + text: string, + params?: unknown[] +): Promise> { + const start = Date.now(); + const result = await pool.query(text, params); + const duration = Date.now() - start; + if (duration > 1000) { + log.warn({ text: text.slice(0, 100), duration, rows: result.rowCount }, 'Slow query'); + } + return result; +} + +export async function getClient() { + return pool.connect(); +} + +export async function transaction(fn: (client: pg.PoolClient) => Promise): Promise { + const client = await pool.connect(); + try { + await client.query('BEGIN'); + const result = await fn(client); + await client.query('COMMIT'); + return result; + } catch (e) { + await client.query('ROLLBACK'); + throw e; + } finally { + client.release(); + } +} + +export async function batchInsert( + table: string, + columns: string[], + rows: unknown[][], + onConflict?: string +): Promise { + if (rows.length === 0) return 0; + + const client = await pool.connect(); + try { + await client.query('BEGIN'); + let inserted = 0; + const batchSize = 100; + + for (let i = 0; i < rows.length; i += batchSize) { + const batch = rows.slice(i, i + batchSize); + const placeholders = batch.map((row, ri) => + `(${row.map((_, ci) => `$${ri * row.length + ci + 1}`).join(', ')})` + ).join(', '); + + const values = batch.flat(); + const conflict = onConflict ? ` ON CONFLICT ${onConflict}` : ''; + const sql = `INSERT INTO ${table} (${columns.join(', ')}) VALUES ${placeholders}${conflict}`; + + const result = await client.query(sql, values); + inserted += result.rowCount ?? 0; + } + + await client.query('COMMIT'); + return inserted; + } catch (e) { + await client.query('ROLLBACK'); + throw e; + } finally { + client.release(); + } +} + +export { pool }; +export default { query, getClient, transaction, batchInsert, pool }; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8819aee --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "lib": ["ES2022"], + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": false, + "noUnusedParameters": false + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist", "test"] +}