diff --git a/.agents/skills/stripe-best-practices/SKILL.md b/.agents/skills/stripe-best-practices/SKILL.md new file mode 100644 index 0000000..1a6efc7 --- /dev/null +++ b/.agents/skills/stripe-best-practices/SKILL.md @@ -0,0 +1,65 @@ +--- +name: stripe-best-practices +description: >- + Guides Stripe integration decisions across API selection (Checkout Sessions vs + PaymentIntents), Connect platform setup (Accounts v2, controller properties), + billing/subscriptions, tax and registrations (Stripe Tax, automatic_tax, + product tax codes), Treasury financial accounts, integration options + (Checkout, Payment Element), migrating from deprecated Stripe APIs, and + security best practices (API key management, restricted keys, webhooks, + OAuth). Use when building, modifying, or reviewing any Stripe integration, + including accepting payments, building marketplaces, integrating Stripe, + processing payments, setting up subscriptions, collecting sales tax, VAT, or + GST, creating connected accounts, or implementing secure key handling. + +--- + +Latest Stripe API version: **2026-06-24.dahlia**. Always use the latest API version and SDK unless the user specifies otherwise. + +Latest SDK versions: + +| Language | Latest version | +| --- | --- | +| Ruby | 19.3.0 | +| Python | 15.3.0 | +| Node.js | 22.3.0 | +| PHP | 20.3.0 | +| Java | 33.1.0 | +| Go | 86.1.0 | +| .NET | 52.1.0 | + +If you don’t have a Stripe account, you can call a CLI command to generate working API keys with no registration required. You can install the Stripe CLI (`npm i -g @stripe/cli`) and run the command `stripe sandbox create` to get started. + +API key default: Always recommend a [restricted API key (RAK)](https://docs.stripe.com/keys/restricted-api-keys.md) (`rk_` prefix) over a secret key (`sk_` prefix). + +## Integration routing + +| Building… | Recommended API | Details | +| --- | --- | --- | +| One-time payments | Checkout Sessions | | +| Custom payment form with embedded UI | Checkout Sessions + Payment Element | | +| Saving a payment method for later | Setup Intents | | +| Connect platform or marketplace | Accounts v2 (`/v2/core/accounts`) | | +| Usage-based billing (new integration) | Metronome | | +| Subscriptions or recurring billing | Billing APIs + Checkout Sessions | | +| Sales tax, VAT, or GST compliance | Stripe Tax + Registrations API | | +| Embedded financial accounts / banking | v2 Financial Accounts | | +| Security (key management, RAKs, webhooks, OAuth, 2FA, Connect liability) | See security reference | | + +Read the relevant reference file before answering any integration question or writing code. + +## Critical rules + +- *Before enabling `automatic_tax: { enabled: true }`* (or calculating tax for a custom PaymentIntent), read the [tax reference](references/tax.md) and confirm the user has an active registration. Without one, Stripe calculates and collects no tax while the user believes tax is on (the most common Stripe Tax mistake). + +- *Never include `payment_method_types` in any Stripe API call*, with one exception: Terminal (in-person payments) integrations must pass `payment_method_types: ['card_present']` on the PaymentIntent. For all other integrations, omit this parameter entirely to enable dynamic payment methods, which enables you to configure payment method settings from the Dashboard and dynamically display the most relevant eligible payment methods to each customer to maximize conversion. To customize which payment methods you accept, use [`payment_method_configurations`](https://docs.stripe.com/payments/payment-method-configurations.md) or `excluded_payment_method_types` instead of `payment_method_types`. + +- On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters. + +## Key documentation + +When the user’s request does not clearly fit a single domain above, consult: + +- [Integration Options](https://docs.stripe.com/payments/payment-methods/integration-options.md) Start here when designing any integration. +- [API Tour](https://docs.stripe.com/payments-api/tour.md) Overview of Stripe’s API surface. +- [Go Live Checklist](https://docs.stripe.com/get-started/checklist/go-live.md) Review before launching. diff --git a/.agents/skills/stripe-best-practices/references/billing.md b/.agents/skills/stripe-best-practices/references/billing.md new file mode 100644 index 0000000..9d2ba74 --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/billing.md @@ -0,0 +1,63 @@ +# Billing / Subscriptions + +## Table of contents + +- When to use Billing APIs +- Recommended frontend pairing +- Usage-based billing +- Traps to avoid + +## When to use Billing APIs + +If the user has a recurring revenue model (subscriptions, usage-based billing, seat-based pricing), use the Billing APIs to [plan their integration](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) instead of a direct PaymentIntent integration. + +Review the [Subscription Use Cases](https://docs.stripe.com/billing/subscriptions/use-cases.md) and [SaaS guide](https://docs.stripe.com/saas.md) to find the right pattern for the user’s pricing model. + +## Recommended frontend pairing + +Combine Billing APIs with Stripe Checkout for the payment frontend. Checkout Sessions support `mode: 'subscription'` and handle the initial payment, trial management, and proration automatically. + +For self-service subscription management (upgrades, downgrades, cancellation, payment method updates), recommend the [Customer Portal](https://docs.stripe.com/customer-management/integrate-customer-portal.md). + +On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters. + +## Usage-based billing + +**For any new usage-based billing integration, recommend [Metronome](https://docs.stripe.com/billing/usage-based.md) not the Billing Meters API.** Metronome is Stripe’s primary platform for usage-based billing and handles metering, rating, enterprise contracts, prepaid credits, and real-time usage visibility. + +Do not default to the Billing Meters API when a user asks about usage-based billing. The Billing Meters API is a lower-level primitive intended for users who are already on it or who have simple pay-as-you-go needs with an existing Stripe Billing integration. + +Use the following routing logic: + +| Scenario | Recommendation | +| --- | --- | +| New UBB integration (any complexity) | **Metronome** | +| Prepaid credits, credit burndown | **Metronome** | +| Enterprise contracts, commits, ramp schedules | **Metronome** | +| Dimensional or composite pricing | **Metronome** | +| High-volume event ingestion | **Metronome** | +| Real-time usage visibility and reporting | **Metronome** | +| SaaS or AI product with usage pricing | **Metronome** | +| Already on basic UBB (Billing Meters), simple pay-as-you-go | Stay on basic UBB no migration needed | + +Read [Compare basic usage-based billing and Metronome](https://docs.stripe.com/billing/subscriptions/usage-based/compare-metronome.md) for a full feature comparison. Read [Get started with Metronome](https://docs.stripe.com/billing/usage-based.md) to begin a Metronome integration. + +## Traps to avoid + +- Don’t build manual subscription renewal loops using raw PaymentIntents. Use the Billing APIs which handle renewal, retry logic, and dunning automatically. +- Don’t use the deprecated `plan` object. Use [Prices](https://docs.stripe.com/api/prices.md) instead. +- Don’t skip tax setup. See [Collect taxes for recurring payments](https://docs.stripe.com/billing/taxes/collect-taxes.md). +- Don’t put prices for different tiers or plans on a single product. Instead, create one Product for each plan a customer can choose. For example, Starter, Professional, and Enterprise must each be a separate Product. Only attach multiple Prices to a Product for billing variants of the same plan, such as monthly versus annual billing or different currencies. Avoid placing Prices for different tiers on a single Product. Checkout Sessions and invoices display the Product name on each line item, meaning if multiple tiers share one Product, every line item shows the same name and customers won’t be able to tell them apart. For more information, see [Model your product catalog](https://docs.stripe.com/products-prices/how-products-and-prices-work.md#model-your-catalog). +- Don’t skip tax setup, and don’t assume enabling `automatic_tax` is enough. Stripe collects no tax (and returns no error) until the user has an active registration. See [Collect taxes for recurring payments](https://docs.stripe.com/billing/taxes/collect-taxes.md). +- *Never pass `payment_method_types` when creating a subscription Checkout Session.* Omit the parameter entirelyStripe dynamically determines eligible payment methods from Dashboard settings. Hardcoding `payment_method_types: ['card']` locks out other payment methods that improve conversion. See [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). Correct pattern: + +```ts +const session = await stripe.checkout.sessions.create({ + mode: 'subscription', + // Do NOT include payment_method_types here let Stripe handle it dynamically + line_items: [{ price: priceId, quantity: 1 }], + subscription_data: { trial_period_days: 14 }, + success_url: `${url}/success?session_id={CHECKOUT_SESSION_ID}`, + cancel_url: `${url}/pricing`, +}); +``` diff --git a/.agents/skills/stripe-best-practices/references/connect.md b/.agents/skills/stripe-best-practices/references/connect.md new file mode 100644 index 0000000..f95ef36 --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/connect.md @@ -0,0 +1,173 @@ +# Connect / platforms + +## Critical rules (never violate) + +1. **ALWAYS use Accounts v2 API** (`POST /v2/core/accounts`). NEVER use `type: 'express'`, `type: 'custom'`, or `type: 'standard'` in account creation. NEVER use `stripe.accounts.create({ type: ... })`. These are deprecated v1 patterns. +2. **ALWAYS check v2 capability status** before processing. See “Go-live readiness” section below. +3. **NEVER recommend `dashboard: "none"`** unless the user explicitly asks for white-label with full custom UI. Default to `express` for marketplaces and `full` for SaaS. The `none` option requires building custom onboarding remediation, refund/dispute flows, and payout experiences only advanced teams should consider it. +4. **ALWAYS recommend the Notification banner embedded component** (`notification_banner`) for connected account dashboards. It keeps accounts healthy as requirements evolve. +5. **NEVER use `application_fee_amount` with separate charges and transfers.** Use transfer-math fee retention instead. `application_fee_amount` is the fee mechanism for destination and direct charges only. + +## Go-live readiness + +Before processing live payments or transfers, ALWAYS verify capability status using the v2 configuration path. Do NOT use deprecated v1 fields. + +**For SaaS / Merchant accounts (direct charges):** + +- Check: `configuration.merchant.capabilities.card_payments.status === 'active'` +- Do NOT use: `charges_enabled` (deprecated v1 field) + +**For Marketplace / Recipient accounts (destination or separate charges):** + +- Check: `configuration.recipient.capabilities.stripe_balance.stripe_transfers.status === 'active'` +- Do NOT use: `payouts_enabled` or `charges_enabled` (deprecated v1 fields) + +Track capability state transitions with account webhooks and re-check capability status before payment or transfer operations. + +## Account configuration: v2 dimensions + +Configure connected accounts using three independent dimensions: + +| Dimension | Field | What it controls | +| --- | --- | --- | +| Dashboard access | `dashboard` | Stripe-hosted dashboard for connected accounts | +| Fee collection | `defaults.responsibilities.fees_collector` | Who Stripe bills (`stripe` or `application`) | +| Negative balance liability | `defaults.responsibilities.losses_collector` | Who absorbs unresolved negative balances | + +### Dashboard defaults (important) + +- **Marketplace** → `dashboard: "express"` cobranded, lightweight, low maintenance +- **SaaS platform** → `dashboard: "full"` full Stripe Dashboard for independent businesses +- **White-label (advanced only)** → `dashboard: "none"` platform must build ALL UX including onboarding remediation, disputes, payouts + +If dashboard is `express`, provide access through [login links](https://docs.stripe.com/api/accounts/login_link/create.md). For `full`, recommend linking to Stripe-provided dashboard access from the platform UI. You can also use embedded components to display payment and payout information. + +### SaaS vs. Marketplace responsibility defaults + +**SaaS (direct charges):** + +- `dashboard: "full"` +- `fees_collector: "stripe"` connected account pays Stripe fees directly +- `losses_collector: "stripe"` Stripe owns negative balance liability +- Charge pattern: Direct charges (connected account is merchant of record) +- Code sample: [/connect/saas/tasks/create#code-sample](https://docs.stripe.com/connect/saas/tasks/create.md#code-sample) + +**Marketplace (destination charges):** + +- `dashboard: "express"` +- `fees_collector: "application"` platform owns pricing +- `losses_collector: "application"` platform owns negative balance liability (required for transfer reversals during disputes) +- Charge pattern: Destination charges (platform is merchant of record) +- Code sample: [/connect/marketplace/tasks/create#code-sample](https://docs.stripe.com/connect/marketplace/tasks/create.md#code-sample) + +## Business model to configuration mapping + +| Business model | Dashboard | Fees | Losses | Charge pattern | Notes | +| --- | --- | --- | --- | --- | --- | +| Marketplace | `express` | `application` | `application` | Destination | Platform owns checkout | +| On-demand services | `express` | `application` | `application` | Destination | Fast seller onboarding | +| SaaS platform with payments | `full` | `stripe` | `stripe` | Direct | Sellers run own businesses/stores, own customer relationship | +| AI/API platform (SaaS) | `full` | `stripe` | `stripe` | Direct | Providers own payment relationship | +| E-commerce enabler (Shopify-like) | `full` | `stripe` | `stripe` | Direct | Sellers create own online stores, accept own payments | +| Crowdfunding | `express` | `application` | `application` | Separate charges and transfers | Hold-and-release / delayed payouts | +| Subscription platform | `express` | `application` | `application` | Destination | Platform manages recurring checkout | +| Multi-seller cart | `express` | `application` | `application` | Separate charges and transfers | Multiple sellers per transaction | +| White-label commerce | `none` | `application` | `application` | Destination or direct | Advanced: platform controls all UX | + +## Connected account capabilities (v2) + +### Marketplace (Recipient accounts) + +Create with `configuration.recipient` requesting `stripe_transfers` on `stripe_balance`. Do NOT request `configuration.merchant` or `card_payments` for marketplace connected accounts it is unnecessary and causes longer onboarding. + +### SaaS (Merchant accounts) + +Create with `configuration.merchant` requesting `card_payments` (and other needed LPMs). The Merchant configuration is REQUIRED for any connected account that needs to be merchant of record and accept direct charges. + +## Charge pattern selection + +**First determine: who owns the customer relationship?** + +- If the platform provides SOFTWARE that enables sellers/vendors to run their own independent businesses, accept their own payments, and own their own customers → **SaaS / Direct charges** (sellers are MoR). Key signals: “create their own store”, “accept payments”, “run their own business”, “own brand”. + +- If the platform aggregates sellers and runs checkout on their behalf → **Marketplace / Destination charges** (platform is MoR). Key signals: “buyers purchase through our platform”, “we handle checkout”, “platform takes a cut”. + +- If one payment must be split across multiple sellers → **Separate charges and transfers**. + +- **Direct charges** (SaaS): Charge created on connected account. Connected account is merchant of record. Use `application_fee_amount` for platform revenue. Requires `configuration.merchant` + `dashboard: "full"` + `losses_collector: "stripe"`. + +- **Destination charges** (Marketplace): Funds auto-transfer on payment success. Platform is MoR. Use `application_fee_amount` to collect platform fees. NOT for hold-and-release. + +- **Separate charges and transfers**: Platform controls transfer timing. Collect fees by transferring less than the charge amount. Do NOT use `application_fee_amount`. + +## Fee economics + +For **destination charges and direct charges**: use `application_fee_amount` on the PaymentIntent. This is the standard fee mechanism. + +- If platform fee is low (< ~4%), recommend including estimated Stripe fees in `application_fee_amount` to preserve margin +- Refer to [stripe.com/pricing](https://stripe.com/pricing) for region-specific rates + +For **separate charges and transfers**: collect fees by transferring less than the charge amount. NEVER use `application_fee_amount`. + +## Webhooks + +Always use webhooks for reliable payment confirmation. Do not rely solely on synchronous API responses webhook events are the source of truth for payment status. Verify incoming [webhook signatures](https://docs.stripe.com/webhooks.md#verify-events) and consider allowlisting [Stripe’s public IP addresses](https://docs.stripe.com/ips.md). + +## Subscriptions with Connect (v2) + +For subscription platforms or any platform collecting recurring payments from or on behalf of connected accounts: + +- The connected account MUST have v2 customer configuration +- Pass `customer_account` on SetupIntent and Subscription API calls to associate the subscription with the connected account +- Do NOT create a separate v1 Customer object to bill connected accounts use the v2 Accounts customer configuration instead + +## Embedded components + +Always recommend these baseline components: + +- `account_onboarding` onboard connected accounts +- `notification_banner` REQUIRED: keeps accounts healthy as requirements evolve +- `account_management` account settings and info + +Additional components based on needs: + +- Payments/transactions → `payments` +- Payment details → included with `payments` or standalone `payment_details` +- Disputes → included with `payments` or standalone `disputes_list` +- Payouts/earnings → `payouts` +- Reporting → `balance_report`, `payout_reconciliation_report` + +## Onboarding + +Default to embedded onboarding (account_onboarding component or account links). Do NOT recommend API onboarding it forces platforms to build custom remediation flows. + +## Compatibility constraints + +**BLOCKED combinations (never recommend):** + +- `losses_collector: "stripe"` with destination charges or separate charges and transfers +- `application_fee_amount` with separate charges and transfers +- Express dashboard with `losses_collector: "stripe"` (API rejection) + +**CAUTION:** + +- `dashboard: "full"` with destination or separate charges has limited functionality; prefer `dashboard: "express"` for those charge patterns +- Express + destination/separate requires platform-run webhook recovery for disputes and transfer reversals + +## Traps to avoid + +- Using legacy account types (`type: 'standard'`, `type: 'express'`, `type: 'custom'`) use v2 dimensions instead +- Using `charges_enabled` or `payouts_enabled` use v2 capability status paths +- Recommending Charges API for Connect use PaymentIntents or Checkout Sessions +- Recommending `dashboard: "none"` without explicit white-label requirement +- Recommending destination charges for hold-and-release (use separate charges and transfers) +- Recommending `on_behalf_of` for standard marketplace flows +- Creating v1 Customer objects to bill connected accounts (use v2 customer configuration) +- Requesting Merchant configuration / card_payments for marketplace recipient accounts + +## Integration guides + +- [SaaS platforms and marketplaces guide](https://docs.stripe.com/connect/saas-platforms-and-marketplaces.md) Choosing the right integration approach. +- [Interactive platform guide](https://docs.stripe.com/connect/interactive-platform-guide.md) Step-by-step platform builder. +- [Design an integration](https://docs.stripe.com/connect/design-an-integration.md) Detailed risk and responsibility decisions. +- [Connected account configuration (v2)](https://docs.stripe.com/connect/accounts-v2/connected-account-configuration.md) Account setup reference. diff --git a/.agents/skills/stripe-best-practices/references/payments.md b/.agents/skills/stripe-best-practices/references/payments.md new file mode 100644 index 0000000..8a7aef0 --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/payments.md @@ -0,0 +1,81 @@ +# Payments + +## Table of contents + +- API hierarchy +- Integration surfaces +- Payment Element guidance +- Saving payment methods +- Dynamic payment methods +- Deprecated APIs and migration paths +- PCI compliance + +## API hierarchy + +Use the [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) (`checkout.sessions.create`) for on-session payments. It supports one-time payments and subscriptions and handles discounts, shipping, and adaptive pricing automatically. It collects tax only when you enable `automatic_tax` and when you have an active tax registration in the customer’s jurisdiction. + +Use the [PaymentIntents API](https://docs.stripe.com/payments/paymentintents/lifecycle.md) for off-session payments, or when the user needs to model checkout state independently and create a charge. + +**Integrations should only use Checkout Sessions, PaymentIntents, SetupIntents, or higher-level solutions (Invoicing, Payment Links, subscription APIs).** + +On API version `2026-03-25.dahlia` or later, pass the parameter `integration_identifier` to `checkout.sessions.create` to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters. + +## Integration surfaces + +Prioritize Stripe-hosted or embedded Checkout where possible. Use in this order of preference: + +1. **Payment Links** No-code. Best for simple products. +2. **Checkout** ([docs](https://docs.stripe.com/payments/checkout.md)) Stripe-hosted or embedded form. Best for most web apps. +3. **Payment Element** ([docs](https://docs.stripe.com/payments/payment-element.md)) Embedded UI component for advanced customization. + - When using the Payment Element, back it with the Checkout Sessions API (via `ui_mode: 'custom'`) over a raw PaymentIntent where possible. + +**Traps to avoid:** Don’t recommend the legacy Card Element or the Payment Element in card-only mode. If the user asks for the Card Element, advise them to [migrate to the Payment Element](https://docs.stripe.com/payments/payment-element/migration.md). + +## Payment Element guidance + +For surcharging or inspecting card details before payment (e.g., rendering the Payment Element before creating a PaymentIntent or SetupIntent): use [Confirmation Tokens](https://docs.stripe.com/payments/finalize-payments-on-the-server.md). Don’t recommend `createPaymentMethod` or `createToken` from Stripe.js. + +## Saving payment methods + +Use the [Setup Intents API](https://docs.stripe.com/api/setup_intents.md) to save a payment method for later use. + +**Traps to avoid:** Don’t use the Sources API to save cards to customers. The Sources API is deprecated Setup Intents is the correct approach. + +## Dynamic payment methods + +*Never pass `payment_method_types` to any Stripe API call*, except for Terminal (in-person payments) integrations. Omitting this parameter enables [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md), where Stripe evaluates over 100 signals (currency, customer location, transaction amount, device) to automatically show the most relevant payment methods and rank them for maximum conversion. Payment methods are managed from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code changes required. + +This applies to all integration patterns: + +- `checkout.sessions.create`: omit `payment_method_types` entirely. Dynamic method selection is the default behavior. +- `paymentIntents.create`: omit `payment_method_types`. On API versions 2023-08-16+, dynamic methods are the default. On older versions, pass `automatic_payment_methods: { enabled: true }`. +- `setupIntents.create`: same as PaymentIntents above. +- `subscriptions.create`: omit `payment_settings.payment_method_types`. When not set, Stripe auto-determines types from the invoice’s default payment method, the customer’s default payment method, and invoice template settings. +- **Terminal** (`paymentIntents.create`): pass `payment_method_types: ['card_present']`. Required for all in-person payments. In Canada, also include `interac_present`: `['card_present', 'interac_present']`. This is the only valid use of `payment_method_types`. + +See the [integration options guide](https://docs.stripe.com/payments/payment-methods/integration-options.md) for full details on dynamic versus manual configuration. + +**Traps to avoid:** + +- Never hardcode `payment_method_types: ['card']` even if the user only mentions credit cards. Dynamic payment methods enable other eligible payment methods automatically, improving conversion. +- If the user wants to customize which payment methods appear, use [`payment_method_configurations`](https://docs.stripe.com/payments/payment-method-configurations.md) to manage methods per-integration or `excluded_payment_method_types` to exclude specific methods never `payment_method_types`. +- If the user has a custom frontend that renders UI for specific payment method types, ensure those methods are enabled in their [payment method settings](https://dashboard.stripe.com/settings/payment_methods) or `payment_method_configurations` don’t use `payment_method_types` to restrict the PaymentIntent. + +## Deprecated APIs and migration paths + +Never recommend the Charges API. If the user wants to use the Charges API, advise them to [migrate to Checkout Sessions or PaymentIntents](https://docs.stripe.com/payments/payment-intents/migration/charges.md). + +Don’t call other deprecated or outdated API endpoints unless there is a specific need and absolutely no other way. + +| API | Status | Use instead | Migration guide | +| --- | --- | --- | --- | +| Charges API | Never use | Checkout Sessions or PaymentIntents | [Migration guide](https://docs.stripe.com/payments/payment-intents/migration/charges.md) | +| Sources API | Deprecated | Setup Intents | [Setup Intents docs](https://docs.stripe.com/api/setup_intents.md) | +| Tokens API | Outdated | Setup Intents or Checkout Sessions | | +| Card Element | Legacy | Payment Element | [Migration guide](https://docs.stripe.com/payments/payment-element/migration.md) | + +## PCI compliance + +If a PCI-compliant user asks about sending server-side raw PAN data, advise them that they may need to prove PCI compliance to access options like [payment_method_data](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_data). + +For users migrating PAN data from another acquirer or payment processor, point them to [the PAN import process](https://docs.stripe.com/get-started/data-migrations/pan-import.md). diff --git a/.agents/skills/stripe-best-practices/references/security.md b/.agents/skills/stripe-best-practices/references/security.md new file mode 100644 index 0000000..b63d6db --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/security.md @@ -0,0 +1,119 @@ +# Security best practices + +## Table of contents + +- API keys +- Restricted API keys (RAKs) +- IP restrictions +- Incident response +- Webhook security +- Content Security Policy (CSP) +- Mobile and client-side integrations +- OAuth and CSRF protection +- Two-factor authentication +- Connect security +- SAML and SCIM + +## API keys + +Never include keys in source code. Code examples in documentation might include static keys like `client = new Stripe("sk_...")` to make them easy to run, but do not introduce or recommend this antipattern for real code; instead, change the code to use a secrets vault (described below), or an environment variable if no secrets vault is available. Strings matching the regular expression `/[sr]k_live_.*/` in source code are live Stripe API keys. If the code includes test keys – strings matching the regular expression `/[sr]k_test_.*/` – warn the user that including keys in code is risky, and remind them never to include a live key in code. Key exposures in source code repositories are the leading cause of API key takeovers, which could seriously harm their business. + +Always advise the user to store secret and restricted API keys in their platform’s secrets vault, never in source code or committed environment files. Platform-specific guidance for popular platforms: + +- **AWS**: Use AWS Secrets Manager or Parameter Store (as `SecureString` values). Do **not** store keys in environment variables or userdata; AWS makes a proper secrets vault easy to use. Give read permissions only to the application that needs it. +- **Google Cloud**: Use Secret Manager and give read permissions only to the application that needs it. +- **Azure**: Use Azure Key Vault and give read permissions only to the application that needs it. +- **Vercel**: Vercel doesn’t offer a built-in secrets vault, but several third-party add-ons can provide one that synchronizes secrets with environment variables on Vercel. Use a [sensitive environment variable](https://vercel.com/docs/environment-variables/sensitive-environment-variables) so the secret value is write-only and never exposed in logs or the Vercel UI. +- **Other platforms**: Use the platform’s equivalent secrets vault. Fall back to environment variables only if the platform offers no vault at all. + +Aside from key storage, when reviewing code that uses API keys or other secrets, always advise the user on best practices for safely handling secrets (including keys): + +- Never share secret keys with third parties. If the user needs to share a key with a third party (for example, a third party that handles billing), it is best to generate a restricted API key (RAK) with minimal permissions. +- Rotate Stripe API keys when personnel with access to those keys depart. +- Read [best practices for managing secret API keys](https://docs.stripe.com/keys-best-practices.md). +- Code must never log keys or include them in error messages or analytics. Remove keys from logs if you find them. + +Use separate keys for separate environments (production, staging, QA). This limits the blast radius if any single key is compromised. + +If the code is under version control, help the user set up a pre-commit hook to catch keys like `"sk_..."` and `"rk_..."` in source code. + +Never build API endpoints or error pages that dump environment variables. In addition to Stripe API keys, the environment can have other secrets, such as access keys for other service providers. + +**Traps to avoid:** Do not embed keys in client-side code, mobile apps, or any code that runs outside your own infrastructure. Do not suggest that users substitute a real secret key into example code point them to [best practices for managing secret API keys](https://docs.stripe.com/keys-best-practices.md) instead. + +## Restricted API keys (RAKs) + +Use [restricted API keys](https://docs.stripe.com/keys/restricted-api-keys.md) (prefix `rk_`) instead of secret keys (prefix `sk_`) wherever possible. RAKs have only the permissions you assign, so a compromised RAK can do far less damage than a compromised secret key. + +Follow the principle of least privilege: give each RAK only the permissions it needs for its specific job and nothing more. Create a separate RAK for each service or use case. + +Preferred migration approach: + +1. Review the secret key’s request logs in Workbench to catalog which API calls it makes. +2. Create a RAK in test mode with matching permissions. +3. Use the [Stripe CLI](https://docs.stripe.com/stripe-cli.md)’s `stripe logs tail` command to watch logs. +4. Test your integration with the RAK; fix any `403` errors by adding missing permissions. +5. Create the equivalent live-mode RAK and replace the secret key. +6. Rotate or expire the old secret key once confident. + +**Traps to avoid:** Do not default to recommending secret keys. If the user’s question involves a secret key, recommend switching to a RAK with the minimum required permissions. + +## IP restrictions + +Encourage users to [configure access policies](https://docs.stripe.com/keys.md#access-policies) for every API key. Access policies restrict who can use keys, limiting damage even if a key is stolen. + +Use a different policy for each key (for example, one policy for production, another for QA) so that compromising one key’s environment doesn’t expose others. + +## Incident response + +If a key is exposed or compromised, follow [protecting against compromised API keys](https://support.stripe.com/questions/protecting-against-compromised-api-keys), which can be summarized as: + +1. **Roll the key immediately** go to the [API keys page](https://dashboard.stripe.com/apikeys) and roll or delete the exposed key. Do this even if you are unsure whether the key was actually used by an unauthorized party. +2. **Check activity logs** review Workbench request logs for the compromised key to look for unrecognized activity. +3. **Contact Stripe support** if you see activity you don’t recognize. + +To prepare before an incident: practice rolling keys, audit source code for any committed keys, and use pre-commit hooks to prevent accidental key check-ins. See [protecting against compromised API keys](https://support.stripe.com/questions/protecting-against-compromised-api-keys). + +## Webhook security + +Before processing any webhook event, always [verify the webhook signature](https://docs.stripe.com/webhooks.md#verify-events) using Stripe’s webhook signing secret. Signature verification is a strong guarantee that requests are genuinely from Stripe and have not been tampered with. Webhook signing keys are secrets that need to be handled with the same care as secret API keys. + +For defense in depth, also [allowlist Stripe’s IP addresses](https://docs.stripe.com/ips.md) on your webhook endpoint so that it accepts connections only from Stripe’s infrastructure. + +## Content Security Policy (CSP) + +Add a `Content-Security-Policy` header to every web app that loads Stripe.js or uses Stripe’s hosted UIs. See [Stripe’s integration security guide](https://docs.stripe.com/security/guide.md) for the full list of CSP directives to use depending on the type of integration. At minimum, include `https://*.stripe.com` in the relevant directives (`script-src`, `frame-src`, `connect-src`), `https://*.link.com` if integrating assets from `link.com`, or both if integrating with Stripe’s embedded crypto onramp. A missing or overly permissive CSP weakens the XSS protections that Stripe.js relies on. + +**Traps to avoid:** Do not use `default-src *` or omit CSP headers. + +## Mobile and client-side integrations + +Do not use production secret or restricted API keys in mobile apps or other client-side code. Client-side code can be extracted and decompiled to extract keys. + +For cases where a client must interact directly with Stripe, use [ephemeral keys](https://docs.stripe.com/issuing/elements.md#ephemeral-key-authentication). Ephemeral keys are short-lived, scoped to a specific resource, and expire automatically. + +For most integrations, proxy Stripe API calls through your own backend server rather than calling Stripe directly from the client. + +## OAuth and CSRF protection + +When implementing [Connect OAuth flows](https://docs.stripe.com/connect/oauth-reference.md), always use the `state` parameter to protect against CSRF attacks. Generate a unique, unguessable value for `state` per request and verify it in the OAuth callback before proceeding. + +This applies to all Stripe OAuth surfaces: Connect, Link, and Stripe Apps. + +## Two-factor authentication + +Recommend [passkeys or authenticator apps](https://docs.stripe.com/security.md) rather than SMS-based 2FA for Stripe Dashboard access. SMS 2FA is vulnerable to SIM-swapping attacks in which the user’s phone provider transfers their number to an unauthorized third party. + +Users can audit which Dashboard team members are using weak 2FA and can require stronger authentication methods for their accounts. + +## Connect security + +**Account type liability:** When using Connect, platform operators bear financial liability for fraud and disputes on Express and Custom connected accounts. Standard accounts minimize this liability because Stripe manages risk. Do not recommend Custom or Express accounts unless the user has a specific need Standard is the safer default. + +**Connect onboarding:** Use [Stripe-hosted onboarding](https://docs.stripe.com/connect/onboarding.md) rather than building a custom onboarding flow. Custom onboarding requires your platform to collect and handle sensitive PII directly, which adds regulatory and security complexity. + +## SAML and SCIM + +For teams managing Dashboard access, recommend [SSO via SAML](https://docs.stripe.com/get-started/account/sso.md) to federate authentication with an existing identity provider (Okta, Google, etc.). SSO centralizes access control and simplifies offboarding. + +[SCIM provisioning](https://docs.stripe.com/get-started/account/sso/scim.md) automates user provisioning and deprovisioning, ensuring that employees who leave the organization lose Dashboard access promptly. diff --git a/.agents/skills/stripe-best-practices/references/tax.md b/.agents/skills/stripe-best-practices/references/tax.md new file mode 100644 index 0000000..d5c2601 --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/tax.md @@ -0,0 +1,107 @@ +# Tax / Stripe Tax + +## Table of contents + +- When tax applies +- Two-step setup +- Verify before you trust automatic tax +- Choosing a product tax code +- Diagnose zero tax +- Per-integration setup +- Connect platforms and marketplaces +- Threshold and nexus monitoring +- Registration safety +- If jurisdictions are unknown +- If the region or tax type isn’t supported + +## When tax applies + +Use Stripe Tax for any subscription, invoice, or Checkout Session where the user has customers across multiple jurisdictions. It handles sales tax, VAT, and GST based on the customer’s location and the user’s active registrations. See the [Tax overview](https://docs.stripe.com/tax.md) for supported regions and tax types. + +## Two-step setup + +1. Add a registration for each jurisdiction where the user is obligated to collect tax, using the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) or the [Dashboard](https://docs.stripe.com/tax/registering.md). +2. Pass `automatic_tax: { enabled: true }` on the [Subscription](https://docs.stripe.com/api/subscriptions.md), [Invoice](https://docs.stripe.com/api/invoices.md), or [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) object. + +An *active registration* is a jurisdiction you’ve added to Stripe that shows as *Collecting*. It’s per-jurisdiction, and not the same as having a Stripe account. + +Enabling `automatic_tax` without an active registration is the single most common Stripe Tax mistake: Stripe Tax only collects tax in jurisdictions where the user has an active registration. Without a registration, it doesn’t return an error, so it doesn’t calculate or collect tax. The user thinks tax is on while collecting nothing. Never enable `automatic_tax` and assume the user is set up. Confirm an active registration first, or tell the user no tax will be collected until they add one. + +**Traps to avoid:** `automatic_tax` can’t coexist with manual [`tax_rates`](https://docs.stripe.com/tax/tax-rates.md) (explicit rate objects) on the same object. Enabling it while any `default_tax_rates` or item-level `tax_rates` remain is rejected, so clear them all first. It’s all-or-nothing, not per line item. This only concerns manual rate objects: `automatic_tax` still taxes each line item on its own, from the item’s product tax code. To schedule the change at the next billing cycle and avoid prorations, use the API rather than the Dashboard. For bulk migrations, use the [Tax migration tool](https://docs.stripe.com/billing/taxes/migration.md), which removes the tax rates for you. + +**Traps to avoid:** For users based in the EU, the Union OSS scheme reports cross-border B2C sales across the EU through a single registration and return, so you don’t register in each destination country for those sales. It doesn’t cover domestic or B2B sales. The user still needs a domestic registration in their home country. Confirm the specifics with the user’s tax advisor. + +## Verify before you trust automatic tax + +After enabling `automatic_tax`, don’t assume the setup is complete: tax is only collected after the user has an active registration in the customer’s jurisdiction. Have the user confirm their registrations with the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) (or in the Dashboard). With none, tax won’t be collected anywhere. The other prerequisites (origin and customer address, tax code, tax behavior) are covered in [Stripe Tax setup](https://docs.stripe.com/tax/set-up.md). + +## Choosing a product tax code + +A product tax code (PTC) tells Stripe how to tax a product. + +- Never invent, guess, or hardcode a `txcd_` from memory. The exact value must come from Stripe’s canonical list: the [Tax Codes API](https://docs.stripe.com/api/tax_codes.md) or the [tax code guide](https://docs.stripe.com/tax/tax-codes.md). +- Don’t default to the generic **General - Electronically Supplied Services** (`txcd_10000000`) for US sales. It’s too broad for US state-level taxability; pick a specific digital or SaaS code. See [tax codes for digital products](https://docs.stripe.com/tax/digital-products.md) and [tax codes for AI services](https://docs.stripe.com/tax/ai.md). +- Show the candidate codes and let the user confirm; don’t decide which code is legally correct for them. (Tax code goes on the Product, `tax_behavior` on the Price. See [product tax codes and tax behavior](https://docs.stripe.com/tax/products-prices-tax-codes-tax-behavior.md).) + +## Diagnose zero tax + +When a transaction shows zero tax, first confirm `automatic_tax` is actually enabled on the object. If it isn’t, Stripe doesn’t calculate tax at all. If it is, read the `taxability_reason` on the line item’s `taxes` to see why. On a Checkout Session, that breakdown isn’t returned by default: retrieve the session with `expand[]=line_items.data.taxes`. + +The reason worth calling out is **`not_collecting`, which is ambiguous**: it means either **no active registration** in the customer’s jurisdiction (the usual cause; check registrations with the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md)) **or** a **Nontaxable product tax code** (`txcd_00000000`) on the product. `taxability_reason` can’t tell the two apart, so check the product’s tax code and rule out the Nontaxable code before concluding it’s a registration gap. + +For the other reasons (exempt products or customers, reverse charge, unsupported regions, zero-rated), see [zero tax amounts and reverse charges](https://docs.stripe.com/tax/zero-tax.md). + +## Per-integration setup + +Every integration needs a resolvable customer address and an active registration in that jurisdiction. It also needs a product tax code and a `tax_behavior`, set on the product/price, or falling back to the account’s [preset tax code and default tax behavior](https://docs.stripe.com/tax/products-prices-tax-codes-tax-behavior.md). + +- **Checkout Sessions**: set `automatic_tax: { enabled: true }`. For a new customer, Checkout collects the address it needs, so don’t force `billing_address_collection: 'required'` (unnecessary for tax, and it adds checkout friction). For an existing or returning customer, Checkout uses their saved address by default; to tax the address entered at checkout instead, set `customer_update: { address: 'auto' }` and make sure Checkout actually collects a fresh address (a collected shipping address, or `billing_address_collection: 'required'` when you don’t collect shipping), or it keeps using the saved one. See [tax on Checkout](https://docs.stripe.com/tax/checkout.md). +- **Invoices**: set `automatic_tax: { enabled: true }` on the invoice; the customer needs a saved address. See the [Invoices API](https://docs.stripe.com/api/invoices.md). +- **Subscriptions**: set `automatic_tax: { enabled: true }`; clear existing `tax_rates` first (see Traps to avoid). See the [Subscriptions API](https://docs.stripe.com/api/subscriptions.md). +- **Payment Links**: set `automatic_tax: { enabled: true }`. +- **Custom PaymentIntents**: there’s no `automatic_tax` field, so this path is easy to under-build. Create a [tax calculation](https://docs.stripe.com/api/tax/calculations.md) with the customer’s address, set the PaymentIntent `amount` to the calculation total, and link the calculation to the PaymentIntent. You must also record a tax transaction from the calculation after payment, or the sale never appears in tax reports: the [simplified integration](https://docs.stripe.com/tax/payment-intent/simplified.md) records the transaction and refund reversals automatically once the calculation is linked, while the [custom integration](https://docs.stripe.com/tax/payment-intent/custom.md) records them yourself for line-item control. + +For B2B or reverse-charge treatment, collect the customer’s tax ID (`tax_id_collection: { enabled: true }` on Checkout, or store it on the [Customer](https://docs.stripe.com/billing/customer/tax-ids.md)). Without a valid tax ID, Stripe Tax treats a cross-border B2B sale as B2C and charges tax. See [collect tax IDs](https://docs.stripe.com/tax/checkout/tax-ids.md). + +## Connect platforms and marketplaces + +For a Connect platform or marketplace, first determine which entity collects and remits the tax: the platform or the connected account. This is a legal determination, so route the final call to the user’s tax advisor rather than inferring it from whether they call themselves a platform or a marketplace. The practical signal is who the [merchant of record](https://docs.stripe.com/connect/merchant-of-record.md) is, which follows the charge type: direct charges make the connected account the merchant of record, and destination charges usually make it the platform. Marketplace-facilitator rules can override this, so have the advisor confirm. See [Stripe Tax with Connect](https://docs.stripe.com/tax/connect.md) for the decision. + +Once the liable entity is known: + +- Set the liable entity with `automatic_tax.liability` on Checkout, Invoices, Subscriptions, or Payment Links: `{ type: 'self' }` for the platform, or `{ type: 'account', account: '' }` for the connected account. Destination and separate charges support both; a platform-liable direct charge uses the gated `{ type: 'application' }`. Custom PaymentIntents have no `automatic_tax` field, so follow the PaymentIntents path in the guides instead. Pick the guide by outcome: connected account collects, [tax for platforms](https://docs.stripe.com/tax/tax-for-platforms.md); platform collects, [tax for marketplaces](https://docs.stripe.com/tax/tax-for-marketplaces.md). +- Registrations and tax settings belong to the liable entity. When the connected account is liable, confirm its [tax settings](https://docs.stripe.com/tax/settings-api.md) `status` is `active` before enabling `automatic_tax` on its payments, and manage its registrations with the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) using the `Stripe-Account` header (or Connect embedded components). + +## Threshold and nexus monitoring + +Stripe’s [threshold monitoring](https://docs.stripe.com/tax/monitoring.md) highlights *potential* registration obligations (no public API yet). Present it as information and route the decision to the user’s tax advisor. It’s up to the user to confirm whether registration is required; don’t tell them they must register. + +## Registration safety + +Guide, don’t advise. Never tell a user where they must register or whether they’re legally obligated. Recommend they consult their tax advisor to determine their obligations. + +- The [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) can list, create, update, and expire registrations (set `expires_at` to expire; there’s no delete). A scheduled expiry can be changed, but an expiration that has taken effect is permanent (to collect again, the user adds a new registration), and there’s no pause. A head office address is required before adding a registration. +- Adding a registration in Stripe records where the user is *already* registered. It doesn’t register them with the tax authority. +- Creating or expiring a registration changes whether Stripe collects tax in that jurisdiction, but it doesn’t register or deregister the user with the tax authority. The user must do that separately. Prepare the change and have the user confirm it; never create or expire a registration automatically. + +**How to register.** Present the paths that fit the user and let them (with their tax advisor) choose. Don’t pick for them. + +- **Register themselves, then record it in Stripe**: the user registers with the tax authority, then records it with the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) or the Dashboard. See [Register for tax](https://docs.stripe.com/tax/registering.md). +- **Ask Stripe to register (US only)**: for remote, out-of-state sellers with no physical presence in the state; no public API, requires a Tax Complete subscription, and doesn’t support in-state registrations. See [Use Stripe to register](https://docs.stripe.com/tax/use-stripe-to-register.md). +- **Register outside the US with Taxually**: no public API; done through the Taxually app. See [Register outside the US with Taxually](https://docs.stripe.com/tax/use-taxually-to-register.md). + +**Reporting and filing.** Stripe Tax calculates and collects tax but doesn’t file returns unless the user is on a filing product. Point users to the Dashboard [tax reports and exports](https://docs.stripe.com/tax/reports.md) to reconcile and remit; filing runs through Stripe (US) or Taxually (non-US). + +## If jurisdictions are unknown + +Don’t guess which jurisdictions apply. Ask the user which states or countries they have customers in, then add a registration for each with the [Tax Registrations API](https://docs.stripe.com/api/tax/registrations.md) or the Dashboard. + +## If the region or tax type isn’t supported + +Check the [supported countries list](https://docs.stripe.com/tax/supported-countries.md). If the jurisdiction isn’t listed, tell the user: + +- Stripe Tax doesn’t support that region yet +- They can collect tax manually using `tax_rates` on the subscription or invoice instead (not alongside `automatic_tax`; you can’t use both) +- For unsupported tax types (customs duties, excise taxes), Stripe Tax doesn’t apply, so those are out of scope + +Don’t attempt to approximate using a supported region as a proxy. diff --git a/.agents/skills/stripe-best-practices/references/treasury.md b/.agents/skills/stripe-best-practices/references/treasury.md new file mode 100644 index 0000000..3832f44 --- /dev/null +++ b/.agents/skills/stripe-best-practices/references/treasury.md @@ -0,0 +1,16 @@ +# Treasury / Financial Accounts + +## Table of contents + +- v2 Financial Accounts API +- Legacy v1 Treasury + +## v2 Financial Accounts API + +For embedded financial accounts (bank accounts, account and routing numbers, money movement), use the [v2 Financial Accounts API](https://docs.stripe.com/api/v2/core/vault/financial-accounts.md) (`POST /v2/core/vault/financial_accounts`). This is required for new integrations. + +For Treasury for platforms concepts and guides, see the [Treasury for platforms overview](https://docs.stripe.com/treasury/connect.md). + +## Legacy v1 Treasury + +Don’t use the [v1 Treasury Financial Accounts API](https://docs.stripe.com/api/treasury/financial_accounts.md) (`POST /v1/treasury/financial_accounts`) for new integrations. Existing v1 integrations continue to work. diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0c9f11f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +.next +.git +website +uploads +*.md +.env +.env.* +!.env.example +deploy-*.tgz +scripts +bg-video diff --git a/.env.example b/.env.example index 1bc6b9e..d3784fb 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,46 @@ -DATABASE_URL="postgresql://s2yt:s2yt@localhost:5432/s2yt" -REDIS_URL="redis://localhost:6379" +DATABASE_URL="postgresql://s2yt:s2yt@localhost:5433/s2yt" +REDIS_URL="redis://localhost:6380" NEXTAUTH_URL="http://localhost:3000" -NEXTAUTH_SECRET="generate-a-random-secret-here" -GOOGLE_CLIENT_ID="your-google-client-id" +# Generate with: openssl rand -base64 32 +NEXTAUTH_SECRET="replace-with-a-long-random-secret" +# Used to encrypt YouTube OAuth tokens at rest (falls back to NEXTAUTH_SECRET if unset) +# TOKEN_ENCRYPTION_KEY="replace-with-another-long-random-secret" +# Server-side Google OAuth 2.0 credentials from Google Cloud Console +GOOGLE_CLIENT_ID="your-google-client-id.apps.googleusercontent.com" GOOGLE_CLIENT_SECRET="your-google-client-secret" UPLOAD_DIR="./uploads" +# Open-source / self-hosted: unlimited video quota, API, and Pro features +# S2VID_EDITION="selfhosted" +# Admin API key for approving/rejecting quota extension requests (Bearer token) +# ADMIN_API_KEY="your-secret-admin-key" +# Pro users generate API keys in Dashboard → Settings (stored hashed; shown once) +# Optional: override bundled ffmpeg-static binary (leave unset to use npm package) +# FFMPEG_PATH="C:/path/to/ffmpeg.exe" +# Public Gitea issues URL for community support links +NEXT_PUBLIC_GITEA_ISSUES_URL="https://git.atakanozban.com/Songs2VID/songs2vid/issues" +NEXT_PUBLIC_GITEA_URL="https://git.atakanozban.com/Songs2VID" +NEXT_PUBLIC_DOCKER_HUB_URL="https://hub.docker.com/r/atakanozban/songs2vid" +# Docusaurus docs — local: npm run docs:dev → http://localhost:3001 +# NEXT_PUBLIC_DOCS_URL="http://localhost:3001" +# Production: NEXT_PUBLIC_DOCS_URL="https://docs.songs2vid.com" +# Stripe billing (Pro €5/mo + Free 1–15 credit top-ups @ €0.25) +# STRIPE_SECRET_KEY="sk_test_..." +# Prefer a restricted key (rk_...) with Checkout + Customers + Billing Portal + Webhooks only +# STRIPE_WEBHOOK_SECRET="whsec_..." +# Optional Dashboard Price ID for Pro (otherwise inline price_data €5/mo is used) +# STRIPE_PRO_PRICE_ID="price_..." +# Collect VAT/GST via Stripe Tax AFTER adding Tax registrations in Dashboard: +# STRIPE_AUTOMATIC_TAX="true" +# Force local mock upgrades/grants without Stripe: BILLING_DEV_MOCK=true +# Disable auto-mock when Stripe key missing: BILLING_DEV_MOCK=false +# Point Stripe webhook to: POST /api/stripe/webhook +# Events (required): +# checkout.session.completed +# invoice.payment_succeeded +# invoice.payment_failed +# customer.subscription.updated +# customer.subscription.deleted +# Dashboard: enable Customer portal (Settings → Billing → Customer portal) +# Optional: Managed Payments (MoR) enable in Dashboard + set managed_payments on Checkout if you use it +# Dev helpers: POST /api/dev/grant-credits { "action": "set-pro" | "free-top-up" | "grant-credits" } +# Admin reset: POST /api/admin/reset-credits Authorization: Bearer $ADMIN_API_KEY diff --git a/.gitignore b/.gitignore index 291d773..709b0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ node_modules/ .next/ .env .env.local +website/node_modules/ +website/build/ +website/.docusaurus/ diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 8bd0e39..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,5 +0,0 @@ - -# This is NOT the Next.js you know - -This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. - diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ed0c708 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,58 @@ +# syntax=docker/dockerfile:1 +# Hosted Songs2VID image (cloud plans + PAYG/Stripe). Do not bake selfhosted edition. + +FROM node:22-bookworm-slim AS deps +WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends openssl ca-certificates \ + && rm -rf /var/lib/apt/lists/* +COPY package.json package-lock.json ./ +COPY prisma ./prisma +RUN npm install + +FROM node:22-bookworm-slim AS builder +WORKDIR /app +RUN apt-get update && apt-get install -y --no-install-recommends openssl ca-certificates \ + && rm -rf /var/lib/apt/lists/* +COPY --from=deps /app/node_modules ./node_modules +COPY . . +ENV NEXT_TELEMETRY_DISABLED=1 +RUN npx prisma generate && npm run build + +FROM node:22-bookworm-slim AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV UPLOAD_DIR=/app/uploads +ENV FFMPEG_PATH=ffmpeg +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 +ENV HOME=/home/nextjs +ENV npm_config_cache=/tmp/npm-cache + +RUN apt-get update && apt-get install -y --no-install-recommends \ + openssl ca-certificates ffmpeg \ + && rm -rf /var/lib/apt/lists/* \ + && groupadd --system --gid 1001 nodejs \ + && useradd --system --uid 1001 --gid nodejs --create-home --home-dir /home/nextjs nextjs \ + && mkdir -p /app/uploads \ + && chown nextjs:nodejs /app /app/uploads + +USER nextjs + +COPY --chown=nextjs:nodejs package.json package-lock.json ./ +COPY --chown=nextjs:nodejs prisma ./prisma +RUN npm install --omit=dev \ + && npx prisma generate \ + && rm -rf /tmp/npm-cache + +COPY --chown=nextjs:nodejs --from=builder /app/.next/standalone/server.js ./server.js +COPY --chown=nextjs:nodejs --from=builder /app/.next/standalone/.next ./.next +COPY --chown=nextjs:nodejs --from=builder /app/.next/static ./.next/static +COPY --chown=nextjs:nodejs --from=builder /app/public ./public +COPY --chown=nextjs:nodejs --from=builder /app/assets ./assets +COPY --chown=nextjs:nodejs --from=builder /app/worker ./worker +COPY --chown=nextjs:nodejs --from=builder /app/lib ./lib +COPY --chown=nextjs:nodejs --from=builder /app/tsconfig.json ./tsconfig.json + +EXPOSE 3000 +CMD ["node", "server.js"] diff --git a/README.md b/README.md index 7d04329..5a6eac4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# s2yt +# Songs2VID Create YouTube videos from an image and audio files. @@ -7,11 +7,38 @@ Create YouTube videos from an image and audio files. - Next.js 15 (App Router, TypeScript, Tailwind) - PostgreSQL + Prisma - Redis + BullMQ -- NextAuth (Google OAuth with YouTube scopes) +- NextAuth (Google OAuth 2.0 with YouTube scopes) - FFmpeg for video encoding - YouTube Data API v3 -## Setup +## Editions + +| Edition | How | Limits | +|---------|-----|--------| +| **Hosted** (default) | Leave `S2VID_EDITION` unset | Free / Pro quotas and API gates | +| **Self-hosted / OSS** | `S2VID_EDITION=selfhosted` | No video quota, no API rate caps; playlists + API unlocked | + +Docker Compose sets `S2VID_EDITION=selfhosted` automatically. + +## Quick start (Docker) + +1. Copy env and set Google OAuth + secrets: + +```bash +cp .env.example .env +``` + +2. Build and run the full stack (web, worker, Postgres, Redis): + +```bash +docker compose up -d --build +``` + +Open [http://localhost:3000](http://localhost:3000). + +Add Google OAuth redirect URI: `http://localhost:3000/api/auth/callback/google` (or your public URL). + +## Local development 1. Copy environment variables: @@ -19,13 +46,13 @@ Create YouTube videos from an image and audio files. cp .env.example .env ``` -2. Start PostgreSQL and Redis: +2. Start Postgres and Redis only: ```bash -docker compose up -d +docker compose -f docker-compose.dev.yml up -d ``` -3. Install dependencies and run migrations: +3. Install dependencies and push the schema: ```bash npm install @@ -38,26 +65,55 @@ npm run db:push - Add redirect URI: `http://localhost:3000/api/auth/callback/google` - Set `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` in `.env` -5. Install FFmpeg on your system (required for the worker). +5. Optional for unlimited local use: `S2VID_EDITION=selfhosted` in `.env` -6. Start the web app and worker in separate terminals: +6. Start the app, worker, and docs: ```bash -npm run dev -npm run worker +npm run dev:all ``` -## Free Plan +- App: http://localhost:3000 +- Docs: http://localhost:3001 -- 14 videos/month (each audio = 1 video) -- Max 720p resolution -- 30 MB max per file -- Watermark required -- Per-video metadata (title auto-filled from audio filename) +Or run them separately with `npm run dev`, `npm run worker`, and `npm run docs:dev`. + +## Authentication + +Users sign in with Google via OAuth 2.0. The app handles YouTube channel connection automatically end users never enter API keys for YouTube. + +## Self-hosted edition + +Set `S2VID_EDITION=selfhosted` (Docker Compose does this by default): + +- Unlimited video allowance +- API access and playlists +- Art-track layouts with blur backgrounds and fine-tuning (padding, gaps, text offsets) +- Custom watermarks (text/logo), curated or uploaded fonts + +Composition details: see `website/docs/video-editing.md` (or open Video editing in the docs site after `npm run docs:dev`). ## Scripts -- `npm run dev` — Next.js dev server -- `npm run worker` — Background job processor -- `npm run db:push` — Push Prisma schema to database -- `npm run build` — Production build +- `npm run dev` - Next.js dev server +- `npm run worker` - Background job processor +- `npm run dev:all` - App (3000) + worker + docs (3001) together +- `npm run db:push` - Push Prisma schema to database +- `npm run build` - Production build +- `npm run docs:dev` - Documentation site only (Docusaurus on port 3001) + +## Documentation + +Docs live in `website/` (Docusaurus). API reference: + +```bash +npm run docs:dev +``` + +Open [http://localhost:3001/docs/api/overview](http://localhost:3001/docs/api/overview). + +The app “Full API docs” link and `/dashboard/api-docs` redirect use local docs when `NEXTAUTH_URL` is localhost (or set `NEXT_PUBLIC_DOCS_URL`). +## Source + +- Gitea: https://git.atakanozban.com/Songs2VID +- Docker Hub: https://hub.docker.com/r/atakanozban/songs2vid diff --git a/app/api/account/api-key/route.ts b/app/api/account/api-key/route.ts new file mode 100644 index 0000000..0cc8388 --- /dev/null +++ b/app/api/account/api-key/route.ts @@ -0,0 +1,49 @@ +import { NextResponse } from "next/server"; +import { createUserApiKey, getUserApiKeyStatus, revokeUserApiKey } from "@/lib/api-keys"; +import { hasProFeatures } from "@/lib/edition"; +import { getSessionUser } from "@/lib/session"; + +async function requireApiKeyAccess() { + const user = await getSessionUser(); + if (!user) { + return { error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }), user: null }; + } + if (!hasProFeatures(user.plan)) { + return { + error: NextResponse.json( + { error: "API keys are available on the Pro plan only" }, + { status: 403 }, + ), + user: null, + }; + } + return { error: null, user }; +} + +export async function GET() { + const { error, user } = await requireApiKeyAccess(); + if (error || !user) return error!; + + const status = await getUserApiKeyStatus(user.id); + return NextResponse.json(status); +} + +export async function POST() { + const { error, user } = await requireApiKeyAccess(); + if (error || !user) return error!; + + const { token, prefix } = await createUserApiKey(user.id); + return NextResponse.json({ + apiKey: token, + prefix, + message: "Copy this key now. It will not be shown again.", + }); +} + +export async function DELETE() { + const { error, user } = await requireApiKeyAccess(); + if (error || !user) return error!; + + await revokeUserApiKey(user.id); + return NextResponse.json({ ok: true }); +} diff --git a/app/api/account/api-rate-limit-extension-request/route.ts b/app/api/account/api-rate-limit-extension-request/route.ts new file mode 100644 index 0000000..78c95ca --- /dev/null +++ b/app/api/account/api-rate-limit-extension-request/route.ts @@ -0,0 +1,51 @@ +import { NextRequest, NextResponse } from "next/server"; +import { + createQuotaExtensionRequest, + EXTENSION_KIND, + getQuotaExtensionUsage, +} from "@/lib/quota-extensions"; +import { hasProFeatures } from "@/lib/edition"; +import { getSessionUser } from "@/lib/session"; + +export async function GET() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + if (!hasProFeatures(user.plan)) { + return NextResponse.json({ error: "Pro plan required" }, { status: 403 }); + } + + const usage = await getQuotaExtensionUsage(user.id, EXTENSION_KIND.API_RATE_LIMIT); + return NextResponse.json(usage); +} + +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + if (!hasProFeatures(user.plan)) { + return NextResponse.json({ error: "Pro plan required" }, { status: 403 }); + } + + let message = ""; + try { + const body = await req.json(); + if (typeof body.message === "string") message = body.message; + } catch { + // optional body + } + + try { + const result = await createQuotaExtensionRequest( + user.id, + message, + EXTENSION_KIND.API_RATE_LIMIT, + ); + return NextResponse.json(result); + } catch (err) { + const msg = err instanceof Error ? err.message : "Failed to submit request"; + return NextResponse.json({ error: msg }, { status: 400 }); + } +} diff --git a/app/api/account/api-rate-limit/route.ts b/app/api/account/api-rate-limit/route.ts new file mode 100644 index 0000000..a7f142d --- /dev/null +++ b/app/api/account/api-rate-limit/route.ts @@ -0,0 +1,20 @@ +import { NextResponse } from "next/server"; +import { getApiRateLimitStatus } from "@/lib/api-rate-limit"; +import { hasProFeatures } from "@/lib/edition"; +import { getSessionUser } from "@/lib/session"; + +export async function GET() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + if (!hasProFeatures(user.plan)) { + return NextResponse.json( + { error: "API rate limits are available on the Pro plan only" }, + { status: 403 }, + ); + } + + const status = await getApiRateLimitStatus(user.id); + return NextResponse.json(status); +} diff --git a/app/api/account/billing-portal/route.ts b/app/api/account/billing-portal/route.ts new file mode 100644 index 0000000..a42d02c --- /dev/null +++ b/app/api/account/billing-portal/route.ts @@ -0,0 +1,64 @@ +import { NextRequest, NextResponse } from "next/server"; +import { prisma } from "@/lib/db"; +import { getSessionUser } from "@/lib/session"; +import { getStripe, isBillingDevMock, isStripeConfigured } from "@/lib/stripe"; + +/** + * Stripe Customer Portal update payment method, view invoices, cancel (per Dashboard config). + * @see https://docs.stripe.com/customer-management/integrate-customer-portal + */ +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + if (isBillingDevMock()) { + return NextResponse.json( + { error: "Billing portal is unavailable in mock mode." }, + { status: 503 }, + ); + } + + if (!isStripeConfigured()) { + return NextResponse.json( + { error: "Payments are not configured yet. Set STRIPE_SECRET_KEY." }, + { status: 503 }, + ); + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { stripeCustomerId: true }, + }); + + if (!dbUser.stripeCustomerId) { + return NextResponse.json( + { error: "No Stripe customer on this account. Complete a checkout first." }, + { status: 400 }, + ); + } + + const origin = process.env.NEXTAUTH_URL || req.nextUrl.origin; + const stripe = getStripe(); + + try { + const session = await stripe.billingPortal.sessions.create({ + customer: dbUser.stripeCustomerId, + return_url: `${origin}/dashboard/settings`, + }); + return NextResponse.json({ url: session.url }); + } catch (err) { + const message = err instanceof Error ? err.message : "Could not open billing portal"; + console.error("[stripe] billing portal failed", err); + return NextResponse.json( + { + error: + message.includes("No configuration") || message.includes("portal") + ? "Billing portal is not configured in Stripe Dashboard yet. Enable it under Settings → Billing → Customer portal." + : message, + }, + { status: 502 }, + ); + } +} diff --git a/app/api/account/cancel-subscription/route.ts b/app/api/account/cancel-subscription/route.ts new file mode 100644 index 0000000..ab93490 --- /dev/null +++ b/app/api/account/cancel-subscription/route.ts @@ -0,0 +1,217 @@ +import { NextRequest, NextResponse } from "next/server"; +import { downgradeToFreePlan } from "@/lib/billing"; +import { prisma } from "@/lib/db"; +import { getSessionUser } from "@/lib/session"; +import { getStripe, isBillingDevMock, isStripeConfigured } from "@/lib/stripe"; + +type CancelWhen = "immediate" | "period_end"; +type CancelAction = "cancel" | "resume"; + +function periodEndIso(sub: { + cancel_at?: number | null; + current_period_end?: number; + items?: { data?: Array<{ current_period_end?: number }> }; +}): string | null { + const fromItem = sub.items?.data?.[0]?.current_period_end; + const ts = sub.cancel_at ?? fromItem ?? sub.current_period_end ?? null; + return ts ? new Date(ts * 1000).toISOString() : null; +} + +/** + * Cancel Pro subscription via Stripe. + * Body: { when: "immediate" | "period_end" } or { action: "resume" } + */ +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + if (user.plan !== "PREMIUM") { + return NextResponse.json({ error: "No active subscription to cancel" }, { status: 400 }); + } + + let action: CancelAction = "cancel"; + let when: CancelWhen = "immediate"; + try { + const body = await req.json(); + if (body?.action === "resume") action = "resume"; + if (body?.when === "period_end" || body?.when === "immediate") when = body.when; + } catch { + // empty body → default immediate cancel (legacy) + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { stripeSubscriptionId: true }, + }); + + const subId = dbUser.stripeSubscriptionId; + const isMockSub = !subId || subId.startsWith("dev_sub_"); + const useStripe = + Boolean(subId) && + !isMockSub && + isStripeConfigured() && + !isBillingDevMock(); + + // Resume (undo cancel-at-period-end) + if (action === "resume") { + if (useStripe && subId) { + try { + const stripe = getStripe(); + const sub = await stripe.subscriptions.update(subId, { + cancel_at_period_end: false, + }); + return NextResponse.json({ + ok: true, + action: "resume", + cancelAtPeriodEnd: false, + currentPeriodEnd: periodEndIso(sub as { current_period_end?: number }), + }); + } catch (err) { + console.error("[stripe] resume subscription failed", err); + return NextResponse.json( + { error: err instanceof Error ? err.message : "Failed to keep subscription" }, + { status: 502 }, + ); + } + } + return NextResponse.json({ + ok: true, + action: "resume", + cancelAtPeriodEnd: false, + mocked: true, + }); + } + + // Cancel + if (when === "period_end") { + if (useStripe && subId) { + try { + const stripe = getStripe(); + const sub = await stripe.subscriptions.update(subId, { + cancel_at_period_end: true, + }); + const endsAt = periodEndIso( + sub as { + cancel_at?: number | null; + current_period_end?: number; + items?: { data?: Array<{ current_period_end?: number }> }; + }, + ); + return NextResponse.json({ + ok: true, + when: "period_end", + cancelAtPeriodEnd: true, + endsAt, + // Keep Pro until Stripe sends customer.subscription.deleted + }); + } catch (err) { + console.error("[stripe] cancel at period end failed", err); + return NextResponse.json( + { error: err instanceof Error ? err.message : "Failed to schedule cancellation" }, + { status: 502 }, + ); + } + } + + // Mock / no Stripe id: schedule locally by leaving Pro and reporting next month + const endsAt = new Date(); + endsAt.setMonth(endsAt.getMonth() + 1); + return NextResponse.json({ + ok: true, + when: "period_end", + cancelAtPeriodEnd: true, + endsAt: endsAt.toISOString(), + mocked: true, + }); + } + + // immediate + if (useStripe && subId) { + try { + const stripe = getStripe(); + await stripe.subscriptions.cancel(subId); + } catch (err) { + console.error("[stripe] cancel subscription failed", err); + return NextResponse.json( + { + error: + err instanceof Error + ? err.message + : "Stripe could not cancel the subscription. Your plan was not changed.", + }, + { status: 502 }, + ); + } + } + + await downgradeToFreePlan(user.id); + return NextResponse.json({ + ok: true, + when: "immediate", + cancelAtPeriodEnd: false, + plan: "FREE", + }); +} + +/** Current Stripe subscription cancel status for settings UI. */ +export async function GET() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + if (user.plan !== "PREMIUM") { + return NextResponse.json({ + plan: user.plan, + cancelAtPeriodEnd: false, + endsAt: null, + }); + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { stripeSubscriptionId: true }, + }); + + const subId = dbUser.stripeSubscriptionId; + if ( + !subId || + subId.startsWith("dev_sub_") || + !isStripeConfigured() || + isBillingDevMock() + ) { + return NextResponse.json({ + plan: "PREMIUM", + cancelAtPeriodEnd: false, + endsAt: null, + mocked: true, + }); + } + + try { + const stripe = getStripe(); + const sub = await stripe.subscriptions.retrieve(subId); + return NextResponse.json({ + plan: "PREMIUM", + status: sub.status, + cancelAtPeriodEnd: Boolean(sub.cancel_at_period_end), + endsAt: periodEndIso( + sub as { + cancel_at?: number | null; + current_period_end?: number; + items?: { data?: Array<{ current_period_end?: number }> }; + }, + ), + }); + } catch (err) { + console.error("[stripe] retrieve subscription failed", err); + return NextResponse.json({ + plan: "PREMIUM", + cancelAtPeriodEnd: false, + endsAt: null, + error: "Could not load subscription status from Stripe", + }); + } +} diff --git a/app/api/account/credits/route.ts b/app/api/account/credits/route.ts new file mode 100644 index 0000000..2b560f5 --- /dev/null +++ b/app/api/account/credits/route.ts @@ -0,0 +1,192 @@ +import { NextRequest, NextResponse } from "next/server"; +import { + CREDIT_PRICE_CENTS, + FREE_EXTRA_CREDITS_MAX, + FREE_TOP_UP_MAX, + FREE_TOP_UP_MIN, + formatCreditPrice, + validateFreeTopUpAmount, +} from "@/lib/credits"; +import { prisma } from "@/lib/db"; +import { getSessionUser } from "@/lib/session"; +import { + checkoutTaxAndReferenceOptions, + ensureStripeCustomer, + priceDataTaxFields, + productDataWithTaxCode, +} from "@/lib/stripe-checkout"; +import { getStripe, isBillingDevMock, isStripeConfigured } from "@/lib/stripe"; +import { grantExtraCredits } from "@/lib/billing"; + +export async function GET() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { + extraCredits: true, + plan: true, + monthlyCredits: true, + videosUsed: true, + }, + }); + + const purchases = await prisma.creditPurchase.findMany({ + where: { userId: user.id, status: "COMPLETED" }, + orderBy: { completedAt: "desc" }, + take: 10, + }); + + const cap = FREE_EXTRA_CREDITS_MAX; + const room = Math.max(0, cap - dbUser.extraCredits); + + return NextResponse.json({ + extraCredits: dbUser.extraCredits, + videoCredits: dbUser.extraCredits, + topUpMin: FREE_TOP_UP_MIN, + topUpMax: FREE_TOP_UP_MAX, + priceCentsPerCredit: CREDIT_PRICE_CENTS, + priceLabelPerCredit: formatCreditPrice(1), + creditBalanceMax: cap, + monthlyCredits: dbUser.monthlyCredits, + creditsUsed: dbUser.videosUsed, + plan: dbUser.plan, + stripeConfigured: isStripeConfigured() || isBillingDevMock(), + room, + atExtraCap: room === 0, + purchases: purchases.map((p) => ({ + id: p.id, + credits: p.credits, + amountCents: p.amountCents, + completedAt: p.completedAt?.toISOString() ?? null, + })), + }); +} + +/** Free tier: top up 1–15 extra credits (price = credits × €0.25). */ +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + if (user.plan === "PREMIUM") { + return NextResponse.json( + { + error: + "Credit top-ups are for the Free plan. Pro includes 50 monthly credits; existing extras never expire.", + }, + { status: 403 }, + ); + } + + let credits = 0; + try { + const body = await req.json(); + credits = Math.floor(Number(body.credits)); + } catch { + return NextResponse.json({ error: "Invalid request body" }, { status: 400 }); + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { extraCredits: true, email: true, monthlyCredits: true, videosUsed: true, bonusQuota: true }, + }); + + const monthlyRemaining = Math.max( + 0, + dbUser.monthlyCredits + dbUser.bonusQuota - dbUser.videosUsed, + ); + const validation = validateFreeTopUpAmount(credits, dbUser.extraCredits, monthlyRemaining); + if (!validation.ok) { + return NextResponse.json({ error: validation.error }, { status: 400 }); + } + + const { credits: amount, amountCents } = validation; + + if (isBillingDevMock()) { + const purchase = await prisma.creditPurchase.create({ + data: { + userId: user.id, + credits: amount, + amountCents, + status: "COMPLETED", + completedAt: new Date(), + stripeSessionId: `dev_topup_${Date.now()}`, + }, + }); + await grantExtraCredits(user.id, amount); + return NextResponse.json({ + mocked: true, + granted: amount, + amountCents, + purchaseId: purchase.id, + }); + } + + if (!isStripeConfigured()) { + return NextResponse.json( + { error: "Payments are not configured yet. Set STRIPE_SECRET_KEY." }, + { status: 503 }, + ); + } + + const origin = process.env.NEXTAUTH_URL || req.nextUrl.origin; + const purchase = await prisma.creditPurchase.create({ + data: { + userId: user.id, + credits: amount, + amountCents, + status: "PENDING", + }, + }); + + try { + const stripe = getStripe(); + const customerId = await ensureStripeCustomer(user.id, dbUser.email); + const session = await stripe.checkout.sessions.create({ + mode: "payment", + customer: customerId, + line_items: [ + { + quantity: amount, + price_data: { + currency: "eur", + unit_amount: CREDIT_PRICE_CENTS, + ...priceDataTaxFields(), + product_data: productDataWithTaxCode( + "Songs2VID video credit", + `1 credit = 1 video upload (${formatCreditPrice(1)} each)`, + ), + }, + }, + ], + metadata: { + type: "free_top_up", + userId: user.id, + purchaseId: purchase.id, + credits: String(amount), + }, + ...checkoutTaxAndReferenceOptions(user.id), + success_url: `${origin}/dashboard/settings?credits=success`, + cancel_url: `${origin}/dashboard/settings?credits=cancelled`, + }); + + await prisma.creditPurchase.update({ + where: { id: purchase.id }, + data: { stripeSessionId: session.id }, + }); + + return NextResponse.json({ url: session.url, sessionId: session.id }); + } catch (err) { + await prisma.creditPurchase.update({ + where: { id: purchase.id }, + data: { status: "FAILED" }, + }); + const message = err instanceof Error ? err.message : "Checkout failed"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} diff --git a/app/api/account/delete/route.ts b/app/api/account/delete/route.ts new file mode 100644 index 0000000..8e7bb10 --- /dev/null +++ b/app/api/account/delete/route.ts @@ -0,0 +1,14 @@ +import { NextResponse } from "next/server"; +import { prisma } from "@/lib/db"; +import { getSessionUser } from "@/lib/session"; + +export async function POST() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + await prisma.user.delete({ where: { id: user.id } }); + + return NextResponse.json({ ok: true }); +} diff --git a/app/api/account/quota-extension-request/route.ts b/app/api/account/quota-extension-request/route.ts new file mode 100644 index 0000000..2111378 --- /dev/null +++ b/app/api/account/quota-extension-request/route.ts @@ -0,0 +1,36 @@ +import { NextRequest, NextResponse } from "next/server"; +import { createQuotaExtensionRequest, getQuotaExtensionUsage } from "@/lib/quota-extensions"; +import { getSessionUser } from "@/lib/session"; + +export async function GET() { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const usage = await getQuotaExtensionUsage(user.id); + return NextResponse.json(usage); +} + +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + let message = ""; + try { + const body = await req.json(); + if (typeof body.message === "string") message = body.message; + } catch { + // optional body + } + + try { + const result = await createQuotaExtensionRequest(user.id, message); + return NextResponse.json(result); + } catch (err) { + const msg = err instanceof Error ? err.message : "Failed to submit request"; + return NextResponse.json({ error: msg }, { status: 400 }); + } +} diff --git a/app/api/account/subscribe/route.ts b/app/api/account/subscribe/route.ts new file mode 100644 index 0000000..30a697d --- /dev/null +++ b/app/api/account/subscribe/route.ts @@ -0,0 +1,87 @@ +import { NextRequest, NextResponse } from "next/server"; +import { activateProPlan } from "@/lib/billing"; +import { PRO_PRICE_CENTS } from "@/lib/credits"; +import { prisma } from "@/lib/db"; +import { getSessionUser } from "@/lib/session"; +import { + checkoutTaxAndReferenceOptions, + ensureStripeCustomer, + priceDataTaxFields, + productDataWithTaxCode, +} from "@/lib/stripe-checkout"; +import { getStripe, isBillingDevMock, isStripeConfigured } from "@/lib/stripe"; + +/** Start Pro subscription Checkout (€5/mo) or mock-upgrade in development. */ +export async function POST(req: NextRequest) { + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + if (user.plan === "PREMIUM") { + return NextResponse.json({ error: "Already on Pro." }, { status: 400 }); + } + + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: user.id }, + select: { email: true, stripeCustomerId: true }, + }); + + if (isBillingDevMock()) { + await activateProPlan(user.id, { + stripeCustomerId: dbUser.stripeCustomerId, + stripeSubscriptionId: `dev_sub_${Date.now()}`, + cardLast4: "4242", + }); + return NextResponse.json({ mocked: true, plan: "PREMIUM" }); + } + + if (!isStripeConfigured()) { + return NextResponse.json( + { error: "Payments are not configured yet. Set STRIPE_SECRET_KEY." }, + { status: 503 }, + ); + } + + const origin = process.env.NEXTAUTH_URL || req.nextUrl.origin; + const stripe = getStripe(); + const customerId = await ensureStripeCustomer(user.id, dbUser.email); + const priceId = process.env.STRIPE_PRO_PRICE_ID; + + const session = await stripe.checkout.sessions.create({ + mode: "subscription", + customer: customerId, + line_items: priceId + ? [{ price: priceId, quantity: 1 }] + : [ + { + quantity: 1, + price_data: { + currency: "eur", + unit_amount: PRO_PRICE_CENTS, + recurring: { interval: "month" }, + ...priceDataTaxFields(), + product_data: productDataWithTaxCode( + "Songs2VID Pro", + "50 video credits / month · 1080p · API access · Includes Custom Branding, Watermark Positioning, and Bulk Image Matching", + ), + }, + }, + ], + metadata: { + type: "pro_subscription", + userId: user.id, + }, + subscription_data: { + metadata: { + type: "pro_subscription", + userId: user.id, + }, + }, + ...checkoutTaxAndReferenceOptions(user.id), + success_url: `${origin}/dashboard/settings?upgrade=success`, + cancel_url: `${origin}/dashboard/settings?upgrade=cancelled`, + }); + + return NextResponse.json({ url: session.url, sessionId: session.id }); +} diff --git a/app/api/admin/quota-extension-request/[id]/route.ts b/app/api/admin/quota-extension-request/[id]/route.ts new file mode 100644 index 0000000..48bdde5 --- /dev/null +++ b/app/api/admin/quota-extension-request/[id]/route.ts @@ -0,0 +1,53 @@ +import { NextRequest, NextResponse } from "next/server"; +import { + approveQuotaExtensionRequest, + rejectQuotaExtensionRequest, +} from "@/lib/quota-extensions"; + +function isAuthorized(req: NextRequest) { + const key = process.env.ADMIN_API_KEY; + if (!key) return false; + const auth = req.headers.get("authorization"); + return auth === `Bearer ${key}`; +} + +export async function POST( + req: NextRequest, + { params }: { params: Promise<{ id: string }> }, +) { + if (!isAuthorized(req)) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const { id } = await params; + let action: "approve" | "reject" = "approve"; + let bonusQuota: number | undefined; + let bonusRateLimit: number | undefined; + let adminNote: string | undefined; + + try { + const body = await req.json(); + if (body.action === "reject") action = "reject"; + if (typeof body.bonusQuota === "number" && Number.isFinite(body.bonusQuota)) { + bonusQuota = body.bonusQuota; + } + if (typeof body.bonusRateLimit === "number" && Number.isFinite(body.bonusRateLimit)) { + bonusRateLimit = body.bonusRateLimit; + } + if (typeof body.adminNote === "string") adminNote = body.adminNote; + } catch { + // defaults + } + + try { + if (action === "reject") { + await rejectQuotaExtensionRequest(id, adminNote); + } else { + await approveQuotaExtensionRequest(id, { bonusQuota, bonusRateLimit, adminNote }); + } + return NextResponse.json({ ok: true }); + } catch (err) { + const msg = err instanceof Error ? err.message : "Failed to process request"; + return NextResponse.json({ error: msg }, { status: 400 }); + } +} diff --git a/app/api/admin/reset-credits/route.ts b/app/api/admin/reset-credits/route.ts new file mode 100644 index 0000000..a4f53c2 --- /dev/null +++ b/app/api/admin/reset-credits/route.ts @@ -0,0 +1,69 @@ +import { NextRequest, NextResponse } from "next/server"; +import { adminResetUserCredits } from "@/lib/billing"; +import { prisma } from "@/lib/db"; + +/** + * Admin utility: reset / adjust a user's credits. + * Authorization: Bearer ${ADMIN_API_KEY} + * + * Body: { userId | email, plan?, monthlyCredits?, creditsUsed?, extraCredits?, clearFreeTopUp? } + */ +export async function POST(req: NextRequest) { + const adminKey = process.env.ADMIN_API_KEY; + if (!adminKey) { + return NextResponse.json({ error: "Admin API not configured" }, { status: 503 }); + } + + const auth = req.headers.get("authorization"); + if (auth !== `Bearer ${adminKey}`) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + let body: { + userId?: string; + email?: string; + plan?: "FREE" | "PREMIUM"; + monthlyCredits?: number; + creditsUsed?: number; + extraCredits?: number; + clearFreeTopUp?: boolean; + }; + try { + body = await req.json(); + } catch { + return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); + } + + let userId = body.userId; + if (!userId && body.email) { + const found = await prisma.user.findUnique({ where: { email: body.email } }); + if (!found) { + return NextResponse.json({ error: "User not found" }, { status: 404 }); + } + userId = found.id; + } + if (!userId) { + return NextResponse.json({ error: "Provide userId or email" }, { status: 400 }); + } + + const updated = await adminResetUserCredits(userId, { + plan: body.plan, + monthlyCredits: body.monthlyCredits, + creditsUsed: body.creditsUsed, + extraCredits: body.extraCredits, + clearFreeTopUp: body.clearFreeTopUp, + }); + + return NextResponse.json({ + ok: true, + user: { + id: updated.id, + email: updated.email, + plan: updated.plan, + monthlyCredits: updated.monthlyCredits, + creditsUsed: updated.videosUsed, + extraCredits: updated.extraCredits, + freeTopUpPurchased: updated.freeTopUpPurchased, + }, + }); +} diff --git a/app/api/branding/watermark/route.ts b/app/api/branding/watermark/route.ts new file mode 100644 index 0000000..f81741b --- /dev/null +++ b/app/api/branding/watermark/route.ts @@ -0,0 +1,17 @@ +import fs from "fs/promises"; +import { NextResponse } from "next/server"; +import { getWatermarkPath } from "@/lib/storage"; + +export async function GET() { + try { + const buf = await fs.readFile(getWatermarkPath()); + return new NextResponse(buf, { + headers: { + "Content-Type": "image/png", + "Cache-Control": "public, max-age=86400, immutable", + }, + }); + } catch { + return NextResponse.json({ error: "Watermark asset not found" }, { status: 404 }); + } +} diff --git a/app/api/dev/grant-credits/route.ts b/app/api/dev/grant-credits/route.ts new file mode 100644 index 0000000..2e9d825 --- /dev/null +++ b/app/api/dev/grant-credits/route.ts @@ -0,0 +1,95 @@ +import { NextRequest, NextResponse } from "next/server"; +import { + activateProPlan, + adminResetUserCredits, + grantExtraCredits, + markFreeTopUpPurchased, +} from "@/lib/billing"; +import { FREE_TOP_UP_CREDITS } from "@/lib/credits"; +import { isBillingDevMock } from "@/lib/stripe"; +import { getSessionUser } from "@/lib/session"; + +/** + * Local-only billing helpers (no Stripe CLI required). + * Enabled when NODE_ENV=development (unless BILLING_DEV_MOCK=false) or BILLING_DEV_MOCK=true. + */ +function assertDev() { + if (!isBillingDevMock()) { + return NextResponse.json({ error: "Not available outside development mock mode" }, { status: 404 }); + } + return null; +} + +export async function POST(req: NextRequest) { + const blocked = assertDev(); + if (blocked) return blocked; + + const user = await getSessionUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + let body: { + action?: string; + credits?: number; + plan?: "FREE" | "PREMIUM"; + }; + try { + body = await req.json(); + } catch { + return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); + } + + const action = body.action ?? "grant-credits"; + + switch (action) { + case "grant-credits": { + const credits = Math.floor(Number(body.credits ?? FREE_TOP_UP_CREDITS)); + if (!Number.isFinite(credits) || credits <= 0) { + return NextResponse.json({ error: "Invalid credits" }, { status: 400 }); + } + await grantExtraCredits(user.id, credits); + return NextResponse.json({ ok: true, granted: credits }); + } + case "free-top-up": { + await markFreeTopUpPurchased(user.id); + return NextResponse.json({ ok: true, granted: FREE_TOP_UP_CREDITS }); + } + case "set-pro": { + await activateProPlan(user.id, { + stripeSubscriptionId: `dev_sub_${Date.now()}`, + cardLast4: "4242", + }); + return NextResponse.json({ ok: true, plan: "PREMIUM" }); + } + case "set-free": { + await adminResetUserCredits(user.id, { plan: "FREE", creditsUsed: 0 }); + return NextResponse.json({ ok: true, plan: "FREE" }); + } + case "reset-cycle": { + await adminResetUserCredits(user.id, { + plan: body.plan, + creditsUsed: 0, + }); + return NextResponse.json({ ok: true, reset: true }); + } + default: + return NextResponse.json({ error: `Unknown action: ${action}` }, { status: 400 }); + } +} + +/** Convenience GET for quick browser testing: /api/dev/grant-credits?action=set-pro */ +export async function GET(req: NextRequest) { + const blocked = assertDev(); + if (blocked) return blocked; + + const action = req.nextUrl.searchParams.get("action") ?? "grant-credits"; + const credits = Number(req.nextUrl.searchParams.get("credits") ?? FREE_TOP_UP_CREDITS); + + const fake = new NextRequest(req.url, { + method: "POST", + headers: { "content-type": "application/json", cookie: req.headers.get("cookie") ?? "" }, + body: JSON.stringify({ action, credits }), + }); + return POST(fake); +} diff --git a/app/api/fonts/[key]/route.ts b/app/api/fonts/[key]/route.ts new file mode 100644 index 0000000..3ad57fc --- /dev/null +++ b/app/api/fonts/[key]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; +import fs from "fs/promises"; +import { CURATED_FONTS, isCuratedFontKey } from "@/lib/fonts"; +import { resolveCuratedFontPath } from "@/lib/fonts-server"; + +export async function GET( + _req: NextRequest, + { params }: { params: Promise<{ key: string }> }, +) { + const { key } = await params; + if (!isCuratedFontKey(key)) { + return NextResponse.json({ error: "Unknown font" }, { status: 404 }); + } + + const fontPath = resolveCuratedFontPath(key); + try { + const buf = await fs.readFile(fontPath); + const meta = CURATED_FONTS.find((f) => f.key === key)!; + return new NextResponse(buf, { + headers: { + "Content-Type": "font/ttf", + "Content-Disposition": `inline; filename="${meta.file}"`, + "Cache-Control": "public, max-age=86400, immutable", + }, + }); + } catch { + return NextResponse.json({ error: "Font file not found" }, { status: 404 }); + } +} diff --git a/app/api/jobs/route.ts b/app/api/jobs/route.ts index a332698..55bca49 100644 --- a/app/api/jobs/route.ts +++ b/app/api/jobs/route.ts @@ -1,23 +1,11 @@ import { NextRequest, NextResponse } from "next/server"; -import fs from "fs/promises"; -import path from "path"; -import { Privacy } from "@prisma/client"; -import { FREE_PLAN, isAllowedResolution } from "@/lib/constants"; +import { PremiumRequiredError, premiumRequiredResponse } from "@/lib/entitlements"; +import { createVideoJob } from "@/lib/jobs/create-job"; import { prisma } from "@/lib/db"; -import { enqueueVideoJob } from "@/lib/queue/client"; -import { checkQuota } from "@/lib/quota"; import { requireAuth } from "@/lib/session"; -import { getJobDir } from "@/lib/storage"; import type { CreateJobPayload } from "@/lib/types"; -function validateItemMetadata(metadata: CreateJobPayload["items"][0]["metadata"]) { - if (!metadata.title?.trim()) return "Each video must have a title"; - if (!isAllowedResolution(metadata.resolution)) return "Invalid resolution"; - if (!["PUBLIC", "PRIVATE", "UNLISTED"].includes(metadata.privacy)) { - return "Invalid privacy setting"; - } - return null; -} +export const maxDuration = 120; export async function POST(req: NextRequest) { const { error, user } = await requireAuth(); @@ -25,102 +13,29 @@ export async function POST(req: NextRequest) { const body = (await req.json()) as CreateJobPayload; - if (!body.imagePath || !body.items?.length) { - return NextResponse.json({ error: "Image and at least one audio file required" }, { status: 400 }); - } - - for (const item of body.items) { - const metaError = validateItemMetadata(item.metadata); - if (metaError) { - return NextResponse.json({ error: metaError }, { status: 400 }); - } - if (user.plan === "FREE" && !item.metadata.includeWatermark) { - return NextResponse.json({ error: "Watermark is required on the free plan" }, { status: 400 }); - } - } - - const quotaCheck = await checkQuota(user.id, body.items.length); - if (!quotaCheck.ok) { - return NextResponse.json({ error: quotaCheck.error }, { status: 403 }); - } - try { - await fs.access(body.imagePath); - for (const item of body.items) { - await fs.access(item.audioPath); - const stat = await fs.stat(item.audioPath); - if (stat.size > FREE_PLAN.maxFileSizeBytes) { - return NextResponse.json({ error: `Audio file ${item.audioFilename} exceeds size limit` }, { status: 400 }); - } + const job = await createVideoJob(user, body); + return NextResponse.json({ jobId: job.id }); + } catch (err) { + if (err instanceof PremiumRequiredError) { + return NextResponse.json(premiumRequiredResponse(err.message), { status: 403 }); } - const imageStat = await fs.stat(body.imagePath); - if (imageStat.size > FREE_PLAN.maxFileSizeBytes) { - return NextResponse.json({ error: "Image exceeds size limit" }, { status: 400 }); - } - } catch { - return NextResponse.json({ error: "One or more uploaded files not found" }, { status: 400 }); + const message = err instanceof Error ? err.message : "Failed to create job"; + const status = message.includes("Quota exceeded") ? 403 : 400; + return NextResponse.json({ error: message }, { status }); } - - const job = await prisma.job.create({ - data: { - userId: user.id, - imagePath: body.imagePath, - items: { - create: body.items.map((item) => ({ - audioPath: item.audioPath, - audioFilename: item.audioFilename, - title: item.metadata.title.trim(), - description: item.metadata.description || "", - tags: item.metadata.tags || "", - privacy: item.metadata.privacy as Privacy, - categoryId: item.metadata.categoryId || "10", - resolution: item.metadata.resolution, - notifySubscribers: item.metadata.notifySubscribers, - madeForKids: item.metadata.madeForKids, - embeddable: item.metadata.embeddable, - creativeCommons: item.metadata.creativeCommons, - includeWatermark: user.plan === "FREE" ? true : item.metadata.includeWatermark, - })), - }, - }, - include: { items: true }, - }); - - const jobDir = getJobDir(user.id, job.id); - await fs.mkdir(jobDir, { recursive: true }); - - const imageExt = path.extname(body.imagePath); - const newImagePath = path.join(jobDir, `image${imageExt}`); - await fs.copyFile(body.imagePath, newImagePath); - await prisma.job.update({ where: { id: job.id }, data: { imagePath: newImagePath } }); - - for (const item of job.items) { - const audioExt = path.extname(item.audioPath); - const newAudioPath = path.join(jobDir, `${item.id}${audioExt}`); - await fs.copyFile(item.audioPath, newAudioPath); - await prisma.jobItem.update({ - where: { id: item.id }, - data: { audioPath: newAudioPath }, - }); - - await enqueueVideoJob({ - jobItemId: item.id, - userId: user.id, - jobId: job.id, - }); - } - - return NextResponse.json({ jobId: job.id }); } -export async function GET() { +export async function GET(req: NextRequest) { const { error, user } = await requireAuth(); if (error || !user) return error!; + const limit = Math.min(Number(req.nextUrl.searchParams.get("limit")) || 20, 100); + const jobs = await prisma.job.findMany({ where: { userId: user.id }, orderBy: { createdAt: "desc" }, - take: 20, + take: limit, include: { items: { select: { @@ -135,5 +50,13 @@ export async function GET() { }, }); - return NextResponse.json({ jobs }); + return NextResponse.json({ + jobs: jobs.map((job) => ({ + id: job.id, + status: job.status, + createdAt: job.createdAt.toISOString(), + completedAt: job.completedAt?.toISOString() ?? null, + items: job.items, + })), + }); } diff --git a/app/api/stripe/webhook/route.ts b/app/api/stripe/webhook/route.ts new file mode 100644 index 0000000..d0351f1 --- /dev/null +++ b/app/api/stripe/webhook/route.ts @@ -0,0 +1,255 @@ +import { NextRequest, NextResponse } from "next/server"; +import type Stripe from "stripe"; +import { + activateProPlan, + applyMonthlyCreditRenewal, + downgradeToFreePlan, + grantExtraCredits, +} from "@/lib/billing"; +import { monthlyCreditsForPlan } from "@/lib/credits"; +import { prisma } from "@/lib/db"; +import { getNextMonthlyQuotaReset } from "@/lib/plans"; +import { getStripe } from "@/lib/stripe"; + +export const runtime = "nodejs"; + +/** Stripe API 2025+: subscription lives on parent.subscription_details, not invoice.subscription. */ +function subscriptionIdFromInvoice(invoice: Stripe.Invoice): string | null { + const legacy = (invoice as Stripe.Invoice & { + subscription?: string | Stripe.Subscription | null; + }).subscription; + if (typeof legacy === "string" && legacy) return legacy; + if (legacy && typeof legacy === "object" && "id" in legacy && legacy.id) { + return String(legacy.id); + } + + const parent = ( + invoice as Stripe.Invoice & { + parent?: { + type?: string | null; + subscription_details?: { subscription?: string | Stripe.Subscription | null } | null; + } | null; + } + ).parent; + + const fromParent = parent?.subscription_details?.subscription; + if (typeof fromParent === "string" && fromParent) return fromParent; + if (fromParent && typeof fromParent === "object" && "id" in fromParent && fromParent.id) { + return String(fromParent.id); + } + return null; +} + +async function fulfillFreeTopUp(session: Stripe.Checkout.Session) { + const purchaseId = session.metadata?.purchaseId; + const userId = session.metadata?.userId; + if (!purchaseId || !userId) { + console.error("[stripe] free_top_up missing metadata", session.id); + return; + } + + const purchase = await prisma.creditPurchase.findUnique({ where: { id: purchaseId } }); + if (!purchase || purchase.userId !== userId) { + throw new Error(`Purchase not found: ${purchaseId}`); + } + if (purchase.status === "COMPLETED") return; + + await grantExtraCredits(userId, purchase.credits); + + await prisma.creditPurchase.update({ + where: { id: purchaseId }, + data: { + status: "COMPLETED", + completedAt: new Date(), + stripeSessionId: session.id, + stripePaymentIntentId: + typeof session.payment_intent === "string" + ? session.payment_intent + : session.payment_intent?.id ?? null, + }, + }); +} + +async function fulfillProCheckout(session: Stripe.Checkout.Session) { + const userId = session.metadata?.userId; + if (!userId) { + console.error("[stripe] pro_subscription missing userId", session.id); + return; + } + + const subscriptionId = + typeof session.subscription === "string" + ? session.subscription + : session.subscription?.id ?? null; + + const customerId = + typeof session.customer === "string" ? session.customer : session.customer?.id ?? null; + + await activateProPlan(userId, { + stripeCustomerId: customerId, + stripeSubscriptionId: subscriptionId, + }); +} + +async function handleInvoicePaymentSucceeded(invoice: Stripe.Invoice) { + const subscriptionId = subscriptionIdFromInvoice(invoice); + if (!subscriptionId) { + console.warn("[stripe] invoice.payment_succeeded without subscription id", invoice.id); + return; + } + + // Skip the first invoice if checkout already activated Pro (billing_reason subscription_create) + const user = await prisma.user.findFirst({ + where: { stripeSubscriptionId: subscriptionId }, + }); + if (!user) { + // Fallback: metadata on subscription via Stripe retrieve is optional; try customer + const customerId = + typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id; + if (!customerId) return; + const byCustomer = await prisma.user.findFirst({ + where: { stripeCustomerId: customerId }, + }); + if (!byCustomer) return; + await applyMonthlyCreditRenewal(byCustomer.id, { + plan: "PREMIUM", + newMonthlyCredits: monthlyCreditsForPlan("PREMIUM"), + quotaResetAt: getNextMonthlyQuotaReset(), + }); + await prisma.user.update({ + where: { id: byCustomer.id }, + data: { + stripeSubscriptionId: subscriptionId, + subscribedAt: byCustomer.subscribedAt ?? new Date(), + }, + }); + return; + } + + // Renewal: rollover unused + new monthly, trim to MAX_CREDIT_CAP (30) + await applyMonthlyCreditRenewal(user.id, { + plan: "PREMIUM", + newMonthlyCredits: monthlyCreditsForPlan("PREMIUM"), + quotaResetAt: getNextMonthlyQuotaReset(), + }); +} + +async function handleSubscriptionDeleted(subscription: Stripe.Subscription) { + const user = await prisma.user.findFirst({ + where: { stripeSubscriptionId: subscription.id }, + }); + if (!user) return; + await downgradeToFreePlan(user.id); +} + +/** Stripe retries failed invoices; when status is unpaid/canceled, revoke Pro access. */ +async function handleSubscriptionUpdated(subscription: Stripe.Subscription) { + const terminal = new Set(["canceled", "unpaid", "incomplete_expired"]); + if (!terminal.has(subscription.status)) return; + + const user = await prisma.user.findFirst({ + where: { stripeSubscriptionId: subscription.id }, + }); + if (!user || user.plan !== "PREMIUM") return; + await downgradeToFreePlan(user.id); +} + +async function handleInvoicePaymentFailed(invoice: Stripe.Invoice) { + const subscriptionId = subscriptionIdFromInvoice(invoice); + if (!subscriptionId) return; + + const user = await prisma.user.findFirst({ + where: { + OR: [ + { stripeSubscriptionId: subscriptionId }, + ...(typeof invoice.customer === "string" + ? [{ stripeCustomerId: invoice.customer }] + : invoice.customer?.id + ? [{ stripeCustomerId: invoice.customer.id }] + : []), + ], + }, + }); + if (!user) return; + + // Soft signal only Stripe Smart Retries continue. Do not downgrade on first failure. + console.warn( + "[stripe] invoice.payment_failed", + invoice.id, + "user", + user.id, + "attempt", + invoice.attempt_count, + ); +} + +export async function POST(req: NextRequest) { + const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; + if (!webhookSecret) { + return NextResponse.json({ error: "Webhook not configured" }, { status: 503 }); + } + + const signature = req.headers.get("stripe-signature"); + if (!signature) { + return NextResponse.json({ error: "Missing signature" }, { status: 400 }); + } + + const rawBody = await req.text(); + let event: Stripe.Event; + + try { + const stripe = getStripe(); + event = stripe.webhooks.constructEvent(rawBody, signature, webhookSecret); + } catch (err) { + const message = err instanceof Error ? err.message : "Invalid signature"; + return NextResponse.json({ error: message }, { status: 400 }); + } + + try { + if (event.type === "checkout.session.completed") { + const session = event.data.object as Stripe.Checkout.Session; + if (session.payment_status === "paid" || session.status === "complete") { + const type = session.metadata?.type; + if (type === "pro_subscription" || session.mode === "subscription") { + await fulfillProCheckout(session); + } else if (type === "free_top_up") { + await fulfillFreeTopUp(session); + } else if (session.metadata?.purchaseId) { + // Legacy PAYG purchases: grant metadata credits as extras + const userId = session.metadata.userId; + const credits = Number(session.metadata.credits); + const purchaseId = session.metadata.purchaseId; + if (userId && purchaseId && Number.isFinite(credits) && credits > 0) { + const purchase = await prisma.creditPurchase.findUnique({ + where: { id: purchaseId }, + }); + if (purchase && purchase.status !== "COMPLETED") { + await grantExtraCredits(userId, credits); + await prisma.creditPurchase.update({ + where: { id: purchaseId }, + data: { + status: "COMPLETED", + completedAt: new Date(), + stripeSessionId: session.id, + }, + }); + } + } + } + } + } else if (event.type === "invoice.payment_succeeded") { + await handleInvoicePaymentSucceeded(event.data.object as Stripe.Invoice); + } else if (event.type === "invoice.payment_failed") { + await handleInvoicePaymentFailed(event.data.object as Stripe.Invoice); + } else if (event.type === "customer.subscription.updated") { + await handleSubscriptionUpdated(event.data.object as Stripe.Subscription); + } else if (event.type === "customer.subscription.deleted") { + await handleSubscriptionDeleted(event.data.object as Stripe.Subscription); + } + } catch (err) { + console.error("[stripe] webhook handler error", event.type, event.id, err); + return NextResponse.json({ error: "Handler failed" }, { status: 500 }); + } + + return NextResponse.json({ received: true }); +} diff --git a/app/api/upload/route.ts b/app/api/upload/route.ts index 8bee9d7..1abdf42 100644 --- a/app/api/upload/route.ts +++ b/app/api/upload/route.ts @@ -1,22 +1,9 @@ import { NextRequest, NextResponse } from "next/server"; -import fs from "fs/promises"; -import path from "path"; -import { FREE_PLAN } from "@/lib/constants"; +import { PremiumRequiredError, premiumRequiredResponse } from "@/lib/entitlements"; +import { saveUploadedFile, type UploadFileType } from "@/lib/jobs/create-job"; import { getSessionUser } from "@/lib/session"; -import { getUploadDir } from "@/lib/storage"; -const ALLOWED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/webp", "image/gif"]; -const ALLOWED_AUDIO_TYPES = [ - "audio/mpeg", - "audio/mp3", - "audio/wav", - "audio/x-wav", - "audio/ogg", - "audio/flac", - "audio/aac", - "audio/mp4", - "audio/x-m4a", -]; +export const maxDuration = 120; export async function POST(req: NextRequest) { const user = await getSessionUser(); @@ -27,34 +14,29 @@ export async function POST(req: NextRequest) { const formData = await req.formData(); const file = formData.get("file") as File | null; const type = formData.get("type") as string | null; + const sessionKey = (formData.get("session") as string | null)?.trim() || undefined; - if (!file || !type) { - return NextResponse.json({ error: "Missing file or type" }, { status: 400 }); - } - - if (file.size > FREE_PLAN.maxFileSizeBytes) { + if ( + !file || + !type || + (type !== "image" && type !== "audio" && type !== "logo" && type !== "font") + ) { return NextResponse.json( - { error: `File exceeds ${FREE_PLAN.maxFileSizeBytes / (1024 * 1024)} MB limit` }, + { error: "Missing file or type (image | audio | logo | font)" }, { status: 400 }, ); } - const allowedTypes = type === "image" ? ALLOWED_IMAGE_TYPES : ALLOWED_AUDIO_TYPES; - if (!allowedTypes.includes(file.type) && !file.name.match(/\.(mp3|wav|ogg|flac|aac|m4a|jpg|jpeg|png|webp|gif)$/i)) { - return NextResponse.json({ error: "Invalid file type" }, { status: 400 }); + try { + const result = await saveUploadedFile(user.id, file, type as UploadFileType, user.plan, { + sessionKey, + }); + return NextResponse.json(result); + } catch (err) { + if (err instanceof PremiumRequiredError) { + return NextResponse.json(premiumRequiredResponse(err.message), { status: 403 }); + } + const message = err instanceof Error ? err.message : "Upload failed"; + return NextResponse.json({ error: message }, { status: 400 }); } - - const sessionDir = path.join(getUploadDir(), user.id, "sessions", Date.now().toString()); - await fs.mkdir(sessionDir, { recursive: true }); - - const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, "_"); - const filePath = path.join(sessionDir, safeName); - const buffer = Buffer.from(await file.arrayBuffer()); - await fs.writeFile(filePath, buffer); - - return NextResponse.json({ - path: filePath, - filename: file.name, - size: file.size, - }); } diff --git a/app/api/v1/jobs/[id]/route.ts b/app/api/v1/jobs/[id]/route.ts new file mode 100644 index 0000000..aca6d3d --- /dev/null +++ b/app/api/v1/jobs/[id]/route.ts @@ -0,0 +1,47 @@ +import { NextRequest, NextResponse } from "next/server"; +import { requirePaidApiUser } from "@/lib/api-auth"; +import { prisma } from "@/lib/db"; + +export async function GET( + _req: NextRequest, + { params }: { params: Promise<{ id: string }> }, +) { + const { error, user } = await requirePaidApiUser(_req); + if (error || !user) return error!; + + const { id } = await params; + + const job = await prisma.job.findFirst({ + where: { id, userId: user.id }, + include: { + items: { + orderBy: { audioFilename: "asc" }, + select: { + id: true, + audioFilename: true, + title: true, + description: true, + tags: true, + privacy: true, + categoryId: true, + resolution: true, + status: true, + youtubeVideoId: true, + error: true, + }, + }, + }, + }); + + if (!job) { + return NextResponse.json({ error: "Job not found" }, { status: 404 }); + } + + return NextResponse.json({ + id: job.id, + status: job.status, + createdAt: job.createdAt.toISOString(), + completedAt: job.completedAt?.toISOString() ?? null, + items: job.items, + }); +} diff --git a/app/api/v1/jobs/batch/route.ts b/app/api/v1/jobs/batch/route.ts new file mode 100644 index 0000000..e0eb38f --- /dev/null +++ b/app/api/v1/jobs/batch/route.ts @@ -0,0 +1,159 @@ +import { NextRequest, NextResponse } from "next/server"; +import { Privacy } from "@prisma/client"; +import { requirePaidApiUser } from "@/lib/api-auth"; +import { PremiumRequiredError, premiumRequiredResponse } from "@/lib/entitlements"; +import { createVideoJob, saveUploadedFile } from "@/lib/jobs/create-job"; +import { + applyCreatePlaylistToItems, + parseCreatePlaylistInput, +} from "@/lib/jobs/resolve-playlist"; +import { filenameWithoutExtension } from "@/lib/constants"; +import { mapWithConcurrency } from "@/lib/fs-utils"; +import { getPlanLimits } from "@/lib/plans"; +import { checkQuota } from "@/lib/quota"; +import type { CreateJobPayload, CreatePlaylistRequest, ItemMetadata } from "@/lib/types"; + +export const maxDuration = 300; + +type BatchItemInput = Partial & { + filename?: string; + title?: string; +}; + +function defaultMetadata(title: string): ItemMetadata { + return { + title, + songTitle: null, + description: "", + tags: "", + privacy: "PUBLIC", + categoryId: "10", + resolution: "1920x1080", + notifySubscribers: true, + madeForKids: false, + embeddable: true, + creativeCommons: false, + includeWatermark: false, + playlistId: null, + artist: null, + }; +} + +export async function POST(req: NextRequest) { + try { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + const formData = await req.formData(); + const image = formData.get("image") as File | null; + const audioFiles = formData.getAll("audio").filter((f): f is File => f instanceof File); + const metadataRaw = formData.get("metadata"); + + if (!image || audioFiles.length === 0) { + return NextResponse.json( + { error: "Provide multipart fields: image (file), audio (one or more files)" }, + { status: 400 }, + ); + } + + const limits = getPlanLimits(user.plan); + if (audioFiles.length > limits.maxBatchSize) { + return NextResponse.json( + { error: `Batch limit exceeded. Your plan allows up to ${limits.maxBatchSize} files per batch.` }, + { status: 400 }, + ); + } + + const quotaCheck = await checkQuota(user.id, audioFiles.length); + if (!quotaCheck.ok) { + return NextResponse.json({ error: quotaCheck.error }, { status: 403 }); + } + + let itemMeta: BatchItemInput[] = []; + let defaults: Partial = {}; + let createPlaylist: CreatePlaylistRequest | null = null; + + if (metadataRaw) { + try { + const parsed = JSON.parse(String(metadataRaw)) as { + items?: BatchItemInput[]; + defaults?: Partial; + createPlaylist?: unknown; + }; + itemMeta = parsed.items ?? []; + defaults = parsed.defaults ?? {}; + createPlaylist = parseCreatePlaylistInput(parsed.createPlaylist); + if (parsed.createPlaylist && !createPlaylist) { + return NextResponse.json( + { + error: + "createPlaylist requires a title. Optional: description, privacy (public|unlisted|private)", + }, + { status: 400 }, + ); + } + } catch { + return NextResponse.json({ error: "metadata must be valid JSON" }, { status: 400 }); + } + } + + const sessionKey = Date.now().toString(); + const imageUpload = await saveUploadedFile(user.id, image, "image", user.plan, { sessionKey }); + + const uploads = await mapWithConcurrency(audioFiles, 4, (audio) => + saveUploadedFile(user.id, audio, "audio", user.plan, { sessionKey }), + ); + + const builtItems: CreateJobPayload["items"] = uploads.map((upload, i) => { + const audio = audioFiles[i]; + const metaInput = itemMeta[i] ?? itemMeta.find((m) => m.filename === audio.name) ?? {}; + const base = defaultMetadata( + metaInput.title?.trim() || filenameWithoutExtension(audio.name), + ); + const metadata: ItemMetadata = { + ...base, + ...defaults, + ...metaInput, + title: (metaInput.title ?? defaults.title ?? base.title).trim(), + privacy: (metaInput.privacy ?? defaults.privacy ?? base.privacy) as Privacy, + }; + + return { + audioPath: upload.path, + audioFilename: upload.filename, + metadata, + }; + }); + + const { items, playlist } = await applyCreatePlaylistToItems(user, builtItems, createPlaylist); + + const job = await createVideoJob(user, { + imagePath: imageUpload.path, + items, + }); + + return NextResponse.json({ + jobId: job.id, + itemCount: job.items.length, + status: job.status, + playlist: playlist + ? { id: playlist.id, title: playlist.title, privacy: playlist.privacy } + : null, + }); + } catch (err) { + console.error("Batch upload failed:", err); + if (err instanceof PremiumRequiredError) { + return NextResponse.json(premiumRequiredResponse(err.message), { status: 403 }); + } + const message = err instanceof Error ? err.message : "Batch upload failed"; + const status = + message.includes("Batch limit exceeded") + ? 400 + : message.includes("Quota exceeded") || + message.includes("Not enough credits") || + message.includes("Payment Required") + ? 402 + : 500; + return NextResponse.json({ error: message }, { status }); + } +} diff --git a/app/api/v1/jobs/route.ts b/app/api/v1/jobs/route.ts new file mode 100644 index 0000000..1baf3c3 --- /dev/null +++ b/app/api/v1/jobs/route.ts @@ -0,0 +1,97 @@ +import { NextRequest, NextResponse } from "next/server"; +import { requirePaidApiUser } from "@/lib/api-auth"; +import { PremiumRequiredError, premiumRequiredResponse } from "@/lib/entitlements"; +import { createVideoJob } from "@/lib/jobs/create-job"; +import { + applyCreatePlaylistToItems, + parseCreatePlaylistInput, +} from "@/lib/jobs/resolve-playlist"; +import { prisma } from "@/lib/db"; +import type { CreateJobPayload } from "@/lib/types"; + +export async function POST(req: NextRequest) { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + const body = (await req.json()) as CreateJobPayload & { createPlaylist?: unknown }; + + try { + const createPlaylist = parseCreatePlaylistInput(body.createPlaylist); + if (body.createPlaylist && !createPlaylist) { + return NextResponse.json( + { + error: + "createPlaylist requires a title. Optional: description, privacy (public|unlisted|private)", + }, + { status: 400 }, + ); + } + + const { items, playlist } = await applyCreatePlaylistToItems( + user, + body.items, + createPlaylist, + ); + + const job = await createVideoJob(user, { + imagePath: body.imagePath, + items, + }); + + return NextResponse.json({ + jobId: job.id, + itemCount: job.items.length, + status: job.status, + playlist: playlist + ? { id: playlist.id, title: playlist.title, privacy: playlist.privacy } + : null, + }); + } catch (err) { + if (err instanceof PremiumRequiredError) { + return NextResponse.json(premiumRequiredResponse(err.message), { status: 403 }); + } + const message = err instanceof Error ? err.message : "Failed to create job"; + const status = + message.includes("Quota exceeded") || + message.includes("Not enough credits") || + message.includes("Payment Required") + ? 402 + : 400; + return NextResponse.json({ error: message }, { status }); + } +} + +export async function GET(req: NextRequest) { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + const limit = Math.min(Number(req.nextUrl.searchParams.get("limit")) || 20, 100); + + const jobs = await prisma.job.findMany({ + where: { userId: user.id }, + orderBy: { createdAt: "desc" }, + take: limit, + include: { + items: { + select: { + id: true, + audioFilename: true, + title: true, + status: true, + youtubeVideoId: true, + error: true, + }, + }, + }, + }); + + return NextResponse.json({ + jobs: jobs.map((job) => ({ + id: job.id, + status: job.status, + createdAt: job.createdAt.toISOString(), + completedAt: job.completedAt?.toISOString() ?? null, + items: job.items, + })), + }); +} diff --git a/app/api/v1/playlists/route.ts b/app/api/v1/playlists/route.ts new file mode 100644 index 0000000..52523fc --- /dev/null +++ b/app/api/v1/playlists/route.ts @@ -0,0 +1,44 @@ +import { NextRequest, NextResponse } from "next/server"; +import { requirePaidApiUser } from "@/lib/api-auth"; +import { parseCreatePlaylistInput } from "@/lib/jobs/resolve-playlist"; +import { createYouTubePlaylist, listYouTubePlaylists } from "@/lib/youtube/upload"; + +export async function GET(req: NextRequest) { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + try { + const playlists = await listYouTubePlaylists(user.id); + return NextResponse.json({ playlists }); + } catch (err) { + console.error("List playlists failed:", err); + const message = err instanceof Error ? err.message : "Failed to list playlists"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} + +export async function POST(req: NextRequest) { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + try { + const body = await req.json(); + const input = parseCreatePlaylistInput(body); + if (!input) { + return NextResponse.json( + { + error: + "Provide JSON body: { title, description?, privacy? } where privacy is public|unlisted|private", + }, + { status: 400 }, + ); + } + + const playlist = await createYouTubePlaylist(user.id, input); + return NextResponse.json({ playlist }); + } catch (err) { + console.error("Create playlist failed:", err); + const message = err instanceof Error ? err.message : "Failed to create playlist"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} diff --git a/app/api/v1/route.ts b/app/api/v1/route.ts new file mode 100644 index 0000000..74255cc --- /dev/null +++ b/app/api/v1/route.ts @@ -0,0 +1,64 @@ +import { NextResponse } from "next/server"; +import { API_DOCS_URL } from "@/lib/plans"; + +export async function GET() { + return NextResponse.json({ + name: "Songs2VID API", + version: "1.0", + authentication: "Authorization: Bearer ", + requirements: ["Pro subscription", "YouTube account connected"], + rateLimit: "60 requests per minute per account (plus any approved bonus)", + guidance: { + recommended: + "For most jobs (especially 5+ audio files): POST /api/v1/upload per file, then POST /api/v1/jobs with the returned paths", + batch: + "POST /api/v1/jobs/batch is for small packs only. Large multipart bodies may fail with 'failed to parse body as FormData'", + }, + endpoints: [ + { + method: "POST", + path: "/api/v1/upload", + description: + "Upload image, audio, PNG logo, or .ttf/.otf font (Pro typography; font ≤10MB)", + body: "multipart/form-data: file, type (image|audio|logo|font)", + }, + { + method: "POST", + path: "/api/v1/jobs", + description: + "Create a video job from uploaded file paths. Pro: layout templates, blur, watermark, per-item covers", + body: "application/json: { imagePath, items[{ audioPath, audioFilename, metadata }] }", + }, + { + method: "POST", + path: "/api/v1/jobs/batch", + description: + "One-shot batch for small packs only; large uploads may fail FormData parsing; prefer upload + jobs", + body: "multipart/form-data: image, audio[] (repeatable), metadata? (JSON string)", + }, + { + method: "GET", + path: "/api/v1/playlists", + description: "List YouTube playlists for the authenticated Pro account", + }, + { + method: "POST", + path: "/api/v1/playlists", + description: "Create a YouTube playlist", + body: "application/json: { title, description?, privacy? (public|unlisted|private) }", + }, + { + method: "GET", + path: "/api/v1/jobs", + description: "List recent jobs", + query: "limit (default 20, max 100)", + }, + { + method: "GET", + path: "/api/v1/jobs/:id", + description: "Get job status and item details", + }, + ], + docs: API_DOCS_URL, + }); +} diff --git a/app/api/v1/upload/route.ts b/app/api/v1/upload/route.ts new file mode 100644 index 0000000..2809834 --- /dev/null +++ b/app/api/v1/upload/route.ts @@ -0,0 +1,37 @@ +import { NextRequest, NextResponse } from "next/server"; +import { requirePaidApiUser } from "@/lib/api-auth"; +import { PremiumRequiredError, premiumRequiredResponse } from "@/lib/entitlements"; +import { saveUploadedFile, type UploadFileType } from "@/lib/jobs/create-job"; + +export const maxDuration = 120; + +export async function POST(req: NextRequest) { + const { error, user } = await requirePaidApiUser(req); + if (error || !user) return error!; + + const formData = await req.formData(); + const file = formData.get("file") as File | null; + const type = formData.get("type") as string | null; + + if ( + !file || + !type || + (type !== "image" && type !== "audio" && type !== "logo" && type !== "font") + ) { + return NextResponse.json( + { error: "Provide multipart fields: file, type (image|audio|logo|font)" }, + { status: 400 }, + ); + } + + try { + const result = await saveUploadedFile(user.id, file, type as UploadFileType, user.plan); + return NextResponse.json(result); + } catch (err) { + if (err instanceof PremiumRequiredError) { + return NextResponse.json(premiumRequiredResponse(err.message), { status: 403 }); + } + const message = err instanceof Error ? err.message : "Upload failed"; + return NextResponse.json({ error: message }, { status: 400 }); + } +} diff --git a/app/api/youtube/playlists/route.ts b/app/api/youtube/playlists/route.ts new file mode 100644 index 0000000..13f0c07 --- /dev/null +++ b/app/api/youtube/playlists/route.ts @@ -0,0 +1,63 @@ +import { NextRequest, NextResponse } from "next/server"; +import { hasProFeatures } from "@/lib/edition"; +import { getSessionUser } from "@/lib/session"; +import { parseCreatePlaylistInput } from "@/lib/jobs/resolve-playlist"; +import { createYouTubePlaylist, listYouTubePlaylists } from "@/lib/youtube/upload"; + +async function requirePremiumYouTubeUser() { + const user = await getSessionUser(); + if (!user) { + return { error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }), user: null }; + } + if (!hasProFeatures(user.plan)) { + return { + error: NextResponse.json( + { error: "Playlist features are available on the Pro plan only" }, + { status: 403 }, + ), + user: null, + }; + } + if (!user.youtubeConnection) { + return { + error: NextResponse.json({ error: "YouTube account not connected" }, { status: 403 }), + user: null, + }; + } + return { error: null, user }; +} + +export async function GET() { + const { error, user } = await requirePremiumYouTubeUser(); + if (error || !user) return error!; + + try { + const playlists = await listYouTubePlaylists(user.id); + return NextResponse.json({ playlists }); + } catch (err) { + const message = err instanceof Error ? err.message : "Failed to list playlists"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} + +export async function POST(req: NextRequest) { + const { error, user } = await requirePremiumYouTubeUser(); + if (error || !user) return error!; + + try { + const body = await req.json(); + const input = parseCreatePlaylistInput(body); + if (!input) { + return NextResponse.json( + { error: "Provide title, and optionally description and privacy (public|unlisted|private)" }, + { status: 400 }, + ); + } + + const playlist = await createYouTubePlaylist(user.id, input); + return NextResponse.json({ playlist }); + } catch (err) { + const message = err instanceof Error ? err.message : "Failed to create playlist"; + return NextResponse.json({ error: message }, { status: 500 }); + } +} diff --git a/app/dashboard/history/page.tsx b/app/dashboard/history/page.tsx new file mode 100644 index 0000000..91e6e5c --- /dev/null +++ b/app/dashboard/history/page.tsx @@ -0,0 +1,19 @@ +import { redirect } from "next/navigation"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/lib/auth"; +import { DashboardShell } from "@/components/DashboardShell"; +import { JobHistory } from "@/components/JobHistory"; + +export default async function HistoryPage() { + const session = await getServerSession(authOptions); + if (!session) redirect("/"); + + return ( + +
+

History

+ +
+
+ ); +} diff --git a/app/dashboard/page.tsx b/app/dashboard/page.tsx index bd04417..091fa1d 100644 --- a/app/dashboard/page.tsx +++ b/app/dashboard/page.tsx @@ -1,33 +1,21 @@ import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; +import { DashboardShell } from "@/components/DashboardShell"; +import { RecentYouTubeLimitAlert } from "@/components/RecentYouTubeLimitAlert"; import { UploadForm } from "@/components/UploadForm"; -import { SignOutButton } from "@/components/SignOutButton"; export default async function DashboardPage() { const session = await getServerSession(authOptions); if (!session) redirect("/"); return ( -
-
-
-
- - s2yt - - {session.user.channelTitle && ( -

Channel: {session.user.channelTitle}

- )} -
- -
-
- +

Create Videos

+
-
+ ); } diff --git a/app/dashboard/settings/page.tsx b/app/dashboard/settings/page.tsx new file mode 100644 index 0000000..566e551 --- /dev/null +++ b/app/dashboard/settings/page.tsx @@ -0,0 +1,242 @@ +import Link from "next/link"; +import { redirect } from "next/navigation"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/lib/auth"; +import { prisma } from "@/lib/db"; +import { AccountPrivacyActions } from "@/components/AccountPrivacyActions"; +import { CreditPurchasePanel } from "@/components/CreditPurchasePanel"; +import { PlanBillingActions } from "@/components/PlanBillingActions"; +import { DashboardShell } from "@/components/DashboardShell"; +import { UpgradeProButton } from "@/components/UpgradeProButton"; +import { getUserApiKeyStatus } from "@/lib/api-keys"; +import { getApiRateLimitStatus } from "@/lib/api-rate-limit"; +import { ApiKeySettings } from "@/components/ApiKeySettings"; +import { hasProFeatures, isSelfHostedEdition } from "@/lib/edition"; +import { EXTENSION_KIND, getQuotaExtensionUsage } from "@/lib/quota-extensions"; +import { getQuotaInfo } from "@/lib/quota"; +import { isBillingDevMock, isStripeConfigured } from "@/lib/stripe"; +import { CreditPurchaseStatus } from "@prisma/client"; + +const PLAN_LABELS = { + FREE: "Bedroom Producer", + PREMIUM: "Pro", +} as const; + +function InfoRow({ label, value }: { label: string; value: string }) { + return ( +
+
{label}
+
{value}
+
+ ); +} + +export default async function SettingsPage() { + const session = await getServerSession(authOptions); + if (!session?.user?.email) redirect("/"); + + const user = await prisma.user.findUnique({ + where: { email: session.user.email }, + include: { youtubeConnection: true }, + }); + if (!user) redirect("/"); + + const quota = await getQuotaInfo(user.id); + const selfHosted = isSelfHostedEdition(); + const proFeatures = hasProFeatures(user.plan); + const recentCreditPurchases = await prisma.creditPurchase.findMany({ + where: { userId: user.id, status: CreditPurchaseStatus.COMPLETED }, + orderBy: { completedAt: "desc" }, + take: 5, + }); + const extensionUsage = + !selfHosted && user.plan === "PREMIUM" ? await getQuotaExtensionUsage(user.id) : null; + const apiRateExtensionUsage = proFeatures + ? await getQuotaExtensionUsage(user.id, EXTENSION_KIND.API_RATE_LIMIT) + : null; + const apiKeyStatus = proFeatures ? await getUserApiKeyStatus(user.id) : null; + const apiRateLimit = proFeatures ? await getApiRateLimitStatus(user.id) : null; + const planLabel = selfHosted ? "Self-hosted" : PLAN_LABELS[user.plan]; + const youtube = user.youtubeConnection; + const channelUrl = youtube ? `https://www.youtube.com/channel/${youtube.channelId}` : null; + + return ( + +
+

Settings

+ +
+
+

Account information

+
+ + +
+ +
+

+ YouTube +

+ {youtube ? ( +
+ + +
+ ) : ( +

YouTube account not connected.

+ )} + + {channelUrl && ( + + Go to your channel + + )} + +

+ To refresh your YouTube permissions,{" "} + + sign out and sign in again + + . +

+
+
+ +
+

Plan & billing

+ +
+
+
+

+ Video quota remaining +

+

+ {quota.totalAvailable} + + {" "} + of {quota.limit + quota.extraCredits} videos + +

+
+

+ {quota.used} monthly used + {quota.extraCredits > 0 ? ` · ${quota.extraCredits} extras` : ""} + {quota.bonusQuota > 0 ? ` · +${quota.bonusQuota} bonus` : ""} +

+
+
+
+
+

+ {`Includes monthly + purchased extras · monthly resets on ${quota.resetsIn}`} +

+
+ +
+ + + + {user.plan === "PREMIUM" && user.subscribedAt && ( + + )} + {user.plan === "PREMIUM" && ( + + )} + {extensionUsage && ( + + )} + + +
+ + {user.plan === "FREE" ? ( + <> +

+ for 50 videos/month, 1080p, API access, and lossless audio. +

+ {!selfHosted && ( + ({ + id: p.id, + credits: p.credits, + amountCents: p.amountCents, + completedAt: p.completedAt?.toISOString() ?? null, + }))} + /> + )} + + ) : ( + <> + {extensionUsage && } +

+ Pro uses your monthly allocation first, then any never-expiring extra credits. +

+ + )} +
+ + {proFeatures && apiKeyStatus && apiRateLimit && apiRateExtensionUsage && ( +
+

API access

+ +
+ )} + +
+

Account deletion & data

+

+ Request a copy of your data or permanently delete your account and associated uploads. +

+ +
+
+
+
+ ); +} diff --git a/app/globals.css b/app/globals.css index 3389368..cc93f9a 100644 --- a/app/globals.css +++ b/app/globals.css @@ -3,6 +3,10 @@ @tailwind utilities; @layer base { + html { + scroll-behavior: smooth; + } + body { @apply bg-surface-dark text-gray-100 antialiased; } @@ -12,4 +16,233 @@ .input-field { @apply w-full rounded border border-gray-600 bg-surface-light px-3 py-2 text-sm text-white placeholder-gray-500 focus:border-accent focus:outline-none; } + + .mockup-upload-box { + animation: mockup-border-pulse 3s ease-in-out infinite; + } + + .mockup-upload-box-image { + animation: mockup-border-pulse 3s ease-in-out infinite, + mockup-float 4s ease-in-out infinite; + } + + .mockup-upload-box-audio { + animation: mockup-border-pulse 3s ease-in-out infinite 0.5s, + mockup-float 4s ease-in-out infinite 0.5s; + } + + .mockup-icon-image { + animation: mockup-icon-glow 3s ease-in-out infinite; + } + + .mockup-icon-audio { + animation: mockup-icon-glow 3s ease-in-out infinite 0.5s; + } + + .mockup-progress-shimmer { + animation: mockup-shimmer 2s ease-in-out infinite; + } + + .mockup-dot-1 { + animation: processing-dot 1.4s ease-in-out infinite; + } + + .mockup-dot-2 { + animation: processing-dot 1.4s ease-in-out infinite 0.2s; + } + + .mockup-dot-3 { + animation: processing-dot 1.4s ease-in-out infinite 0.4s; + } + + .benefits-flow-line { + animation: benefits-flow-pulse 2s ease-in-out infinite; + } + + .benefits-process-icon { + animation: benefits-process-pulse 2.5s ease-in-out infinite; + } + + .benefits-flow-path { + stroke-dasharray: 6 8; + animation: benefits-flow-dash 2s linear infinite; + } + + .mobile-sidebar-panel-open { + animation: mobile-sidebar-open 0.42s cubic-bezier(0.22, 1, 0.36, 1) forwards; + } + + .mobile-sidebar-panel-close { + animation: mobile-sidebar-close 0.3s cubic-bezier(0.4, 0, 1, 1) forwards; + } + + .mobile-sidebar-close-btn-open { + animation: mobile-sidebar-close-btn-in 0.35s cubic-bezier(0.22, 1, 0.36, 1) forwards; + } + + .mobile-sidebar-close-btn-close { + animation: mobile-sidebar-close-btn-out 0.2s ease-in forwards; + } + + .mobile-sidebar-link { + @apply relative block overflow-hidden rounded-lg px-4 py-3 text-base font-medium text-gray-300 transition-all duration-300 ease-out; + } + + .mobile-sidebar-link::before { + content: ""; + @apply absolute bottom-2 left-0 top-2 w-1 origin-left scale-y-0 rounded-r bg-accent transition-transform duration-300 ease-out; + } + + .mobile-sidebar-link:hover { + @apply translate-x-1 bg-surface-light text-white shadow-[inset_0_0_0_1px_rgba(74,158,255,0.12)]; + } + + .mobile-sidebar-link:hover::before { + @apply scale-y-100; + } + + .mobile-sidebar-link-active { + @apply bg-surface-light text-white shadow-[inset_0_0_0_1px_rgba(74,158,255,0.2)]; + } + + .mobile-sidebar-link-active::before { + @apply scale-y-100; + } + + .mobile-sidebar-link-danger:hover { + @apply bg-red-500/10 text-red-300 shadow-[inset_0_0_0_1px_rgba(239,68,68,0.2)]; + } + + .mobile-sidebar-link-danger:hover::before { + @apply bg-red-400; + } +} + +@keyframes mockup-float { + 0%, + 100% { + transform: translateY(0); + } + 50% { + transform: translateY(-3px); + } +} + +@keyframes mockup-border-pulse { + 0%, + 100% { + border-color: rgb(75 85 99 / 0.5); + box-shadow: 0 0 0 0 rgb(255 255 255 / 0); + } + 50% { + border-color: rgb(156 163 175 / 0.7); + box-shadow: 0 0 12px 0 rgb(255 255 255 / 0.04); + } +} + +@keyframes mockup-icon-glow { + 0%, + 100% { + opacity: 0.5; + transform: scale(1); + } + 50% { + opacity: 0.85; + transform: scale(1.05); + } +} + +@keyframes mockup-shimmer { + 0% { + left: -30%; + opacity: 0; + } + 30% { + opacity: 0.6; + } + 100% { + left: 100%; + opacity: 0; + } +} + +@keyframes processing-dot { + 0%, + 20% { + opacity: 0; + } + 40%, + 100% { + opacity: 1; + } +} + +@keyframes benefits-flow-pulse { + 0%, + 100% { + opacity: 0.4; + } + 50% { + opacity: 1; + } +} + +@keyframes benefits-process-pulse { + 0%, + 100% { + box-shadow: 0 0 20px rgba(239, 68, 68, 0.2); + } + 50% { + box-shadow: 0 0 28px rgba(239, 68, 68, 0.4); + } +} + +@keyframes benefits-flow-dash { + to { + stroke-dashoffset: -28; + } +} + +@keyframes mobile-sidebar-open { + from { + opacity: 0.85; + transform: translateX(100%) scale(0.96); + } + to { + opacity: 1; + transform: translateX(0) scale(1); + } +} + +@keyframes mobile-sidebar-close { + from { + opacity: 1; + transform: translateX(0) scale(1); + } + to { + opacity: 0.85; + transform: translateX(100%) scale(0.96); + } +} + +@keyframes mobile-sidebar-close-btn-in { + from { + opacity: 0; + transform: scale(0.6) rotate(-90deg); + } + to { + opacity: 1; + transform: scale(1) rotate(0deg); + } +} + +@keyframes mobile-sidebar-close-btn-out { + from { + opacity: 1; + transform: scale(1) rotate(0deg); + } + to { + opacity: 0; + transform: scale(0.6) rotate(90deg); + } } diff --git a/app/icon.png b/app/icon.png new file mode 100644 index 0000000..e77737f Binary files /dev/null and b/app/icon.png differ diff --git a/app/jobs/[id]/page.tsx b/app/jobs/[id]/page.tsx index fc40d32..84cd169 100644 --- a/app/jobs/[id]/page.tsx +++ b/app/jobs/[id]/page.tsx @@ -1,6 +1,7 @@ import { redirect } from "next/navigation"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; +import { DashboardShell } from "@/components/DashboardShell"; import { JobProgress } from "@/components/JobProgress"; type Props = { @@ -14,18 +15,10 @@ export default async function JobPage({ params }: Props) { const { id } = await params; return ( -
-
- -
- +
-
+ ); } diff --git a/app/layout.tsx b/app/layout.tsx index 625ca38..e7ddb11 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -6,8 +6,9 @@ import { Providers } from "./providers"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { - title: "s2yt — Image + Audio to YouTube", - description: "Create and upload YouTube videos from an image and audio files", + title: "Songs2VID", + description: + "Songs2VID is an automation tool that converts your audio and image files into high-quality videos and uploads them directly to YouTube.", }; export default function RootLayout({ @@ -16,8 +17,8 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - + + {children} diff --git a/app/page.tsx b/app/page.tsx index 80902df..4b77fd4 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,68 +1,93 @@ import Link from "next/link"; import { getServerSession } from "next-auth"; import { authOptions } from "@/lib/auth"; +import { BenefitsSection } from "@/components/BenefitsSection"; +import { DownloadSection } from "@/components/DownloadSection"; +import { LandingNavbar } from "@/components/LandingNavbar"; import { SignInButton } from "@/components/SignInButton"; +import { PricingSection } from "@/components/PricingSection"; +import { StepsSection } from "@/components/StepsSection"; +import { Footer } from "@/components/Footer"; +import { SupportSection } from "@/components/SupportSection"; export default async function HomePage() { const session = await getServerSession(authOptions); return (
-
-
- s2yt - {session ? ( - - Dashboard - - ) : ( - - )} +
+ +
- -
-

- Turn images and audio into YouTube videos -

-

- Upload one image and one or more audio files. Each audio becomes its own video - with individual metadata, then uploads directly to your YouTube channel. -

- -
- - - -
- - {session ? ( - - Go to Dashboard - - ) : ( - - )} - -

- Free plan: up to 14 videos/month, 720p max, 30 MB per file -

+ + + + + + + + + +
); } - -function Feature({ title, desc }: { title: string; desc: string }) { - return ( -
-

{title}

-

{desc}

-
- ); -} diff --git a/app/privacy/page.tsx b/app/privacy/page.tsx index c269f85..828896b 100644 --- a/app/privacy/page.tsx +++ b/app/privacy/page.tsx @@ -42,36 +42,60 @@ export default function PrivacyPage() {
  • Your name, email address, and profile image (from Google)
  • OAuth tokens required to authenticate your session
  • YouTube connection data, including channel ID and title
  • -
  • Encrypted YouTube API access and refresh tokens needed to upload videos on your behalf
  • +
  • + Encrypted YouTube API access and refresh tokens needed to upload videos, create or list + playlists, and manage related YouTube actions you request +
  • -

    3.2 Uploaded content

    +

    3.2 Uploaded content and job data

    When you use the service, we temporarily process:

      -
    • Image and audio files you upload
    • -
    • Generated video files
    • -
    • Per-video metadata you provide (title, description, tags, privacy settings, etc.)
    • +
    • Image and audio files you upload (including optional per-track cover images)
    • +
    • Optional custom watermark assets (text, PNG logo, or font files)
    • +
    • Generated video files prior to or during YouTube upload
    • +
    • + Per-video metadata you provide (title, artist, description, tags, privacy, category, + resolution, layout, watermark settings, Made for Kids / embedding / license flags, etc.) +
    • +
    • + Embedded audio tag metadata (for example ID3 title/artist/album) when we read it from + uploaded MP3 files to help prefill fields +
    • +
    • Playlist titles and IDs when you create or attach YouTube playlists through the Service
    -

    3.3 Usage and technical data

    +

    3.3 Usage, API, and technical data

      -
    • Plan type, quota usage, and job processing status
    • +
    • + Plan type, monthly credit allocation, credits used, purchased extra credits, quota reset + dates, and job processing status +
    • +
    • + Quota reset / extension and API rate-limit extension request history (Pro) when you submit + a request +
    • +
    • + API key material for Pro users: we store a cryptographic hash and a short non-secret + prefix; the full key is shown once at creation and is not stored in plaintext +
    • IP address, browser type, device information, and request logs
    • Error reports and operational diagnostics

    3.4 Payment data

    - If you purchase a paid plan, payment processing is handled by our payment provider. We do - not store full payment card details on our servers. We may receive billing status, - subscription identifiers, and transaction references. + If you purchase a Pro subscription or Free-plan extra credits, payment processing is handled + by Stripe. We do not store full payment card details on our servers. We may receive and store + billing status, Stripe customer and subscription identifiers, Checkout session or payment + references, purchase amounts, and credit pack size for fulfilled top-ups.

    4. Why we process your data

    • - Contract performance: to provide video encoding, metadata handling, and - YouTube upload features you request + Contract performance: to provide video encoding, metadata handling, + playlist actions, API access, and YouTube upload features you request
    • Legitimate interests: to secure our service, prevent abuse, improve @@ -91,14 +115,35 @@ export default function PrivacyPage() {
      • Google / YouTube: authentication and video uploads via Google OAuth and - the YouTube Data API + the YouTube Data API. Your use of Google and YouTube is also subject to{" "} + + Google's Privacy Policy + + ,{" "} + + YouTube Terms of Service + + , and related Google API terms
      • Hosting and infrastructure providers: servers, databases, queues, and storage
      • - Payment processors: for Pro and Enterprise billing when available + Stripe: Pro subscriptions, Free-plan credit top-ups, and related billing + webhooks ( + + Stripe Privacy Policy + + )

      @@ -106,26 +151,71 @@ export default function PrivacyPage() { appropriate contractual safeguards where required.

      -

      Google User Data Sharing and Disclosure

      +

      6. Google / YouTube user data (Limited Use)

      - We do not sell, share, transfer, or disclose any Google user data to any third parties. + Songs2VID's use and transfer to any other app of information received from Google APIs + will adhere to the{" "} + + Google API Services User Data Policy + + , including the Limited Use requirements.

      - All user data retrieved via Google OAuth APIs is used solely and strictly for the core - functionality of the application (uploading user-generated media) and is never distributed, - transferred, or disclosed to external services, partners, or third parties. + We request Google OAuth access (including the YouTube Data API scope needed to upload videos + and manage playlists on your connected channel) solely to provide prominent, user-facing + features of Songs2VID: signing you in, connecting your channel, encoding your media, uploading + videos you create, and creating or listing playlists you request. We do not use Google user + data for advertising, credit scoring, or unrelated profiling. +

      +

      + We do not sell, share, transfer, or disclose Google user data obtained via Google OAuth / + YouTube APIs to third parties, except as needed to operate the Service infrastructure under + our control or when required by law. Google / YouTube themselves process data when we call + their APIs on your behalf to perform actions you initiate. +

      +

      + You can revoke Songs2VID's access to your Google account at any time in{" "} + + Google Account → Security → Third-party access + + . After revocation (or when tokens can no longer be refreshed), we will stop using those + credentials and delete or invalidate stored YouTube OAuth tokens and related connection data + associated with that consent, subject to short-term backup or security logs and any legal + retention duties.

      -

      6. Data retention

      +

      7. Data retention and account deletion

        -
      • Uploaded source files and generated outputs are retained only as long as needed to complete your jobs
      • +
      • + Uploaded source files and generated outputs are retained only as long as needed to complete + your jobs (typically removed after successful processing/upload or when no longer required) +
      • Account data is kept while your account remains active
      • Billing records may be retained as required by law
      • Logs are retained for a limited period for security and troubleshooting
      • +
      • + API key hashes are removed when you revoke the key, downgrade from Pro (where applicable), + or delete your account +
      -

      You may request deletion of your account data subject to legal retention obligations.

      +

      + You may delete your account from Dashboard → Settings (account deletion + control) or by emailing{" "} + {LEGAL_OPERATOR.email}. Deletion removes + account and connection data from active systems subject to legal retention obligations + (for example certain billing records). Cancelling a subscription does not by itself delete + your account. +

      -

      7. Self-hosted deployments

      +

      8. Self-hosted deployments

      If you deploy Songs2VID on your own infrastructure, you are the data controller for data processed on your instance. This Privacy Policy applies to the hosted cloud service @@ -133,7 +223,7 @@ export default function PrivacyPage() { hosting for you under contract.

      -

      8. Your rights

      +

      9. Your rights

      Depending on your location, you may have the right to:

      • Access the personal data we hold about you
      • @@ -141,48 +231,57 @@ export default function PrivacyPage() {
      • Restrict or object to certain processing
      • Data portability
      • Withdraw consent where processing is consent-based
      • -
      • Lodge a complaint with a supervisory authority
      • +
      • + Lodge a complaint with a supervisory authority (in Hungary, the Nemzeti Adatvédelmi és + Információszabadság Hatóság — NAIH) +

      To exercise these rights, contact{" "} - {LEGAL_OPERATOR.email}. + {LEGAL_OPERATOR.email}, or use in-product + account deletion where available. You may also revoke Google access as described in section + 6.

      -

      9. Cookies and local storage

      +

      10. Cookies and local storage

      We use essential cookies and similar technologies for authentication, session management, and security. We do not use non-essential tracking cookies unless disclosed separately and enabled with your consent where required.

      -

      10. Security

      +

      11. Security

      We implement appropriate technical and organizational measures to protect your data, - including encryption in transit, access controls, and isolated processing environments. - No method of transmission or storage is 100% secure. + including encryption in transit, encrypted storage of YouTube OAuth tokens at rest, access + controls, and isolated processing environments. No method of transmission or storage is + 100% secure.

      -

      11. International transfers

      +

      12. International transfers

      If data is transferred outside your country, we ensure appropriate safeguards such as - standard contractual clauses or equivalent mechanisms where required by law. + standard contractual clauses or equivalent mechanisms where required by law. Google, Stripe, + and infrastructure providers may process data in other countries as described in their + policies.

      -

      12. Children

      +

      13. Children

      Songs2VID is not directed at children under 16. We do not knowingly collect personal data from children. If you believe a child has provided us data, please contact us.

      -

      13. Changes to this policy

      +

      14. Changes to this policy

      We may update this Privacy Policy from time to time. Material changes will be posted on - this page with an updated effective date. + this page with an updated effective date. If we change how we use Google user data, we will + update this policy and, where required, notify you or obtain renewed consent.

      -

      14. Contact

      +

      15. Contact

      - Questions about this Privacy Policy:{" "} + Questions about this Privacy Policy or our privacy practices:{" "} {LEGAL_OPERATOR.email}

      diff --git a/app/refund/page.tsx b/app/refund/page.tsx new file mode 100644 index 0000000..5e96adf --- /dev/null +++ b/app/refund/page.tsx @@ -0,0 +1,118 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { LegalPageLayout } from "@/components/LegalPageLayout"; +import { LEGAL_OPERATOR } from "@/lib/legal/constants"; + +export const metadata: Metadata = { + title: "Refund Policy | Songs2VID", + description: "Refund and cancellation policy for Songs2VID paid plans.", +}; + +export default function RefundPage() { + return ( + +

      1. Overview

      +

      + This Refund Policy explains how refunds and cancellations work for paid Songs2VID plans and + credit purchases. The free monthly Bedroom Producer allocation does not involve payment and + is not subject to refunds; optional Free-plan extra credit purchases are covered in section + 2. +

      + +

      2. Free plan and extra credits

      +

      + The Bedroom Producer (Free) monthly allocation is provided at no charge. Free users may + optionally purchase extra video credits (currently €0.25 each, 1–15 per checkout, Free extras + balance capped at 15). Once extra credits are granted to your account, those one-time + purchases are generally non-refundable, except where mandatory consumer law + requires otherwise. Credits trimmed under the account accumulation cap (see our{" "} + Terms of Service) are not refundable. +

      + +

      3. Pro subscriptions

      +

      3.1 Billing cycle

      +

      + Pro plans are billed on a recurring monthly basis unless otherwise stated at checkout. + Your subscription renews automatically until cancelled. +

      + +

      3.2 14-day refund window

      +

      + If you are a new Pro subscriber, you may request a full refund within 14 days of + your initial purchase, provided you have not substantially consumed paid entitlements + (for example, a large portion of your monthly video quota or premium-only features). +

      + +

      3.3 After the refund window

      +

      + After 14 days, subscription fees are generally non-refundable for the current billing + period. You may cancel at any time to prevent future renewals. Access typically continues + until the end of the paid period. +

      + +

      3.4 Cancellation

      +

      + You can cancel your subscription through your account billing settings (choose{" "} + cancel immediately or at the end of the billing period) or + via the Stripe customer portal / by contacting{" "} + {LEGAL_OPERATOR.email}. Cancelling at period + end keeps Pro access until the paid period finishes and stops future renewals. Cancelling + immediately ends Pro access and moves you to the Free plan right away (including loss of Pro + API access). Cancellation does not automatically delete your account; use{" "} + Dashboard → Settings or contact us if you want permanent account deletion. +

      + +

      4. Enterprise and custom agreements

      +

      + Enterprise, managed cloud, and paid self-hosted setup fees are governed by the individual + quote or contract signed with us. Refund terms for those services are specified in your + agreement. Contact{" "} + {LEGAL_OPERATOR.salesEmail} for + contract-related billing questions. +

      + +

      5. Non-refundable situations

      +

      Refunds are generally not provided when:

      +
        +
      • The refund request is made outside the applicable refund window
      • +
      • The account was terminated for violation of our Terms of Service
      • +
      • The issue is caused by third-party services outside our control (e.g. YouTube API outages, Google account restrictions)
      • +
      • You simply changed your mind after substantial use of paid quota or features
      • +
      • Purchased Free-plan extra credits have already been granted to your account
      • +
      • Credits expired or were trimmed under the 30-credit accumulation cap
      • +
      • One-time setup or license fees after delivery of agreed setup work, unless required by law or contract
      • +
      + +

      6. Chargebacks

      +

      + If you believe a charge is incorrect, please contact us before initiating a chargeback so + we can resolve the issue promptly. Unjustified chargebacks may result in account suspension. +

      + +

      7. How to request a refund

      +

      Email us at {LEGAL_OPERATOR.email} with:

      +
        +
      • Your account email address
      • +
      • Date of purchase and invoice or transaction reference if available
      • +
      • Reason for the refund request
      • +
      +

      We aim to respond within 5 business days. Approved refunds are issued to the original payment method where possible.

      + +

      8. Consumer rights

      +

      + Nothing in this policy limits mandatory statutory rights you may have as a consumer under + applicable law, including withdrawal rights where required by EU or local consumer + protection regulations. +

      + +

      9. Changes

      +

      + We may update this Refund Policy from time to time. The version published on this page + applies to purchases made after the effective date shown at the top. +

      +
      + ); +} diff --git a/app/terms/page.tsx b/app/terms/page.tsx new file mode 100644 index 0000000..7587897 --- /dev/null +++ b/app/terms/page.tsx @@ -0,0 +1,261 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { LegalPageLayout } from "@/components/LegalPageLayout"; +import { LEGAL_OPERATOR } from "@/lib/legal/constants"; + +export const metadata: Metadata = { + title: "Terms of Service | Songs2VID", + description: "Terms and conditions for using the Songs2VID hosted service.", +}; + +export default function TermsPage() { + return ( + +

      1. Agreement

      +

      + These Terms of Service ("Terms") govern your access to and use of the Songs2VID + website and hosted cloud service (the "Service") operated by{" "} + {LEGAL_OPERATOR.legalName} ("we", "us"). By creating an account or using + the Service, you agree to these Terms. +

      +

      + If you do not agree, do not use the Service. If you self-host the open-source software on + your own infrastructure without using our hosted Service, these Terms apply only to the + extent you use our website, support channels, or paid services we provide. +

      + +

      2. The Service

      +

      + Songs2VID converts user-provided images and audio files into videos and can upload them to + YouTube using your connected Google/YouTube account. Features, limits, and availability + depend on your plan. +

      +
        +
      • + Bedroom Producer (Free): 10 video credits per calendar month, 720p, MP3, + optional Songs2VID watermark (bottom-right), one static cover image per batch; may purchase + limited extra credits as described in Clause 8.2 +
      • +
      • + Independent Artist (Pro): 50 video credits per month, higher resolution and + batch limits, API access, custom watermark/logo/typography, blurred art-track layouts with + position controls, unique image per + track in bulk uploads, and other features as described on our pricing page (€5/month + unless otherwise stated at checkout) +
      • +
      • + Enterprise (Record Label / Studio): custom terms as agreed in writing +
      • +
      +

      + We may modify features, limits, or pricing with reasonable notice where required. The + open-source software is provided separately under its applicable open-source license. +

      + +

      3. Eligibility and accounts

      +
        +
      • You must be at least 16 years old or the age required in your jurisdiction
      • +
      • You must have a valid Google account and authorized access to the YouTube channel you connect
      • +
      • You are responsible for maintaining the security of your account and OAuth connection
      • +
      • You must provide accurate information and promptly update it if it changes
      • +
      + +

      4. Your content and responsibilities

      +

      You retain ownership of content you upload. You grant us a limited license to host, process, encode, transmit, and upload your content solely to provide the Service.

      +

      You represent and warrant that:

      +
        +
      • You own or have all necessary rights to the content you upload
      • +
      • Your content and use of the Service comply with applicable law and YouTube policies
      • +
      • Your content does not infringe third-party rights or contain unlawful material
      • +
      • You have configured metadata (including "Made for Kids" and privacy settings) accurately
      • +
      +

      + You are solely responsible for content published to your YouTube channel through the + Service. +

      + +

      5. Acceptable use

      +

      You agree not to:

      +
        +
      • Use the Service for unlawful, harmful, or abusive purposes
      • +
      • Upload malware, attempt unauthorized access, or interfere with the Service
      • +
      • Circumvent quotas, plan limits, or technical restrictions
      • +
      • Resell or commercially exploit the hosted Service without authorization
      • +
      • Use the Service in a way that violates Google, YouTube, or third-party terms
      • +
      +

      We may suspend or terminate access for violations or risks to the Service or other users.

      + +

      6. YouTube and third-party services

      +

      + The Service integrates with Google OAuth and the YouTube Data API to sign you in, connect + your channel, upload videos you create, and create or list playlists you request. Your use + of those services is also subject to{" "} + + Google Terms of Service + + ,{" "} + + YouTube Terms of Service + + ,{" "} + + YouTube API Services Terms + + , and{" "} + + Google's Privacy Policy + + . We are not responsible for changes, outages, quota limits, or enforcement actions taken by + Google or YouTube. How we handle Google user data is described in our{" "} + Privacy Policy. +

      + +

      7. Open-source software

      +

      + Portions of Songs2VID are available as open-source software. Self-hosting is permitted under + the applicable open-source license. The hosted Service, enterprise features, managed + infrastructure, and certain premium capabilities may require a separate commercial license + or subscription. +

      + +

      8. Subscription, Billing & Credits

      +

      + Paid plans and credit top-ups are billed according to the pricing displayed at the time of + purchase. Taxes may apply. Payments are processed by Stripe. Subscriptions renew + automatically unless cancelled in accordance with our{" "} + Refund Policy. Failure to pay may result in downgrade or + suspension. +

      +

      + Credit usage order: when you create video jobs, we deduct from your current + monthly allocation first, then from any purchased extra credits. +

      + +

      8.1 Pro plan quota and rate-limit extensions

      +

      + Independent Artist (Pro) subscribers receive 50 video credits per + subscription month. Unused credits from prior cycles may roll over into the next cycle + subject to the accumulation cap in Clause 8.3. Renewal and rollover occur on successful + Stripe subscription renewal (typically aligned with your billing period). +

      +

      + Pro subscribers may request a manual video-quota reset or temporary extension, and/or an API + rate-limit extension, via account settings or by emailing{" "} + + {LEGAL_OPERATOR.quotaRequestEmail} + + . Each Pro account is entitled to up to{" "} + five (5) video-quota reset or extension requests per calendar year and up + to five (5) API rate-limit extension requests per calendar year. We review + requests in good faith and may decline requests that are abusive, repetitive without cause, + or inconsistent with fair use. Approved requests do not increase those annual limits. +

      + +

      8.2 Free plan extra credits

      +

      + Bedroom Producer (Free) accounts receive 10 video credits per calendar + month. Free users may purchase additional never-expiring extra credits at the price shown at + checkout (currently €0.25 per credit), in packs of{" "} + 1 to 15 credits per purchase. On the Free plan, the extras balance may not + exceed 15 credits. After monthly and extra credits are exhausted, further + uploads require upgrading to Pro (or waiting for the next monthly reset). Extra credits are + available only on the Free plan purchase flow; Pro includes its monthly allocation and does + not sell the same Free top-up packs. +

      + +

      8.3 Credit rollover & accumulation cap

      +

      + Unused credits from previous cycles may roll over, but the total accumulated balance on any + account (remaining monthly allocation + extra credits) shall strictly not exceed{" "} + 30 credits at any given time. Upon renewal (or when applying a new monthly + allocation), any excess above this 30-credit threshold is automatically trimmed and expires + permanently, without entitlement to refund or compensation. +

      + +

      8.4 Pro API access

      +

      + Independent Artist (Pro) subscribers may generate an API key in account settings to upload + files and create batch video jobs programmatically. API access requires an active Pro + subscription, a connected YouTube account, and compliance with the same quota, file-type, and + resolution limits as the web interface. API keys are personal, must be kept confidential, and + may be revoked by you or by us if misused. We may apply rate limits and suspend API access + for abuse, security incidents, or plan downgrades. If your subscription ends or you are + moved to the Free plan, API keys and Pro-only API access are revoked or disabled. +

      + +

      9. Availability and support

      +

      + We strive for high availability but do not guarantee uninterrupted access. Maintenance, + updates, and outages may occur. Support levels depend on your plan. Self-hosted DIY + deployments without a paid setup are community-supported unless otherwise agreed in + writing. +

      + +

      10. Disclaimer of warranties

      +

      + THE SERVICE IS PROVIDED "AS IS" AND "AS AVAILABLE" TO THE MAXIMUM EXTENT + PERMITTED BY LAW. WE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. WE DO NOT WARRANT THAT ENCODING, + UPLOADS, OR METADATA TRANSFER WILL BE ERROR-FREE OR UNINTERRUPTED. +

      + +

      11. Limitation of liability

      +

      + TO THE MAXIMUM EXTENT PERMITTED BY LAW, WE SHALL NOT BE LIABLE FOR INDIRECT, INCIDENTAL, + SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS, REVENUE, DATA, OR + GOODWILL. OUR TOTAL LIABILITY FOR ANY CLAIM ARISING OUT OF THESE TERMS OR THE SERVICE IS + LIMITED TO THE AMOUNT YOU PAID US IN THE TWELVE (12) MONTHS BEFORE THE EVENT GIVING RISE TO + THE CLAIM, OR EUR 100 IF YOU USE THE FREE PLAN ONLY. +

      +

      + Some jurisdictions do not allow certain limitations, so some of the above may not apply to + you. +

      + +

      12. Indemnification

      +

      + You agree to indemnify and hold us harmless from claims arising out of your content, your + use of the Service, or your violation of these Terms or applicable law. +

      + +

      13. Termination and account deletion

      +

      + You may stop using the Service at any time. You may cancel a paid subscription (see our{" "} + Refund Policy) without deleting your account. To permanently + delete your account and associated active data, use the account deletion control in{" "} + Dashboard → Settings or contact{" "} + {LEGAL_OPERATOR.email}. We may suspend or + terminate your access if you breach these Terms, create risk or legal exposure, or where + required by law. Upon termination or deletion, your right to use the hosted Service ends. + Provisions that by nature should survive will survive. Deletion is subject to legal + retention obligations described in our Privacy Policy. +

      + +

      14. Governing law

      +

      + These Terms are governed by the laws of Hungary, excluding conflict + of law rules. Courts in Hungary shall have exclusive jurisdiction unless + mandatory consumer protection laws in your country provide otherwise. +

      + +

      15. Changes

      +

      + We may update these Terms from time to time. Continued use after changes become effective + constitutes acceptance of the revised Terms, where permitted by law. +

      + +

      16. Contact

      +

      + Questions about these Terms:{" "} + {LEGAL_OPERATOR.email} +

      +
      + ); +} diff --git a/assets/Purple minimalist Tech Company Logo 120x120.png b/assets/Purple minimalist Tech Company Logo 120x120.png new file mode 100644 index 0000000..23eb367 Binary files /dev/null and b/assets/Purple minimalist Tech Company Logo 120x120.png differ diff --git a/assets/Purple minimalist Tech Company Logo.png b/assets/Purple minimalist Tech Company Logo.png new file mode 100644 index 0000000..a686fee Binary files /dev/null and b/assets/Purple minimalist Tech Company Logo.png differ diff --git a/assets/README.md b/assets/README.md new file mode 100644 index 0000000..3b37b07 --- /dev/null +++ b/assets/README.md @@ -0,0 +1,7 @@ +# Watermark image + +Place `watermark.png` here for the default bottom-right video overlay. + +Curated Pro typography fonts live in `fonts/` (run `node scripts/fetch-watermark-fonts.mjs`). +The image should include the full attribution: "Uploaded through Songs2VID.com". +If missing, FFmpeg falls back to bottom-right drawtext with the same message. diff --git a/assets/bg-video - Repaired.mp4 b/assets/bg-video - Repaired.mp4 new file mode 100644 index 0000000..4d39ad2 Binary files /dev/null and b/assets/bg-video - Repaired.mp4 differ diff --git a/assets/bg-video.mp4 b/assets/bg-video.mp4 new file mode 100644 index 0000000..4d39ad2 Binary files /dev/null and b/assets/bg-video.mp4 differ diff --git a/assets/database.png b/assets/database.png new file mode 100644 index 0000000..b7c3f0b Binary files /dev/null and b/assets/database.png differ diff --git a/assets/favicon-s2vid.png b/assets/favicon-s2vid.png new file mode 100644 index 0000000..e77737f Binary files /dev/null and b/assets/favicon-s2vid.png differ diff --git a/assets/favicon-s2yt.png b/assets/favicon-s2yt.png new file mode 100644 index 0000000..e77737f Binary files /dev/null and b/assets/favicon-s2yt.png differ diff --git a/assets/fonts/Inter-Regular.ttf b/assets/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..047c92f Binary files /dev/null and b/assets/fonts/Inter-Regular.ttf differ diff --git a/assets/fonts/Montserrat-Regular.ttf b/assets/fonts/Montserrat-Regular.ttf new file mode 100644 index 0000000..c97aca1 Binary files /dev/null and b/assets/fonts/Montserrat-Regular.ttf differ diff --git a/assets/fonts/Oswald-Regular.ttf b/assets/fonts/Oswald-Regular.ttf new file mode 100644 index 0000000..d1a3b9c Binary files /dev/null and b/assets/fonts/Oswald-Regular.ttf differ diff --git a/assets/fonts/PlayfairDisplay-Regular.ttf b/assets/fonts/PlayfairDisplay-Regular.ttf new file mode 100644 index 0000000..7a09eb7 Binary files /dev/null and b/assets/fonts/PlayfairDisplay-Regular.ttf differ diff --git a/assets/fonts/README.md b/assets/fonts/README.md new file mode 100644 index 0000000..5aa544a --- /dev/null +++ b/assets/fonts/README.md @@ -0,0 +1,4 @@ +# Watermark fonts + +Curated TTF assets for FFmpeg `drawtext` (OFL via Google Fonts). +Refresh with `node scripts/fetch-watermark-fonts.mjs`. diff --git a/assets/fonts/Roboto-Regular.ttf b/assets/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..5522a36 Binary files /dev/null and b/assets/fonts/Roboto-Regular.ttf differ diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 0000000..09e67cb Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/watermark.png b/assets/watermark.png new file mode 100644 index 0000000..3fc2584 Binary files /dev/null and b/assets/watermark.png differ diff --git a/basibozuk_cover.jpg b/basibozuk_cover.jpg new file mode 100644 index 0000000..6897cba Binary files /dev/null and b/basibozuk_cover.jpg differ diff --git a/bg-video/12336223-uhd_3840_2160_25fps.mp4 b/bg-video/12336223-uhd_3840_2160_25fps.mp4 new file mode 100644 index 0000000..f8728e9 Binary files /dev/null and b/bg-video/12336223-uhd_3840_2160_25fps.mp4 differ diff --git a/bg-video/5657838-uhd_4096_2160_25fps.mp4 b/bg-video/5657838-uhd_4096_2160_25fps.mp4 new file mode 100644 index 0000000..24eff30 Binary files /dev/null and b/bg-video/5657838-uhd_4096_2160_25fps.mp4 differ diff --git a/bg-video/5657843-uhd_4096_2160_25fps.mp4 b/bg-video/5657843-uhd_4096_2160_25fps.mp4 new file mode 100644 index 0000000..66dbe8e Binary files /dev/null and b/bg-video/5657843-uhd_4096_2160_25fps.mp4 differ diff --git a/bg-video/7507373-uhd_3840_2160_25fps.mp4 b/bg-video/7507373-uhd_3840_2160_25fps.mp4 new file mode 100644 index 0000000..9ef7b76 Binary files /dev/null and b/bg-video/7507373-uhd_3840_2160_25fps.mp4 differ diff --git a/bg-video/9006055-hd_1920_1080_25fps.mp4 b/bg-video/9006055-hd_1920_1080_25fps.mp4 new file mode 100644 index 0000000..a991c77 Binary files /dev/null and b/bg-video/9006055-hd_1920_1080_25fps.mp4 differ diff --git a/bg-video/bg-video - Repaired.mlt b/bg-video/bg-video - Repaired.mlt new file mode 100644 index 0000000..80f3e42 --- /dev/null +++ b/bg-video/bg-video - Repaired.mlt @@ -0,0 +1,571 @@ + + + + + 00:00:07.560 + pause + 12336223-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 2 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 26564154 + 2022-06-01T09:11:45.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + audio + fltp + 48000 + 2 + stereo + aac + AAC (Advanced Audio Coding) + 253375 + 2022-06-01T09:11:45.000000Z + L-SMASH Audio Handler + [0][0][0][0] + mp42 + 0 + mp42mp41isomavc1 + 2022-06-01T09:11:45.000000Z + 1 + 1 + 1 + 1 + 0 + 2022-06-01T09:11:45 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 0 + 1 + was here + deedb8954e1edb1403f9bfcfeec06fd4 + + + 00:00:13.320 + pause + 5657838-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 15838633 + 2020-10-21T09:36:44.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:36:44.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:36:44 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a8579d660409a043fa3836308c1d07fc + + + 00:00:08.960 + pause + 5657843-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22478882 + 2020-10-21T09:34:54.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:34:54.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:34:54 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a680baf367e6ad49fff40416e3d971cd + 1 + 0 + 1 + 5657843-uhd_4096_2160_25fps.mp4 + + + 00:00:09.920 + pause + 7507373-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22476258 + 2021-04-14T11:58:42.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-04-14T11:58:42.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-04-14T11:58:42 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 1 + was here + 54400e51ad7e058f46fefae726dc0f77 + + + 00:00:30.680 + pause + 9006055-hd_1920_1080_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 1920 + 1080 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 5666771 + 2021-07-31T17:21:02.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-07-31T17:21:02.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-07-31T17:21:02 + 0 + 25 + 1 + 709 + 1 + 2 + 1920 + 1080 + 1 + mpeg + 1 + was here + 153beb054a7e25fb75735a4129b379f2 + + + 1 + + + + + + + + 00:00:20.400 + pause + 0 + 1 + color + rgba + 0 + + + + + + 00:00:08.960 + pause + 5657843-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22478882 + 2020-10-21T09:34:54.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:34:54.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:34:54 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a680baf367e6ad49fff40416e3d971cd + 0 + 0 + 1 + 5657843-uhd_4096_2160_25fps.mp4 + + + 00:00:09.920 + pause + 7507373-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22476258 + 2021-04-14T11:58:42.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-04-14T11:58:42.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-04-14T11:58:42 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 1 + was here + 54400e51ad7e058f46fefae726dc0f77 + 0 + 1 + 7507373-uhd_3840_2160_25fps.mp4 + + + 00:00:30.680 + pause + 9006055-hd_1920_1080_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 1920 + 1080 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 5666771 + 2021-07-31T17:21:02.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-07-31T17:21:02.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-07-31T17:21:02 + 0 + 25 + 1 + 709 + 1 + 2 + 1920 + 1080 + 1 + mpeg + 1 + was here + 153beb054a7e25fb75735a4129b379f2 + 0 + 1 + 9006055-hd_1920_1080_25fps.mp4 + + + 00:00:07.560 + pause + 12336223-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 2 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 26564154 + 2022-06-01T09:11:45.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + audio + fltp + 48000 + 2 + stereo + aac + AAC (Advanced Audio Coding) + 253375 + 2022-06-01T09:11:45.000000Z + L-SMASH Audio Handler + [0][0][0][0] + mp42 + 0 + mp42mp41isomavc1 + 2022-06-01T09:11:45.000000Z + 1 + 1 + 1 + 1 + 0 + 2022-06-01T09:11:45 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 0 + 1 + was here + deedb8954e1edb1403f9bfcfeec06fd4 + 0 + 1 + 12336223-uhd_3840_2160_25fps.mp4 + + + 00:00:13.320 + pause + 5657838-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 15838633 + 2020-10-21T09:36:44.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:36:44.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:36:44 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a8579d660409a043fa3836308c1d07fc + 0 + 1 + 5657838-uhd_4096_2160_25fps.mp4 + + + 1 + V1 + + + + + + + + 1 + 5.11712 + 2 + 1 + + + + 0 + 1 + mix + 1 + 1 + + + 0 + 1 + 0.1 + frei0r.cairoblend + 0 + 1 + + + + diff --git a/bg-video/bg-video.mlt b/bg-video/bg-video.mlt new file mode 100644 index 0000000..d1f85a0 --- /dev/null +++ b/bg-video/bg-video.mlt @@ -0,0 +1,570 @@ + + + + + 00:00:07.560 + pause + C:/Users/Atakan Doğan Özban/Desktop/12336223-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 2 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 26564154 + 2022-06-01T09:11:45.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + audio + fltp + 48000 + 2 + stereo + aac + AAC (Advanced Audio Coding) + 253375 + 2022-06-01T09:11:45.000000Z + L-SMASH Audio Handler + [0][0][0][0] + mp42 + 0 + mp42mp41isomavc1 + 2022-06-01T09:11:45.000000Z + 1 + 1 + 1 + 1 + 0 + 2022-06-01T09:11:45 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 0 + 1 + was here + deedb8954e1edb1403f9bfcfeec06fd4 + + + 00:00:13.320 + pause + C:/Users/Atakan Doğan Özban/Desktop/5657838-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 15838633 + 2020-10-21T09:36:44.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:36:44.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:36:44 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a8579d660409a043fa3836308c1d07fc + + + 00:00:08.960 + pause + C:/Users/Atakan Doğan Özban/Desktop/5657843-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22478882 + 2020-10-21T09:34:54.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:34:54.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:34:54 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a680baf367e6ad49fff40416e3d971cd + 1 + 0 + 1 + 5657843-uhd_4096_2160_25fps.mp4 + + + 00:00:09.920 + pause + C:/Users/Atakan Doğan Özban/Desktop/7507373-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22476258 + 2021-04-14T11:58:42.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-04-14T11:58:42.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-04-14T11:58:42 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 1 + was here + 54400e51ad7e058f46fefae726dc0f77 + + + 00:00:30.680 + pause + C:/Users/Atakan Doğan Özban/Desktop/9006055-hd_1920_1080_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 1920 + 1080 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 5666771 + 2021-07-31T17:21:02.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-07-31T17:21:02.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-07-31T17:21:02 + 0 + 25 + 1 + 709 + 1 + 2 + 1920 + 1080 + 1 + mpeg + 1 + was here + 153beb054a7e25fb75735a4129b379f2 + + + 1 + + + + + + + + 00:00:20.400 + pause + 0 + 1 + color + rgba + 0 + + + + + + 00:00:08.960 + pause + C:/Users/Atakan Doğan Özban/Desktop/5657843-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22478882 + 2020-10-21T09:34:54.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:34:54.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:34:54 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a680baf367e6ad49fff40416e3d971cd + 0 + 0 + 1 + 5657843-uhd_4096_2160_25fps.mp4 + + + 00:00:09.920 + pause + C:/Users/Atakan Doğan Özban/Desktop/7507373-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 22476258 + 2021-04-14T11:58:42.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-04-14T11:58:42.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-04-14T11:58:42 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 1 + was here + 54400e51ad7e058f46fefae726dc0f77 + 0 + 1 + 7507373-uhd_3840_2160_25fps.mp4 + + + 00:00:30.680 + pause + C:/Users/Atakan Doğan Özban/Desktop/9006055-hd_1920_1080_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 1920 + 1080 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 5666771 + 2021-07-31T17:21:02.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2021-07-31T17:21:02.000000Z + 1 + 1 + 1 + -1 + 0 + 2021-07-31T17:21:02 + 0 + 25 + 1 + 709 + 1 + 2 + 1920 + 1080 + 1 + mpeg + 1 + was here + 153beb054a7e25fb75735a4129b379f2 + 0 + 1 + 9006055-hd_1920_1080_25fps.mp4 + + + 00:00:07.560 + pause + C:/Users/Atakan Doğan Özban/Desktop/12336223-uhd_3840_2160_25fps.mp4 + avformat-novalidate + 2 + video + 25 + 0 + 3840 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 26564154 + 2022-06-01T09:11:45.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + audio + fltp + 48000 + 2 + stereo + aac + AAC (Advanced Audio Coding) + 253375 + 2022-06-01T09:11:45.000000Z + L-SMASH Audio Handler + [0][0][0][0] + mp42 + 0 + mp42mp41isomavc1 + 2022-06-01T09:11:45.000000Z + 1 + 1 + 1 + 1 + 0 + 2022-06-01T09:11:45 + 0 + 25 + 1 + 709 + 1 + 2 + 3840 + 2160 + 1 + mpeg + 0 + 1 + was here + deedb8954e1edb1403f9bfcfeec06fd4 + 0 + 1 + 12336223-uhd_3840_2160_25fps.mp4 + + + 00:00:13.320 + pause + C:/Users/Atakan Doğan Özban/Desktop/5657838-uhd_4096_2160_25fps.mp4 + avformat-novalidate + 1 + video + 25 + 0 + 4096 + 2160 + 0 + yuv420p + 0 + 709 + 1 + h264 + H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 + 15838633 + 2020-10-21T09:36:44.000000Z + L-SMASH Video Handler + [0][0][0][0] + AVC Coding + mp42 + 0 + mp42mp41isomavc1 + 2020-10-21T09:36:44.000000Z + 1 + 1 + 1 + -1 + 0 + 2020-10-21T09:36:44 + 0 + 25 + 1 + 709 + 1 + 2 + 4096 + 2160 + 1 + mpeg + 1 + was here + a8579d660409a043fa3836308c1d07fc + 0 + 1 + 5657838-uhd_4096_2160_25fps.mp4 + + + 1 + V1 + + + + + + + + 1 + 5.11712 + 2 + 1 + + + + 0 + 1 + mix + 1 + 1 + + + 0 + 1 + 0.1 + frei0r.cairoblend + 0 + 1 + + + diff --git a/components/AccountPrivacyActions.tsx b/components/AccountPrivacyActions.tsx new file mode 100644 index 0000000..d618f6b --- /dev/null +++ b/components/AccountPrivacyActions.tsx @@ -0,0 +1,78 @@ +"use client"; + +import { signOut } from "next-auth/react"; +import { useState } from "react"; +import { SUPPORT_EMAIL } from "@/lib/plans"; + +type Props = { + email: string; +}; + +export function AccountPrivacyActions({ email }: Props) { + const [deleting, setDeleting] = useState(false); + const [error, setError] = useState(null); + + async function handleDeleteAccount() { + if ( + !confirm( + "Delete your account permanently? This removes your jobs, uploads, and YouTube connection. This cannot be undone.", + ) + ) { + return; + } + + setDeleting(true); + setError(null); + + try { + const res = await fetch("/api/account/delete", { method: "POST" }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to delete account"); + await signOut({ callbackUrl: "/" }); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to delete account"); + setDeleting(false); + } + } + + const dataRequestSubject = encodeURIComponent("Data export request"); + const dataRequestBody = encodeURIComponent( + `Hello,\n\nI would like to request a copy of my personal data associated with my Songs2VID account (${email}).\n\nThank you.`, + ); + + return ( +
      + {error && ( +
      + {error} +
      + )} + +
      + + Request my data + + + +
      + +

      + Data requests are handled within the timelines described in our{" "} + + Privacy Policy + + . +

      +
      + ); +} diff --git a/components/ApiKeySettings.tsx b/components/ApiKeySettings.tsx new file mode 100644 index 0000000..e8d4c8e --- /dev/null +++ b/components/ApiKeySettings.tsx @@ -0,0 +1,302 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { API_DOCS_URL } from "@/lib/plans"; + +type ApiKeyStatus = { + configured: boolean; + prefix: string | null; +}; + +type RateLimitStatus = { + limit: number; + used: number; + remaining: number; + windowSeconds: number; + resetsInSeconds: number; + bonus?: number; +}; + +type ExtensionRequest = { + id: string; + status: string; + message: string; + requestedAt: string; + processedAt: string | null; + adminNote: string | null; +}; + +type ExtensionUsage = { + used: number; + limit: number; + remaining: number; + requests: ExtensionRequest[]; +}; + +type Props = { + initialStatus: ApiKeyStatus; + initialRateLimit: RateLimitStatus; + initialExtensionUsage: ExtensionUsage; +}; + +export function ApiKeySettings({ + initialStatus, + initialRateLimit, + initialExtensionUsage, +}: Props) { + const [status, setStatus] = useState(initialStatus); + const [rateLimit, setRateLimit] = useState(initialRateLimit); + const [extensionUsage, setExtensionUsage] = useState(initialExtensionUsage); + const [newKey, setNewKey] = useState(null); + const [loading, setLoading] = useState(false); + const [requesting, setRequesting] = useState(false); + const [error, setError] = useState(null); + const [success, setSuccess] = useState(null); + + useEffect(() => { + let active = true; + const refresh = () => { + fetch("/api/account/api-rate-limit") + .then(async (res) => { + if (!res.ok) return; + const data = await res.json(); + if (active) setRateLimit(data); + }) + .catch(() => {}); + }; + refresh(); + const id = setInterval(refresh, 5000); + return () => { + active = false; + clearInterval(id); + }; + }, []); + + async function generateKey() { + if ( + status.configured && + !confirm("This will replace your existing API key. Continue?") + ) { + return; + } + + setLoading(true); + setError(null); + setNewKey(null); + setSuccess(null); + + try { + const res = await fetch("/api/account/api-key", { method: "POST" }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to generate API key"); + + setNewKey(data.apiKey); + setStatus({ configured: true, prefix: data.prefix }); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to generate API key"); + } finally { + setLoading(false); + } + } + + async function revokeKey() { + if (!confirm("Revoke your API key? External integrations will stop working.")) return; + + setLoading(true); + setError(null); + setSuccess(null); + + try { + const res = await fetch("/api/account/api-key", { method: "DELETE" }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to revoke API key"); + + setStatus({ configured: false, prefix: null }); + setNewKey(null); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to revoke API key"); + } finally { + setLoading(false); + } + } + + async function requestRateLimitExtension() { + if (extensionUsage.remaining <= 0) return; + + const reason = prompt( + "Optional: tell us why you need a higher API rate limit (leave blank to skip).", + ); + if (reason === null) return; + + setRequesting(true); + setError(null); + setSuccess(null); + + try { + const res = await fetch("/api/account/api-rate-limit-extension-request", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message: reason }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to submit request"); + + setExtensionUsage({ + used: data.used, + limit: data.limit, + remaining: data.remaining, + requests: data.requests ?? extensionUsage.requests, + }); + setSuccess( + `Rate limit extension request submitted. ${data.used} of ${data.limit} used this year.`, + ); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to submit request"); + } finally { + setRequesting(false); + } + } + + const hasPending = extensionUsage.requests.some((r) => r.status === "PENDING"); + const usedPct = Math.min(100, Math.round((rateLimit.used / Math.max(1, rateLimit.limit)) * 100)); + + return ( +
      +

      + Use the REST API to upload files and create batch video jobs programmatically. Pro plan + only. +

      + +
      +
      +

      API rate limit

      +

      + Resets in {rateLimit.resetsInSeconds}s +

      +
      +

      + {rateLimit.used} / {rateLimit.limit} requests used this minute + {rateLimit.bonus ? ( + (includes +{rateLimit.bonus} bonus) + ) : null} +

      +
      +
      = 90 ? "bg-red-500" : usedPct >= 70 ? "bg-amber-500" : "bg-accent" + }`} + style={{ width: `${usedPct}%` }} + /> +
      +

      + {rateLimit.remaining} requests remaining · window {rateLimit.windowSeconds}s +

      + +
      +

      + Extension requests this year: {extensionUsage.used} / {extensionUsage.limit} +

      + +
      + + {extensionUsage.requests.length > 0 && ( +
        + {extensionUsage.requests.slice(0, 5).map((req) => ( +
      • + {new Date(req.requestedAt).toLocaleDateString()} · {req.status} + {req.adminNote ? ` · ${req.adminNote}` : ""} +
      • + ))} +
      + )} +
      + + {status.configured && status.prefix && ( +

      + Active key: {status.prefix}… +

      + )} + + {newKey && ( +
      +

      Your new API key (copy now)

      + + {newKey} + +
      + )} + + {success && ( +
      + {success} +
      + )} + + {error && ( +
      + {error} +
      + )} + +
      + + {status.configured && ( + + )} +
      + +
      +

      Endpoints

      +
        +
      • POST /api/v1/upload: upload image or audio file
      • +
      • POST /api/v1/jobs: create job from paths (recommended for large batches)
      • +
      • POST /api/v1/jobs/batch: small packs only (one-shot multipart)
      • +
      • GET /api/v1/playlists: list YouTube playlists
      • +
      • POST /api/v1/playlists: create a YouTube playlist
      • +
      • GET /api/v1/jobs: list jobs
      • +
      • GET /api/v1/jobs/:id: job status
      • +
      +

      + Send Authorization: Bearer YOUR_API_KEY on every + request. For many audio files, upload each file then call{" "} + /api/v1/jobs (avoid large one-shot batches).{" "} + + Full API docs + +

      +
      +
      + ); +} diff --git a/components/BenefitsSection.tsx b/components/BenefitsSection.tsx new file mode 100644 index 0000000..f179c60 --- /dev/null +++ b/components/BenefitsSection.tsx @@ -0,0 +1,436 @@ +"use client"; + +import Image from "next/image"; +import { useEffect, useRef, useState } from "react"; +import { ScrollReveal } from "@/components/ScrollReveal"; +import { useInView } from "@/hooks/useInView"; +import { useMockupProgress } from "@/hooks/useMockupProgress"; +import { SectionScrollTitle } from "@/components/SectionScrollTitle"; + +function FilmStripIcon({ className }: { className?: string }) { + return ( + + + + + + ); +} + +function YouTubeIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +function CoinsIcon({ className }: { className?: string }) { + return ( + + + + + + + + ); +} + +function PlaylistIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +function NoteIcon({ className }: { className?: string }) { + return ( + + + + + + ); +} + +function WaveIcon({ className }: { className?: string }) { + return ( + + + + ); +} + +function GearsIcon({ className }: { className?: string }) { + return ( + + + + + ); +} + +const BENEFITS = [ + { + title: "No editing required", + desc: "Skip complex video editors. Just upload an image and audio, and Songs2VID handles the rest.", + Icon: FilmStripIcon, + }, + { + title: "YouTube-ready output", + desc: "Videos are encoded and uploaded with the metadata you set, ready for your channel.", + Icon: YouTubeIcon, + }, + { + title: "Free tier included", + desc: "Start creating with 10 videos every month at up to 720p. No credit card needed.", + Icon: CoinsIcon, + }, + { + title: "YouTube playlists", + desc: "Independent Artist (Pro) can create YouTube playlists and add every upload from the dashboard or API.", + Icon: PlaylistIcon, + }, +] as const; + +const STOCK_THUMBS = [ + "https://images.unsplash.com/photo-1511379938547-c1f69419868d?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1470225620780-dba8ba36b745?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1514320291840-2e0a9bf2a9ae?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1487180144351-b8472da7d491?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1598488035139-bdbb2231ce04?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1571330735066-03aaa9429d89?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1619983081563-430f63602796?w=120&h=120&fit=crop&auto=format", + "https://images.unsplash.com/photo-1483412033650-1015ddeb83d1?w=120&h=120&fit=crop&auto=format", +] as const; + +function TypewriterText({ text }: { text: string }) { + const [displayed, setDisplayed] = useState(""); + const [done, setDone] = useState(false); + + useEffect(() => { + let index = 0; + const interval = setInterval(() => { + index += 1; + setDisplayed(text.slice(0, index)); + if (index >= text.length) { + clearInterval(interval); + setDone(true); + } + }, 45); + + return () => clearInterval(interval); + }, [text]); + + return ( + + {displayed} + {!done && |} + + ); +} + +function BenefitCard({ + title, + desc, + Icon, +}: { + title: string; + desc: string; + Icon: typeof FilmStripIcon; +}) { + return ( +
      + +

      {title}

      +

      {desc}

      +
      + ); +} + +function CheckIcon({ className }: { className?: string }) { + return ( + + ); +} + +function MockupProgressRow({ + initialWidth, + midWidth, + active, + phaseOneMs = 3000, + phaseTwoMs = 2000, +}: { + initialWidth: string; + midWidth: string; + active: boolean; + phaseOneMs?: number; + phaseTwoMs?: number; +}) { + const { phase, processed, transitionMs } = useMockupProgress(active, phaseOneMs, phaseTwoMs); + + const width = phase === 0 ? initialWidth : phase === 1 ? midWidth : "100%"; + + return ( +
      +

      {processed ? "Processed" : "Processing..."}

      +
      +
      +
      = 1 ? `width ${transitionMs}ms ease-out` : "none", + }} + /> +
      + +
      +
      + ); +} + +function DashboardMockup() { + const { ref, inView } = useInView(); + const sidebarIcons = [NoteIcon, WaveIcon, GearsIcon] as const; + + return ( +
      +
      +
      +
      + {sidebarIcons.map((Icon, i) => ( +
      + +
      + ))} +
      + +
      +
      + +
      +
      +
      + Title +
      +
      + genre + audio +
      +
      + Category Music ▾ +
      +
      + + +
      +
      +
      +
      + ); +} + +function ProcessFlow() { + return ( +
      + + +
      +
      +
      + + +
      + +
      +
      + Process +
      + Process +
      + +
      +
      + {STOCK_THUMBS.map((src) => ( +
      + +
      + + ▶ + +
      + ))} +
      + + + +
      + +
      +

      YouTube

      +

      DIRECT UPLOAD

      +
      +
      +
      +
      +
      +
      + ); +} + +function FlowInput({ label, icon }: { label: string; icon: "audio" | "image" }) { + return ( +
      +
      + {icon === "audio" ? ( + + ) : ( + + + + + + )} +
      + {label} +
      + ); +} + +function BenefitsVisual() { + return ( +
      + + +
      + ); +} + +function BenefitsScrollTitle({ sectionRef }: { sectionRef: React.RefObject }) { + return ; +} + +export function BenefitsSection() { + const sectionRef = useRef(null); + + return ( +
      + +
      + +

      Benefits

      +
      + +
      +
      + {BENEFITS.map((benefit, index) => ( + + + + ))} +
      + + + + +
      +
      +
      + ); +} diff --git a/components/CreditPurchasePanel.tsx b/components/CreditPurchasePanel.tsx new file mode 100644 index 0000000..e709320 --- /dev/null +++ b/components/CreditPurchasePanel.tsx @@ -0,0 +1,199 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { useMemo, useState } from "react"; +import { UpgradeProButton } from "@/components/UpgradeProButton"; +import { + CREDIT_PRICE_CENTS, + FREE_EXTRA_CREDITS_MAX, + FREE_TOP_UP_MAX, + FREE_TOP_UP_MIN, + formatCreditPrice, + formatEuroFromCents, +} from "@/lib/credits"; + +type Purchase = { + id: string; + credits: number; + amountCents: number; + completedAt: string | null; +}; + +type Props = { + initialCredits: number; + stripeConfigured: boolean; + recentPurchases?: Purchase[]; +}; + +export function CreditPurchasePanel({ + initialCredits, + stripeConfigured, + recentPurchases = [], +}: Props) { + const router = useRouter(); + const [creditsBalance, setCreditsBalance] = useState(initialCredits); + const [amount, setAmount] = useState(FREE_TOP_UP_MIN); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [message, setMessage] = useState(null); + + const room = Math.max(0, FREE_EXTRA_CREDITS_MAX - creditsBalance); + const maxBuyable = Math.min(FREE_TOP_UP_MAX, room); + const minBuyable = room < FREE_TOP_UP_MIN ? 0 : FREE_TOP_UP_MIN; + const atCap = room === 0; + + const totalLabel = useMemo(() => formatCreditPrice(amount), [amount]); + const unitLabel = formatCreditPrice(1); + + async function handleBuy() { + setLoading(true); + setError(null); + setMessage(null); + try { + const res = await fetch("/api/account/credits", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ credits: amount }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Checkout failed"); + + if (data.mocked) { + setCreditsBalance((c) => c + (data.granted ?? amount)); + setMessage( + `Granted +${data.granted ?? amount} credits for ${formatEuroFromCents(data.amountCents ?? amount * CREDIT_PRICE_CENTS)} (dev mock).`, + ); + setLoading(false); + router.refresh(); + return; + } + + if (!data.url) throw new Error("No checkout URL returned"); + window.location.href = data.url; + } catch (err) { + setError(err instanceof Error ? err.message : "Checkout failed"); + setLoading(false); + } + } + + function clampAmount(value: number) { + if (maxBuyable < FREE_TOP_UP_MIN) return FREE_TOP_UP_MIN; + return Math.min(maxBuyable, Math.max(FREE_TOP_UP_MIN, value)); + } + + return ( +
      +

      + Extra credits +

      +

      + Free plan: 10 monthly videos + up to {FREE_EXTRA_CREDITS_MAX} paid extras ( + {unitLabel} each). After both are used, Pro is required. +

      + +
      +

      + Extra credit balance +

      +

      + {Math.min(creditsBalance, FREE_EXTRA_CREDITS_MAX)} + + {" "} + / {FREE_EXTRA_CREDITS_MAX} credits + +

      + {creditsBalance > FREE_EXTRA_CREDITS_MAX && ( +

      + You have {creditsBalance} extras from earlier purchases; no further top-ups until + under {FREE_EXTRA_CREDITS_MAX}. +

      + )} +
      + + {atCap ? ( +
      +

      + Free extras are capped at {FREE_EXTRA_CREDITS_MAX}. When your monthly 10 and these + extras are gone, continue with Pro (€5/mo · 50 videos). +

      + +
      + ) : !stripeConfigured ? ( +

      + Card checkout is not configured yet (missing Stripe keys). In development you can also + use{" "} + POST /api/dev/grant-credits. +

      + ) : ( +
      + + +

      + Total:{" "} + {totalLabel} + + {" "} + ({unitLabel} × {clampAmount(amount)}) + +

      + + +
      + )} + + {message &&

      {message}

      } + {error &&

      {error}

      } + + {recentPurchases.length > 0 && ( +
      +

      + Recent purchases +

      +
        + {recentPurchases.map((p) => ( +
      • + +{p.credits} credits · {formatEuroFromCents(p.amountCents)} + {p.completedAt + ? ` · ${new Date(p.completedAt).toLocaleDateString()}` + : ""} +
      • + ))} +
      +
      + )} +
      + ); +} diff --git a/components/DashboardNav.tsx b/components/DashboardNav.tsx new file mode 100644 index 0000000..40dc2e8 --- /dev/null +++ b/components/DashboardNav.tsx @@ -0,0 +1,95 @@ +"use client"; + +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { useState } from "react"; +import { signOut } from "next-auth/react"; +import { Logo } from "@/components/Logo"; +import { SignOutButton } from "@/components/SignOutButton"; +import { MobileMenuButton, MobileSidebar, dashboardSidebarLinkClass } from "@/components/MobileSidebar"; + +const NAV_LINKS = [ + { href: "/dashboard", label: "Create", match: (path: string) => path === "/dashboard" }, + { + href: "/dashboard/history", + label: "History", + match: (path: string) => path.startsWith("/dashboard/history"), + }, + { + href: "/dashboard/settings", + label: "Settings", + match: (path: string) => path.startsWith("/dashboard/settings"), + }, +] as const; + +type Props = { + channelTitle?: string | null; +}; + +export function DashboardNav({ channelTitle }: Props) { + const pathname = usePathname(); + const [menuOpen, setMenuOpen] = useState(false); + + return ( + <> +
      +
      +
      + + {channelTitle && ( +

      Channel: {channelTitle}

      + )} +
      + +
      + + +
      + + setMenuOpen((prev) => !prev)} + /> +
      +
      + + setMenuOpen(false)} title="Dashboard"> + {NAV_LINKS.map(({ href, label, match }) => ( + setMenuOpen(false)} + className={dashboardSidebarLinkClass(match(pathname))} + > + {label} + + ))} + + + + ); +} diff --git a/components/DashboardShell.tsx b/components/DashboardShell.tsx new file mode 100644 index 0000000..06ac120 --- /dev/null +++ b/components/DashboardShell.tsx @@ -0,0 +1,18 @@ +import type { ReactNode } from "react"; +import { DashboardNav } from "@/components/DashboardNav"; +import { LegalFooter } from "@/components/LegalFooter"; + +type Props = { + channelTitle?: string | null; + children: ReactNode; +}; + +export function DashboardShell({ channelTitle, children }: Props) { + return ( +
      + +
      {children}
      + +
      + ); +} diff --git a/components/DownloadSection.tsx b/components/DownloadSection.tsx new file mode 100644 index 0000000..135f486 --- /dev/null +++ b/components/DownloadSection.tsx @@ -0,0 +1,160 @@ +"use client"; + +import { useRef } from "react"; +import { ScrollReveal } from "@/components/ScrollReveal"; +import { SectionScrollTitle } from "@/components/SectionScrollTitle"; +import { DOCKER_HUB_URL, GITEA_URL } from "@/lib/plans"; + +function DockerIcon({ className }: { className?: string }) { + return ( + + + + ); +} + +function GiteaIcon({ className }: { className?: string }) { + return ( + + + + ); +} + +const DEPLOY_CARDS = [ + { + name: "Docker Hub", + desc: "Pull the image and run Songs2VID on your own server with Docker Compose.", + Icon: DockerIcon, + cta: "View on Docker Hub", + href: DOCKER_HUB_URL, + accent: "text-[#2496ED]", + hover: + "hover:border-[#2496ED]/45 hover:bg-[#2496ED]/[0.06] hover:shadow-lg hover:shadow-[#2496ED]/20", + titleHover: "group-hover:text-[#2496ED]", + }, + { + name: "Gitea", + desc: "Clone the open-source repository and deploy from source on your infrastructure.", + Icon: GiteaIcon, + cta: "View on Gitea", + href: GITEA_URL, + accent: "text-[#609926]", + hover: + "hover:border-[#609926]/45 hover:bg-[#609926]/[0.06] hover:shadow-lg hover:shadow-[#609926]/20", + titleHover: "group-hover:text-[#609926]", + }, +] as const; + +function DeployCard({ + name, + desc, + Icon, + cta, + href, + accent, + hover, + titleHover, +}: (typeof DEPLOY_CARDS)[number]) { + return ( + +
      + + + Open Source + +
      +

      + {name} +

      +

      + {desc} +

      +

      + {cta} +

      +
      + ); +} + +export function DownloadSection() { + const sectionRef = useRef(null); + + return ( +
      + + +
      + +

      Download

      +

      + Songs2VID is open source. Self-host on your own server with Docker or deploy from source. +

      +
      + +
      + +
      +
      +

      Run it yourself

      +

      + Host Songs2VID on your infrastructure with full control over data, queues, and + storage. Ideal for teams and creators who want a private deployment. +

      +
      + +
        +
      • + + Docker image published to Docker Hub +
      • +
      • + + Source code available on Gitea +
      • +
      • + + Gitea Issues community support +
      • +
      • + + PostgreSQL, Redis, FFmpeg, and worker included +
      • +
      + +
      +

      Quick start

      +
      +                  {`docker pull atakanozban/songs2vid:latest\ndocker compose up -d`}
      +                
      +
      +
      +
      + +
      + {DEPLOY_CARDS.map((card, index) => ( + + + + ))} +
      +
      +
      +
      + ); +} diff --git a/components/Footer.tsx b/components/Footer.tsx new file mode 100644 index 0000000..f9d653b --- /dev/null +++ b/components/Footer.tsx @@ -0,0 +1,206 @@ +import Link from "next/link"; +import type { ReactNode } from "react"; +import { Logo } from "@/components/Logo"; +import { + DOCKER_HUB_URL, + DOCS_URL, + GITEA_ISSUES_URL, + GITEA_URL, + SUPPORT_EMAIL, +} from "@/lib/plans"; + +function GiteaIcon({ className }: { className?: string }) { + return ( + + ); +} + +function DockerIcon({ className }: { className?: string }) { + return ( + + ); +} + +function FooterLink({ + href, + children, + external, +}: { + href: string; + children: ReactNode; + external?: boolean; +}) { + const className = "transition-colors duration-300 hover:text-white"; + + if (external || href.startsWith("#") || href.startsWith("mailto:")) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} + +function LegalLink({ + href, + children, + external, +}: { + href: string; + children: ReactNode; + external?: boolean; +}) { + const className = "transition-colors duration-300 hover:text-gray-300"; + + if (external) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} + +const STATUS_URL = "https://status.atakanozban.com/status/2"; +const DOCS_INTRO_URL = `${DOCS_URL.replace(/\/$/, "")}/docs/intro`; +const DOCS_API_URL = `${DOCS_URL.replace(/\/$/, "")}/docs/api/overview`; + +export function Footer() { + const year = new Date().getFullYear(); + + return ( +
      +
      +
      +
      + +

      + Convert your audio tracks into stunning videos for YouTube. Beautiful, automated, and + fully open-source. +

      + +
      + +
      +
      + + Product + + Pricing + Download + Benefits + + Documentation + + + API Reference + + + Service Status + +
      + +
      + + Open Source + + + Gitea Instance + + + Docker Image + + + Report a Bug + +
      + +
      + + Contact + + Support Email + Response within 24h for Pro users +
      +
      +
      + +
      +
      + © {year} Songs2VID. All rights reserved. + + Privacy Policy + + Terms of Service + + Refund Policy +
      + + Made with ❤ by{" "} + + atakan + + . + +
      +
      +
      + ); +} diff --git a/components/JobHistory.tsx b/components/JobHistory.tsx new file mode 100644 index 0000000..050ca8d --- /dev/null +++ b/components/JobHistory.tsx @@ -0,0 +1,210 @@ +"use client"; + +import Link from "next/link"; +import { useEffect, useMemo, useState } from "react"; +import { displayJobItemError, isYouTubeUploadLimitError } from "@/lib/youtube/errors"; +import type { JobResponse } from "@/lib/types"; +import { YouTubeLimitBanner } from "./YouTubeLimitBanner"; + +const STATUS_LABELS: Record = { + PENDING: "Queued", + ENCODING: "Encoding", + UPLOADING: "Uploading", + COMPLETED: "Completed", + FAILED: "Failed", +}; + +function sameDay(a: Date, b: Date) { + return ( + a.getFullYear() === b.getFullYear() && + a.getMonth() === b.getMonth() && + a.getDate() === b.getDate() + ); +} + +function formatDayLabel(date: Date) { + const today = new Date(); + const yesterday = new Date(); + yesterday.setDate(today.getDate() - 1); + + if (sameDay(date, today)) return "Today"; + if (sameDay(date, yesterday)) return "Yesterday"; + + return date.toLocaleDateString(undefined, { + weekday: "long", + year: "numeric", + month: "long", + day: "numeric", + }); +} + +function groupJobsByDay(jobs: JobResponse[]) { + const groups = new Map(); + + for (const job of jobs) { + const date = new Date(job.createdAt); + const key = date.toLocaleDateString("en-CA"); + const existing = groups.get(key); + + if (existing) { + existing.jobs.push(job); + } else { + groups.set(key, { label: formatDayLabel(date), jobs: [job] }); + } + } + + return Array.from(groups.entries()) + .sort(([a], [b]) => b.localeCompare(a)) + .map(([, group]) => group); +} + +function statusClass(status: string) { + if (status === "COMPLETED") return "bg-green-500/20 text-green-400"; + if (status === "FAILED") return "bg-red-500/20 text-red-400"; + return "bg-yellow-500/20 text-yellow-400"; +} + +export function JobHistory() { + const [jobs, setJobs] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + let active = true; + + async function load() { + try { + const res = await fetch("/api/jobs?limit=100"); + if (!res.ok) throw new Error("Failed to load history"); + const data = await res.json(); + if (active) setJobs(data.jobs); + } catch (err) { + if (active) setError(err instanceof Error ? err.message : "Error loading history"); + } finally { + if (active) setLoading(false); + } + } + + load(); + return () => { + active = false; + }; + }, []); + + const dayGroups = useMemo(() => groupJobsByDay(jobs), [jobs]); + const youtubeLimitHit = useMemo( + () => + jobs.some((job) => + job.items.some( + (item) => item.status === "FAILED" && item.error && isYouTubeUploadLimitError(item.error), + ), + ), + [jobs], + ); + + if (loading) { + return
      Loading history…
      ; + } + + if (error) { + return ( +
      {error}
      + ); + } + + if (dayGroups.length === 0) { + return ( +
      +

      No videos created yet.

      + + Create your first video + +
      + ); + } + + return ( +
      + {youtubeLimitHit && } + + {dayGroups.map((group) => ( +
      +

      {group.label}

      + +
      + {group.jobs.map((job) => ( +
      +
      +
      +

      + {new Date(job.createdAt).toLocaleTimeString(undefined, { + hour: "2-digit", + minute: "2-digit", + })} + {" · "} + {job.items.length} video{job.items.length === 1 ? "" : "s"} +

      +

      + Status: {job.status} +

      +
      + + View job + +
      + +
      + {job.items.map((item) => { + const itemError = + item.status === "FAILED" ? displayJobItemError(item.error) : null; + + return ( +
      +
      +
      +

      {item.title}

      +

      {item.audioFilename}

      + {item.youtubeVideoId && ( + + View on YouTube + + )} +
      + + {STATUS_LABELS[item.status] || item.status} + +
      + {itemError && ( +

      {itemError}

      + )} +
      + ); + })} +
      +
      + ))} +
      +
      + ))} +
      + ); +} diff --git a/components/JobProgress.tsx b/components/JobProgress.tsx index 171defc..c6ccd1b 100644 --- a/components/JobProgress.tsx +++ b/components/JobProgress.tsx @@ -1,7 +1,10 @@ "use client"; +import Link from "next/link"; import { useEffect, useState } from "react"; +import { displayJobItemError, isYouTubeUploadLimitError } from "@/lib/youtube/errors"; import type { JobResponse } from "@/lib/types"; +import { YouTubeLimitBanner } from "./YouTubeLimitBanner"; type Props = { jobId: string; @@ -17,7 +20,13 @@ const STATUS_LABELS: Record = { export function JobProgress({ jobId }: Props) { const [job, setJob] = useState(null); - const [quota, setQuota] = useState<{ remaining: number; limit: number } | null>(null); + const [quota, setQuota] = useState<{ + remaining: number; + limit: number; + totalAvailable: number; + plan: string; + resetsIn: string; + } | null>(null); const [error, setError] = useState(null); useEffect(() => { @@ -36,7 +45,14 @@ export function JobProgress({ jobId }: Props) { if (quotaRes.ok) { const quotaData = await quotaRes.json(); - if (active) setQuota({ remaining: quotaData.remaining, limit: quotaData.limit }); + if (active) + setQuota({ + remaining: quotaData.remaining, + limit: quotaData.limit, + totalAvailable: quotaData.totalAvailable ?? quotaData.remaining, + plan: quotaData.plan, + resetsIn: quotaData.resetsIn, + }); } } catch (err) { if (active) setError(err instanceof Error ? err.message : "Error loading job"); @@ -60,6 +76,9 @@ export function JobProgress({ jobId }: Props) { } const allDone = job.items.every((i) => i.status === "COMPLETED" || i.status === "FAILED"); + const youtubeLimitHit = job.items.some( + (i) => i.status === "FAILED" && i.error && isYouTubeUploadLimitError(i.error), + ); return (
      @@ -72,11 +91,16 @@ export function JobProgress({ jobId }: Props) {
      {quota && (
      - {quota.remaining} / {quota.limit} videos remaining this month + {quota.remaining} / {quota.limit} plan · {quota.totalAvailable} total available ·{" "} + {quota.plan === "FREE" + ? `resets ${quota.resetsIn}` + : `monthly resets on ${quota.resetsIn}`}
      )}
      + {youtubeLimitHit && } +
      {job.items.map((item) => (
      - View on YouTube → + View on YouTube )} - {item.error && ( -

      {item.error}

      + {item.status === "FAILED" && displayJobItemError(item.error) && ( +

      {displayJobItemError(item.error)}

      )}
      ))}
      {allDone && ( - Create another video - + )}
      ); diff --git a/components/LandingNavbar.tsx b/components/LandingNavbar.tsx new file mode 100644 index 0000000..6891dec --- /dev/null +++ b/components/LandingNavbar.tsx @@ -0,0 +1,105 @@ +"use client"; + +import { useState } from "react"; +import { Logo } from "@/components/Logo"; +import { MobileMenuButton, MobileSidebar, sidebarLinkClass } from "@/components/MobileSidebar"; +import { DOCS_URL } from "@/lib/plans"; + +const NAV_LINKS = [ + { href: "#benefits", label: "Benefits" }, + { href: "#download", label: "Download" }, + { href: "#pricing", label: "Pricing" }, + { href: "#support", label: "Support" }, +] as const; + +const DOCS_HREF = `${DOCS_URL.replace(/\/$/, "")}/docs/intro`; + +function NavAnchor({ + href, + label, + onNavigate, + className = "text-base font-medium text-gray-300 transition-colors duration-200 hover:text-white", +}: { + href: string; + label: string; + onNavigate?: () => void; + className?: string; +}) { + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + const id = href.replace("#", ""); + document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" }); + window.history.pushState(null, "", href); + onNavigate?.(); + }; + + return ( + + {label} + + ); +} + +function DocsLink({ + onNavigate, + className = "text-base font-medium text-gray-300 transition-colors duration-200 hover:text-white", +}: { + onNavigate?: () => void; + className?: string; +}) { + return ( + onNavigate?.()} + > + Docs + + ); +} + +export function LandingNavbar() { + const [menuOpen, setMenuOpen] = useState(false); + + return ( + <> +
      +
      + + +
      + + + setMenuOpen((prev) => !prev)} + /> +
      +
      +
      + + setMenuOpen(false)} title="Menu"> + {NAV_LINKS.map(({ href, label }) => ( + setMenuOpen(false)} + className={sidebarLinkClass()} + /> + ))} + setMenuOpen(false)} + className={sidebarLinkClass()} + /> + + + ); +} diff --git a/components/LayoutStudio.tsx b/components/LayoutStudio.tsx new file mode 100644 index 0000000..f608ddb --- /dev/null +++ b/components/LayoutStudio.tsx @@ -0,0 +1,866 @@ +"use client"; + +import { + useEffect, + useMemo, + useState, + type CSSProperties, + type ChangeEvent, +} from "react"; +import { getVideoAttributionText } from "@/lib/branding"; +import { + CURATED_FONTS, + type CuratedFontKey, + type WatermarkFontKey, +} from "@/lib/fonts"; +import { + BLUR_AMOUNT_MAX, + BLUR_AMOUNT_MIN, + BLUR_OPACITY_DEFAULT, + BLUR_OPACITY_MAX, + BLUR_OPACITY_MIN, + DEFAULT_LAYOUT, + LAYOUT_TEMPLATE_LABELS, + LAYOUT_TEMPLATES, + TEXT_OFFSET_MAX, + TEXT_OFFSET_MIN, + TEXT_PADDING_MAX, + TEXT_PADDING_MIN, + TITLE_ARTIST_GAP_MAX, + TITLE_ARTIST_GAP_MIN, + type LayoutSettings, + type LayoutTemplate, +} from "@/lib/layout"; +import { + WATERMARK_WIDTH_FRACTION, + artistFontSizeForWidth, + curatedFontApiUrl, + previewFontFamilyCss, + scaleFontToPreview, + titleFontSizeForWidth, + watermarkFontSizeForWidth, +} from "@/lib/preview-typography"; +import { + DEFAULT_WATERMARK, + WATERMARK_OFFSET_MAX, + WATERMARK_OFFSET_MIN, + WATERMARK_POSITIONS, + WATERMARK_TEXT_MAX, + type WatermarkMode, + type WatermarkPosition, + type WatermarkSettings, +} from "@/lib/watermark"; +import { UpgradeProButton } from "./UpgradeProButton"; + +type Props = { + locked: boolean; + previewImageUrl: string | null; + /** On-video song title (art-track layouts). */ + songTitle: string; + artist: string; + /** Encode width from selected resolution (e.g. 1280). */ + encodeWidth?: number; + layout: LayoutSettings; + onLayoutChange: (next: LayoutSettings) => void; + watermark: WatermarkSettings; + onWatermarkChange: (next: WatermarkSettings) => void; + onUploadLogo: (file: File) => Promise; + onUploadFont: (file: File) => Promise; + logoPreviewUrl?: string | null; +}; + +const WM_POSITION_LABELS: Record = { + "top-left": "Top left", + "top-right": "Top right", + "bottom-left": "Bottom left", + "bottom-right": "Bottom right", + center: "Center", +}; + +const CUSTOM_PREVIEW_FAMILY = "S2VIDCustomWm"; + +function previewFontFamily(fontKey: WatermarkFontKey | undefined): string { + return previewFontFamilyCss(fontKey); +} + +function watermarkOverlayStyle( + position: WatermarkPosition, + offsetX: number, + offsetY: number, +): CSSProperties { + const base: CSSProperties = { + position: "absolute", + maxWidth: "32%", + pointerEvents: "none", + zIndex: 5, + }; + const ox = `${offsetX}px`; + const oy = `${offsetY}px`; + switch (position) { + case "top-left": + return { ...base, top: oy, left: ox }; + case "top-right": + return { ...base, top: oy, right: ox }; + case "bottom-left": + return { ...base, bottom: oy, left: ox }; + case "center": + return { + ...base, + top: "50%", + left: "50%", + transform: `translate(calc(-50% + ${offsetX}px), calc(-50% + ${offsetY}px))`, + }; + case "bottom-right": + default: + return { ...base, bottom: oy, right: ox }; + } +} + +function MiniThumb({ + template, + active, + onClick, + disabled, +}: { + template: LayoutTemplate | null; + active: boolean; + onClick: () => void; + disabled: boolean; +}) { + const isClassic = template === null; + return ( + + ); +} + +function previewCoverStyle( + template: LayoutTemplate, + padPct: number, +): CSSProperties { + const p = `${padPct}%`; + switch (template) { + case "COVER_LEFT_TEXT_RIGHT": + return { + position: "absolute", + left: p, + top: "50%", + transform: "translateY(-50%)", + width: "38%", + maxHeight: "72%", + objectFit: "contain", + }; + case "COVER_RIGHT_TEXT_LEFT": + return { + position: "absolute", + right: p, + top: "50%", + transform: "translateY(-50%)", + width: "38%", + maxHeight: "72%", + objectFit: "contain", + }; + case "COVER_TOP_TEXT_BOTTOM": + return { + position: "absolute", + left: "50%", + top: p, + transform: "translateX(-50%)", + width: `calc(100% - ${padPct * 2}%)`, + maxHeight: "56%", + objectFit: "contain", + }; + case "CENTERED_COMPACT": + return { + position: "absolute", + left: "50%", + top: "16%", + transform: "translateX(-50%)", + width: "38%", + maxHeight: "38%", + objectFit: "contain", + }; + } +} + +function previewTextStyle( + template: LayoutTemplate, + padPct: number, + textOffsetX: number, + textOffsetY: number, + titleArtistGap: number, +): CSSProperties { + const p = `${padPct}%`; + const shift = { + transform: undefined as string | undefined, + }; + + const baseGap = { display: "flex", flexDirection: "column" as const, gap: `${titleArtistGap}px` }; + + switch (template) { + case "COVER_LEFT_TEXT_RIGHT": + return { + ...baseGap, + position: "absolute", + left: `calc(48% + ${textOffsetX}px)`, + right: p, + top: "50%", + transform: `translateY(calc(-50% + ${textOffsetY}px))`, + textAlign: "left", + }; + case "COVER_RIGHT_TEXT_LEFT": + return { + ...baseGap, + position: "absolute", + left: p, + right: `calc(48% - ${textOffsetX}px)`, + top: "50%", + transform: `translateY(calc(-50% + ${textOffsetY}px))`, + textAlign: "left", + }; + case "COVER_TOP_TEXT_BOTTOM": + return { + ...baseGap, + position: "absolute", + left: p, + right: p, + bottom: `calc(10% - ${textOffsetY}px)`, + transform: textOffsetX ? `translateX(${textOffsetX}px)` : undefined, + textAlign: "center", + alignItems: "center", + }; + case "CENTERED_COMPACT": + return { + ...baseGap, + position: "absolute", + left: p, + right: p, + top: `calc(58% + ${textOffsetY}px)`, + transform: textOffsetX ? `translateX(${textOffsetX}px)` : undefined, + textAlign: "center", + alignItems: "center", + }; + } + void shift; +} + +export function LayoutStudio({ + locked, + previewImageUrl, + songTitle, + artist, + encodeWidth = 1280, + layout, + onLayoutChange, + watermark, + onWatermarkChange, + onUploadLogo, + onUploadFont, + logoPreviewUrl, +}: Props) { + const [logoUploading, setLogoUploading] = useState(false); + const [logoError, setLogoError] = useState(null); + const [fontUploading, setFontUploading] = useState(false); + const [fontError, setFontError] = useState(null); + const [customFontObjectUrl, setCustomFontObjectUrl] = useState(null); + + // Always coalesce HMR / older session state may omit newly added fields + const L: LayoutSettings = { + ...DEFAULT_LAYOUT, + ...layout, + blurAmount: layout.blurAmount ?? DEFAULT_LAYOUT.blurAmount, + blurOpacity: layout.blurOpacity ?? BLUR_OPACITY_DEFAULT, + textPadding: layout.textPadding ?? DEFAULT_LAYOUT.textPadding, + titleArtistGap: layout.titleArtistGap ?? DEFAULT_LAYOUT.titleArtistGap, + textOffsetX: layout.textOffsetX ?? DEFAULT_LAYOUT.textOffsetX, + textOffsetY: layout.textOffsetY ?? DEFAULT_LAYOUT.textOffsetY, + }; + const W: WatermarkSettings = { + ...DEFAULT_WATERMARK, + ...watermark, + text: watermark.text ?? "", + offsetX: watermark.offsetX ?? DEFAULT_WATERMARK.offsetX, + offsetY: watermark.offsetY ?? DEFAULT_WATERMARK.offsetY, + fontKey: watermark.fontKey ?? "system", + }; + + const blurPx = useMemo( + () => Math.round((L.blurAmount / 100) * 28), + [L.blurAmount], + ); + const padPct = useMemo( + () => + 3 + + ((L.textPadding - TEXT_PADDING_MIN) / (TEXT_PADDING_MAX - TEXT_PADDING_MIN)) * 5, + [L.textPadding], + ); + + const wmOverlay = useMemo( + () => watermarkOverlayStyle(W.position, W.offsetX, W.offsetY), + [W.position, W.offsetX, W.offsetY], + ); + + const textFontStyle = useMemo( + () => ({ fontFamily: previewFontFamily(W.fontKey) }), + [W.fontKey], + ); + + const titlePreviewPx = useMemo( + () => scaleFontToPreview(titleFontSizeForWidth(encodeWidth), encodeWidth), + [encodeWidth], + ); + const artistPreviewPx = useMemo( + () => scaleFontToPreview(artistFontSizeForWidth(encodeWidth), encodeWidth), + [encodeWidth], + ); + const wmTextPreviewPx = useMemo( + () => scaleFontToPreview(watermarkFontSizeForWidth(encodeWidth), encodeWidth), + [encodeWidth], + ); + + useEffect(() => { + const styleId = "s2vid-preview-curated-fonts"; + let el = document.getElementById(styleId) as HTMLStyleElement | null; + if (!el) { + el = document.createElement("style"); + el.id = styleId; + document.head.appendChild(el); + } + el.textContent = CURATED_FONTS.map( + (f) => `@font-face { + font-family: 'S2VIDPreview-${f.key}'; + src: url('${curatedFontApiUrl(f.key)}') format('truetype'); + font-display: swap; +}`, + ).join("\n"); + }, []); + + useEffect(() => { + if (!customFontObjectUrl) return; + const styleId = "s2vid-watermark-custom-font"; + let el = document.getElementById(styleId) as HTMLStyleElement | null; + if (!el) { + el = document.createElement("style"); + el.id = styleId; + document.head.appendChild(el); + } + el.textContent = ` +@font-face { + font-family: '${CUSTOM_PREVIEW_FAMILY}'; + src: url('${customFontObjectUrl}'); + font-display: swap; +}`; + }, [customFontObjectUrl]); + + useEffect(() => { + return () => { + if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl); + }; + }, [customFontObjectUrl]); + + function patchLayout(partial: Partial) { + if (locked) return; + onLayoutChange({ ...DEFAULT_LAYOUT, ...layout, ...partial }); + } + + function patchWm(partial: Partial) { + if (locked) return; + onWatermarkChange({ ...DEFAULT_WATERMARK, ...watermark, ...partial }); + } + + async function handleLogo(e: ChangeEvent) { + const file = e.target.files?.[0]; + e.target.value = ""; + if (!file || locked) return; + setLogoError(null); + setLogoUploading(true); + try { + const path = await onUploadLogo(file); + patchWm({ mode: "logo", logoPath: path }); + } catch (err) { + setLogoError(err instanceof Error ? err.message : "Logo upload failed"); + } finally { + setLogoUploading(false); + } + } + + async function handleFont(e: ChangeEvent) { + const file = e.target.files?.[0]; + e.target.value = ""; + if (!file || locked) return; + setFontError(null); + setFontUploading(true); + try { + const objectUrl = URL.createObjectURL(file); + if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl); + setCustomFontObjectUrl(objectUrl); + const path = await onUploadFont(file); + patchWm({ fontKey: "custom", fontPath: path }); + } catch (err) { + setFontError(err instanceof Error ? err.message : "Font upload failed"); + } finally { + setFontUploading(false); + } + } + + function setFontKey(key: WatermarkFontKey) { + if (key === "custom") { + patchWm({ fontKey: "custom", fontPath: watermark.fontPath ?? null }); + return; + } + patchWm({ fontKey: key, fontPath: null }); + } + + const artTrack = Boolean(L.template); + + return ( +
      + {locked && ( +
      + + Pro + +

      + Art-track layouts, blur backgrounds, typography, and watermark studio are Pro features. +

      + +
      + )} + +
      +

      Video layout

      + + Pro + +
      + + {/* Single live preview: art-track + watermark */} +
      + {previewImageUrl ? ( + <> + {artTrack ? ( + <> +
      + {/* eslint-disable-next-line @next/next/no-img-element */} + 0 ? `blur(${blurPx}px)` : undefined, + transform: "scale(1.15)", + opacity: L.blurOpacity / 100, + }} + /> + {/* eslint-disable-next-line @next/next/no-img-element */} + +
      +

      + {songTitle.trim() || "Track title"} +

      +

      + {artist.trim() || "Artist"} +

      +
      + + ) : ( +
      + {/* eslint-disable-next-line @next/next/no-img-element */} + +
      + )} + + {W.mode !== "none" && ( +
      + {W.mode === "default" ? ( + // eslint-disable-next-line @next/next/no-img-element + + ) : W.mode === "logo" && logoPreviewUrl ? ( + // eslint-disable-next-line @next/next/no-img-element + + ) : W.mode === "text" ? ( + + {W.text?.trim() + ? W.text.trim().slice(0, WATERMARK_TEXT_MAX) + : getVideoAttributionText()} + + ) : null} +
      + )} + + ) : ( +
      + Upload a cover image to preview +
      + )} +
      + + {/* Art-track templates */} +

      Composition

      +
      + patchLayout({ template: null })} + /> + {LAYOUT_TEMPLATES.map((t) => ( + patchLayout({ template: t })} + /> + ))} +
      + +
      + + + + + + +
      + + {/* Typography (matches FFmpeg art-track + watermark text fonts) */} +
      +

      Typography

      + + {W.fontKey === "custom" && ( +
      + + void handleFont(e)} + className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white" + /> + {fontUploading && ( +

      Uploading font…

      + )} + {fontError &&

      {fontError}

      } +
      + )} + {(W.fontKey === "custom" || + (W.fontKey && + W.fontKey !== "system" && + CURATED_FONTS.some((f) => f.key === (W.fontKey as CuratedFontKey)))) && ( +

      + Preview: The quick brown fox jumps over the lazy dog +

      + )} +
      + + {/* Watermark section */} +
      +

      Watermark

      +
      + {( + [ + ["none", "No watermark"], + ["default", "Songs2VID badge"], + ["text", "Custom text"], + ["logo", "PNG logo"], + ] as const + ).map(([mode, label]) => ( + + ))} +
      + + {W.mode === "text" && ( +
      + +
      + )} + + {W.mode === "logo" && ( +
      + + void handleLogo(e)} + className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white" + /> + {logoUploading && ( +

      Uploading logo…

      + )} + {logoError &&

      {logoError}

      } +
      + )} + +
      +

      Watermark position

      +
      + {WATERMARK_POSITIONS.map((pos) => ( + + ))} +
      +
      + +
      + + +
      +
      +
      + ); +} diff --git a/components/LegalFooter.tsx b/components/LegalFooter.tsx new file mode 100644 index 0000000..557228b --- /dev/null +++ b/components/LegalFooter.tsx @@ -0,0 +1,67 @@ +import Link from "next/link"; +import type { ReactNode } from "react"; + +function LegalLink({ + href, + children, + external, +}: { + href: string; + children: ReactNode; + external?: boolean; +}) { + const className = "transition-colors duration-300 hover:text-gray-300"; + + if (external) { + return ( + + {children} + + ); + } + + return ( + + {children} + + ); +} + +export function LegalFooter() { + const year = new Date().getFullYear(); + + return ( +
      +
      + © {year} Songs2VID. All rights reserved. + + + Made with ❤ by{" "} + + atakan + + + + Privacy Policy + + Terms of Service + + Refund Policy + + + Service Status + +
      +
      + ); +} diff --git a/components/LegalPageLayout.tsx b/components/LegalPageLayout.tsx new file mode 100644 index 0000000..311d57e --- /dev/null +++ b/components/LegalPageLayout.tsx @@ -0,0 +1,62 @@ +import Link from "next/link"; +import type { ReactNode } from "react"; +import { Logo } from "@/components/Logo"; +import { LEGAL_LAST_UPDATED } from "@/lib/legal/constants"; + +type Props = { + title: string; + description?: string; + children: ReactNode; +}; + +export function LegalPageLayout({ title, description, children }: Props) { + return ( +
      +
      +
      + + + ← Back to home + +
      +
      + +
      +

      + Last updated: {LEGAL_LAST_UPDATED} +

      +

      {title}

      + {description &&

      {description}

      } + +
      + {children} +
      +
      + + +
      + ); +} diff --git a/components/Logo.tsx b/components/Logo.tsx new file mode 100644 index 0000000..702b397 --- /dev/null +++ b/components/Logo.tsx @@ -0,0 +1,45 @@ +import Link from "next/link"; +import { BRAND_NAME } from "@/lib/branding"; + +type Props = { + href?: string; + size?: "sm" | "md"; + /** Small Beta mark at top-right of the wordmark (public marketing surfaces). */ + beta?: boolean; +}; + +export function Logo({ href = "/", size = "md", beta = false }: Props) { + const textSize = size === "sm" ? "text-xl" : "text-2xl"; + const betaSize = size === "sm" ? "text-[0.5rem]" : "text-[0.55rem]"; + + const content = ( + + Songs + 2VID + {beta ? ( + + ) : null} + + ); + + const label = beta ? `${BRAND_NAME} Beta` : BRAND_NAME; + + if (href) { + return ( + + {content} + + ); + } + + return ( + + {content} + + ); +} diff --git a/components/MobileSidebar.tsx b/components/MobileSidebar.tsx new file mode 100644 index 0000000..5ac53a8 --- /dev/null +++ b/components/MobileSidebar.tsx @@ -0,0 +1,169 @@ +"use client"; + +import { Children, useEffect, useState, type ReactNode } from "react"; + +type Props = { + open: boolean; + onClose: () => void; + title?: string; + children: ReactNode; +}; + +const PANEL_MS = 420; +const ITEM_BASE_MS = 90; + +function CloseIcon({ className }: { className?: string }) { + return ( + + + + ); +} + +export function MobileSidebar({ open, onClose, title = "Menu", children }: Props) { + const [mounted, setMounted] = useState(false); + const [visible, setVisible] = useState(false); + + useEffect(() => { + if (open) { + setMounted(true); + const frame = requestAnimationFrame(() => setVisible(true)); + return () => cancelAnimationFrame(frame); + } + + setVisible(false); + const timer = window.setTimeout(() => setMounted(false), PANEL_MS); + return () => window.clearTimeout(timer); + }, [open]); + + useEffect(() => { + if (!mounted) return; + + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape") onClose(); + }; + + document.body.style.overflow = "hidden"; + window.addEventListener("keydown", onKeyDown); + + return () => { + document.body.style.overflow = ""; + window.removeEventListener("keydown", onKeyDown); + }; + }, [mounted, onClose]); + + if (!mounted) return null; + + return ( +
      + + + +
      + ); +} + +export function MobileMenuButton({ + onClick, + open = false, +}: { + onClick: () => void; + open?: boolean; +}) { + return ( + + ); +} + +export function sidebarLinkClass(active = false) { + return `block rounded-lg px-4 py-3 text-base font-medium transition-all duration-200 hover:translate-x-0.5 ${ + active ? "bg-surface-light text-white" : "text-gray-300 hover:bg-surface-light hover:text-white" + }`; +} + +export function dashboardSidebarLinkClass(active = false, danger = false) { + const classes = ["mobile-sidebar-link"]; + if (active) classes.push("mobile-sidebar-link-active"); + if (danger) classes.push("mobile-sidebar-link-danger"); + return classes.join(" "); +} diff --git a/components/PaygPriceCalculator.tsx b/components/PaygPriceCalculator.tsx new file mode 100644 index 0000000..1f190f6 --- /dev/null +++ b/components/PaygPriceCalculator.tsx @@ -0,0 +1,93 @@ +"use client"; + +import Link from "next/link"; +import { useState } from "react"; +import { + CREDIT_PRICE_CENTS, + CREDIT_PURCHASE_MAX, + CREDIT_PURCHASE_MIN, + formatCreditPrice, +} from "@/lib/credits"; + +export function PaygPriceCalculator() { + const [videos, setVideos] = useState(CREDIT_PURCHASE_MIN); + const total = formatCreditPrice(videos); + const unit = formatCreditPrice(1); + + return ( +
      +

      + Pay as you go +

      +

      + Choose how many videos you need +

      +

      + {unit} per video · minimum {CREDIT_PURCHASE_MIN} videos ( + {formatCreditPrice(CREDIT_PURCHASE_MIN)}) +

      + +
      +
      + +
      + { + const n = Math.floor(Number(e.target.value)); + if (!Number.isFinite(n)) return; + setVideos( + Math.min(CREDIT_PURCHASE_MAX, Math.max(CREDIT_PURCHASE_MIN, n)), + ); + }} + className="w-20 rounded border border-gray-600 bg-surface-dark px-3 py-2 text-center text-lg font-semibold text-white focus:border-accent focus:outline-none" + /> +
      +
      + + setVideos(Number(e.target.value))} + className="mt-4 w-full accent-amber-400" + aria-valuemin={CREDIT_PURCHASE_MIN} + aria-valuemax={CREDIT_PURCHASE_MAX} + aria-valuenow={videos} + aria-label="Number of videos" + /> +
      + {CREDIT_PURCHASE_MIN} + {CREDIT_PURCHASE_MAX} +
      +
      + +
      +
      +

      Total

      +

      {total}

      +

      + {videos} × {unit}{" "} + + (€{(CREDIT_PRICE_CENTS / 100).toFixed(2)} each) + +

      +
      + + Buy credits + +
      +
      + ); +} diff --git a/components/PlanBillingActions.tsx b/components/PlanBillingActions.tsx new file mode 100644 index 0000000..14a7b39 --- /dev/null +++ b/components/PlanBillingActions.tsx @@ -0,0 +1,412 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { useEffect, useState } from "react"; +import { QUOTA_REQUEST_EMAIL } from "@/lib/plans"; + +type ExtensionRequest = { + id: string; + status: string; + message: string; + requestedAt: string; + processedAt: string | null; + adminNote: string | null; +}; + +type ExtensionUsage = { + used: number; + limit: number; + remaining: number; + requests: ExtensionRequest[]; +}; + +type Props = { + initialUsage: ExtensionUsage; +}; + +function openQuotaRequestMailto(reason?: string) { + const subject = encodeURIComponent("Songs2VID Quota reset / extension request"); + const body = encodeURIComponent( + [ + "Hi,", + "", + "I'd like to request a Pro quota reset or temporary extension.", + "", + reason?.trim() ? `Reason:\n${reason.trim()}` : "Reason: (optional add details here)", + "", + "Account email: (please keep the address you use to sign in)", + "", + "Thanks,", + ].join("\n"), + ); + window.location.href = `mailto:${QUOTA_REQUEST_EMAIL}?subject=${subject}&body=${body}`; +} + +function formatEndDate(iso: string | null) { + if (!iso) return null; + return new Date(iso).toLocaleDateString(undefined, { + year: "numeric", + month: "long", + day: "numeric", + }); +} + +export function PlanBillingActions({ initialUsage }: Props) { + const router = useRouter(); + const [usage, setUsage] = useState(initialUsage); + const [cancelling, setCancelling] = useState(false); + const [requesting, setRequesting] = useState(false); + const [openingPortal, setOpeningPortal] = useState(false); + const [showCancelChoices, setShowCancelChoices] = useState(false); + const [cancelAtPeriodEnd, setCancelAtPeriodEnd] = useState(false); + const [endsAt, setEndsAt] = useState(null); + const [error, setError] = useState(null); + const [success, setSuccess] = useState(null); + + useEffect(() => { + let cancelled = false; + (async () => { + try { + const res = await fetch("/api/account/cancel-subscription"); + if (!res.ok) return; + const data = await res.json(); + if (cancelled) return; + setCancelAtPeriodEnd(Boolean(data.cancelAtPeriodEnd)); + setEndsAt(data.endsAt ?? null); + } catch { + /* ignore */ + } + })(); + return () => { + cancelled = true; + }; + }, []); + + async function handleOpenBillingPortal() { + setOpeningPortal(true); + setError(null); + setSuccess(null); + try { + const res = await fetch("/api/account/billing-portal", { method: "POST" }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Could not open billing portal"); + if (!data.url) throw new Error("No portal URL returned"); + window.location.href = data.url; + } catch (err) { + setError(err instanceof Error ? err.message : "Could not open billing portal"); + setOpeningPortal(false); + } + } + + async function cancelWithMode(when: "immediate" | "period_end") { + setCancelling(true); + setError(null); + setSuccess(null); + try { + const res = await fetch("/api/account/cancel-subscription", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ when }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to cancel subscription"); + + setShowCancelChoices(false); + + if (when === "period_end") { + setCancelAtPeriodEnd(true); + setEndsAt(data.endsAt ?? null); + const label = formatEndDate(data.endsAt ?? null); + setSuccess( + label + ? `Cancellation scheduled. You keep Pro until ${label}; no further charges after that.` + : "Cancellation scheduled at the end of your current billing period. You keep Pro until then.", + ); + } else { + setCancelAtPeriodEnd(false); + setEndsAt(null); + setSuccess("Subscription canceled immediately. You are now on the Free plan."); + } + router.refresh(); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to cancel subscription"); + } finally { + setCancelling(false); + } + } + + async function handleResumeSubscription() { + setCancelling(true); + setError(null); + setSuccess(null); + try { + const res = await fetch("/api/account/cancel-subscription", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ action: "resume" }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to resume subscription"); + setCancelAtPeriodEnd(false); + setEndsAt(data.currentPeriodEnd ?? null); + setSuccess("Subscription kept. It will renew as usual."); + router.refresh(); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to resume subscription"); + } finally { + setCancelling(false); + } + } + + async function handleQuotaRequest() { + if (usage.remaining <= 0) return; + + const reason = prompt( + "Optional: tell us why you need a quota reset or extension (leave blank to skip).", + ); + if (reason === null) return; + + setRequesting(true); + setError(null); + setSuccess(null); + + try { + const res = await fetch("/api/account/quota-extension-request", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message: reason }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to submit request"); + + setUsage({ + used: data.used, + limit: data.limit, + remaining: data.remaining, + requests: data.requests ?? usage.requests, + }); + setSuccess( + `Request recorded (${data.used} of ${data.limit} this year). Opening your email client to contact support…`, + ); + openQuotaRequestMailto(reason); + router.refresh(); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to submit request"); + } finally { + setRequesting(false); + } + } + + const hasPending = usage.requests.some((r) => r.status === "PENDING"); + const endLabel = formatEndDate(endsAt); + + return ( +
      +
      +

      + Extension requests this year:{" "} + + {usage.used} / {usage.limit} + + {usage.remaining > 0 ? ( + · {usage.remaining} remaining + ) : ( + · limit reached + )} +

      +
      + + {cancelAtPeriodEnd && ( +
      +

      + Cancellation scheduled + {endLabel ? ( + <> + {" "} + Pro stays active until {endLabel} + + ) : ( + <> at the end of your current billing period + )} + . You will not be charged again. +

      + +
      + )} + + {error && ( +
      + {error} +
      + )} + + {success && ( +
      + {success} +
      + )} + +
      + + + {!cancelAtPeriodEnd && ( + + )} + + { + if (requesting || usage.remaining <= 0 || hasPending) { + e.preventDefault(); + return; + } + e.preventDefault(); + void handleQuotaRequest(); + }} + aria-disabled={requesting || usage.remaining <= 0 || hasPending} + className={`inline-flex items-center justify-center rounded border border-accent/40 px-4 py-2 text-sm font-medium text-accent transition-colors hover:bg-accent/10 ${ + requesting || usage.remaining <= 0 || hasPending + ? "pointer-events-none cursor-not-allowed opacity-50" + : "" + }`} + > + {requesting + ? "Submitting…" + : hasPending + ? "Request pending…" + : "Request quota reset & extension"} + +
      + + {showCancelChoices && ( +
      +

      + When should Pro end? +

      +

      + This is sent to Stripe. Choose how you want to cancel your subscription. +

      +
      + + +
      + +
      + )} + + {usage.requests.length > 0 && ( +
      +

      + Request history +

      +
        + {usage.requests.slice(0, 5).map((req) => ( +
      • +
        + + {new Date(req.requestedAt).toLocaleDateString(undefined, { + month: "short", + day: "numeric", + year: "numeric", + })} + + + {req.status} + +
        + {req.message &&

        {req.message}

        } +

        ID: {req.id}

        +
      • + ))} +
      +
      + )} + +

      + Pro users may request up to 5 manual quota resets or extensions per calendar year by emailing{" "} + + {QUOTA_REQUEST_EMAIL} + + . See our{" "} + + Terms of Service + + . +

      +
      + ); +} diff --git a/components/PlaylistSelect.tsx b/components/PlaylistSelect.tsx new file mode 100644 index 0000000..f4ddabb --- /dev/null +++ b/components/PlaylistSelect.tsx @@ -0,0 +1,195 @@ +"use client"; + +import { useCallback, useEffect, useState } from "react"; +import { UpgradeProLink } from "./UpgradeProLink"; + +type Playlist = { + id: string; + title: string; + itemCount: number; +}; + +type Props = { + value: string; + onChange: (playlistId: string) => void; + enabled: boolean; +}; + +export function PlaylistSelect({ value, onChange, enabled }: Props) { + const [playlists, setPlaylists] = useState([]); + const [loading, setLoading] = useState(false); + const [creating, setCreating] = useState(false); + const [error, setError] = useState(null); + const [showCreate, setShowCreate] = useState(false); + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [privacy, setPrivacy] = useState<"public" | "unlisted" | "private">("private"); + + const loadPlaylists = useCallback(async () => { + setLoading(true); + setError(null); + try { + const res = await fetch("/api/youtube/playlists"); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to load playlists"); + setPlaylists(data.playlists ?? []); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to load playlists"); + } finally { + setLoading(false); + } + }, []); + + useEffect(() => { + if (!enabled) return; + void loadPlaylists(); + }, [enabled, loadPlaylists]); + + async function handleCreate() { + if (!title.trim()) { + setError("Playlist title is required"); + return; + } + + setCreating(true); + setError(null); + try { + const res = await fetch("/api/youtube/playlists", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + title: title.trim(), + description: description.trim() || undefined, + privacy, + }), + }); + const data = await res.json(); + if (!res.ok) throw new Error(data.error || "Failed to create playlist"); + + const playlist = data.playlist as Playlist; + setPlaylists((prev) => [playlist, ...prev]); + onChange(playlist.id); + setShowCreate(false); + setTitle(""); + setDescription(""); + setPrivacy("private"); + } catch (err) { + setError(err instanceof Error ? err.message : "Failed to create playlist"); + } finally { + setCreating(false); + } + } + + if (!enabled) { + return ( +

      + Add uploaded videos to a YouTube playlist with{" "} + . +

      + ); + } + + return ( +
      +
      + + +
      + +
      + + +
      + + {showCreate && ( +
      +
      + + setTitle(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") { + e.preventDefault(); + void handleCreate(); + } + }} + className="input-field w-full" + placeholder="My Songs2VID uploads" + /> +
      +
      + + setDescription(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") { + e.preventDefault(); + void handleCreate(); + } + }} + className="input-field w-full" + /> +
      +
      + + +
      + +
      + )} + + {loading &&

      Loading playlists…

      } + {error &&

      {error}

      } + {!loading && !error && playlists.length === 0 && !showCreate && ( +

      + No playlists yet. Create one above. If playlist access was just added, sign out and sign + in again to grant the new Google permission. +

      + )} +
      + ); +} diff --git a/components/PricingSection.tsx b/components/PricingSection.tsx new file mode 100644 index 0000000..3b4a3c5 --- /dev/null +++ b/components/PricingSection.tsx @@ -0,0 +1,336 @@ +"use client"; + +import Link from "next/link"; +import { useRef } from "react"; +import { ScrollReveal } from "@/components/ScrollReveal"; +import { SectionScrollTitle } from "@/components/SectionScrollTitle"; +import { SignInButton } from "@/components/SignInButton"; +import { getVideoAttributionText } from "@/lib/branding"; +import { SALES_EMAIL } from "@/lib/plans"; + +const FEATURE_LABELS = [ + "Infrastructure", + "Limit", + "Batch mode", + "Bulk image matching", + "File type", + "Playlists", + "API support", + "ID3 tags", + "Support", + "Watermark", +] as const; + +type PlanFeatures = Record<(typeof FEATURE_LABELS)[number], string>; + +type InfrastructureChip = "cloud" | "self-hosted"; + +type PlanConfig = { + name: string; + badge: string; + price: string; + priceNote: string; + features: PlanFeatures; + infrastructureChips: InfrastructureChip[]; + watermarkNote?: string; + cta: + | { type: "signin" } + | { type: "link"; label: string; href: string } + | { type: "disabled"; label: string } + | { type: "mailto"; label: string; email: string; subject: string }; + highlighted: boolean; + hover: string; + accent: string; + badgeClass: string; + ctaClass?: string; +}; + +const PLANS: PlanConfig[] = [ + { + name: "Bedroom Producer", + badge: "Free", + price: "€0", + priceNote: "/ forever", + features: { + Infrastructure: "Cloud", + Limit: "10 videos* / month · 720p · buy 1–15 extras (€0.25 each)", + "Batch mode": "Limited batch · up to 3 files", + "Bulk image matching": "1 static image only", + "File type": "MP3", + Playlists: "Not included", + "API support": "Not included", + "ID3 tags": "Auto-fill title & metadata from MP3 tags", + Support: "Community", + Watermark: "Optional Songs2VID badge · bottom-right", + }, + infrastructureChips: ["cloud"], + watermarkNote: + `Show "${getVideoAttributionText()}" to support open-source development - opt out anytime for a clean video.`, + cta: { type: "signin" }, + highlighted: false, + hover: + "hover:border-red-500/40 hover:bg-red-500/[0.04] hover:shadow-lg hover:shadow-red-500/15", + accent: "text-red-400", + badgeClass: "bg-gray-800 text-gray-400", + }, + { + name: "Independent Artist", + badge: "Pro", + price: "€5", + priceNote: "/ mo", + features: { + Infrastructure: "Cloud", + Limit: "50 videos / month · 1080p", + "Batch mode": "Full batch · up to 5 files", + "Bulk image matching": "Unique image per track (PRO)", + "File type": "MP3 / WAV / FLAC", + Playlists: "Create & add uploads to YouTube playlists", + "API support": "REST API · upload, batch & playlists", + "ID3 tags": "Extended metadata support", + Support: "E-Mail", + Watermark: "Custom text/logo/fonts · art-track layouts + blur (PRO)", + }, + infrastructureChips: ["cloud"], + cta: { type: "link", label: "Upgrade to Pro", href: "/dashboard/settings" }, + highlighted: true, + hover: + "hover:border-accent/50 hover:bg-accent/[0.06] hover:shadow-lg hover:shadow-accent/20", + accent: "text-accent", + badgeClass: "bg-accent/15 text-accent", + }, + { + name: "Record Label / Studio", + badge: "Enterprise", + price: "Custom", + priceNote: "/ contact sales", + features: { + Infrastructure: "Cloud or self-hosted", + Limit: "Unlimited 4K · zero limit", + "Batch mode": "Unlimited synchronized batch processing", + "Bulk image matching": "Unique image per track", + "File type": "WAV / FLAC / lossless", + Playlists: "Org-wide playlist workflows", + "API support": "Full API access · custom integrations & SLAs", + "ID3 tags": "Full metadata · custom mapping", + Support: "Top-priority**", + Watermark: "Custom branding · position studio", + }, + infrastructureChips: ["cloud", "self-hosted"], + cta: { + type: "mailto", + label: "Contact Sales", + email: SALES_EMAIL, + subject: "Songs2VID Enterprise Inquiry", + }, + highlighted: false, + hover: + "hover:border-[#609926]/45 hover:bg-[#609926]/[0.06] hover:shadow-lg hover:shadow-[#609926]/20", + accent: "text-[#609926]", + badgeClass: "bg-[#609926]/15 text-[#609926]", + ctaClass: + "border-[#609926]/40 bg-[#609926]/10 text-[#609926] hover:border-[#609926]/60 hover:bg-[#609926]/20", + }, +]; + +function FeatureValue({ value }: { value: string }) { + return {value}; +} + +function CloudIcon({ className }: { className?: string }) { + return ( + + ); +} + +function ServerIcon({ className }: { className?: string }) { + return ( + + ); +} + +function InfrastructureChips({ + chips, +}: { + chips: InfrastructureChip[]; +}) { + return ( +
      + {chips.includes("cloud") && ( + + + Cloud + + )} + {chips.includes("self-hosted") && ( + + + Self-hosted + + )} +
      + ); +} + +function PricingCard({ plan }: { plan: PlanConfig }) { + const { + name, + badge, + price, + priceNote, + features, + watermarkNote, + infrastructureChips, + cta, + highlighted, + hover, + accent, + badgeClass, + ctaClass, + } = plan; + + return ( +
      + {highlighted && ( + + Most popular + + )} + +
      +
      +

      {name}

      + + {badge} + +
      + +
      + {price} + {priceNote} +
      +
      + +
        + {FEATURE_LABELS.map((label) => ( +
      • +

        {label}

        + {label === "Infrastructure" ? ( + + ) : ( + + )} + {label === "Watermark" && watermarkNote && ( +

        + {watermarkNote} +

        + )} +
      • + ))} +
      + +
      + {cta.type === "signin" && } + {cta.type === "link" && ( + + {cta.label} + + )} + {cta.type === "disabled" && ( + + )} + {cta.type === "mailto" && ( + + {cta.label} + + )} +
      +
      + ); +} + +export function PricingSection() { + const sectionRef = useRef(null); + + return ( +
      + + +
      + +

      Pricing

      +

      + Free with optional extras, Pro at €5/month, or Enterprise for studios. +

      +
      + +
      + {PLANS.map((plan, index) => ( + + + + ))} +
      + + +

      + *Free includes 10 videos/month; buy 1–15 extras at €0.25 each (max 15 extras). After both + are used, Pro (€5/mo · 50 videos) is required. Total balance capped at 30. Deduction + order: monthly first, then extras. +

      +

      + **Technical support is strictly reserved for Managed Cloud and paid Professional Setup + agreements; independent self-hosted deployments are community-supported. +

      +
      +
      +
      + ); +} diff --git a/components/RecentYouTubeLimitAlert.tsx b/components/RecentYouTubeLimitAlert.tsx new file mode 100644 index 0000000..9276710 --- /dev/null +++ b/components/RecentYouTubeLimitAlert.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { isYouTubeUploadLimitError } from "@/lib/youtube/errors"; +import { YouTubeLimitBanner } from "./YouTubeLimitBanner"; + +/** Shows a dashboard alert when a recent job hit YouTube's upload limit. */ +export function RecentYouTubeLimitAlert() { + const [show, setShow] = useState(false); + + useEffect(() => { + let active = true; + + fetch("/api/jobs?limit=10") + .then(async (res) => { + if (!res.ok) return; + const data = await res.json(); + const hit = (data.jobs ?? []).some((job: { items?: Array<{ status: string; error?: string | null }> }) => + (job.items ?? []).some( + (item) => item.status === "FAILED" && item.error && isYouTubeUploadLimitError(item.error), + ), + ); + if (active) setShow(hit); + }) + .catch(() => {}); + + return () => { + active = false; + }; + }, []); + + if (!show) return null; + return ; +} diff --git a/components/ResolutionSelect.tsx b/components/ResolutionSelect.tsx index 5296a42..e73edb7 100644 --- a/components/ResolutionSelect.tsx +++ b/components/ResolutionSelect.tsx @@ -1,14 +1,18 @@ "use client"; -import { RESOLUTIONS } from "@/lib/constants"; +import { Plan } from "@prisma/client"; +import { getResolutionsForPlan } from "@/lib/plans"; type Props = { value: string; onChange: (value: string) => void; disabled?: boolean; + plan?: Plan; }; -export function ResolutionSelect({ value, onChange, disabled }: Props) { +export function ResolutionSelect({ value, onChange, disabled, plan = "FREE" }: Props) { + const resolutions = getResolutionsForPlan(plan); + return (

      Video details (per audio)

      - Each audio file gets its own metadata. Title is auto-filled from the filename. + Each audio file gets its own metadata. Video title is used for YouTube; song title and + artist appear in Pro art-track layouts.

      +
      + +
      + {audioItems.map((item, index) => (
      - + updateItemMetadata(item.id, { title: e.target.value })} className="input-field" required + placeholder="Title shown on YouTube" /> + + updateItemMetadata(item.id, { songTitle: e.target.value })} + className="input-field disabled:cursor-not-allowed disabled:opacity-60" + disabled={!isPro} + placeholder={isPro ? "Shown in art-track layout" : "Pro feature"} + maxLength={SONG_TITLE_MAX} + /> + +
      + +
      + + updateItemMetadata(item.id, { artist: e.target.value })} + className="input-field disabled:cursor-not-allowed disabled:opacity-60" + disabled={!isPro} + placeholder={isPro ? "Shown in art-track layout" : "Pro feature"} + maxLength={80} + /> + updateItemMetadata(item.id, { resolution: v })} + plan={quota?.plan} /> +
      + {!canPerItemImages && ( +
      + + Pro + + Unique image per track +
      + )} + + { + const f = e.target.files?.[0] ?? null; + void handleItemImageChange(item.id, f); + e.target.value = ""; + }} + className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white disabled:opacity-50" + /> + + {item.itemImageName && ( +

      + {item.itemImagePath ? `Using ${item.itemImageName}` : `Uploading ${item.itemImageName}…`} +

      + )} + {!canPerItemImages && ( +

      + +

      + )} +
      +
      updateItemMetadata(item.id, { creativeCommons: v })} /> - {}} - disabled - /> + {!canCustomWatermark && ( + + applyWatermarkToAll({ + ...DEFAULT_WATERMARK, + mode: v ? "default" : "none", + }) + } + /> + )}
      ))} )} -

      - Upgrade your account to remove watermarks, go ad-free, and unlock advanced settings. -

      + a.itemImagePreview)?.itemImagePreview || imagePreviewUrl + } + songTitle={ + audioItems[0]?.metadata.songTitle || + audioItems[0]?.metadata.title || + "Track title" + } + artist={audioItems[0]?.metadata.artist || ""} + encodeWidth={parseInt(readyAudios[0]?.metadata.resolution?.split("x")[0] || "1280", 10)} + layout={jobLayout} + onLayoutChange={applyLayoutToAll} + watermark={jobWatermark} + onWatermarkChange={applyWatermarkToAll} + onUploadLogo={handleLogoUpload} + onUploadFont={handleFontUpload} + logoPreviewUrl={logoPreviewUrl} + /> + + {quota && !quota.selfHosted && quota.plan === "FREE" && ( + <> +

      + Free plan: one static cover image for the batch · optional Songs2VID watermark + (bottom-right only). +

      +

      + for custom branding, typography, + blurred art-track layouts, watermark positioning, unique image matching, 1080p, and + lossless audio. +

      + + )}
      + ); +} + function Checkbox({ label, checked, diff --git a/components/WatermarkPreview.tsx b/components/WatermarkPreview.tsx new file mode 100644 index 0000000..02c7a02 --- /dev/null +++ b/components/WatermarkPreview.tsx @@ -0,0 +1,417 @@ +"use client"; + +import { + useEffect, + useMemo, + useState, + type CSSProperties, + type ChangeEvent, +} from "react"; +import { getVideoAttributionText } from "@/lib/branding"; +import { + CURATED_FONTS, + googleFontsStylesheetUrl, + type CuratedFontKey, + type WatermarkFontKey, +} from "@/lib/fonts"; +import { + WATERMARK_OFFSET_MAX, + WATERMARK_OFFSET_MIN, + WATERMARK_POSITIONS, + WATERMARK_TEXT_MAX, + type WatermarkMode, + type WatermarkPosition, + type WatermarkSettings, +} from "@/lib/watermark"; +import { UpgradeProButton } from "./UpgradeProButton"; + +type Props = { + enabled: boolean; + locked: boolean; + previewImageUrl: string | null; + value: WatermarkSettings; + onChange: (next: WatermarkSettings) => void; + onUploadLogo: (file: File) => Promise; + onUploadFont: (file: File) => Promise; + logoPreviewUrl?: string | null; +}; + +const POSITION_LABELS: Record = { + "top-left": "Top left", + "top-right": "Top right", + "bottom-left": "Bottom left", + "bottom-right": "Bottom right", + center: "Center", +}; + +const CUSTOM_PREVIEW_FAMILY = "S2VIDCustomWm"; + +function previewStyle( + position: WatermarkPosition, + offsetX: number, + offsetY: number, +): CSSProperties { + const base: CSSProperties = { + position: "absolute", + maxWidth: "32%", + pointerEvents: "none", + }; + const ox = `${offsetX}px`; + const oy = `${offsetY}px`; + switch (position) { + case "top-left": + return { ...base, top: oy, left: ox }; + case "top-right": + return { ...base, top: oy, right: ox }; + case "bottom-left": + return { ...base, bottom: oy, left: ox }; + case "center": + return { + ...base, + top: "50%", + left: "50%", + transform: `translate(calc(-50% + ${offsetX}px), calc(-50% + ${offsetY}px))`, + }; + case "bottom-right": + default: + return { ...base, bottom: oy, right: ox }; + } +} + +function previewFontFamily(fontKey: WatermarkFontKey | undefined): string { + if (!fontKey || fontKey === "system") return "ui-sans-serif, system-ui, sans-serif"; + if (fontKey === "custom") return `'${CUSTOM_PREVIEW_FAMILY}', sans-serif`; + const meta = CURATED_FONTS.find((f) => f.key === fontKey); + return meta ? `'${meta.cssFamily}', sans-serif` : "sans-serif"; +} + +export function WatermarkPreview({ + enabled, + locked, + previewImageUrl, + value, + onChange, + onUploadLogo, + onUploadFont, + logoPreviewUrl, +}: Props) { + const [logoUploading, setLogoUploading] = useState(false); + const [logoError, setLogoError] = useState(null); + const [fontUploading, setFontUploading] = useState(false); + const [fontError, setFontError] = useState(null); + const [customFontObjectUrl, setCustomFontObjectUrl] = useState(null); + + const overlay = useMemo( + () => previewStyle(value.position, value.offsetX, value.offsetY), + [value.position, value.offsetX, value.offsetY], + ); + + const textFontStyle = useMemo( + () => ({ fontFamily: previewFontFamily(value.fontKey) }), + [value.fontKey], + ); + + // Load curated Google Fonts for live canvas preview + useEffect(() => { + const id = "s2vid-watermark-google-fonts"; + if (document.getElementById(id)) return; + const link = document.createElement("link"); + link.id = id; + link.rel = "stylesheet"; + link.href = googleFontsStylesheetUrl(CURATED_FONTS.map((f) => f.key)); + document.head.appendChild(link); + }, []); + + // @font-face for uploaded custom font (browser preview only) + useEffect(() => { + if (!customFontObjectUrl) return; + const styleId = "s2vid-watermark-custom-font"; + let el = document.getElementById(styleId) as HTMLStyleElement | null; + if (!el) { + el = document.createElement("style"); + el.id = styleId; + document.head.appendChild(el); + } + el.textContent = ` +@font-face { + font-family: '${CUSTOM_PREVIEW_FAMILY}'; + src: url('${customFontObjectUrl}'); + font-display: swap; +}`; + return () => { + /* keep style until next custom font replaces it */ + }; + }, [customFontObjectUrl]); + + useEffect(() => { + return () => { + if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl); + }; + }, [customFontObjectUrl]); + + function patch(partial: Partial) { + if (locked) return; + onChange({ ...value, ...partial }); + } + + async function handleLogo(e: ChangeEvent) { + const file = e.target.files?.[0]; + e.target.value = ""; + if (!file || locked) return; + setLogoError(null); + setLogoUploading(true); + try { + const path = await onUploadLogo(file); + patch({ mode: "logo", logoPath: path }); + } catch (err) { + setLogoError(err instanceof Error ? err.message : "Logo upload failed"); + } finally { + setLogoUploading(false); + } + } + + async function handleFont(e: ChangeEvent) { + const file = e.target.files?.[0]; + e.target.value = ""; + if (!file || locked) return; + setFontError(null); + setFontUploading(true); + try { + const objectUrl = URL.createObjectURL(file); + if (customFontObjectUrl) URL.revokeObjectURL(customFontObjectUrl); + setCustomFontObjectUrl(objectUrl); + const path = await onUploadFont(file); + patch({ mode: "text", fontKey: "custom", fontPath: path }); + } catch (err) { + setFontError(err instanceof Error ? err.message : "Font upload failed"); + } finally { + setFontUploading(false); + } + } + + function setFontKey(key: WatermarkFontKey) { + if (key === "custom") { + patch({ fontKey: "custom", fontPath: value.fontPath ?? null }); + return; + } + patch({ fontKey: key, fontPath: null }); + } + + return ( +
      + {locked && ( +
      + + Pro + +

      + Custom branding, typography, logo overlay, and position controls are Pro features. +

      + +
      + )} + +
      +

      Watermark layout

      + + Pro / B2B + +
      + +
      + {previewImageUrl ? ( + // eslint-disable-next-line @next/next/no-img-element + + ) : ( +
      + Upload a cover image to preview +
      + )} + + {enabled && value.mode !== "none" && ( +
      + {value.mode === "logo" && logoPreviewUrl ? ( + // eslint-disable-next-line @next/next/no-img-element + + ) : ( + + {value.mode === "text" && value.text?.trim() + ? value.text.trim().slice(0, WATERMARK_TEXT_MAX) + : getVideoAttributionText()} + + )} +
      + )} +
      + +
      +
      + {( + [ + ["none", "No watermark"], + ["default", "Songs2VID badge"], + ["text", "Custom text"], + ["logo", "PNG logo"], + ] as const + ).map(([mode, label]) => ( + + ))} +
      + + {value.mode === "text" && ( + <> + + + + + {(value.fontKey === "custom" || + (value.fontKey && + value.fontKey !== "system" && + CURATED_FONTS.some((f) => f.key === (value.fontKey as CuratedFontKey)))) && ( +

      + Preview: The quick brown fox jumps over the lazy dog +

      + )} + + {value.fontKey === "custom" && ( +
      + + void handleFont(e)} + className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white" + /> + {fontUploading && ( +

      Uploading font…

      + )} + {fontError &&

      {fontError}

      } + {value.fontPath && !fontError && ( +

      Custom font ready for render

      + )} +
      + )} + + )} + + {value.mode === "logo" && ( +
      + + void handleLogo(e)} + className="block w-full text-sm text-gray-300 file:mr-4 file:rounded file:border-0 file:bg-accent file:px-4 file:py-2 file:text-sm file:text-white" + /> + {logoUploading &&

      Uploading logo…

      } + {logoError &&

      {logoError}

      } +
      + )} + +
      +

      Position

      +
      + {WATERMARK_POSITIONS.map((pos) => ( + + ))} +
      +
      + +
      + + +
      +
      +
      + ); +} diff --git a/components/YouTubeLimitBanner.tsx b/components/YouTubeLimitBanner.tsx new file mode 100644 index 0000000..ca95283 --- /dev/null +++ b/components/YouTubeLimitBanner.tsx @@ -0,0 +1,16 @@ +import { YOUTUBE_UPLOAD_LIMIT_USER_MESSAGE } from "@/lib/youtube/errors"; + +type Props = { + className?: string; +}; + +export function YouTubeLimitBanner({ className = "" }: Props) { + return ( +
      +

      YouTube upload limit reached

      +

      {YOUTUBE_UPLOAD_LIMIT_USER_MESSAGE}

      +
      + ); +} diff --git a/deploy/songs2vid/Caddyfile b/deploy/songs2vid/Caddyfile new file mode 100644 index 0000000..c06b319 --- /dev/null +++ b/deploy/songs2vid/Caddyfile @@ -0,0 +1,21 @@ +songs2vid.com, www.songs2vid.com { + encode gzip + reverse_proxy web:3000 +} + +docs.songs2vid.com { + encode gzip + root * /srv/docs + file_server + try_files {path} /index.html +} + +# Basic-auth hash is generated on the server (caddy hash-password). +# Do not commit live hashes/passwords here. +studio.songs2vid.com { + encode gzip + basicauth { + admin REPLACE_WITH_CADDY_HASH + } + reverse_proxy studio:5555 +} diff --git a/deploy/songs2vid/docker-compose.yml b/deploy/songs2vid/docker-compose.yml new file mode 100644 index 0000000..6fa08c7 --- /dev/null +++ b/deploy/songs2vid/docker-compose.yml @@ -0,0 +1,101 @@ +services: + postgres: + image: postgres:16-alpine + restart: unless-stopped + environment: + POSTGRES_USER: s2vid + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: s2vid + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U s2vid -d s2vid"] + interval: 5s + timeout: 5s + retries: 10 + + redis: + image: redis:7-alpine + restart: unless-stopped + command: ["redis-server", "--appendonly", "yes"] + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 10 + + web: + image: atakanozban/songs2vid:latest + restart: unless-stopped + expose: + - "3000" + env_file: + - .env + environment: + DATABASE_URL: postgresql://s2vid:${POSTGRES_PASSWORD}@postgres:5432/s2vid + REDIS_URL: redis://redis:6379 + UPLOAD_DIR: /app/uploads + NEXTAUTH_URL: ${NEXTAUTH_URL} + volumes: + - uploads_data:/app/uploads + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + command: > + sh -c "npx prisma db push && node server.js" + + worker: + image: atakanozban/songs2vid:latest + restart: unless-stopped + env_file: + - .env + environment: + DATABASE_URL: postgresql://s2vid:${POSTGRES_PASSWORD}@postgres:5432/s2vid + REDIS_URL: redis://redis:6379 + UPLOAD_DIR: /app/uploads + volumes: + - uploads_data:/app/uploads + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + command: ["npx", "tsx", "worker/index.ts"] + + studio: + image: atakanozban/songs2vid:latest + restart: unless-stopped + expose: + - "5555" + environment: + DATABASE_URL: postgresql://s2vid:${POSTGRES_PASSWORD}@postgres:5432/s2vid + depends_on: + postgres: + condition: service_healthy + command: ["npx", "prisma", "studio", "--hostname", "0.0.0.0", "--port", "5555", "--browser", "none"] + + caddy: + image: caddy:2-alpine + restart: unless-stopped + ports: + - "80:80" + - "443:443" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile:ro + - ./docs-site:/srv/docs:ro + - caddy_data:/data + - caddy_config:/config + depends_on: + - web + - studio + +volumes: + postgres_data: + redis_data: + uploads_data: + caddy_data: + caddy_config: diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..680f6a5 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,37 @@ +# Local infra only (Postgres + Redis). Use root docker-compose.yml for full stack. +# Host ports 5433/6380 avoid clashes with other local stacks on 5432/6379. +services: + postgres: + image: postgres:16-alpine + restart: unless-stopped + environment: + POSTGRES_USER: s2yt + POSTGRES_PASSWORD: s2yt + POSTGRES_DB: s2yt + ports: + - "127.0.0.1:5433:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U s2yt -d s2yt"] + interval: 5s + timeout: 5s + retries: 10 + + redis: + image: redis:7-alpine + restart: unless-stopped + ports: + - "127.0.0.1:6380:6379" + command: ["redis-server", "--appendonly", "yes"] + volumes: + - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 10 + +volumes: + postgres_data: + redis_data: diff --git a/docker-compose.yml b/docker-compose.yml index 426f7c9..698e1e6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,19 +6,70 @@ services: POSTGRES_USER: s2yt POSTGRES_PASSWORD: s2yt POSTGRES_DB: s2yt - ports: - - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U s2yt -d s2yt"] + interval: 5s + timeout: 5s + retries: 10 redis: image: redis:7-alpine restart: unless-stopped - ports: - - "6379:6379" + command: ["redis-server", "--appendonly", "yes"] volumes: - redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 10 + + web: + build: . + # Multi-arch Hub release: ./scripts/release-cloud.sh --push + restart: unless-stopped + ports: + - "${S2VID_PORT:-3000}:3000" + env_file: + - .env + environment: + S2VID_EDITION: selfhosted + DATABASE_URL: postgresql://s2yt:s2yt@postgres:5432/s2yt + REDIS_URL: redis://redis:6379 + UPLOAD_DIR: /app/uploads + NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000} + volumes: + - uploads_data:/app/uploads + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + command: > + sh -c "npx prisma db push && node server.js" + + worker: + build: . + restart: unless-stopped + env_file: + - .env + environment: + S2VID_EDITION: selfhosted + DATABASE_URL: postgresql://s2yt:s2yt@postgres:5432/s2yt + REDIS_URL: redis://redis:6379 + UPLOAD_DIR: /app/uploads + volumes: + - uploads_data:/app/uploads + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + command: ["npx", "tsx", "worker/index.ts"] volumes: postgres_data: redis_data: + uploads_data: diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 05e726d..0000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,18 +0,0 @@ -import { defineConfig, globalIgnores } from "eslint/config"; -import nextVitals from "eslint-config-next/core-web-vitals"; -import nextTs from "eslint-config-next/typescript"; - -const eslintConfig = defineConfig([ - ...nextVitals, - ...nextTs, - // Override default ignores of eslint-config-next. - globalIgnores([ - // Default ignores of eslint-config-next: - ".next/**", - "out/**", - "build/**", - "next-env.d.ts", - ]), -]); - -export default eslintConfig; diff --git a/hooks/useInView.ts b/hooks/useInView.ts new file mode 100644 index 0000000..fc8166e --- /dev/null +++ b/hooks/useInView.ts @@ -0,0 +1,40 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; + +type Options = { + threshold?: number; + rootMargin?: string; + once?: boolean; +}; + +export function useInView({ + threshold = 0.15, + rootMargin = "0px 0px -40px 0px", + once = true, +}: Options = {}) { + const ref = useRef(null); + const [inView, setInView] = useState(false); + + useEffect(() => { + const el = ref.current; + if (!el) return; + + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + setInView(true); + if (once) observer.unobserve(el); + } else if (!once) { + setInView(false); + } + }, + { threshold, rootMargin }, + ); + + observer.observe(el); + return () => observer.disconnect(); + }, [threshold, rootMargin, once]); + + return { ref, inView }; +} diff --git a/hooks/useMockupProgress.ts b/hooks/useMockupProgress.ts new file mode 100644 index 0000000..71340de --- /dev/null +++ b/hooks/useMockupProgress.ts @@ -0,0 +1,30 @@ +"use client"; + +import { useEffect, useState } from "react"; + +export function useMockupProgress( + active: boolean, + phaseOneMs = 3000, + phaseTwoMs = 2000, +) { + const [phase, setPhase] = useState<0 | 1 | 2>(0); + const [processed, setProcessed] = useState(false); + + useEffect(() => { + if (!active) return; + + const startFrame = requestAnimationFrame(() => setPhase(1)); + const midTimer = setTimeout(() => setPhase(2), phaseOneMs); + const doneTimer = setTimeout(() => setProcessed(true), phaseOneMs + phaseTwoMs); + + return () => { + cancelAnimationFrame(startFrame); + clearTimeout(midTimer); + clearTimeout(doneTimer); + }; + }, [active, phaseOneMs, phaseTwoMs]); + + const transitionMs = phase === 1 ? phaseOneMs : phase === 2 ? phaseTwoMs : 0; + + return { phase, processed, transitionMs }; +} diff --git a/lib/api-auth.ts b/lib/api-auth.ts new file mode 100644 index 0000000..5c165e8 --- /dev/null +++ b/lib/api-auth.ts @@ -0,0 +1,105 @@ +import { NextRequest, NextResponse } from "next/server"; +import { findUserByApiKey } from "./api-keys"; +import { checkApiRateLimit } from "./api-rate-limit"; +import { hasProFeatures } from "./edition"; +import { getSessionUser } from "./session"; + +function extractBearerToken(req: NextRequest) { + const auth = req.headers.get("authorization"); + if (!auth?.startsWith("Bearer ")) return null; + return auth.slice(7).trim(); +} + +export async function requirePaidApiUser(req: NextRequest) { + const token = extractBearerToken(req); + if (!token) { + return { + error: NextResponse.json( + { error: "Missing API key. Use Authorization: Bearer " }, + { status: 401 }, + ), + user: null, + }; + } + + const user = await findUserByApiKey(token); + if (!user) { + return { + error: NextResponse.json({ error: "Invalid API key" }, { status: 401 }), + user: null, + }; + } + + if (!hasProFeatures(user.plan)) { + return { + error: NextResponse.json( + { error: "API access requires an active Pro subscription" }, + { status: 403 }, + ), + user: null, + }; + } + + if (!user.youtubeConnection) { + return { + error: NextResponse.json( + { error: "YouTube account not connected. Sign in via the dashboard first." }, + { status: 403 }, + ), + user: null, + }; + } + + const rateLimit = await checkApiRateLimit(user.id); + if (!rateLimit.ok) { + return { + error: NextResponse.json( + { + error: "API rate limit exceeded. Try again shortly.", + retryAfterSeconds: rateLimit.retryAfterSeconds, + }, + { + status: 429, + headers: { "Retry-After": String(rateLimit.retryAfterSeconds) }, + }, + ), + user: null, + }; + } + + return { error: null, user }; +} + +export async function requirePaidUserFromSessionOrApi(req: NextRequest) { + const apiResult = await requirePaidApiUser(req); + if (apiResult.user) return apiResult; + + const sessionUser = await getSessionUser(); + if (!sessionUser) { + return apiResult.error + ? apiResult + : { + error: NextResponse.json({ error: "Unauthorized" }, { status: 401 }), + user: null, + }; + } + + if (!hasProFeatures(sessionUser.plan)) { + return { + error: NextResponse.json( + { error: "API access requires an active Pro subscription" }, + { status: 403 }, + ), + user: null, + }; + } + + if (!sessionUser.youtubeConnection) { + return { + error: NextResponse.json({ error: "YouTube account not connected" }, { status: 403 }), + user: null, + }; + } + + return { error: null, user: sessionUser }; +} diff --git a/lib/api-keys.ts b/lib/api-keys.ts new file mode 100644 index 0000000..3e01b8a --- /dev/null +++ b/lib/api-keys.ts @@ -0,0 +1,64 @@ +import { createHash, randomBytes } from "crypto"; +import { prisma } from "./db"; + +const API_KEY_PREFIX = "s2yt_live_"; + +export function hashApiKey(token: string) { + return createHash("sha256").update(token).digest("hex"); +} + +export function generateApiKeyMaterial() { + const secret = randomBytes(24).toString("base64url"); + const token = `${API_KEY_PREFIX}${secret}`; + return { + token, + hash: hashApiKey(token), + prefix: token.slice(0, 20), + }; +} + +export async function createUserApiKey(userId: string) { + const { token, hash, prefix } = generateApiKeyMaterial(); + + await prisma.user.update({ + where: { id: userId }, + data: { + apiKeyHash: hash, + apiKeyPrefix: prefix, + }, + }); + + return { token, prefix }; +} + +export async function revokeUserApiKey(userId: string) { + await prisma.user.update({ + where: { id: userId }, + data: { + apiKeyHash: null, + apiKeyPrefix: null, + }, + }); +} + +export async function getUserApiKeyStatus(userId: string) { + const user = await prisma.user.findUniqueOrThrow({ + where: { id: userId }, + select: { apiKeyPrefix: true, apiKeyHash: true }, + }); + + return { + configured: Boolean(user.apiKeyHash), + prefix: user.apiKeyPrefix, + }; +} + +export async function findUserByApiKey(token: string) { + if (!token.startsWith(API_KEY_PREFIX)) return null; + + const hash = hashApiKey(token); + return prisma.user.findFirst({ + where: { apiKeyHash: hash }, + include: { youtubeConnection: true }, + }); +} diff --git a/lib/api-rate-limit.ts b/lib/api-rate-limit.ts new file mode 100644 index 0000000..04acd86 --- /dev/null +++ b/lib/api-rate-limit.ts @@ -0,0 +1,155 @@ +import IORedis from "ioredis"; +import { prisma } from "./db"; +import { isSelfHostedEdition } from "./edition"; + +export const DEFAULT_API_RATE_LIMIT = 60; +export const API_RATE_WINDOW_SECONDS = 60; +export const MAX_ADMIN_API_RATE_BONUS = 120; +const SELFHOSTED_API_RATE_LIMIT = 100_000; + +type MemoryBucket = { + count: number; + resetAt: number; +}; + +const memoryBuckets = new Map(); +let redis: IORedis | null | undefined; + +function getRedis() { + if (redis !== undefined) return redis; + try { + const url = process.env.REDIS_URL || "redis://localhost:6379"; + redis = new IORedis(url, { + maxRetriesPerRequest: 1, + enableOfflineQueue: false, + lazyConnect: true, + }); + return redis; + } catch { + redis = null; + return null; + } +} + +function rateKey(userId: string) { + return `s2yt:api-rate:${userId}`; +} + +export async function getEffectiveApiRateLimit(userId: string) { + if (isSelfHostedEdition()) return SELFHOSTED_API_RATE_LIMIT; + const user = await prisma.user.findUnique({ + where: { id: userId }, + select: { apiRateLimitBonus: true, plan: true }, + }); + if (!user || user.plan !== "PREMIUM") return DEFAULT_API_RATE_LIMIT; + return DEFAULT_API_RATE_LIMIT + Math.max(0, user.apiRateLimitBonus); +} + +function memoryStatus(userId: string, limit: number) { + const now = Date.now(); + const bucket = memoryBuckets.get(userId); + if (!bucket || now >= bucket.resetAt) { + return { + limit, + used: 0, + remaining: limit, + windowSeconds: API_RATE_WINDOW_SECONDS, + resetsInSeconds: API_RATE_WINDOW_SECONDS, + bonus: Math.max(0, limit - DEFAULT_API_RATE_LIMIT), + }; + } + const used = Math.min(bucket.count, limit); + return { + limit, + used, + remaining: Math.max(0, limit - used), + windowSeconds: API_RATE_WINDOW_SECONDS, + resetsInSeconds: Math.max(1, Math.ceil((bucket.resetAt - now) / 1000)), + bonus: Math.max(0, limit - DEFAULT_API_RATE_LIMIT), + }; +} + +export async function getApiRateLimitStatus(userId: string) { + const limit = await getEffectiveApiRateLimit(userId); + const client = getRedis(); + if (!client) return memoryStatus(userId, limit); + + try { + if (client.status !== "ready") { + await client.connect().catch(() => {}); + } + const key = rateKey(userId); + const [countRaw, ttl] = await Promise.all([client.get(key), client.ttl(key)]); + const used = Math.min(Number(countRaw || 0), limit); + return { + limit, + used, + remaining: Math.max(0, limit - used), + windowSeconds: API_RATE_WINDOW_SECONDS, + resetsInSeconds: ttl > 0 ? ttl : API_RATE_WINDOW_SECONDS, + bonus: Math.max(0, limit - DEFAULT_API_RATE_LIMIT), + }; + } catch { + return { ...memoryStatus(userId, limit), bonus: Math.max(0, limit - DEFAULT_API_RATE_LIMIT) }; + } +} + +function checkMemoryRateLimit(userId: string, limit: number) { + const now = Date.now(); + const bucket = memoryBuckets.get(userId); + + if (!bucket || now >= bucket.resetAt) { + memoryBuckets.set(userId, { + count: 1, + resetAt: now + API_RATE_WINDOW_SECONDS * 1000, + }); + return { ok: true as const, limit, remaining: limit - 1 }; + } + + if (bucket.count >= limit) { + return { + ok: false as const, + retryAfterSeconds: Math.max(1, Math.ceil((bucket.resetAt - now) / 1000)), + limit, + remaining: 0, + }; + } + + bucket.count += 1; + return { ok: true as const, limit, remaining: Math.max(0, limit - bucket.count) }; +} + +export async function checkApiRateLimit(userId: string) { + if (isSelfHostedEdition()) { + return { ok: true as const, limit: SELFHOSTED_API_RATE_LIMIT, remaining: SELFHOSTED_API_RATE_LIMIT }; + } + const limit = await getEffectiveApiRateLimit(userId); + const client = getRedis(); + if (!client) return checkMemoryRateLimit(userId, limit); + + try { + if (client.status !== "ready") { + await client.connect().catch(() => {}); + } + + const key = rateKey(userId); + const count = await client.incr(key); + if (count === 1) { + await client.expire(key, API_RATE_WINDOW_SECONDS); + } + + if (count > limit) { + const ttl = await client.ttl(key); + return { + ok: false as const, + retryAfterSeconds: Math.max(1, ttl > 0 ? ttl : API_RATE_WINDOW_SECONDS), + limit, + remaining: 0, + }; + } + + return { ok: true as const, limit, remaining: Math.max(0, limit - count) }; + } catch { + return checkMemoryRateLimit(userId, limit); + } +} diff --git a/lib/audio-tags.ts b/lib/audio-tags.ts new file mode 100644 index 0000000..fb0303a --- /dev/null +++ b/lib/audio-tags.ts @@ -0,0 +1,51 @@ +import { parseFile } from "music-metadata"; +import type { ItemMetadata } from "./types"; + +export type AudioTagMetadata = { + title?: string; + artist?: string; + album?: string; + genre?: string; + year?: string; +}; + +export async function readAudioTags(filePath: string): Promise { + try { + const { common } = await parseFile(filePath); + if (!common.title && !common.artist && !common.album && !common.genre?.length) { + return null; + } + + return { + title: common.title, + artist: common.artist, + album: common.album, + genre: common.genre?.join(", "), + year: common.year?.toString(), + }; + } catch { + return null; + } +} + +export function audioTagsToMetadata( + tags: AudioTagMetadata, + fallbackTitle: string, +): Pick { + const songTitle = tags.title || fallbackTitle; + const videoTitle = + tags.artist && tags.title + ? `${tags.artist} - ${tags.title}` + : tags.title || fallbackTitle; + + const description = [tags.artist, tags.album, tags.year].filter(Boolean).join(" · "); + const tagParts = [tags.genre, tags.artist].filter(Boolean); + + return { + title: videoTitle, + songTitle, + description, + tags: tagParts.join(", "), + artist: tags.artist || null, + }; +} diff --git a/lib/auth.ts b/lib/auth.ts index 7e9c9a9..2331956 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -36,6 +36,7 @@ export const authOptions: NextAuthOptions = { email: user.email, name: user.name, image: user.image, + monthlyCredits: 10, quotaResetAt: getInitialQuotaResetAt(), }, update: { diff --git a/lib/billing.ts b/lib/billing.ts new file mode 100644 index 0000000..c7fe2f7 --- /dev/null +++ b/lib/billing.ts @@ -0,0 +1,304 @@ +import { Plan } from "@prisma/client"; +import { + EXTRA_CREDITS_MAX, + FREE_TOP_UP_CREDITS, + MAX_CREDIT_CAP, + monthlyCreditsForPlan, +} from "./credits"; +import { prisma } from "./db"; +import { getNextMonthlyQuotaReset } from "./plans"; + +export class CreditInsufficientError extends Error { + readonly status = 402; + constructor(message = "Payment Required: no credits remaining.") { + super(message); + this.name = "CreditInsufficientError"; + } +} + +export type DeductResult = { + fromMonthly: number; + fromExtra: number; +}; + +export type RenewalBalances = { + monthlyCredits: number; + videosUsed: number; + extraCredits: number; + bonusQuota: number; + trimmed: number; + totalAfter: number; +}; + +/** + * Rollover + hard cap on renewal. + * prospective = unused (monthly remaining + extras) + newMonthly + * If prospective > MAX_CREDIT_CAP (30), trim excess (no refund). + * + * Storage: prefer filling the new monthly allocation first, leftover as extras. + */ +export function computeRenewalBalances(input: { + monthlyCredits: number; + videosUsed: number; + bonusQuota?: number; + extraCredits: number; + newMonthlyCredits: number; + maxCap?: number; +}): RenewalBalances { + const cap = input.maxCap ?? MAX_CREDIT_CAP; + const bonus = input.bonusQuota ?? 0; + const unusedMonthly = Math.max(0, input.monthlyCredits + bonus - input.videosUsed); + const currentUnused = unusedMonthly + Math.max(0, input.extraCredits); + const prospective = currentUnused + input.newMonthlyCredits; + const totalAfter = Math.min(prospective, cap); + const trimmed = Math.max(0, prospective - totalAfter); + + const monthlyCredits = Math.min(input.newMonthlyCredits, totalAfter); + const extraCredits = Math.max(0, totalAfter - monthlyCredits); + + return { + monthlyCredits, + videosUsed: 0, + extraCredits, + bonusQuota: 0, + trimmed, + totalAfter, + }; +} + +/** + * Apply monthly credit renewal with MAX_CREDIT_CAP rollover trim. + */ +export async function applyMonthlyCreditRenewal( + userId: string, + opts: { + plan?: Plan; + newMonthlyCredits?: number; + quotaResetAt?: Date; + } = {}, +) { + return prisma.$transaction(async (tx) => { + const user = await tx.user.findUniqueOrThrow({ where: { id: userId } }); + const plan = opts.plan ?? user.plan; + const newMonthly = opts.newMonthlyCredits ?? monthlyCreditsForPlan(plan); + const balances = computeRenewalBalances({ + monthlyCredits: user.monthlyCredits, + videosUsed: user.videosUsed, + bonusQuota: user.bonusQuota, + extraCredits: user.extraCredits, + newMonthlyCredits: newMonthly, + }); + + return tx.user.update({ + where: { id: userId }, + data: { + plan, + monthlyCredits: balances.monthlyCredits, + videosUsed: balances.videosUsed, + extraCredits: balances.extraCredits, + bonusQuota: balances.bonusQuota, + quotaResetAt: opts.quotaResetAt ?? getNextMonthlyQuotaReset(), + }, + }); + }); +} + +/** + * Deduct video creation credits for `count` items. + * Order: monthly allocation first, then extraCredits. + */ +export async function deductUserCredit( + userId: string, + count = 1, +): Promise { + if (count <= 0) return { fromMonthly: 0, fromExtra: 0 }; + + return prisma.$transaction(async (tx) => { + const rows = await tx.$queryRaw< + Array<{ + id: string; + plan: Plan; + videosUsed: number; + monthlyCredits: number; + bonusQuota: number; + videoCredits: number; + }> + >`SELECT id, plan, "videosUsed", "monthlyCredits", "bonusQuota", "videoCredits" + FROM "User" WHERE id = ${userId} FOR UPDATE`; + + const user = rows[0]; + if (!user) throw new Error("User not found"); + + const monthlyLimit = user.monthlyCredits + user.bonusQuota; + const monthlyRemaining = Math.max(0, monthlyLimit - user.videosUsed); + const extra = user.videoCredits; + const total = monthlyRemaining + extra; + + if (total < count) { + throw new CreditInsufficientError( + `Not enough credits. Available: ${total} (monthly remaining ${monthlyRemaining} + extras ${extra}).`, + ); + } + + const fromMonthly = Math.min(count, monthlyRemaining); + const fromExtra = count - fromMonthly; + + await tx.user.update({ + where: { id: userId }, + data: { + ...(fromMonthly > 0 ? { videosUsed: { increment: fromMonthly } } : {}), + ...(fromExtra > 0 ? { extraCredits: { decrement: fromExtra } } : {}), + }, + }); + + return { fromMonthly, fromExtra }; + }); +} + +/** Refund reserved credits (job create failure / worker failure). */ +export async function refundUserCredit( + userId: string, + fromMonthly: number, + fromExtra: number, +) { + if (fromMonthly > 0) { + await prisma.$executeRaw` + UPDATE "User" + SET "videosUsed" = GREATEST(0, "videosUsed" - ${fromMonthly}) + WHERE id = ${userId} + `; + } + if (fromExtra > 0) { + await prisma.$executeRaw` + UPDATE "User" + SET "videoCredits" = LEAST(${EXTRA_CREDITS_MAX}, "videoCredits" + ${fromExtra}) + WHERE id = ${userId} + `; + } +} + +/** + * Admin / support: reset or adjust a user's billing cycle and extras. + */ +export async function adminResetUserCredits( + userId: string, + options: { + plan?: Plan; + monthlyCredits?: number; + creditsUsed?: number; + extraCredits?: number; + clearFreeTopUp?: boolean; + } = {}, +) { + const user = await prisma.user.findUniqueOrThrow({ where: { id: userId } }); + const plan = options.plan ?? user.plan; + const monthlyCredits = + options.monthlyCredits ?? monthlyCreditsForPlan(plan); + + const extras = + options.extraCredits !== undefined + ? Math.max(0, Math.min(EXTRA_CREDITS_MAX, options.extraCredits)) + : user.extraCredits; + const used = options.creditsUsed ?? 0; + const remainingMonthly = Math.max(0, monthlyCredits - used); + const total = remainingMonthly + extras; + const cappedExtras = + total > MAX_CREDIT_CAP + ? Math.max(0, MAX_CREDIT_CAP - remainingMonthly) + : extras; + + return prisma.user.update({ + where: { id: userId }, + data: { + plan, + monthlyCredits, + videosUsed: used, + extraCredits: cappedExtras, + ...(options.clearFreeTopUp ? { freeTopUpPurchased: false } : {}), + quotaResetAt: getNextMonthlyQuotaReset(), + ...(plan === "FREE" + ? { + stripeSubscriptionId: null, + subscribedAt: null, + cardLast4: null, + bonusQuota: 0, + } + : {}), + }, + }); +} + +export async function activateProPlan( + userId: string, + opts: { + stripeCustomerId?: string | null; + stripeSubscriptionId?: string | null; + cardLast4?: string | null; + } = {}, +) { + await applyMonthlyCreditRenewal(userId, { + plan: "PREMIUM", + newMonthlyCredits: monthlyCreditsForPlan("PREMIUM"), + }); + + return prisma.user.update({ + where: { id: userId }, + data: { + plan: "PREMIUM", + subscribedAt: new Date(), + ...(opts.stripeCustomerId !== undefined + ? { stripeCustomerId: opts.stripeCustomerId } + : {}), + ...(opts.stripeSubscriptionId !== undefined + ? { stripeSubscriptionId: opts.stripeSubscriptionId } + : {}), + ...(opts.cardLast4 !== undefined ? { cardLast4: opts.cardLast4 } : {}), + }, + }); +} + +export async function downgradeToFreePlan(userId: string) { + await applyMonthlyCreditRenewal(userId, { + plan: "FREE", + newMonthlyCredits: monthlyCreditsForPlan("FREE"), + }); + + return prisma.user.update({ + where: { id: userId }, + data: { + plan: "FREE", + stripeSubscriptionId: null, + subscribedAt: null, + cardLast4: null, + apiKeyHash: null, + apiKeyPrefix: null, + apiRateLimitBonus: 0, + }, + }); +} + +export async function grantExtraCredits(userId: string, credits: number) { + if (credits <= 0) return; + await prisma.$transaction(async (tx) => { + const user = await tx.user.findUniqueOrThrow({ where: { id: userId } }); + const monthlyRemaining = Math.max( + 0, + user.monthlyCredits + user.bonusQuota - user.videosUsed, + ); + const room = Math.max(0, MAX_CREDIT_CAP - monthlyRemaining - user.extraCredits); + const grant = Math.min(credits, room); + if (grant <= 0) return; + await tx.user.update({ + where: { id: userId }, + data: { extraCredits: { increment: grant } }, + }); + }); +} + +export async function markFreeTopUpPurchased(userId: string) { + await prisma.user.update({ + where: { id: userId }, + data: { freeTopUpPurchased: true }, + }); + await grantExtraCredits(userId, FREE_TOP_UP_CREDITS); +} diff --git a/lib/branding.ts b/lib/branding.ts new file mode 100644 index 0000000..15a63db --- /dev/null +++ b/lib/branding.ts @@ -0,0 +1,7 @@ +export const BRAND_NAME = "Songs2VID"; +export const BRAND_DOMAIN = "songs2vid.com"; +export const VIDEO_ATTRIBUTION_PREFIX = "Uploaded through"; + +export function getVideoAttributionText() { + return `${VIDEO_ATTRIBUTION_PREFIX} ${BRAND_NAME}.com`; +} diff --git a/lib/constants.ts b/lib/constants.ts index 2a7a8e3..734cfd2 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -1,10 +1,12 @@ export const FREE_PLAN = { - monthlyQuota: 14, + monthlyQuota: 10, maxFileSizeBytes: 30 * 1024 * 1024, - watermarkRequired: true, + maxBatchSize: 3, + watermarkOptional: true, } as const; export const RESOLUTIONS = [ + { value: "1920x1080", label: "1920x1080 (16:9)", width: 1920, height: 1080 }, { value: "1280x720", label: "1280x720 (16:9)", width: 1280, height: 720 }, { value: "854x480", label: "854x480 (16:9)", width: 854, height: 480 }, { value: "720x720", label: "720x720 (1:1)", width: 720, height: 720 }, diff --git a/lib/credits.ts b/lib/credits.ts new file mode 100644 index 0000000..8fa9415 --- /dev/null +++ b/lib/credits.ts @@ -0,0 +1,113 @@ +/** + * Billing / credit constants for Songs2VID hybrid pricing. + * Plan enum in DB: FREE | PREMIUM (Pro = €5/mo "starter_5eur"). + */ + +export const CREDIT_CURRENCY = "eur"; + +/** Free monthly allocation */ +export const FREE_MONTHLY_CREDITS = 10; + +/** Pro monthly allocation */ +export const PRO_MONTHLY_CREDITS = 50; + +/** Free-tier top-up: buyer picks 1–15 credits */ +export const FREE_TOP_UP_MIN = 1; +export const FREE_TOP_UP_MAX = 15; + +/** €0.25 per extra credit */ +export const CREDIT_PRICE_CENTS = 25; + +/** @deprecated use FREE_TOP_UP_MAX */ +export const FREE_TOP_UP_CREDITS = FREE_TOP_UP_MAX; + +/** @deprecated use creditPurchaseTotalCents(FREE_TOP_UP_MAX) */ +export const FREE_TOP_UP_PRICE_CENTS = FREE_TOP_UP_MAX * CREDIT_PRICE_CENTS; + +/** Pro subscription €5 / month */ +export const PRO_PRICE_CENTS = 500; + +/** Soft cap on never-expiring extra credits (Pro / legacy storage bound) */ +export const EXTRA_CREDITS_MAX = 1000; + +/** + * Hard cap on total accumulated credits (monthly remaining + extras). + * On renewal, unused + new monthly is trimmed to this threshold. + */ +export const MAX_CREDIT_CAP = 30; + +/** + * Free plan: extras balance cannot exceed 15. + * After monthly (10) + extras (≤15) are used, upgrade to Pro is required. + */ +export const FREE_EXTRA_CREDITS_MAX = FREE_TOP_UP_MAX; + +/** Stripe Tax / Managed Payments SaaS personal use */ +export const STRIPE_PRODUCT_TAX_CODE = "txcd_10103000"; + +export const CREDIT_PURCHASE_MIN = FREE_TOP_UP_MIN; +export const CREDIT_PURCHASE_MAX = FREE_TOP_UP_MAX; +export const CREDIT_BALANCE_MAX = EXTRA_CREDITS_MAX; + +/** Shown in quota UI errors so UpgradeProLink can attach a CTA */ +export const PRO_UPGRADE_REQUIRED_SUFFIX = " Upload up to 50 videos with Pro!"; + +export function monthlyCreditsForPlan(plan: "FREE" | "PREMIUM"): number { + return plan === "PREMIUM" ? PRO_MONTHLY_CREDITS : FREE_MONTHLY_CREDITS; +} + +export function freeExtraCreditsCap(): number { + return FREE_EXTRA_CREDITS_MAX; +} + +export function formatEuroFromCents(cents: number): string { + const amount = cents / 100; + const formatted = amount % 1 === 0 ? String(amount) : amount.toFixed(2); + return `€${formatted}`; +} + +export function creditPurchaseTotalCents(credits: number): number { + return credits * CREDIT_PRICE_CENTS; +} + +export function formatCreditPrice(credits = 1): string { + return formatEuroFromCents(creditPurchaseTotalCents(credits)); +} + +export function validateFreeTopUpAmount( + credits: number, + currentExtraBalance: number, + monthlyRemaining = 0, +): { ok: true; credits: number; amountCents: number } | { ok: false; error: string } { + if (!Number.isInteger(credits)) { + return { ok: false, error: "Credit amount must be a whole number." }; + } + if (credits < FREE_TOP_UP_MIN || credits > FREE_TOP_UP_MAX) { + return { + ok: false, + error: `You can buy between ${FREE_TOP_UP_MIN} and ${FREE_TOP_UP_MAX} credits per top-up.`, + }; + } + if (currentExtraBalance >= FREE_EXTRA_CREDITS_MAX) { + return { + ok: false, + error: `Free plan extras are capped at ${FREE_EXTRA_CREDITS_MAX}. Upgrade to Pro for 50 videos every month.${PRO_UPGRADE_REQUIRED_SUFFIX}`, + }; + } + const freeExtraRoom = FREE_EXTRA_CREDITS_MAX - currentExtraBalance; + const totalRoom = Math.max(0, MAX_CREDIT_CAP - monthlyRemaining - currentExtraBalance); + const room = Math.min(freeExtraRoom, totalRoom); + if (room <= 0) { + return { + ok: false, + error: `Your total credit balance cannot exceed ${MAX_CREDIT_CAP}. Upgrade to Pro or use existing credits first.${PRO_UPGRADE_REQUIRED_SUFFIX}`, + }; + } + if (credits > room) { + return { + ok: false, + error: `You can buy up to ${room} more credits under the ${MAX_CREDIT_CAP}-credit account cap.`, + }; + } + return { ok: true, credits, amountCents: creditPurchaseTotalCents(credits) }; +} diff --git a/lib/crypto/secrets.ts b/lib/crypto/secrets.ts new file mode 100644 index 0000000..7ed5c94 --- /dev/null +++ b/lib/crypto/secrets.ts @@ -0,0 +1,55 @@ +import { createCipheriv, createDecipheriv, createHash, randomBytes } from "crypto"; + +const ENC_PREFIX = "enc:v1:"; + +function getEncryptionKey() { + const secret = process.env.TOKEN_ENCRYPTION_KEY || process.env.NEXTAUTH_SECRET; + if (!secret) { + throw new Error("TOKEN_ENCRYPTION_KEY or NEXTAUTH_SECRET must be set to encrypt secrets"); + } + return createHash("sha256").update(secret).digest(); +} + +/** Encrypt a secret for DB storage (AES-256-GCM). Idempotent if already encrypted. */ +export function encryptSecret(plaintext: string): string { + if (!plaintext) return plaintext; + if (plaintext.startsWith(ENC_PREFIX)) return plaintext; + + const iv = randomBytes(12); + const cipher = createCipheriv("aes-256-gcm", getEncryptionKey(), iv); + const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]); + const tag = cipher.getAuthTag(); + + return [ + ENC_PREFIX, + iv.toString("base64url"), + ".", + tag.toString("base64url"), + ".", + encrypted.toString("base64url"), + ].join(""); +} + +/** Decrypt a stored secret. Legacy plaintext values are returned as-is. */ +export function decryptSecret(value: string): string { + if (!value) return value; + if (!value.startsWith(ENC_PREFIX)) return value; + + const payload = value.slice(ENC_PREFIX.length); + const [ivB64, tagB64, dataB64] = payload.split("."); + if (!ivB64 || !tagB64 || !dataB64) { + throw new Error("Invalid encrypted secret format"); + } + + const decipher = createDecipheriv( + "aes-256-gcm", + getEncryptionKey(), + Buffer.from(ivB64, "base64url"), + ); + decipher.setAuthTag(Buffer.from(tagB64, "base64url")); + const decrypted = Buffer.concat([ + decipher.update(Buffer.from(dataB64, "base64url")), + decipher.final(), + ]); + return decrypted.toString("utf8"); +} diff --git a/lib/edition.ts b/lib/edition.ts new file mode 100644 index 0000000..bc1c808 --- /dev/null +++ b/lib/edition.ts @@ -0,0 +1,9 @@ +import { Plan } from "@prisma/client"; + +export function isSelfHostedEdition(): boolean { + return process.env.S2VID_EDITION === "selfhosted"; +} + +export function hasProFeatures(plan: Plan): boolean { + return isSelfHostedEdition() || plan === "PREMIUM"; +} diff --git a/lib/entitlements.ts b/lib/entitlements.ts new file mode 100644 index 0000000..23085b4 --- /dev/null +++ b/lib/entitlements.ts @@ -0,0 +1,62 @@ +import { Plan } from "@prisma/client"; +import { getPlanLimits } from "./plans"; +import { hasProFeatures } from "./edition"; +import { + requiresArtTrackLayoutEntitlement, + type LayoutSettings, +} from "./layout"; +import { + PREMIUM_REQUIRED_CODE, + requiresCustomWatermarkEntitlement, + type WatermarkSettings, +} from "./watermark"; + +export class PremiumRequiredError extends Error { + readonly code = PREMIUM_REQUIRED_CODE; + readonly status = 403; + constructor(message: string) { + super(message); + this.name = "PremiumRequiredError"; + } +} + +export function assertCustomWatermarkAllowed(plan: Plan, settings: WatermarkSettings) { + if (!requiresCustomWatermarkEntitlement(settings)) return; + if (getPlanLimits(plan).customWatermark || hasProFeatures(plan)) return; + throw new PremiumRequiredError( + "Custom watermark, typography, logo overlay, and position controls require Pro.", + ); +} + +export function assertArtTrackLayoutAllowed(plan: Plan, settings: LayoutSettings) { + if (!requiresArtTrackLayoutEntitlement(settings)) return; + if (getPlanLimits(plan).artTrackLayouts || hasProFeatures(plan)) return; + throw new PremiumRequiredError( + "Blurred backgrounds and art-track layout templates require Pro.", + ); +} + +export function assertPerItemImagesAllowed( + plan: Plan, + sharedImagePath: string, + itemImagePaths: Array, +) { + const unique = new Set( + itemImagePaths + .map((p) => (p && p.trim() ? p.trim() : sharedImagePath)) + .filter(Boolean), + ); + // More than one distinct cover in the batch → Pro + if (unique.size <= 1) return; + if (getPlanLimits(plan).perItemImages || hasProFeatures(plan)) return; + throw new PremiumRequiredError( + "Matching a unique image to each audio file requires Pro. Free plan uses one shared cover image.", + ); +} + +export function premiumRequiredResponse(message: string) { + return { + error: message, + code: PREMIUM_REQUIRED_CODE, + }; +} \ No newline at end of file diff --git a/lib/ffmpeg/encode.ts b/lib/ffmpeg/encode.ts index 26bbaf5..cfc868b 100644 --- a/lib/ffmpeg/encode.ts +++ b/lib/ffmpeg/encode.ts @@ -1,8 +1,98 @@ import { spawn } from "child_process"; import fs from "fs/promises"; import path from "path"; +import ffmpegStatic from "ffmpeg-static"; +import { getVideoAttributionText } from "../branding"; import { getResolution } from "../constants"; +import { + isCuratedFontKey, + sanitizeFontfileForFilter, +} from "../fonts"; +import { resolveCuratedFontPath } from "../fonts-server"; +import { + buildArtTrackFilterComplex, + type LayoutSettings, +} from "../layout"; import { getWatermarkPath } from "../storage"; +import { + buildDrawtextFilter, + normalizeWatermarkSettings, + overlayXy, + sanitizeDrawtext, + type WatermarkSettings, +} from "../watermark"; + +function getFfmpegPath(): string { + if (process.env.FFMPEG_PATH) return process.env.FFMPEG_PATH; + if (ffmpegStatic) return ffmpegStatic; + return "ffmpeg"; +} + +export { getFfmpegPath }; + +async function fileExists(p: string): Promise { + try { + await fs.access(p); + return true; + } catch { + return false; + } +} + +/** Verify PNG magic bytes (prevents MIME spoof → FFmpeg surprises). */ +export async function assertPngFile(filePath: string): Promise { + const fh = await fs.open(filePath, "r"); + try { + const buf = Buffer.alloc(8); + await fh.read(buf, 0, 8, 0); + const sig = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]); + if (!buf.equals(sig)) { + throw new Error("Logo must be a valid PNG file"); + } + } finally { + await fh.close(); + } +} + +async function resolveFontfileEscaped( + settings: WatermarkSettings, +): Promise { + const key = settings.fontKey ?? "system"; + if (key === "system") return null; + + if (key === "custom") { + if (!settings.fontPath) return null; + if (!(await fileExists(settings.fontPath))) { + throw new Error("Custom watermark font file not found"); + } + return sanitizeFontfileForFilter(path.resolve(settings.fontPath)); + } + + if (isCuratedFontKey(key)) { + const fontPath = resolveCuratedFontPath(key); + if (!(await fileExists(fontPath))) { + console.warn(`[ffmpeg] curated font missing: ${key} at ${fontPath}; using system font`); + return null; + } + return sanitizeFontfileForFilter(fontPath); + } + + return null; +} + +function classicScaleFilter(width: number, height: number): string { + return `scale=${width}:${height}:force_original_aspect_ratio=decrease,pad=${width}:${height}:(ow-iw)/2:(oh-ih)/2:black`; +} + +/** + * Art-track filter that ends at `outLabel` instead of hardcoded [laid]. + */ +function artTrackFilterEndingAt( + opts: Parameters[0], + outLabel: string, +): string { + return buildArtTrackFilterComplex(opts).replace(/\[laid\]$/, `[${outLabel}]`); +} export async function encodeVideo(options: { imagePath: string; @@ -10,62 +100,148 @@ export async function encodeVideo(options: { outputPath: string; resolution: string; includeWatermark: boolean; + watermark?: Partial | null; + layout?: LayoutSettings | null; + /** On-video song title (art-track layouts). */ + songTitle?: string; + artist?: string | null; }): Promise { const res = getResolution(options.resolution); if (!res) throw new Error(`Invalid resolution: ${options.resolution}`); await fs.mkdir(path.dirname(options.outputPath), { recursive: true }); - const scaleFilter = `scale=${res.width}:${res.height}:force_original_aspect_ratio=decrease,pad=${res.width}:${res.height}:(ow-iw)/2:(oh-ih)/2:black`; + const settings = normalizeWatermarkSettings(options.watermark, options.includeWatermark); + const layout = options.layout?.template ? options.layout : null; + const watermarkWidth = Math.max(1, Math.round(res.width * 0.32)); + const fontSize = Math.max(16, Math.round(res.width * 0.018)); + const fontfile = await resolveFontfileEscaped(settings); - const watermarkPath = getWatermarkPath(); - let watermarkExists = false; - try { - await fs.access(watermarkPath); - watermarkExists = true; - } catch { - watermarkExists = false; + const args = ["-y", "-loop", "1", "-r", "1", "-i", options.imagePath, "-i", options.audioPath]; + + let nextInput = 2; + let logoInputIndex: number | null = null; + let defaultWmInputIndex: number | null = null; + + const needsLogo = settings.mode === "logo" && Boolean(settings.logoPath); + const defaultPath = getWatermarkPath(); + const useDefaultPng = + settings.mode === "default" && (await fileExists(defaultPath)); + + if (needsLogo && settings.logoPath) { + if (!(await fileExists(settings.logoPath))) { + throw new Error("Watermark logo file not found"); + } + await assertPngFile(settings.logoPath); + args.push("-i", settings.logoPath); + logoInputIndex = nextInput++; + } else if (useDefaultPng) { + args.push("-i", defaultPath); + defaultWmInputIndex = nextInput++; } - const useWatermark = options.includeWatermark && watermarkExists; + const applyWm = + settings.mode === "logo" && logoInputIndex !== null + ? ("logo" as const) + : settings.mode === "text" && settings.text?.trim() + ? ("text" as const) + : settings.mode === "default" && defaultWmInputIndex !== null + ? ("default-png" as const) + : settings.mode === "default" + ? ("default-text" as const) + : ("none" as const); - const args = ["-y", "-loop", "1", "-i", options.imagePath, "-i", options.audioPath]; - - if (useWatermark) { - args.push("-i", watermarkPath); + // Fast path: classic letterbox, no watermark + if (!layout && applyWm === "none") { + args.push("-vf", classicScaleFilter(res.width, res.height)); args.push( - "-filter_complex", - `[0:v]${scaleFilter}[scaled];[2:v]scale=iw*0.15:-1[wm];[scaled][wm]overlay=W-w-20:H-h-20[vout]`, - "-map", - "[vout]", - "-map", - "1:a", + "-c:v", + "libx264", + "-tune", + "stillimage", + "-c:a", + "copy", + "-shortest", + "-pix_fmt", + "yuv420p", + options.outputPath, ); - } else if (options.includeWatermark && !watermarkExists) { - args.push( - "-filter_complex", - `[0:v]${scaleFilter},drawtext=text='s2yt':fontsize=24:fontcolor=white@0.7:x=w-tw-20:y=h-th-20[vout]`, - "-map", - "[vout]", - "-map", - "1:a", + await runFfmpeg(args); + return; + } + + const outDirect = applyWm === "none"; + const baseLabel = outDirect ? "vout" : "base"; + const filterParts: string[] = []; + + if (layout) { + const titleEscaped = sanitizeDrawtext(options.songTitle?.trim() || "Untitled"); + const artistRaw = options.artist?.trim(); + const artistEscaped = artistRaw ? sanitizeDrawtext(artistRaw) : null; + filterParts.push( + artTrackFilterEndingAt( + { + width: res.width, + height: res.height, + layout, + titleEscaped, + artistEscaped, + fontfileEscaped: fontfile, + }, + baseLabel, + ), ); } else { - args.push("-vf", scaleFilter); + filterParts.push(`[0:v]${classicScaleFilter(res.width, res.height)}[${baseLabel}]`); } + if (applyWm === "logo" && logoInputIndex !== null) { + const { x, y } = overlayXy(settings.position, settings.offsetX, settings.offsetY); + filterParts.push( + `[${logoInputIndex}:v]scale=${watermarkWidth}:-1[wm]`, + `[${baseLabel}][wm]overlay=${x}:${y}[vout]`, + ); + } else if (applyWm === "text") { + const draw = buildDrawtextFilter({ + text: settings.text!.trim(), + fontSize, + fontColor: "white@0.9", + position: settings.position, + offsetX: settings.offsetX, + offsetY: settings.offsetY, + fontfileEscaped: fontfile, + }); + filterParts.push(`[${baseLabel}]${draw}[vout]`); + } else if (applyWm === "default-png" && defaultWmInputIndex !== null) { + const { x, y } = overlayXy(settings.position, settings.offsetX, settings.offsetY); + filterParts.push( + `[${defaultWmInputIndex}:v]scale=${watermarkWidth}:-1[wm]`, + `[${baseLabel}][wm]overlay=${x}:${y}[vout]`, + ); + } else if (applyWm === "default-text") { + const draw = buildDrawtextFilter({ + text: getVideoAttributionText(), + fontSize, + fontColor: "white@0.85", + position: settings.position, + offsetX: settings.offsetX, + offsetY: settings.offsetY, + fontfileEscaped: null, + }); + filterParts.push(`[${baseLabel}]${draw}[vout]`); + } + + args.push("-filter_complex", filterParts.join(";"), "-map", "[vout]", "-map", "1:a"); args.push( "-c:v", "libx264", "-tune", "stillimage", "-c:a", - "aac", - "-b:a", - "192k", + "copy", + "-shortest", "-pix_fmt", "yuv420p", - "-shortest", options.outputPath, ); @@ -74,10 +250,11 @@ export async function encodeVideo(options: { function runFfmpeg(args: string[]): Promise { return new Promise((resolve, reject) => { - const proc = spawn("ffmpeg", args, { stdio: ["ignore", "pipe", "pipe"] }); + const proc = spawn(getFfmpegPath(), args, { stdio: ["ignore", "pipe", "pipe"] }); let stderr = ""; proc.stderr.on("data", (chunk) => { stderr += chunk.toString(); + if (stderr.length > 64_000) stderr = stderr.slice(-32_000); }); proc.on("close", (code) => { if (code === 0) resolve(); diff --git a/lib/fonts-server.ts b/lib/fonts-server.ts new file mode 100644 index 0000000..fc6b9d5 --- /dev/null +++ b/lib/fonts-server.ts @@ -0,0 +1,44 @@ +/** Server-only font filesystem helpers. Do not import from client components. */ + +import fs from "fs/promises"; +import path from "path"; +import { CURATED_FONTS, type CuratedFontKey } from "./fonts"; + +export function getFontsDir(): string { + return path.join(process.cwd(), "assets", "fonts"); +} + +/** Resolve a curated font file on disk (must exist under assets/fonts). */ +export function resolveCuratedFontPath(key: CuratedFontKey): string { + const meta = CURATED_FONTS.find((f) => f.key === key); + if (!meta) throw new Error("Unknown font"); + // Whitelist filename only never accept user-controlled path segments + const safe = meta.file.replace(/[^a-zA-Z0-9._-]/g, ""); + if (safe !== meta.file) throw new Error("Invalid font asset name"); + return path.join(getFontsDir(), safe); +} + +/** + * Validate TTF / OTF magic bytes. + * TTF: 00 01 00 00 | true | typ1 + * OTF: OTTO + */ +export async function assertFontFile(filePath: string): Promise<"ttf" | "otf"> { + const fh = await fs.open(filePath, "r"); + try { + const buf = Buffer.alloc(4); + await fh.read(buf, 0, 4, 0); + const asStr = buf.toString("ascii"); + if (asStr === "OTTO") return "otf"; + if (asStr === "true" || asStr === "typ1") return "ttf"; + if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00) { + return "ttf"; + } + if (asStr === "wOFF" || asStr === "wOF2") { + throw new Error("WOFF fonts are not supported. Upload a .ttf or .otf file."); + } + throw new Error("File is not a valid TTF or OTF font"); + } finally { + await fh.close(); + } +} diff --git a/lib/fonts.ts b/lib/fonts.ts new file mode 100644 index 0000000..3e7d3eb --- /dev/null +++ b/lib/fonts.ts @@ -0,0 +1,75 @@ +/** Shared font catalog safe for client and server bundles (no Node APIs). */ + +/** Max custom font upload size (10 MB). */ +export const FONT_UPLOAD_MAX_BYTES = 10 * 1024 * 1024; + +export const CURATED_FONTS = [ + { + key: "inter", + label: "Inter", + cssFamily: "Inter", + googleCss: "Inter:wght@400;600", + file: "Inter-Regular.ttf", + }, + { + key: "montserrat", + label: "Montserrat", + cssFamily: "Montserrat", + googleCss: "Montserrat:wght@400;600", + file: "Montserrat-Regular.ttf", + }, + { + key: "roboto", + label: "Roboto", + cssFamily: "Roboto", + googleCss: "Roboto:wght@400;500", + file: "Roboto-Regular.ttf", + }, + { + key: "oswald", + label: "Oswald", + cssFamily: "Oswald", + googleCss: "Oswald:wght@400;500", + file: "Oswald-Regular.ttf", + }, + { + key: "playfair", + label: "Playfair Display", + cssFamily: "Playfair Display", + googleCss: "Playfair+Display:wght@400;600", + file: "PlayfairDisplay-Regular.ttf", + }, +] as const; + +export type CuratedFontKey = (typeof CURATED_FONTS)[number]["key"]; +export type WatermarkFontKey = CuratedFontKey | "custom" | "system"; + +const CURATED_KEYS = new Set(CURATED_FONTS.map((f) => f.key)); + +export function isCuratedFontKey(v: unknown): v is CuratedFontKey { + return typeof v === "string" && CURATED_KEYS.has(v); +} + +export function isWatermarkFontKey(v: unknown): v is WatermarkFontKey { + return v === "custom" || v === "system" || isCuratedFontKey(v); +} + +/** + * Escape an absolute font path for use inside an FFmpeg filtergraph `fontfile=` value. + * Paths are never passed through a shell; this only escapes filter special chars. + */ +export function sanitizeFontfileForFilter(absPath: string): string { + return absPath + .replace(/\\/g, "/") + .replace(/:/g, "\\:") + .replace(/'/g, "\\'") + .replace(/\[/g, "\\[") + .replace(/\]/g, "\\]"); +} + +export function googleFontsStylesheetUrl(keys: CuratedFontKey[]): string { + const families = CURATED_FONTS.filter((f) => keys.includes(f.key)) + .map((f) => `family=${f.googleCss}`) + .join("&"); + return `https://fonts.googleapis.com/css2?${families}&display=swap`; +} diff --git a/lib/fs-utils.ts b/lib/fs-utils.ts new file mode 100644 index 0000000..f86bd36 --- /dev/null +++ b/lib/fs-utils.ts @@ -0,0 +1,45 @@ +import { createWriteStream } from "fs"; +import fs from "fs/promises"; +import { Readable } from "stream"; +import { pipeline } from "stream/promises"; + +export async function writeUploadedFile(file: File, destPath: string) { + const webStream = file.stream(); + const nodeStream = Readable.fromWeb(webStream as Parameters[0]); + await pipeline(nodeStream, createWriteStream(destPath)); +} + +export async function moveFile(src: string, dest: string) { + try { + await fs.rename(src, dest); + } catch (err) { + const code = err && typeof err === "object" && "code" in err ? err.code : null; + if (code === "EXDEV") { + await fs.copyFile(src, dest); + await fs.unlink(src).catch(() => {}); + return; + } + throw err; + } +} + +export async function mapWithConcurrency( + items: T[], + concurrency: number, + fn: (item: T, index: number) => Promise, +) { + const results: R[] = new Array(items.length); + let nextIndex = 0; + + async function worker() { + while (nextIndex < items.length) { + const index = nextIndex; + nextIndex += 1; + results[index] = await fn(items[index], index); + } + } + + const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker()); + await Promise.all(workers); + return results; +} diff --git a/lib/jobs/create-job.ts b/lib/jobs/create-job.ts new file mode 100644 index 0000000..b90bbbb --- /dev/null +++ b/lib/jobs/create-job.ts @@ -0,0 +1,534 @@ +import fs from "fs/promises"; +import path from "path"; +import { Plan, Privacy } from "@prisma/client"; +import { readAudioTags } from "../audio-tags"; +import { filenameWithoutExtension, isAllowedResolution } from "../constants"; +import { prisma } from "../db"; +import { hasProFeatures } from "../edition"; +import { + assertArtTrackLayoutAllowed, + assertCustomWatermarkAllowed, + assertPerItemImagesAllowed, + PremiumRequiredError, +} from "../entitlements"; +import { FONT_UPLOAD_MAX_BYTES } from "../fonts"; +import { assertFontFile } from "../fonts-server"; +import { assertPngFile } from "../ffmpeg/encode"; +import { moveFile, writeUploadedFile } from "../fs-utils"; +import { + ARTIST_MAX, + INVALID_LAYOUT_TEMPLATE_MESSAGE, + normalizeLayoutSettings, + SONG_TITLE_MAX, + type LayoutSettings, +} from "../layout"; +import { enqueueVideoJob } from "../queue/client"; +import { + getPlanLimits, + isAudioExtensionAllowed, + isResolutionAllowedForPlan, +} from "../plans"; +import { releaseReservationSplit, reserveQuota } from "../quota"; +import { getJobDir } from "../storage"; +import { + assertPathInUserUploads, + getUserStagingDir, + sanitizeUploadSessionKey, +} from "../upload-paths"; +import type { CreateJobPayload, ItemMetadata } from "../types"; +import { resolveBurnedSongTitle, resolveYouTubeTitle, validateYouTubeTitle } from "../titles"; +import { + normalizeWatermarkSettings, + WATERMARK_TEXT_MAX, +} from "../watermark"; + +/** Merge nested + flat layout fields, then normalize (throws on bad template / coords). */ +export function resolveLayoutFromMetadata(metadata: ItemMetadata): LayoutSettings { + return normalizeLayoutSettings({ + ...(metadata.layout ?? {}), + template: + metadata.layout?.template ?? + metadata.layout?.layoutTemplate ?? + metadata.layout?.layout_template ?? + metadata.layoutTemplate ?? + metadata.layout_template, + blurAmount: + metadata.layout?.blurAmount ?? + metadata.layout?.blur_amount ?? + metadata.blurAmount ?? + metadata.blur_amount, + blurOpacity: + metadata.layout?.blurOpacity ?? + (metadata.layout as { blur_opacity?: number } | null | undefined)?.blur_opacity ?? + metadata.blurOpacity ?? + metadata.blur_opacity, + textPadding: + metadata.layout?.textPadding ?? + metadata.layout?.text_padding ?? + metadata.textPadding ?? + metadata.text_padding, + titleArtistGap: + metadata.layout?.titleArtistGap ?? + (metadata.layout as { title_artist_gap?: number } | null | undefined)?.title_artist_gap ?? + metadata.titleArtistGap ?? + metadata.title_artist_gap, + textOffsetX: + metadata.layout?.textOffsetX ?? + (metadata.layout as { text_offset_x?: number } | null | undefined)?.text_offset_x ?? + metadata.textOffsetX ?? + metadata.text_offset_x, + textOffsetY: + metadata.layout?.textOffsetY ?? + (metadata.layout as { text_offset_y?: number } | null | undefined)?.text_offset_y ?? + metadata.textOffsetY ?? + metadata.text_offset_y, + }); +} + +export function validateItemMetadata( + metadata: CreateJobPayload["items"][0]["metadata"], + plan: Plan, +) { + const titleErr = validateYouTubeTitle(metadata, plan); + if (titleErr) return titleErr; + if (!isAllowedResolution(metadata.resolution)) return "Invalid resolution"; + if (!["PUBLIC", "PRIVATE", "UNLISTED"].includes(metadata.privacy)) { + return "Invalid privacy setting"; + } + if (metadata.watermark?.text && metadata.watermark.text.length > WATERMARK_TEXT_MAX) { + return `Watermark text must be at most ${WATERMARK_TEXT_MAX} characters`; + } + if (metadata.artist && metadata.artist.length > ARTIST_MAX) { + return `Artist must be at most ${ARTIST_MAX} characters`; + } + if (metadata.songTitle && metadata.songTitle.length > SONG_TITLE_MAX) { + return `Song title must be at most ${SONG_TITLE_MAX} characters`; + } + try { + resolveLayoutFromMetadata(metadata); + } catch (err) { + if (err instanceof Error && err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE) { + return INVALID_LAYOUT_TEMPLATE_MESSAGE; + } + throw err; + } + return null; +} + +export async function validateJobPayload(user: { id: string; plan: Plan }, body: CreateJobPayload) { + if (!body.imagePath || !body.items?.length) { + return "Image and at least one audio file required"; + } + + const itemImagePaths: Array = []; + + for (const item of body.items) { + const metaError = validateItemMetadata(item.metadata, user.plan); + if (metaError) return metaError; + if (!isResolutionAllowedForPlan(item.metadata.resolution, user.plan)) { + return `Resolution ${item.metadata.resolution} is not available on your plan`; + } + if (item.metadata.playlistId && !hasProFeatures(user.plan)) { + return "Adding videos to a YouTube playlist requires the Pro plan"; + } + + const wm = normalizeWatermarkSettings( + item.metadata.watermark, + item.metadata.includeWatermark, + ); + try { + assertCustomWatermarkAllowed(user.plan, wm); + assertArtTrackLayoutAllowed(user.plan, resolveLayoutFromMetadata(item.metadata)); + } catch (err) { + if (err instanceof PremiumRequiredError) return err.message; + if (err instanceof Error && err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE) { + return INVALID_LAYOUT_TEMPLATE_MESSAGE; + } + throw err; + } + + itemImagePaths.push(item.metadata.imagePath); + } + + try { + assertPerItemImagesAllowed(user.plan, body.imagePath, itemImagePaths); + } catch (err) { + if (err instanceof PremiumRequiredError) return err.message; + throw err; + } + + const limits = getPlanLimits(user.plan); + + try { + const imagePath = assertPathInUserUploads(user.id, body.imagePath); + await fs.access(imagePath); + const imageStat = await fs.stat(imagePath); + if (imageStat.size > limits.maxFileSizeBytes) { + return "Image exceeds size limit"; + } + + for (const item of body.items) { + if (!isAudioExtensionAllowed(item.audioFilename, user.plan)) { + return `Audio file ${item.audioFilename} is not supported on your plan`; + } + const audioPath = assertPathInUserUploads(user.id, item.audioPath); + await fs.access(audioPath); + const stat = await fs.stat(audioPath); + if (stat.size > limits.maxFileSizeBytes) { + return `Audio file ${item.audioFilename} exceeds size limit`; + } + + if (item.metadata.imagePath) { + const itemImg = assertPathInUserUploads(user.id, item.metadata.imagePath); + await fs.access(itemImg); + const st = await fs.stat(itemImg); + if (st.size > limits.maxFileSizeBytes) { + return `Per-item image for ${item.audioFilename} exceeds size limit`; + } + } + + const wm = normalizeWatermarkSettings( + item.metadata.watermark, + item.metadata.includeWatermark, + ); + if (wm.mode === "logo" && wm.logoPath) { + const logoPath = assertPathInUserUploads(user.id, wm.logoPath); + await fs.access(logoPath); + await assertPngFile(logoPath); + const st = await fs.stat(logoPath); + if (st.size > limits.maxFileSizeBytes) { + return "Watermark logo exceeds size limit"; + } + } + if (wm.mode === "text" && !wm.text?.trim()) { + return "Watermark text mode requires non-empty text"; + } + if (wm.fontKey === "custom") { + if (!wm.fontPath) { + return "Custom font selected but no font file uploaded"; + } + const fontPath = assertPathInUserUploads(user.id, wm.fontPath); + await fs.access(fontPath); + await assertFontFile(fontPath); + const st = await fs.stat(fontPath); + if (st.size > FONT_UPLOAD_MAX_BYTES) { + return "Custom font exceeds 10 MB limit"; + } + } + } + } catch (err) { + if (err instanceof PremiumRequiredError) return err.message; + if (err instanceof Error && err.message === "Invalid upload path") { + return "Invalid upload path"; + } + if ( + err instanceof Error && + (err.message.includes("PNG") || + err.message.includes("font") || + err.message.includes("TTF") || + err.message.includes("OTF") || + err.message.includes("WOFF")) + ) { + return err.message; + } + return "One or more uploaded files not found"; + } + + return null; +} + +export async function createVideoJob( + user: { id: string; plan: Plan }, + body: CreateJobPayload, +) { + const validationError = await validateJobPayload(user, body); + if (validationError) { + if (validationError === INVALID_LAYOUT_TEMPLATE_MESSAGE) { + throw new Error(validationError); + } + const isPremium = + validationError.includes("requires Pro") || + validationError.includes("Pro plan"); + const err = isPremium + ? new PremiumRequiredError(validationError) + : new Error(validationError); + throw err; + } + + const imagePath = assertPathInUserUploads(user.id, body.imagePath); + const items = body.items.map((item) => ({ + ...item, + audioPath: assertPathInUserUploads(user.id, item.audioPath), + itemImagePath: item.metadata.imagePath + ? assertPathInUserUploads(user.id, item.metadata.imagePath) + : null, + watermarkLogoPath: item.metadata.watermark?.logoPath + ? assertPathInUserUploads(user.id, item.metadata.watermark.logoPath) + : null, + watermarkFontPath: + item.metadata.watermark?.fontKey === "custom" && item.metadata.watermark?.fontPath + ? assertPathInUserUploads(user.id, item.metadata.watermark.fontPath) + : null, + })); + + const reservation = await reserveQuota(user.id, items.length); + + try { + const job = await prisma.job.create({ + data: { + userId: user.id, + imagePath, + items: { + create: items.map((item, index) => { + const wm = normalizeWatermarkSettings( + item.metadata.watermark + ? { + ...item.metadata.watermark, + logoPath: item.watermarkLogoPath, + fontPath: item.watermarkFontPath, + } + : null, + item.metadata.includeWatermark, + ); + const layout = resolveLayoutFromMetadata(item.metadata); + const pro = hasProFeatures(user.plan); + const youtubeTitle = resolveYouTubeTitle(item.metadata, user.plan); + const burnedTitle = pro + ? resolveBurnedSongTitle( + item.metadata, + filenameWithoutExtension(item.audioFilename), + ) + : null; + return { + audioPath: item.audioPath, + audioFilename: item.audioFilename, + title: youtubeTitle, + songTitle: burnedTitle, + description: item.metadata.description || "", + tags: item.metadata.tags || "", + privacy: item.metadata.privacy as Privacy, + categoryId: item.metadata.categoryId || "10", + resolution: item.metadata.resolution, + notifySubscribers: item.metadata.notifySubscribers, + madeForKids: item.metadata.madeForKids, + embeddable: item.metadata.embeddable, + creativeCommons: item.metadata.creativeCommons, + includeWatermark: wm.mode !== "none", + itemImagePath: item.itemImagePath, + watermarkMode: wm.mode, + watermarkText: wm.mode === "text" ? wm.text?.trim() || null : null, + watermarkLogoPath: wm.mode === "logo" ? item.watermarkLogoPath : null, + watermarkFontKey: wm.fontKey ?? "system", + watermarkFontPath: + wm.fontKey === "custom" ? item.watermarkFontPath : null, + watermarkPosition: wm.position, + watermarkOffsetX: wm.offsetX, + watermarkOffsetY: wm.offsetY, + artist: pro + ? item.metadata.artist?.trim().slice(0, ARTIST_MAX) || null + : null, + layoutTemplate: layout.template, + blurAmount: layout.blurAmount, + blurOpacity: layout.blurOpacity, + textPadding: layout.textPadding, + titleArtistGap: layout.titleArtistGap, + textOffsetX: layout.textOffsetX, + textOffsetY: layout.textOffsetY, + playlistId: item.metadata.playlistId?.trim() || null, + billingSource: index < reservation.fromQuota ? "QUOTA" : "CREDIT", + }; + }), + }, + }, + include: { items: true }, + }); + + const jobDir = getJobDir(user.id, job.id); + await fs.mkdir(jobDir, { recursive: true }); + + const imageExt = path.extname(imagePath); + const newImagePath = path.join(jobDir, `image${imageExt}`); + await moveFile(imagePath, newImagePath); + await prisma.job.update({ where: { id: job.id }, data: { imagePath: newImagePath } }); + + const moved = new Map(); + moved.set(imagePath, newImagePath); + + await Promise.all( + job.items.map(async (item) => { + const audioExt = path.extname(item.audioPath); + const newAudioPath = path.join(jobDir, `${item.id}${audioExt}`); + await moveFile(item.audioPath, newAudioPath); + + let newItemImage: string | null = null; + if (item.itemImagePath) { + const src = item.itemImagePath; + if (moved.has(src)) { + newItemImage = moved.get(src)!; + } else { + const ext = path.extname(src); + newItemImage = path.join(jobDir, `${item.id}-cover${ext}`); + await moveFile(src, newItemImage); + moved.set(src, newItemImage); + } + } + + let newLogo: string | null = null; + if (item.watermarkLogoPath) { + const src = item.watermarkLogoPath; + if (moved.has(src)) { + newLogo = moved.get(src)!; + } else { + newLogo = path.join(jobDir, `${item.id}-logo.png`); + await moveFile(src, newLogo); + moved.set(src, newLogo); + } + } + + let newFont: string | null = null; + if (item.watermarkFontPath) { + const src = item.watermarkFontPath; + if (moved.has(src)) { + newFont = moved.get(src)!; + } else { + const ext = path.extname(src).toLowerCase() === ".otf" ? ".otf" : ".ttf"; + newFont = path.join(jobDir, `${item.id}-font${ext}`); + await moveFile(src, newFont); + moved.set(src, newFont); + } + } + + await prisma.jobItem.update({ + where: { id: item.id }, + data: { + audioPath: newAudioPath, + itemImagePath: newItemImage, + watermarkLogoPath: newLogo, + watermarkFontPath: newFont, + }, + }); + + await enqueueVideoJob({ + jobItemId: item.id, + userId: user.id, + jobId: job.id, + }); + }), + ); + + return job; + } catch (err) { + await releaseReservationSplit(user.id, reservation).catch(() => {}); + throw err; + } +} + +export type UploadFileType = "image" | "audio" | "logo" | "font"; + +export async function saveUploadedFile( + userId: string, + file: File, + type: UploadFileType, + plan: Plan, + options?: { sessionKey?: string }, +) { + const limits = getPlanLimits(plan); + + if (type === "font") { + if (!limits.customWatermark && !hasProFeatures(plan)) { + throw new PremiumRequiredError("Custom watermark fonts require Pro."); + } + if (file.size > FONT_UPLOAD_MAX_BYTES) { + throw new Error("Font file must be 10 MB or smaller"); + } + if (!/\.(ttf|otf)$/i.test(file.name)) { + throw new Error("Font must be a .ttf or .otf file"); + } + } else if (file.size > limits.maxFileSizeBytes) { + throw new Error(`File exceeds ${limits.maxFileSizeBytes / (1024 * 1024)} MB limit`); + } + + if (type === "logo") { + if (!limits.customWatermark && !hasProFeatures(plan)) { + throw new PremiumRequiredError("Custom logo watermarks require Pro."); + } + const nameOk = /\.png$/i.test(file.name); + const typeOk = file.type === "image/png" || file.type === ""; + if (!nameOk && !typeOk) { + throw new Error("Watermark logo must be a PNG file"); + } + } + + const allowedImageTypes = ["image/jpeg", "image/png", "image/webp", "image/gif"]; + const allowedAudioTypes = [ + "audio/mpeg", + "audio/mp3", + "audio/wav", + "audio/x-wav", + "audio/ogg", + "audio/flac", + "audio/aac", + "audio/mp4", + "audio/x-m4a", + ]; + + if (type === "image") { + if ( + !allowedImageTypes.includes(file.type) && + !file.name.match(/\.(jpg|jpeg|png|webp|gif)$/i) + ) { + throw new Error("Invalid image file type"); + } + } else if (type === "audio") { + if ( + !allowedAudioTypes.includes(file.type) && + !file.name.match(/\.(mp3|wav|ogg|flac|aac|m4a)$/i) + ) { + throw new Error("Invalid audio file type"); + } + if (!isAudioExtensionAllowed(file.name, plan)) { + const allowed = limits.allowedAudioExtensions.join(", "); + throw new Error(`Your plan supports ${allowed} audio files only`); + } + } + + const sessionKey = sanitizeUploadSessionKey(options?.sessionKey); + const sessionDir = getUserStagingDir(userId, sessionKey); + await fs.mkdir(sessionDir, { recursive: true }); + + const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, "_"); + const uniqueName = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}-${safeName}`; + const filePath = path.join(sessionDir, uniqueName); + assertPathInUserUploads(userId, filePath); + await writeUploadedFile(file, filePath); + + if (type === "logo") { + try { + await assertPngFile(filePath); + } catch (err) { + await fs.unlink(filePath).catch(() => {}); + throw err; + } + } + + if (type === "font") { + try { + await assertFontFile(filePath); + } catch (err) { + await fs.unlink(filePath).catch(() => {}); + throw err; + } + } + + let audioTags = null; + if (type === "audio" && limits.id3TagSupport && file.name.toLowerCase().endsWith(".mp3")) { + audioTags = await readAudioTags(filePath); + } + + return { + path: filePath, + filename: file.name, + size: file.size, + audioTags, + }; +} diff --git a/lib/jobs/resolve-playlist.ts b/lib/jobs/resolve-playlist.ts new file mode 100644 index 0000000..389c999 --- /dev/null +++ b/lib/jobs/resolve-playlist.ts @@ -0,0 +1,47 @@ +import type { Plan } from "@prisma/client"; +import { hasProFeatures } from "../edition"; +import type { CreateJobPayload, CreatePlaylistRequest, ItemMetadata } from "../types"; +import { createYouTubePlaylist } from "../youtube/upload"; + +export function parseCreatePlaylistInput(raw: unknown): CreatePlaylistRequest | null { + if (!raw || typeof raw !== "object") return null; + const value = raw as Record; + const title = typeof value.title === "string" ? value.title.trim() : ""; + if (!title) return null; + + const privacy = + value.privacy === "public" || value.privacy === "unlisted" || value.privacy === "private" + ? value.privacy + : undefined; + + return { + title, + description: typeof value.description === "string" ? value.description : undefined, + privacy, + }; +} + +export async function applyCreatePlaylistToItems( + user: { id: string; plan: Plan }, + items: CreateJobPayload["items"], + createPlaylist: CreatePlaylistRequest | null | undefined, +) { + if (!createPlaylist) { + return { items, playlist: null as Awaited> | null }; + } + + if (!hasProFeatures(user.plan)) { + throw new Error("Creating a YouTube playlist requires the Pro plan"); + } + + const playlist = await createYouTubePlaylist(user.id, createPlaylist); + const nextItems = items.map((item) => ({ + ...item, + metadata: { + ...item.metadata, + playlistId: item.metadata.playlistId || playlist.id, + } satisfies ItemMetadata, + })); + + return { items: nextItems, playlist }; +} diff --git a/lib/layout.ts b/lib/layout.ts new file mode 100644 index 0000000..b703a0c --- /dev/null +++ b/lib/layout.ts @@ -0,0 +1,418 @@ +/** + * Art-track layout templates + blur background (Pro). + * Cover/text anchors come from enum templates; only clamped fine-tuning offsets are allowed. + */ + +export const LAYOUT_TEMPLATES = [ + "COVER_LEFT_TEXT_RIGHT", + "COVER_TOP_TEXT_BOTTOM", + "COVER_RIGHT_TEXT_LEFT", + "CENTERED_COMPACT", +] as const; + +export type LayoutTemplate = (typeof LAYOUT_TEMPLATES)[number]; + +export const INVALID_LAYOUT_TEMPLATE_MESSAGE = + "Invalid layout template. Refer to API documentation for valid enum values."; + +export const BLUR_AMOUNT_MIN = 0; +export const BLUR_AMOUNT_MAX = 100; +export const BLUR_AMOUNT_DEFAULT = 55; + +/** Visibility of the blurred cover fill over black (0 = solid black, 100 = full blur). */ +export const BLUR_OPACITY_MIN = 0; +export const BLUR_OPACITY_MAX = 100; +export const BLUR_OPACITY_DEFAULT = 100; + +export const TEXT_PADDING_MIN = 16; +export const TEXT_PADDING_MAX = 120; +export const TEXT_PADDING_DEFAULT = 48; + +export const TITLE_ARTIST_GAP_MIN = 0; +export const TITLE_ARTIST_GAP_MAX = 64; +export const TITLE_ARTIST_GAP_DEFAULT = 10; + +/** Fine-tune title/artist block within the template (not free-form canvas coords). */ +export const TEXT_OFFSET_MIN = -120; +export const TEXT_OFFSET_MAX = 120; +export const TEXT_OFFSET_DEFAULT = 0; + +export const ARTIST_MAX = 80; +export const SONG_TITLE_MAX = 120; + +export type LayoutSettings = { + /** When null, classic letterbox (no art-track layout / blur fill). */ + template: LayoutTemplate | null; + /** 0–100 → FFmpeg boxblur intensity. */ + blurAmount: number; + /** 0–100 → how visible the blurred fill is (vs black). */ + blurOpacity: number; + /** Pixel padding / gap around cover + text. */ + textPadding: number; + /** Extra pixels between title and artist lines. */ + titleArtistGap: number; + /** Shift text block horizontally within the template. */ + textOffsetX: number; + /** Shift text block vertically within the template. */ + textOffsetY: number; +}; + +export const DEFAULT_LAYOUT: LayoutSettings = { + template: null, + blurAmount: BLUR_AMOUNT_DEFAULT, + blurOpacity: BLUR_OPACITY_DEFAULT, + textPadding: TEXT_PADDING_DEFAULT, + titleArtistGap: TITLE_ARTIST_GAP_DEFAULT, + textOffsetX: TEXT_OFFSET_DEFAULT, + textOffsetY: TEXT_OFFSET_DEFAULT, +}; + +export function isLayoutTemplate(v: unknown): v is LayoutTemplate { + return typeof v === "string" && (LAYOUT_TEMPLATES as readonly string[]).includes(v); +} + +export function clampBlurAmount(n: unknown, fallback = BLUR_AMOUNT_DEFAULT): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(BLUR_AMOUNT_MIN, Math.min(BLUR_AMOUNT_MAX, Math.round(v))); +} + +export function clampBlurOpacity(n: unknown, fallback = BLUR_OPACITY_DEFAULT): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(BLUR_OPACITY_MIN, Math.min(BLUR_OPACITY_MAX, Math.round(v))); +} + +export function clampTextPadding(n: unknown, fallback = TEXT_PADDING_DEFAULT): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(TEXT_PADDING_MIN, Math.min(TEXT_PADDING_MAX, Math.round(v))); +} + +export function clampTitleArtistGap(n: unknown, fallback = TITLE_ARTIST_GAP_DEFAULT): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(TITLE_ARTIST_GAP_MIN, Math.min(TITLE_ARTIST_GAP_MAX, Math.round(v))); +} + +export function clampTextOffset(n: unknown, fallback = TEXT_OFFSET_DEFAULT): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(TEXT_OFFSET_MIN, Math.min(TEXT_OFFSET_MAX, Math.round(v))); +} + +export function blurToBoxblur(blurAmount: number): { radius: number; power: number } | null { + const amount = clampBlurAmount(blurAmount, 0); + if (amount <= 0) return null; + const radius = Math.max(1, Math.round((amount / 100) * 50)); + const power = Math.max(1, Math.min(4, Math.ceil(amount / 25))); + return { radius, power }; +} + +export function boxblurFilterSegment(blurAmount: number): string { + const bb = blurToBoxblur(blurAmount); + if (!bb) return ""; + return `boxblur=luma_radius=${bb.radius}:luma_power=${bb.power}:chroma_radius=${bb.radius}:chroma_power=${bb.power}`; +} + +type RawLayoutInput = { + template?: unknown; + layoutTemplate?: unknown; + layout_template?: unknown; + blurAmount?: unknown; + blur_amount?: unknown; + blurOpacity?: unknown; + blur_opacity?: unknown; + textPadding?: unknown; + text_padding?: unknown; + titleArtistGap?: unknown; + title_artist_gap?: unknown; + textOffsetX?: unknown; + text_offset_x?: unknown; + textOffsetY?: unknown; + text_offset_y?: unknown; + /** Rejected clients must not send free-form cover coordinates. */ + x?: unknown; + y?: unknown; + coverX?: unknown; + coverY?: unknown; + offsetX?: unknown; + offsetY?: unknown; +}; + +export function normalizeLayoutSettings( + input: RawLayoutInput | Partial | null | undefined, +): LayoutSettings { + if (!input) return { ...DEFAULT_LAYOUT }; + + const forbidden = ["x", "y", "coverX", "coverY", "offsetX", "offsetY"] as const; + for (const k of forbidden) { + if ((input as RawLayoutInput)[k] !== undefined) { + throw new Error(INVALID_LAYOUT_TEMPLATE_MESSAGE); + } + } + + const raw = + (input as RawLayoutInput).template ?? + (input as RawLayoutInput).layoutTemplate ?? + (input as RawLayoutInput).layout_template; + + let template: LayoutTemplate | null = null; + if (raw !== undefined && raw !== null && raw !== "" && raw !== "CLASSIC" && raw !== "classic") { + if (!isLayoutTemplate(raw)) { + throw new Error(INVALID_LAYOUT_TEMPLATE_MESSAGE); + } + template = raw; + } + + const blurRaw = + (input as RawLayoutInput).blurAmount ?? + (input as RawLayoutInput).blur_amount ?? + (input as LayoutSettings).blurAmount; + const opacityRaw = + (input as RawLayoutInput).blurOpacity ?? + (input as RawLayoutInput).blur_opacity ?? + (input as LayoutSettings).blurOpacity; + const padRaw = + (input as RawLayoutInput).textPadding ?? + (input as RawLayoutInput).text_padding ?? + (input as LayoutSettings).textPadding; + const gapRaw = + (input as RawLayoutInput).titleArtistGap ?? + (input as RawLayoutInput).title_artist_gap ?? + (input as LayoutSettings).titleArtistGap; + const oxRaw = + (input as RawLayoutInput).textOffsetX ?? + (input as RawLayoutInput).text_offset_x ?? + (input as LayoutSettings).textOffsetX; + const oyRaw = + (input as RawLayoutInput).textOffsetY ?? + (input as RawLayoutInput).text_offset_y ?? + (input as LayoutSettings).textOffsetY; + + return { + template, + blurAmount: clampBlurAmount(blurRaw, BLUR_AMOUNT_DEFAULT), + blurOpacity: clampBlurOpacity(opacityRaw, BLUR_OPACITY_DEFAULT), + textPadding: clampTextPadding(padRaw, TEXT_PADDING_DEFAULT), + titleArtistGap: clampTitleArtistGap(gapRaw, TITLE_ARTIST_GAP_DEFAULT), + textOffsetX: clampTextOffset(oxRaw, TEXT_OFFSET_DEFAULT), + textOffsetY: clampTextOffset(oyRaw, TEXT_OFFSET_DEFAULT), + }; +} + +export function requiresArtTrackLayoutEntitlement(settings: LayoutSettings): boolean { + return settings.template !== null; +} + +export type LayoutGeometry = { + coverMaxW: number; + coverMaxH: number; + coverX: string; + coverY: string; + titleFontSize: number; + artistFontSize: number; + titleX: string; + titleY: string; + artistX: string; + artistY: string; +}; + +function applyTextOffsets( + geo: LayoutGeometry, + textOffsetX: number, + textOffsetY: number, +): LayoutGeometry { + const ox = clampTextOffset(textOffsetX); + const oy = clampTextOffset(textOffsetY); + if (ox === 0 && oy === 0) return geo; + + const shiftX = (expr: string) => { + if (expr === "(w-text_w)/2") return `(w-text_w)/2+${ox}`; + if (/^-?\d+$/.test(expr)) return String(Number(expr) + ox); + return `${expr}+${ox}`; + }; + const shiftY = (expr: string) => { + if (/^-?\d+$/.test(expr)) return String(Number(expr) + oy); + return `${expr}+${oy}`; + }; + + return { + ...geo, + titleX: shiftX(geo.titleX), + titleY: shiftY(geo.titleY), + artistX: shiftX(geo.artistX), + artistY: shiftY(geo.artistY), + }; +} + +/** Pixel geometry template + padding + title/artist gap + text offsets. */ +export function computeLayoutGeometry( + template: LayoutTemplate, + width: number, + height: number, + textPadding: number, + titleArtistGap: number = TITLE_ARTIST_GAP_DEFAULT, + textOffsetX: number = 0, + textOffsetY: number = 0, +): LayoutGeometry { + const pad = clampTextPadding(textPadding); + const gap = clampTitleArtistGap(titleArtistGap); + const titleFontSize = Math.max(22, Math.round(width * 0.032)); + const artistFontSize = Math.max(16, Math.round(width * 0.02)); + const lineGap = gap; + + let base: LayoutGeometry; + + switch (template) { + case "COVER_LEFT_TEXT_RIGHT": { + const coverMaxW = Math.round(width * 0.42); + const coverMaxH = height - pad * 2; + const textX = pad + coverMaxW + pad; + const midY = Math.round(height / 2); + base = { + coverMaxW, + coverMaxH, + coverX: String(pad), + coverY: "(H-h)/2", + titleFontSize, + artistFontSize, + titleX: String(textX), + titleY: String(midY - titleFontSize - Math.round(lineGap / 2)), + artistX: String(textX), + artistY: String(midY + Math.round(lineGap / 2)), + }; + break; + } + case "COVER_RIGHT_TEXT_LEFT": { + const coverMaxW = Math.round(width * 0.42); + const coverMaxH = height - pad * 2; + const textX = pad; + const midY = Math.round(height / 2); + base = { + coverMaxW, + coverMaxH, + coverX: `W-w-${pad}`, + coverY: "(H-h)/2", + titleFontSize, + artistFontSize, + titleX: String(textX), + titleY: String(midY - titleFontSize - Math.round(lineGap / 2)), + artistX: String(textX), + artistY: String(midY + Math.round(lineGap / 2)), + }; + break; + } + case "COVER_TOP_TEXT_BOTTOM": { + // Near full width avoid empty side gutters next to the cover + const coverMaxW = width - pad * 2; + const coverMaxH = Math.round(height * 0.56); + const textBlockTop = pad + coverMaxH + Math.round(pad * 0.55); + base = { + coverMaxW, + coverMaxH, + coverX: "(W-w)/2", + coverY: String(pad), + titleFontSize, + artistFontSize, + titleX: "(w-text_w)/2", + titleY: String(textBlockTop), + artistX: "(w-text_w)/2", + artistY: String(textBlockTop + titleFontSize + lineGap), + }; + break; + } + case "CENTERED_COMPACT": { + const side = Math.round(Math.min(width, height) * 0.4); + const stackH = side + pad + titleFontSize + lineGap + artistFontSize; + const stackTop = Math.round((height - stackH) / 2); + const coverY = Math.max(pad, stackTop); + const titleY = coverY + side + Math.round(pad * 0.55); + base = { + coverMaxW: side, + coverMaxH: side, + coverX: "(W-w)/2", + coverY: String(coverY), + titleFontSize, + artistFontSize, + titleX: "(w-text_w)/2", + titleY: String(titleY), + artistX: "(w-text_w)/2", + artistY: String(titleY + titleFontSize + lineGap), + }; + break; + } + default: { + throw new Error(INVALID_LAYOUT_TEMPLATE_MESSAGE); + } + } + + return applyTextOffsets(base, textOffsetX, textOffsetY); +} + +export function buildArtTrackFilterComplex(opts: { + width: number; + height: number; + layout: LayoutSettings; + titleEscaped: string; + artistEscaped: string | null; + fontfileEscaped?: string | null; +}): string { + const { width: W, height: H, layout } = opts; + if (!layout.template) { + throw new Error("Art-track filter requires a layout template"); + } + + const geo = computeLayoutGeometry( + layout.template, + W, + H, + layout.textPadding, + layout.titleArtistGap, + layout.textOffsetX, + layout.textOffsetY, + ); + const blurSeg = boxblurFilterSegment(layout.blurAmount); + const bgChain = blurSeg + ? `scale=${W}:${H}:force_original_aspect_ratio=increase,crop=${W}:${H},${blurSeg}` + : `scale=${W}:${H}:force_original_aspect_ratio=increase,crop=${W}:${H}`; + + const opacity = clampBlurOpacity(layout.blurOpacity, BLUR_OPACITY_DEFAULT) / 100; + const fontPart = opts.fontfileEscaped ? `:fontfile='${opts.fontfileEscaped}'` : ""; + const titleDraw = `drawtext=text='${opts.titleEscaped}'${fontPart}:fontsize=${geo.titleFontSize}:fontcolor=white@0.95:x=${geo.titleX}:y=${geo.titleY}`; + const artistDraw = opts.artistEscaped + ? `,drawtext=text='${opts.artistEscaped}'${fontPart}:fontsize=${geo.artistFontSize}:fontcolor=white@0.75:x=${geo.artistX}:y=${geo.artistY}` + : ""; + + const parts: string[] = [`[0:v]split=2[bg][fg]`]; + + // Fade blurred fill toward black when opacity < 100% + if (opacity >= 0.999) { + parts.push(`[bg]${bgChain}[blurred]`); + } else if (opacity <= 0.001) { + parts.push(`color=c=black:s=${W}x${H}:d=1[blurred]`); + } else { + const a = opacity.toFixed(3); + const b = (1 - opacity).toFixed(3); + parts.push( + `[bg]${bgChain}[blur_raw]`, + `color=c=black:s=${W}x${H}:d=1[blk]`, + `[blur_raw][blk]blend=all_expr='A*${a}+B*${b}':shortest=1[blurred]`, + ); + } + + parts.push( + `[fg]scale=${geo.coverMaxW}:${geo.coverMaxH}:force_original_aspect_ratio=decrease[cover]`, + `[blurred][cover]overlay=${geo.coverX}:${geo.coverY}[composed]`, + `[composed]${titleDraw}${artistDraw}[laid]`, + ); + + return parts.join(";"); +} + +export const LAYOUT_TEMPLATE_LABELS: Record = { + COVER_LEFT_TEXT_RIGHT: "Cover left · text right", + COVER_TOP_TEXT_BOTTOM: "Cover top · text bottom", + COVER_RIGHT_TEXT_LEFT: "Cover right · text left", + CENTERED_COMPACT: "Centered compact", +}; diff --git a/lib/legal/constants.ts b/lib/legal/constants.ts new file mode 100644 index 0000000..39dfba1 --- /dev/null +++ b/lib/legal/constants.ts @@ -0,0 +1,15 @@ +import { SUPPORT_EMAIL, SALES_EMAIL, QUOTA_REQUEST_EMAIL } from "@/lib/plans"; +import { BRAND_DOMAIN, BRAND_NAME } from "@/lib/branding"; + +export const LEGAL_LAST_UPDATED = "July 25, 2026"; + +export const LEGAL_OPERATOR = { + name: BRAND_NAME, + legalName: "Atakan Doğan Özban", + address: "Universitas u. 2/A", + city: "7622 Pécs, Hungary", + email: SUPPORT_EMAIL, + salesEmail: SALES_EMAIL, + quotaRequestEmail: QUOTA_REQUEST_EMAIL, + website: `https://www.${BRAND_DOMAIN}`, +} as const; diff --git a/lib/plans.ts b/lib/plans.ts new file mode 100644 index 0000000..5376c90 --- /dev/null +++ b/lib/plans.ts @@ -0,0 +1,111 @@ +import { Plan } from "@prisma/client"; +import { getResolution, RESOLUTIONS } from "./constants"; +import { isSelfHostedEdition } from "./edition"; + +export type PlanLimits = { + monthlyQuota: number; + maxBatchSize: number; + maxResolutionHeight: number; + maxFileSizeBytes: number; + watermarkOptional: boolean; + /** Custom text / PNG logo + position controls (Pro). */ + customWatermark: boolean; + /** Pair a unique cover image per audio in a batch (Pro). */ + perItemImages: boolean; + /** Blurred cover background + art-track layout templates (Pro). */ + artTrackLayouts: boolean; + allowedAudioExtensions: readonly string[]; + id3TagSupport: boolean; +}; + +export const PLAN_LIMITS: Record = { + FREE: { + monthlyQuota: 10, + maxBatchSize: 3, + maxResolutionHeight: 720, + maxFileSizeBytes: 30 * 1024 * 1024, + watermarkOptional: true, + customWatermark: false, + perItemImages: false, + artTrackLayouts: false, + allowedAudioExtensions: [".mp3"], + id3TagSupport: true, + }, + PREMIUM: { + monthlyQuota: 50, + maxBatchSize: 5, + maxResolutionHeight: 1080, + maxFileSizeBytes: 30 * 1024 * 1024, + watermarkOptional: true, + customWatermark: true, + perItemImages: true, + artTrackLayouts: true, + allowedAudioExtensions: [".mp3", ".wav", ".flac"], + id3TagSupport: true, + }, +}; + +export const SELFHOSTED_LIMITS: PlanLimits = { + monthlyQuota: 1_000_000, + maxBatchSize: 100, + maxResolutionHeight: Math.max(...RESOLUTIONS.map((r) => r.height)), + maxFileSizeBytes: 500 * 1024 * 1024, + watermarkOptional: true, + customWatermark: true, + perItemImages: true, + artTrackLayouts: true, + allowedAudioExtensions: [".mp3", ".wav", ".flac"], + id3TagSupport: true, +}; + +export const SALES_EMAIL = "songs2vid@atakanozban.com"; +export const SUPPORT_EMAIL = "songs2vid@atakanozban.com"; +/** Pro quota reset / extension requests */ +export const QUOTA_REQUEST_EMAIL = "songs2vid@atakanozban.com"; +export const UPGRADE_URL = "/#pricing"; +export const GITEA_ISSUES_URL = + process.env.NEXT_PUBLIC_GITEA_ISSUES_URL ?? "https://git.atakanozban.com/Songs2VID/songs2vid/issues"; +export const GITEA_URL = + process.env.NEXT_PUBLIC_GITEA_URL ?? "https://git.atakanozban.com/Songs2VID"; +export const DOCKER_HUB_URL = + process.env.NEXT_PUBLIC_DOCKER_HUB_URL ?? "https://hub.docker.com/r/atakanozban/songs2vid"; + +/** Docusaurus docs base URL. Local: http://localhost:3001 (npm run docs:dev). */ +export function resolveDocsUrl(): string { + if (process.env.NEXT_PUBLIC_DOCS_URL?.trim()) { + return process.env.NEXT_PUBLIC_DOCS_URL.replace(/\/$/, ""); + } + const auth = process.env.NEXTAUTH_URL ?? ""; + if (/localhost|127\.0\.0\.1/i.test(auth)) { + return "http://localhost:3001"; + } + return "https://docs.songs2vid.com"; +} + +export const DOCS_URL = resolveDocsUrl(); +export const API_DOCS_URL = `${DOCS_URL}/docs/api/overview`; + +export function getPlanLimits(plan: Plan): PlanLimits { + if (isSelfHostedEdition()) return SELFHOSTED_LIMITS; + return PLAN_LIMITS[plan]; +} + +export function getResolutionsForPlan(plan: Plan) { + const maxHeight = getPlanLimits(plan).maxResolutionHeight; + return RESOLUTIONS.filter((r) => r.height <= maxHeight); +} + +export function isResolutionAllowedForPlan(resolution: string, plan: Plan): boolean { + const res = getResolution(resolution); + if (!res) return false; + return res.height <= getPlanLimits(plan).maxResolutionHeight; +} + +export function isAudioExtensionAllowed(filename: string, plan: Plan): boolean { + const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase(); + return getPlanLimits(plan).allowedAudioExtensions.includes(ext); +} + +export function getNextMonthlyQuotaReset(from: Date = new Date()): Date { + return new Date(from.getFullYear(), from.getMonth() + 1, 1, 0, 0, 0, 0); +} diff --git a/lib/preview-typography.ts b/lib/preview-typography.ts new file mode 100644 index 0000000..427914e --- /dev/null +++ b/lib/preview-typography.ts @@ -0,0 +1,46 @@ +/** + * Shared typography math for dashboard preview ↔ FFmpeg output parity. + * Preview container uses a fixed reference width; scale from target encode resolution. + */ + +import type { WatermarkFontKey } from "./fonts"; +import { CURATED_FONTS } from "./fonts"; + +/** Matches LayoutStudio max preview width (tailwind max-w-xl ≈ 576px; use 576 for scaling). */ +export const PREVIEW_REFERENCE_WIDTH = 576; + +export function titleFontSizeForWidth(width: number): number { + return Math.max(22, Math.round(width * 0.032)); +} + +export function artistFontSizeForWidth(width: number): number { + return Math.max(16, Math.round(width * 0.02)); +} + +export function watermarkFontSizeForWidth(width: number): number { + return Math.max(16, Math.round(width * 0.018)); +} + +/** Scale encode-resolution px to preview container px. */ +export function scaleFontToPreview(fontPx: number, encodeWidth: number): number { + const ref = encodeWidth > 0 ? encodeWidth : 1280; + return Math.max(8, Math.round((fontPx * PREVIEW_REFERENCE_WIDTH) / ref)); +} + +export function previewFontFamilyCss(fontKey: WatermarkFontKey | undefined): string { + if (!fontKey || fontKey === "system") { + return "Arial, Helvetica, sans-serif"; + } + if (fontKey === "custom") { + return "'S2VIDCustomWm', Arial, sans-serif"; + } + const meta = CURATED_FONTS.find((f) => f.key === fontKey); + return meta ? `'S2VIDPreview-${meta.key}', Arial, sans-serif` : "Arial, sans-serif"; +} + +export function curatedFontApiUrl(key: string): string { + return `/api/fonts/${key}`; +} + +/** Watermark overlay width as fraction of frame (matches encode.ts). */ +export const WATERMARK_WIDTH_FRACTION = 0.32; diff --git a/lib/queue/client.ts b/lib/queue/client.ts index a63a900..2a6c54b 100644 --- a/lib/queue/client.ts +++ b/lib/queue/client.ts @@ -1,24 +1,29 @@ -import { Redis } from "ioredis"; import { Queue } from "bullmq"; -import { QUEUE_NAME } from "./constants"; -import type { VideoJobData } from "./types"; +import { QUEUE_NAME } from "../constants"; +import type { VideoJobData } from "../types"; -let connection: Redis | null = null; -let queue: Queue | null = null; - -export function getRedisConnection(): Redis { - if (!connection) { - connection = new Redis(process.env.REDIS_URL || "redis://localhost:6379", { - maxRetriesPerRequest: null, - }); - } - return connection; +function getConnectionOptions() { + const url = process.env.REDIS_URL || "redis://localhost:6379"; + const parsed = new URL(url); + return { + host: parsed.hostname, + port: Number(parsed.port) || 6379, + username: parsed.username || undefined, + password: parsed.password || undefined, + maxRetriesPerRequest: null as null, + }; } -export function getVideoQueue(): Queue { +let queue: Queue | null = null; + +export function getRedisConnection() { + return getConnectionOptions(); +} + +export function getVideoQueue(): Queue { if (!queue) { - queue = new Queue(QUEUE_NAME, { - connection: getRedisConnection(), + queue = new Queue(QUEUE_NAME, { + connection: getConnectionOptions(), }); } return queue; diff --git a/lib/quota-extensions.ts b/lib/quota-extensions.ts new file mode 100644 index 0000000..625dc8a --- /dev/null +++ b/lib/quota-extensions.ts @@ -0,0 +1,186 @@ +import { QuotaExtensionRequestStatus } from "@prisma/client"; +import { MAX_ADMIN_API_RATE_BONUS } from "./api-rate-limit"; +import { prisma } from "./db"; +import { getPlanLimits } from "./plans"; + +export const QUOTA_EXTENSION_ANNUAL_LIMIT = 5; +/** Max bonus videos an admin may grant per approval. */ +export const MAX_ADMIN_BONUS_QUOTA = 50; + +export const EXTENSION_KIND = { + VIDEO_QUOTA: "VIDEO_QUOTA", + API_RATE_LIMIT: "API_RATE_LIMIT", +} as const; + +export type ExtensionKind = (typeof EXTENSION_KIND)[keyof typeof EXTENSION_KIND]; + +function getCalendarYearBounds(year = new Date().getFullYear()) { + return { + start: new Date(year, 0, 1), + end: new Date(year + 1, 0, 1), + }; +} + +export async function getQuotaExtensionUsage( + userId: string, + kind: ExtensionKind = EXTENSION_KIND.VIDEO_QUOTA, +) { + const { start, end } = getCalendarYearBounds(); + + const requests = await prisma.quotaExtensionRequest.findMany({ + where: { + userId, + kind, + requestedAt: { gte: start, lt: end }, + }, + orderBy: { requestedAt: "desc" }, + }); + + const used = requests.filter((r) => r.status !== QuotaExtensionRequestStatus.REJECTED).length; + + return { + used, + limit: QUOTA_EXTENSION_ANNUAL_LIMIT, + remaining: Math.max(0, QUOTA_EXTENSION_ANNUAL_LIMIT - used), + kind, + requests: requests.map((r) => ({ + id: r.id, + kind: r.kind, + status: r.status, + message: r.message, + requestedAt: r.requestedAt.toISOString(), + processedAt: r.processedAt?.toISOString() ?? null, + adminNote: r.adminNote, + })), + }; +} + +export async function createQuotaExtensionRequest( + userId: string, + message = "", + kind: ExtensionKind = EXTENSION_KIND.VIDEO_QUOTA, +) { + const user = await prisma.user.findUniqueOrThrow({ where: { id: userId } }); + + if (user.plan !== "PREMIUM") { + throw new Error("Only Pro subscribers can request quota resets or extensions."); + } + + const usage = await getQuotaExtensionUsage(userId, kind); + if (usage.remaining <= 0) { + throw new Error( + `You have used all ${QUOTA_EXTENSION_ANNUAL_LIMIT} ${ + kind === EXTENSION_KIND.API_RATE_LIMIT ? "API rate limit" : "quota" + } extension requests for this year.`, + ); + } + + const pending = await prisma.quotaExtensionRequest.findFirst({ + where: { userId, kind, status: QuotaExtensionRequestStatus.PENDING }, + }); + if (pending) { + throw new Error("You already have a pending request. Please wait for it to be processed."); + } + + const request = await prisma.quotaExtensionRequest.create({ + data: { + userId, + kind, + message: message.trim().slice(0, 1000), + status: QuotaExtensionRequestStatus.PENDING, + }, + }); + + const updatedUsage = await getQuotaExtensionUsage(userId, kind); + + return { + requestId: request.id, + ...updatedUsage, + }; +} + +/** Call when approving a request in the database (admin / support). */ +export async function approveQuotaExtensionRequest( + requestId: string, + options?: { bonusQuota?: number; bonusRateLimit?: number; adminNote?: string }, +) { + const request = await prisma.quotaExtensionRequest.findUniqueOrThrow({ + where: { id: requestId }, + include: { user: true }, + }); + + if (request.status !== QuotaExtensionRequestStatus.PENDING) { + throw new Error("Request is not pending."); + } + + if (request.kind === EXTENSION_KIND.API_RATE_LIMIT) { + const bonus = Math.min( + MAX_ADMIN_API_RATE_BONUS, + Math.max(0, Math.floor(options?.bonusRateLimit ?? 30)), + ); + + await prisma.$transaction([ + prisma.quotaExtensionRequest.update({ + where: { id: requestId }, + data: { + status: QuotaExtensionRequestStatus.APPROVED, + processedAt: new Date(), + adminNote: options?.adminNote?.trim().slice(0, 500) ?? null, + }, + }), + prisma.user.update({ + where: { id: request.userId }, + data: { + apiRateLimitBonus: request.user.apiRateLimitBonus + bonus, + }, + }), + ]); + return; + } + + const bonus = Math.min( + MAX_ADMIN_BONUS_QUOTA, + Math.max(0, Math.floor(options?.bonusQuota ?? 0)), + ); + + await prisma.$transaction([ + prisma.quotaExtensionRequest.update({ + where: { id: requestId }, + data: { + status: QuotaExtensionRequestStatus.APPROVED, + processedAt: new Date(), + adminNote: options?.adminNote?.trim().slice(0, 500) ?? null, + }, + }), + prisma.user.update({ + where: { id: request.userId }, + data: { + videosUsed: 0, + bonusQuota: request.user.bonusQuota + bonus, + }, + }), + ]); +} + +export async function rejectQuotaExtensionRequest(requestId: string, adminNote?: string) { + const request = await prisma.quotaExtensionRequest.findUniqueOrThrow({ + where: { id: requestId }, + }); + + if (request.status !== QuotaExtensionRequestStatus.PENDING) { + throw new Error("Request is not pending."); + } + + await prisma.quotaExtensionRequest.update({ + where: { id: requestId }, + data: { + status: QuotaExtensionRequestStatus.REJECTED, + processedAt: new Date(), + adminNote: adminNote?.trim().slice(0, 500) ?? null, + }, + }); +} + +export function getEffectiveQuotaLimit(plan: Parameters[0], bonusQuota: number) { + return getPlanLimits(plan).monthlyQuota + bonusQuota; +} diff --git a/lib/quota.ts b/lib/quota.ts index 5f26d45..918cd7b 100644 --- a/lib/quota.ts +++ b/lib/quota.ts @@ -1,55 +1,276 @@ -import { FREE_PLAN } from "./constants"; +import { Plan } from "@prisma/client"; +import { + CreditInsufficientError, + applyMonthlyCreditRenewal, + deductUserCredit, + refundUserCredit, +} from "./billing"; +import { FREE_EXTRA_CREDITS_MAX, MAX_CREDIT_CAP, PRO_UPGRADE_REQUIRED_SUFFIX, monthlyCreditsForPlan } from "./credits"; import { prisma } from "./db"; +import { isSelfHostedEdition } from "./edition"; +import { getNextMonthlyQuotaReset, getPlanLimits } from "./plans"; -function getNextQuotaReset(from: Date = new Date()): Date { - return new Date(from.getFullYear(), from.getMonth() + 1, 1); +export function formatQuotaResetCountdown(resetsAt: Date | string): string { + const target = typeof resetsAt === "string" ? new Date(resetsAt) : resetsAt; + const ms = Math.max(0, target.getTime() - Date.now()); + const totalSec = Math.ceil(ms / 1000); + const hours = Math.floor(totalSec / 3600); + const minutes = Math.floor((totalSec % 3600) / 60); + const seconds = totalSec % 60; + return `${hours}h ${minutes}m ${seconds}s`; } +export function formatQuotaResetDisplay(plan: Plan, resetsAt: Date | string): string { + const target = typeof resetsAt === "string" ? new Date(resetsAt) : resetsAt; + return target.toLocaleDateString(undefined, { + month: "long", + day: "numeric", + year: "numeric", + }); +} + +function getQuotaExceededMessage( + plan: Plan, + resetsAt: Date, + extraCredits: number, +): string { + const resetLabel = formatQuotaResetDisplay(plan, resetsAt); + if (plan === "PREMIUM") { + return extraCredits > 0 + ? `Monthly Pro quota exhausted. You still have ${extraCredits} extra credits.` + : `Quota exceeded. Your Pro monthly credits reset on ${resetLabel}.`; + } + if (extraCredits > 0) { + return `Monthly free quota exhausted. You still have ${extraCredits} extra credits.`; + } + return ( + `You've used your free monthly credits (10) and any extra top-ups (max ${FREE_EXTRA_CREDITS_MAX}). ` + + `Upgrade to the Pro monthly plan to continue uploading.` + + PRO_UPGRADE_REQUIRED_SUFFIX + ); +} + +/** Reset cycle when due: rollover unused into extras, add new monthly, trim to MAX_CREDIT_CAP. */ export async function ensureQuotaReset(userId: string) { const user = await prisma.user.findUniqueOrThrow({ where: { id: userId } }); - if (new Date() >= user.quotaResetAt) { - return prisma.user.update({ - where: { id: userId }, - data: { - videosUsed: 0, - quotaResetAt: getNextQuotaReset(), - }, + const now = new Date(); + const expectedMonthly = monthlyCreditsForPlan(user.plan); + + if (now >= user.quotaResetAt) { + return applyMonthlyCreditRenewal(userId, { + plan: user.plan, + newMonthlyCredits: expectedMonthly, + quotaResetAt: getNextMonthlyQuotaReset(now), }); } + + // Keep monthlyCredits in sync if plan was changed mid-cycle without reset + if (user.monthlyCredits !== expectedMonthly && user.videosUsed === 0 && user.extraCredits === 0) { + return prisma.user.update({ + where: { id: userId }, + data: { monthlyCredits: expectedMonthly }, + }); + } + return user; } export async function getQuotaInfo(userId: string) { const user = await ensureQuotaReset(userId); - const remaining = Math.max(0, FREE_PLAN.monthlyQuota - user.videosUsed); + const limits = getPlanLimits(user.plan); + const limit = isSelfHostedEdition() + ? limits.monthlyQuota + : user.monthlyCredits + (user.plan === "PREMIUM" ? user.bonusQuota : 0); + const remaining = Math.max(0, limit - user.videosUsed); + const extraCredits = isSelfHostedEdition() ? 0 : user.extraCredits; + return { used: user.videosUsed, - limit: FREE_PLAN.monthlyQuota, + creditsUsed: user.videosUsed, + limit, + monthlyCredits: user.monthlyCredits, + baseLimit: limits.monthlyQuota, + bonusQuota: isSelfHostedEdition() ? 0 : user.bonusQuota, remaining, + /** @deprecated use extraCredits */ + videoCredits: extraCredits, + extraCredits, + creditBalanceMax: MAX_CREDIT_CAP, + requiresProUpgrade: + !isSelfHostedEdition() && + user.plan === "FREE" && + remaining === 0 && + extraCredits === 0, + freeTopUpPurchased: user.freeTopUpPurchased, + totalAvailable: remaining + extraCredits, resetsAt: user.quotaResetAt.toISOString(), + resetsIn: formatQuotaResetDisplay(user.plan, user.quotaResetAt), + plan: user.plan, + maxBatchSize: limits.maxBatchSize, + watermarkOptional: limits.watermarkOptional, + customWatermark: limits.customWatermark, + perItemImages: limits.perItemImages, + artTrackLayouts: limits.artTrackLayouts, + maxResolutionHeight: limits.maxResolutionHeight, + selfHosted: isSelfHostedEdition(), }; } -export async function checkQuota(userId: string, requestedCount: number) { - const info = await getQuotaInfo(userId); - if (requestedCount > info.remaining) { - return { - ok: false as const, - error: `Quota exceeded. You have ${info.remaining} videos remaining this month.`, - ...info, - }; - } - return { ok: true as const, ...info }; +export type ReservationSplit = { + fromQuota: number; + fromCredits: number; +}; + +/** + * Monthly first, then never-expiring extras for both FREE and PREMIUM. + */ +export function planReservation( + _plan: Plan, + remainingQuota: number, + extraCredits: number, + count: number, +): ReservationSplit | null { + if (count <= 0) return { fromQuota: 0, fromCredits: 0 }; + const fromQuota = Math.min(count, Math.max(0, remainingQuota)); + const fromCredits = count - fromQuota; + if (fromCredits > extraCredits) return null; + return { fromQuota, fromCredits }; } -export async function incrementQuota(userId: string, count: number) { +export async function checkQuota(userId: string, requestedCount: number) { + if (isSelfHostedEdition()) { + const info = await getQuotaInfo(userId); + if (requestedCount > info.maxBatchSize) { + return { + ok: false as const, + error: `Batch limit exceeded. Max ${info.maxBatchSize} files per batch.`, + used: info.used, + limit: info.limit, + remaining: info.remaining, + videoCredits: 0, + extraCredits: 0, + resetsAt: info.resetsAt, + }; + } + return { + ok: true as const, + ...info, + reservation: { fromQuota: requestedCount, fromCredits: 0 }, + }; + } + + const user = await ensureQuotaReset(userId); + const limits = getPlanLimits(user.plan); + const limit = user.monthlyCredits + (user.plan === "PREMIUM" ? user.bonusQuota : 0); + const remaining = Math.max(0, limit - user.videosUsed); + + if (requestedCount > limits.maxBatchSize) { + return { + ok: false as const, + error: `Batch limit exceeded. Your plan allows up to ${limits.maxBatchSize} files per batch.`, + used: user.videosUsed, + limit, + remaining, + videoCredits: user.extraCredits, + extraCredits: user.extraCredits, + resetsAt: user.quotaResetAt.toISOString(), + }; + } + + const split = planReservation(user.plan, remaining, user.extraCredits, requestedCount); + if (!split) { + return { + ok: false as const, + error: getQuotaExceededMessage(user.plan, user.quotaResetAt, user.extraCredits), + used: user.videosUsed, + limit, + remaining, + videoCredits: user.extraCredits, + extraCredits: user.extraCredits, + resetsAt: user.quotaResetAt.toISOString(), + }; + } + + const info = await getQuotaInfo(userId); + return { ok: true as const, ...info, reservation: split }; +} + +/** + * Atomically reserve monthly credits first, then extras. + */ +export async function reserveQuota(userId: string, count: number): Promise { + if (count <= 0) return { fromQuota: 0, fromCredits: 0 }; + + if (isSelfHostedEdition()) { + const limits = getPlanLimits("FREE"); + if (count > limits.maxBatchSize) { + throw new Error(`Batch limit exceeded. Max ${limits.maxBatchSize} files per batch.`); + } + await ensureQuotaReset(userId); + await prisma.user.update({ + where: { id: userId }, + data: { videosUsed: { increment: count } }, + }); + return { fromQuota: count, fromCredits: 0 }; + } + await ensureQuotaReset(userId); - await prisma.user.update({ - where: { id: userId }, - data: { videosUsed: { increment: count } }, - }); + + const limits = getPlanLimits( + (await prisma.user.findUniqueOrThrow({ where: { id: userId } })).plan, + ); + if (count > limits.maxBatchSize) { + throw new Error( + `Batch limit exceeded. Your plan allows up to ${limits.maxBatchSize} files per batch.`, + ); + } + + try { + const result = await deductUserCredit(userId, count); + return { fromQuota: result.fromMonthly, fromCredits: result.fromExtra }; + } catch (err) { + if (err instanceof CreditInsufficientError) { + const user = await prisma.user.findUniqueOrThrow({ where: { id: userId } }); + throw new Error( + getQuotaExceededMessage(user.plan, user.quotaResetAt, user.extraCredits), + ); + } + throw err; + } +} + +export async function releaseQuota(userId: string, count: number) { + if (count <= 0) return; + await refundUserCredit(userId, count, 0); +} + +export async function releaseCredits(userId: string, count: number) { + if (count <= 0) return; + await refundUserCredit(userId, 0, count); +} + +export async function releaseReservation( + userId: string, + billingSource: "QUOTA" | "CREDIT", + count = 1, +) { + if (billingSource === "CREDIT") { + await releaseCredits(userId, count); + } else { + await releaseQuota(userId, count); + } +} + +export async function releaseReservationSplit(userId: string, split: ReservationSplit) { + if (split.fromQuota > 0) await releaseQuota(userId, split.fromQuota); + if (split.fromCredits > 0) await releaseCredits(userId, split.fromCredits); +} + +/** @deprecated Prefer reserveQuota at create */ +export async function incrementQuota(userId: string, count: number) { + await reserveQuota(userId, count); } export function getInitialQuotaResetAt(): Date { - return getNextQuotaReset(); + return getNextMonthlyQuotaReset(); } diff --git a/lib/stripe-checkout.ts b/lib/stripe-checkout.ts new file mode 100644 index 0000000..4963562 --- /dev/null +++ b/lib/stripe-checkout.ts @@ -0,0 +1,71 @@ +import type Stripe from "stripe"; +import { STRIPE_PRODUCT_TAX_CODE } from "@/lib/credits"; +import { prisma } from "@/lib/db"; +import { getStripe } from "@/lib/stripe"; + +/** Enable Stripe Tax only when Dashboard registrations are active (STRIPE_AUTOMATIC_TAX=true). */ +export function isStripeAutomaticTaxEnabled(): boolean { + return process.env.STRIPE_AUTOMATIC_TAX === "true"; +} + +/** + * Shared Checkout Session options required/recommended by Stripe for SaaS: + * - client_reference_id for linking + * - automatic_tax (opt-in) + customer_update.address when tax is on + * - tax_code already set on product_data by callers + */ +export function checkoutTaxAndReferenceOptions(userId: string): Partial { + const opts: Partial = { + client_reference_id: userId, + }; + + if (isStripeAutomaticTaxEnabled()) { + opts.automatic_tax = { enabled: true }; + opts.customer_update = { address: "auto", name: "auto" }; + // Collect billing address so tax can be calculated for new/returning customers + opts.billing_address_collection = "required"; + } + + return opts; +} + +/** tax_behavior required on Prices when automatic tax is enabled. */ +export function priceDataTaxFields(): { tax_behavior?: Stripe.Checkout.SessionCreateParams.LineItem.PriceData["tax_behavior"] } { + if (!isStripeAutomaticTaxEnabled()) return {}; + // Exclusive: listed prices are pre-tax; VAT/GST added at checkout + return { tax_behavior: "exclusive" }; +} + +export function productDataWithTaxCode( + name: string, + description: string, +): Stripe.Checkout.SessionCreateParams.LineItem.PriceData.ProductData { + return { + name, + description, + tax_code: STRIPE_PRODUCT_TAX_CODE, + }; +} + +/** Ensure the app user has a Stripe Customer and return its id. */ +export async function ensureStripeCustomer(userId: string, email: string): Promise { + const dbUser = await prisma.user.findUniqueOrThrow({ + where: { id: userId }, + select: { stripeCustomerId: true }, + }); + + if (dbUser.stripeCustomerId) return dbUser.stripeCustomerId; + + const stripe = getStripe(); + const customer = await stripe.customers.create({ + email, + metadata: { userId }, + }); + + await prisma.user.update({ + where: { id: userId }, + data: { stripeCustomerId: customer.id }, + }); + + return customer.id; +} diff --git a/lib/stripe.ts b/lib/stripe.ts new file mode 100644 index 0000000..c3e49c5 --- /dev/null +++ b/lib/stripe.ts @@ -0,0 +1,30 @@ +import Stripe from "stripe"; + +let stripe: Stripe | null = null; + +export function getStripe(): Stripe { + const key = process.env.STRIPE_SECRET_KEY; + if (!key) { + throw new Error("STRIPE_SECRET_KEY is not configured"); + } + if (!stripe) { + stripe = new Stripe(key); + } + return stripe; +} + +export function isStripeConfigured(): boolean { + return Boolean(process.env.STRIPE_SECRET_KEY); +} + +/** + * Bypass Stripe Checkout when: + * - BILLING_DEV_MOCK=true, or + * - development and no STRIPE_SECRET_KEY (so UI still works without stripe listen) + * Set BILLING_DEV_MOCK=false to force real Stripe even without keys (will 503). + */ +export function isBillingDevMock(): boolean { + if (process.env.BILLING_DEV_MOCK === "true") return true; + if (process.env.BILLING_DEV_MOCK === "false") return false; + return process.env.NODE_ENV === "development" && !process.env.STRIPE_SECRET_KEY; +} diff --git a/lib/titles.ts b/lib/titles.ts new file mode 100644 index 0000000..990a574 --- /dev/null +++ b/lib/titles.ts @@ -0,0 +1,45 @@ +import { Plan } from "@prisma/client"; +import { hasProFeatures } from "./edition"; + +export type TitleFields = { + /** YouTube video title */ + title?: string | null; + /** On-video song / track title (art-track layouts) */ + songTitle?: string | null; + artist?: string | null; +}; + +/** Resolve the title sent to YouTube. Pro may omit video title → `${artist} - ${songTitle}`. */ +export function resolveYouTubeTitle(meta: TitleFields, plan: Plan): string { + const videoTitle = meta.title?.trim(); + if (videoTitle) return videoTitle; + + if (hasProFeatures(plan)) { + const artist = meta.artist?.trim(); + const song = meta.songTitle?.trim(); + if (artist && song) return `${artist} - ${song}`; + if (song) return song; + if (artist) return artist; + } + + return ""; +} + +/** Title burned into art-track layout (never the YouTube-only field alone when songTitle set). */ +export function resolveBurnedSongTitle( + meta: TitleFields, + fallback = "Untitled", +): string { + return meta.songTitle?.trim() || fallback; +} + +export function validateYouTubeTitle(meta: TitleFields, plan: Plan): string | null { + const resolved = resolveYouTubeTitle(meta, plan); + if (!resolved) { + if (hasProFeatures(plan)) { + return "Enter a video title, or both artist and song title for the YouTube fallback"; + } + return "Each video must have a video title"; + } + return null; +} diff --git a/lib/types.ts b/lib/types.ts index c52ed11..5b5bb09 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,4 +1,6 @@ import { Privacy } from "@prisma/client"; +import type { LayoutSettings } from "./layout"; +import type { WatermarkSettings } from "./watermark"; export type ItemMetadata = { title: string; @@ -11,7 +13,50 @@ export type ItemMetadata = { madeForKids: boolean; embeddable: boolean; creativeCommons: boolean; + /** Legacy Free toggle default Songs2VID branding when watermark.mode is omitted. */ includeWatermark: boolean; + /** YouTube playlist ID (Pro only). Video is added after upload. */ + playlistId?: string | null; + /** + * Optional per-item cover image path (Pro / perItemImages). + * When omitted, the job-level shared imagePath is used. + */ + imagePath?: string | null; + /** Pro custom branding. Free may only use mode none|default at bottom-right. */ + watermark?: Partial | null; + /** Artist line for art-track layouts (Pro, on-video only). */ + artist?: string | null; + /** Song / track title burned into art-track layouts (Pro, on-video only). */ + songTitle?: string | null; + /** + * Pro art-track layout. Prefer camelCase; snake_case aliases accepted: + * layout_template, blur_amount, text_padding. + */ + layout?: Partial & { + layoutTemplate?: string | null; + layout_template?: string | null; + blur_amount?: number; + blur_opacity?: number; + text_padding?: number; + title_artist_gap?: number; + text_offset_x?: number; + text_offset_y?: number; + } | null; + /** Flat aliases (also accepted). */ + layoutTemplate?: string | null; + layout_template?: string | null; + blurAmount?: number; + blur_amount?: number; + blurOpacity?: number; + blur_opacity?: number; + textPadding?: number; + text_padding?: number; + titleArtistGap?: number; + title_artist_gap?: number; + textOffsetX?: number; + text_offset_x?: number; + textOffsetY?: number; + text_offset_y?: number; }; export type UploadedAudio = { @@ -20,13 +65,22 @@ export type UploadedAudio = { metadata: ItemMetadata; }; +export type CreatePlaylistRequest = { + title: string; + description?: string; + privacy?: "public" | "unlisted" | "private"; +}; + export type CreateJobPayload = { + /** Shared cover for Free / default when items omit imagePath. */ imagePath: string; items: Array<{ audioPath: string; audioFilename: string; metadata: ItemMetadata; }>; + /** Create a new playlist and attach its ID to every item (Pro). */ + createPlaylist?: CreatePlaylistRequest | null; }; export type JobItemResponse = { diff --git a/lib/upload-paths.ts b/lib/upload-paths.ts new file mode 100644 index 0000000..df5a2e3 --- /dev/null +++ b/lib/upload-paths.ts @@ -0,0 +1,47 @@ +import path from "path"; +import { randomBytes } from "crypto"; +import { getUploadDir } from "./storage"; + +/** Allow only safe staging folder names from clients. */ +export function sanitizeUploadSessionKey(raw?: string | null): string { + const cleaned = (raw ?? "").replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 64); + if (cleaned.length >= 8) return cleaned; + return `${Date.now().toString(36)}-${randomBytes(6).toString("hex")}`; +} + +function userUploadRoot(userId: string) { + return path.resolve(getUploadDir(), userId); +} + +function isInsideDir(filePath: string, dir: string) { + const resolvedFile = path.resolve(filePath); + const resolvedDir = path.resolve(dir); + return resolvedFile === resolvedDir || resolvedFile.startsWith(resolvedDir + path.sep); +} + +/** Ensure a path stays under uploads/{userId}/ (blocks traversal & cross-user access). */ +export function assertPathInUserUploads(userId: string, filePath: string): string { + if (!filePath?.trim()) { + throw new Error("Invalid upload path"); + } + + const resolved = path.resolve(filePath); + const root = userUploadRoot(userId); + + if (!isInsideDir(resolved, root)) { + throw new Error("Invalid upload path"); + } + + return resolved; +} + +export function getUserStagingDir(userId: string, sessionKey: string) { + const safeSession = sanitizeUploadSessionKey(sessionKey); + const dir = path.join(userUploadRoot(userId), "staging", safeSession); + // Defense in depth: resolve and re-check + const resolved = path.resolve(dir); + if (!isInsideDir(resolved, userUploadRoot(userId))) { + throw new Error("Invalid upload session"); + } + return resolved; +} diff --git a/lib/watermark.ts b/lib/watermark.ts new file mode 100644 index 0000000..833411c --- /dev/null +++ b/lib/watermark.ts @@ -0,0 +1,192 @@ +/** + * Watermark / branding helpers position math + FFmpeg-safe sanitization. + * Never interpolate unsanitized user text into filter graphs. + */ + +import { + isWatermarkFontKey, + type WatermarkFontKey, +} from "./fonts"; + +export const WATERMARK_POSITIONS = [ + "top-left", + "top-right", + "bottom-left", + "bottom-right", + "center", +] as const; + +export type WatermarkPosition = (typeof WATERMARK_POSITIONS)[number]; + +export const WATERMARK_MODES = ["none", "default", "text", "logo"] as const; +export type WatermarkMode = (typeof WATERMARK_MODES)[number]; + +export type WatermarkSettings = { + mode: WatermarkMode; + text?: string | null; + logoPath?: string | null; + position: WatermarkPosition; + /** Pixel offset from the chosen anchor (0–200). */ + offsetX: number; + offsetY: number; + /** + * Typography (Pro / text mode). + * `system` = FFmpeg default; curated keys map to assets/fonts; `custom` uses fontPath. + */ + fontKey?: WatermarkFontKey; + /** Absolute/staging path to uploaded .ttf/.otf when fontKey === "custom". */ + fontPath?: string | null; +}; + +export const DEFAULT_WATERMARK: WatermarkSettings = { + mode: "default", + text: null, + logoPath: null, + position: "bottom-right", + offsetX: 20, + offsetY: 20, + fontKey: "system", + fontPath: null, +}; + +export const WATERMARK_TEXT_MAX = 80; +export const WATERMARK_OFFSET_MIN = 0; +export const WATERMARK_OFFSET_MAX = 200; + +export function isWatermarkPosition(v: unknown): v is WatermarkPosition { + return typeof v === "string" && (WATERMARK_POSITIONS as readonly string[]).includes(v); +} + +export function isWatermarkMode(v: unknown): v is WatermarkMode { + return typeof v === "string" && (WATERMARK_MODES as readonly string[]).includes(v); +} + +export function clampOffset(n: unknown, fallback = 20): number { + const v = typeof n === "number" ? n : Number(n); + if (!Number.isFinite(v)) return fallback; + return Math.max(WATERMARK_OFFSET_MIN, Math.min(WATERMARK_OFFSET_MAX, Math.round(v))); +} + +/** + * Escape user text for FFmpeg drawtext. + * Strips control chars; escapes \, :, ', %, and [. + */ +export function sanitizeDrawtext(raw: string): string { + return raw + .slice(0, WATERMARK_TEXT_MAX) + .replace(/[\u0000-\u001f\u007f]/g, "") + .replace(/\\/g, "\\\\") + .replace(/:/g, "\\:") + .replace(/'/g, "\\'") + .replace(/%/g, "%%") + .replace(/\[/g, "\\["); +} + +/** FFmpeg overlay=x:y expressions for a scaled watermark layer `[wm]`. */ +export function overlayXy( + position: WatermarkPosition, + offsetX: number, + offsetY: number, +): { x: string; y: string } { + const ox = clampOffset(offsetX); + const oy = clampOffset(offsetY); + switch (position) { + case "top-left": + return { x: String(ox), y: String(oy) }; + case "top-right": + return { x: `W-w-${ox}`, y: String(oy) }; + case "bottom-left": + return { x: String(ox), y: `H-h-${oy}` }; + case "center": + return { x: `(W-w)/2+${ox}`, y: `(H-h)/2+${oy}` }; + case "bottom-right": + default: + return { x: `W-w-${ox}`, y: `H-h-${oy}` }; + } +} + +/** drawtext x/y for text watermarks. */ +export function drawtextXy( + position: WatermarkPosition, + offsetX: number, + offsetY: number, +): { x: string; y: string } { + const ox = clampOffset(offsetX); + const oy = clampOffset(offsetY); + switch (position) { + case "top-left": + return { x: String(ox), y: String(oy) }; + case "top-right": + return { x: `w-text_w-${ox}`, y: String(oy) }; + case "bottom-left": + return { x: String(ox), y: `h-th-${oy}` }; + case "center": + return { x: `(w-text_w)/2+${ox}`, y: `(h-th)/2+${oy}` }; + case "bottom-right": + default: + return { x: `w-text_w-${ox}`, y: `h-th-${oy}` }; + } +} + +/** + * Build a drawtext filter segment (without leading comma). + * `fontfileEscaped` must already be sanitized via sanitizeFontfileForFilter. + */ +export function buildDrawtextFilter(opts: { + text: string; + fontSize: number; + fontColor?: string; + position: WatermarkPosition; + offsetX: number; + offsetY: number; + fontfileEscaped?: string | null; +}): string { + const text = sanitizeDrawtext(opts.text); + const { x, y } = drawtextXy(opts.position, opts.offsetX, opts.offsetY); + const color = opts.fontColor ?? "white@0.9"; + const fontPart = opts.fontfileEscaped + ? `:fontfile='${opts.fontfileEscaped}'` + : ""; + return `drawtext=text='${text}'${fontPart}:fontsize=${opts.fontSize}:fontcolor=${color}:x=${x}:y=${y}`; +} + +export function normalizeWatermarkSettings( + input: Partial | null | undefined, + includeWatermarkFallback: boolean, +): WatermarkSettings { + if (!input) { + return { + ...DEFAULT_WATERMARK, + mode: includeWatermarkFallback ? "default" : "none", + }; + } + const mode = isWatermarkMode(input.mode) + ? input.mode + : includeWatermarkFallback + ? "default" + : "none"; + const fontKey = isWatermarkFontKey(input.fontKey) ? input.fontKey : "system"; + return { + mode, + text: typeof input.text === "string" ? input.text.slice(0, WATERMARK_TEXT_MAX) : null, + logoPath: typeof input.logoPath === "string" ? input.logoPath : null, + position: isWatermarkPosition(input.position) ? input.position : "bottom-right", + offsetX: clampOffset(input.offsetX, 20), + offsetY: clampOffset(input.offsetY, 20), + fontKey, + fontPath: typeof input.fontPath === "string" ? input.fontPath : null, + }; +} + +/** True when settings go beyond Free-tier default branding toggle. */ +export function requiresCustomWatermarkEntitlement(settings: WatermarkSettings): boolean { + if (settings.mode === "text" || settings.mode === "logo") return true; + if (settings.mode === "none") return false; + if (settings.position !== "bottom-right") return true; + if (settings.offsetX !== 20 || settings.offsetY !== 20) return true; + if (settings.fontKey && settings.fontKey !== "system") return true; + if (settings.fontPath) return true; + return false; +} + +export const PREMIUM_REQUIRED_CODE = "PREMIUM_REQUIRED" as const; diff --git a/lib/youtube/errors.ts b/lib/youtube/errors.ts new file mode 100644 index 0000000..985aaad --- /dev/null +++ b/lib/youtube/errors.ts @@ -0,0 +1,57 @@ +/** Extract a readable message from googleapis / Gaxios errors. */ +export function extractYouTubeErrorMessage(err: unknown): string { + if (!err || typeof err !== "object") { + return typeof err === "string" ? err : "Unknown YouTube error"; + } + + const anyErr = err as { + message?: string; + errors?: Array<{ message?: string; reason?: string }>; + response?: { + data?: { + error?: { + message?: string; + errors?: Array<{ message?: string; reason?: string }>; + }; + }; + }; + }; + + const nested = + anyErr.response?.data?.error?.errors?.[0]?.message || + anyErr.response?.data?.error?.message || + anyErr.errors?.[0]?.message; + + if (nested?.trim()) return nested.trim(); + if (anyErr.message?.trim()) return anyErr.message.trim(); + return "Unknown YouTube error"; +} + +export function isYouTubeUploadLimitError(message: string) { + const lower = message.toLowerCase(); + return ( + lower.includes("exceeded the number of videos") || + lower.includes("uploadLimitExceeded") || + lower.includes("upload limit") || + (lower.includes("quota") && lower.includes("exceeded") && lower.includes("youtube")) + ); +} + +export const YOUTUBE_UPLOAD_LIMIT_USER_MESSAGE = + "YouTube upload limit reached: this Google/YouTube account has exceeded the number of videos " + + "it may upload right now. This is YouTube's own daily limit, not your Songs2VID plan quota. " + + "Try again later (often after 24 hours) or use a different YouTube channel."; + +/** User-facing message for the dashboard (distinct from Songs2VID plan quota). */ +export function formatYouTubeErrorForUser(err: unknown): string { + const raw = extractYouTubeErrorMessage(err); + if (isYouTubeUploadLimitError(raw)) return YOUTUBE_UPLOAD_LIMIT_USER_MESSAGE; + return raw; +} + +/** Normalize a stored job-item error string for display in the UI. */ +export function displayJobItemError(message: string | null | undefined): string | null { + if (!message?.trim()) return null; + if (isYouTubeUploadLimitError(message)) return YOUTUBE_UPLOAD_LIMIT_USER_MESSAGE; + return message.trim(); +} diff --git a/lib/youtube/upload.ts b/lib/youtube/upload.ts index f9b03e6..8d85bc0 100644 --- a/lib/youtube/upload.ts +++ b/lib/youtube/upload.ts @@ -2,7 +2,9 @@ import { google } from "googleapis"; import fs from "fs"; import { prisma } from "../db"; import { parseTags } from "../constants"; +import { decryptSecret, encryptSecret } from "../crypto/secrets"; import type { JobItem } from "@prisma/client"; +import { formatYouTubeErrorForUser } from "./errors"; async function refreshAccessToken(refreshToken: string) { const oauth2Client = new google.auth.OAuth2( @@ -25,11 +27,12 @@ export async function getYouTubeClient(userId: string) { process.env.GOOGLE_CLIENT_SECRET, ); - let accessToken = connection.accessToken; + let accessToken = decryptSecret(connection.accessToken); + const refreshToken = decryptSecret(connection.refreshToken); let expiresAt = connection.expiresAt; if (new Date() >= expiresAt) { - const credentials = await refreshAccessToken(connection.refreshToken); + const credentials = await refreshAccessToken(refreshToken); if (!credentials.access_token) { throw new Error("Failed to refresh YouTube access token"); } @@ -40,13 +43,18 @@ export async function getYouTubeClient(userId: string) { await prisma.youTubeConnection.update({ where: { userId }, - data: { accessToken, expiresAt }, + data: { + accessToken: encryptSecret(accessToken), + // Re-encrypt refresh token if it was still plaintext legacy + refreshToken: encryptSecret(refreshToken), + expiresAt, + }, }); } oauth2Client.setCredentials({ access_token: accessToken, - refresh_token: connection.refreshToken, + refresh_token: refreshToken, }); return google.youtube({ version: "v3", auth: oauth2Client }); @@ -57,41 +65,153 @@ export async function uploadToYouTube( videoPath: string, item: JobItem, ): Promise { + try { + const youtube = await getYouTubeClient(userId); + const tags = parseTags(item.tags); + + const privacyStatus = + item.privacy === "PUBLIC" + ? "public" + : item.privacy === "PRIVATE" + ? "private" + : "unlisted"; + + const response = await youtube.videos.insert({ + part: ["snippet", "status"], + notifySubscribers: item.notifySubscribers, + requestBody: { + snippet: { + title: item.title, + description: item.description, + tags: tags.length > 0 ? tags : undefined, + categoryId: item.categoryId, + }, + status: { + privacyStatus, + embeddable: item.embeddable, + selfDeclaredMadeForKids: item.madeForKids, + license: item.creativeCommons ? "creativeCommon" : "youtube", + }, + }, + media: { + body: fs.createReadStream(videoPath), + }, + }); + + const videoId = response.data.id; + if (!videoId) throw new Error("YouTube upload succeeded but no video ID returned"); + + if (item.playlistId) { + try { + await addVideoToPlaylist(youtube, item.playlistId, videoId); + } catch (playlistErr) { + throw new Error( + `Video uploaded (${videoId}) but failed to add to playlist: ${formatYouTubeErrorForUser(playlistErr)}`, + ); + } + } + + return videoId; + } catch (err) { + if (err instanceof Error && err.message.startsWith("Video uploaded (")) { + throw err; + } + throw new Error(formatYouTubeErrorForUser(err)); + } +} + +export type PlaylistPrivacy = "public" | "unlisted" | "private"; + +export type CreatePlaylistInput = { + title: string; + description?: string; + privacy?: PlaylistPrivacy; +}; + +function toPlaylistPrivacyStatus(privacy?: PlaylistPrivacy) { + if (privacy === "public") return "public"; + if (privacy === "unlisted") return "unlisted"; + return "private"; +} + +export async function listYouTubePlaylists(userId: string) { const youtube = await getYouTubeClient(userId); - const tags = parseTags(item.tags); + const playlists: Array<{ id: string; title: string; itemCount: number }> = []; + let pageToken: string | undefined; - const privacyStatus = - item.privacy === "PUBLIC" - ? "public" - : item.privacy === "PRIVATE" - ? "private" - : "unlisted"; + do { + const response = await youtube.playlists.list({ + part: ["snippet", "contentDetails"], + mine: true, + maxResults: 50, + pageToken, + }); - const response = await youtube.videos.insert({ - part: ["snippet", "status"], - notifySubscribers: item.notifySubscribers, + for (const playlist of response.data.items ?? []) { + if (!playlist.id || !playlist.snippet?.title) continue; + playlists.push({ + id: playlist.id, + title: playlist.snippet.title, + itemCount: playlist.contentDetails?.itemCount ?? 0, + }); + } + + pageToken = response.data.nextPageToken ?? undefined; + } while (pageToken); + + return playlists; +} + +export async function createYouTubePlaylist(userId: string, input: CreatePlaylistInput) { + const title = input.title?.trim(); + if (!title) throw new Error("Playlist title is required"); + + try { + const youtube = await getYouTubeClient(userId); + const response = await youtube.playlists.insert({ + part: ["snippet", "status"], + requestBody: { + snippet: { + title, + description: input.description?.trim() || "", + }, + status: { + privacyStatus: toPlaylistPrivacyStatus(input.privacy), + }, + }, + }); + + const id = response.data.id; + if (!id) throw new Error("YouTube created the playlist but returned no ID"); + + return { + id, + title: response.data.snippet?.title || title, + itemCount: 0, + privacy: input.privacy ?? "private", + }; + } catch (err) { + throw new Error(formatYouTubeErrorForUser(err)); + } +} + +async function addVideoToPlaylist( + youtube: Awaited>, + playlistId: string, + videoId: string, +) { + await youtube.playlistItems.insert({ + part: ["snippet"], requestBody: { snippet: { - title: item.title, - description: item.description, - tags: tags.length > 0 ? tags : undefined, - categoryId: item.categoryId, + playlistId, + resourceId: { + kind: "youtube#video", + videoId, + }, }, - status: { - privacyStatus, - embeddable: item.embeddable, - selfDeclaredMadeForKids: item.madeForKids, - licenseId: item.creativeCommons ? "creativeCommon" : "youtube", - }, - }, - media: { - body: fs.createReadStream(videoPath), }, }); - - const videoId = response.data.id; - if (!videoId) throw new Error("YouTube upload succeeded but no video ID returned"); - return videoId; } export async function fetchYouTubeChannel(accessToken: string, refreshToken: string) { diff --git a/next-env.d.ts b/next-env.d.ts index 6080add..830fb59 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,2 +1,6 @@ /// /// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/next.config.ts b/next.config.ts index 23a6fdc..574e1c0 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,11 +1,42 @@ import type { NextConfig } from "next"; +function resolveDocsUrl(): string { + if (process.env.NEXT_PUBLIC_DOCS_URL?.trim()) { + return process.env.NEXT_PUBLIC_DOCS_URL.replace(/\/$/, ""); + } + const auth = process.env.NEXTAUTH_URL ?? ""; + if (/localhost|127\.0\.0\.1/i.test(auth)) { + return "http://localhost:3001"; + } + return "https://docs.songs2vid.com"; +} + +const apiDocsUrl = `${resolveDocsUrl()}/docs/api/overview`; + const nextConfig: NextConfig = { + output: "standalone", + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "images.unsplash.com", + }, + ], + }, experimental: { serverActions: { bodySizeLimit: "32mb", }, }, + async redirects() { + return [ + { + source: "/dashboard/api-docs", + destination: apiDocsUrl, + permanent: false, + }, + ]; + }, }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 4ab934c..3ee283a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,27 +1,32 @@ { - "name": "s2yt", + "name": "songs2vid", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "s2yt", + "name": "songs2vid", "version": "0.1.0", "dependencies": { "@auth/prisma-adapter": "^2.7.4", "@prisma/client": "^6.1.0", + "@tailwindcss/typography": "^0.5.20", "bullmq": "^5.34.5", + "ffmpeg-static": "^5.3.0", "googleapis": "^144.0.0", - "ioredis": "^5.4.2", + "ioredis": "^5.11.1", + "music-metadata": "^11.13.0", "next": "^15.1.3", "next-auth": "^4.24.11", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "stripe": "^22.3.2" }, "devDependencies": { "@types/node": "^22.10.2", "@types/react": "^19.0.2", "@types/react-dom": "^19.0.2", + "concurrently": "^9.2.0", "eslint": "^9.17.0", "eslint-config-next": "^15.1.3", "postcss": "^8.4.49", @@ -35,7 +40,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -96,18 +100,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/@auth/core/node_modules/preact": { - "version": "10.11.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", - "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", - "license": "MIT", - "optional": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, "node_modules/@auth/core/node_modules/preact-render-to-string": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz", @@ -198,34 +190,35 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, + "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", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/@emnapi/runtime": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", - "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "node_modules/@derhuerst/http-basic": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.4.tgz", + "integrity": "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw==", "license": "MIT", - "optional": true, - "peer": true, "dependencies": { - "tslib": "^2.4.0" + "caseless": "^0.12.0", + "concat-stream": "^2.0.0", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, "license": "MIT", "optional": true, @@ -1361,7 +1354,6 @@ "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", @@ -1372,7 +1364,6 @@ "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" @@ -1382,14 +1373,12 @@ "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", @@ -1641,7 +1630,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -1655,7 +1643,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -1665,7 +1652,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -1810,6 +1796,54 @@ "tslib": "^2.8.0" } }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.20.tgz", + "integrity": "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" + } + }, + "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "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/@tybys/wasm-util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", @@ -1853,8 +1887,9 @@ "version": "22.20.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", - "dev": true, + "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~6.21.0" } @@ -2434,6 +2469,18 @@ "node": ">=14.0.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", @@ -2445,6 +2492,17 @@ "tslib": "^2.4.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", @@ -2537,6 +2595,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2557,14 +2625,12 @@ "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/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -2578,7 +2644,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -2851,7 +2916,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2875,7 +2939,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -2890,6 +2953,12 @@ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, "node_modules/bullmq": { "version": "5.80.2", "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.80.2.tgz", @@ -3036,7 +3105,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -3062,6 +3130,12 @@ ], "license": "CC-BY-4.0" }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3111,6 +3185,21 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/cluster-key-slot": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.1.tgz", @@ -3144,7 +3233,6 @@ "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" @@ -3157,6 +3245,62 @@ "dev": true, "license": "MIT" }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concurrently": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.4.tgz", + "integrity": "sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.9.0", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/confbox": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", @@ -3174,6 +3318,19 @@ "node": "^14.18.0 || >=16.10.0" } }, + "node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -3214,7 +3371,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -3398,14 +3554,12 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, "license": "MIT" }, "node_modules/doctrine": { @@ -3485,6 +3639,15 @@ "node": ">=14" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/es-abstract": { "version": "1.24.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", @@ -3685,7 +3848,7 @@ "version": "0.28.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, + "devOptional": true, "hasInstallScript": true, "license": "MIT", "bin": { @@ -3723,6 +3886,16 @@ "@esbuild/win32-x64": "0.28.1" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3916,6 +4089,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -4235,12 +4409,52 @@ "version": "1.20.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/ffmpeg-static": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.3.0.tgz", + "integrity": "sha512-H+K6sW6TiIX6VGend0KQwthe+kaceeH/luE8dIZyOP35ik7ahYojDuqlTV1bOrtEwl01sy2HFNGQfi5IDJvotg==", + "hasInstallScript": true, + "license": "GPL-3.0-or-later", + "dependencies": { + "@derhuerst/http-basic": "^8.2.0", + "env-paths": "^2.2.0", + "https-proxy-agent": "^5.0.0", + "progress": "^2.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/ffmpeg-static/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ffmpeg-static/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -4254,11 +4468,28 @@ "node": ">=16.0.0" } }, + "node_modules/file-type": { + "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -4325,7 +4556,6 @@ "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, @@ -4419,6 +4649,16 @@ "node": ">= 0.4" } }, + "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==", + "dev": true, + "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", @@ -4509,7 +4749,6 @@ "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" @@ -4721,6 +4960,21 @@ "node": ">= 0.4" } }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "license": "MIT", + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "license": "MIT" + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -4734,6 +4988,26 @@ "node": ">= 14" } }, + "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", @@ -4771,6 +5045,12 @@ "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/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -4866,7 +5146,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -4919,7 +5198,6 @@ "version": "2.16.2", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.3" @@ -4986,7 +5264,6 @@ "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" @@ -5008,6 +5285,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-function": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", @@ -5032,7 +5319,6 @@ "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" @@ -5071,7 +5357,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -5461,7 +5746,6 @@ "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" @@ -5474,7 +5758,6 @@ "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/locate-path": { @@ -5555,11 +5838,23 @@ "node": ">= 0.4" } }, + "node_modules/media-typer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-2.0.0.tgz", + "integrity": "sha512-kOy3OxT2HH39N70UnKgu4NWDZjLOz8W/mfyvniHjRH/DrL3f2pOfvWQ4p60offbbtDAnXWp0v9LfMIqMec269Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -5569,7 +5864,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -5639,11 +5933,41 @@ "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" } }, + "node_modules/music-metadata": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.13.0.tgz", + "integrity": "sha512-uXRaov9dfjSpQufXIU7sMxVZnh+FilCQv2mXn+K5EJ/decP3dTWrgvPYa5r6MtRbieNSCE708Da4J0u1UGfQIw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.2", + "@tokenizer/token": "^0.3.0", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "file-type": "^21.3.4", + "media-typer": "^2.0.0", + "strtok3": "^10.3.5", + "token-types": "^6.1.2", + "uint8array-extras": "^1.5.0", + "win-guid": "^0.2.1" + }, + "engines": { + "node": ">=18" + } + }, "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", @@ -5895,7 +6219,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5946,7 +6269,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6185,6 +6507,11 @@ "node": ">=6" } }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6209,7 +6536,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, "license": "MIT" }, "node_modules/pathe": { @@ -6236,7 +6562,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -6249,7 +6574,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6259,7 +6583,6 @@ "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" @@ -6291,7 +6614,6 @@ "version": "8.5.17", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.17.tgz", "integrity": "sha512-J7EF+8X+CzRPaJPOv9Ck2wNWJvGnnl3PcNPAdGg6GTLjyVpyQ0yATMSXRFRV01BviT/9Gwuc3rjEyJbDJG9a4w==", - "dev": true, "funding": [ { "type": "opencollective", @@ -6321,7 +6643,6 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -6339,7 +6660,6 @@ "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -6361,7 +6681,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -6387,7 +6706,6 @@ "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", @@ -6430,7 +6748,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -6456,7 +6773,6 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -6470,7 +6786,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, "license": "MIT" }, "node_modules/preact": { @@ -6539,6 +6854,15 @@ } } }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -6598,7 +6922,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -6660,12 +6983,25 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, "license": "MIT", "dependencies": { "pify": "^2.3.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", @@ -6745,6 +7081,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "2.0.0-next.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", @@ -6793,7 +7139,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -6804,7 +7149,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -6824,6 +7168,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", @@ -7034,6 +7388,19 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.9.0.tgz", + "integrity": "sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", @@ -7142,6 +7509,37 @@ "node": ">= 0.4" } }, + "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-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/string.prototype.includes": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", @@ -7256,6 +7654,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -7279,6 +7690,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stripe": { + "version": "22.3.2", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-22.3.2.tgz", + "integrity": "sha512-O13QOvgEIQvDlTy6Ubb5kB980wpbhmoZNsgCXKILjCMZS67f+bW+6w99k3gnSi/N1lkryoj1WYdpGT5Wc5edjg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "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/styled-jsx": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", @@ -7306,7 +7750,6 @@ "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", @@ -7342,7 +7785,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7355,8 +7797,8 @@ "version": "3.4.19", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", - "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -7393,7 +7835,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -7418,7 +7859,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -7431,7 +7871,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -7448,7 +7887,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -7461,7 +7899,6 @@ "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", - "dev": true, "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -7471,7 +7908,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -7481,7 +7917,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -7494,7 +7929,6 @@ "version": "1.22.12", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -7516,7 +7950,6 @@ "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" @@ -7526,7 +7959,6 @@ "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" @@ -7549,7 +7981,6 @@ "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -7566,7 +7997,6 @@ "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" @@ -7584,7 +8014,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", - "dev": true, "license": "MIT", "peer": true, "engines": { @@ -7598,7 +8027,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -7607,12 +8035,40 @@ "node": ">=8.0" } }, + "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/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -7630,7 +8086,6 @@ "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/tsconfig-paths": { @@ -7656,7 +8111,7 @@ "version": "4.23.0", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.0.tgz", "integrity": "sha512-eUdUIaCr963q2h5u3+QwvYp0+eqPvn+egeqZUm0hwERCqqx1E3kK5ehbGCvqSE5MQAULr67ww0cA3jKc3YkM1w==", - "dev": true, + "devOptional": true, "license": "MIT", "peer": true, "dependencies": { @@ -7763,6 +8218,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -7778,6 +8239,18 @@ "node": ">=14.17" } }, + "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/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -7801,7 +8274,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unrs-resolver": { @@ -7862,7 +8335,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, "license": "MIT" }, "node_modules/uuid": { @@ -8000,6 +8472,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/win-guid": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/win-guid/-/win-guid-0.2.1.tgz", + "integrity": "sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==", + "license": "MIT" + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -8010,12 +8488,69 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "license": "ISC" }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "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==", + "dev": true, + "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", diff --git a/package.json b/package.json index 63dd58e..93ba4c3 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,41 @@ { - "name": "s2yt", + "name": "songs2vid", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", + "dev:all": "concurrently -n web,worker,docs -c blue,green,magenta \"npm run dev\" \"npm run worker\" \"npm run docs:dev\"", "build": "next build", "start": "next start", "lint": "next lint", - "worker": "tsx worker/index.ts", + "worker": "tsx --env-file=.env worker/index.ts", "db:generate": "prisma generate", "db:migrate": "prisma migrate dev", - "db:push": "prisma db push" + "db:push": "prisma db push", + "docs:dev": "npm run start --prefix website -- --port 3001", + "docs:build": "npm run build --prefix website", + "docs:serve": "npm run serve --prefix website -- --port 3001" }, "dependencies": { "@auth/prisma-adapter": "^2.7.4", "@prisma/client": "^6.1.0", + "@tailwindcss/typography": "^0.5.20", "bullmq": "^5.34.5", + "ffmpeg-static": "^5.3.0", "googleapis": "^144.0.0", - "ioredis": "^5.4.2", + "ioredis": "^5.11.1", + "music-metadata": "^11.13.0", "next": "^15.1.3", "next-auth": "^4.24.11", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "stripe": "^22.3.2" }, "devDependencies": { "@types/node": "^22.10.2", "@types/react": "^19.0.2", "@types/react-dom": "^19.0.2", + "concurrently": "^9.2.0", "eslint": "^9.17.0", "eslint-config-next": "^15.1.3", "postcss": "^8.4.49", diff --git a/prisma/migrations/20260714135015_init/migration.sql b/prisma/migrations/20260714135015_init/migration.sql new file mode 100644 index 0000000..9225473 --- /dev/null +++ b/prisma/migrations/20260714135015_init/migration.sql @@ -0,0 +1,90 @@ +-- CreateEnum +CREATE TYPE "Plan" AS ENUM ('FREE', 'PREMIUM'); + +-- CreateEnum +CREATE TYPE "Privacy" AS ENUM ('PUBLIC', 'PRIVATE', 'UNLISTED'); + +-- CreateEnum +CREATE TYPE "JobStatus" AS ENUM ('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'PARTIAL'); + +-- CreateEnum +CREATE TYPE "JobItemStatus" AS ENUM ('PENDING', 'ENCODING', 'UPLOADING', 'COMPLETED', 'FAILED'); + +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "image" TEXT, + "plan" "Plan" NOT NULL DEFAULT 'FREE', + "videosUsed" INTEGER NOT NULL DEFAULT 0, + "quotaResetAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "YouTubeConnection" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "accessToken" TEXT NOT NULL, + "refreshToken" TEXT NOT NULL, + "expiresAt" TIMESTAMP(3) NOT NULL, + "channelId" TEXT NOT NULL, + "channelTitle" TEXT NOT NULL, + + CONSTRAINT "YouTubeConnection_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Job" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "status" "JobStatus" NOT NULL DEFAULT 'PENDING', + "imagePath" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "completedAt" TIMESTAMP(3), + + CONSTRAINT "Job_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "JobItem" ( + "id" TEXT NOT NULL, + "jobId" TEXT NOT NULL, + "audioPath" TEXT NOT NULL, + "audioFilename" TEXT NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT NOT NULL DEFAULT '', + "tags" TEXT NOT NULL DEFAULT '', + "privacy" "Privacy" NOT NULL DEFAULT 'PUBLIC', + "categoryId" TEXT NOT NULL DEFAULT '10', + "resolution" TEXT NOT NULL DEFAULT '1280x720', + "notifySubscribers" BOOLEAN NOT NULL DEFAULT true, + "madeForKids" BOOLEAN NOT NULL DEFAULT false, + "embeddable" BOOLEAN NOT NULL DEFAULT true, + "creativeCommons" BOOLEAN NOT NULL DEFAULT false, + "includeWatermark" BOOLEAN NOT NULL DEFAULT true, + "status" "JobItemStatus" NOT NULL DEFAULT 'PENDING', + "outputPath" TEXT, + "youtubeVideoId" TEXT, + "error" TEXT, + + CONSTRAINT "JobItem_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "YouTubeConnection_userId_key" ON "YouTubeConnection"("userId"); + +-- AddForeignKey +ALTER TABLE "YouTubeConnection" ADD CONSTRAINT "YouTubeConnection_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Job" ADD CONSTRAINT "Job_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "JobItem" ADD CONSTRAINT "JobItem_jobId_fkey" FOREIGN KEY ("jobId") REFERENCES "Job"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20260714182648_add_billing_fields/migration.sql b/prisma/migrations/20260714182648_add_billing_fields/migration.sql new file mode 100644 index 0000000..78865f2 --- /dev/null +++ b/prisma/migrations/20260714182648_add_billing_fields/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "cardLast4" TEXT, +ADD COLUMN "subscribedAt" TIMESTAMP(3); diff --git a/prisma/migrations/20260714185235_add_quota_extension_requests/migration.sql b/prisma/migrations/20260714185235_add_quota_extension_requests/migration.sql new file mode 100644 index 0000000..b0e85da --- /dev/null +++ b/prisma/migrations/20260714185235_add_quota_extension_requests/migration.sql @@ -0,0 +1,21 @@ +-- CreateEnum +CREATE TYPE "QuotaExtensionRequestStatus" AS ENUM ('PENDING', 'APPROVED', 'REJECTED'); + +-- AlterTable +ALTER TABLE "User" ADD COLUMN "bonusQuota" INTEGER NOT NULL DEFAULT 0; + +-- CreateTable +CREATE TABLE "QuotaExtensionRequest" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "status" "QuotaExtensionRequestStatus" NOT NULL DEFAULT 'PENDING', + "message" TEXT NOT NULL DEFAULT '', + "requestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "processedAt" TIMESTAMP(3), + "adminNote" TEXT, + + CONSTRAINT "QuotaExtensionRequest_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "QuotaExtensionRequest" ADD CONSTRAINT "QuotaExtensionRequest_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/20260715010000_add_api_key_fields/migration.sql b/prisma/migrations/20260715010000_add_api_key_fields/migration.sql new file mode 100644 index 0000000..203bb60 --- /dev/null +++ b/prisma/migrations/20260715010000_add_api_key_fields/migration.sql @@ -0,0 +1,6 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "apiKeyHash" TEXT, +ADD COLUMN "apiKeyPrefix" TEXT; + +-- CreateIndex +CREATE UNIQUE INDEX "User_apiKeyHash_key" ON "User"("apiKeyHash"); diff --git a/prisma/migrations/20260716010000_add_playlist_id/migration.sql b/prisma/migrations/20260716010000_add_playlist_id/migration.sql new file mode 100644 index 0000000..399d1a5 --- /dev/null +++ b/prisma/migrations/20260716010000_add_playlist_id/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "JobItem" ADD COLUMN "playlistId" TEXT; diff --git a/prisma/migrations/20260716023000_api_rate_limit_bonus/migration.sql b/prisma/migrations/20260716023000_api_rate_limit_bonus/migration.sql new file mode 100644 index 0000000..1e99c73 --- /dev/null +++ b/prisma/migrations/20260716023000_api_rate_limit_bonus/migration.sql @@ -0,0 +1,8 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "apiRateLimitBonus" INTEGER NOT NULL DEFAULT 0; + +-- CreateEnum +CREATE TYPE "QuotaExtensionKind" AS ENUM ('VIDEO_QUOTA', 'API_RATE_LIMIT'); + +-- AlterTable +ALTER TABLE "QuotaExtensionRequest" ADD COLUMN "kind" "QuotaExtensionKind" NOT NULL DEFAULT 'VIDEO_QUOTA'; diff --git a/prisma/migrations/20260727160000_add_song_title/migration.sql b/prisma/migrations/20260727160000_add_song_title/migration.sql new file mode 100644 index 0000000..f386b3b --- /dev/null +++ b/prisma/migrations/20260727160000_add_song_title/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "JobItem" ADD COLUMN "songTitle" TEXT; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..044d57c --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7df73f0..b55304b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -34,17 +34,82 @@ enum JobItemStatus { FAILED } +enum QuotaExtensionRequestStatus { + PENDING + APPROVED + REJECTED +} + +enum QuotaExtensionKind { + VIDEO_QUOTA + API_RATE_LIMIT +} + model User { - id String @id @default(cuid()) - email String @unique - name String? - image String? - plan Plan @default(FREE) - videosUsed Int @default(0) - quotaResetAt DateTime - youtubeConnection YouTubeConnection? - jobs Job[] - createdAt DateTime @default(now()) + id String @id @default(cuid()) + email String @unique + name String? + image String? + /// FREE = free tier; PREMIUM = Pro (€5/mo, formerly starter_5eur) + plan Plan @default(FREE) + /// Credits consumed in the current billing cycle (credits_used) + videosUsed Int @default(0) + /// Monthly allocation for the current cycle (10 free / 50 pro) + monthlyCredits Int @default(10) + quotaResetAt DateTime + cardLast4 String? + subscribedAt DateTime? + bonusQuota Int @default(0) + apiRateLimitBonus Int @default(0) + /// Purchased extras that never expire (maps to legacy "videoCredits" column) + extraCredits Int @default(0) @map("videoCredits") + /// Free-tier one-time +15 top-up already purchased + freeTopUpPurchased Boolean @default(false) + stripeCustomerId String? + stripeSubscriptionId String? + apiKeyHash String? @unique + apiKeyPrefix String? + youtubeConnection YouTubeConnection? + jobs Job[] + quotaExtensionRequests QuotaExtensionRequest[] + creditPurchases CreditPurchase[] + createdAt DateTime @default(now()) +} + +enum CreditPurchaseStatus { + PENDING + COMPLETED + FAILED +} + +model CreditPurchase { + id String @id @default(cuid()) + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + credits Int + amountCents Int + status CreditPurchaseStatus @default(PENDING) + stripeSessionId String? @unique + stripePaymentIntentId String? + createdAt DateTime @default(now()) + completedAt DateTime? +} + +enum JobItemBilling { + QUOTA + CREDIT +} + +model QuotaExtensionRequest { + id String @id @default(cuid()) + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + kind QuotaExtensionKind @default(VIDEO_QUOTA) + status QuotaExtensionRequestStatus @default(PENDING) + message String @default("") + requestedAt DateTime @default(now()) + processedAt DateTime? + adminNote String? } model YouTubeConnection { @@ -86,6 +151,39 @@ model JobItem { embeddable Boolean @default(true) creativeCommons Boolean @default(false) includeWatermark Boolean @default(true) + /// Optional per-item cover (Pro). Falls back to Job.imagePath when null. + itemImagePath String? + /// none | default | text | logo custom modes require Pro + watermarkMode String @default("default") + watermarkText String? + watermarkLogoPath String? + /// curated key | custom | system + watermarkFontKey String? + /// uploaded .ttf/.otf when fontKey=custom + watermarkFontPath String? + /// top-left | top-right | bottom-left | bottom-right | center + watermarkPosition String @default("bottom-right") + watermarkOffsetX Int @default(20) + watermarkOffsetY Int @default(20) + /// Optional artist line for art-track layouts (Pro, on-video only) + artist String? + /// Song title burned into art-track layouts (Pro, on-video only) + songTitle String? + /// COVER_LEFT_TEXT_RIGHT | COVER_TOP_TEXT_BOTTOM | COVER_RIGHT_TEXT_LEFT | CENTERED_COMPACT | null=classic + layoutTemplate String? + /// 0–100 Gaussian / boxblur intensity (Pro art-track) + blurAmount Int @default(55) + /// 0–100 visibility of blurred fill vs black + blurOpacity Int @default(100) + /// Padding around cover + text in art-track layouts + textPadding Int @default(48) + /// Extra gap between title and artist lines (px) + titleArtistGap Int @default(10) + /// Fine-tune text block within template (-120..120) + textOffsetX Int @default(0) + textOffsetY Int @default(0) + playlistId String? + billingSource JobItemBilling @default(QUOTA) status JobItemStatus @default(PENDING) outputPath String? youtubeVideoId String? diff --git a/public/bg-video.mp4 b/public/bg-video.mp4 new file mode 100644 index 0000000..4d39ad2 Binary files /dev/null and b/public/bg-video.mp4 differ diff --git a/public/brands/docker.svg b/public/brands/docker.svg new file mode 100644 index 0000000..bf283fc --- /dev/null +++ b/public/brands/docker.svg @@ -0,0 +1 @@ +Docker \ No newline at end of file diff --git a/public/brands/gitea.svg b/public/brands/gitea.svg new file mode 100644 index 0000000..860d347 --- /dev/null +++ b/public/brands/gitea.svg @@ -0,0 +1 @@ +Gitea \ No newline at end of file diff --git a/public/database.png b/public/database.png new file mode 100644 index 0000000..b7c3f0b Binary files /dev/null and b/public/database.png differ diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..e77737f Binary files /dev/null and b/public/favicon.png differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..09e67cb Binary files /dev/null and b/public/logo.png differ diff --git a/scripts/fetch-watermark-fonts.mjs b/scripts/fetch-watermark-fonts.mjs new file mode 100644 index 0000000..bd68a02 --- /dev/null +++ b/scripts/fetch-watermark-fonts.mjs @@ -0,0 +1,71 @@ +/** + * Download curated watermark fonts into assets/fonts for FFmpeg drawtext. + * Run: node scripts/fetch-watermark-fonts.mjs + */ +import fs from "fs/promises"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const outDir = path.join(__dirname, "..", "assets", "fonts"); + +/** Direct TTF URLs from Google Fonts GitHub (OFL). */ +const FONTS = [ + { + file: "Inter-Regular.ttf", + url: "https://github.com/google/fonts/raw/main/ofl/inter/Inter%5Bopsz%2Cwght%5D.ttf", + }, + { + file: "Montserrat-Regular.ttf", + url: "https://github.com/google/fonts/raw/main/ofl/montserrat/Montserrat%5Bwght%5D.ttf", + }, + { + file: "Roboto-Regular.ttf", + url: "https://github.com/google/fonts/raw/main/ofl/roboto/Roboto%5Bwdth%2Cwght%5D.ttf", + }, + { + file: "Oswald-Regular.ttf", + url: "https://github.com/google/fonts/raw/main/ofl/oswald/Oswald%5Bwght%5D.ttf", + }, + { + file: "PlayfairDisplay-Regular.ttf", + url: "https://github.com/google/fonts/raw/main/ofl/playfairdisplay/PlayfairDisplay%5Bwght%5D.ttf", + }, +]; + +await fs.mkdir(outDir, { recursive: true }); + +for (const font of FONTS) { + const dest = path.join(outDir, font.file); + try { + await fs.access(dest); + console.log("skip (exists)", font.file); + continue; + } catch { + /* download */ + } + console.log("fetch", font.file); + const res = await fetch(font.url, { + headers: { "User-Agent": "songs2vid-font-fetch/1.0" }, + redirect: "follow", + }); + if (!res.ok) { + console.error("FAILED", font.file, res.status); + continue; + } + const buf = Buffer.from(await res.arrayBuffer()); + await fs.writeFile(dest, buf); + console.log("wrote", font.file, buf.length, "bytes"); +} + +await fs.writeFile( + path.join(outDir, "README.md"), + `# Watermark fonts + +Curated TTF assets for FFmpeg \`drawtext\` (OFL via Google Fonts). +Refresh with \`node scripts/fetch-watermark-fonts.mjs\`. +`, + "utf8", +); + +console.log("done →", outDir); diff --git a/scripts/layout.test.ts b/scripts/layout.test.ts new file mode 100644 index 0000000..86b51c9 --- /dev/null +++ b/scripts/layout.test.ts @@ -0,0 +1,103 @@ +import assert from "node:assert/strict"; +import { + BLUR_AMOUNT_MAX, + INVALID_LAYOUT_TEMPLATE_MESSAGE, + blurToBoxblur, + boxblurFilterSegment, + buildArtTrackFilterComplex, + clampBlurAmount, + clampTextPadding, + clampTitleArtistGap, + computeLayoutGeometry, + normalizeLayoutSettings, + requiresArtTrackLayoutEntitlement, +} from "../lib/layout"; +import { sanitizeDrawtext } from "../lib/watermark"; + +function testEnumsAndClamp() { + assert.equal(clampBlurAmount(150), BLUR_AMOUNT_MAX); + assert.equal(clampBlurAmount(-1), 0); + assert.equal(clampTextPadding(999), 120); + assert.equal(clampTextPadding(1), 16); + assert.equal(clampTitleArtistGap(100), 64); + assert.equal(clampTitleArtistGap(-5), 0); + + assert.equal(blurToBoxblur(0), null); + const mid = blurToBoxblur(50); + assert.ok(mid && mid.radius >= 1 && mid.power >= 1); + assert.ok(boxblurFilterSegment(60).includes("boxblur=")); + assert.equal(boxblurFilterSegment(0), ""); +} + +function testNormalize() { + const classic = normalizeLayoutSettings(null); + assert.equal(classic.template, null); + assert.equal(classic.titleArtistGap, 10); + assert.equal(classic.textOffsetX, 0); + + assert.equal( + normalizeLayoutSettings({ + layout_template: "CENTERED_COMPACT", + blur_amount: 80, + title_artist_gap: 24, + text_offset_y: -20, + }).titleArtistGap, + 24, + ); + + assert.throws( + () => normalizeLayoutSettings({ template: "NOT_A_TEMPLATE" }), + (err: Error) => err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE, + ); + assert.throws( + () => normalizeLayoutSettings({ template: "COVER_LEFT_TEXT_RIGHT", x: 10 }), + (err: Error) => err.message === INVALID_LAYOUT_TEMPLATE_MESSAGE, + ); + + assert.equal( + requiresArtTrackLayoutEntitlement(normalizeLayoutSettings({ template: null })), + false, + ); + assert.equal( + requiresArtTrackLayoutEntitlement( + normalizeLayoutSettings({ template: "COVER_TOP_TEXT_BOTTOM" }), + ), + true, + ); +} + +function testGeometryAndFilter() { + const geo = computeLayoutGeometry("COVER_TOP_TEXT_BOTTOM", 1920, 1080, 48, 16, 10, -5); + assert.ok(geo.coverMaxW > 1600, "top layout cover should be near full width"); + assert.ok(geo.artistY !== geo.titleY); + + const withGap = computeLayoutGeometry("COVER_LEFT_TEXT_RIGHT", 1280, 720, 40, 40, 0, 0); + const tight = computeLayoutGeometry("COVER_LEFT_TEXT_RIGHT", 1280, 720, 40, 0, 0, 0); + assert.ok(Number(withGap.artistY) - Number(withGap.titleY) > Number(tight.artistY) - Number(tight.titleY)); + + const fc = buildArtTrackFilterComplex({ + width: 1280, + height: 720, + layout: { + template: "CENTERED_COMPACT", + blurAmount: 40, + blurOpacity: 70, + textPadding: 40, + titleArtistGap: 18, + textOffsetX: 5, + textOffsetY: -8, + }, + titleEscaped: sanitizeDrawtext("Hello:World"), + artistEscaped: sanitizeDrawtext("Artist"), + }); + assert.ok(fc.includes("split=2")); + assert.ok(fc.includes("blend=") || fc.includes("[blurred]")); + assert.ok(fc.includes("overlay=")); + assert.ok(fc.includes("drawtext=")); + assert.ok(fc.endsWith("[laid]")); +} + +testEnumsAndClamp(); +testNormalize(); +testGeometryAndFilter(); +console.log("layout.test.ts: ok"); diff --git a/scripts/preview-typography.test.ts b/scripts/preview-typography.test.ts new file mode 100644 index 0000000..9aafa51 --- /dev/null +++ b/scripts/preview-typography.test.ts @@ -0,0 +1,25 @@ +import assert from "node:assert/strict"; +import { + artistFontSizeForWidth, + scaleFontToPreview, + titleFontSizeForWidth, + watermarkFontSizeForWidth, +} from "../lib/preview-typography"; + +function testFontSizesMatchLayout() { + const width = 1280; + assert.equal(titleFontSizeForWidth(width), Math.max(22, Math.round(width * 0.032))); + assert.equal(artistFontSizeForWidth(width), Math.max(16, Math.round(width * 0.02))); + assert.equal(watermarkFontSizeForWidth(width), Math.max(16, Math.round(width * 0.018))); +} + +function testPreviewScaling() { + const encodeWidth = 1920; + const titlePx = titleFontSizeForWidth(encodeWidth); + const previewPx = scaleFontToPreview(titlePx, encodeWidth); + assert.ok(previewPx > 0 && previewPx < titlePx); +} + +testFontSizesMatchLayout(); +testPreviewScaling(); +console.log("preview-typography.test.ts: ok"); diff --git a/scripts/release-cloud.sh b/scripts/release-cloud.sh new file mode 100644 index 0000000..e513527 --- /dev/null +++ b/scripts/release-cloud.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Build multi-arch production image and optionally push to Docker Hub. +# Usage: +# ./scripts/release-cloud.sh # build locally (current arch) +# ./scripts/release-cloud.sh --push # build+push linux/amd64,linux/arm64 +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$ROOT" + +IMAGE="${DOCKER_IMAGE:-atakanozban/songs2vid}" +TAG="${DOCKER_TAG:-latest}" +FULL="${IMAGE}:${TAG}" + +echo "==> Prisma generate" +npx prisma generate + +echo "==> Typecheck / lint (optional soft)" +npm run lint || true + +echo "==> Watermark unit checks" +npx tsx scripts/watermark.test.ts + +if [[ "${1:-}" == "--push" ]]; then + echo "==> Multi-arch build+push ${FULL} (amd64,arm64)" + docker buildx create --name s2yt-builder --use 2>/dev/null || docker buildx use s2yt-builder + docker buildx build \ + --platform linux/amd64,linux/arm64 \ + -t "$FULL" \ + --push \ + . + echo "Pushed ${FULL}. Deploy on songs2vid.com host with deploy/songs2vid/docker-compose.yml" +else + echo "==> Local docker build ${FULL}" + docker build -t "$FULL" . + echo "Built ${FULL}. Re-run with --push for Hub multi-arch." +fi diff --git a/scripts/titles.test.ts b/scripts/titles.test.ts new file mode 100644 index 0000000..0a4168f --- /dev/null +++ b/scripts/titles.test.ts @@ -0,0 +1,53 @@ +import assert from "node:assert/strict"; +import { Plan } from "@prisma/client"; +import { + resolveBurnedSongTitle, + resolveYouTubeTitle, + validateYouTubeTitle, +} from "../lib/titles"; + +function testYouTubeTitleResolution() { + assert.equal( + resolveYouTubeTitle({ title: "My Video", songTitle: "Song", artist: "Artist" }, Plan.FREE), + "My Video", + ); + + assert.equal( + resolveYouTubeTitle({ title: "", songTitle: "Song", artist: "Artist" }, Plan.FREE), + "", + ); + + assert.equal( + resolveYouTubeTitle({ title: "", songTitle: "Song", artist: "Artist" }, Plan.PREMIUM), + "Artist - Song", + ); + + assert.equal( + resolveYouTubeTitle({ title: "Custom", songTitle: "Song", artist: "Artist" }, Plan.PREMIUM), + "Custom", + ); + + assert.equal( + resolveYouTubeTitle({ title: "", songTitle: "Song", artist: "" }, Plan.PREMIUM), + "Song", + ); +} + +function testBurnedSongTitle() { + assert.equal(resolveBurnedSongTitle({ songTitle: "Track" }), "Track"); + assert.equal(resolveBurnedSongTitle({ title: "YouTube only" }, "Fallback"), "Fallback"); +} + +function testValidation() { + assert.equal(validateYouTubeTitle({ title: "Ok" }, Plan.FREE), null); + assert.ok(validateYouTubeTitle({ title: "" }, Plan.FREE)); + assert.equal( + validateYouTubeTitle({ title: "", songTitle: "S", artist: "A" }, Plan.PREMIUM), + null, + ); +} + +testYouTubeTitleResolution(); +testBurnedSongTitle(); +testValidation(); +console.log("titles.test.ts: ok"); diff --git a/scripts/watermark.test.ts b/scripts/watermark.test.ts new file mode 100644 index 0000000..50d54e3 --- /dev/null +++ b/scripts/watermark.test.ts @@ -0,0 +1,89 @@ +import assert from "node:assert/strict"; +import { sanitizeFontfileForFilter } from "../lib/fonts"; +import { + buildDrawtextFilter, + clampOffset, + drawtextXy, + overlayXy, + requiresCustomWatermarkEntitlement, + sanitizeDrawtext, + normalizeWatermarkSettings, +} from "../lib/watermark"; + +function testSanitize() { + const s = sanitizeDrawtext("Hi:there'100%[x]"); + assert.ok(s.includes("\\:"), "colon escaped as \\\\:"); + assert.ok(s.includes("\\'"), "quote escaped"); + assert.equal(sanitizeDrawtext("a".repeat(200)).length, 80); + assert.equal(sanitizeDrawtext("ok\nline").includes("\n"), false); +} + +function testPositions() { + assert.deepEqual(overlayXy("bottom-right", 20, 20), { x: "W-w-20", y: "H-h-20" }); + assert.deepEqual(overlayXy("top-left", 10, 5), { x: "10", y: "5" }); + assert.deepEqual(drawtextXy("center", 0, 0), { + x: "(w-text_w)/2+0", + y: "(h-th)/2+0", + }); +} + +function testEntitlements() { + assert.equal( + requiresCustomWatermarkEntitlement( + normalizeWatermarkSettings({ mode: "default" }, true), + ), + false, + ); + assert.equal( + requiresCustomWatermarkEntitlement( + normalizeWatermarkSettings({ mode: "text", text: "Brand" }, true), + ), + true, + ); + assert.equal( + requiresCustomWatermarkEntitlement( + normalizeWatermarkSettings({ mode: "default", position: "top-left" }, true), + ), + true, + ); + assert.equal( + requiresCustomWatermarkEntitlement( + normalizeWatermarkSettings({ mode: "default", fontKey: "inter" }, true), + ), + true, + ); + assert.equal(clampOffset(999), 200); + assert.equal(clampOffset(-5), 0); +} + +function testDrawtextFontfile() { + const withFont = buildDrawtextFilter({ + text: "Brand", + fontSize: 24, + position: "bottom-right", + offsetX: 20, + offsetY: 20, + fontfileEscaped: sanitizeFontfileForFilter("C:\\fonts\\My Font.ttf"), + }); + assert.ok(withFont.includes("fontfile="), "fontfile present"); + assert.ok(withFont.includes("C\\:/fonts/My Font.ttf") || withFont.includes("C\\:/fonts/My\\ Font.ttf") || withFont.includes("fontfile='"), "escaped path"); + assert.ok(!withFont.includes("C:\\fonts"), "backslashes normalized"); + + const injection = sanitizeFontfileForFilter("/tmp/evil':drawtext=text='x"); + assert.ok(injection.includes("\\'"), "quote escaped in font path"); + + const noFont = buildDrawtextFilter({ + text: "Hi", + fontSize: 18, + position: "top-left", + offsetX: 0, + offsetY: 0, + }); + assert.equal(noFont.includes("fontfile"), false); +} + +testSanitize(); +testPositions(); +testEntitlements(); +testDrawtextFontfile(); +console.log("watermark.test.ts: ok"); diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..a93dc55 --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,10 @@ +{ + "version": 1, + "skills": { + "stripe-best-practices": { + "source": "docs.stripe.com", + "sourceType": "well-known", + "computedHash": "a06bdd7108b561fdeea22afcd6fc42ba4ed1a59b465813d63f9b159b02f9e8b2" + } + } +} diff --git a/tailwind.config.ts b/tailwind.config.ts index 8742380..525d168 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,4 +1,5 @@ import type { Config } from "tailwindcss"; +import typography from "@tailwindcss/typography"; const config: Config = { content: [ @@ -21,7 +22,7 @@ const config: Config = { }, }, }, - plugins: [], + plugins: [typography], }; export default config; diff --git a/tsconfig.json b/tsconfig.json index eea7ea5..0625d2f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,5 +19,5 @@ } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "exclude": ["node_modules", "website"] } diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo new file mode 100644 index 0000000..9c1f582 --- /dev/null +++ b/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2024.d.ts","./node_modules/typescript/lib/lib.esnext.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.es2023.intl.d.ts","./node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2024.collection.d.ts","./node_modules/typescript/lib/lib.es2024.object.d.ts","./node_modules/typescript/lib/lib.es2024.promise.d.ts","./node_modules/typescript/lib/lib.es2024.regexp.d.ts","./node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2024.string.d.ts","./node_modules/typescript/lib/lib.esnext.array.d.ts","./node_modules/typescript/lib/lib.esnext.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.promise.d.ts","./node_modules/typescript/lib/lib.esnext.decorators.d.ts","./node_modules/typescript/lib/lib.esnext.iterator.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.esnext.error.d.ts","./node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./.next/types/routes.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/web-globals/streams.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/@types/react/compiler-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/static.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./next-env.d.ts","./next.config.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/tailwindcss/types/generated/corepluginlist.d.ts","./node_modules/tailwindcss/types/generated/colors.d.ts","./node_modules/tailwindcss/types/config.d.ts","./node_modules/tailwindcss/types/index.d.ts","./node_modules/@tailwindcss/typography/src/index.d.ts","./tailwind.config.ts","./node_modules/@prisma/client/runtime/library.d.ts","./node_modules/.prisma/client/index.d.ts","./node_modules/.prisma/client/default.d.ts","./node_modules/@prisma/client/default.d.ts","./lib/db.ts","./lib/api-keys.ts","./lib/edition.ts","./node_modules/@types/cookie/index.d.ts","./node_modules/oauth4webapi/build/index.d.ts","./node_modules/@auth/core/lib/utils/cookie.d.ts","./node_modules/@auth/core/lib/utils/logger.d.ts","./node_modules/@auth/core/providers/webauthn.d.ts","./node_modules/@auth/core/lib/utils/webauthn-utils.d.ts","./node_modules/@auth/core/lib/index.d.ts","./node_modules/@auth/core/lib/utils/env.d.ts","./node_modules/@auth/core/jwt.d.ts","./node_modules/@auth/core/lib/utils/actions.d.ts","./node_modules/@auth/core/index.d.ts","./node_modules/@auth/core/types.d.ts","./node_modules/preact/src/jsx.d.ts","./node_modules/preact/src/index.d.ts","./node_modules/@auth/core/providers/credentials.d.ts","./node_modules/@auth/core/providers/nodemailer.d.ts","./node_modules/@auth/core/providers/email.d.ts","./node_modules/@auth/core/providers/oauth-types.d.ts","./node_modules/@auth/core/providers/oauth.d.ts","./node_modules/@auth/core/providers/index.d.ts","./node_modules/@auth/core/adapters.d.ts","./node_modules/next-auth/adapters.d.ts","./node_modules/jose/dist/types/types.d.ts","./node_modules/jose/dist/types/jwe/compact/decrypt.d.ts","./node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts","./node_modules/jose/dist/types/jwe/general/decrypt.d.ts","./node_modules/jose/dist/types/jwe/general/encrypt.d.ts","./node_modules/jose/dist/types/jws/compact/verify.d.ts","./node_modules/jose/dist/types/jws/flattened/verify.d.ts","./node_modules/jose/dist/types/jws/general/verify.d.ts","./node_modules/jose/dist/types/jwt/verify.d.ts","./node_modules/jose/dist/types/jwt/decrypt.d.ts","./node_modules/jose/dist/types/jwt/produce.d.ts","./node_modules/jose/dist/types/jwe/compact/encrypt.d.ts","./node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts","./node_modules/jose/dist/types/jws/compact/sign.d.ts","./node_modules/jose/dist/types/jws/flattened/sign.d.ts","./node_modules/jose/dist/types/jws/general/sign.d.ts","./node_modules/jose/dist/types/jwt/sign.d.ts","./node_modules/jose/dist/types/jwt/encrypt.d.ts","./node_modules/jose/dist/types/jwk/thumbprint.d.ts","./node_modules/jose/dist/types/jwk/embedded.d.ts","./node_modules/jose/dist/types/jwks/local.d.ts","./node_modules/jose/dist/types/jwks/remote.d.ts","./node_modules/jose/dist/types/jwt/unsecured.d.ts","./node_modules/jose/dist/types/key/export.d.ts","./node_modules/jose/dist/types/key/import.d.ts","./node_modules/jose/dist/types/util/decode_protected_header.d.ts","./node_modules/jose/dist/types/util/decode_jwt.d.ts","./node_modules/jose/dist/types/util/errors.d.ts","./node_modules/jose/dist/types/key/generate_key_pair.d.ts","./node_modules/jose/dist/types/key/generate_secret.d.ts","./node_modules/jose/dist/types/util/base64url.d.ts","./node_modules/jose/dist/types/util/runtime.d.ts","./node_modules/jose/dist/types/index.d.ts","./node_modules/openid-client/types/index.d.ts","./node_modules/next-auth/providers/oauth-types.d.ts","./node_modules/next-auth/providers/oauth.d.ts","./node_modules/next-auth/providers/email.d.ts","./node_modules/next-auth/core/lib/cookie.d.ts","./node_modules/next-auth/core/index.d.ts","./node_modules/next-auth/providers/credentials.d.ts","./node_modules/next-auth/providers/index.d.ts","./node_modules/next-auth/jwt/types.d.ts","./node_modules/next-auth/jwt/index.d.ts","./node_modules/next-auth/utils/logger.d.ts","./node_modules/next-auth/core/types.d.ts","./node_modules/next-auth/next/index.d.ts","./node_modules/next-auth/index.d.ts","./node_modules/next-auth/providers/google.d.ts","./lib/crypto/secrets.ts","./lib/credits.ts","./lib/constants.ts","./lib/plans.ts","./lib/billing.ts","./lib/quota.ts","./node_modules/gaxios/build/src/common.d.ts","./node_modules/gaxios/build/src/interceptor.d.ts","./node_modules/gaxios/build/src/gaxios.d.ts","./node_modules/gaxios/build/src/index.d.ts","./node_modules/google-auth-library/build/src/transporters.d.ts","./node_modules/google-auth-library/build/src/auth/credentials.d.ts","./node_modules/google-auth-library/build/src/crypto/crypto.d.ts","./node_modules/google-auth-library/build/src/util.d.ts","./node_modules/google-auth-library/build/src/auth/authclient.d.ts","./node_modules/google-auth-library/build/src/auth/loginticket.d.ts","./node_modules/google-auth-library/build/src/auth/oauth2client.d.ts","./node_modules/google-auth-library/build/src/auth/idtokenclient.d.ts","./node_modules/google-auth-library/build/src/auth/envdetect.d.ts","./node_modules/gtoken/build/src/index.d.ts","./node_modules/google-auth-library/build/src/auth/jwtclient.d.ts","./node_modules/google-auth-library/build/src/auth/refreshclient.d.ts","./node_modules/google-auth-library/build/src/auth/impersonated.d.ts","./node_modules/google-auth-library/build/src/auth/baseexternalclient.d.ts","./node_modules/google-auth-library/build/src/auth/identitypoolclient.d.ts","./node_modules/google-auth-library/build/src/auth/awsrequestsigner.d.ts","./node_modules/google-auth-library/build/src/auth/awsclient.d.ts","./node_modules/google-auth-library/build/src/auth/pluggable-auth-client.d.ts","./node_modules/google-auth-library/build/src/auth/externalclient.d.ts","./node_modules/google-auth-library/build/src/auth/externalaccountauthorizeduserclient.d.ts","./node_modules/google-auth-library/build/src/auth/googleauth.d.ts","./node_modules/gcp-metadata/build/src/gcp-residency.d.ts","./node_modules/gcp-metadata/build/src/index.d.ts","./node_modules/google-auth-library/build/src/auth/computeclient.d.ts","./node_modules/google-auth-library/build/src/auth/iam.d.ts","./node_modules/google-auth-library/build/src/auth/jwtaccess.d.ts","./node_modules/google-auth-library/build/src/auth/downscopedclient.d.ts","./node_modules/google-auth-library/build/src/auth/passthrough.d.ts","./node_modules/google-auth-library/build/src/index.d.ts","./node_modules/googleapis-common/build/src/schema.d.ts","./node_modules/googleapis-common/build/src/endpoint.d.ts","./node_modules/googleapis-common/build/src/api.d.ts","./node_modules/googleapis-common/build/src/apiindex.d.ts","./node_modules/googleapis-common/build/src/apirequest.d.ts","./node_modules/googleapis-common/build/src/authplus.d.ts","./node_modules/googleapis-common/build/src/discovery.d.ts","./node_modules/googleapis-common/build/src/index.d.ts","./node_modules/googleapis/build/src/apis/abusiveexperiencereport/v1.d.ts","./node_modules/googleapis/build/src/apis/abusiveexperiencereport/index.d.ts","./node_modules/googleapis/build/src/apis/acceleratedmobilepageurl/v1.d.ts","./node_modules/googleapis/build/src/apis/acceleratedmobilepageurl/index.d.ts","./node_modules/googleapis/build/src/apis/accessapproval/v1.d.ts","./node_modules/googleapis/build/src/apis/accessapproval/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/accessapproval/index.d.ts","./node_modules/googleapis/build/src/apis/accesscontextmanager/v1.d.ts","./node_modules/googleapis/build/src/apis/accesscontextmanager/v1beta.d.ts","./node_modules/googleapis/build/src/apis/accesscontextmanager/index.d.ts","./node_modules/googleapis/build/src/apis/acmedns/v1.d.ts","./node_modules/googleapis/build/src/apis/acmedns/index.d.ts","./node_modules/googleapis/build/src/apis/addressvalidation/v1.d.ts","./node_modules/googleapis/build/src/apis/addressvalidation/index.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer/v1.2.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer/v1.3.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer/v1.4.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer/index.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer2/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/adexchangebuyer2/index.d.ts","./node_modules/googleapis/build/src/apis/adexperiencereport/v1.d.ts","./node_modules/googleapis/build/src/apis/adexperiencereport/index.d.ts","./node_modules/googleapis/build/src/apis/admin/datatransfer_v1.d.ts","./node_modules/googleapis/build/src/apis/admin/directory_v1.d.ts","./node_modules/googleapis/build/src/apis/admin/reports_v1.d.ts","./node_modules/googleapis/build/src/apis/admin/index.d.ts","./node_modules/googleapis/build/src/apis/admob/v1.d.ts","./node_modules/googleapis/build/src/apis/admob/v1beta.d.ts","./node_modules/googleapis/build/src/apis/admob/index.d.ts","./node_modules/googleapis/build/src/apis/adsense/v1.4.d.ts","./node_modules/googleapis/build/src/apis/adsense/v2.d.ts","./node_modules/googleapis/build/src/apis/adsense/index.d.ts","./node_modules/googleapis/build/src/apis/adsensehost/v4.1.d.ts","./node_modules/googleapis/build/src/apis/adsensehost/index.d.ts","./node_modules/googleapis/build/src/apis/adsenseplatform/v1.d.ts","./node_modules/googleapis/build/src/apis/adsenseplatform/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/adsenseplatform/index.d.ts","./node_modules/googleapis/build/src/apis/advisorynotifications/v1.d.ts","./node_modules/googleapis/build/src/apis/advisorynotifications/index.d.ts","./node_modules/googleapis/build/src/apis/aiplatform/v1.d.ts","./node_modules/googleapis/build/src/apis/aiplatform/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/aiplatform/index.d.ts","./node_modules/googleapis/build/src/apis/airquality/v1.d.ts","./node_modules/googleapis/build/src/apis/airquality/index.d.ts","./node_modules/googleapis/build/src/apis/alertcenter/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/alertcenter/index.d.ts","./node_modules/googleapis/build/src/apis/alloydb/v1.d.ts","./node_modules/googleapis/build/src/apis/alloydb/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/alloydb/v1beta.d.ts","./node_modules/googleapis/build/src/apis/alloydb/index.d.ts","./node_modules/googleapis/build/src/apis/analytics/v3.d.ts","./node_modules/googleapis/build/src/apis/analytics/index.d.ts","./node_modules/googleapis/build/src/apis/analyticsadmin/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/analyticsadmin/v1beta.d.ts","./node_modules/googleapis/build/src/apis/analyticsadmin/index.d.ts","./node_modules/googleapis/build/src/apis/analyticsdata/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/analyticsdata/v1beta.d.ts","./node_modules/googleapis/build/src/apis/analyticsdata/index.d.ts","./node_modules/googleapis/build/src/apis/analyticshub/v1.d.ts","./node_modules/googleapis/build/src/apis/analyticshub/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/analyticshub/index.d.ts","./node_modules/googleapis/build/src/apis/analyticsreporting/v4.d.ts","./node_modules/googleapis/build/src/apis/analyticsreporting/index.d.ts","./node_modules/googleapis/build/src/apis/androiddeviceprovisioning/v1.d.ts","./node_modules/googleapis/build/src/apis/androiddeviceprovisioning/index.d.ts","./node_modules/googleapis/build/src/apis/androidenterprise/v1.d.ts","./node_modules/googleapis/build/src/apis/androidenterprise/index.d.ts","./node_modules/googleapis/build/src/apis/androidmanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/androidmanagement/index.d.ts","./node_modules/googleapis/build/src/apis/androidpublisher/v1.1.d.ts","./node_modules/googleapis/build/src/apis/androidpublisher/v1.d.ts","./node_modules/googleapis/build/src/apis/androidpublisher/v2.d.ts","./node_modules/googleapis/build/src/apis/androidpublisher/v3.d.ts","./node_modules/googleapis/build/src/apis/androidpublisher/index.d.ts","./node_modules/googleapis/build/src/apis/apigateway/v1.d.ts","./node_modules/googleapis/build/src/apis/apigateway/v1beta.d.ts","./node_modules/googleapis/build/src/apis/apigateway/index.d.ts","./node_modules/googleapis/build/src/apis/apigeeregistry/v1.d.ts","./node_modules/googleapis/build/src/apis/apigeeregistry/index.d.ts","./node_modules/googleapis/build/src/apis/apikeys/v2.d.ts","./node_modules/googleapis/build/src/apis/apikeys/index.d.ts","./node_modules/googleapis/build/src/apis/apim/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/apim/index.d.ts","./node_modules/googleapis/build/src/apis/appengine/v1.d.ts","./node_modules/googleapis/build/src/apis/appengine/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/appengine/v1beta.d.ts","./node_modules/googleapis/build/src/apis/appengine/index.d.ts","./node_modules/googleapis/build/src/apis/apphub/v1.d.ts","./node_modules/googleapis/build/src/apis/apphub/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/apphub/index.d.ts","./node_modules/googleapis/build/src/apis/appsactivity/v1.d.ts","./node_modules/googleapis/build/src/apis/appsactivity/index.d.ts","./node_modules/googleapis/build/src/apis/area120tables/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/area120tables/index.d.ts","./node_modules/googleapis/build/src/apis/artifactregistry/v1.d.ts","./node_modules/googleapis/build/src/apis/artifactregistry/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/artifactregistry/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/artifactregistry/index.d.ts","./node_modules/googleapis/build/src/apis/assuredworkloads/v1.d.ts","./node_modules/googleapis/build/src/apis/assuredworkloads/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/assuredworkloads/index.d.ts","./node_modules/googleapis/build/src/apis/authorizedbuyersmarketplace/v1.d.ts","./node_modules/googleapis/build/src/apis/authorizedbuyersmarketplace/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/authorizedbuyersmarketplace/index.d.ts","./node_modules/googleapis/build/src/apis/backupdr/v1.d.ts","./node_modules/googleapis/build/src/apis/backupdr/index.d.ts","./node_modules/googleapis/build/src/apis/baremetalsolution/v1.d.ts","./node_modules/googleapis/build/src/apis/baremetalsolution/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/baremetalsolution/v2.d.ts","./node_modules/googleapis/build/src/apis/baremetalsolution/index.d.ts","./node_modules/googleapis/build/src/apis/batch/v1.d.ts","./node_modules/googleapis/build/src/apis/batch/index.d.ts","./node_modules/googleapis/build/src/apis/beyondcorp/v1.d.ts","./node_modules/googleapis/build/src/apis/beyondcorp/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/beyondcorp/index.d.ts","./node_modules/googleapis/build/src/apis/biglake/v1.d.ts","./node_modules/googleapis/build/src/apis/biglake/index.d.ts","./node_modules/googleapis/build/src/apis/bigquery/v2.d.ts","./node_modules/googleapis/build/src/apis/bigquery/index.d.ts","./node_modules/googleapis/build/src/apis/bigqueryconnection/v1.d.ts","./node_modules/googleapis/build/src/apis/bigqueryconnection/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/bigqueryconnection/index.d.ts","./node_modules/googleapis/build/src/apis/bigquerydatapolicy/v1.d.ts","./node_modules/googleapis/build/src/apis/bigquerydatapolicy/index.d.ts","./node_modules/googleapis/build/src/apis/bigquerydatatransfer/v1.d.ts","./node_modules/googleapis/build/src/apis/bigquerydatatransfer/index.d.ts","./node_modules/googleapis/build/src/apis/bigqueryreservation/v1.d.ts","./node_modules/googleapis/build/src/apis/bigqueryreservation/v1alpha2.d.ts","./node_modules/googleapis/build/src/apis/bigqueryreservation/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/bigqueryreservation/index.d.ts","./node_modules/googleapis/build/src/apis/bigtableadmin/v1.d.ts","./node_modules/googleapis/build/src/apis/bigtableadmin/v2.d.ts","./node_modules/googleapis/build/src/apis/bigtableadmin/index.d.ts","./node_modules/googleapis/build/src/apis/billingbudgets/v1.d.ts","./node_modules/googleapis/build/src/apis/billingbudgets/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/billingbudgets/index.d.ts","./node_modules/googleapis/build/src/apis/binaryauthorization/v1.d.ts","./node_modules/googleapis/build/src/apis/binaryauthorization/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/binaryauthorization/index.d.ts","./node_modules/googleapis/build/src/apis/blockchainnodeengine/v1.d.ts","./node_modules/googleapis/build/src/apis/blockchainnodeengine/index.d.ts","./node_modules/googleapis/build/src/apis/blogger/v2.d.ts","./node_modules/googleapis/build/src/apis/blogger/v3.d.ts","./node_modules/googleapis/build/src/apis/blogger/index.d.ts","./node_modules/googleapis/build/src/apis/books/v1.d.ts","./node_modules/googleapis/build/src/apis/books/index.d.ts","./node_modules/googleapis/build/src/apis/businessprofileperformance/v1.d.ts","./node_modules/googleapis/build/src/apis/businessprofileperformance/index.d.ts","./node_modules/googleapis/build/src/apis/calendar/v3.d.ts","./node_modules/googleapis/build/src/apis/calendar/index.d.ts","./node_modules/googleapis/build/src/apis/certificatemanager/v1.d.ts","./node_modules/googleapis/build/src/apis/certificatemanager/index.d.ts","./node_modules/googleapis/build/src/apis/chat/v1.d.ts","./node_modules/googleapis/build/src/apis/chat/index.d.ts","./node_modules/googleapis/build/src/apis/checks/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/checks/index.d.ts","./node_modules/googleapis/build/src/apis/chromemanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/chromemanagement/index.d.ts","./node_modules/googleapis/build/src/apis/chromepolicy/v1.d.ts","./node_modules/googleapis/build/src/apis/chromepolicy/index.d.ts","./node_modules/googleapis/build/src/apis/chromeuxreport/v1.d.ts","./node_modules/googleapis/build/src/apis/chromeuxreport/index.d.ts","./node_modules/googleapis/build/src/apis/civicinfo/v2.d.ts","./node_modules/googleapis/build/src/apis/civicinfo/index.d.ts","./node_modules/googleapis/build/src/apis/classroom/v1.d.ts","./node_modules/googleapis/build/src/apis/classroom/index.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1p1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1p4beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1p5beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/v1p7beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudasset/index.d.ts","./node_modules/googleapis/build/src/apis/cloudbilling/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudbilling/v1beta.d.ts","./node_modules/googleapis/build/src/apis/cloudbilling/index.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/v1alpha2.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudbuild/index.d.ts","./node_modules/googleapis/build/src/apis/cloudchannel/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudchannel/index.d.ts","./node_modules/googleapis/build/src/apis/cloudcontrolspartner/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudcontrolspartner/v1beta.d.ts","./node_modules/googleapis/build/src/apis/cloudcontrolspartner/index.d.ts","./node_modules/googleapis/build/src/apis/clouddebugger/v2.d.ts","./node_modules/googleapis/build/src/apis/clouddebugger/index.d.ts","./node_modules/googleapis/build/src/apis/clouddeploy/v1.d.ts","./node_modules/googleapis/build/src/apis/clouddeploy/index.d.ts","./node_modules/googleapis/build/src/apis/clouderrorreporting/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/clouderrorreporting/index.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/v2alpha.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/v2beta.d.ts","./node_modules/googleapis/build/src/apis/cloudfunctions/index.d.ts","./node_modules/googleapis/build/src/apis/cloudidentity/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudidentity/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudidentity/index.d.ts","./node_modules/googleapis/build/src/apis/cloudiot/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudiot/index.d.ts","./node_modules/googleapis/build/src/apis/cloudkms/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudkms/index.d.ts","./node_modules/googleapis/build/src/apis/cloudprofiler/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudprofiler/index.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/v3.d.ts","./node_modules/googleapis/build/src/apis/cloudresourcemanager/index.d.ts","./node_modules/googleapis/build/src/apis/cloudscheduler/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudscheduler/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudscheduler/index.d.ts","./node_modules/googleapis/build/src/apis/cloudsearch/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudsearch/index.d.ts","./node_modules/googleapis/build/src/apis/cloudshell/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudshell/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/cloudshell/index.d.ts","./node_modules/googleapis/build/src/apis/cloudsupport/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudsupport/v2beta.d.ts","./node_modules/googleapis/build/src/apis/cloudsupport/index.d.ts","./node_modules/googleapis/build/src/apis/cloudtasks/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudtasks/v2beta2.d.ts","./node_modules/googleapis/build/src/apis/cloudtasks/v2beta3.d.ts","./node_modules/googleapis/build/src/apis/cloudtasks/index.d.ts","./node_modules/googleapis/build/src/apis/cloudtrace/v1.d.ts","./node_modules/googleapis/build/src/apis/cloudtrace/v2.d.ts","./node_modules/googleapis/build/src/apis/cloudtrace/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/cloudtrace/index.d.ts","./node_modules/googleapis/build/src/apis/composer/v1.d.ts","./node_modules/googleapis/build/src/apis/composer/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/composer/index.d.ts","./node_modules/googleapis/build/src/apis/compute/alpha.d.ts","./node_modules/googleapis/build/src/apis/compute/beta.d.ts","./node_modules/googleapis/build/src/apis/compute/v1.d.ts","./node_modules/googleapis/build/src/apis/compute/index.d.ts","./node_modules/googleapis/build/src/apis/config/v1.d.ts","./node_modules/googleapis/build/src/apis/config/index.d.ts","./node_modules/googleapis/build/src/apis/connectors/v1.d.ts","./node_modules/googleapis/build/src/apis/connectors/v2.d.ts","./node_modules/googleapis/build/src/apis/connectors/index.d.ts","./node_modules/googleapis/build/src/apis/contactcenteraiplatform/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/contactcenteraiplatform/index.d.ts","./node_modules/googleapis/build/src/apis/contactcenterinsights/v1.d.ts","./node_modules/googleapis/build/src/apis/contactcenterinsights/index.d.ts","./node_modules/googleapis/build/src/apis/container/v1.d.ts","./node_modules/googleapis/build/src/apis/container/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/container/index.d.ts","./node_modules/googleapis/build/src/apis/containeranalysis/v1.d.ts","./node_modules/googleapis/build/src/apis/containeranalysis/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/containeranalysis/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/containeranalysis/index.d.ts","./node_modules/googleapis/build/src/apis/content/v2.1.d.ts","./node_modules/googleapis/build/src/apis/content/v2.d.ts","./node_modules/googleapis/build/src/apis/content/index.d.ts","./node_modules/googleapis/build/src/apis/contentwarehouse/v1.d.ts","./node_modules/googleapis/build/src/apis/contentwarehouse/index.d.ts","./node_modules/googleapis/build/src/apis/css/v1.d.ts","./node_modules/googleapis/build/src/apis/css/index.d.ts","./node_modules/googleapis/build/src/apis/customsearch/v1.d.ts","./node_modules/googleapis/build/src/apis/customsearch/index.d.ts","./node_modules/googleapis/build/src/apis/datacatalog/v1.d.ts","./node_modules/googleapis/build/src/apis/datacatalog/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/datacatalog/index.d.ts","./node_modules/googleapis/build/src/apis/dataflow/v1b3.d.ts","./node_modules/googleapis/build/src/apis/dataflow/index.d.ts","./node_modules/googleapis/build/src/apis/dataform/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/dataform/index.d.ts","./node_modules/googleapis/build/src/apis/datafusion/v1.d.ts","./node_modules/googleapis/build/src/apis/datafusion/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/datafusion/index.d.ts","./node_modules/googleapis/build/src/apis/datalabeling/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/datalabeling/index.d.ts","./node_modules/googleapis/build/src/apis/datalineage/v1.d.ts","./node_modules/googleapis/build/src/apis/datalineage/index.d.ts","./node_modules/googleapis/build/src/apis/datamigration/v1.d.ts","./node_modules/googleapis/build/src/apis/datamigration/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/datamigration/index.d.ts","./node_modules/googleapis/build/src/apis/datapipelines/v1.d.ts","./node_modules/googleapis/build/src/apis/datapipelines/index.d.ts","./node_modules/googleapis/build/src/apis/dataplex/v1.d.ts","./node_modules/googleapis/build/src/apis/dataplex/index.d.ts","./node_modules/googleapis/build/src/apis/dataportability/v1.d.ts","./node_modules/googleapis/build/src/apis/dataportability/v1beta.d.ts","./node_modules/googleapis/build/src/apis/dataportability/index.d.ts","./node_modules/googleapis/build/src/apis/dataproc/v1.d.ts","./node_modules/googleapis/build/src/apis/dataproc/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/dataproc/index.d.ts","./node_modules/googleapis/build/src/apis/datastore/v1.d.ts","./node_modules/googleapis/build/src/apis/datastore/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/datastore/v1beta3.d.ts","./node_modules/googleapis/build/src/apis/datastore/index.d.ts","./node_modules/googleapis/build/src/apis/datastream/v1.d.ts","./node_modules/googleapis/build/src/apis/datastream/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/datastream/index.d.ts","./node_modules/googleapis/build/src/apis/deploymentmanager/alpha.d.ts","./node_modules/googleapis/build/src/apis/deploymentmanager/v2.d.ts","./node_modules/googleapis/build/src/apis/deploymentmanager/v2beta.d.ts","./node_modules/googleapis/build/src/apis/deploymentmanager/index.d.ts","./node_modules/googleapis/build/src/apis/developerconnect/v1.d.ts","./node_modules/googleapis/build/src/apis/developerconnect/index.d.ts","./node_modules/googleapis/build/src/apis/dfareporting/v3.3.d.ts","./node_modules/googleapis/build/src/apis/dfareporting/v3.4.d.ts","./node_modules/googleapis/build/src/apis/dfareporting/v3.5.d.ts","./node_modules/googleapis/build/src/apis/dfareporting/v4.d.ts","./node_modules/googleapis/build/src/apis/dfareporting/index.d.ts","./node_modules/googleapis/build/src/apis/dialogflow/v2.d.ts","./node_modules/googleapis/build/src/apis/dialogflow/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/dialogflow/v3.d.ts","./node_modules/googleapis/build/src/apis/dialogflow/v3beta1.d.ts","./node_modules/googleapis/build/src/apis/dialogflow/index.d.ts","./node_modules/googleapis/build/src/apis/digitalassetlinks/v1.d.ts","./node_modules/googleapis/build/src/apis/digitalassetlinks/index.d.ts","./node_modules/googleapis/build/src/apis/discovery/v1.d.ts","./node_modules/googleapis/build/src/apis/discovery/index.d.ts","./node_modules/googleapis/build/src/apis/discoveryengine/v1.d.ts","./node_modules/googleapis/build/src/apis/discoveryengine/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/discoveryengine/v1beta.d.ts","./node_modules/googleapis/build/src/apis/discoveryengine/index.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v1.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v1beta.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v1dev.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v2.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v3.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/v4.d.ts","./node_modules/googleapis/build/src/apis/displayvideo/index.d.ts","./node_modules/googleapis/build/src/apis/dlp/v2.d.ts","./node_modules/googleapis/build/src/apis/dlp/index.d.ts","./node_modules/googleapis/build/src/apis/dns/v1.d.ts","./node_modules/googleapis/build/src/apis/dns/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/dns/v2.d.ts","./node_modules/googleapis/build/src/apis/dns/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/dns/index.d.ts","./node_modules/googleapis/build/src/apis/docs/v1.d.ts","./node_modules/googleapis/build/src/apis/docs/index.d.ts","./node_modules/googleapis/build/src/apis/documentai/v1.d.ts","./node_modules/googleapis/build/src/apis/documentai/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/documentai/v1beta3.d.ts","./node_modules/googleapis/build/src/apis/documentai/index.d.ts","./node_modules/googleapis/build/src/apis/domains/v1.d.ts","./node_modules/googleapis/build/src/apis/domains/v1alpha2.d.ts","./node_modules/googleapis/build/src/apis/domains/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/domains/index.d.ts","./node_modules/googleapis/build/src/apis/domainsrdap/v1.d.ts","./node_modules/googleapis/build/src/apis/domainsrdap/index.d.ts","./node_modules/googleapis/build/src/apis/doubleclickbidmanager/v1.1.d.ts","./node_modules/googleapis/build/src/apis/doubleclickbidmanager/v1.d.ts","./node_modules/googleapis/build/src/apis/doubleclickbidmanager/v2.d.ts","./node_modules/googleapis/build/src/apis/doubleclickbidmanager/index.d.ts","./node_modules/googleapis/build/src/apis/doubleclicksearch/v2.d.ts","./node_modules/googleapis/build/src/apis/doubleclicksearch/index.d.ts","./node_modules/googleapis/build/src/apis/drive/v2.d.ts","./node_modules/googleapis/build/src/apis/drive/v3.d.ts","./node_modules/googleapis/build/src/apis/drive/index.d.ts","./node_modules/googleapis/build/src/apis/driveactivity/v2.d.ts","./node_modules/googleapis/build/src/apis/driveactivity/index.d.ts","./node_modules/googleapis/build/src/apis/drivelabels/v2.d.ts","./node_modules/googleapis/build/src/apis/drivelabels/v2beta.d.ts","./node_modules/googleapis/build/src/apis/drivelabels/index.d.ts","./node_modules/googleapis/build/src/apis/essentialcontacts/v1.d.ts","./node_modules/googleapis/build/src/apis/essentialcontacts/index.d.ts","./node_modules/googleapis/build/src/apis/eventarc/v1.d.ts","./node_modules/googleapis/build/src/apis/eventarc/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/eventarc/index.d.ts","./node_modules/googleapis/build/src/apis/factchecktools/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/factchecktools/index.d.ts","./node_modules/googleapis/build/src/apis/fcm/v1.d.ts","./node_modules/googleapis/build/src/apis/fcm/index.d.ts","./node_modules/googleapis/build/src/apis/fcmdata/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/fcmdata/index.d.ts","./node_modules/googleapis/build/src/apis/file/v1.d.ts","./node_modules/googleapis/build/src/apis/file/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/file/index.d.ts","./node_modules/googleapis/build/src/apis/firebase/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/firebase/index.d.ts","./node_modules/googleapis/build/src/apis/firebaseappcheck/v1.d.ts","./node_modules/googleapis/build/src/apis/firebaseappcheck/v1beta.d.ts","./node_modules/googleapis/build/src/apis/firebaseappcheck/index.d.ts","./node_modules/googleapis/build/src/apis/firebaseappdistribution/v1.d.ts","./node_modules/googleapis/build/src/apis/firebaseappdistribution/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/firebaseappdistribution/index.d.ts","./node_modules/googleapis/build/src/apis/firebasedatabase/v1beta.d.ts","./node_modules/googleapis/build/src/apis/firebasedatabase/index.d.ts","./node_modules/googleapis/build/src/apis/firebasedynamiclinks/v1.d.ts","./node_modules/googleapis/build/src/apis/firebasedynamiclinks/index.d.ts","./node_modules/googleapis/build/src/apis/firebasehosting/v1.d.ts","./node_modules/googleapis/build/src/apis/firebasehosting/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/firebasehosting/index.d.ts","./node_modules/googleapis/build/src/apis/firebaseml/v1.d.ts","./node_modules/googleapis/build/src/apis/firebaseml/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/firebaseml/v2beta.d.ts","./node_modules/googleapis/build/src/apis/firebaseml/index.d.ts","./node_modules/googleapis/build/src/apis/firebaserules/v1.d.ts","./node_modules/googleapis/build/src/apis/firebaserules/index.d.ts","./node_modules/googleapis/build/src/apis/firebasestorage/v1beta.d.ts","./node_modules/googleapis/build/src/apis/firebasestorage/index.d.ts","./node_modules/googleapis/build/src/apis/firestore/v1.d.ts","./node_modules/googleapis/build/src/apis/firestore/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/firestore/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/firestore/index.d.ts","./node_modules/googleapis/build/src/apis/fitness/v1.d.ts","./node_modules/googleapis/build/src/apis/fitness/index.d.ts","./node_modules/googleapis/build/src/apis/forms/v1.d.ts","./node_modules/googleapis/build/src/apis/forms/index.d.ts","./node_modules/googleapis/build/src/apis/games/v1.d.ts","./node_modules/googleapis/build/src/apis/games/index.d.ts","./node_modules/googleapis/build/src/apis/gamesconfiguration/v1configuration.d.ts","./node_modules/googleapis/build/src/apis/gamesconfiguration/index.d.ts","./node_modules/googleapis/build/src/apis/gamesmanagement/v1management.d.ts","./node_modules/googleapis/build/src/apis/gamesmanagement/index.d.ts","./node_modules/googleapis/build/src/apis/gameservices/v1.d.ts","./node_modules/googleapis/build/src/apis/gameservices/v1beta.d.ts","./node_modules/googleapis/build/src/apis/gameservices/index.d.ts","./node_modules/googleapis/build/src/apis/genomics/v1.d.ts","./node_modules/googleapis/build/src/apis/genomics/v1alpha2.d.ts","./node_modules/googleapis/build/src/apis/genomics/v2alpha1.d.ts","./node_modules/googleapis/build/src/apis/genomics/index.d.ts","./node_modules/googleapis/build/src/apis/gkebackup/v1.d.ts","./node_modules/googleapis/build/src/apis/gkebackup/index.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v1.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v1alpha2.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v1beta.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v2.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v2alpha.d.ts","./node_modules/googleapis/build/src/apis/gkehub/v2beta.d.ts","./node_modules/googleapis/build/src/apis/gkehub/index.d.ts","./node_modules/googleapis/build/src/apis/gkeonprem/v1.d.ts","./node_modules/googleapis/build/src/apis/gkeonprem/index.d.ts","./node_modules/googleapis/build/src/apis/gmail/v1.d.ts","./node_modules/googleapis/build/src/apis/gmail/index.d.ts","./node_modules/googleapis/build/src/apis/gmailpostmastertools/v1.d.ts","./node_modules/googleapis/build/src/apis/gmailpostmastertools/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/gmailpostmastertools/index.d.ts","./node_modules/googleapis/build/src/apis/groupsmigration/v1.d.ts","./node_modules/googleapis/build/src/apis/groupsmigration/index.d.ts","./node_modules/googleapis/build/src/apis/groupssettings/v1.d.ts","./node_modules/googleapis/build/src/apis/groupssettings/index.d.ts","./node_modules/googleapis/build/src/apis/healthcare/v1.d.ts","./node_modules/googleapis/build/src/apis/healthcare/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/healthcare/index.d.ts","./node_modules/googleapis/build/src/apis/homegraph/v1.d.ts","./node_modules/googleapis/build/src/apis/homegraph/index.d.ts","./node_modules/googleapis/build/src/apis/iam/v1.d.ts","./node_modules/googleapis/build/src/apis/iam/v2.d.ts","./node_modules/googleapis/build/src/apis/iam/v2beta.d.ts","./node_modules/googleapis/build/src/apis/iam/index.d.ts","./node_modules/googleapis/build/src/apis/iamcredentials/v1.d.ts","./node_modules/googleapis/build/src/apis/iamcredentials/index.d.ts","./node_modules/googleapis/build/src/apis/iap/v1.d.ts","./node_modules/googleapis/build/src/apis/iap/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/iap/index.d.ts","./node_modules/googleapis/build/src/apis/ideahub/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/ideahub/v1beta.d.ts","./node_modules/googleapis/build/src/apis/ideahub/index.d.ts","./node_modules/googleapis/build/src/apis/identitytoolkit/v2.d.ts","./node_modules/googleapis/build/src/apis/identitytoolkit/v3.d.ts","./node_modules/googleapis/build/src/apis/identitytoolkit/index.d.ts","./node_modules/googleapis/build/src/apis/ids/v1.d.ts","./node_modules/googleapis/build/src/apis/ids/index.d.ts","./node_modules/googleapis/build/src/apis/indexing/v3.d.ts","./node_modules/googleapis/build/src/apis/indexing/index.d.ts","./node_modules/googleapis/build/src/apis/integrations/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/integrations/index.d.ts","./node_modules/googleapis/build/src/apis/jobs/v2.d.ts","./node_modules/googleapis/build/src/apis/jobs/v3.d.ts","./node_modules/googleapis/build/src/apis/jobs/v3p1beta1.d.ts","./node_modules/googleapis/build/src/apis/jobs/v4.d.ts","./node_modules/googleapis/build/src/apis/jobs/index.d.ts","./node_modules/googleapis/build/src/apis/keep/v1.d.ts","./node_modules/googleapis/build/src/apis/keep/index.d.ts","./node_modules/googleapis/build/src/apis/kgsearch/v1.d.ts","./node_modules/googleapis/build/src/apis/kgsearch/index.d.ts","./node_modules/googleapis/build/src/apis/kmsinventory/v1.d.ts","./node_modules/googleapis/build/src/apis/kmsinventory/index.d.ts","./node_modules/googleapis/build/src/apis/language/v1.d.ts","./node_modules/googleapis/build/src/apis/language/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/language/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/language/v2.d.ts","./node_modules/googleapis/build/src/apis/language/index.d.ts","./node_modules/googleapis/build/src/apis/libraryagent/v1.d.ts","./node_modules/googleapis/build/src/apis/libraryagent/index.d.ts","./node_modules/googleapis/build/src/apis/licensing/v1.d.ts","./node_modules/googleapis/build/src/apis/licensing/index.d.ts","./node_modules/googleapis/build/src/apis/lifesciences/v2beta.d.ts","./node_modules/googleapis/build/src/apis/lifesciences/index.d.ts","./node_modules/googleapis/build/src/apis/localservices/v1.d.ts","./node_modules/googleapis/build/src/apis/localservices/index.d.ts","./node_modules/googleapis/build/src/apis/logging/v2.d.ts","./node_modules/googleapis/build/src/apis/logging/index.d.ts","./node_modules/googleapis/build/src/apis/looker/v1.d.ts","./node_modules/googleapis/build/src/apis/looker/index.d.ts","./node_modules/googleapis/build/src/apis/managedidentities/v1.d.ts","./node_modules/googleapis/build/src/apis/managedidentities/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/managedidentities/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/managedidentities/index.d.ts","./node_modules/googleapis/build/src/apis/manufacturers/v1.d.ts","./node_modules/googleapis/build/src/apis/manufacturers/index.d.ts","./node_modules/googleapis/build/src/apis/marketingplatformadmin/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/marketingplatformadmin/index.d.ts","./node_modules/googleapis/build/src/apis/meet/v2.d.ts","./node_modules/googleapis/build/src/apis/meet/index.d.ts","./node_modules/googleapis/build/src/apis/memcache/v1.d.ts","./node_modules/googleapis/build/src/apis/memcache/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/memcache/index.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/accounts_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/conversions_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/datasources_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/inventories_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/lfp_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/notifications_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/products_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/promotions_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/quota_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/reports_v1beta.d.ts","./node_modules/googleapis/build/src/apis/merchantapi/index.d.ts","./node_modules/googleapis/build/src/apis/metastore/v1.d.ts","./node_modules/googleapis/build/src/apis/metastore/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/metastore/v1beta.d.ts","./node_modules/googleapis/build/src/apis/metastore/index.d.ts","./node_modules/googleapis/build/src/apis/migrationcenter/v1.d.ts","./node_modules/googleapis/build/src/apis/migrationcenter/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/migrationcenter/index.d.ts","./node_modules/googleapis/build/src/apis/ml/v1.d.ts","./node_modules/googleapis/build/src/apis/ml/index.d.ts","./node_modules/googleapis/build/src/apis/monitoring/v1.d.ts","./node_modules/googleapis/build/src/apis/monitoring/v3.d.ts","./node_modules/googleapis/build/src/apis/monitoring/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessaccountmanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessaccountmanagement/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessbusinesscalls/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessbusinesscalls/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessbusinessinformation/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessbusinessinformation/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinesslodging/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinesslodging/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessnotifications/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessnotifications/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessplaceactions/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessplaceactions/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessqanda/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessqanda/index.d.ts","./node_modules/googleapis/build/src/apis/mybusinessverifications/v1.d.ts","./node_modules/googleapis/build/src/apis/mybusinessverifications/index.d.ts","./node_modules/googleapis/build/src/apis/networkconnectivity/v1.d.ts","./node_modules/googleapis/build/src/apis/networkconnectivity/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/networkconnectivity/index.d.ts","./node_modules/googleapis/build/src/apis/networkmanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/networkmanagement/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/networkmanagement/index.d.ts","./node_modules/googleapis/build/src/apis/networksecurity/v1.d.ts","./node_modules/googleapis/build/src/apis/networksecurity/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/networksecurity/index.d.ts","./node_modules/googleapis/build/src/apis/networkservices/v1.d.ts","./node_modules/googleapis/build/src/apis/networkservices/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/networkservices/index.d.ts","./node_modules/googleapis/build/src/apis/notebooks/v1.d.ts","./node_modules/googleapis/build/src/apis/notebooks/v2.d.ts","./node_modules/googleapis/build/src/apis/notebooks/index.d.ts","./node_modules/googleapis/build/src/apis/oauth2/v2.d.ts","./node_modules/googleapis/build/src/apis/oauth2/index.d.ts","./node_modules/googleapis/build/src/apis/ondemandscanning/v1.d.ts","./node_modules/googleapis/build/src/apis/ondemandscanning/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/ondemandscanning/index.d.ts","./node_modules/googleapis/build/src/apis/orgpolicy/v2.d.ts","./node_modules/googleapis/build/src/apis/orgpolicy/index.d.ts","./node_modules/googleapis/build/src/apis/osconfig/v1.d.ts","./node_modules/googleapis/build/src/apis/osconfig/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/osconfig/v1beta.d.ts","./node_modules/googleapis/build/src/apis/osconfig/index.d.ts","./node_modules/googleapis/build/src/apis/oslogin/v1.d.ts","./node_modules/googleapis/build/src/apis/oslogin/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/oslogin/v1beta.d.ts","./node_modules/googleapis/build/src/apis/oslogin/index.d.ts","./node_modules/googleapis/build/src/apis/pagespeedonline/v5.d.ts","./node_modules/googleapis/build/src/apis/pagespeedonline/index.d.ts","./node_modules/googleapis/build/src/apis/paymentsresellersubscription/v1.d.ts","./node_modules/googleapis/build/src/apis/paymentsresellersubscription/index.d.ts","./node_modules/googleapis/build/src/apis/people/v1.d.ts","./node_modules/googleapis/build/src/apis/people/index.d.ts","./node_modules/googleapis/build/src/apis/places/v1.d.ts","./node_modules/googleapis/build/src/apis/places/index.d.ts","./node_modules/googleapis/build/src/apis/playablelocations/v3.d.ts","./node_modules/googleapis/build/src/apis/playablelocations/index.d.ts","./node_modules/googleapis/build/src/apis/playcustomapp/v1.d.ts","./node_modules/googleapis/build/src/apis/playcustomapp/index.d.ts","./node_modules/googleapis/build/src/apis/playdeveloperreporting/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/playdeveloperreporting/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/playdeveloperreporting/index.d.ts","./node_modules/googleapis/build/src/apis/playgrouping/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/playgrouping/index.d.ts","./node_modules/googleapis/build/src/apis/playintegrity/v1.d.ts","./node_modules/googleapis/build/src/apis/playintegrity/index.d.ts","./node_modules/googleapis/build/src/apis/plus/v1.d.ts","./node_modules/googleapis/build/src/apis/plus/index.d.ts","./node_modules/googleapis/build/src/apis/policyanalyzer/v1.d.ts","./node_modules/googleapis/build/src/apis/policyanalyzer/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/policyanalyzer/index.d.ts","./node_modules/googleapis/build/src/apis/policysimulator/v1.d.ts","./node_modules/googleapis/build/src/apis/policysimulator/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/policysimulator/v1beta.d.ts","./node_modules/googleapis/build/src/apis/policysimulator/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/policysimulator/index.d.ts","./node_modules/googleapis/build/src/apis/policytroubleshooter/v1.d.ts","./node_modules/googleapis/build/src/apis/policytroubleshooter/v1beta.d.ts","./node_modules/googleapis/build/src/apis/policytroubleshooter/index.d.ts","./node_modules/googleapis/build/src/apis/pollen/v1.d.ts","./node_modules/googleapis/build/src/apis/pollen/index.d.ts","./node_modules/googleapis/build/src/apis/poly/v1.d.ts","./node_modules/googleapis/build/src/apis/poly/index.d.ts","./node_modules/googleapis/build/src/apis/privateca/v1.d.ts","./node_modules/googleapis/build/src/apis/privateca/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/privateca/index.d.ts","./node_modules/googleapis/build/src/apis/prod_tt_sasportal/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/prod_tt_sasportal/index.d.ts","./node_modules/googleapis/build/src/apis/publicca/v1.d.ts","./node_modules/googleapis/build/src/apis/publicca/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/publicca/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/publicca/index.d.ts","./node_modules/googleapis/build/src/apis/pubsub/v1.d.ts","./node_modules/googleapis/build/src/apis/pubsub/v1beta1a.d.ts","./node_modules/googleapis/build/src/apis/pubsub/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/pubsub/index.d.ts","./node_modules/googleapis/build/src/apis/pubsublite/v1.d.ts","./node_modules/googleapis/build/src/apis/pubsublite/index.d.ts","./node_modules/googleapis/build/src/apis/rapidmigrationassessment/v1.d.ts","./node_modules/googleapis/build/src/apis/rapidmigrationassessment/index.d.ts","./node_modules/googleapis/build/src/apis/readerrevenuesubscriptionlinking/v1.d.ts","./node_modules/googleapis/build/src/apis/readerrevenuesubscriptionlinking/index.d.ts","./node_modules/googleapis/build/src/apis/realtimebidding/v1.d.ts","./node_modules/googleapis/build/src/apis/realtimebidding/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/realtimebidding/index.d.ts","./node_modules/googleapis/build/src/apis/recaptchaenterprise/v1.d.ts","./node_modules/googleapis/build/src/apis/recaptchaenterprise/index.d.ts","./node_modules/googleapis/build/src/apis/recommendationengine/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/recommendationengine/index.d.ts","./node_modules/googleapis/build/src/apis/recommender/v1.d.ts","./node_modules/googleapis/build/src/apis/recommender/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/recommender/index.d.ts","./node_modules/googleapis/build/src/apis/redis/v1.d.ts","./node_modules/googleapis/build/src/apis/redis/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/redis/index.d.ts","./node_modules/googleapis/build/src/apis/remotebuildexecution/v1.d.ts","./node_modules/googleapis/build/src/apis/remotebuildexecution/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/remotebuildexecution/v2.d.ts","./node_modules/googleapis/build/src/apis/remotebuildexecution/index.d.ts","./node_modules/googleapis/build/src/apis/reseller/v1.d.ts","./node_modules/googleapis/build/src/apis/reseller/index.d.ts","./node_modules/googleapis/build/src/apis/resourcesettings/v1.d.ts","./node_modules/googleapis/build/src/apis/resourcesettings/index.d.ts","./node_modules/googleapis/build/src/apis/retail/v2.d.ts","./node_modules/googleapis/build/src/apis/retail/v2alpha.d.ts","./node_modules/googleapis/build/src/apis/retail/v2beta.d.ts","./node_modules/googleapis/build/src/apis/retail/index.d.ts","./node_modules/googleapis/build/src/apis/run/v1.d.ts","./node_modules/googleapis/build/src/apis/run/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/run/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/run/v2.d.ts","./node_modules/googleapis/build/src/apis/run/index.d.ts","./node_modules/googleapis/build/src/apis/runtimeconfig/v1.d.ts","./node_modules/googleapis/build/src/apis/runtimeconfig/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/runtimeconfig/index.d.ts","./node_modules/googleapis/build/src/apis/safebrowsing/v4.d.ts","./node_modules/googleapis/build/src/apis/safebrowsing/v5.d.ts","./node_modules/googleapis/build/src/apis/safebrowsing/index.d.ts","./node_modules/googleapis/build/src/apis/sasportal/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/sasportal/index.d.ts","./node_modules/googleapis/build/src/apis/script/v1.d.ts","./node_modules/googleapis/build/src/apis/script/index.d.ts","./node_modules/googleapis/build/src/apis/searchads360/v0.d.ts","./node_modules/googleapis/build/src/apis/searchads360/index.d.ts","./node_modules/googleapis/build/src/apis/searchconsole/v1.d.ts","./node_modules/googleapis/build/src/apis/searchconsole/index.d.ts","./node_modules/googleapis/build/src/apis/secretmanager/v1.d.ts","./node_modules/googleapis/build/src/apis/secretmanager/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/secretmanager/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/secretmanager/index.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/v1.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/v1p1alpha1.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/v1p1beta1.d.ts","./node_modules/googleapis/build/src/apis/securitycenter/index.d.ts","./node_modules/googleapis/build/src/apis/serviceconsumermanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/serviceconsumermanagement/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/serviceconsumermanagement/index.d.ts","./node_modules/googleapis/build/src/apis/servicecontrol/v1.d.ts","./node_modules/googleapis/build/src/apis/servicecontrol/v2.d.ts","./node_modules/googleapis/build/src/apis/servicecontrol/index.d.ts","./node_modules/googleapis/build/src/apis/servicedirectory/v1.d.ts","./node_modules/googleapis/build/src/apis/servicedirectory/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/servicedirectory/index.d.ts","./node_modules/googleapis/build/src/apis/servicemanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/servicemanagement/index.d.ts","./node_modules/googleapis/build/src/apis/servicenetworking/v1.d.ts","./node_modules/googleapis/build/src/apis/servicenetworking/v1beta.d.ts","./node_modules/googleapis/build/src/apis/servicenetworking/index.d.ts","./node_modules/googleapis/build/src/apis/serviceusage/v1.d.ts","./node_modules/googleapis/build/src/apis/serviceusage/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/serviceusage/index.d.ts","./node_modules/googleapis/build/src/apis/sheets/v4.d.ts","./node_modules/googleapis/build/src/apis/sheets/index.d.ts","./node_modules/googleapis/build/src/apis/siteverification/v1.d.ts","./node_modules/googleapis/build/src/apis/siteverification/index.d.ts","./node_modules/googleapis/build/src/apis/slides/v1.d.ts","./node_modules/googleapis/build/src/apis/slides/index.d.ts","./node_modules/googleapis/build/src/apis/smartdevicemanagement/v1.d.ts","./node_modules/googleapis/build/src/apis/smartdevicemanagement/index.d.ts","./node_modules/googleapis/build/src/apis/solar/v1.d.ts","./node_modules/googleapis/build/src/apis/solar/index.d.ts","./node_modules/googleapis/build/src/apis/sourcerepo/v1.d.ts","./node_modules/googleapis/build/src/apis/sourcerepo/index.d.ts","./node_modules/googleapis/build/src/apis/spanner/v1.d.ts","./node_modules/googleapis/build/src/apis/spanner/index.d.ts","./node_modules/googleapis/build/src/apis/speech/v1.d.ts","./node_modules/googleapis/build/src/apis/speech/v1p1beta1.d.ts","./node_modules/googleapis/build/src/apis/speech/v2beta1.d.ts","./node_modules/googleapis/build/src/apis/speech/index.d.ts","./node_modules/googleapis/build/src/apis/sql/v1beta4.d.ts","./node_modules/googleapis/build/src/apis/sql/index.d.ts","./node_modules/googleapis/build/src/apis/sqladmin/v1.d.ts","./node_modules/googleapis/build/src/apis/sqladmin/v1beta4.d.ts","./node_modules/googleapis/build/src/apis/sqladmin/index.d.ts","./node_modules/googleapis/build/src/apis/storage/v1.d.ts","./node_modules/googleapis/build/src/apis/storage/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/storage/index.d.ts","./node_modules/googleapis/build/src/apis/storagetransfer/v1.d.ts","./node_modules/googleapis/build/src/apis/storagetransfer/index.d.ts","./node_modules/googleapis/build/src/apis/streetviewpublish/v1.d.ts","./node_modules/googleapis/build/src/apis/streetviewpublish/index.d.ts","./node_modules/googleapis/build/src/apis/sts/v1.d.ts","./node_modules/googleapis/build/src/apis/sts/v1beta.d.ts","./node_modules/googleapis/build/src/apis/sts/index.d.ts","./node_modules/googleapis/build/src/apis/tagmanager/v1.d.ts","./node_modules/googleapis/build/src/apis/tagmanager/v2.d.ts","./node_modules/googleapis/build/src/apis/tagmanager/index.d.ts","./node_modules/googleapis/build/src/apis/tasks/v1.d.ts","./node_modules/googleapis/build/src/apis/tasks/index.d.ts","./node_modules/googleapis/build/src/apis/testing/v1.d.ts","./node_modules/googleapis/build/src/apis/testing/index.d.ts","./node_modules/googleapis/build/src/apis/texttospeech/v1.d.ts","./node_modules/googleapis/build/src/apis/texttospeech/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/texttospeech/index.d.ts","./node_modules/googleapis/build/src/apis/toolresults/v1beta3.d.ts","./node_modules/googleapis/build/src/apis/toolresults/index.d.ts","./node_modules/googleapis/build/src/apis/tpu/v1.d.ts","./node_modules/googleapis/build/src/apis/tpu/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/tpu/v2.d.ts","./node_modules/googleapis/build/src/apis/tpu/v2alpha1.d.ts","./node_modules/googleapis/build/src/apis/tpu/index.d.ts","./node_modules/googleapis/build/src/apis/trafficdirector/v2.d.ts","./node_modules/googleapis/build/src/apis/trafficdirector/v3.d.ts","./node_modules/googleapis/build/src/apis/trafficdirector/index.d.ts","./node_modules/googleapis/build/src/apis/transcoder/v1.d.ts","./node_modules/googleapis/build/src/apis/transcoder/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/transcoder/index.d.ts","./node_modules/googleapis/build/src/apis/translate/v2.d.ts","./node_modules/googleapis/build/src/apis/translate/v3.d.ts","./node_modules/googleapis/build/src/apis/translate/v3beta1.d.ts","./node_modules/googleapis/build/src/apis/translate/index.d.ts","./node_modules/googleapis/build/src/apis/travelimpactmodel/v1.d.ts","./node_modules/googleapis/build/src/apis/travelimpactmodel/index.d.ts","./node_modules/googleapis/build/src/apis/vault/v1.d.ts","./node_modules/googleapis/build/src/apis/vault/index.d.ts","./node_modules/googleapis/build/src/apis/vectortile/v1.d.ts","./node_modules/googleapis/build/src/apis/vectortile/index.d.ts","./node_modules/googleapis/build/src/apis/verifiedaccess/v1.d.ts","./node_modules/googleapis/build/src/apis/verifiedaccess/v2.d.ts","./node_modules/googleapis/build/src/apis/verifiedaccess/index.d.ts","./node_modules/googleapis/build/src/apis/versionhistory/v1.d.ts","./node_modules/googleapis/build/src/apis/versionhistory/index.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/v1.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/v1beta2.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/v1p1beta1.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/v1p2beta1.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/v1p3beta1.d.ts","./node_modules/googleapis/build/src/apis/videointelligence/index.d.ts","./node_modules/googleapis/build/src/apis/vision/v1.d.ts","./node_modules/googleapis/build/src/apis/vision/v1p1beta1.d.ts","./node_modules/googleapis/build/src/apis/vision/v1p2beta1.d.ts","./node_modules/googleapis/build/src/apis/vision/index.d.ts","./node_modules/googleapis/build/src/apis/vmmigration/v1.d.ts","./node_modules/googleapis/build/src/apis/vmmigration/v1alpha1.d.ts","./node_modules/googleapis/build/src/apis/vmmigration/index.d.ts","./node_modules/googleapis/build/src/apis/vmwareengine/v1.d.ts","./node_modules/googleapis/build/src/apis/vmwareengine/index.d.ts","./node_modules/googleapis/build/src/apis/vpcaccess/v1.d.ts","./node_modules/googleapis/build/src/apis/vpcaccess/v1beta1.d.ts","./node_modules/googleapis/build/src/apis/vpcaccess/index.d.ts","./node_modules/googleapis/build/src/apis/walletobjects/v1.d.ts","./node_modules/googleapis/build/src/apis/walletobjects/index.d.ts","./node_modules/googleapis/build/src/apis/webfonts/v1.d.ts","./node_modules/googleapis/build/src/apis/webfonts/index.d.ts","./node_modules/googleapis/build/src/apis/webmasters/v3.d.ts","./node_modules/googleapis/build/src/apis/webmasters/index.d.ts","./node_modules/googleapis/build/src/apis/webrisk/v1.d.ts","./node_modules/googleapis/build/src/apis/webrisk/index.d.ts","./node_modules/googleapis/build/src/apis/websecurityscanner/v1.d.ts","./node_modules/googleapis/build/src/apis/websecurityscanner/v1alpha.d.ts","./node_modules/googleapis/build/src/apis/websecurityscanner/v1beta.d.ts","./node_modules/googleapis/build/src/apis/websecurityscanner/index.d.ts","./node_modules/googleapis/build/src/apis/workflowexecutions/v1.d.ts","./node_modules/googleapis/build/src/apis/workflowexecutions/v1beta.d.ts","./node_modules/googleapis/build/src/apis/workflowexecutions/index.d.ts","./node_modules/googleapis/build/src/apis/workflows/v1.d.ts","./node_modules/googleapis/build/src/apis/workflows/v1beta.d.ts","./node_modules/googleapis/build/src/apis/workflows/index.d.ts","./node_modules/googleapis/build/src/apis/workloadmanager/v1.d.ts","./node_modules/googleapis/build/src/apis/workloadmanager/index.d.ts","./node_modules/googleapis/build/src/apis/workspaceevents/v1.d.ts","./node_modules/googleapis/build/src/apis/workspaceevents/index.d.ts","./node_modules/googleapis/build/src/apis/workstations/v1.d.ts","./node_modules/googleapis/build/src/apis/workstations/v1beta.d.ts","./node_modules/googleapis/build/src/apis/workstations/index.d.ts","./node_modules/googleapis/build/src/apis/youtube/v3.d.ts","./node_modules/googleapis/build/src/apis/youtube/index.d.ts","./node_modules/googleapis/build/src/apis/youtubeanalytics/v1.d.ts","./node_modules/googleapis/build/src/apis/youtubeanalytics/v2.d.ts","./node_modules/googleapis/build/src/apis/youtubeanalytics/index.d.ts","./node_modules/googleapis/build/src/apis/youtubereporting/v1.d.ts","./node_modules/googleapis/build/src/apis/youtubereporting/index.d.ts","./node_modules/googleapis/build/src/apis/index.d.ts","./node_modules/googleapis/build/src/googleapis.d.ts","./node_modules/googleapis/build/src/index.d.ts","./lib/youtube/errors.ts","./lib/youtube/upload.ts","./lib/auth.ts","./lib/session.ts","./app/api/account/api-key/route.ts","./node_modules/ioredis/built/types.d.ts","./node_modules/ioredis/built/command.d.ts","./node_modules/ioredis/built/scanstream.d.ts","./node_modules/ioredis/built/utils/rediscommander.d.ts","./node_modules/ioredis/built/transaction.d.ts","./node_modules/ioredis/built/utils/commander.d.ts","./node_modules/ioredis/built/connectors/abstractconnector.d.ts","./node_modules/ioredis/built/connectors/connectorconstructor.d.ts","./node_modules/ioredis/built/connectors/sentinelconnector/types.d.ts","./node_modules/ioredis/built/connectors/sentinelconnector/sentineliterator.d.ts","./node_modules/ioredis/built/connectors/sentinelconnector/index.d.ts","./node_modules/ioredis/built/connectors/standaloneconnector.d.ts","./node_modules/ioredis/built/redis/redisoptions.d.ts","./node_modules/ioredis/built/cluster/util.d.ts","./node_modules/ioredis/built/cluster/clusteroptions.d.ts","./node_modules/ioredis/built/cluster/index.d.ts","./node_modules/denque/index.d.ts","./node_modules/ioredis/built/subscriptionset.d.ts","./node_modules/ioredis/built/datahandler.d.ts","./node_modules/ioredis/built/tracing.d.ts","./node_modules/ioredis/built/redis.d.ts","./node_modules/ioredis/built/pipeline.d.ts","./node_modules/ioredis/built/index.d.ts","./lib/api-rate-limit.ts","./app/api/account/api-rate-limit/route.ts","./lib/quota-extensions.ts","./app/api/account/api-rate-limit-extension-request/route.ts","./node_modules/stripe/esm/net/httpclient.d.ts","./node_modules/stripe/esm/stripecontext.d.ts","./node_modules/stripe/esm/apiversion.d.ts","./node_modules/stripe/esm/lib.d.ts","./node_modules/stripe/esm/striperesource.d.ts","./node_modules/stripe/esm/crypto/cryptoprovider.d.ts","./node_modules/stripe/esm/stripeemitter.d.ts","./node_modules/stripe/esm/platform/platformfunctions.d.ts","./node_modules/stripe/esm/decimal.d.ts","./node_modules/stripe/esm/shared.d.ts","./node_modules/stripe/esm/resources/billing/metereventsummaries.d.ts","./node_modules/stripe/esm/resources/billing/meters.d.ts","./node_modules/stripe/esm/resources/coupons.d.ts","./node_modules/stripe/esm/resources/promotioncodes.d.ts","./node_modules/stripe/esm/resources/discounts.d.ts","./node_modules/stripe/esm/resources/taxrates.d.ts","./node_modules/stripe/esm/resources/creditnotelineitems.d.ts","./node_modules/stripe/esm/resources/feerefunds.d.ts","./node_modules/stripe/esm/resources/capabilities.d.ts","./node_modules/stripe/esm/resources/bankaccounts.d.ts","./node_modules/stripe/esm/resources/cards.d.ts","./node_modules/stripe/esm/resources/externalaccounts.d.ts","./node_modules/stripe/esm/resources/loginlinks.d.ts","./node_modules/stripe/esm/multipart.d.ts","./node_modules/stripe/esm/resources/filelinks.d.ts","./node_modules/stripe/esm/resources/files.d.ts","./node_modules/stripe/esm/resources/persons.d.ts","./node_modules/stripe/esm/resources/applications.d.ts","./node_modules/stripe/esm/resources/taxids.d.ts","./node_modules/stripe/esm/resources/accounts.d.ts","./node_modules/stripe/esm/resources/paymentintentamountdetailslineitems.d.ts","./node_modules/stripe/esm/resources/mandates.d.ts","./node_modules/stripe/esm/resources/sourcetransactions.d.ts","./node_modules/stripe/esm/resources/sources.d.ts","./node_modules/stripe/esm/resources/customersources.d.ts","./node_modules/stripe/esm/resources/setupintents.d.ts","./node_modules/stripe/esm/resources/setupattempts.d.ts","./node_modules/stripe/esm/resources/paymentmethods.d.ts","./node_modules/stripe/esm/resources/reviews.d.ts","./node_modules/stripe/esm/resources/paymentintents.d.ts","./node_modules/stripe/esm/resources/transferreversals.d.ts","./node_modules/stripe/esm/resources/transfers.d.ts","./node_modules/stripe/esm/resources/charges.d.ts","./node_modules/stripe/esm/resources/applicationfees.d.ts","./node_modules/stripe/esm/resources/connectcollectiontransfers.d.ts","./node_modules/stripe/esm/resources/customercashbalancetransactions.d.ts","./node_modules/stripe/esm/resources/disputes.d.ts","./node_modules/stripe/esm/resources/payouts.d.ts","./node_modules/stripe/esm/resources/reservetransactions.d.ts","./node_modules/stripe/esm/resources/taxdeductedatsources.d.ts","./node_modules/stripe/esm/resources/topups.d.ts","./node_modules/stripe/esm/resources/issuing/cardholders.d.ts","./node_modules/stripe/esm/resources/issuing/physicalbundles.d.ts","./node_modules/stripe/esm/resources/issuing/personalizationdesigns.d.ts","./node_modules/stripe/esm/resources/issuing/cards.d.ts","./node_modules/stripe/esm/resources/issuing/tokens.d.ts","./node_modules/stripe/esm/resources/issuing/disputes.d.ts","./node_modules/stripe/esm/resources/issuing/transactions.d.ts","./node_modules/stripe/esm/resources/issuing/authorizations.d.ts","./node_modules/stripe/esm/resources/issuing/index.d.ts","./node_modules/stripe/esm/resources/balancetransactionsources.d.ts","./node_modules/stripe/esm/resources/balancetransactions.d.ts","./node_modules/stripe/esm/resources/refunds.d.ts","./node_modules/stripe/esm/resources/entitlements/features.d.ts","./node_modules/stripe/esm/resources/entitlements/activeentitlements.d.ts","./node_modules/stripe/esm/resources/entitlements/activeentitlementsummaries.d.ts","./node_modules/stripe/esm/resources/entitlements/index.d.ts","./node_modules/stripe/esm/resources/productfeatures.d.ts","./node_modules/stripe/esm/resources/prices.d.ts","./node_modules/stripe/esm/resources/taxcodes.d.ts","./node_modules/stripe/esm/resources/products.d.ts","./node_modules/stripe/esm/resources/plans.d.ts","./node_modules/stripe/esm/resources/subscriptionitems.d.ts","./node_modules/stripe/esm/resources/confirmationtokens.d.ts","./node_modules/stripe/esm/resources/testhelpers/confirmationtokens.d.ts","./node_modules/stripe/esm/resources/testhelpers/customers.d.ts","./node_modules/stripe/esm/resources/testhelpers/refunds.d.ts","./node_modules/stripe/esm/resources/testhelpers/testclocks.d.ts","./node_modules/stripe/esm/resources/testhelpers/issuing/authorizations.d.ts","./node_modules/stripe/esm/resources/testhelpers/issuing/cards.d.ts","./node_modules/stripe/esm/resources/testhelpers/issuing/personalizationdesigns.d.ts","./node_modules/stripe/esm/resources/testhelpers/issuing/transactions.d.ts","./node_modules/stripe/esm/resources/testhelpers/issuing/index.d.ts","./node_modules/stripe/esm/resources/terminal/locations.d.ts","./node_modules/stripe/esm/resources/terminal/readers.d.ts","./node_modules/stripe/esm/resources/testhelpers/terminal/readers.d.ts","./node_modules/stripe/esm/resources/testhelpers/terminal/index.d.ts","./node_modules/stripe/esm/resources/treasury/creditreversals.d.ts","./node_modules/stripe/esm/resources/treasury/debitreversals.d.ts","./node_modules/stripe/esm/resources/treasury/outboundpayments.d.ts","./node_modules/stripe/esm/resources/treasury/outboundtransfers.d.ts","./node_modules/stripe/esm/resources/treasury/receivedcredits.d.ts","./node_modules/stripe/esm/resources/treasury/receiveddebits.d.ts","./node_modules/stripe/esm/resources/treasury/transactionentries.d.ts","./node_modules/stripe/esm/resources/treasury/transactions.d.ts","./node_modules/stripe/esm/resources/treasury/inboundtransfers.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/inboundtransfers.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/outboundpayments.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/outboundtransfers.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/receivedcredits.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/receiveddebits.d.ts","./node_modules/stripe/esm/resources/testhelpers/treasury/index.d.ts","./node_modules/stripe/esm/resources/testhelpers/index.d.ts","./node_modules/stripe/esm/resources/subscriptionschedules.d.ts","./node_modules/stripe/esm/resources/subscriptions.d.ts","./node_modules/stripe/esm/resources/invoicelineitems.d.ts","./node_modules/stripe/esm/resources/paymentrecords.d.ts","./node_modules/stripe/esm/resources/invoicepayments.d.ts","./node_modules/stripe/esm/resources/shippingrates.d.ts","./node_modules/stripe/esm/resources/invoices.d.ts","./node_modules/stripe/esm/resources/creditnotes.d.ts","./node_modules/stripe/esm/resources/lineitems.d.ts","./node_modules/stripe/esm/resources/paymentlinks.d.ts","./node_modules/stripe/esm/resources/checkout/sessions.d.ts","./node_modules/stripe/esm/resources/checkout/index.d.ts","./node_modules/stripe/esm/resources/customerbalancetransactions.d.ts","./node_modules/stripe/esm/resources/cashbalances.d.ts","./node_modules/stripe/esm/resources/fundinginstructions.d.ts","./node_modules/stripe/esm/resources/customers.d.ts","./node_modules/stripe/esm/resources/billing/alerts.d.ts","./node_modules/stripe/esm/resources/billing/creditbalancesummary.d.ts","./node_modules/stripe/esm/resources/billing/creditgrants.d.ts","./node_modules/stripe/esm/resources/billing/creditbalancetransactions.d.ts","./node_modules/stripe/esm/resources/billing/meterevents.d.ts","./node_modules/stripe/esm/resources/billing/metereventadjustments.d.ts","./node_modules/stripe/esm/resources/billing/alerttriggereds.d.ts","./node_modules/stripe/esm/resources/billing/index.d.ts","./node_modules/stripe/esm/resources/billingportal/configurations.d.ts","./node_modules/stripe/esm/resources/billingportal/sessions.d.ts","./node_modules/stripe/esm/resources/billingportal/index.d.ts","./node_modules/stripe/esm/resources/climate/suppliers.d.ts","./node_modules/stripe/esm/resources/climate/products.d.ts","./node_modules/stripe/esm/resources/climate/orders.d.ts","./node_modules/stripe/esm/resources/climate/index.d.ts","./node_modules/stripe/esm/resources/financialconnections/accountowners.d.ts","./node_modules/stripe/esm/resources/financialconnections/accountownerships.d.ts","./node_modules/stripe/esm/resources/financialconnections/accounts.d.ts","./node_modules/stripe/esm/resources/financialconnections/sessions.d.ts","./node_modules/stripe/esm/resources/financialconnections/transactions.d.ts","./node_modules/stripe/esm/resources/financialconnections/index.d.ts","./node_modules/stripe/esm/resources/identity/verificationreports.d.ts","./node_modules/stripe/esm/resources/identity/verificationsessions.d.ts","./node_modules/stripe/esm/resources/identity/index.d.ts","./node_modules/stripe/esm/resources/radar/earlyfraudwarnings.d.ts","./node_modules/stripe/esm/resources/radar/paymentevaluations.d.ts","./node_modules/stripe/esm/resources/radar/valuelistitems.d.ts","./node_modules/stripe/esm/resources/radar/valuelists.d.ts","./node_modules/stripe/esm/resources/radar/index.d.ts","./node_modules/stripe/esm/resources/reporting/reportruns.d.ts","./node_modules/stripe/esm/resources/reporting/reporttypes.d.ts","./node_modules/stripe/esm/resources/reporting/index.d.ts","./node_modules/stripe/esm/resources/reserve/plans.d.ts","./node_modules/stripe/esm/resources/reserve/holds.d.ts","./node_modules/stripe/esm/resources/reserve/releases.d.ts","./node_modules/stripe/esm/resources/reserve/index.d.ts","./node_modules/stripe/esm/resources/sigma/scheduledqueryruns.d.ts","./node_modules/stripe/esm/resources/sigma/index.d.ts","./node_modules/stripe/esm/resources/tax/associations.d.ts","./node_modules/stripe/esm/resources/tax/calculationlineitems.d.ts","./node_modules/stripe/esm/resources/tax/calculations.d.ts","./node_modules/stripe/esm/resources/tax/registrations.d.ts","./node_modules/stripe/esm/resources/tax/settings.d.ts","./node_modules/stripe/esm/resources/tax/transactionlineitems.d.ts","./node_modules/stripe/esm/resources/tax/transactions.d.ts","./node_modules/stripe/esm/resources/tax/index.d.ts","./node_modules/stripe/esm/resources/terminal/configurations.d.ts","./node_modules/stripe/esm/resources/terminal/connectiontokens.d.ts","./node_modules/stripe/esm/resources/terminal/onboardinglinks.d.ts","./node_modules/stripe/esm/resources/terminal/index.d.ts","./node_modules/stripe/esm/resources/treasury/financialaccountfeatures.d.ts","./node_modules/stripe/esm/resources/treasury/financialaccounts.d.ts","./node_modules/stripe/esm/resources/treasury/index.d.ts","./node_modules/stripe/esm/resources/balance.d.ts","./node_modules/stripe/esm/resources/balancesettings.d.ts","./node_modules/stripe/esm/resources/invoiceitems.d.ts","./node_modules/stripe/esm/resources/quotes.d.ts","./node_modules/stripe/esm/resources/sourcemandatenotifications.d.ts","./node_modules/stripe/esm/resources/events.d.ts","./node_modules/stripe/esm/webhooks.d.ts","./node_modules/stripe/esm/resources/accountlinks.d.ts","./node_modules/stripe/esm/resources/accountsessions.d.ts","./node_modules/stripe/esm/resources/applepaydomains.d.ts","./node_modules/stripe/esm/resources/countryspecs.d.ts","./node_modules/stripe/esm/resources/customersessions.d.ts","./node_modules/stripe/esm/resources/ephemeralkeys.d.ts","./node_modules/stripe/esm/resources/exchangerates.d.ts","./node_modules/stripe/esm/resources/invoicerenderingtemplates.d.ts","./node_modules/stripe/esm/resources/oauth.d.ts","./node_modules/stripe/esm/resources/paymentattemptrecords.d.ts","./node_modules/stripe/esm/resources/paymentmethodconfigurations.d.ts","./node_modules/stripe/esm/resources/paymentmethoddomains.d.ts","./node_modules/stripe/esm/resources/tokens.d.ts","./node_modules/stripe/esm/resources/webhookendpoints.d.ts","./node_modules/stripe/esm/resourcenamespace.d.ts","./node_modules/stripe/esm/resources.d.ts","./node_modules/stripe/esm/resources/apps/secrets.d.ts","./node_modules/stripe/esm/resources/apps/index.d.ts","./node_modules/stripe/esm/resources/forwarding/requests.d.ts","./node_modules/stripe/esm/resources/forwarding/index.d.ts","./node_modules/stripe/esm/resources/v2/deletedobject.d.ts","./node_modules/stripe/esm/resources/v2/billing/meterevents.d.ts","./node_modules/stripe/esm/resources/v2/billing/metereventadjustments.d.ts","./node_modules/stripe/esm/resources/v2/billing/metereventsession.d.ts","./node_modules/stripe/esm/resources/v2/billing/metereventstream.d.ts","./node_modules/stripe/esm/resources/v2/billing/index.d.ts","./node_modules/stripe/esm/resources/v2/commerce/productcatalogimports.d.ts","./node_modules/stripe/esm/resources/v2/commerce/productcatalog/imports.d.ts","./node_modules/stripe/esm/resources/v2/commerce/productcatalog/index.d.ts","./node_modules/stripe/esm/resources/v2/commerce/index.d.ts","./node_modules/stripe/esm/resources/v2/v2amounts.d.ts","./node_modules/stripe/esm/resources/v2/core/accountpersons.d.ts","./node_modules/stripe/esm/resources/v2/core/accounts/persons.d.ts","./node_modules/stripe/esm/resources/v2/core/accountpersontokens.d.ts","./node_modules/stripe/esm/resources/v2/core/accounts/persontokens.d.ts","./node_modules/stripe/esm/resources/v2/core/accounts.d.ts","./node_modules/stripe/esm/resources/v2/core/accountlinks.d.ts","./node_modules/stripe/esm/resources/v2/core/accounttokens.d.ts","./node_modules/stripe/esm/resources/v2/core/events.d.ts","./node_modules/stripe/esm/resources/v2/core/eventdestinations.d.ts","./node_modules/stripe/esm/resources/v2/core/index.d.ts","./node_modules/stripe/esm/resources/v2/index.d.ts","./node_modules/stripe/esm/stripe.core.d.ts","./node_modules/stripe/esm/types.d.ts","./node_modules/stripe/esm/requestsender.d.ts","./node_modules/stripe/esm/error.d.ts","./node_modules/stripe/esm/stripe.esm.node.d.ts","./lib/stripe.ts","./app/api/account/billing-portal/route.ts","./app/api/account/cancel-subscription/route.ts","./lib/stripe-checkout.ts","./app/api/account/credits/route.ts","./app/api/account/delete/route.ts","./app/api/account/quota-extension-request/route.ts","./app/api/account/subscribe/route.ts","./app/api/admin/quota-extension-request/[id]/route.ts","./app/api/admin/reset-credits/route.ts","./app/api/auth/[...nextauth]/route.ts","./app/api/dev/grant-credits/route.ts","./lib/watermark.ts","./lib/entitlements.ts","./node_modules/strtok3/lib/stream/errors.d.ts","./node_modules/strtok3/lib/stream/abstractstreamreader.d.ts","./node_modules/strtok3/lib/stream/streamreader.d.ts","./node_modules/strtok3/lib/stream/webstreamreader.d.ts","./node_modules/strtok3/lib/stream/webstreambyobreader.d.ts","./node_modules/strtok3/lib/stream/webstreamdefaultreader.d.ts","./node_modules/strtok3/lib/stream/webstreamreaderfactory.d.ts","./node_modules/strtok3/lib/stream/index.d.ts","./node_modules/@tokenizer/token/index.d.ts","./node_modules/strtok3/lib/types.d.ts","./node_modules/strtok3/lib/abstracttokenizer.d.ts","./node_modules/strtok3/lib/readstreamtokenizer.d.ts","./node_modules/strtok3/lib/buffertokenizer.d.ts","./node_modules/strtok3/lib/blobtokenizer.d.ts","./node_modules/strtok3/lib/core.d.ts","./node_modules/music-metadata/lib/common/generictagtypes.d.ts","./node_modules/music-metadata/lib/apev2/apev2token.d.ts","./node_modules/music-metadata/lib/ebml/types.d.ts","./node_modules/music-metadata/lib/matroska/types.d.ts","./node_modules/music-metadata/lib/common/util.d.ts","./node_modules/music-metadata/lib/id3v2/id3v2token.d.ts","./node_modules/music-metadata/lib/type.d.ts","./node_modules/music-metadata/lib/parseerror.d.ts","./node_modules/music-metadata/lib/core.d.ts","./lib/types.ts","./lib/audio-tags.ts","./node_modules/ffmpeg-static/types/index.d.ts","./lib/branding.ts","./lib/storage.ts","./lib/ffmpeg/encode.ts","./lib/fs-utils.ts","./node_modules/bullmq/dist/esm/classes/async-fifo-queue.d.ts","./node_modules/bullmq/dist/esm/interfaces/backoff-options.d.ts","./node_modules/bullmq/dist/esm/types/keep-jobs.d.ts","./node_modules/bullmq/dist/esm/interfaces/parent-options.d.ts","./node_modules/cron-parser/types/common.d.ts","./node_modules/cron-parser/types/index.d.ts","./node_modules/bullmq/dist/esm/interfaces/repeat-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/base-job-options.d.ts","./node_modules/bullmq/dist/esm/types/deduplication-options.d.ts","./node_modules/bullmq/dist/esm/types/job-options.d.ts","./node_modules/bullmq/dist/esm/types/job-progress.d.ts","./node_modules/bullmq/dist/esm/interfaces/parent.d.ts","./node_modules/bullmq/dist/esm/interfaces/job-json.d.ts","./node_modules/bullmq/dist/esm/types/job-json-sandbox.d.ts","./node_modules/bullmq/dist/esm/interfaces/minimal-job.d.ts","./node_modules/bullmq/dist/esm/types/backoff-strategy.d.ts","./node_modules/bullmq/dist/esm/classes/backoffs.d.ts","./node_modules/bullmq/dist/esm/types/repeat-strategy.d.ts","./node_modules/bullmq/dist/esm/interfaces/advanced-options.d.ts","./node_modules/bullmq/dist/esm/enums/parent-command.d.ts","./node_modules/bullmq/dist/esm/interfaces/child-message.d.ts","./node_modules/bullmq/dist/esm/interfaces/redis-client.d.ts","./node_modules/bullmq/dist/esm/interfaces/connection.d.ts","./node_modules/bullmq/dist/esm/types/database-type.d.ts","./node_modules/bullmq/dist/esm/types/finished-status.d.ts","./node_modules/bullmq/dist/esm/types/job-scheduler-template-options.d.ts","./node_modules/bullmq/dist/esm/types/job-type.d.ts","./node_modules/bullmq/dist/esm/types/index.d.ts","./node_modules/bullmq/node_modules/ioredis/built/types.d.ts","./node_modules/bullmq/node_modules/ioredis/built/command.d.ts","./node_modules/bullmq/node_modules/ioredis/built/scanstream.d.ts","./node_modules/bullmq/node_modules/ioredis/built/utils/rediscommander.d.ts","./node_modules/bullmq/node_modules/ioredis/built/transaction.d.ts","./node_modules/bullmq/node_modules/ioredis/built/utils/commander.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/abstractconnector.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/connectorconstructor.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/sentinelconnector/types.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/sentinelconnector/sentineliterator.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/sentinelconnector/index.d.ts","./node_modules/bullmq/node_modules/ioredis/built/connectors/standaloneconnector.d.ts","./node_modules/bullmq/node_modules/ioredis/built/redis/redisoptions.d.ts","./node_modules/bullmq/node_modules/ioredis/built/cluster/util.d.ts","./node_modules/bullmq/node_modules/ioredis/built/cluster/clusteroptions.d.ts","./node_modules/bullmq/node_modules/ioredis/built/cluster/index.d.ts","./node_modules/bullmq/node_modules/ioredis/built/subscriptionset.d.ts","./node_modules/bullmq/node_modules/ioredis/built/datahandler.d.ts","./node_modules/bullmq/node_modules/ioredis/built/redis.d.ts","./node_modules/bullmq/node_modules/ioredis/built/pipeline.d.ts","./node_modules/bullmq/node_modules/ioredis/built/index.d.ts","./node_modules/bullmq/dist/esm/interfaces/redis-options.d.ts","./node_modules/bullmq/dist/esm/enums/child-command.d.ts","./node_modules/bullmq/dist/esm/enums/error-code.d.ts","./node_modules/bullmq/dist/esm/enums/metrics-time.d.ts","./node_modules/bullmq/dist/esm/enums/telemetry-attributes.d.ts","./node_modules/bullmq/dist/esm/enums/index.d.ts","./node_modules/bullmq/dist/esm/interfaces/telemetry.d.ts","./node_modules/bullmq/dist/esm/interfaces/queue-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/flow-job.d.ts","./node_modules/bullmq/dist/esm/interfaces/ioredis-events.d.ts","./node_modules/bullmq/dist/esm/interfaces/job-scheduler-json.d.ts","./node_modules/bullmq/dist/esm/interfaces/lock-manager-worker-context.d.ts","./node_modules/bullmq/dist/esm/interfaces/metrics-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/metrics.d.ts","./node_modules/bullmq/dist/esm/classes/queue-keys.d.ts","./node_modules/bullmq/dist/esm/interfaces/script-queue-context.d.ts","./node_modules/bullmq/dist/esm/interfaces/minimal-queue.d.ts","./node_modules/bullmq/dist/esm/interfaces/parent-message.d.ts","./node_modules/bullmq/dist/esm/interfaces/queue-meta.d.ts","./node_modules/bullmq/dist/esm/interfaces/rate-limiter-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/redis-streams.d.ts","./node_modules/bullmq/dist/esm/interfaces/repeatable-job.d.ts","./node_modules/bullmq/dist/esm/interfaces/repeatable-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/retry-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/sandboxed-job.d.ts","./node_modules/bullmq/dist/esm/interfaces/sandboxed-job-processor.d.ts","./node_modules/bullmq/dist/esm/interfaces/sandboxed-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/worker-options.d.ts","./node_modules/bullmq/dist/esm/interfaces/receiver.d.ts","./node_modules/bullmq/dist/esm/interfaces/index.d.ts","./node_modules/bullmq/dist/esm/classes/child.d.ts","./node_modules/bullmq/dist/esm/classes/child-pool.d.ts","./node_modules/bullmq/dist/esm/classes/child-processor.d.ts","./node_modules/bullmq/dist/esm/classes/errors/connection-closed-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/delayed-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/rate-limit-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/unrecoverable-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/waiting-children-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/waiting-error.d.ts","./node_modules/bullmq/dist/esm/classes/errors/index.d.ts","./node_modules/bullmq/dist/esm/classes/scripts.d.ts","./node_modules/bullmq/dist/esm/classes/redis-connection.d.ts","./node_modules/bullmq/dist/esm/classes/queue-base.d.ts","./node_modules/bullmq/dist/esm/classes/queue-events.d.ts","./node_modules/bullmq/dist/esm/classes/job.d.ts","./node_modules/bullmq/dist/esm/classes/flow-producer.d.ts","./node_modules/bullmq/dist/esm/classes/ioredis-client.d.ts","./node_modules/bullmq/dist/esm/classes/node-redis-client.d.ts","./node_modules/bullmq/dist/esm/classes/bun-redis-client.d.ts","./node_modules/bullmq/dist/esm/classes/job-scheduler.d.ts","./node_modules/node-abort-controller/index.d.ts","./node_modules/bullmq/dist/esm/classes/abort-controller.d.ts","./node_modules/bullmq/dist/esm/classes/lock-manager.d.ts","./node_modules/bullmq/dist/esm/classes/queue-events-producer.d.ts","./node_modules/bullmq/dist/esm/classes/queue-getters.d.ts","./node_modules/bullmq/dist/esm/classes/repeat.d.ts","./node_modules/bullmq/dist/esm/classes/queue.d.ts","./node_modules/bullmq/dist/esm/classes/sandbox.d.ts","./node_modules/bullmq/dist/esm/types/processor.d.ts","./node_modules/bullmq/dist/esm/classes/worker.d.ts","./node_modules/bullmq/dist/esm/classes/index.d.ts","./node_modules/bullmq/dist/esm/utils/index.d.ts","./node_modules/bullmq/dist/esm/utils/create-scripts.d.ts","./node_modules/bullmq/dist/esm/index.d.ts","./lib/queue/client.ts","./lib/upload-paths.ts","./lib/jobs/create-job.ts","./app/api/jobs/route.ts","./app/api/jobs/[id]/route.ts","./app/api/quota/route.ts","./app/api/stripe/webhook/route.ts","./app/api/upload/route.ts","./app/api/v1/route.ts","./lib/api-auth.ts","./lib/jobs/resolve-playlist.ts","./app/api/v1/jobs/route.ts","./app/api/v1/jobs/[id]/route.ts","./app/api/v1/jobs/batch/route.ts","./app/api/v1/playlists/route.ts","./app/api/v1/upload/route.ts","./app/api/youtube/playlists/route.ts","./hooks/useinview.ts","./hooks/usemockupprogress.ts","./lib/legal/constants.ts","./scripts/watermark.test.ts","./types/next-auth.d.ts","./worker/index.ts","./node_modules/next/dist/compiled/@next/font/dist/types.d.ts","./node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","./node_modules/next/font/google/index.d.ts","./node_modules/next-auth/client/_utils.d.ts","./node_modules/next-auth/react/types.d.ts","./node_modules/next-auth/react/index.d.ts","./app/providers.tsx","./app/layout.tsx","./components/scrollreveal.tsx","./components/sectionscrolltitle.tsx","./components/benefitssection.tsx","./components/downloadsection.tsx","./components/logo.tsx","./components/mobilesidebar.tsx","./components/landingnavbar.tsx","./components/signinbutton.tsx","./components/pricingsection.tsx","./components/stepssection.tsx","./components/footer.tsx","./components/supportsection.tsx","./app/page.tsx","./components/signoutbutton.tsx","./components/dashboardnav.tsx","./components/legalfooter.tsx","./components/dashboardshell.tsx","./components/youtubelimitbanner.tsx","./components/recentyoutubelimitalert.tsx","./components/categoryselect.tsx","./components/upgradeprobutton.tsx","./components/upgradeprolink.tsx","./components/playlistselect.tsx","./components/privacytoggle.tsx","./components/resolutionselect.tsx","./components/watermarkpreview.tsx","./components/uploadform.tsx","./app/dashboard/page.tsx","./app/dashboard/api-docs/page.tsx","./components/jobhistory.tsx","./app/dashboard/history/page.tsx","./components/accountprivacyactions.tsx","./components/creditpurchasepanel.tsx","./components/planbillingactions.tsx","./components/apikeysettings.tsx","./app/dashboard/settings/page.tsx","./components/jobprogress.tsx","./app/jobs/[id]/page.tsx","./components/legalpagelayout.tsx","./app/privacy/page.tsx","./app/refund/page.tsx","./app/terms/page.tsx","./components/paygpricecalculator.tsx","./.next/types/cache-life.d.ts","./.next/types/validator.ts","./.next/types/app/layout.ts","./.next/types/app/page.ts","./.next/types/app/api/account/api-rate-limit/route.ts","./.next/types/app/api/account/billing-portal/route.ts","./.next/types/app/api/account/cancel-subscription/route.ts","./.next/types/app/api/account/credits/route.ts","./.next/types/app/api/account/quota-extension-request/route.ts","./.next/types/app/api/account/subscribe/route.ts","./.next/types/app/api/auth/[...nextauth]/route.ts","./.next/types/app/api/jobs/route.ts","./.next/types/app/api/quota/route.ts","./.next/types/app/api/stripe/webhook/route.ts","./.next/types/app/dashboard/page.ts","./.next/types/app/dashboard/settings/page.ts","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/json5/index.d.ts"],"fileIdsList":[[100,149,166,167,496,1513],[100,149,166,167,496,1743],[100,149,166,167,496,1744],[100,149,166,167,496,1746],[100,149,166,167,496,1748],[100,149,166,167,496,1749],[100,149,166,167,496,1752],[100,149,166,167,496,1903],[100,149,166,167,496,1905],[100,149,166,167,496,1906],[100,149,166,167,342,1958],[100,149,166,167,342,1966],[100,149,166,167,342,1930],[100,149,166,167,342,1943],[100,149,166,167,449,450,451,452],[100,149,166,167],[83,100,149,166,167,496,499,1488,1513,1515,1743,1744,1746,1747,1748,1749,1750,1751,1752,1753,1903,1904,1905,1906,1907,1908,1911,1912,1913,1914,1915,1916,1930,1943,1958,1959,1961,1966,1968,1970,1971,1972],[100,149,166,167,496,535,536,1487],[100,149,166,167,496,536,1487,1514],[100,149,166,167,496,536,1487,1512],[100,149,166,167,496,534,1487,1742],[100,149,166,167,496,534,611,1487,1742],[100,149,166,167,496,534,608,611,1487,1742,1745],[100,149,166,167,496,534,1487],[100,149,166,167,496,1487,1514],[100,149,166,167,496,1514],[100,149,166,167,496,534,611],[100,149,166,167,605,1486,1921],[100,149,166,167,496,608,611,1487,1742],[100,149,166,167,496,534,1487,1755,1780,1902],[100,149,166,167,496,612,1487],[100,149,166,167,496,534,608,610,611,1741,1742],[100,149,166,167,496,1487,1755,1902],[100,149,166,167,496,534,1909],[100,149,166,167,496,533,609,610,612,1755,1780,1786,1902,1909,1910],[100,149,166,167,496,534,1755,1780,1902,1909,1910],[100,149,166,167,496,1485,1909,1910],[100,149,166,167,496],[100,149,166,167,496,1755,1902,1909],[100,149,166,167,496,536,1485,1487,1910],[100,149,166,167,473,483,534,536,605,1486,1921,1947,1952],[100,149,166,167,483,605,1486,1921,1947,1960],[100,149,166,167,483,605,1486,1921,1947,1949,1957],[100,149,166,167,473,483,533,534,535,536,605,612,1486,1512,1514,1742,1921,1947,1951,1962,1963,1964,1965],[100,149,166,167,483,605,1486,1921,1947,1967],[100,149,166,167,500,1925,1929],[100,149,166,167,473,605,1486,1921,1933,1934,1937,1938,1939,1940,1941,1942],[100,149,166,167,500,1919,1969],[100,149,166,167,1928],[100,149,166,167,473,500,1919,1969],[86,100,149,166,167,610,1928],[86,100,149,166,167],[86,100,149,166,167,471,1917,1918,1931,1932],[100,149,166,167,609],[86,100,149,166,167,483,608,1951],[86,100,149,166,167,473,483,1928,1935,1936,1944],[86,100,149,166,167,1945,1946],[86,100,149,166,167,610,1931,1932],[86,100,149,166,167,473,610,1935],[86,100,149,166,167,473,1484,1780,1948],[86,100,149,166,167,1935,1936],[86,100,149,166,167,473],[86,100,149,166,167,473,1919,1935],[100,149,166,167,473,1783],[86,100,149,166,167,473,608],[86,100,149,166,167,483,610],[86,100,149,166,167,1952],[86,100,149,166,167,473,610,1783,1931,1932,1938],[100,149,166,167,533],[86,100,149,166,167,1484,1948],[100,149,166,167,533,610],[100,149,166,167,1917,1918,1931],[86,100,149,166,167,483],[86,100,149,166,167,473,608,610,1951],[86,100,149,166,167,483,533,609,1754,1780,1781,1783,1950,1951,1952,1953,1954,1955,1956],[86,100,149,166,167,1754,1783,1951],[100,149,166,167,1484],[100,149,166,167,496,535,536,1487,1512],[100,149,154,166,167,534],[100,149,166,167,534,536,1511],[100,149,166,167,1779,1780],[100,149,166,167,534,605,606,607,612,1485,1921],[100,149,166,167,533,534,608,610],[100,149,154,166,167],[100,149,166,167,533,536,610,1754],[100,149,150,162,166,167,171,609,1754,1782,1783,1784],[100,149,161,162,166,167,181,182],[100,149,162,166,167,171,533,534,536,609,610,612,1754,1755,1780,1781,1784,1785,1786,1900,1901],[100,149,166,167,533,536,1485,1780],[100,149,166,167,610,1783],[100,149,166,167,533,536,609],[100,149,166,167,609,1780,1899],[100,149,166,167,533,534,610,1512],[100,149,166,167,533,534,536,608,610,611],[100,149,166,167,496,534,605,1486,1921],[100,149,166,167,171],[100,149,166,167,534,608,1741,1742],[100,149,166,167,1741],[100,149,166,167,533,1754],[100,149,154,166,167,171,1784],[100,149,161,166,167,533,534,607,609,1483,1484],[83,100,149,166,167,500,501],[100,149,166,167,500],[100,149,166,167,531],[100,149,166,167,530],[100,149,166,167,548,556,558],[100,149,166,167,540,543,544,545,546,548,556,557],[100,149,166,167,540,548],[100,149,166,167,548],[100,149,166,167,547,548],[100,149,166,167,539,541,548,557],[100,149,166,167,548,550,556],[100,149,166,167,548,552,556],[100,149,166,167,541,548,551,553,555],[100,149,166,167,548,553],[100,149,166,167,538,547,548,554,556],[100,149,166,167,548,556],[100,149,166,167,537,538,539,540,542,547,556],[100,149,166,167,532],[100,146,147,149,166,167],[100,148,149,166,167],[149,166,167],[100,149,154,166,167,184],[100,149,150,155,160,166,167,169,181,192],[100,149,150,151,160,166,167,169],[95,96,97,100,149,166,167],[100,149,152,166,167,193],[100,149,153,154,161,166,167,170],[100,149,154,166,167,181,189],[100,149,155,157,160,166,167,169],[100,148,149,156,166,167],[100,149,157,158,166,167],[100,149,159,160,166,167],[100,148,149,160,166,167],[100,149,160,161,162,166,167,181,192],[100,149,160,161,162,166,167,176,181,184],[100,141,149,157,160,163,166,167,169,181,192],[100,149,160,161,163,164,166,167,169,181,189,192],[100,149,163,165,166,167,181,189,192],[98,99,100,101,102,103,104,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198],[100,149,160,166,167],[100,149,166,167,168,192],[100,149,157,160,166,167,169,181],[100,149,166,167,170],[100,148,149,166,167,172],[100,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198],[100,149,166,167,174],[100,149,166,167,175],[100,149,160,166,167,176,177],[100,149,166,167,176,178,193,195],[100,149,161,166,167],[100,149,160,166,167,181,182,184],[100,149,166,167,183,184],[100,149,166,167,181,182],[100,149,166,167,184],[100,149,166,167,185],[100,146,149,166,167,181,186,192],[100,149,160,166,167,187,188],[100,149,166,167,187,188],[100,149,154,166,167,169,181,189],[100,149,166,167,190],[100,149,166,167,169,191],[100,149,163,166,167,175,192],[100,149,154,166,167,193],[100,149,166,167,181,194],[100,149,166,167,168,195],[100,149,166,167,196],[100,141,149,166,167],[100,141,149,160,162,166,167,172,181,184,192,194,195,197],[100,149,166,167,181,198],[86,90,100,149,166,167,200,201,202,204,444,492],[86,90,100,149,166,167,200,201,202,203,359,444,492],[86,90,100,149,166,167,200,201,203,204,444,492],[86,100,149,166,167,204,359,360],[86,100,149,166,167,204,359],[86,90,100,149,166,167,201,202,203,204,444,492],[86,90,100,149,166,167,200,202,203,204,444,492],[84,85,100,149,166,167],[100,149,166,167,1886],[100,149,166,167,1788,1801,1802],[100,149,166,167,1808],[100,149,166,167,1865,1866],[100,149,166,167,1814,1865],[100,149,150,160,166,167,197,1865],[100,149,166,167,1869,1870,1871,1872,1873,1874],[100,149,160,166,167,1850,1865,1877,1880],[100,149,166,167,1787,1803,1850,1866,1867,1868,1875,1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1888,1889,1890,1891,1892,1893,1895],[100,149,166,167,1808,1835],[100,149,166,167,1814,1865,1877,1878,1880],[100,149,166,167,1814,1865,1876,1879],[100,149,166,167,1865,1887],[100,149,160,166,167,1810,1841,1850,1865,1876,1877,1880],[100,149,166,167,1865,1877,1878],[100,149,166,167,1814,1865,1877,1878],[100,149,166,167,1814,1865,1878,1880],[100,149,166,167,1814,1865,1877,1880,1885,1890,1891],[100,149,160,166,167,1808,1814,1865],[100,149,166,167,1867,1880],[100,149,166,167,192,1814,1865,1877,1878,1880,1885,1887,1888,1891,1894],[100,149,166,167,1806,1837,1838,1839,1840],[100,149,166,167,1814,1841,1865,1894,1896,1897,1898],[100,149,166,167,1802,1804],[100,149,166,167,1788,1789,1790,1793],[100,149,166,167,1806],[100,149,160,166,167,1808],[100,149,166,167,1814,1843],[100,149,166,167,1788,1790,1793,1794,1798,1799,1801,1805,1807,1808,1809,1836,1842,1843,1844,1845,1846,1847,1848,1849,1851,1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864],[100,149,166,167,1796,1797,1798],[100,149,166,167,1814],[100,149,166,167,1841,1842],[100,149,166,167,1790,1796,1797,1798,1799,1800],[100,149,166,167,1809,1840,1842,1851],[100,149,166,167,1799,1837],[100,149,166,167,1796],[100,149,166,167,1794,1805,1836,1842],[100,149,166,167,181],[100,149,166,167,1792],[100,149,166,167,1860],[100,149,166,167,1801,1814],[100,149,150,166,167,197],[100,149,166,167,1809,1810,1843,1850],[100,149,166,167,1841],[100,149,166,167,1789,1805,1842,1843,1848,1855,1862],[100,149,166,167,1801],[100,149,166,167,1789,1795,1796,1797,1800,1802,1804,1810,1811,1812,1813],[100,149,166,167,1799],[100,149,166,167,1794,1795],[100,149,166,167,1811],[100,149,166,167,1880],[100,149,166,167,1793],[100,149,166,167,1865,1876],[100,149,166,167,1814,1835,1841,1865,1887],[100,149,157,166,167,199,1820,1827,1828],[100,149,160,166,167,199,1815,1816,1817,1819,1820,1828,1829,1833],[100,149,157,166,167,199],[100,149,166,167,199,1815],[100,149,166,167,1815],[100,149,166,167,1821],[100,149,160,166,167,189,199,1815,1821,1823,1824,1829],[100,149,166,167,1823],[100,149,166,167,1827],[100,149,166,167,169,189,199,1815,1821],[100,149,160,166,167,199,1505,1815,1831],[100,149,166,167,1815,1816,1817,1818,1821,1825,1826,1827,1828,1829,1830,1833,1834],[100,149,166,167,1816,1820,1830,1833],[100,149,160,166,167,199,1505,1815,1816,1817,1819,1820,1827,1830,1832],[100,149,166,167,1820,1822,1825,1826],[100,149,166,167,181,199],[100,149,166,167,1816],[100,149,166,167,1818],[100,149,166,167,169,189,199],[100,149,166,167,1815,1816,1818],[100,149,166,167,1791],[100,149,163,166,167,181,192],[100,149,163,166,167,192,613,614],[100,149,166,167,613,614,615],[100,149,166,167,613],[100,149,163,166,167,638],[100,149,160,166,167,616,617,618,620,623],[100,149,166,167,620,621,630,632],[100,149,166,167,616],[100,149,166,167,616,617,618,620,621,623],[100,149,166,167,616,623],[100,149,166,167,616,617,618,621,623],[100,149,166,167,616,617,618,621,623,630],[100,149,166,167,621,630,631,633,634],[100,149,166,167,181,616,617,618,621,623,624,625,627,628,629,630,635,636,645],[100,149,166,167,620,621,630],[100,149,166,167,623],[100,149,166,167,621,623,624,637],[100,149,166,167,181,618,623],[100,149,166,167,181,618,623,624,626],[100,149,166,167,175,616,617,618,619,621,622],[100,149,166,167,616,621,623],[100,149,166,167,621,630],[100,149,166,167,616,617,618,621,622,623,624,625,627,628,629,630,631,632,633,634,635,637,639,640,641,642,643,644,645],[100,149,166,167,616,645,647],[100,149,166,167,653],[100,149,166,167,616,648],[100,149,166,167,645],[100,149,166,167,647,648],[100,149,166,167,646,648],[100,149,166,167,616,645,646,647,648,649,650,651,652],[100,149,166,167,653,654],[100,149,166,167,181,199,653],[100,149,166,167,653,656],[100,149,166,167,653,658,659],[100,149,166,167,653,661,662],[100,149,166,167,653,664],[100,149,166,167,653,666],[100,149,166,167,653,668,669,670],[100,149,166,167,653,672],[100,149,166,167,653,674],[100,149,166,167,653,676,677,678],[100,149,166,167,653,680,681],[100,149,166,167,653,683,684],[100,149,166,167,653,686],[100,149,166,167,653,688,689],[100,149,166,167,653,691],[100,149,166,167,653,693,694],[100,149,166,167,653,696],[100,149,166,167,653,698],[100,149,166,167,653,700,701,702],[100,149,166,167,653,704],[100,149,166,167,653,706,707],[100,149,166,167,653,709,710],[100,149,166,167,653,712,713],[100,149,166,167,653,715],[100,149,166,167,653,717],[100,149,166,167,653,719],[100,149,166,167,653,721],[100,149,166,167,653,723,724,725,726],[100,149,166,167,653,728,729],[100,149,166,167,653,731],[100,149,166,167,653,733],[100,149,166,167,653,735],[100,149,166,167,653,737,738,739],[100,149,166,167,653,741,742],[100,149,166,167,653,744],[100,149,166,167,653,746],[100,149,166,167,653,748,749,750],[100,149,166,167,653,752,753],[100,149,166,167,653,755,756],[100,149,166,167,653,758],[100,149,166,167,653,760,761,762],[100,149,166,167,653,764],[100,149,166,167,653,766,767],[100,149,166,167,653,769],[100,149,166,167,653,771],[100,149,166,167,653,773,774],[100,149,166,167,653,776],[100,149,166,167,653,778],[100,149,166,167,653,780,781,782],[100,149,166,167,653,784,785],[100,149,166,167,653,787,788],[100,149,166,167,653,790,791],[100,149,166,167,653,793],[100,149,166,167,653,795,796],[100,149,166,167,653,798],[100,149,166,167,653,800],[100,149,166,167,653,802],[100,149,166,167,653,804],[100,149,166,167,653,806],[100,149,166,167,653,808],[100,149,166,167,653,810],[100,149,166,167,653,812],[100,149,166,167,653,814],[100,149,166,167,653,816],[100,149,166,167,653,818],[100,149,166,167,653,820,821,822,823,824,825],[100,149,166,167,653,827,828],[100,149,166,167,653,830,831,832,833,834],[100,149,166,167,653,836],[100,149,166,167,653,838,839],[100,149,166,167,653,841],[100,149,166,167,653,843],[100,149,166,167,653,845],[100,149,166,167,653,847,848,849,850,851],[100,149,166,167,653,853,854],[100,149,166,167,653,856],[100,149,166,167,653,858],[100,149,166,167,653,860],[100,149,166,167,653,862,863,864,865,866],[100,149,166,167,653,868,869],[100,149,166,167,653,871],[100,149,166,167,653,873,874],[100,149,166,167,653,876,877],[100,149,166,167,653,879,880,881],[100,149,166,167,653,883,884,885],[100,149,166,167,653,887,888],[100,149,166,167,653,890,891,892],[100,149,166,167,653,894],[100,149,166,167,653,896,897],[100,149,166,167,653,899],[100,149,166,167,653,901],[100,149,166,167,653,903,904],[100,149,166,167,653,906,907,908],[100,149,166,167,653,910,911],[100,149,166,167,653,913],[100,149,166,167,653,915],[100,149,166,167,653,917],[100,149,166,167,653,919,920],[100,149,166,167,653,922],[100,149,166,167,653,924],[100,149,166,167,653,926,927],[100,149,166,167,653,929],[100,149,166,167,653,931],[100,149,166,167,653,933,934],[100,149,166,167,653,936],[100,149,166,167,653,938],[100,149,166,167,653,940,941],[100,149,166,167,653,943,944],[100,149,166,167,653,946,947,948],[100,149,166,167,653,950,951],[100,149,166,167,653,953,954,955],[100,149,166,167,653,957],[100,149,166,167,653,959,960,961,962],[100,149,166,167,653,964,965,966,967],[100,149,166,167,653,969],[100,149,166,167,653,971],[100,149,166,167,653,973,974,975],[100,149,166,167,653,977,978,979,980,981,982,983],[100,149,166,167,653,985],[100,149,166,167,653,987,988,989,990],[100,149,166,167,653,992],[100,149,166,167,653,994,995,996],[100,149,166,167,653,998,999,1000],[100,149,166,167,653,1002],[100,149,166,167,653,1004,1005,1006],[100,149,166,167,653,1008],[100,149,166,167,653,1010,1011],[100,149,166,167,653,1013],[100,149,166,167,653,1015,1016],[100,149,166,167,653,1018],[100,149,166,167,653,1020,1021],[100,149,166,167,653,1023],[100,149,166,167,653,1025],[100,149,166,167,653,1027],[100,149,166,167,653,1029,1030],[100,149,166,167,653,1032],[100,149,166,167,653,1034,1035],[100,149,166,167,653,1037,1038],[100,149,166,167,653,1040],[100,149,166,167,653,1042],[100,149,166,167,653,1044,1045],[100,149,166,167,653,1047,1048,1049],[100,149,166,167,653,1051],[100,149,166,167,653,1053],[100,149,166,167,653,1055,1056,1057],[100,149,166,167,653,1059],[100,149,166,167,653,1061],[100,149,166,167,653,1063],[100,149,166,167,653,1065],[100,149,166,167,653,1069,1070],[100,149,166,167,653,1067],[100,149,166,167,653,1072,1073,1074],[100,149,166,167,653,1076],[100,149,166,167,653,1078,1079,1080,1081,1082,1083,1084,1085],[100,149,166,167,653,1087],[100,149,166,167,653,1089],[100,149,166,167,653,1091,1092],[100,149,166,167,653,1094],[100,149,166,167,653,1096],[100,149,166,167,653,1098,1099],[100,149,166,167,653,1101],[100,149,166,167,653,1103,1104,1105],[100,149,166,167,653,1107],[100,149,166,167,653,1109,1110],[100,149,166,167,653,1112,1113],[100,149,166,167,653,1115,1116],[100,149,166,167,653,1118],[100,149,166,167,655,657,660,663,665,667,671,673,675,679,682,685,687,690,692,695,697,699,703,705,708,711,714,716,718,720,722,727,730,732,734,736,740,743,745,747,751,754,757,759,763,765,768,770,772,775,777,779,783,786,789,792,794,797,799,801,803,805,807,809,811,813,815,817,819,826,829,835,837,840,842,844,846,852,855,857,859,861,867,870,872,875,878,882,886,889,893,895,898,900,902,905,909,912,914,916,918,921,923,925,928,930,932,935,937,939,942,945,949,952,956,958,963,968,970,972,976,984,986,991,993,997,1001,1003,1007,1009,1012,1014,1017,1019,1022,1024,1026,1028,1031,1033,1036,1039,1041,1043,1046,1050,1052,1054,1058,1060,1062,1064,1066,1068,1071,1075,1077,1086,1088,1090,1093,1095,1097,1100,1102,1106,1108,1111,1114,1117,1119,1121,1123,1128,1130,1132,1134,1139,1141,1143,1145,1147,1149,1151,1155,1157,1159,1161,1164,1175,1179,1182,1184,1187,1189,1191,1193,1195,1197,1199,1201,1203,1206,1209,1212,1215,1218,1220,1223,1225,1229,1233,1235,1237,1239,1241,1243,1245,1248,1250,1252,1254,1257,1262,1265,1267,1269,1272,1274,1278,1282,1284,1286,1288,1291,1293,1295,1298,1301,1305,1307,1309,1313,1318,1321,1324,1326,1328,1330,1332,1336,1342,1345,1348,1351,1353,1356,1359,1361,1363,1365,1367,1369,1371,1373,1377,1379,1382,1385,1387,1389,1392,1395,1397,1399,1402,1404,1409,1412,1415,1419,1421,1423,1425,1428,1430,1436,1440,1443,1445,1448,1450,1452,1454,1456,1460,1463,1466,1468,1470,1473,1475,1478,1480],[100,149,166,167,653,1120],[100,149,166,167,653,1122],[100,149,166,167,653,1124,1125,1126,1127],[100,149,166,167,653,1129],[100,149,166,167,653,1131],[100,149,166,167,653,1133],[100,149,166,167,653,1135,1136,1137,1138],[100,149,166,167,653,1140],[100,149,166,167,653,1142],[100,149,166,167,653,1144],[100,149,166,167,653,1146],[100,149,166,167,653,1148],[100,149,166,167,653,1150],[100,149,166,167,653,1152,1153,1154],[100,149,166,167,653,1156],[100,149,166,167,653,1158],[100,149,166,167,653,1160],[100,149,166,167,653,1162,1163],[100,149,166,167,653,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174],[100,149,166,167,653,1176,1177,1178],[100,149,166,167,653,1180,1181],[100,149,166,167,653,1183],[100,149,166,167,653,1185,1186],[100,149,166,167,653,1188],[100,149,166,167,653,1190],[100,149,166,167,653,1192],[100,149,166,167,653,1194],[100,149,166,167,653,1196],[100,149,166,167,653,1198],[100,149,166,167,653,1200],[100,149,166,167,653,1202],[100,149,166,167,653,1204,1205],[100,149,166,167,653,1207,1208],[100,149,166,167,653,1210,1211],[100,149,166,167,653,1213,1214],[100,149,166,167,653,1216,1217],[100,149,166,167,653,1219],[100,149,166,167,653,1221,1222],[100,149,166,167,653,1224],[100,149,166,167,653,1226,1227,1228],[100,149,166,167,653,1230,1231,1232],[100,149,166,167,653,1234],[100,149,166,167,653,1236],[100,149,166,167,653,1238],[100,149,166,167,653,1240],[100,149,166,167,653,1242],[100,149,166,167,653,1244],[100,149,166,167,653,1246,1247],[100,149,166,167,653,1249],[100,149,166,167,653,1251],[100,149,166,167,653,1253],[100,149,166,167,653,1255,1256],[100,149,166,167,653,1258,1259,1260,1261],[100,149,166,167,653,1263,1264],[100,149,166,167,653,1266],[100,149,166,167,653,1268],[100,149,166,167,653,1270,1271],[100,149,166,167,653,1273],[100,149,166,167,653,1275,1276,1277],[100,149,166,167,653,1279,1280,1281],[100,149,166,167,653,1283],[100,149,166,167,653,1285],[100,149,166,167,653,1287],[100,149,166,167,653,1289,1290],[100,149,166,167,653,1292],[100,149,166,167,653,1294],[100,149,166,167,653,1296,1297],[100,149,166,167,653,1299,1300],[100,149,166,167,653,1302,1303,1304],[100,149,166,167,653,1306],[100,149,166,167,653,1308],[100,149,166,167,653,1310,1311,1312],[100,149,166,167,653,1314,1315,1316,1317],[100,149,166,167,653,1319,1320],[100,149,166,167,653,1322,1323],[100,149,166,167,653,1325],[100,149,166,167,653,1327],[100,149,166,167,653,1329],[100,149,166,167,653,1331],[100,149,166,167,653,1333,1334,1335],[100,149,166,167,653,1337,1338,1339,1340,1341],[100,149,166,167,653,1343,1344],[100,149,166,167,653,1346,1347],[100,149,166,167,653,1349,1350],[100,149,166,167,653,1352],[100,149,166,167,653,1354,1355],[100,149,166,167,653,1357,1358],[100,149,166,167,653,1360],[100,149,166,167,653,1362],[100,149,166,167,653,1364],[100,149,166,167,653,1366],[100,149,166,167,653,1368],[100,149,166,167,653,1370],[100,149,166,167,653,1372],[100,149,166,167,653,1374,1375,1376],[100,149,166,167,653,1378],[100,149,166,167,653,1380,1381],[100,149,166,167,653,1383,1384],[100,149,166,167,653,1386],[100,149,166,167,653,1388],[100,149,166,167,653,1390,1391],[100,149,166,167,653,1393,1394],[100,149,166,167,653,1396],[100,149,166,167,653,1398],[100,149,166,167,653,1400,1401],[100,149,166,167,653,1403],[100,149,166,167,653,1405,1406,1407,1408],[100,149,166,167,653,1410,1411],[100,149,166,167,653,1413,1414],[100,149,166,167,653,1416,1417,1418],[100,149,166,167,653,1420],[100,149,166,167,653,1422],[100,149,166,167,653,1424],[100,149,166,167,653,1426,1427],[100,149,166,167,653,1429],[100,149,166,167,653,1431,1432,1433,1434,1435],[100,149,166,167,653,1437,1438,1439],[100,149,166,167,653,1441,1442],[100,149,166,167,653,1444],[100,149,166,167,653,1446,1447],[100,149,166,167,653,1449],[100,149,166,167,653,1451],[100,149,166,167,653,1453],[100,149,166,167,653,1455],[100,149,166,167,653,1457,1458,1459],[100,149,166,167,653,1461,1462],[100,149,166,167,653,1464,1465],[100,149,166,167,653,1467],[100,149,166,167,653,1469],[100,149,166,167,653,1471,1472],[100,149,166,167,653,1474],[100,149,166,167,653,1476,1477],[100,149,166,167,653,1479],[100,149,166,167,653,1481],[100,149,166,167,645,653,654,656,658,659,661,662,664,666,668,669,670,672,674,676,677,678,680,681,683,684,686,688,689,691,693,694,696,698,700,701,702,704,706,707,709,710,712,713,715,717,719,721,723,724,725,726,728,729,731,733,735,737,738,739,741,742,744,746,748,749,750,752,753,755,756,758,760,761,762,764,766,767,769,771,773,774,776,778,780,781,782,784,785,787,788,790,791,793,795,796,798,800,802,804,806,808,810,812,814,816,818,820,821,822,823,824,825,827,828,830,831,832,833,834,836,838,839,841,843,845,847,848,849,850,851,853,854,856,858,860,862,863,864,865,866,868,869,871,873,874,876,877,879,880,881,883,884,885,887,888,890,891,892,894,896,897,899,901,903,904,906,907,908,910,911,913,915,917,919,920,922,924,926,927,929,931,933,934,936,938,940,941,943,944,946,947,948,950,951,953,954,955,957,959,960,961,962,964,965,966,967,969,971,973,974,975,977,978,979,980,981,982,983,985,987,988,989,990,992,994,995,996,998,999,1000,1002,1004,1005,1006,1008,1010,1011,1013,1015,1016,1018,1020,1021,1023,1025,1027,1029,1030,1032,1034,1035,1037,1038,1040,1042,1044,1045,1047,1048,1049,1051,1053,1055,1056,1057,1059,1061,1063,1065,1067,1069,1070,1072,1073,1074,1076,1078,1079,1080,1081,1082,1083,1084,1085,1087,1089,1091,1092,1094,1096,1098,1099,1101,1103,1104,1105,1107,1109,1110,1112,1113,1115,1116,1118,1120,1122,1124,1125,1126,1127,1129,1131,1133,1135,1136,1137,1138,1140,1142,1144,1146,1148,1150,1152,1153,1154,1156,1158,1160,1162,1163,1165,1166,1167,1168,1169,1170,1171,1172,1173,1174,1176,1177,1178,1180,1181,1183,1185,1186,1188,1190,1192,1194,1196,1198,1200,1202,1204,1205,1207,1208,1210,1211,1213,1214,1216,1217,1219,1221,1222,1224,1226,1227,1228,1230,1231,1232,1234,1236,1238,1240,1242,1244,1246,1247,1249,1251,1253,1255,1256,1258,1259,1260,1261,1263,1264,1266,1268,1270,1271,1273,1275,1276,1277,1279,1280,1281,1283,1285,1287,1289,1290,1292,1294,1296,1297,1299,1300,1302,1303,1304,1306,1308,1310,1311,1312,1314,1315,1316,1317,1319,1320,1322,1323,1325,1327,1329,1331,1333,1334,1335,1337,1338,1339,1340,1341,1343,1344,1346,1347,1349,1350,1352,1354,1355,1357,1358,1360,1362,1364,1366,1368,1370,1372,1374,1375,1376,1378,1380,1381,1383,1384,1386,1388,1390,1391,1393,1394,1396,1398,1400,1401,1403,1405,1406,1407,1408,1410,1411,1413,1414,1416,1417,1418,1420,1422,1424,1426,1427,1429,1431,1432,1433,1434,1435,1437,1438,1439,1441,1442,1444,1446,1447,1449,1451,1453,1455,1457,1458,1459,1461,1462,1464,1465,1467,1469,1471,1472,1474,1476,1477,1479,1482],[100,149,157,166,167,199,1494,1501,1502],[100,149,160,166,167,199,1489,1490,1491,1493,1494,1502,1503,1509],[100,149,166,167,199,1489],[100,149,166,167,1489],[100,149,166,167,1495],[100,149,160,166,167,189,199,1489,1495,1497,1498,1503],[100,149,166,167,1497],[100,149,166,167,1501],[100,149,166,167,169,189,199,1489,1495],[100,149,160,166,167,199,1489,1505,1506],[100,149,166,167,1489,1490,1491,1492,1495,1499,1500,1501,1502,1503,1504,1508,1509,1510],[100,149,166,167,1490,1494,1504,1509],[100,149,160,166,167,199,1489,1490,1491,1493,1494,1501,1504,1505,1507,1508],[100,149,166,167,1494,1496,1499,1500],[100,149,166,167,1490],[100,149,166,167,1492],[100,149,166,167,1489,1490,1492],[100,149,166,167,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590],[100,149,166,167,559],[100,149,166,167,559,569],[100,149,166,167,1770],[100,149,166,167,1777],[100,149,166,167,181,1770,1777,1778],[100,149,166,167,1770,1775],[100,149,166,167,1773],[100,149,166,167,1771,1772,1774,1776],[100,149,166,167,557,605,1921],[100,149,163,166,167,199,605,1921],[100,149,166,167,596,603],[100,149,166,167,496,500,603,605,1921],[100,149,166,167,537,557,558,592,599,601,602,1921],[100,149,166,167,597,603,604],[100,149,166,167,496,500,600,605,1921],[100,149,166,167,199,605,1921],[100,149,166,167,597,599,605,1921],[100,149,166,167,599,603,605,1921],[100,149,166,167,599],[100,149,166,167,594,595,598],[100,149,166,167,591,592,593,599,605,1921],[86,100,149,166,167,599,605,1921,1926,1927],[86,100,149,166,167,599,605,1921],[92,100,149,166,167],[100,149,166,167,447],[100,149,166,167,454],[100,149,166,167,208,222,223,224,226,441],[100,149,166,167,208,247,249,251,252,255,441,443],[100,149,166,167,208,212,214,215,216,217,218,430,441,443],[100,149,166,167,441],[100,149,166,167,223,325,411,420,437],[100,149,166,167,208],[100,149,166,167,205,437],[100,149,166,167,259],[100,149,166,167,258,441,443],[100,149,163,166,167,307,325,354,498],[100,149,163,166,167,318,334,420,436],[100,149,163,166,167,372],[100,149,166,167,424],[100,149,166,167,423,424,425],[100,149,166,167,423],[94,100,149,163,166,167,205,208,212,215,219,220,221,223,227,235,236,365,390,421,441,444],[100,149,166,167,208,225,243,247,248,253,254,441,498],[100,149,166,167,225,498],[100,149,166,167,236,243,305,441,498],[100,149,166,167,498],[100,149,166,167,208,225,226,498],[100,149,166,167,250,498],[100,149,166,167,219,422,429],[100,149,166,167,175,267,437],[100,149,166,167,267,437],[86,100,149,166,167,267],[86,100,149,166,167,326],[100,149,166,167,322,370,437,480,481],[100,149,166,167,417,474,475,476,477,479],[100,149,166,167,416],[100,149,166,167,416,417],[100,149,166,167,216,366,367,368],[100,149,166,167,366,369,370],[100,149,166,167,478],[100,149,166,167,366,370],[86,100,149,166,167,209,468],[86,100,149,166,167,192],[86,100,149,166,167,225,295],[86,100,149,166,167,225],[100,149,166,167,293,297],[86,100,149,166,167,294,446],[100,149,166,167,1923],[86,90,100,149,163,166,167,199,200,201,202,203,204,444,490,491],[100,149,163,166,167],[100,149,163,166,167,212,274,366,376,391,411,426,427,441,442,498],[100,149,166,167,235,428],[100,149,166,167,444],[100,149,166,167,207],[86,100,149,166,167,307,321,333,343,345,436],[100,149,166,167,175,307,321,342,343,344,436,497],[100,149,166,167,336,337,338,339,340,341],[100,149,166,167,338],[100,149,166,167,342],[100,149,166,167,265,266,267,269],[86,100,149,166,167,260,261,262,268],[100,149,166,167,265,268],[100,149,166,167,263],[100,149,166,167,264],[86,100,149,166,167,267,294,446],[86,100,149,166,167,267,445,446],[86,100,149,166,167,267,446],[100,149,166,167,391,433],[100,149,166,167,433],[100,149,163,166,167,442,446],[100,149,166,167,330],[100,148,149,166,167,329],[100,149,166,167,237,275,313,315,317,318,319,320,363,366,436,439,442],[100,149,166,167,237,351,366,370],[100,149,166,167,318,436],[86,100,149,166,167,318,327,328,330,331,332,333,334,335,346,347,348,349,350,352,353,436,437,498],[100,149,166,167,312],[100,149,163,166,167,175,237,238,274,289,319,363,364,365,370,391,411,432,441,442,443,444,498],[100,149,166,167,436],[100,148,149,166,167,223,316,319,365,432,434,435,442],[100,149,166,167,318],[100,148,149,166,167,274,279,308,309,310,311,312,313,314,315,317,436,437],[100,149,163,166,167,279,280,308,442,443],[100,149,166,167,223,365,366,391,432,436,442],[100,149,163,166,167,441,443],[100,149,163,166,167,181,439,442,443],[100,149,163,166,167,175,192,205,212,225,237,238,240,275,276,281,286,289,315,319,366,376,378,381,383,386,387,388,389,390,411,431,432,437,439,441,442,443],[100,149,163,166,167,181],[100,149,166,167,208,209,210,212,217,220,225,243,431,439,440,444,446,498],[100,149,163,166,167,181,192,255,257,259,260,261,262,269,498],[100,149,166,167,175,192,205,247,257,285,286,287,288,315,366,381,390,391,397,400,401,411,432,437,439],[100,149,166,167,219,220,235,365,390,432,441],[100,149,163,166,167,192,209,212,315,395,439,441],[100,149,166,167,306],[100,149,163,166,167,398,399,408],[100,149,166,167,439,441],[100,149,166,167,313,316],[100,149,166,167,315,319,431,446],[100,149,163,166,167,175,241,247,288,381,391,397,400,403,439],[100,149,163,166,167,219,235,247,404],[100,149,166,167,208,240,406,431,441],[100,149,163,166,167,192,441],[100,149,163,166,167,225,239,240,241,252,270,405,407,431,441],[94,100,149,166,167,237,319,410,444,446],[100,149,163,166,167,175,192,212,219,227,235,238,275,281,285,286,287,288,289,315,366,378,391,392,394,396,411,431,432,437,438,439,446],[100,149,163,166,167,181,219,397,402,408,439],[100,149,166,167,230,231,232,233,234],[100,149,166,167,276,382],[100,149,166,167,384],[100,149,166,167,382],[100,149,166,167,384,385],[100,149,163,166,167,212,215,216,274,442],[100,149,163,166,167,175,207,209,237,275,289,319,374,375,411,439,443,444,446],[100,149,163,166,167,175,192,211,216,315,375,438,442],[100,149,166,167,308],[100,149,166,167,309],[100,149,166,167,310],[100,149,166,167,437],[100,149,166,167,256,272],[100,149,163,166,167,212,256,275],[100,149,166,167,271,272],[100,149,166,167,273],[100,149,166,167,256,257],[100,149,166,167,256,290],[100,149,166,167,256],[100,149,166,167,276,380,438],[100,149,166,167,379],[100,149,166,167,257,437,438],[100,149,166,167,377,438],[100,149,166,167,257,437],[100,149,166,167,363],[100,149,166,167,212,217,275,304,307,313,315,319,321,324,355,358,362,366,410,431,439,442],[100,149,166,167,298,301,302,303,322,323,370],[86,100,149,166,167,202,204,267,356,357],[86,100,149,166,167,202,204,267,356,357,361],[100,149,166,167,419],[100,149,166,167,223,280,318,319,330,334,366,410,412,413,414,415,417,418,421,431,436,441],[100,149,166,167,370],[100,149,166,167,374],[100,149,163,166,167,275,291,371,373,376,410,439,444,446],[100,149,166,167,298,299,300,301,302,303,322,323,370,445],[94,100,149,163,166,167,175,192,238,256,257,289,315,319,408,409,411,431,432,441,442,444],[100,149,166,167,280,282,285,432],[100,149,163,166,167,276,441],[100,149,166,167,279,318],[100,149,166,167,278],[100,149,166,167,280,281],[100,149,166,167,277,279,441],[100,149,163,166,167,211,280,282,283,284,441,442],[86,100,149,166,167,366,367,369],[100,149,166,167,242],[86,100,149,166,167,209],[86,100,149,166,167,437],[86,94,100,149,166,167,289,319,444,446],[100,149,166,167,209,468,469],[86,100,149,166,167,297],[86,100,149,166,167,175,192,207,254,292,294,296,446],[100,149,166,167,225,437,442],[100,149,166,167,393,437],[100,149,166,167,366],[86,100,149,161,163,166,167,175,207,243,249,297,444,445],[86,100,149,166,167,200,201,202,203,204,444,492],[86,87,88,89,90,100,149,166,167],[100,149,166,167,244,245,246],[100,149,166,167,244],[86,90,100,149,163,165,166,167,175,199,200,201,202,203,204,205,207,238,342,403,441,443,446,492],[100,149,166,167,456],[100,149,166,167,458],[100,149,166,167,460],[100,149,166,167,1924],[100,149,166,167,462],[100,149,166,167,464,465,466],[100,149,166,167,470],[91,93,100,149,166,167,448,453,455,457,459,461,463,467,471,473,483,484,486,496,497,498,499],[100,149,166,167,472],[100,149,166,167,482],[100,149,166,167,294],[100,149,166,167,485],[100,148,149,166,167,280,282,283,285,333,437,487,488,489,492,493,494,495],[100,149,166,167,199],[100,149,154,163,164,165,166,167,192,193,199,591],[100,149,166,167,519],[100,149,166,167,517,519],[100,149,166,167,508,516,517,518,520,522],[100,149,166,167,506],[100,149,166,167,509,514,519,522],[100,149,166,167,505,522],[100,149,166,167,509,510,513,514,515,522],[100,149,166,167,509,510,511,513,514,522],[100,149,166,167,506,507,508,509,510,514,515,516,518,519,520,522],[100,149,166,167,522],[100,149,166,167,504,506,507,508,509,510,511,513,514,515,516,517,518,519,520,521],[100,149,166,167,504,522],[100,149,166,167,509,511,512,514,515,522],[100,149,166,167,513,522],[100,149,166,167,514,515,519,522],[100,149,166,167,507,517],[100,149,166,167,549],[100,149,166,167,550],[100,149,166,167,1550,1551,1553,1555,1738,1739],[100,149,163,166,167,199,1516,1517,1518,1738],[100,149,166,167,1738],[100,149,166,167,199,1738],[100,149,160,163,166,167,199,1516,1521,1522,1738],[100,149,166,167,1516,1519,1737,1738],[100,149,166,167,1737,1738],[100,149,166,167,1528,1529,1531,1540,1541,1544,1545,1547,1549,1551,1552,1553,1554,1555,1557,1558,1559,1562,1563,1566,1577,1578,1584,1585,1586,1587,1588,1589,1619,1620,1622,1623,1624,1625,1626,1628,1634,1688,1689,1690,1691,1693,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1737],[100,149,166,167,1519,1520],[100,149,166,167,1519,1520,1525,1534,1537,1538,1541,1542,1544],[100,149,166,167,1519,1520,1525],[100,149,166,167,1519,1520,1525,1533,1543,1545,1558,1577],[100,149,166,167,1711,1737],[100,149,166,167,1519,1520,1525,1576],[100,149,166,167,1533,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1575,1578],[100,149,166,167,1525,1545,1634],[100,149,166,167,1519,1520,1525,1527,1634],[100,149,166,167,1635],[100,149,166,167,1519,1520,1634],[100,149,166,167,1519,1520,1525,1618,1625,1637],[100,149,166,167,1519,1520,1525,1618,1634],[100,149,166,167,1526,1527,1635,1636,1637,1638,1639,1640,1641,1737],[100,149,166,167,1519,1520,1525,1526],[100,149,166,167,1519,1520,1525,1543],[100,149,166,167,1643,1644,1737],[100,149,166,167,1519,1520,1643],[100,149,166,167,1545],[100,149,166,167,1519,1520,1525,1543,1545,1547,1550,1553,1554,1555,1557,1559,1577,1578,1634],[100,149,166,167,1629,1737],[100,149,166,167,1519,1520,1525,1528,1529,1530,1531,1544,1545,1551,1555,1620,1624,1625,1627,1628,1634],[100,149,166,167,1646,1647,1648,1737],[100,149,166,167,1519,1520,1525,1646,1647],[100,149,166,167,1519,1520,1525,1646],[100,149,166,167,1519,1520,1525,1552,1558,1634],[100,149,166,167,1525,1530,1531,1642],[100,149,166,167,1519,1520,1525,1530,1531,1532,1578,1624,1625,1631,1634,1642],[100,149,166,167,1525,1625,1626,1630,1634],[100,149,166,167,1555,1577,1578,1634],[100,149,166,167,1519,1520,1525,1530,1535,1544,1550,1553,1561,1618,1620,1631,1632,1633],[100,149,166,167,1535,1536,1545,1549],[100,149,166,167,1528,1529,1634],[100,149,166,167,1519,1520,1525,1541,1555,1558,1577],[100,149,166,167,1519,1520,1525,1579],[100,149,166,167,1519,1580],[100,149,166,167,1579,1580,1581,1737],[100,149,166,167,1519,1520,1525,1528,1529,1530,1531,1533,1534,1537,1541,1542,1543,1544,1545,1547,1548,1549,1550,1551,1553,1554,1555,1557,1558,1559,1561,1562,1563,1566,1575,1578,1582,1584,1586,1587,1618,1619,1620,1623,1625,1626,1628,1630,1632,1634,1642,1645,1649,1655,1658,1663,1666,1670,1672,1680,1684,1687,1688,1689,1690,1691,1692],[100,149,166,167,1535,1536],[100,149,166,167,1525,1559,1577],[100,149,166,167,1519,1520,1525,1541],[100,149,166,167,1519,1520,1525,1539,1540],[100,149,166,167,1519,1650],[100,149,166,167,1519,1520,1525,1634,1650,1651],[100,149,166,167,1650,1651,1652,1653,1654,1737],[100,149,166,167,1519,1520,1634,1652],[100,149,166,167,1713,1737],[100,149,166,167,1525],[100,149,166,167,1656,1657,1737],[100,149,166,167,1519,1520,1525,1656],[100,149,166,167,1519,1520,1525,1530,1531,1584,1618,1625,1634],[100,149,166,167,1525,1530,1584,1620,1642],[100,149,166,167,1519,1520,1525,1555,1558,1622,1625],[100,149,166,167,1519,1520,1525,1530,1531,1543,1544,1545,1550,1551,1553,1555,1618,1620,1621,1623,1624,1634,1642],[100,149,166,167,1519,1520,1525,1567,1570,1571,1573,1577],[100,149,166,167,1519,1520,1525,1567,1569],[100,149,166,167,1519,1520,1525,1541,1573,1577],[100,149,166,167,1567,1568,1569,1570,1571,1572,1573,1574,1737],[100,149,166,167,1519,1520,1525,1541,1568],[100,149,166,167,1519,1520,1525,1570],[100,149,166,167,1519,1520,1525,1567,1570,1571,1572,1574,1577],[100,149,166,167,1525,1530,1531,1584],[100,149,166,167,1519,1520,1553],[100,149,166,167,1519,1520,1738],[100,149,166,167,1519,1520,1525,1547,1553],[100,149,166,167,1519,1520,1525,1543,1545,1546,1550,1551,1553,1554,1558,1634],[100,149,166,167,1519,1520,1525,1543,1544,1545,1624,1627],[100,149,166,167,1519,1520,1525,1537,1559,1577],[100,149,166,167,1525,1541],[100,149,166,167,1519,1520,1525,1586],[100,149,166,167,1582],[100,149,166,167,1519,1520,1525,1583,1584,1585],[100,149,166,167,1519,1520,1525,1528,1634],[100,149,166,167,1519,1520,1525,1530,1531,1543,1545,1618,1619,1620,1625,1627,1634],[100,149,166,167,1519,1520,1525,1555,1558],[100,149,166,167,1659,1660,1661,1662,1737],[100,149,166,167,1519,1520,1525,1553],[100,149,166,167,1519,1520,1525,1661],[100,149,166,167,1519,1520,1525,1555,1556,1558,1577],[100,149,166,167,1664,1665,1737],[100,149,166,167,1525,1558,1667],[100,149,166,167,1667,1668,1669],[100,149,166,167,1525,1562,1578,1667,1668],[100,149,166,167,1519,1520,1525,1543,1545,1547,1550,1551,1553,1555,1634],[100,149,166,167,1519,1520,1525,1543,1545,1547,1550,1552,1553,1555,1634],[100,149,166,167,1519,1520,1525,1585],[100,149,166,167,1671,1737],[100,149,166,167,1549],[100,149,166,167,1519,1520,1525,1548],[100,149,166,167,1519,1520,1525,1530,1531,1584,1587],[100,149,166,167,1519,1520,1525,1530,1531,1543,1544,1545,1550,1551,1553,1584,1588,1618,1619,1625,1634],[100,149,166,167,1519,1520,1525,1528,1529,1530,1531,1543,1544,1545,1553,1584,1587,1618,1620,1634],[100,149,166,167,1519,1520,1525,1674],[100,149,166,167,1673,1674,1675,1676,1677,1678,1679,1737],[100,149,166,167,1519,1520,1525,1678],[100,149,166,167,1519,1520,1525,1543,1545,1634],[100,149,166,167,1599,1600,1681,1682,1683,1737],[100,149,166,167,1519,1520,1525,1550,1551,1553,1555,1558,1578,1599],[100,149,166,167,1519,1520,1525,1589],[100,149,166,167,1519,1520,1561],[100,149,166,167,1590,1591,1592,1593,1598,1602,1617,1737],[100,149,166,167,1519,1520,1525,1574],[100,149,166,167,1519,1520,1570],[100,149,166,167,1594,1595,1596,1597,1737],[100,149,166,167,1519,1520,1569],[100,149,166,167,1519,1520,1525,1573],[100,149,166,167,1519,1520,1578],[100,149,166,167,1601,1737],[100,149,166,167,1519,1520,1600],[100,149,166,167,1519,1520,1611],[100,149,166,167,1612,1613,1614,1615,1616,1737],[100,149,166,167,1519,1520,1605],[100,149,166,167,1519,1520,1606],[100,149,166,167,1519,1520,1607],[100,149,166,167,1519,1520,1608],[100,149,166,167,1519,1520,1525,1535,1536],[100,149,166,167,1519,1520,1525,1549,1577],[100,149,166,167,1525,1557,1577,1578],[100,149,166,167,1519,1520,1525,1545,1556,1558,1577],[100,149,166,167,1519,1520,1525,1610],[100,149,166,167,1519,1520,1525,1685],[100,149,166,167,1519,1520,1525,1547,1610],[100,149,166,167,1603,1604,1605,1606,1607,1608,1609,1610,1611,1685,1686,1737],[100,149,166,167,1519,1520,1525,1563,1603,1605,1606,1610],[100,149,166,167,1519,1520,1525,1575,1603,1604,1605,1606,1607,1608,1610,1611],[100,149,166,167,1519,1520,1525,1575,1603,1604,1605,1606,1607,1608,1609,1611],[100,149,166,167,1716,1717,1718,1719,1737],[100,149,166,167,1721,1723,1737],[100,149,166,167,1519,1520,1525,1721],[100,149,166,167,1722,1737],[100,149,166,167,1519,1520,1525,1725,1727,1729,1737],[100,149,166,167,1519,1520,1525,1715,1726],[100,149,166,167,1519,1520,1525,1728],[100,149,166,167,1519,1520,1525,1725],[100,149,166,167,1519,1520,1525,1715,1733],[100,149,166,167,1517,1519,1520,1525,1642,1724,1735],[100,149,166,167,1726,1728,1730,1731,1732,1733,1734,1737],[100,149,166,167,1715,1720,1724,1735,1737],[100,149,166,167,1524],[100,149,166,167,1516,1517,1518,1519,1520,1521,1523,1525,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1575,1576,1577,1578,1582,1583,1584,1585,1586,1587,1588,1589,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1630,1631,1632,1633,1634,1642,1645,1649,1655,1658,1663,1666,1670,1672,1680,1684,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1710,1712,1714,1736,1738,1739,1740],[100,149,166,167,1519,1737,1738],[100,149,160,166,167,199,1516,1517,1519,1550,1551,1553,1555,1737,1739],[100,149,166,167,1521,1523,1693],[100,149,166,167,1764,1765],[100,149,166,167,1765,1766],[100,149,166,167,181,1763,1764,1765,1766,1767,1768,1769],[100,149,166,167,1763,1765,1766],[100,149,166,167,1756,1757,1758,1760,1761,1762],[100,149,166,167,181,1757],[100,149,166,167,1759],[100,149,166,167,1757],[100,149,166,167,184,1760,1761],[100,149,166,167,1764],[100,149,166,167,524,525],[100,149,166,167,523,526],[100,113,117,149,166,167,192],[100,113,149,166,167,181,192],[100,108,149,166,167],[100,110,113,149,166,167,189,192],[100,149,166,167,169,189],[100,108,149,166,167,199],[100,110,113,149,166,167,169,192],[100,105,106,109,112,149,160,166,167,181,192],[100,113,120,149,166,167],[100,105,111,149,166,167],[100,113,134,135,149,166,167],[100,109,113,149,166,167,184,192,199],[100,134,149,166,167,199],[100,107,108,149,166,167,199],[100,113,149,166,167],[100,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,135,136,137,138,139,140,149,166,167],[100,113,128,149,166,167],[100,113,120,121,149,166,167],[100,111,113,121,122,149,166,167],[100,112,149,166,167],[100,105,108,113,149,166,167],[100,113,117,121,122,149,166,167],[100,117,149,166,167],[100,111,113,116,149,166,167,192],[100,105,110,113,120,149,166,167],[100,108,113,134,149,166,167,197,199],[100,147,149,166,167,1754],[100,149,166,167,527,528],[100,149,166,167,601,605,1921],[100,149,166,167,171,533,534,609,612,1484,1485,1780,1784,1785,1899,1900]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"d49c6f5cfcdd6f136cf14362640f87340b0da1c963875589a252cd8c26deaa50","affectsGlobalScope":true},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"dc782ff85b2cb10075ecffc158af7bfb27ff97bf8491c917efea0c3d622d5ac4","impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d97fb21da858fb18b8ae72c314e9743fd52f73ebe2764e12af1db32fc03f853f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"78dbea00e90d2df8ea3dbef0cc379d95b8be9b71cd6bde4c28728f306811803b","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e1e46d0a9837ee058c100501080c920fa98081ea3956af0374308ba6f22a33e","impliedFormat":1},{"version":"272ca407e0c9068bdc5152552d876e68037ceae3de62e529306403e973dec8e1","impliedFormat":1},{"version":"fa7834c715d5357e4540cee40ce96c3250ddb67a7b879a6b7fa0e86d6696f121","impliedFormat":1},{"version":"22dfb07a7ab15b66ac043829056fe70124844636ae719551812ac631ba04985b","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"a6f137d651076822d4fe884287e68fd61785a0d3d1fdb250a5059b691fa897db","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"bceb58df66ab8fb00170df20cd813978c5ab84be1d285710c4eb005d8e9d8efb","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"0cb167c371eaa8c869f8a7656a7296f2e4fae43b4d8b803a680236b24794e5f9","impliedFormat":1},{"version":"0a839dba0287cc0481ad4beedd48a1c64acf1e212ae865d1315f7007ca215161","impliedFormat":1},{"version":"38dc4655376cd1a4bd6bb3763d92949233e33d38d3dd3cbea7bbf218175a38ef","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"d61e0a64cd175208ac0b83670151a9a6b5916f0d1ffcdc5c29c90b1cebfc5045","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"48a679952eefe4cb776d5a0e1ccba2d3eb53b57448bbb7abc1fcebcbd5440188","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"2d14da6ecb49bf828d83948765ec2d3a579d476bbb9645e749610baa6ec880ca","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"0aef708fb4c7a6b915e8305cbfac40cd207b032dbaabe9a01889a5fff3254681","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"ad9bdafb4e7abf14cc53ce7970486a84c87831e62891e5dfe798ddcd55e84701","affectsGlobalScope":true,"impliedFormat":1},{"version":"358765d5ea8afd285d4fd1532e78b88273f18cb3f87403a9b16fef61ac9fdcfe","impliedFormat":1},{"version":"71d3ae6a5e73ca4130762560425e00984ebaff64d5353a3333d1bb7eb86ef336","impliedFormat":1},{"version":"2beff543f6e9a9701df88daeee3cdd70a34b4a1c11cb4c734472195a5cb2af54","impliedFormat":1},{"version":"2e07abf27aa06353d46f4448c0bbac73431f6065eef7113128a5cd804d0c384d","impliedFormat":1},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1},{"version":"42bc0e1a903408137c3df2b06dfd7e402cdab5bbfa5fcfb871b22ebfdb30bd0b","impliedFormat":1},{"version":"9894dafe342b976d251aac58e616ac6df8db91fb9d98934ff9dd103e9e82578f","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5f90b8c733a1bda63e42160b15a2301051e83a6f9d5332a59d16eb12f463270d","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"b838d4c72740eb0afd284bf7575b74c624b105eff2e8c7b4aeead57e7ac320ff","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"c30436b130b6218b7714314dc41d3f459590db4bdf099eecd51cb1bda32109a8","impliedFormat":1},{"version":"20fa37b636fdcc1746ea0738f733d0aed17890d1cd7cb1b2f37010222c23f13e","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},{"version":"19df3488557c2fc9b4d8f0bac0fd20fb59aa19dec67c81f93813951a81a867f8","affectsGlobalScope":true,"impliedFormat":1},{"version":"b25350193e103ae90423c5418ddb0ad1168dc9c393c9295ef34980b990030617","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"bd5f641cc4616eee49497a362c4cb401e9346265bc52670448c4452b4d9be401","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"e91f7b1344577a02f051b9b471f33044fef8334a76dc9e1de003d17595a5219b","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"c1de754ab5f3b0f4036d6893c74a0fc984c7fcb07936086f19bbe2974406775b","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"85ae5aee75f011967cf2d25cbc342f62d69314e9d925f7f4aa3456fc2cffcca6","4256f8b5c177e0b4ca62d5888c734f48b086740efee31ce11335f65da4f2cb2b",{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"52dcc257df5119fb66d864625112ce5033ac51a4c2afe376a0b299d2f7f76e4a","impliedFormat":1},{"version":"e5bab5f871ef708d52d47b3e5d0aa72a08ee7a152f33931d9a60809711a2a9a3","impliedFormat":1},{"version":"e16dc2a81595736024a206c7d5c8a39bfe2e6039208ef29981d0d95434ba8fcf","impliedFormat":1},{"version":"cc4a4903fb698ca1d961d4c10dce658aa3a479faf40509d526f122b044eaf6a4","impliedFormat":1},{"version":"19ee8416e6473ed6c7adb868fa796b5653cf0fa2a337658e677eaa0d134388c3","impliedFormat":1},{"version":"1328ab4e442614b28cdb3d4b414cf68325c0da0dca07287a338d0654b7a00261","impliedFormat":1},{"version":"a039dc21f045919f3cbee2ec13812cc6cc3eebc99dae4be00973230f468d19a6","impliedFormat":1},{"version":"3fbe57af01460e49dcd29df55d6931e1672bc6f1be0fb073d11410bc16f9037d","impliedFormat":1},{"version":"f760be449e8562ec5c09bb5187e8e1eabf3c113c0c58cddda53ef8c69f3e2131","impliedFormat":1},{"version":"44325ed13294fce6ab825b82947bbeed2611db7dad9d9135260192f375e5a189","impliedFormat":1},{"version":"e392e8fb5b514eafc585601c1d781485aa6dd6a320e75daf1064a4c6918a1b45","impliedFormat":1},{"version":"46e4a36e8ddbdfb4e7330e11c81c970dc8b218611df9183d39c41c5f8c653b55","impliedFormat":1},{"version":"370bde134aa8c2abc926d0e99d3a4d5d5dba65c6ee65459137e4f02670cbf841","impliedFormat":1},{"version":"6332f565867cf4a740a70e30f31cefba37ef7cebcf74f22eab8d744fde6d193e","impliedFormat":1},{"version":"2977b7884aedc895a1d0c9c210c7cf3272c29d6959a08a6fa3ff71e0aff08175","impliedFormat":1},{"version":"17f2922d41ddd032830a91371c948cd9ce903b35c95adca72271a54584f19b0b","impliedFormat":1},{"version":"3eed76ede2a1a14d7c9bb0a642041282dcc264811139d3dd275c9fe14efc9840","impliedFormat":1},{"version":"e3cf0611709328b449ec13f8c436712d62003620ce480139fae46ce001c2ee9f","impliedFormat":1},{"version":"8d369483f0c2b9ee388129cfdb6a43bc8112b377e86a41884bd06e19ce04f4c1","impliedFormat":99},{"version":"b558c9a18ea4e6e4157124465c3ef1063e64640da139e67be5edb22f534f2f08","impliedFormat":1},{"version":"01374379f82be05d25c08d2f30779fa4a4c41895a18b93b33f14aeef51768692","impliedFormat":1},{"version":"b0dee183d4e65cf938242efaf3d833c6b645afb35039d058496965014f158141","impliedFormat":1},{"version":"c0bbbf84d3fbd85dd60d040c81e8964cc00e38124a52e9c5dcdedf45fea3f213","impliedFormat":1},{"version":"1dacb6ae2c0d095c0c085032f1f918cbb29f27f1f433c0374935347a0d99bb5b","impliedFormat":1},"cb268678928da8a5da61814985a84963a63a9326b36230bba03db5f63b7227a3",{"version":"b845876de475c230a1e012150db8d2c2a62bd6835a93e8cd23ebb10f7de16266","impliedFormat":1},{"version":"58ac8ffb0608f2ef0e94e466d41bd1144ed3c7ac55a2f268f97b15d5061c3a8f","impliedFormat":1},{"version":"d5eb5865d4cbaa9985cc3cfb920b230cdcf3363f1e70903a08dc4baab80b0ce1","impliedFormat":1},{"version":"51ebca098538b252953b1ef83c165f25b52271bfb6049cd09d197dddd4cd43c5","impliedFormat":1},"0fb7497b1fc62118f6a85028f2c6589418203e7a8dfffcaab5f4f9a211be0d04","ba586ebdbfb25f0d4e81ef68c12860caeea0a8c4389b8e8d8c8a705794e74894","b465e5720dc632ad5e2af5400f40eda5a7620c34412a88937ee6561238a55776",{"version":"1748c03e7a7d118f7f6648c709507971eb0d416f489958492c5ae625de445184","impliedFormat":1},{"version":"6e9e63e27a2fbbee54d15cbcbeb0e83a3ffcc383a863c46332512faf9527e495","impliedFormat":99},{"version":"20be44c04e883d5fe7840d630a8d0656e95b00c2d6eebab9ab253275e7170534","impliedFormat":99},{"version":"1c57d55fdd18834c5ef949eb36f5457abd35cd64a59e1cbaf05574795b2aa215","impliedFormat":99},{"version":"b52f7568bb9b00bcee6c4929938226541c09d86b849b8ba8db2fe2a8bba46f49","impliedFormat":99},{"version":"d42e1872d53ebb213e7bbe15e5fecdcaa9a490d2f2a2b035ee9cf4a6d3f1e44e","impliedFormat":99},{"version":"c9104d351c38d877033d847643d2475586fc123f3294c687cba437517ffa7609","impliedFormat":99},{"version":"ae5fe32e831c6c8963d5256d597639d1e55c5e60907b6914b37bde12729b1888","impliedFormat":99},{"version":"2ead4a178cce2310362fd95b838ab512e1942e6b4f40e60438ac7a1b2fc27f5e","impliedFormat":99},{"version":"ef816ad6735a271c4c8035a1914c3a9beaaa90b3c174da312d26bce8736e56ec","impliedFormat":99},{"version":"f1c0f426425ba6123c861d831d45a8e97f7ec54d076d8126a16c63c5a6260dcb","impliedFormat":99},{"version":"90594ab5bf771388aaed17402463079c09e4f52f563863f18eaadf0176796eee","impliedFormat":99},{"version":"fd40c454d56e1d14e60ce13f3bc60c7fdb9bc70c6ef9c7bfafec1f0eb5d8075b","impliedFormat":1},{"version":"155ced96d70533d95c481061e2691802fae7cfb96869d7c85ac8622f53b51cb7","impliedFormat":1},{"version":"f4272c1409ba5ce42d17be35575083f37dfe282284cc5e350d5fa60481ff44eb","impliedFormat":99},{"version":"07f609e01ca03efd53916cfc22216971df742e7072875ca5e3ed52eaf6462c19","impliedFormat":99},{"version":"1edcaa95999601c800bd61523f500dfe19bb10ebcf5fd2f56aaf1b0c8b0d2609","impliedFormat":99},{"version":"6352af46828724958706a1282df7e5883b77da9ca6b810044a316675c2ca6d97","impliedFormat":99},{"version":"db4a80dfbca7fcc6ce5a2be3bd73a18d75ae7cad56fa250aef8f523a463a39a5","impliedFormat":99},{"version":"d11667aa2a6063fde3c4054da9ab98e3b9bc7e3da800beaca437f1eff2a17fe2","impliedFormat":99},{"version":"99d19f0424a219ecc012d845bd6207083d88f16a2b69179fd3e3482fe0b9f169","impliedFormat":99},{"version":"b7ca2f47522d4ea41e65ff92c4c6dd9c4c8260da7c456a7631a9c88dc056b4d0","impliedFormat":1},{"version":"4f01e4d0959f9125b89e5737eb1ca2bfa69fd6b7d6126eba22feb8b505b00cde","impliedFormat":1},{"version":"4363a1adb9c77f2ed1ca383a41fbab1afadd35d485c018b2f84e834edde6a2c7","impliedFormat":1},{"version":"1d6458533adb99938d041a93e73c51d6c00e65f84724e9585e3cc8940b25523f","impliedFormat":1},{"version":"b0878fbd194bdc4d49fc9c42bfeeb25650842fe1412c88e283dc80854b019768","impliedFormat":1},{"version":"a892ea0b88d9d19281e99d61baba3155200acced679b8af290f86f695b589b16","impliedFormat":1},{"version":"03b42e83b3bcdf5973d28641d72b81979e3ce200318e4b46feb8347a1828cd5d","impliedFormat":1},{"version":"8a3d57426cd8fb0d59f6ca86f62e05dde8bfd769de3ba45a1a4b2265d84bac5a","impliedFormat":1},{"version":"afc6e1f323b476fdf274e61dab70f26550a1be2353e061ab34e6eed180d349b6","impliedFormat":1},{"version":"7c14483430d839976481fe42e26207f5092f797e1a4190823086f02cd09c113c","impliedFormat":1},{"version":"828a3bea78921789cbd015e968b5b09b671f19b1c14c4bbf3490b58fbf7d6841","impliedFormat":1},{"version":"69759c42e48938a714ee2f002fe5679a7ab56f0b5f29d571e4c31a5398d038fe","impliedFormat":1},{"version":"6e5e666fa6adeb60774b576084eeff65181a40443166f0a46ae9ba0829300fcb","impliedFormat":1},{"version":"1a4d43bdc0f2e240395fd204e597349411c1141dd08f5114c37d6268c3c9d577","impliedFormat":1},{"version":"874e58f8d945c7ac25599128a40ec9615aa67546e91ca12cbf12f97f6baf54ff","impliedFormat":1},{"version":"da2627da8d01662eb137ccd84af7ffa8c94cf2b2547d4970f17802324e54defc","impliedFormat":1},{"version":"07af06b740c01ed0473ebdd3f2911c8e4f5ebf4094291d31db7c1ab24ff559aa","impliedFormat":1},{"version":"ba1450574b1962fcf595fc53362b4d684c76603da5f45b44bc4c7eeed5de045b","impliedFormat":1},{"version":"b7903668ee9558d758c64c15d66a89ed328fee5ac629b2077415f0b6ca2f41bc","impliedFormat":1},{"version":"c7628425ee3076c4530b4074f7d48f012577a59f5ddade39cea236d6405c36ba","impliedFormat":1},{"version":"28c8aff998cc623ab0864a26e2eb1a31da8eb04e59f31fa80f02ec78eb225bcd","impliedFormat":1},{"version":"78d542989bdf7b6ba5410d5a884c0ab5ec54aa9ce46916d34267f885fcf65270","impliedFormat":1},{"version":"4d95060af2775a3a86db5ab47ca7a0ed146d1f6f13e71d96f7ac3b321718a832","impliedFormat":1},{"version":"6708cd298541a89c2abf66cceffc6c661f8ee31c013f98ddb58d2ec4407d0876","impliedFormat":1},{"version":"2e90928c29c445563409d89a834662c2ba6a660204fb3d4dc181914e77f8e29d","impliedFormat":1},{"version":"84be1b8b8011c2aab613901b83309d017d57f6e1c2450dfda11f7b107953286a","impliedFormat":1},{"version":"d7af890ef486b4734d206a66b215ebc09f6743b7fb2f3c79f2fb8716d1912d27","impliedFormat":1},{"version":"7e82c1d070c866eaf448ac7f820403d4e1b86112de582901178906317efc35ad","impliedFormat":1},{"version":"c5c4f547338457f4e8e2bec09f661af14ee6e157c7dc711ccca321ab476dbc6d","impliedFormat":1},{"version":"223e233cb645b44fa058320425293e68c5c00744920fc31f55f7df37b32f11ad","impliedFormat":1},{"version":"1394fe4da1ab8ab3ea2f2b0fcbfd7ccbb8f65f5581f98d10b037c91194141b03","impliedFormat":1},{"version":"086d9e59a579981bdf4f3bfa6e8e893570e5005f7219292bf7d90c153066cdfc","impliedFormat":1},{"version":"1ea59d0d71022de8ea1c98a3f88d452ad5701c7f85e74ddaa0b3b9a34ed0e81c","impliedFormat":1},{"version":"cd66a32437a555f7eb63490509a038d1122467f77fe7a114986186d156363215","impliedFormat":1},{"version":"f53d243499acfacc46e882bbf0bf1ae93ecea350e6c22066a062520b94055e47","impliedFormat":1},{"version":"65522e30a02d2720811b11b658c976bff99b553436d99bafd80944acba5b33b4","impliedFormat":1},{"version":"76b3244ec0b2f5b09b4ebf0c7419260813820f128d2b592b07ea59622038e45c","impliedFormat":1},{"version":"66eb7e876b49beff61e33f746f87b6e586382b49f3de21d54d41313aadb27ee6","impliedFormat":1},{"version":"69e8dc4b276b4d431f5517cd6507f209669691c9fb2f97933e7dbd5619fd07b7","impliedFormat":1},{"version":"361a647c06cec2e7437fa5d7cdf07a0dcce3247d93fbf3b6de1dc75139ff5700","impliedFormat":1},{"version":"fe5726291be816d0c89213057cd0c411bb9e39e315ed7e1987adc873f0e26856","impliedFormat":1},{"version":"1b76990de23762eb038e8d80b3f9c810974a7ed2335caa97262c5b752760f11a","impliedFormat":1},{"version":"5e050e05fe99cd06f2d4ad70e73aa4a72961d0df99525e9cad4a78fa588f387b","impliedFormat":1},{"version":"4ff327e8b16da9d54347b548f85675e35a1dc1076f2c22b2858e276771010dd2","impliedFormat":1},{"version":"f767787945b5c51c0c488f50b3b3aeb2804dfd2ddafcb61125d8d8857c339f5a","impliedFormat":1},{"version":"14ab21a9aeff5710d1d1262459a6d49fb42bed835aa0f4cfc36b75aa36faddcd","impliedFormat":1},{"version":"ba3c4682491b477c63716864a035b2cfdd727e64ec3a61f2ca0c9af3c0116cfd","affectsGlobalScope":true,"impliedFormat":1},{"version":"b222d32836d745e1e021bb10f6a0f4a562dd42206203060a8539a6b9f16523f0","impliedFormat":1},{"version":"651df11341eff0b769fb83af75b1872e6cedf406674c5eaa2650551aceb5a816","impliedFormat":1},"6e5152cf26279cf64a2896118a42c1c1c5c77f92dcbc6c1c5fff7bfda2ab5253","fa3d196c357dc18fcdf745def3bb9f7350237c855788b4198b21dd949fe26e5b","8bfc638c3b9ab9c619d2dd995c09d63a6feadfb4b010d716c68c5a81e7a02c12","468ed654a876fcd7ecec6c48ba7fdf2065f6930ca230deb2fe704e5090c58254","af0e24dbe934c38978674a89507fee43bfa3818fa5285a402fb8e2f0298aaac7","bb7b594a11a9cf49d1da660983410a0c691f496b78740406b0067190c5af9dfb",{"version":"005f10cafe0939ae8d6a98e19c4ddf8b59faf3f9ae38dfa5907b82b9a6cb4de9","impliedFormat":1},{"version":"089c056ad8ecb34ee72cb831491ab72c214d8fb7ecf94b96a1b4736ab54397a1","impliedFormat":1},{"version":"e643ef3093cba63af26396ae8dc58dc542c241027749dcdf715f3d3209f79a03","impliedFormat":1},{"version":"f40e6338b8137033a5b4efbe01de45a4399f2c304648eace01d852cd05eb861e","impliedFormat":1},{"version":"89d879fae02696e226dbcb7444d6153158fa264bb646071988f19a2e422b314f","impliedFormat":1},{"version":"57de3f0b1730cf8439c8aa4686f78f38b170a9b55e7a8393ae6f8a524bb3ba5a","impliedFormat":1},{"version":"e933bd300ea4f6c724d222bf2d93a0ae2b1e748baa1db09cb71d67d563794b2d","impliedFormat":1},{"version":"c43d0df83d8bb68ab9e2795cf1ec896ff1b5fab2023c977f3777819bc6b5c880","impliedFormat":1},{"version":"bf810d50332562d1b223a7ce607e5f8dc42714d8a3fa7bf39afe33830e107bf7","impliedFormat":1},{"version":"f025aff69699033567ebb4925578dedb18f63b4aa185f85005451cfd5fc53343","impliedFormat":1},{"version":"3d36c36df6ce6c4c3651a5f804ab07fe1c9bb8ce7d40ef4134038c364b429cb3","impliedFormat":1},{"version":"e9243dd3c92d2c56a2edf96cbce8faf357caf9397b95acaa65e960ad36cb7235","impliedFormat":1},{"version":"a24a9c59b7baecbb85c0ace2c07c9c5b7c2330bb5a2ae5d766f6bbf68f75e727","impliedFormat":1},{"version":"3c264d6a0f6be4f8684cb9e025f32c9b131cca7199c658eea28f0dae1f439124","impliedFormat":1},{"version":"d3cd789b0eebd5cebde1404383fd32c610bec782c74a415aa05ab3593abc35c8","impliedFormat":1},{"version":"8c1babb42f52952a6593b678f4cfb4afea5dc91e5cfaf3ca922cdd2d23b1277a","impliedFormat":1},{"version":"04ebb965333800caba800cabd1e18b02e0e69ab6a6f8948f2d53211df00a193c","impliedFormat":1},{"version":"f8e2be107b3e756e0a1c4f5e195e69dce69d38d0ff5c0b0509933e970c6d915b","impliedFormat":1},{"version":"309e580094520f9675a85c406ab5d1de4735f74a38f36690d569dbc5341f36a8","impliedFormat":1},{"version":"c2fa79fd37e4b0e4040de9d8db1b79accb1f8f63b3458cd0e5dac9d4f9e6f3f1","impliedFormat":1},{"version":"4f0d1a7e2a5a8b85d69f60a7be2a6223827f5fec473ba2142279841a54e8a845","impliedFormat":1},{"version":"ae2fb62b3647083fe8299e95dbfab2063c8301e9a626f42be0f360a57e434797","impliedFormat":1},{"version":"f53d803d9c9c8acdbb82ef5c6b8f224d42be50e9ab8bc09c8a9a942717214f9a","impliedFormat":1},{"version":"d2d70166533a2233aa35977eecea4b08c2f0f2e6e7b56c12a1c613c5ebf2c384","impliedFormat":1},{"version":"1097820fae2d12eb60006de0b5d057105e60d165cf8a6e6125f9876e6335cde7","impliedFormat":1},{"version":"8f62905f50830a638fd1a5ff68d9c8f2c1347ff046908eeb9119d257e8e8ae4a","impliedFormat":1},{"version":"8b4d34279952175f972f1aa62e136248311889148eb40a3e4782b244cece09f3","impliedFormat":1},{"version":"d3c3cc0840704fe524dbe8a812290bfd303e43d3bd43dcaac83ee682d2e15be0","impliedFormat":1},{"version":"71725ba9235f9d2aa02839162b1df2df59fd9dd91c110a54ea02112243d7a4d9","impliedFormat":1},{"version":"80af0c272dcb64518f7768428cdf91d21966a7f24ed0dfc69fad964d4c2ed8c1","impliedFormat":1},{"version":"1dc9702aa16e3ada78c84aa96868a7e5502001c402918b6d85ed25acbe80fd51","impliedFormat":1},{"version":"35f891c1bc36c97469df06316c65a718956515c8b3bdbeb146b468c02493ef13","impliedFormat":1},{"version":"2e9b05d7db853315f44d824e13840e6fdf17d615d13170b5f5cf830442018dcd","impliedFormat":1},{"version":"ea377421970b0ee4b5e235d329023d698dcd773a5e839632982ec1dd19550f2e","impliedFormat":1},{"version":"42bc8b066037373fd013aaa8d434cb89f3f3c66bff38bccfa9a1b95d0f53da7b","impliedFormat":1},{"version":"63427caec4ad7bb6e3bff8ceb3ead82dac7f1433dfbe7f3690b910426543cf13","impliedFormat":1},{"version":"ba477f04b5e2b35f6be4839578302aefdcdeaa5b14156234698d5ba9defb7136","impliedFormat":1},{"version":"3ed98b1231ae188d35ba5aeb18eb2cdbd918b70075e3fbc71959ee9055ce2904","impliedFormat":1},{"version":"450747d3afba2311520c45000c9d3675a8637e0feeb049587ec46bbfbe150084","impliedFormat":1},{"version":"6367899812ae700d8b6e675828c501e56a2d6ea9e19b7f6a19699c2bf3f5410d","impliedFormat":1},{"version":"55205c6dbc94a8b6face2736e9d81eb26115f047360da38d9960657bc254c8ba","impliedFormat":1},{"version":"a1b3f5e004361def2fb3687490a3ad760c65fa6956a98f373fb427f84e186622","impliedFormat":1},{"version":"a2af662be84d59fddf13d4fe8eb937277d6b2403032eb399f29ce93e109b7840","impliedFormat":1},{"version":"4905915dc882e64a92f648d71aa22967d17806bc7dfb14112616f28f7ad64a86","impliedFormat":1},{"version":"f2552aaf43e006701a2c7a12d815f9ab92b4ea74541cb94ac572745a3182af1e","impliedFormat":1},{"version":"74914aa5df44badab2d6c6f26888ecd7ae1498ac141110edbf0d076e3b78d834","impliedFormat":1},{"version":"66aff1650105be2e13a071a759bd73f2fbbb9f0ccc7be4a82f9b4b90fade57ea","impliedFormat":1},{"version":"04b7c0343f394a54d055b7dc92839736eadce575735d8cf27829cc9ed8beb071","impliedFormat":1},{"version":"3ab1edcd71fc84b833365363dcb9cc57ef2b6b221e2596c8f46a6dc357cf4c8e","impliedFormat":1},{"version":"19d1f2c26d18fe022f6d42ce10b527d16c869822213659a2d5341ec5bd4d64ea","impliedFormat":1},{"version":"013caa871633534a6cb0a2eabd3aaaa103374273917e7b1069c1107701c06322","impliedFormat":1},{"version":"8212da76658a962def8c1cf880a535619b7ba18082f16c9ec1a81e57ac7a4310","impliedFormat":1},{"version":"4fd01f378c52da142d0b9b75d9ff045a56743119210bc377906eba06474b93f2","impliedFormat":1},{"version":"cdea7d48792b22fc2982c6c9d1224694ab4c4934922549d23386ba914700cdb1","impliedFormat":1},{"version":"31cb4e10d97bc3cc7060580875623d10855d3ec6f30ba8d559b82367ac2a4b78","impliedFormat":1},{"version":"253f4be36fac44b5490f82b03548213f3b3b2a336b6e99256a5284c1518cbcdc","impliedFormat":1},{"version":"850f9127467b7111eb7d1d7e27b133c2ca4b37e21ea95603be4c1515a1d2a090","impliedFormat":1},{"version":"a0027c6261e055b122973ef5a81c6ea42e71cbdd00bf48f035da6a41901d7baf","impliedFormat":1},{"version":"c88fac812559ada55e72155739fe7ae9e7814bd08dfd4e987cb8de252b58934c","impliedFormat":1},{"version":"f79ccc20893bcfd015bd1e1786441755c5d194a46b6141272f24ba3b7943ac91","impliedFormat":1},{"version":"1b204fe0b411d618599395438221e7611b8efe4ccc03ea23b94444ed428c7d37","impliedFormat":1},{"version":"92fcf18040af20479667ec310cc3776e1a39787bee9be0102be3be3d56143644","impliedFormat":1},{"version":"dc40287c52b3604245745eef59cf5113afbd0403563f89782ecb7070463194b9","impliedFormat":1},{"version":"5e25c6704992bef5469941dd7d79741975724ec148e3b6ff4b6293f40dba7340","impliedFormat":1},{"version":"4553ee0c6984a870bcb788051061042cb298d66593c76d3650b8779b1f85c565","impliedFormat":1},{"version":"7e11a4e1b2fd0ffaf1c5fea48612f773b99f03b0cce4408cc78eacb5a89f3a5e","impliedFormat":1},{"version":"9eb9073fc2db3307427bc66c63fb6d79db58c727284e2eb43bf6a702adf7edd7","impliedFormat":1},{"version":"851df570f2099a24f29ccb6ead2232ebdbfabcd2e861c79f1a437fbbd80c4ff0","impliedFormat":1},{"version":"155d2fa3265c3726dc74a727c9e332e05c368a0d6c708bdea4e0ee0278770be6","impliedFormat":1},{"version":"6e903d0bcdbb97ea1b3943e52b386f30ef2e71441a11f467651e0e14527b1a2f","impliedFormat":1},{"version":"6820d14792c6d99355efeeb876b40d4a241d6e0d78aef82d023729ca3cba6595","impliedFormat":1},{"version":"9f2a47cc564979be753558c56917c5d67d5b0ed6b295bef7b07734be840b3e91","impliedFormat":1},{"version":"24ea00984c775211302c98237e16400b8842acb2655e3498ee05310ce7240c50","impliedFormat":1},{"version":"d432e628af37cbc180fb9b18d0b421f6e37d19227439acafb107381361609602","impliedFormat":1},{"version":"298bc76807612f73d64a045849f8f9d2e9df078d5052e8f034e933f76ca60d81","impliedFormat":1},{"version":"57e3e9fc5c580c4b8c9041a9d3b4a334b8402a35fce10e8c94efc89c5b8ecbaf","impliedFormat":1},{"version":"fe587bb0b49b4d02434b796f442bb89ac0d045b836c94acd8f106a55cdf7959a","impliedFormat":1},{"version":"c442605e6ce4071fc952c7bc317ce81c66c0e4ec23e1efa6a0b6afb7458169ea","impliedFormat":1},{"version":"482a3179dd90570039d90e4159b2ccfda7186a3a216b33c6e35c5b4d021178a6","impliedFormat":1},{"version":"85a265dfbca44cc58b790d1caf2bbda8d9aa5730bbf30d78f61f828fad3f7b17","impliedFormat":1},{"version":"3dd9d9a2f65d26c36475822f78ebd8dc8a842114cf3115432becf0ce64edd8cc","impliedFormat":1},{"version":"072140774022f65f8d79fb8495a2a2c4b6ee841388de0fafd76bc59f7ae01775","impliedFormat":1},{"version":"40b19ca60b8dcd84eb1cc723ab2fd979cb0aa25cd38345dc7da7e106ab0411ad","impliedFormat":1},{"version":"1e1dc965cc3a49fb7452b3fdaa2f74f9a1118e0a904ba3f491005d2423b126ea","impliedFormat":1},{"version":"9bfdeaeb78c48a547cb758649911790b284ac8835673acdeff40ef99785182fb","impliedFormat":1},{"version":"5c6d364da5cffbb9683d919374182cd06b12cdb5ab2df1f7a95dda8dedc70035","impliedFormat":1},{"version":"cda98321016e30a315da804937b2131abb46ca7124b87e0571809149686bc2b2","impliedFormat":1},{"version":"2ea570fce87bee69236ad613e555bda51d78a4e1fe704d30feeba4a4d0d811d1","impliedFormat":1},{"version":"35e6bb2564253aa70cbf05ce99a1f006296cf454d26cb31554f95e43ae136dde","impliedFormat":1},{"version":"af8e5441071834a8ff8051d8d85750e9e473e6aba8d2c2b2324ff7ccaf89ca32","impliedFormat":1},{"version":"78cd4ed880bd0b6cd1825a0ae8d8a4e8cd698de357dcb7d9b87fe06b86470925","impliedFormat":1},{"version":"5a72c3b5f4f7b12e3845bc2448bafd7e1043d906681c11f66505cf296bd6e4b6","impliedFormat":1},{"version":"01f7fcb2fc6ac56e69f3a7f6fea5ceacbc67f736f48ea5305fd08ccbd580a205","impliedFormat":1},{"version":"8c80e470fde3e62d24293b5135dbda138cf13a899c46efb21bd09ab0829d731c","impliedFormat":1},{"version":"738f7d65c72a30e9e14e850b3809d9fc7ea3d4e836af084b1d1ec11a180d453e","impliedFormat":1},{"version":"1fe1170e8c2dd0f83350f429478aea0004baec18d9b0da1bbf7c843c6185e21f","impliedFormat":1},{"version":"ade5bed2580d59938a6eab180b05d2d3dbe49420a32080741a58d971519ea076","impliedFormat":1},{"version":"12f485fa0a429d4fc7cb81059009b1115ced010deb9a992b2deaa24f7ac1465c","impliedFormat":1},{"version":"606ecc3152f39cb58b33a5d6b0cb71d7a2e7ecdc466e3a0a34e6e03caad77f33","impliedFormat":1},{"version":"0121199d5ecb3a4f1c4e77cbc37882812c9e4533b6a035f9e1fc39fa9b698820","impliedFormat":1},{"version":"d2c12e73cdf765bad858e24d78867c8702986a04d98ba2c4b6476af99f3d193c","impliedFormat":1},{"version":"d6431a739f0ee5a0ef7d28bf30139bc0825141678418ccd370b4f7244b316168","impliedFormat":1},{"version":"fe5ca32422e41036b73d8a99e65430b40e633c09a03b57bd6586ae18ecb02463","impliedFormat":1},{"version":"dcba161fd6f7e2e6fa97acc01b37b085292e4ff9449df3db7dec9383c03be886","impliedFormat":1},{"version":"59d53805f2255bf14afa11c336df340ca2dcd71b369e8ea8ec42b371743ab3df","impliedFormat":1},{"version":"30bb85fb0a208e563a2eca3e650824b502188746d32be95ff994ba1b8a6f883b","impliedFormat":1},{"version":"598f543b3263aaf38c0107a8e87cc9f88417451e9431174736df228393b5b789","impliedFormat":1},{"version":"db9ede91bbbb7fc19b7fdf1576cf94f66c97c40e7aa2d8b56cdb73f7c5ee7cc6","impliedFormat":1},{"version":"26ba4bc8d6360f95b78ad383e842017792442f10fdc5155e9f414d4d9804a281","impliedFormat":1},{"version":"58189830df1b27bd67b5de94d5b7d3fad32f1fc8d17fafb723104e74eaba1aaf","impliedFormat":1},{"version":"66f096fe5d81f57d026da9886cda3fec992dc395cf4009d6b27da44265bdd6a1","impliedFormat":1},{"version":"4d820c75d431d6ab0a19406c78003b1ffb8be9db1b233ea413ccc9d855022cbd","impliedFormat":1},{"version":"d69f4d745833ade297ed1114863aece1a19594f7479da78a532eed3121eca07d","impliedFormat":1},{"version":"61de67a6412dac01b334b61218e9c6bd052fddace144195cf5957fecbdf5aa3d","impliedFormat":1},{"version":"0a09c49e3d93b667eb4299a42c402b56c42ca09ef12f188ba76c0a5fc3620d85","impliedFormat":1},{"version":"26da972b373d69d5fc3352d4a0d9f11014ffa2167d0935540926bf08070d0f9c","impliedFormat":1},{"version":"b344f5a2c011df183ce6d132124047bb932b14e1a7923198ff7814a641a9b7eb","impliedFormat":1},{"version":"6571324bcb254ec812a469c3d7480738b96d8153090b0ada6356698a2315d8d4","impliedFormat":1},{"version":"6570e72915ab1c3693a41fe1736c9c8deadbd8b6061304108390001afe05e510","impliedFormat":1},{"version":"cd83f0f5f9e1630da050e4ec4701f607d98e5df679b82215422584759d0950cb","impliedFormat":1},{"version":"81bbea2421d5c0ef4fdafe3074dc6ef0f096693efb2f6ec10990c33980ff90d5","impliedFormat":1},{"version":"1ef0facd0c8d3dfbdcbec215097659414bf638db2d1392a72bd95718ec7c9574","impliedFormat":1},{"version":"2f3d50df625cf9d51dee885bcd54640cd24015b20302e2bb22e5d82cfe5d817e","impliedFormat":1},{"version":"a33740d241e7cc043528b6c9ea403a8e9eefcf37accde6ae982f1156a30a7ee1","impliedFormat":1},{"version":"0595e92268d5449de31dc79b869063bba3e5b5073b8ddff31e96254d1f97e51b","impliedFormat":1},{"version":"beab480c4b3fb3f14678399d3a919c0956100457fb0177c15271d1bcdb05db12","impliedFormat":1},{"version":"a678ab2d887c6418d6eb192a6725e95829cf85c26de96b988210a166d9329cd5","impliedFormat":1},{"version":"cf17e3026b3b73a58c981056509b9811fd75ba3556ae7335f8bc26ca5b8d4d87","impliedFormat":1},{"version":"1792a2909d10e781fd41293b47a0b1d8e48dac71f6220988653950eefd08d517","impliedFormat":1},{"version":"9ea6fef546dc430d77c4cdb97da3b10cc44fa62ecd6a012778b194ef39a8da8b","impliedFormat":1},{"version":"8cae882b093bf807a88c18173f41d340efd011ec534e7e1f0bdeab81a9f8e46c","impliedFormat":1},{"version":"9021a860ed1f446c405a698d54ce8e29518f4cc49804c2fc77f8679bec0e882d","impliedFormat":1},{"version":"cc19e3067d3daa95fc5a9d9693bdd324de02a1695fdb55a155b4482732b2de43","impliedFormat":1},{"version":"0671d332cf6aee602dbe433a35e29ac8aa27a017e74435b6a4690895cfdaf912","impliedFormat":1},{"version":"ad027c73b1f22dcd5c4a632e383f1b07439ac1f3c07ec85ca22f3df1c610fd11","impliedFormat":1},{"version":"bda20f225d2ab07ad1efa681b5b98a82b79bd60b8db209f255d80f324272c006","impliedFormat":1},{"version":"3626a285d29636bf9b2b9a4c0a1372a4a91edc706e555e6a598c8d8fc33584fa","impliedFormat":1},{"version":"7f30ea4dd02c9465637b070cea283ee3a795761102dbeac2f59fefd8a34695bb","impliedFormat":1},{"version":"f68cb1619447a31870d82ac30a467b88cd38cc0fe899a1e549da4e82775d1ad7","impliedFormat":1},{"version":"93b65c26488d167e23595dc0691a48edf02aa479d3868e8b8f63e9671bd44f46","impliedFormat":1},{"version":"d1476dc9f5f15e87fb4f1ca1b201743c2fdf8e3cbdf947ba0eafd94c42e38ae6","impliedFormat":1},{"version":"693fdac094a44a8014b999516a545bbfadf1e515355b896b980c2f6c88653e54","impliedFormat":1},{"version":"a7bad6ba5ed47fc5234eedb80b69839278ad6fe062cba314b064736187a5a05c","impliedFormat":1},{"version":"05642805a3cda9d29080dece865b57a1d6682f55e32a6b7b69ccebce13801c2f","impliedFormat":1},{"version":"41b1ee91c14f7268bcd53b1620e9a2cd8fca9b9073c6ba13cac28e014ceca0f6","impliedFormat":1},{"version":"fb2dd37a90231854242e8f0dc54fa68c60e833b951e7aaee09efcbee46d45c2c","impliedFormat":1},{"version":"ebbde780f9038b3ba3b388a7df1fc92d30d3cf4331919b7169e404eaeebfe877","impliedFormat":1},{"version":"46ccd74bac38ae9452be4adbffa5046c2d6f76efcedb6749c96275151c99a285","impliedFormat":1},{"version":"9d0d7965a4f797b13ef2675e287db52a7075f6fe5c80aefd81fe37c461ffe646","impliedFormat":1},{"version":"6d396d6322ac9530a24f948a53a67eb664fc171bbb280bf36d2ffa07f295fcac","impliedFormat":1},{"version":"d644215a2353c2ed0ab0bd7039e0c78a0949faba20e98d25b793bf7560478d38","impliedFormat":1},{"version":"6f1cf6da2ac3459c1beef43d4f5cf21ab7545fa67d5fd064217324677090b1d2","impliedFormat":1},{"version":"0c5133efd4d70db33c0799c65ea805890e2d3a5678826d064924007f31380616","impliedFormat":1},{"version":"d004cc45fff02adf312dc0e7b75b966f676a357eedf91e16f0d7f9381b9cd230","impliedFormat":1},{"version":"ebbd153ccaae498934ed84158e9193d957b9a03555991220fdd420b35a92756a","impliedFormat":1},{"version":"ecda555c3481deb9d28ab32e23d60809e1395dc8266e79e741d2b7d1faa94a7c","impliedFormat":1},{"version":"a59a99a1e6cea500b2c468e1c0c71842bf7c379e790e70be5900c2f19e3cd609","impliedFormat":1},{"version":"fb72b3dda87d69b17e31be6e5ac1cf82820cb446ac9196ee2fa9b38564a33825","impliedFormat":1},{"version":"813428a716c4bfe57045db81e95ff5e930a673bc497fc9dbf8b5e39bfca9d506","impliedFormat":1},{"version":"4b8c4976a60970ca17ba185a58ae225602531abd0d17cc5b7a74d7c53b1b2806","impliedFormat":1},{"version":"e68b32e7aed76fed2d248a17895ec5eef00a52420122ba2256a2f8406f390baa","impliedFormat":1},{"version":"102207fd553f30c8ddb71cf7b85ea8c1a2d823c990fd67a323a6fe6eb5e2fcab","impliedFormat":1},{"version":"5002b5d18082227d854635fb9c210334395638987c52fe62846775bc7b089826","impliedFormat":1},{"version":"7707b25484e54ee7ae4fe68e346abdba7c113ae9d796eb69f7a04f179d45f827","impliedFormat":1},{"version":"251341f627ecad05f1c337750cd3deaf3cd759707f43a7d253c585529fef9d3f","impliedFormat":1},{"version":"feacf0441306659c81ee58def3001660cdf555cbddfd3771ba78a2175f2af1e3","impliedFormat":1},{"version":"376b45ca125a07348dacab3d28dd2be0f4fd93244d98fb7b7a0b5e3c30ac0214","impliedFormat":1},{"version":"712941c4f77fe496988eebfc2f723ecdade134c6409d92610998408a243e4b5f","impliedFormat":1},{"version":"6fe76204ed893bbf9c57aada5c1ef7aeb02dd3732f711ef848c03b4bb340e7a2","impliedFormat":1},{"version":"b74defc682ae38289f33c1b15258d76d3608385233e8b9d400ec40d4763328db","impliedFormat":1},{"version":"5a81417ab92470d2165b02dcd26ada9cee903e0bb9d8fac7ca23c833a5330b1c","impliedFormat":1},{"version":"187846a5bcdcf674cc71ab2db1713ea32daf59555916c8b2325ba7d053e0b961","impliedFormat":1},{"version":"912a90a2b59b9d181b09d99525b46f4882240a9d10e53493f618ef73941f22f7","impliedFormat":1},{"version":"06074a2fd3649211b7c2f1221c250bbc15edf1141e5d06a8851ed06f17897b79","impliedFormat":1},{"version":"db3fd8dbe6444f1c9c75bd826307cef5daef47af41b085dede77a347b38a0e56","impliedFormat":1},{"version":"8108657ad8732b4ec8cc5ec6ff5ee6d9c849e310cddd1dd1ad08b4a550b36d39","impliedFormat":1},{"version":"3a2b4cfcbf3dcb0c393ac545216da2accc9dc4733e39e51f796ef6f420b8a0a3","impliedFormat":1},{"version":"e100cc03952121b87dd532e5422de36ba7f0ddf785bcb80001a207df2ff6318e","impliedFormat":1},{"version":"a3b43d54be4ee2b0615ffc17c6d679763ed6a7430d38305eab03a32cf71714dd","impliedFormat":1},{"version":"864af93dcdbc48818817291d4374dcd4de5767c0dfa78068a7abc42c9312f6d4","impliedFormat":1},{"version":"0990402dfffde022e48977341ed6bd3c1bb333d85472d045ddbd90f54b8dbcbe","impliedFormat":1},{"version":"85a3e6c929a8957543fb0ded79640d3e27462d5937af0055806058f0bcb060c5","impliedFormat":1},{"version":"8ac17fb1f96322718c1f9ccaf0157adb8c3992b16cfecf24fe9352a8911f9c1f","impliedFormat":1},{"version":"0a623e5fe2aecbb7b9e53754f88f21dc81225a5da6f1a48c378aed2a27fdd776","impliedFormat":1},{"version":"114f46bab4ef24e51336206ea0baad234b215825bd1f04139606b3b61ce64b97","impliedFormat":1},{"version":"3c1781db18a5d008aea14223a2ad41d04e58c6fdcbec35bf83dde627a6318078","impliedFormat":1},{"version":"f59481a27bc13a30eae650a150378e6c1904fc08cd3e90fbce41f25ec71ff5b8","impliedFormat":1},{"version":"0a92ff71af6f42d18435f5f6d0f515a27942d177992853e4be2b99592129e6a1","impliedFormat":1},{"version":"c87289b49867bbd1e2896a1104bc85e65d65840a0bab688a472c8e4aa68fde32","impliedFormat":1},{"version":"f3426ade86c219be8010d109750b4ec38aa2a47c3a95effc6d0a8bf8832aa7be","impliedFormat":1},{"version":"73c3e5c4bb7b23d333cdfc4d245b31b00ff39608fb5e7bbabc5baae443596da8","impliedFormat":1},{"version":"8de5baf5b89f33333e78f5e160971c650ceb7a73a589998c5f4c8e683701e00e","impliedFormat":1},{"version":"3d0dbec8e4ab0c2f321a5e785387e48fdff7f9c7d2c4c5013ac1aae8d6354bd2","impliedFormat":1},{"version":"3f6dc049f17ecf06211ae0d1051bc0d9471ec940d97ec718ff0f469138672ea4","impliedFormat":1},{"version":"87f4ed26b8db81fa983b3d6b476dec32e35c60f25bd30670e0802e6a9bdd8603","impliedFormat":1},{"version":"9ec420478d84ef14805a734e1786331304fd3de7860908da9ed1a79f1529a2e0","impliedFormat":1},{"version":"b7d77ee3b4a46f83e9fa265f3eaca648b26edd450e5ea683a94b20998cee66d4","impliedFormat":1},{"version":"a45a8f50ab6c02374c33ccca554b36e6b70b9e0eb73435654d86e36816d177a5","impliedFormat":1},{"version":"491bfb9da13993c96d51f798d67fd4b786b97fcd26f9223c74924f7e2f190dcf","impliedFormat":1},{"version":"7c5a6093dcc366f0ced8fe2fcb18f9564deaa10ae0c0dd4adcc9e0bdc70e647e","impliedFormat":1},{"version":"608e8177e088c1b73d24ef0067816fab9b11e58d6d65c59d93cd033450564f4a","impliedFormat":1},{"version":"d201d1a7edb595e96b5e411b3ba52fde41678a3fd94947f0293de0175048d516","impliedFormat":1},{"version":"d2a81e681eed24cfb6172c05c686ee8abad38573b8f42322d9114cc63a1287ac","impliedFormat":1},{"version":"b8eeb4c5df0178d0f732eca804930c0a8daebe5f26d2c3d355d5e3789f96d072","impliedFormat":1},{"version":"2eefc31fcdac31ea30ce28c8228739b7c9321fc560460c04906165a6379745f1","impliedFormat":1},{"version":"7d9d0d19daa08af870ff49b76f3afa0df5991fcfbe6ddf592563a1bac87a63b1","impliedFormat":1},{"version":"a8fe86756bcde593a6eab61f0e60f52d2480a35a33f43d8c60c11efa34b783ff","impliedFormat":1},{"version":"1537d7e30578752414d18973932f0790a6c296717f76147147b9f1257d3cf490","impliedFormat":1},{"version":"b04a1c6e14037dcc4fbef5f4f2d04fe26054ee29bd227d17debbf0021eb3c711","impliedFormat":1},{"version":"4afe6a88f11bcdf5f1f849d0dcb3f4c7548a51de289dce9e94827cd1cb55a82a","impliedFormat":1},{"version":"84a5cdb4eadf0c94a9451b79a5c71f7aa7a978c4cb29f82083b10d6d0797166a","impliedFormat":1},{"version":"6961e9eaa7eda33a765bbe4c3821cb3623637ed53c093a3b8d2a77b40aa41f07","impliedFormat":1},{"version":"f5eb7b80029f740dea9eb597b2a049391b1cbe48568cd294194ff884f55d0013","impliedFormat":1},{"version":"142bcab07ddef9a99a65d4cf93193ee46ba9ebc8fdf6a95cbd10d59926a7ac8d","impliedFormat":1},{"version":"73a887b634d7968268b0a7d289cd128232ce3cc9914e61830225406ba196861f","impliedFormat":1},{"version":"13779d67bbc86f47568cba5c66cbac894f9332969ab9870bccd2748ebf377e43","impliedFormat":1},{"version":"528720fc5cf37df5760b4e85202b3ffd47546b56430f13486e09ad229706b969","impliedFormat":1},{"version":"40c9c8d868706a097981adbf518bf84b2780f9fa5de87af24f56138ac7b941cf","impliedFormat":1},{"version":"f0912a4dddf3a7c066932ab5fe0f1637ad76ec4c67f9da49f040e2f4a31aaceb","impliedFormat":1},{"version":"750a6a3f69f1032cbe34e7c2fe8a45c8f013eaedec5c324dbf5ea76b2d15156d","impliedFormat":1},{"version":"f3916b725bbba8e6af7c96967bd2d6c88ab721314f79c6ded2ed973f23f10aec","impliedFormat":1},{"version":"d99c5b55f2a7c3bf5ab5184965cc9244db06d6d4c7de2ad1b6633b12fbe3356f","impliedFormat":1},{"version":"92cb410d441f11668a3894a6d4a70202841689c53cdc3b0c7561eb6d3c696abb","impliedFormat":1},{"version":"781f638357e9902aaabae805410786a1c772bce961fc29507ddc44f73a4cccec","impliedFormat":1},{"version":"2adb545499bfe3f471112fbc871ecccc7ee303569edeca250c6ec2506ea63952","impliedFormat":1},{"version":"d23e59667c6eb3bc5f1cc0228c464d9ed8ef974cb9858f3f123a480f422f15c6","impliedFormat":1},{"version":"b270523911758636f2cfd194ed9387edebb02fec9f708583bce3481d12a5f42f","impliedFormat":1},{"version":"3a83aefcff33a1975df3860b023db474afd759a417ec68ccde77b1cd060e4a58","impliedFormat":1},{"version":"8cc3a6ae941624d9f9f4a673db68df1a52c7a01030f19ff3b2a29da98f070be1","impliedFormat":1},{"version":"3f8a77f378250ca5e0979cec8787bff5725de5eb43003d2161fdd8f64d7fa599","impliedFormat":1},{"version":"4a59fc1152fe86b169e19bfbf1a676b7f1946dae603bb73eaf17d57756b80b35","impliedFormat":1},{"version":"3c4d407a2971f9c84fdb3908f8bf51ba807ec015dbe89a49a7f23f278febb703","impliedFormat":1},{"version":"9248aa99bf1c1768a50115c195be15aed0abfc67e3513f65798483c7886daa87","impliedFormat":1},{"version":"348fa3c3bfd5581e563b3206ab44b7c6f0e8ff6059124ef71c8f676633d4b1f4","impliedFormat":1},{"version":"987275f98ef0bec6becfa9ed2ce0abda3f88921efd38c565d3ae88a269d8feec","impliedFormat":1},{"version":"9985dfe74df31d21668649f8d9377c28faac1b3cc6838297bc54ef57f5bbd4e1","impliedFormat":1},{"version":"4a5c8c838e4cea59ed710cdc58e99012b5a7f8aab5c9477ed572fd8c8daf7ac7","impliedFormat":1},{"version":"e9ea77667103da8c7e4c73e392f486a12c4b9c48deefd1a3f71aa47245ce402c","impliedFormat":1},{"version":"8df27047eaa93fc6643c4cb8fcaf2a5a5f0d9d0df429752ab44a535d4749fff6","impliedFormat":1},{"version":"1078e32910bade9017f764acccac07648843ef6eb4a4dd10d8bbf4ced3a8221b","impliedFormat":1},{"version":"149c73989041efcb7b123f0aec9a0aab86005fe7c17d3eae31981853c4b445f2","impliedFormat":1},{"version":"4bd62e172df81152508d0e88344ed130fbc57140be879cff0d19e6061ffa173d","impliedFormat":1},{"version":"8538ac1726aa74bec9e9bc763dfa8dd7beff8f82353036c99131436ad84c0707","impliedFormat":1},{"version":"a8349c8a82ee2d41ad95624dbaf02abe4dce09091a500231a667b6b7bbb74a1a","impliedFormat":1},{"version":"6d008996a2a453d570c26b07e91f07901309e47b345bddd0da4ac9d0f4aafaab","impliedFormat":1},{"version":"8e11e19716cc71fa3cbbd1bd00ea1fb0ae29781a0ed5727d7a7c5a12f3aeafb0","impliedFormat":1},{"version":"cd639fea9a1fd5e8fb0b2678518e670871f3ce689f9a67f98d64f0942ebba7d6","impliedFormat":1},{"version":"ad56f529f9b1916ca206ecd7562b3a871a502f9d20199c32a410d8dc8396127a","impliedFormat":1},{"version":"37882652b72fbf86ca9c7b78bf8b3c46b3a11f0863a683de583d3b22e1967fda","impliedFormat":1},{"version":"9588c4e501fec831dc80a71d027fd5b5c0ac9dd1ef2a43fec25a39b916709a6e","impliedFormat":1},{"version":"2d9c777540b2a4d9ce1ee8e7ac16a35ef2e1b5057547b234e4f06567b2c2c512","impliedFormat":1},{"version":"7851e9d188484dcb329bb68ac5b3bd856ac38254280a2be8069f93bbe7919405","impliedFormat":1},{"version":"0a403f4a79203e3dadbf352c6be9a1ab63d8f5f3c034e8aef9139d297fde75cf","impliedFormat":1},{"version":"0a251fbd045ba1f92652040d10c03595e170bf3c45d09abd07e6dad51bc4c22e","impliedFormat":1},{"version":"bcae937e5e40a1527e52cb6b5841e64007c82345cf731a8846a4353df8150f61","impliedFormat":1},{"version":"f994a26765784b6ef3624ba555e00e88e3b4913a00a1408cae50174634e4c817","impliedFormat":1},{"version":"d524ecf1b7043f8e9ee5228c2ceaad059120e9e2e33d8ba554e9e7602e6b714f","impliedFormat":1},{"version":"5b56e1893b5690831de139fc38b87b7cdd539806c9a406624c0c6375a60dca14","impliedFormat":1},{"version":"f345f0c384bd81314b2591eb7753ef73354227e0e710d2db28743d60349b9069","impliedFormat":1},{"version":"a4d7d10ec50b4925fcc425c242e8045363489f8cdd6cf313de7f4e1108cb7c24","impliedFormat":1},{"version":"e20b3473a1915d9f554f60a6ecb4800a6284e9ae5024e68aa1f7415a749de423","impliedFormat":1},{"version":"ee4a1829d09a57b33e865819a765f955d51e877a88dc4e2772a64f0ae56b6799","impliedFormat":1},{"version":"f733e16767d662333f7968410be298041a21b0ae43654c49599acec154d3257c","impliedFormat":1},{"version":"4fe7a597c29e2cb98218ebac44f736b18651801f9d570079fb73b9ec14d6c51c","impliedFormat":1},{"version":"a9e1c151185e11f88885fba32fb8dd897e28fd626b990ea8d4de0c25f5bf463b","impliedFormat":1},{"version":"524b6d55a7621e2016d4e64c395ee5d07e2380f91be83823b9d4c1e0722cf998","impliedFormat":1},{"version":"1c6d028b4d5967a4aaea9861d05248242696d25ed35d47f570d38945f2b0cb72","impliedFormat":1},{"version":"9787af26d4f0d8022c60eba8052da6d950cc17110dd0bce453fae69ff9068925","impliedFormat":1},{"version":"1053d65f53ffa40d6f93d31fac0a772bd54da3f5f0766415670fcaefc5d6db65","impliedFormat":1},{"version":"11a75ed6935f7ed72564781ab7b960af3013ae3368c4940f1e926ec030d7ede6","impliedFormat":1},{"version":"c28ef31731a44a04a03eb09b297bb98f133f2534945c6960d3c1f26a5aa4f2ee","impliedFormat":1},{"version":"17af18eec2a68629b3966326a8ad26b945ad7cfadf7645e6ad2bd8dcbe194b3d","impliedFormat":1},{"version":"af3d1b69d67a397b1d43d73fceb378c6cfde7b08345e6f42182c4005d537090c","impliedFormat":1},{"version":"f02b14f037389344febb79d1e16e262c62c6e15d528d15cb0d5b172ba172e5ca","impliedFormat":1},{"version":"cde00eea2fc8aa29ae54b3f47be202f478316f61bb68e963fd29171eb5856c13","impliedFormat":1},{"version":"04c434851b52ccf3da19d2ebb17a9059ce3ab6ae19b6565b29a8c4495f695c6a","impliedFormat":1},{"version":"e90f050b6dad98f6c4364437408e446b414a10b12bcece3da7167b0f59337b66","impliedFormat":1},{"version":"83866f1209bbe522e7df6d8a2d765617eed7bb950ebb06199a4fbf7345688c5a","impliedFormat":1},{"version":"01a59b7f3bb8c538135a7232868378a1d748335f8d122f132f4b80a543bf993e","impliedFormat":1},{"version":"2906cdcc4a9410316cab1663a9826293833eec8d79347e6f1e77b8f84725ca07","impliedFormat":1},{"version":"d3a66f2362d1d0cc9380207e97626856bd3c4714a615c2b2c9496d976d7736ef","impliedFormat":1},{"version":"18a13a5151346517aaac11458ef13cad8aea42ecb6f4f4aad593fa80c7f094da","impliedFormat":1},{"version":"9303793dafcdde3e719a77ec780a03577898704c9ca4b8bdbaa1d7e9e859d5cd","impliedFormat":1},{"version":"8e0755806a099720074363db4ec9fe16f4399ee0f9c96f5c5dd220ff3dc35d7f","impliedFormat":1},{"version":"f5a0a1cf2edff1794389b53d34ae9a2d3b4676c827db1d4a99f80e663b3bdcbc","impliedFormat":1},{"version":"d7018cf4289038687a576096884a016a0f74225055fedc9de51f62f407acc11a","impliedFormat":1},{"version":"75f56a33aff680fb9adf0109084e0344eaf85bf5e64bc4498fd31124e3dcd391","impliedFormat":1},{"version":"f46900a0bcae506cd5c073966c8810c166271cb9120f624135713ffa19da8324","impliedFormat":1},{"version":"65f468190a1d2a83d8f3be5e2ef9fb6f32a6fe59212704f629614ea0aa6f2cea","impliedFormat":1},{"version":"7b82aa44f95cdc8f4ea38baf90b3c8655b6e25ee235bcffb7a031de3db5729ab","impliedFormat":1},{"version":"e13913af0e02e9dce4d280831c6ebc37b202905661746dd9fe26da93ca0a8253","impliedFormat":1},{"version":"a93f3abe451857b2c12f87e3631d24a4ed0ebd7d84f9b0f1b19dd39f4e1138eb","impliedFormat":1},{"version":"3e84a56e78d5109391c376e835903fe4aba818edea0a21bbe841a6310a2d0e93","impliedFormat":1},{"version":"5f5cb73713cddf57cf4b49f0f117f5812db59568eaf149d2e6425262f47a080a","impliedFormat":1},{"version":"2f3eb57081e4e3fac07401842d21255e8c043f447dab576c2da9f395f5a0f541","impliedFormat":1},{"version":"8ae50d3c209725ea637692b7443fc373f5da381e8ce5fc7c45a9aeb8dbffc49a","impliedFormat":1},{"version":"0e8ae1d7fc9bb6da02d9a17720bf33dde528eceecad0baeb643dba7b415f7aa3","impliedFormat":1},{"version":"16329df80fa60647f193a9077f5c9b09e70906c247458b793bea44532a0037ec","impliedFormat":1},{"version":"729b59b9493b1965a66df2daa611e2e40d89869e02e7abdc0e95a786e2079ce5","impliedFormat":1},{"version":"f71486238c37a441ba57e75bfc30e6e5f2f90ed126bc5aabd1bc42c515ffc759","impliedFormat":1},{"version":"12294a1bba61a5a82ad9bf1f292d8b7cc6ffa67643c06c48df5180089d1c02c8","impliedFormat":1},{"version":"8862eae7af1e5e31edd902dc61445c9d5d95dd9cf9b746322680991830e0b80d","impliedFormat":1},{"version":"aba723a858bee7ceba4cfd85e80cd7aeabd4d8dc6ab20bbc3685b8ba06bd209a","impliedFormat":1},{"version":"49553430f3568ce4cfbe146d744670e2751dc52f3e403434d3d4035795f03c49","impliedFormat":1},{"version":"25049ba7f889bd8e06e8c747dbaadf7d682818f424bc759c52bc8274b8f51cb6","impliedFormat":1},{"version":"ab5bcc053aaf3399fdd8364ba0691d6f5be77584ad4a1da5937a96c15fa9d5c1","impliedFormat":1},{"version":"49f6279a7ebc6c2f059300cb5958c0cc1eb803337f2945db34540df5ff2cf58e","impliedFormat":1},{"version":"ee426f8afabcf2d92677b82c1989778de95786a5ef5de9e6e99949e4d4458856","impliedFormat":1},{"version":"dc49475b5423fe50f7392dd9e4c0480d75dc8dff68ecf9dedf50c6ae347dec55","impliedFormat":1},{"version":"c15d4641edcc518a7d7268023391cbd8d718512c8f6010e7e717142dae595b9b","impliedFormat":1},{"version":"43631ff6d6270b599c16d8c5fa5dc7329f5d9828b34ed03236d90ca97d483e65","impliedFormat":1},{"version":"c0bc5ba5bf1c39e26162d69b989873ce64438232e6cf613c61307508dc953f7e","impliedFormat":1},{"version":"68a0d4d9784054c30821c37511d3c60f61410891be22130034632c888967b6c1","impliedFormat":1},{"version":"ae614dc9605413b3d5f7393f7321ff16a2e94fa5b0281fadd29fc9f41bdb714e","impliedFormat":1},{"version":"d50d998bbce191f4ad8fa1d46d5e557d2d0b9184c4bb139da836e325eb9228f1","impliedFormat":1},{"version":"67e403468cca8a36da706fd99e18bdc8f41bb05c5729e6ef77107fc50dbf84cc","impliedFormat":1},{"version":"3ea201fb6f9cc81e39d8056643ed92bda36979f6a46ae2fbc2669f0f816f5a32","impliedFormat":1},{"version":"8fc71c7c6d751177e8cfd8f3e56648bc1a660fffa371c78c3f5c711c436360f0","impliedFormat":1},{"version":"7ad3c109919a99f6f415373b554085e602de8fc4cbed6d9bb4edc026e8b1bdd7","impliedFormat":1},{"version":"bc89dab508975faaf58146a4352a0a0366192064b60e4b958a7bdf0f8899f34e","impliedFormat":1},{"version":"9882e7599ab32fa74a89f49dce12b4e7d6b580c86a679124b17be8484448f750","impliedFormat":1},{"version":"26da15b6113809eaf5f07e6e53c6c5250343f1c2b6500a54a47a50e2fa46069e","impliedFormat":1},{"version":"522ca69ebaa603f814742bb481e626d75326758a836d3524321a29e1af6c4566","impliedFormat":1},{"version":"127936770383d88526e8023e050b6eca51726e979c93ebed7bdba150a95752a2","impliedFormat":1},{"version":"2c399c16749ec28ffdbb45e4ff876ac797e08ece8ebe608cb9c9cc46d7dd429d","impliedFormat":1},{"version":"1940a1a96a1560579e39dfaf3a428615ffa91ecc0a3bffc54e57be37de72e058","impliedFormat":1},{"version":"0784bfadf05ff50d72a7e30e2c5264b92e6f1228e1a8b198eb1d878a8f541844","impliedFormat":1},{"version":"32207943ea3b00914bcaf9d2f4a86a188c4a5a313fdb6379eec1599d5a0f1466","impliedFormat":1},{"version":"f03e0b00e2fe2c2f2f78230688db4364e4f3900de6747afdf35d7c0f85325814","impliedFormat":1},{"version":"c751158ccf21347856b268a1f8caaf1f2f8db256dc68ab1e3f7651eba1d60bd3","impliedFormat":1},{"version":"d98a6c16791630fd7c656ce87434717c850da749412c67f09fcfc60c0aa43d4a","impliedFormat":1},{"version":"3e437ca93f7eec1bdc4c32bc53268323fe909c3c29b18399bb27d76ce0916992","impliedFormat":1},{"version":"a35988d5283ef91b943c569449a55d97a50ab3e822b08d4a73722a2bdca588dd","impliedFormat":1},{"version":"3653f9e5256db842bf9b56c3d9bf1f0a0d9d1ef1ddbdf36637ccfcbc99cabcc5","impliedFormat":1},{"version":"63c6500f9ea3cd202c7491295d4eb9af2ad65becef2dfa55a6c9158970d586a1","impliedFormat":1},{"version":"c6ae6de9a043720a019ebca6f7cf22a1d05c2a22241f3cc8da22f54ae2888c3b","impliedFormat":1},{"version":"c44afddaa5f633559fd1af64b358bd8fc3948144a9c49aca02adfa7dfe1531cf","impliedFormat":1},{"version":"0ac29e14e4a147e008a256e8ebadd015949fef17985ee87abc49187ba0ac9ccf","impliedFormat":1},{"version":"8ff9092e0b11519a4b0637a677b13d6daceaab64b0663557469215c9fe93b871","impliedFormat":1},{"version":"de9250288e487076171af7e3f9e5eb6d5b33ee28dd59199a599f0de50bd326ef","impliedFormat":1},{"version":"e62780653615687ffe25698ff1a26e2288bc75aa20168339f2428307488378c2","impliedFormat":1},{"version":"4f9afcf96dc4f3ea57c4434fe1f80d09b2c6566d92f28f49a87344e5b790390d","impliedFormat":1},{"version":"6cb40aef0ccacac80e64582df2d2115ea61ec60317a59caae71e37185c6d569b","impliedFormat":1},{"version":"2b4d632bbe28cc535074b6bc3b979b059a0b230064a7deaff4473651b359f9c3","impliedFormat":1},{"version":"19faad0aa7b3cc5e95424c7419c1d4f6ae86a831499212c77fc3efbb53c6ebe2","impliedFormat":1},{"version":"164f7da74ac924db55579e1842d4022ac661e175991350fc15a3451d4ca90ff6","impliedFormat":1},{"version":"b8a4a87e27ab60532c4f548081b5a2b63a2012f48209d758fc54ce75fe382748","impliedFormat":1},{"version":"50485b00f01e946ce50661d1892a71871539d7e4b574a6410d169257d24584f0","impliedFormat":1},{"version":"814553a796f380e47fd72cba91f783f6805554c82d8b9d077e2af43572049534","impliedFormat":1},{"version":"1eac93a7865eb35a084fa4274dacd5f1ddf93d9332d355bcadfdf2a20aec37ff","impliedFormat":1},{"version":"5661b4b8459d8bb7ffb65f678ab32dd2ac14999b348f9e143f143a4948040e2f","impliedFormat":1},{"version":"1884c39ea6d66c62f578d46288958e3560f460e81cddbb729d1e1873473da7b7","impliedFormat":1},{"version":"187bb2d5f3f5dfd2508a9d299e0edee7d5178f72b261b73ad3fe6c8a44a2e735","impliedFormat":1},{"version":"e46e0bdedae67ceef0938a6d23d8f256bd0867c192dba71fc97cd714154c4ff4","impliedFormat":1},{"version":"3af1b0cd662a3c0d17e60254d95ea51a221d0b36a9086f56e0527889fba06038","impliedFormat":1},{"version":"077528d2b3ebc067f5da152194bca6e11a6157e5bad429f4576f3a1dc93015b5","impliedFormat":1},{"version":"c6bb7d4ace52a09e76bd5626252086db65e801dcd89897343f3cff9503b24d7c","impliedFormat":1},{"version":"ed75dc49b1b8ed8abd774079ff5a9c8d0da2fa545d09ce6b4d807f150af314fd","impliedFormat":1},{"version":"26d559b50c73bf5f3e9899e2f8ee75ab62b9a8c3e361cd45a8c817f02d436983","impliedFormat":1},{"version":"42fbdaca103f33f0c492a996d8e393c80a034e4b9fcd9730ad2dfeb8a128f686","impliedFormat":1},{"version":"3a1da59c1c591d5b74342ce42945512e19d559d2ea8b5c694724a0bf602057d2","impliedFormat":1},{"version":"e03928d60b3cfea34bc02fdae54ed09719ba81aeb88db7616ca3f9885e0ce010","impliedFormat":1},{"version":"22c9bce7aafa3d3db8dd96bd9cb7ef5db7aad6db096bce9f50b1470aad329eb2","impliedFormat":1},{"version":"2bffe78ea8c697f61efc52434fea25aa2587b41fac2f32743450ca40eaed81c6","impliedFormat":1},{"version":"40e863df00097ca5ff6cb918b88e58c0c4f5c491eaf3dfd85ab7fc68364b7f78","impliedFormat":1},{"version":"f0feb4db795c86bb499a91375dca9edd59a2cb2ec41629b43850b6e94ca85931","impliedFormat":1},{"version":"10abba3da372c0abbf8efbd4ca16921c289918c343b1e58e1166d32c2d6d7058","impliedFormat":1},{"version":"c3236bfa9b797f758fd0c36f8a0e3a9d870022268c1cd11e66894212835d5b7c","impliedFormat":1},{"version":"8a2580630f3fbd5ca4d7bd46a4236fa66935ce7dc8da5cb5f9e59ed663034162","impliedFormat":1},{"version":"92381738ede8411e7faf362783f0fcb5d93224d10997d5f1e87f77f10dd1269e","impliedFormat":1},{"version":"0df39c7bfa5830298f40f0ad783de0691b754117171e743793f9bc9dd3b9e4c4","impliedFormat":1},{"version":"b25def2864136aba133e85a9537fd3de11bc9cb493df3861a21248d4bce93902","impliedFormat":1},{"version":"d93287cf452df544c688ccb9a4c089fb14d7523ab69aea27c0f4e1e5df333f0a","impliedFormat":1},{"version":"8ece28b7a82c0a376f04ef48859b0f7d710a358d7c7ab704e39a0ebf1da728b8","impliedFormat":1},{"version":"812581ffb5131f534eacf36437499ed55e6848857fee327607204d401dcbbd60","impliedFormat":1},{"version":"af69d6b89c91c98d95e305cdc8a606e75f8677827a784d099dd8b551203e3a24","impliedFormat":1},{"version":"aa57411a58be0cd634262a7c7b9b556e34c726a9168d86e8a3f7e4ada4bb957d","impliedFormat":1},{"version":"f89f6b2dc18ff7795a92e7a125a1474255d7777a3c966331e81a65ffab805345","impliedFormat":1},{"version":"797332973b9b34c7eb34404ec920a7a24bbd3d357f9d8d53760ce6977ae3c218","impliedFormat":1},{"version":"05c140d3cb72a7860d68f3c8cba3c38aaed47849dca77f9ac64ca2fba70f872d","impliedFormat":1},{"version":"bd9cdfb9d580e7545361f0129d08f2a7265451affa9f80a7d2b7e249750b18f1","impliedFormat":1},{"version":"ecdc675f0e93127361cff793797f80fe76fdf70abfad54b927fd8b26607de761","impliedFormat":1},{"version":"e6e4d8d9edfe3dfb80965a5043798801c86a159e707ed7650e27ff49355b18ec","impliedFormat":1},{"version":"ec92ffc93dd0be4335a918f79210cd7b897a82fac6b40931efa2da9127201cc8","impliedFormat":1},{"version":"14710e1fb4a46b5a118c721fb4c51a8cd73205e2cf8e55043968df6fda2f0368","impliedFormat":1},{"version":"7d9eb84c83c9de7469484e4efab450054afa388b65cfe6f4e97809b809a36c77","impliedFormat":1},{"version":"5230ceca0cdce9e76614c24d307078eba2b0b44d0c531ad146bf446337373f9d","impliedFormat":1},{"version":"f725d18736a1c0bd455c625358e4be0a435b9aaf5102b7605134c64c6cb0a78d","impliedFormat":1},{"version":"29a1a7e60e121d729bc1b6eb41dd2ac3381ae7ce8d97900ddcc0ced0b6272a6a","impliedFormat":1},{"version":"b67611716f1a37d1e1d5cd004af6c3d7cedf2ab79004f2a6a75f32ca0f7bb17a","impliedFormat":1},{"version":"069862840e19178306b1d808d0e1e9e5ec63ffde54cc77acbfc0f18378d06c62","impliedFormat":1},{"version":"78cd77c6966ddb5fc0d52c775d912028be7eecb95cab8b956b9e6f33b72586f6","impliedFormat":1},{"version":"14c468bcdcefbb1e658ac9b6e5c2260592b10803ebe431f8382c0fbe95b43d2d","impliedFormat":1},{"version":"f3e771bf798caf7ed613ffa02ce10e3faa726aeb72f5a2dcb7033c3c4fd7f060","impliedFormat":1},{"version":"f5875b60ff6c36a46d0b3679a9d032e9d289dfab897e0dc9ebd260d4a3f17fe3","impliedFormat":1},{"version":"8a90805d55641399d9c005481565ef917f34cb0dd40d95595c714aea415f48a1","impliedFormat":1},{"version":"94d53649aa6a7609c445c8d4361b1894fa6bd370e98983b0f6ffed8552910d10","impliedFormat":1},{"version":"0787c493379f370b838f77a22db07c3c309356cbe9d4731ecf88a15fe39e1284","impliedFormat":1},{"version":"1e462419e099fe667fae16dddeecfa38fec31d7f731a285a591a98faaedcf20b","impliedFormat":1},{"version":"352d395ebd9e1e3fbb54dcda03cf4b5fe1f501817682f02f41cfdb92e5e9ebfa","impliedFormat":1},{"version":"9c35f65c404de2f5f8c47b90809a4a396b5fc6a13110ddd145ca430f44cd5506","impliedFormat":1},{"version":"60c637cc6771d315311d69b84b24ea5189e5ae499428bd1f99154ba94f04fb2a","impliedFormat":1},{"version":"7b2125962294e3fbad621365ad3ae5eb482ee92492b4037e6b4c30b1b872c208","impliedFormat":1},{"version":"77a4133f03091bf1f478aec5bdaeb09450f6286783a59aee60516f22028d1d52","impliedFormat":1},{"version":"bdf996a735a1f8c356ca5e807504579b57b90e0f0e95af0251d52debad79b6fc","impliedFormat":1},{"version":"07bc4528e7a8efd252a2b2c5c0b9ce60140ef613b4c426edae5b2c0c3e7e5801","impliedFormat":1},{"version":"76f99fddf78c9f19c9556a0b2b39244a3d36c74cdef34b036471531a9aa98bd3","impliedFormat":1},{"version":"a92e1e934dd90068b9933ad82bf4a73c7e70c28dbbbabda89be7eaa5274b72dc","impliedFormat":1},{"version":"60a0d104c1203290ef8f83586fd064c6288e5c52e54d090e7e2790885c558ab6","impliedFormat":1},{"version":"5899aac37faea91d36ddd5a394f6d2711b5290e15212da1b2883575f9790aed4","impliedFormat":1},{"version":"ea15626b4d37595220a02e098b03f7a66e405700bc970d459a2a0ae4e37c1726","impliedFormat":1},{"version":"adc2f4ff306c29e64a693be388ba322120f08b7d39bde15801fdc43eb63bec8e","impliedFormat":1},{"version":"17cc62d187b947e2b2b408b54fc7a29b28c364f2b55c7008eb02e2ed5f906fcc","impliedFormat":1},{"version":"30532ac0db0d0c9d98a5d0cfe9ec51aa4cf8e977e43f5de2a6896e73ebd0047a","impliedFormat":1},{"version":"0a1a0ab7e3c249cf778fcba6e3735f74172be72a64f3045930b1003332a5496d","impliedFormat":1},{"version":"b08e65c2810709cd637e8a58d509a3a6d1efd80d7d0f6b78b864f12e6889c38d","impliedFormat":1},{"version":"65446bb8d6a9e4bc80fe8bbf1b45a53eb469f78b3c8287f4daf7b7ca0dffdeb9","impliedFormat":1},{"version":"51deaafc7d88a341b169fbd6ac38c9e1074846064b7c945f564e9e0d53bc543c","impliedFormat":1},{"version":"060927763b99e1c5b30df489981b2b004817d2c16a831988ba4bd8722e8debbd","impliedFormat":1},{"version":"a88087f489b32d85c6de137294a50e273d5835952c799314909faae8e7eda5ce","impliedFormat":1},{"version":"1df0730288cbcd3fa338bb23d1736cca8c3211ef62fbed9910bd3ce144bae8b8","impliedFormat":1},{"version":"efb3284c7b47d3d14cada6bfb425e0f2d6f2eba4b40e0933bfbd195bf469b5bd","impliedFormat":1},{"version":"16f2ed85656df3d0d241c5ad3eb2af2a92d4891153778b0cd069a4349c711a3b","impliedFormat":1},{"version":"45d964e4074dff4b110e261609d517beabaebbb7c2ec045c53ef31b7f1f38daa","impliedFormat":1},{"version":"48aa809baeb792e083daa0aff6cb7c30aaab26c5a9784f166a6b1cedcc9e819a","impliedFormat":1},{"version":"ffff3a1f33a6caccb0e55f573bb47487d8e426c17018360cbd8c60db2721104d","impliedFormat":1},{"version":"6eac61335abc02d7516a7f206f2db0a41c08c9001f7f41e1a4928641e924b2c4","impliedFormat":1},{"version":"b0ad178e030c29b49b796e75e274bd6891a91137a7c6fa6a31c8ef42a02fdf81","impliedFormat":1},{"version":"59dbd08f2e53680360b3b2bced75a21d7b8283a10cd53f3fe61da2c4d5434157","impliedFormat":1},{"version":"90d0e48565c3c233f681ecd4a970e822d52d5fa9bf0cfed9fca86d3bb9abbaeb","impliedFormat":1},{"version":"0d0823386811829d4ec5b688c6fb8528f0ac2eb20d509857f1f884e61a544888","impliedFormat":1},{"version":"216cff6e50e4774e146d17d5e9bcd6c50edb7dd49f963f02f26d07158428122c","impliedFormat":1},{"version":"81b23bd4bdce658744b1fadd24b365e05cb23bab4b42b28ac75ae6f1d7f6b33f","impliedFormat":1},{"version":"f1effd7f74e678e1bf3295fadfea49f1ee9704eebfa132d2908bdab8724336a5","impliedFormat":1},{"version":"2c7324acb4ad89ae740260ea55862b8169626f231845a43640fff376e52626ae","impliedFormat":1},{"version":"b080b653746d60e78b018c219cacfb3f1f225dcbe30162d4e32a034208ee4f81","impliedFormat":1},{"version":"e1a4c250fc0a706261bce9ff10948d26c9436c42b9e760ea87a9192a12b29ad9","impliedFormat":1},{"version":"69f802f2d01bc829d0948cfffb49ff72bb213ce0cf088afb018347cceef3c9f9","impliedFormat":1},{"version":"7b329a1ac9315e5bb5315012397df20ef445298caf28e0ca3b6d554eac48934c","impliedFormat":1},{"version":"bc4a7ebaeb14dd42ea11a71e35dd4a165d88fb11e797456b84c6c85002e28055","impliedFormat":1},{"version":"6a33b434bc85acf5ca12fb4d1e13eebe5f696739a175f00ac0393c0279659d06","impliedFormat":1},{"version":"ab56f0e3441a79165899897edc1565c6e49241dc76950675271bdb2ea7d1b550","impliedFormat":1},{"version":"565d4f09322025170ab0129a400607c59c787ac942af37bfaeb5db7338148f5e","impliedFormat":1},{"version":"7cadc657f8392f9b8ea95134348532389fcda20c1b642d4ee9ef4d48bcade6f1","impliedFormat":1},{"version":"0aa3b2f513844030a5a74837dacc2cc25126f6b33839b4d679c31939a1d2c809","impliedFormat":1},{"version":"80687c94cdf1338e544f0ddea222cb16ef1c10e32067c14ada455a15310195b0","impliedFormat":1},{"version":"d3f615a83208ea22f0710526c44b2aff0bdb0416846716b6c52d1fe0fbf7bbcb","impliedFormat":1},{"version":"4e386cd11163d5cbff4858136b52c018a8c3fb45cc40d52400b9f950130fc7d1","impliedFormat":1},{"version":"ce5c51c18612ce1b894508bf536edb7218a8c6ee3dce31c8435a5d402ff89aec","impliedFormat":1},{"version":"917891660cc843ccc8928036e34f17dd4ab2a033c02a537cc2adad3ed17efb6b","impliedFormat":1},{"version":"3f1b01d5bba344dc9f967d342ff9ab8c7838b18ec42ea85379673abc5ebe0172","impliedFormat":1},{"version":"b20ba8d9f214cbf5a2632b7937d137cc329e5f4743bd93446dd8303b61395dc6","impliedFormat":1},{"version":"86a381ab6061b647213f266aa5973a7ae639250ebe7b496ef22c903ab4cfde56","impliedFormat":1},{"version":"a18e66a3a526c19a60e436515d5cbbadd2465fe73ab9855c0fe4ce476a8322e0","impliedFormat":1},{"version":"8a84735b7d2c9d32efb220f39845f9047377b9e7cfa9211fe54bb05c940878e4","impliedFormat":1},{"version":"0bcb138e5c3575e2a3740b4ee558ea0e7cfed3d06768c5a44b73d37e33d169a4","impliedFormat":1},{"version":"d791a36938691ab212ff74d7474172c99d49fadfed20a8948f8af3695c4bad2e","impliedFormat":1},{"version":"114551c50c61b0769e1fea3a86a7bd789dc7bf80524940927e2d3252687d7bda","impliedFormat":1},{"version":"ead484dee4a498681465705f978c6392a0fbf1fe82a00294e2fe4d7e4cbf6515","impliedFormat":1},{"version":"fd70db1a08be5b1273b4e89a0c17786fde726f3f6fb6f3ee02c118cb18493fa1","impliedFormat":1},{"version":"226b03afecb044c57d29cb1247c8293ed2c45ed5b33884abfb585e6dd8af0a1d","impliedFormat":1},{"version":"76beb543255249efb2d8617340c16f467a0fe1a9d27ab8ed386bee521cde68ba","impliedFormat":1},{"version":"643810b48f15f3194ab114bca134d4fd75ba373dc430202c016b8640a396b163","impliedFormat":1},{"version":"a50ed9fc3d47d6bffe6c17335180300d8fb3cafee4798ebc0d96b0af56d60b3a","impliedFormat":1},{"version":"5ec08734e87239b9ec01cf49181daf2144cd075967f6a957a6661ccbe7700327","impliedFormat":1},{"version":"121c3c0f3992e6b51e83329ab8a56ea268bb6adcce6837ec55cac42d2a37b09f","impliedFormat":1},{"version":"4a20fd9177e6ae1d5e02fec839a957e770f8b997201d3acf9bf594fac57a1abe","impliedFormat":1},{"version":"2e3f98a24cdfa68d3414ec1bffa53ea43dc56ff4ad65b06a39c8e0cbe817e41b","impliedFormat":1},{"version":"051853967777c1ea04ea61977b4d104d99b52b1821c27a4c79b63f609b1cd193","impliedFormat":1},{"version":"329a57d8ab17ad6448fd941d4d01cee0940ae73efd5ad27600a45aa663b7b869","impliedFormat":1},{"version":"bfc5cc4cd38acbb61073659892335646b89b75f0f00537f279fe8a9adeaa236b","impliedFormat":1},{"version":"2b94711ad249dc8bc40a76a318be0f0b6c0b49970acbee8361ef8b083d005521","impliedFormat":1},{"version":"4356606c390a97f1f3976c1ad49338e331b49f69c98f1ea4cca4fc7e16dd950a","impliedFormat":1},{"version":"48dabe9a448cca789618231c5fa043ddb6f125cf5173f954e34c3946f8770907","impliedFormat":1},{"version":"2f17fd5072ae414cebfb3aa3ec45fd1337847b0c6842f47c948537b2cb002a50","impliedFormat":1},{"version":"264502910816d013293783360f61ac9c00e4befe6f30f199cf937213d4019eb4","impliedFormat":1},{"version":"4e261a95a59ee811b5ea776eb3eef45664b2f051fd9c70746bb686ba20c3e9b0","impliedFormat":1},{"version":"243fbf83c712a03e50151006a53b2a485ea7fb1d6e36f41d8efeab750e5c709c","impliedFormat":1},{"version":"4f6a81fe5ec94a44b4529b3a9ce3e8ffefc79f6dacaa160e34b0fbb7674f0ef0","impliedFormat":1},{"version":"c4814494bb1059ea0385fe4d74daefdd2ee1a834b4d97f7a065da78d5d65d03a","impliedFormat":1},{"version":"55c520aaf6d36a38a3977d4653107682758226ea603d6339899c13496979f7a5","impliedFormat":1},{"version":"2a4faf4fe50494498baee3d2a75b305effc4c5c4956738b801383477327a97bb","impliedFormat":1},{"version":"9fb2fa211999614f2152f1dc5a094e4063467dd07d213750c5a20598d514241e","impliedFormat":1},{"version":"a30b51f84c4c12534b9847be50f4f0a231dc59419597b4f3d3c7317cfe57931b","impliedFormat":1},{"version":"27eb927bc525db21cde8b0c8928366135a1c7347e19d633ebcb8a639ccfddaf1","impliedFormat":1},{"version":"b209f7d45d6fb1dfc9247f7be55c570202954398bc464d60258012aceaf1a92b","impliedFormat":1},{"version":"28600d07c87e832483b7201ff1030a860a254d6284a864451afae74fce2ceab8","impliedFormat":1},{"version":"a17afbdf5485aad8ea1f7af5fc9d5c89f8d37db4837bfc3b71414da0a897dfbd","impliedFormat":1},{"version":"c78871596c51c47f4baf94185e2ad746905d8efdc5475749456800fadee78804","impliedFormat":1},{"version":"70b6450de44ee884c8b103e157b6967b019a3156a870d6860f5fa97f225290c0","impliedFormat":1},{"version":"2e80da711c1460ac69bbe285ea4f62489e4fabdf4ae2f2f9c2b8ca33f548c453","impliedFormat":1},{"version":"34f40c604593a989ef51407701f998f5f6c1e08159b138d4971ec337baee26da","impliedFormat":1},{"version":"d38ead09d31a065f5351d61334716a96a56fd884be7b5960db5b98a2e675a4e0","impliedFormat":1},{"version":"b679760aa1dc2303466bd349c8ca86feff384af6b141ebb44c4734c939292353","impliedFormat":1},{"version":"1d236848bdaaddf757df57b07aa41c03497de099cc30d81355e782f6e52488bf","impliedFormat":1},{"version":"addf906b9a8bb5c962309c237d85b6aa0eae438609c62788e012d81562ba50bb","impliedFormat":1},{"version":"cd10e7286c6c87c3c4c4b30636635b8ca13de18e4918e2ceec0423a7498b0681","impliedFormat":1},{"version":"d4cb3b2314cd83e3d869bf3f7cd1815ef52a43a6db688a202e550afca2ade771","impliedFormat":1},{"version":"5525db0109a3d2a763c5187885d96b4f09f7e21716fdd55e6cc88f71f8ce9dd4","impliedFormat":1},{"version":"270e1ec5df8e7c681eeee1c3aa9c95a2de57b68ba96943476e37afc6ad8a413b","impliedFormat":1},{"version":"b73cf2f93ff17d54e6a1995f28bfad788832df6b9c81efd9a1a2546ab0917d8b","impliedFormat":1},{"version":"e31f0fce38286ae7266c006aa58ca07894b6cb0a2ece0fda477d71eaf7680ff9","impliedFormat":1},{"version":"fbc3292f562ed60b055b2c3371a8a65c8794731a5390dc45b876f8ca01d30541","impliedFormat":1},{"version":"eebb86f8df7a4a7148f565fd80f46f7d4f7d2ca9ad3bc7a1551ddbf63044624f","impliedFormat":1},{"version":"b9e6dd9e64a23b38aa28c0ad65b5e9013760ca2081bd8798f6e3ec25595c8d1a","impliedFormat":1},{"version":"b4f6693546ff80daf918a0f22e9786a9f6a60db947912206bf829c73910f09cb","impliedFormat":1},{"version":"e75c2d9b8d8e1fe8adc7949ec16b68ef8c7326ee5c3b14f0ffdb1cec5a698e2c","impliedFormat":1},{"version":"7ea8673332f39cc3b1ebe48843447adcb923e4fe38733c48487f6d974424c00a","impliedFormat":1},{"version":"ad763bc0a5f86559540063ea221951bbe242d822a8bed293637182bf70ae051f","impliedFormat":1},{"version":"967209ba6bb766b3e305f88023dd20176c771158427049b82033dbba1fa0da8c","impliedFormat":1},{"version":"6fdc68a66cce3d425e6e333ba2c6dd299f8d14ea5b5317c327197042552de1ef","impliedFormat":1},{"version":"a81dca452c503e191ee11a8bb0ad7b7c6887b598c847b75beeda9c52cc24ada0","impliedFormat":1},{"version":"5736c3eb7cf592ab627c245a1e00a7c30a846f01f149158fcc7c849efc39ea93","impliedFormat":1},{"version":"55c7e6192e52ed31198c051c1a22dae5336b2258872a6af0ff7e7a997a3a1fca","impliedFormat":1},{"version":"335f62e57051aeeb6a71d5847a232229ce6199853a9310f9c4074ea557a8030d","impliedFormat":1},{"version":"f7f74a888ea163b6b0a9cbd3e711d1c949aeb1ae330141725dce794dd230abeb","impliedFormat":1},{"version":"a8b7e7e4f9dfe9eaa4795174e651703f76d94664ea0d64f476c76d7d32b2c278","impliedFormat":1},{"version":"c1e600ad80221aa3207754f6977e5625b06620f7b5001d80c00fa91fdddb1def","impliedFormat":1},{"version":"be51e27ae1706b11dc4dc62d55d5e4388df0aa52bd5533033b172bb348d2df1c","impliedFormat":1},{"version":"857dbbdaf913414976a7325b234a185686b3d44d5c2701129df9a4a75e8eb836","impliedFormat":1},{"version":"d9d2863f2974a359e20c42038408c09edecf9e295427e885778295cee9e9d87d","impliedFormat":1},{"version":"dac627cb38e9aba84cb0cec928dcb4400302bf4fa5d94120ddb0dc60bb7a89f7","impliedFormat":1},{"version":"3cdf4e886166d3de407b509ba490ca4cb8bd6f28cc2b11f375347dd13206e494","impliedFormat":1},{"version":"afdac3a1bb83b5ee0347adcdbcdf360ffdfb9ef90d3d489cdb623fe24be6ddb7","impliedFormat":1},{"version":"f661522f434177ba51de16f9377f3349319d2c3dac7310c0b6b90bcfaa45ada6","impliedFormat":1},{"version":"f7c138d7c44f1a9475aca1b62f37b8850ded7be2f4f3d0ff2dfed86ef30d77d5","impliedFormat":1},{"version":"d341e62c4df56512a9569dbe7b6f4852a84b30ff9878c34ed3ac9741f23a4617","impliedFormat":1},{"version":"5f70bf4840ec03d257ee9f92267153ddcc7bcf8d17158a24f450aabe553b2334","impliedFormat":1},{"version":"b28c7173caf24150b4885acbc496a0a8ae8a7cc9ae94b95aef74ceb271512462","impliedFormat":1},{"version":"236b752302296b9d0fc51974cdd577430f16263b1103d6e4926c0bce6c91db0e","impliedFormat":1},{"version":"16133655b614985a38f075ec0b203f9a243acb8224a8f69f63c9893207d41ac5","impliedFormat":1},{"version":"82bcba050383d47f1d4e34198808f8a75153fa220840af913629079c42973177","impliedFormat":1},{"version":"54c3dacbf6a355666715a30430beb0e13a132b81e53c2af291d48b29495771d1","impliedFormat":1},{"version":"8bd6c3cabf2b5745b2fca2cebc79ff16609dd2a1be35cb37acf5d740b51c9e30","impliedFormat":1},{"version":"20af67c2fc1511ae9783fbb999f82f9914270eb2f8c309a10efbb94a757d8a33","impliedFormat":1},{"version":"4e82e2e2d1845cb1f5638966f69e7df6a60632e7bef4dd1cf66dd70d959ed5bd","impliedFormat":1},{"version":"edf7a947c59d91e2418e984a88a70beeffe3a52a4c22d59ad6aa9eb540f3777b","impliedFormat":1},{"version":"4322f6acc048091031f50660078f0371aa6ad33a4d31736781ee5fffd6c2cc42","impliedFormat":1},{"version":"a755cbf5f39d5a7d2c5a13c9722fd6796de7ffc62b45a03494ea4271a92f2442","impliedFormat":1},{"version":"10dfd913c2d850ba1e47cb1d4f8d2d61fec7ce14de0b12bc1f030a67810e9daa","impliedFormat":1},{"version":"b6cb68af3cb48a21ea9d4302cccbf8753ed8f6647af223e7eb24d32db6f9ff75","impliedFormat":1},{"version":"60d7b57b0cc9a6fc796c1e18a60325af16a2d72e7502278bb2d42f51544f983d","impliedFormat":1},{"version":"dd587809e5253350a5924f103f11b760a77428861227d930e9d3afc58837610b","impliedFormat":1},{"version":"3a3013b2178ac39f289ff261f164875b2ddd3b67b08add9105b1f4c3ee4e6a90","impliedFormat":1},{"version":"d1359a98d40ff1344b92f1947e2d4645dee86866e2c2ede9d0344bd86fbfd5e4","impliedFormat":1},{"version":"6cb22ff59c49ac59e0e61efe07d2e6f2c893238c7761c9f3a57399acb61ec432","impliedFormat":1},{"version":"daf2740fa82f30d1fcfdd1ae23ef7e0ec6100ea1cd2031226128c05fce31ed7c","impliedFormat":1},{"version":"20ff710b2460efd4bbb2815398de0c4fc8654dee12915e68a37572e03bdb6ffe","impliedFormat":1},{"version":"40c4b8f6967d6625ec2a1c7de5af5bdec3f3d6d169343fe4ecc1d1cfdeb3589f","impliedFormat":1},{"version":"b55db69976223356588590f6c8ea72288f65fe4c318b61f7ca55f0743ab1ce7c","impliedFormat":1},{"version":"f1936794585e24e43dad31a59d4040a5655c923df8195becce5acb32fdfe5154","impliedFormat":1},{"version":"6c9c1172d4c7a0f32c4ee487e389e00058df0a4558ccb383deb68715b7ffb8bb","impliedFormat":1},{"version":"4f19fb7a1375858768a0b3ce6cf8d8c21ca5b09400fbb03b221f128408d8b95a","impliedFormat":1},{"version":"0d50e9033ebafcec558a84ed3b3b695720d586bbcf35f4c360fb361650d2c349","impliedFormat":1},{"version":"63a87b94b98eb459e534b33ef9c8aca4dc5ec16ef0aa5b11d84a0f013bd7508f","impliedFormat":1},{"version":"891092f7dfb459d77bf5d600729331ede59202d5291316a63070466a3504631b","impliedFormat":1},{"version":"81504bb68e2ed2d1dc8e0ca540ba9d1b699d9a07d0123ae7aa2ffc84e3f70526","impliedFormat":1},{"version":"9e9d53557646567fd95e69db5dbecb5547b1c374f700a94b3068ef1972064882","impliedFormat":1},{"version":"488240456d6297a5fe919dca673a0d9ee841c494a86febf272a77e703ebb9cca","impliedFormat":1},{"version":"d89178375c7314253638dc35d67bd0b6c0dc53b5a7232751febfbc7824cdd213","impliedFormat":1},{"version":"aa624f94ff1534db2e19e3cb93c99a76b34392a9d66552faed2fc0caf320912e","impliedFormat":1},{"version":"2b137cdec1be8db5bbc20f54c90a17c0066991f7f75628a70115dec411598b88","impliedFormat":1},{"version":"c1a05a75882a4a5b2d76a30191eeb357c4ae3f172db29e18fa06551f83275d6e","impliedFormat":1},{"version":"2354e6aee38b4251db659995e30f2be5d1f2c377764bf29cd6d73d9a8312abd9","impliedFormat":1},{"version":"876d62a9731fa6c754fe4950fafbb7ed75b8ce0f728e6fc06c0827304c84a9ea","impliedFormat":1},{"version":"22cb559bc54b4fa307da9f7d2a28be856636bf85326faecbbe9f07ad66abe38c","impliedFormat":1},{"version":"e9e1745b422d627197c05c944e842ec8cdbf6f11ca9fbddb14d36f1841470baa","impliedFormat":1},{"version":"f833cd62d4d09e51b215040c6578132a7ddb59ea70605b08e7c68e45f56100b4","impliedFormat":1},{"version":"f2d1bc63855fe9c30c598f29427c1493f461fefe81fee53e55390ca9c27db4ea","impliedFormat":1},{"version":"1ef1d9be107143e78fe1c696c565e08024dfffa5f7c8fd7caff5ac18382ec03f","impliedFormat":1},{"version":"3b66f270d6deaa52d3cc39e0b2f8fcc7a05676047ffd588574363ea36f83484e","impliedFormat":1},{"version":"0617eca03f88191a0197796f065b96a11264d9f902240f90da2173762cb41221","impliedFormat":1},{"version":"cdd061902568416110960b77d3c46b9d68dff8b7945bf8772efefd91475393a9","impliedFormat":1},{"version":"768107dac9b4ad225c403b333ff6e770daea8b9a22065483b62f162b40ab37d5","impliedFormat":1},{"version":"f070a3de72748a21d50550b6a1b5b363e3c2fa3a1a06933754a0a4f4e837eb66","impliedFormat":1},{"version":"8c61ec9f859c30cdc7e904a6a5980fa4fabf5e60c85e375108800461316cd8b4","impliedFormat":1},{"version":"b7e16fadbe50a4a0afc5fde603661fb812ac1e3b9368fa626d1339f8701f0a61","impliedFormat":1},{"version":"cdf4cf8addd6579a381203dc926bc8f12e0ea6981fade6761d1dd1eba65ed001","impliedFormat":1},{"version":"3ba1e11da3a50e157ff92008a9be4df341660689aaf247e39dc797ce2ed4ccef","impliedFormat":1},{"version":"ac96821e962abad356f1b1f190f16c26d6fdc7a62e56cba2f3db7322ec1aa838","impliedFormat":1},{"version":"6b99f60bc4c00a4dfa275bd5219886eaf456cac7836cd67b70cc9eaf6bade677","impliedFormat":1},{"version":"bd4058e05112f4217b864efef66802d78b5fdd24f62b03e8c286034304dcf1b9","impliedFormat":1},{"version":"43b14b20813c909aefe2142e24c96896ea199890574c57e6c84f26a9046e5917","impliedFormat":1},{"version":"60807d43534b557cf238d2e5b52bc8dd6201c76ba9ac9dadc09c9a9ec474d7ce","impliedFormat":1},{"version":"200fece6287426bf59229067f26556687e53a74bc96ddb07f5c66f2b857ea331","impliedFormat":1},{"version":"c9ab3d7322bff9e3ce3c1db0e968d9e7d18a6e90c7e72bd3e107ef248e442cf4","impliedFormat":1},{"version":"870135a21986d78d61a9ee4081372197629d14a44c405dc01807f2f333fa379c","impliedFormat":1},{"version":"f1969e9df499ac8e47b438317f4ee17b0c1b805f0a1444706f86f158d97a862c","impliedFormat":1},{"version":"efb4aed3599f3d118da25be786eac1574db3e32fd16d1d5583c03ac60b9227a6","impliedFormat":1},{"version":"1e168d4d4a92c45b721289f0aec0fc1b0ff6cd694fd00c2bd68a8dc25f4dc1b6","impliedFormat":1},{"version":"9a34b3bdef7691f891770097e535ba6ad0fe1b7a286c23bd5e0230bd8886f4ef","impliedFormat":1},{"version":"f57fa13c4097c802e131a887e378a4fd155ac9178aa3a67d91e83cc3cf8f4fc9","impliedFormat":1},{"version":"86a84fe42175f0a0085ddbf8221b1438854d55805bd6d15982f582c065540378","impliedFormat":1},{"version":"638c35c7e219719a51fbd55324cde96a4ed52e7ed68fb75a28d50846d4df8117","impliedFormat":1},{"version":"32f0d0f151f54e676400c4b83fd6cf5c4e16144ccb46cc561405590699537677","impliedFormat":1},{"version":"d1d004ab1be7e7b775c02109c76a5515f82b8311f2e99c3fe2f1342e6dc842be","impliedFormat":1},{"version":"3beff2d22b3a6e15ec0e7c7cf530989491c7d74cc1ae7da0525541b15222c742","impliedFormat":1},{"version":"9a940ff667270e1390903877a11566cbebd766f4d1213e3a6e07590cbfdd6b69","impliedFormat":1},{"version":"02bd5ed573f648071ae7b0a008c88de83fbd0054835524ba6e9ffb281a5436a7","impliedFormat":1},{"version":"5d95747dce550603e6454f6d6ca36d51c5933052851427afb9514f788d06cdd0","impliedFormat":1},{"version":"918163651fb58c3c2d99c304e0827b4117586fa4c5dc1c6ef496021a4fbb6f8e","impliedFormat":1},{"version":"70782d0badc3c6f43d3c6609d1d9f4986a3bd5c780369d2c5691b5bc1aa73374","impliedFormat":1},{"version":"83c3cbe213ae1cc17e106b4420e22e795b303145bab4eff9eef10ff0a743af5f","impliedFormat":1},{"version":"4224c0dda7fc8e3edc9d9d0225e3b5cfafe0490449a07b68f383321ec877e409","impliedFormat":1},{"version":"965210e950edff940bf60d6c3dd5023bd1ac6b923cfea42fae5c36fcc4f0d51c","impliedFormat":1},{"version":"70517f7146412eebc5e7c25ccc2bc31e15c944f00037d848e61b6b864340f229","impliedFormat":1},{"version":"43c768f0f1761f366b5167b2c1d45f897f9d057ac5331fcd6ccf3baa661b5546","impliedFormat":1},{"version":"b3bbbbfda1f102b69eef2526c3c4d5e5e609e82966a28ed6ed3aa6c807874047","impliedFormat":1},{"version":"e85f8a7e202903f2cc4ce0da0295e992be3c009370110d4cf3d663bc479af2c3","impliedFormat":1},{"version":"0170e69a4e928c4b3852867a2994969cb862f0c441e77e422865503f990bc08a","impliedFormat":1},{"version":"92f43c652697e1fe6771c3f7613fd3d4eb639834bc025152e90515ea3587d575","impliedFormat":1},{"version":"4fed2aa13a7e280ba7f9aaff6363e44c41d90f026ea99e73d1aff4312b0587cb","impliedFormat":1},{"version":"0f9ca6e056922c380917d0047c22ceea531e963f752a037d270c02b5d0a7c73b","impliedFormat":1},{"version":"6a800577f051daf82e3fb233b253815b5f00569c94c432f53ea51113f25e4b32","impliedFormat":1},{"version":"11e7a1c03a8b5b6da80a14431a3db7b3a74867c6fea5c819208718348a96f2f3","impliedFormat":1},{"version":"b114c218c34ed7e9c6bc02c46b3f1385cfc3307d434b129050c51abb39752335","impliedFormat":1},{"version":"5d5e2025e1e4b2e2292b4ce82587369d1e293408543e5af7fc7d6f82eb05a838","impliedFormat":1},{"version":"1ba613798c991cc9224dd987ab863ad7c79dc8c5dd57b4d7d02dbc36305c310a","impliedFormat":1},{"version":"cbce8d9489c2a909d0ee4d2dcde2a4410d6b1bf31fbd023ff414d498f7a3ffbd","impliedFormat":1},{"version":"a03d68e2cdccbe1323594021192e9dd93997744d4b70733c5d8b6d23c98bdfec","impliedFormat":1},{"version":"b4f48d3abcf8a3a9cad36529f99f6015335c35217f72b5c00868acc964f55be0","impliedFormat":1},{"version":"508b8cd1ec2d77d4a9ff2464d6c7e7af387afe035b872ccb0edd059fe73cd8ad","impliedFormat":1},{"version":"ea47849a708b5976db82c4795b2785ab60e0a9bb201f2c75e75dc5e7a746ad98","impliedFormat":1},{"version":"f8d4b2e4d38ce941a82f1f9039df2eaa65edc8a64bd999bf9024c1281838cf34","impliedFormat":1},{"version":"53a7ceea2317c488ef9ad81e291f4d7209c3e5b6c8397fa78f2651f809641532","impliedFormat":1},{"version":"1d9c2300255ece5518a22fa1c398bc7b49c60e5cc7e9476966dde5b8a3470ff6","impliedFormat":1},{"version":"313b573f1ba2499803201f8c90cbd4f23560c41b4fa1386144c2994e960ac6b9","impliedFormat":1},{"version":"46eef56ecbf780209ab523f77c5ab0b2adf83ef997b01d385713c4e14ce1066d","impliedFormat":1},{"version":"340c15db71e463fb1aff5a3e14b1b9ea9450de078318a6504625dd806ea10f97","impliedFormat":1},{"version":"434824797d2b76a87373d2afe710c1732c1e6f16d586763cc15215ebb2043b5d","impliedFormat":1},{"version":"2d0b4734bf716c17ffee6e5630dd4a72f834e6374e87bc18f4c076691be3c189","impliedFormat":1},{"version":"91e3948e8eb207cfc0a0b1be1be6887ab45e49cf34d5805a77d1ca4346e5ba3d","impliedFormat":1},{"version":"76302429860a9f014796d2e25d4cb7c2f034040557dbe0e787164ea19eef983b","impliedFormat":1},{"version":"68709bb6ad1a0e113d9bd3779aa30214375c091678e186f8f6f50a10e4eaab35","impliedFormat":1},{"version":"2991bd0c18ca530879cba696c97e9eb588dd500b5ac5145d368d3585fd244259","impliedFormat":1},{"version":"dd94044b4e4ef3ae34f65a5739a295638cb24d854d4ec02055d68170d9024e46","impliedFormat":1},{"version":"6f5f0ac410b479bead70f9bb40d3b6f4644ae66b592cb3c8d03216a74eb000d3","impliedFormat":1},{"version":"29c37d96345902511d8aab5f08202064be006e0ba5446814ed59ea0399128365","impliedFormat":1},{"version":"5a7d4dfc204e85d7bb3a4218f1d4153074a4294f5f88eb161a3c7913e75d4e88","impliedFormat":1},{"version":"d1753f94e9728077fbe3c76e7b6f3d3269164ecb87f0834b4e4a930d0dd3bcfe","impliedFormat":1},{"version":"61cf0eacf097bbe26eef469f3f8025593c0442e9851a7a7278d08e6879df97c8","impliedFormat":1},{"version":"6aee9a0dc91fd18b2adf857ae6491d24925af67f341de000b8bbd2558b04bcc5","impliedFormat":1},{"version":"4a2aba6c504a0f3039810dacbf72f4d7a7006423dd1e0017353c34198ca64480","impliedFormat":1},{"version":"64bc15a76c8fdce437f2fc3875bea3afcaf9fe7000c76a65275e949e2b85a3dd","impliedFormat":1},{"version":"25e6b4f10c88016dedf0ae0f6c277fe419e9afec6dce3481e390c4f66e0484e3","impliedFormat":1},{"version":"d2377541d395f1581addc351f3da9c3b8d4380a4c54252bdaf4850f981157f32","impliedFormat":1},{"version":"246eda7f92ef0f068ae5492766869637be22ac933a644244c6c04e9935c4a8f6","impliedFormat":1},{"version":"e17a73b4a8adde24e2f37d9ea5a8a73166051dd043f56785a3da609e7c0c7d2b","impliedFormat":1},{"version":"b56e0fd06973cdbdc852d763a26b6f0c3c2a9c542aa6f7afd718d6501a8f9b2d","impliedFormat":1},{"version":"f80f0d17539bbe3af7d2a7fdadd1fb4a62e6f675cfb432a5e94da83d3ce55a7b","impliedFormat":1},{"version":"c6970064a81cc822ea3cb93086c979d54fbe0e6a0a2300e43f20af57687e00fe","impliedFormat":1},{"version":"557912327e14caab47cec45262c86e8ef5af5123c28f2489d24dd1a58ede4fcd","impliedFormat":1},{"version":"ffe90a3d808414444c1797099a9e2ad13f7f61dc5cae7abab51af7d2a6948c10","impliedFormat":1},{"version":"cf38f1af976bbe510b95aa64f2705ab5835b51fbdd2df269a5b48282ba0b6b99","impliedFormat":1},{"version":"4fe78ee188b939ec988ba6d249e7c5158f4e06889db9b5a85986235bc8e56ade","impliedFormat":1},{"version":"da3b47e1c8571994f45a9fae794e4df81984dd25fde1b1b6bee9781efc22e579","impliedFormat":1},{"version":"244986f1386941c23b28ab833320210875a75f84fbee6e170af1704e66d7bbe5","impliedFormat":1},{"version":"37ee394831aaac3a74663df95a526160d7c7fbfd0db2a23191debb271ca1ab74","impliedFormat":1},{"version":"f366bdc349d71e56ad8cb337a086884eeb2f0342d12c223671774d157341648a","impliedFormat":1},{"version":"94212fed9d200d59cf1e2f47eead06570a6ca19766faceaa3606c9556b1ba77c","impliedFormat":1},{"version":"ade336d7147dcbacd1a9e1dba5fa7db2b2475bda895d916d1c4ba8358d3cae18","impliedFormat":1},{"version":"d24bfcf987bae2aae4d1da32547275f7155ee315cc8cdb7ac7372e43aafebbe2","impliedFormat":1},{"version":"286bbed457f0a00e517ee762c84a777b312ab90e90d4ce8560c77b4aaea2408a","impliedFormat":1},{"version":"6c774248a39ed7603bd6d78bdbb99df4073ba49a99b5c4e5807e8ce0f8ee54db","impliedFormat":1},{"version":"fc4e70d99123af7f7728bd17e16d3b6a7deb354bda23a3139fd253888a9e3488","impliedFormat":1},{"version":"18a9f08ba564215b71132e233f091ce19aa9f2085418bcbbba8e030b3e2f1d0a","impliedFormat":1},{"version":"dd1a69d7fded43f67ed3ecbd26a456658816df57f1891ed925219463ed9dc0fc","impliedFormat":1},{"version":"f98405b9283f18af92db40efc1a4535b1184540acf27155f1659c7324f9a627f","impliedFormat":1},{"version":"08cd2182f2254acf1e67363b458d517f84e52027c04342fb673a419f096c52b9","impliedFormat":1},{"version":"5fa81054806c69c5ad73651e60a89a731bca039cb3c6230acb312cf6143d797a","impliedFormat":1},{"version":"f089a5b0a340bcae527fac55b6b7b7aa91306c26c6e95913595a55b6d129c30a","impliedFormat":1},{"version":"6ed13e23e800e5683df806429be529b8ceb23c5de813394bf47be219704e4eb1","impliedFormat":1},{"version":"8246097375c540e7c7ddeee6367e928d436652eb602d929ad3af612d677227b6","impliedFormat":1},{"version":"ef30da985841d1d9b9d2e0e5a145cdc9f2ac20bc7f8ab6c7083df079c5c4031a","impliedFormat":1},{"version":"d496321eadd07c908f07b0b09ecefbac1a0107750ef4c8b7369f601b86397567","impliedFormat":1},{"version":"6b5f20686879f3e2af76734387e165edcfd0f85dfb9352a26674f679e1e73fce","impliedFormat":1},{"version":"2f2db52bb2117ece9b0ad792a1ac71909f646401aa750d7e89fdcbc1a49fa35b","impliedFormat":1},{"version":"71baa8b5276f5c7a50ab127626d082a097d9760cbbbc761de97928a576185317","impliedFormat":1},{"version":"6f9753ad8d735bb8ed7e79a493259ef440ad609240200daa5fe0e39f6abeb5d7","impliedFormat":1},{"version":"195d8773932dfb77961e7e3c7c460f39c456c2f6fb0889db01ded8f59272f1af","impliedFormat":1},{"version":"f073516f37efef8f162c336c111d236cb2c4b3630283457a1473afe7a37f428a","impliedFormat":1},{"version":"c3355c4b1fd179013174e0a76b8457f55ea961d6f77b20c216c07472182d5265","impliedFormat":1},{"version":"6231e578c9ead853e7990e0d1740c526fde90bfe1fd96871fe0d6f1c561da46a","impliedFormat":1},{"version":"6fabbcd5c878957606726ebe2153aaa0c3c57c643d8a6e7676b398bda14d7451","impliedFormat":1},{"version":"f37e86a6bcc56c0c83989293ab28338127504a4bd879e5bdb1c4abb9abdccc92","impliedFormat":1},{"version":"0f21a731fac54f7ee72d8d30c0d134a93e4695f16013fc5891ff93a2444135be","impliedFormat":1},{"version":"806fa3f57fdaccdf8a7df38bbf3d67b6153567b9717d44c5cb41c30f89b5c537","impliedFormat":1},{"version":"68efd5d3dd0a229bb66ded706a89a34d3afa79ca438161b4df6927a9d1836f70","impliedFormat":1},{"version":"25e1b6f0b8d648b25bcca8450741c25f518e0ac4ff859855ad505259437cabca","impliedFormat":1},{"version":"ba88fd3338403d9128f2c8ac87acccfc13985e05489365b6fc54f5aa1d69663a","impliedFormat":1},{"version":"bcb2c0c7aa7597dd74ee87a247374ea7b9cc7dbcae02598af368b8478c0e9e87","impliedFormat":1},{"version":"da3249731a7fd121d6b07ab4c36e0fbd237f9d1cbfed31e7a63b6696f06b03b4","impliedFormat":1},{"version":"8c899a1d841c2238b1e6b3797f1a4225b3b3a8157e2b10b9c96bb71b6dab6791","impliedFormat":1},{"version":"4dd1abd66a002e86e3156d0c55ae13c0ce62024c4d43599b32c88400a1a531dd","impliedFormat":1},{"version":"aa093f3b38e0b68c1ba5f12eba0e47667caeea62fe69051508d783d848be6423","impliedFormat":1},{"version":"891d8e7357aa45715c3c44a83f631bb1a94ddf094d931f37c07278556a92d62b","impliedFormat":1},{"version":"76cdadda90099ed4ac292c9aa237bd195484b296f9b8d55ea0a874c74411ee74","impliedFormat":1},{"version":"990cd82033ff881c5dfe552e8abdfa1fd6f1975836b1985657975d6f9c9bb1ea","impliedFormat":1},{"version":"d2c1d35842d0b9acf9bce9097bab7c3bd858671bc001340ad6170855165c0604","impliedFormat":1},{"version":"da1d352119877e52e18efffe4dd3a30ca6d8827075480a6e761222212a797131","impliedFormat":1},{"version":"a182a2e4a840655ed78d0471195533acef6c3a0f1bf92b4fa199718d5786c826","impliedFormat":1},{"version":"b90ccea421718a666be31e7e6301f9a2c29b09e1a8f76c2b84e79732c188c5b7","impliedFormat":1},{"version":"4c6ca54e9219165627de4e4db3a53eaf091439b2a1fb0671a788ff2d91e73bfb","impliedFormat":1},{"version":"2a3337cd788f49109b5491eaadfd805cfee4fcff70f422619c3124240a47358e","impliedFormat":1},{"version":"da5eaa2b4545f8fa3df249d163bced954bd93bfd57dc3d7473a2de2719fa4758","impliedFormat":1},{"version":"90dbe4fbb5f975598c97bf4522cde1a9a06d34aa91cc8882bcbdca8b46a15b3c","impliedFormat":1},{"version":"fcd81175c613f6c68c413df8e11f879fb80c4f2be09cc50be9166215b0358391","impliedFormat":1},{"version":"56342e40351e8415ef160b728b1a59cae5c3abc104748a576063ea05cfd12203","impliedFormat":1},{"version":"a565163b5195664f1838ed4ab1c8f4ec00092805391e9d359ee7a0131c7d4a06","impliedFormat":1},{"version":"372a328cc1c2c6b72f496632c7d70e2c843b377958061b15e1e6ea06de63c5fe","impliedFormat":1},{"version":"c84d7d6083d907aab88028eea67b0abf2e0de2121f69845172d29152af6c2ece","impliedFormat":1},{"version":"48a9df3be0284da4db5930bfb52cae8d5857ca74b3bee99b5c169b2d2e4e810a","impliedFormat":1},{"version":"2ddbc3aceab6095e8db3522d79bb80cc1a4426dfd4eb9ff10a6a79d9b8385892","impliedFormat":1},{"version":"a2cb82a5c43b0da768fdf28fa84097aeea6b75748498fbbcfa3f0cf2e4d443c7","impliedFormat":1},{"version":"0b9c1945e78e0ad861c174b95c19edb3cf469ab9d7846580c787737a87c2802a","impliedFormat":1},{"version":"212a84c6a5b24f9a4c2fb11295ce88c691fe3153fd7c4c687401c364263feea4","impliedFormat":1},{"version":"7ea0bb0671106abafbedc57469e089f0e8b4df3f9b4e6a37afb500d50672eaa1","impliedFormat":1},{"version":"db741b3842c4128580b111de317c9549125a857ca33383d843e7bce8c1fb4cd6","impliedFormat":1},{"version":"005430ae37410a063be39ddbf96f5e69643efe48ba9c5aa8593f5def9049c150","impliedFormat":1},{"version":"5bda855ad7b0b1b77110c52f1465b9f75eeb990ef63961e39896a9226b22d6e9","impliedFormat":1},{"version":"9ebefb4e5da6d69e276d5da285e8974c2e35f507083123f40367c750bfa23de7","impliedFormat":1},{"version":"f0595370d361e260674b7da88d5c9ed2d36340c4e60032ccac3ee26fc2600789","impliedFormat":1},{"version":"36e3ca76e7c6a2612b8a52d8ff49959a61b8a64a735e507c3e360526d4a45c3b","impliedFormat":1},{"version":"ba056a236b0b8300536cf0105ccb81602d4f3912c86b1e62097ea739b6b54b1f","impliedFormat":1},{"version":"2c31bb5176b6d6e1e345042c43246fb759aea3cf2ef0059b7e20d7b52b020818","impliedFormat":1},{"version":"c9aad0bd92ad792b734d13dd1665b9a5ea6c6c47f324f9dec643bac8f439bd2e","impliedFormat":1},{"version":"eef4859cc6e74ca4c2e8c893adae997032d666c6bb0bc97915feb6769efd705b","impliedFormat":1},{"version":"f3579c867029086ed11121462e06c7635eb5031c2b52a0916f00f308d6d7af3c","impliedFormat":1},{"version":"24cf22d13f05e6a15af879c9e8794405e066950ae5e73822225aad0ec913bac1","impliedFormat":1},{"version":"34b7200ed0f9d066cb8869487d3d50cf1661f9df573756f61dc366fa43a0f550","impliedFormat":1},{"version":"bf38beef171db95f10efda9cdf99b4d4a63c073667fc5c1d6d83e9be31cab06c","impliedFormat":1},{"version":"830fe3c56fcacfa5f4c63f175a4f0a6f49cd79996f18da0523f223e559f0fae0","impliedFormat":1},{"version":"b841bb8e4fc8ebaedcd08f992e47ecabb4d63d3b0b5f861640fd2aecf7ac2c48","impliedFormat":1},{"version":"68e403a368de3c8c436b2205af3feef8a7565742dc58f998675814bffe0d9ced","impliedFormat":1},{"version":"99a4322a9c9327da3d1e3671301075d209c77163f2a2704c91250e60f8dbe4d8","impliedFormat":1},{"version":"22bd96f4e254cfb66442baf9789b34c462966c28649e04588c1a8775f95440c6","impliedFormat":1},{"version":"7d73cb9623f2a42637da372607189c5aabb731d7117de2f6698c657fae0a82d3","impliedFormat":1},{"version":"12044046e6300551b49195bbedc444bdf2e156a1ac649a2e2d7fc0611ab05c42","impliedFormat":1},{"version":"40a55d1e2b36312ff179302307cb087ab19671f6fbb674d587726ea455f98fc2","impliedFormat":1},{"version":"5a050d0d711a551d6fdcb0736d1604ea17309588bc7d548dd7325819a09ef265","impliedFormat":1},{"version":"041da17f93536a433733eff5f72d9550069649e51c250e252a633de006d635a9","impliedFormat":1},{"version":"27f7559b848c3b0eea2fafc0bf1fcab2ef8f8f72ff383eafc2656bce7e92bf17","impliedFormat":1},{"version":"5d0641bee91d1160b6cf126ea9b1bec12a66c5fb4e3a236c954e66e3b73daec9","impliedFormat":1},{"version":"13f359089698435483be919d334a3b98c55d9b47d65fbe7360fbfdbc67cf0c1d","impliedFormat":1},{"version":"30dc6de37afdc9bfccdec356abb22f5dbc95eaa0d7e807e7a0b0a32af7fe7916","impliedFormat":1},{"version":"b97fc0ea9e73c52bcd63a1f762b599e9aef7351113456526e99edb9e2bfb8ed5","impliedFormat":1},{"version":"e94447f90b58812f15e5078c8e70f736e268fae0c95a07c6f39ddfb255457709","impliedFormat":1},{"version":"a6f6fd62dc22393044a5ffd26eab6ee0cdba21c6f861f55e0a53c9880415db52","impliedFormat":1},{"version":"dd1e32d49dba65f0f2d5c97f23920c337cb38ee6d9fafde8d721b799b9f68490","impliedFormat":1},{"version":"3de25e47a95b8a84b6661bb60808867204b473a70a1a689ad459986ff9e9720d","impliedFormat":1},{"version":"5692fd935516050b482d2cd59578572e3ba7202aea1a86e44387b16fdf2a797a","impliedFormat":1},{"version":"bc51dea911a4eb4af53c7882f957ad454ca1981806d19408d0f3824e5934d28f","impliedFormat":1},{"version":"4bb79bd0337fd7d5f5e34418a37aa71aa0faaa5677abc445a1100871f3cee8f0","impliedFormat":1},{"version":"3cdeeb669285d49dac7b5c1fd5b3e8d95f795796f596c6291937db5d7d44f2d1","impliedFormat":1},{"version":"8083f8bdb3a8b8f6f727ef49ed6ab9dd76edc0134c5aa6e26399edd6313aef1f","impliedFormat":1},{"version":"f7fa3f64ba2d2508bac42cad26775a3a108ef88e7444b1495aa102d7eb54a41d","impliedFormat":1},{"version":"cb6522fe6e5b65ba6e12bd158147f826268ad98389c45d5b2192e8ddb6926a0d","impliedFormat":1},{"version":"b0210a51262b6e92d46aea44871c0ff25e6c1ae25ccb98c35408d4c82b909565","impliedFormat":1},{"version":"1dd1173cf650c56d7e3679703af3dfc8a183c5af93f342c59b9fa746cab9118d","impliedFormat":1},{"version":"746f37408fd8ea632674076ed4094520e1719afd7aa99d5b4d85c5e96bef15fe","impliedFormat":1},{"version":"f910a3ee9034efb08fbed0914195ebb540f674e481885340d0c5c2ec9eb6d7a4","impliedFormat":1},{"version":"d2d71f88a49eec8fe7ac10ddbb731a5ca6264c90c9fd3f3cae07dd27c181827a","impliedFormat":1},{"version":"6ac932af484a0b1529eb1fc3cd0f568fe3f7a94c949d987842092918c61c306f","impliedFormat":1},{"version":"86f3fb5e8763b06d42c4dfd77280de4949017eade1d65a9403468045e2413176","impliedFormat":1},{"version":"622cc50c7aa77abe53556bb7123250c45203558110265b709cd6fb331372a4c1","impliedFormat":1},{"version":"54958c1621c0420965ab3011cc3eead3a5c7977a629cb5fe9cccc91f4a31b48d","impliedFormat":1},{"version":"18fcabe65d4c81c06fd15e49353a9662601f2863aecbaba305f8ad801c311f9d","impliedFormat":1},{"version":"39acc6a0652b9907237cd6bcf2f2787c4c0967936fabaea913c6f2254862aaeb","impliedFormat":1},{"version":"88bc8fbe6e3b0ec263aba5d236eb3840921f1723e858b23211e14eb16ccbf572","impliedFormat":1},{"version":"cd234fc04397a3cb20780199591839da3e94cfbef798a49eb420f6f337a300c0","impliedFormat":1},{"version":"1f471d7023d9f5803df94ce454e572026513f45232b0179245804b35fcf5ad36","impliedFormat":1},{"version":"6fd1d183ffba50d64abb08ec5c0c35d0c2b2971af45e978ffc4c9ac10acf0ade","impliedFormat":1},{"version":"62c63acda9e8b912644774060a2e45b5289976479c3f371333d63b62ccd71067","impliedFormat":1},{"version":"d65d60870245f85155b27995ddf9ec3750d0035d57300b5682d629aa30cd296f","impliedFormat":1},{"version":"1b6b253fe74ee94f03c0d30853c04fb9e843bc388c339975940fc396497e6105","impliedFormat":1},{"version":"b4e6fcbff87541828238ec196f2512bf760d1b64140b70bf8f6eea95bab62679","impliedFormat":1},{"version":"5d1431765bafece3a000d21da900619d6b471920f7951be8989ef39bed0907d3","impliedFormat":1},{"version":"3446d03b23ba04a16ed59fe990ba9a152debb6a5872fbf2aa6dd9303dcd292a9","impliedFormat":1},{"version":"e1dabd723091a33a2cea821007e96b59b255ca5d10d902bfade94de7bfdc0bc1","impliedFormat":1},{"version":"122bbf7dff210cedaad0ce91a9af0888055e96ba861cf105681803b14c76c8cb","impliedFormat":1},{"version":"c753bcc855b249119b110d1f6caa69fadd48cda8778ca8d7f72ca2ff28d19162","impliedFormat":1},{"version":"d19b3b3289ce004b97417d621b7a1baea1152ea92f2a281926202f52db47635c","impliedFormat":1},{"version":"cea5db9e3b3cdd0401d888d43db601f19d8817d448f750e2af78f8d5fcaba9ec","impliedFormat":1},{"version":"04f5e6dd2358f87674dd28ab85ef2efbcc8033b118a9c6105a8c895c78eaf710","impliedFormat":1},{"version":"e2162f26e466fa593637b72d7c70d40f704d1e4b2a127ee4d6c91b8b5e356802","impliedFormat":1},{"version":"f4e582ee5d0abca81b3c93873091abd6cc772facf61707f05a9c53c1288551af","impliedFormat":1},{"version":"c39f31d9a4c609ec59156faf1f9bdf65c8750d2efffa3eec256415a92781f144","impliedFormat":1},{"version":"7eb1afaefe1f2f6a0020daf70ae064b13c5ba0d53d011785613a62a3c6ba5959","impliedFormat":1},{"version":"bbef3c9533c0d21ecc3f3a1fc6bb38979abebffb9592e9d78d20ac81e67ac844","impliedFormat":1},{"version":"8685919169b4320224ed02130a1489cbde4afa783093248ddb23a79c7b1134ab","impliedFormat":1},{"version":"51a48bace2adce70e461a01dcc6eb11864c448c32c271bbcd69579902614b3f7","impliedFormat":1},{"version":"291f63d61c323204e9a218fc7e225a1104357f659a9f8957cc55bcc0d24c7833","impliedFormat":1},{"version":"9d4573f75054b08463c761fbe6bd962cbe8cbaeace51401fc3a95f73233a0487","impliedFormat":1},{"version":"f0e2e5d41a5cf5dd31f2aada980e492dc870967dd1f77732948e199ef25f1a68","impliedFormat":1},{"version":"fac3e682a21939bf0e44b230601f0ec910de904a464f34c7881041e60647c551","impliedFormat":1},{"version":"0a5a49f2d4a39e30eb990d83587dc5d6c15b4fe0a17dc0efedb53b7db78172da","impliedFormat":1},{"version":"951f88df4bad93d8b78040a7fe4a379130200601c0dbbcfd7b24c647af32a9bb","impliedFormat":1},{"version":"cacf2dcf4477e1ef1f52396f019520b574d80a4a6537610310fc97cd555b77d4","impliedFormat":1},{"version":"12090ff48a9d5118c9de0d0c0218797110491322c7180ba2cae887360b371af1","impliedFormat":1},{"version":"76da24e26e9c3658464f161c4c39a3237cb056a7eacafb55863d602399a2f30e","impliedFormat":1},{"version":"6421f162de737f2692bcded0353cd3587a41e2d2caaf48b0824dcaf98b148064","impliedFormat":1},{"version":"2a769cea819af9990b557a8ac2d4e9fea192020445513fb9dc95b3032fcd5ea5","impliedFormat":1},{"version":"3a37809c5ccec5930efa96fefad37374aa5d1d15ec590ffc51580caaf08c1ff1","impliedFormat":1},{"version":"e7797c996404939a4ff5413a8cb50cc101c17a35e560ddc5f621ab16b529a9f2","impliedFormat":1},{"version":"43f6a460d5252cc630df50e4e129d913d67f3a29182970f57ebd75c8f845508e","impliedFormat":1},{"version":"31960b9e127bbdff1b916daadce7dbf8d7c569be2dfe092fef5f7f728b384336","impliedFormat":1},{"version":"7f1392985c2ea47475f0d16cf2b4e8f579bacbe662f68936d6b3c339c2c6d2f8","impliedFormat":1},{"version":"b850dfd753988644e89199342560ebbfe59766be5ec63d947aec1658f1dcee1e","impliedFormat":1},{"version":"43b9baa359fb0704d1f302d6b6160d962379ec9446e3ae9a146dea11e3d69606","impliedFormat":1},{"version":"6ad6d126967a6beb8ae6b58e56339c70ef6ed83d034de403928d2876ebf07b0e","impliedFormat":1},{"version":"7093516dbf4d458c1b10743fbe23d36d321d582b0a06dd0eeaafbec63bde1c5b","impliedFormat":1},{"version":"c28722b43216325956e5f4d93a4605dfbff8a1f79777c846d2ea11d754af7ce7","impliedFormat":1},{"version":"723ba6d7404b6f2b9d497143494b524cad1cbf141e5b982e353f57b9024b4b52","impliedFormat":1},{"version":"f06cdff167bda31dc2ff9ef830350ce7cdad6a68031de6f6391064b1644fe853","impliedFormat":1},{"version":"cf2d351a170d69215650765a9e2684feda2adbbc71b788c0cffef9c3e2256a1d","impliedFormat":1},{"version":"8d6455f685e133eabb5ee511bdb5a96d811e4e0df68972ca43a79ff5dc7f2f1a","impliedFormat":1},{"version":"3c5faf2f69961755a6c8f8ea38e9f057f27b55ba80100887c038f247674a6345","impliedFormat":1},{"version":"08a3321f94dd4cbe109240bdfb505399348a117a83db03fbe0ea36a7ba21521e","impliedFormat":1},{"version":"b93bbc73c2058542b35f47c01c67636f60859f6debb94e58b55a1a19031c39e7","impliedFormat":1},{"version":"a69caf122916f7c02724b4606b078eb41a335283231968f2409dc82781029026","impliedFormat":1},{"version":"a418c802b8ea2fd1e8825299a210b57f7d49f76db0202bf79820c42e05f434e6","impliedFormat":1},{"version":"c578207e594b6aa08a42f6f2bc1daef1ca5a5f9e6c990f9583146d1b50c7b81a","impliedFormat":1},{"version":"01465b8701bd80812c0e66007fa97d60991876cbdcae8df4c7b3c528a01ec0f9","impliedFormat":1},{"version":"a69a4f75f16a3586e7aa690819f6686c804b78fbbaa57285b1c5eff435a4459e","impliedFormat":1},{"version":"63aafd08cd9363f7355f6bc0cfd450810b907ecf01d27ea1683d8aad17175165","impliedFormat":1},{"version":"8413895ac4fb4d19fca5a54a97ee1a7852d743101e01fa6f508803446cc5f7ec","impliedFormat":1},{"version":"9287252aa6f61cc8f505ba643da628025f7aa033499a6469307f88bfc78efafd","impliedFormat":1},{"version":"be611693e939b6bef7a956ac4a714ca3a7bfe1e6baa5f1d334c174e657d06a9d","impliedFormat":1},{"version":"5b4c10e516cc21ad4e289d79df9a493552d7c2e8428e8163258a5ca3bc4d5804","impliedFormat":1},{"version":"14dfc69cf147d8032fbd69fa10d0f02502e3d8278a890cf16bbe34bcac6915f3","impliedFormat":1},{"version":"880576ad1af984a61167a4aad368f0abae75a7428dd629cb2270520bdab764fb","impliedFormat":1},{"version":"a87b08c47938fa134a67b8ff34f4806d1fa3492e1fe5f0ef5f5da6f5b22fe2c8","impliedFormat":1},{"version":"f57f9debc83a1c3f560b647a3193261115d9a5764234b6fd4d0c819e4eef50e6","impliedFormat":1},{"version":"e1d3d914c3dfbdcf65ae0251377decdaf1d334bdc6394c5648f1ec442adae48f","impliedFormat":1},{"version":"7f9268f354ea8c48a6804c9d881b0266791c81af2561ee0d4d4b1e8fdde53344","impliedFormat":1},{"version":"3254d5ecfbae8f9715f6962471a3f11aaac41b0dbb211788c293512a4cb53083","impliedFormat":1},{"version":"8100186d312049f4378c4b79958f7950dc02e5b7ebac6c897302a6e5e7976700","impliedFormat":1},{"version":"e909ac22ea14b0742bd0061cd256c4e499400523091d3393c9a173e7137a6095","impliedFormat":1},{"version":"caac3e567c787501377445963ee53d79dd7ac3a35ceef24c65c085195b9fedf5","impliedFormat":1},{"version":"b0fd8ad93b545e8f032f950a214d3c4fd5186252d0e5f62b6ce23e2b645f27c7","impliedFormat":1},{"version":"3270171aa3655d7e7cc321312f2a7362e2e768b72d9243780734dd75bce6a244","impliedFormat":1},{"version":"f8ae2848bda55826a669ae353819ac8a528704982cdf30d1e33f594cfa004083","impliedFormat":1},{"version":"e2d77af103d0039a9a8d171ae6934a0fe1de89f96d9d8fc0c8914425b7abad44","impliedFormat":1},{"version":"5c241d5391c5bdc611321ce0dc3b02e2fdbe9d492cc0286afa28209d0a486581","impliedFormat":1},{"version":"64cdca7e66a404ee6153031855b6e8d6999481597b1fb2d326f17b5ea18b233e","impliedFormat":1},{"version":"b7bbc5acc0a605ff01fcf6d4bb2d81d1226419734cc59e9885bff9e7a87001d2","impliedFormat":1},{"version":"a92c0aa09d9a53d75ef0d11c1cac0a5a7ec8bb6af0f775a2b473eb45a6d68555","impliedFormat":1},{"version":"7434d97845faefc5ce872e92485748544a1532b2965725402cc35ccbef1438b1","impliedFormat":1},{"version":"dbd400593eae8c2b8ebf1676b6642dc23126e2e8cfa1acd340d800583cf0477e","impliedFormat":1},{"version":"138fdbc9ab6f6289278a465794d1c7185ba94952d7e912c2e9df9f7c5fda6c96","impliedFormat":1},{"version":"5dd7481267da117174ca4ba103cd5764e8220d29122745726b92f8b59c591190","impliedFormat":1},{"version":"8407621ce6af001fbd022887f5e5cec9760fd3903c898119b449ea9dfac9a4da","impliedFormat":1},{"version":"0f57a8417172ccb940ffe7dd1401099a80577973f435474ac0324c7bc12cc0a8","impliedFormat":1},{"version":"d1af15419c62a51d5845308cdeb75391da607a18f787e228161c345ac93f3051","impliedFormat":1},{"version":"f1d19629fd1f1a0ac4d1331346cd4e89e4e69652ce09e20932608dbd17837ba4","impliedFormat":1},{"version":"363bc8f4f5b703ed37c5050fb9afc31986a0dfc051bb139e5528c92b8089d512","impliedFormat":1},{"version":"8ee7d4b3bdb1976f2a81f8a5dbeeda747ce6a25d55d22ca23e9946aa41df86bb","impliedFormat":1},{"version":"d4f12106d684952e7f2a380d807851ff7eab085bc022668aa5ee75baa1edfd99","impliedFormat":1},{"version":"62d21da4df5cc1681cd48bc8326e3cbc34b19905e0a0b1bfc931cdbf87a2ba7c","impliedFormat":1},{"version":"436fe00034ddf6eeefc8957e465d7ed169a825b0d17c641b465ef9276c38b274","impliedFormat":1},{"version":"3fd65231d75afbd854e27ded6df8989ce37a54128536aa24205cd82b3969a1c2","impliedFormat":1},{"version":"6fdbc7acffd6e8b25b585ed0fde2aac4d40973c16c47c9fb6c973baae3534c0f","impliedFormat":1},{"version":"a1b290bdb1b13407c24a4a544e18e6a0640da4636a6a1091045bda8415c85adb","impliedFormat":1},{"version":"ffb45c5b7425e845827717da910e9652714a19dcb22319db270089aff02f8cf2","impliedFormat":1},{"version":"3b051a748f2ccf77c9d8c58c964de677bc33c5c47be980412b6ed870b6087371","impliedFormat":1},{"version":"d346879201df635ba44eeb3bc2aa1c7a95cb77fd7719249430b33e91bbd8937e","impliedFormat":1},{"version":"02a87db2b3f647f44a7af7c11bbbc1022ab5193b6ed3fe105ebceea8b095053a","impliedFormat":1},{"version":"70f49e2bb0bd5f32a96e2bd58429e33823ad2a929bbbd048c5b5cdb115e4246b","impliedFormat":1},{"version":"e53cbf76bae6d7ded48032620e4a31df7ab3a63f480a8337beb985d07c0ef733","impliedFormat":1},{"version":"194ba3b10431ff063d8dbbdad309c1b0df101bd422de09bfb7d700ea0492a619","impliedFormat":1},{"version":"8e567ecd7f2ecd9ac7a225515bdb269ea85ce7ce48157455f056c6e6175b2052","impliedFormat":1},"a13b9595c54ddaed08800360f5f2fdc718fc8831d13fef5f82ea5f4877d83b09","053730e27f3883effdf63bc82bb9117772c2f1a68e63603e1ea41ae6687983de","2b20d4c21a994245f5d4d75d9b2859b1ee92409f619cc419b1a9aa9567bb1f74","831e1a4d35d551cb77c7dbcc92f07f709ead0428b3212123657e1c5dd313760f","90742b6e9716b0a0bebfbe0fea95c8db4ffc7b0143a74e55a6a6a38c25629712",{"version":"332680a9475bd631519399f9796c59502aa499aa6f6771734eec82fa40c6d654","impliedFormat":1},{"version":"e269c531fbbfe9f97dfe0e73b8b7ff1301ad3b9f9fdad63e9df8a96e24365df1","impliedFormat":1},{"version":"d83f3c0362467589b3a65d3a83088c068099c665a39061bf9b477f16708fa0f9","impliedFormat":1},{"version":"da83cf072f354357f28fd842998b7ca345e744fd24d1023851a0eacf9485ac4a","impliedFormat":1},{"version":"29994a97447d10d003957bcc0c9355c272d8cf0f97143eb1ade331676e860945","impliedFormat":1},{"version":"f4260022f7af38e533d364ea62eb7ae01b0a32050033d7f6772073e1dc908025","impliedFormat":1},{"version":"9cddf06f2bc6753a8628670a737754b5c7e93e2cfe982a300a0b43cf98a7d032","impliedFormat":1},{"version":"3f8e68bd94e82fe4362553aa03030fcf94c381716ce3599d242535b0d9953e49","impliedFormat":1},{"version":"63e628515ec7017458620e1624c594c9bd76382f606890c8eebf2532bcab3b7c","impliedFormat":1},{"version":"355d5e2ba58012bc059e347a70aa8b72d18d82f0c3491e9660adaf852648f032","impliedFormat":1},{"version":"311cc121259b3e0c3c08304fc25b525aa02ba0f9bf55b3e7c60b0dbb7422014e","impliedFormat":1},{"version":"74c269b43d39e5ece20b2cca49c14e64c05b01e46407200d7558301d0fcaabf4","impliedFormat":1},{"version":"cde21e822ae5de7b130f6db6b2fce8435e23e33a00a9d62fae06b3982ef38a39","impliedFormat":1},{"version":"482d0ac70d56aa79941be30da6df28e926a007f835eed70cf7b5f3135368d1f6","impliedFormat":1},{"version":"f0715a6654ab21cf89f1c2544b1afc704b60c2ff687b29ee8727ab01e05e8211","impliedFormat":1},{"version":"84cbf6204ada0ee2f80493e55e45befa079954788718efd6dcc103183104e3c0","impliedFormat":1},{"version":"ed849d616865076f44a41c87f27698f7cdf230290c44bafc71d7c2bc6919b202","impliedFormat":1},{"version":"9a0a0af04065ddfecc29d2b090659fce57f46f64c7a04a9ba63835ef2b2d0efa","impliedFormat":1},{"version":"10297d22a9209a718b9883a384db19249b206a0897e95f2b9afeed3144601cb0","impliedFormat":1},{"version":"6bab5c65a7a5bf20eebac39b4a84259351914c2458af04d11819319e01f0aa10","impliedFormat":1},{"version":"84828aa498631f28c5d8d6f53aaa6614ebceec9742f6a31ef1a77452ab8f3890","impliedFormat":1},{"version":"34d206f6ba993e601dade2791944bdf742ab0f7a8caccc661106c87438f4f904","impliedFormat":1},{"version":"f92729b267ea7acf1984487c16c9cf8ae32ec3bc7fbe261d19bce7aad1c7ba1b","impliedFormat":1},"f660790dca2b8351bbf619e036a4d24aae1a285902e9d336b2af70d180eee69d","ccf119b5a9f0bb7b0007ba105c5bc87295578ef5d343eeab6bc8997c30e74201","736a61155534a15659073a8cfd884f273afbba263f0377ad79f5467afb889a03","b05b7d205f0a289b1db921af0bf6a4a27f683e6efe671ec18122016cbc70bfed",{"version":"529e8d544daef015d9b7e08f3327f487ff5c1fdc9ae00969b90fe6d7f662c410","impliedFormat":99},{"version":"32d72e24ec52676fbd422d6109ba2e7326f8cb0ae09d62433609994d772b1218","impliedFormat":99},{"version":"e94825a54ccc0d3ee220d8194d3871735a633bc9840af4c228b90572ec8f9bca","impliedFormat":99},{"version":"ed5ac3ea851a0e455e615a7c926d3cda913d4171337486950069b9c2fb6db907","impliedFormat":99},{"version":"97c9b25718cea0d37894c5dd9f7e7fff4f8bcbc56ca3bba011c074560be291f1","impliedFormat":99},{"version":"abfdbcd2e417125d1b38209aa079bfec08b42611feedaebf29be8676e74c43cc","impliedFormat":99},{"version":"6d7a5d9f2190bd6d5086a130b3ef5231d7bc8a3d923133628544b265611a3afc","impliedFormat":99},{"version":"f8857d69e6717a043169ded98ca4c7a40432abfc0f768a7d442d7374700dfe50","impliedFormat":99},{"version":"7debb6b27ee0e7383618739a56fd13d9332d58a97eb1001f57ec2d4c1f133536","impliedFormat":99},{"version":"828968bfd8325c1e6b427043673be3aee122dd5125ea5ff3adcdb56cb62ac202","impliedFormat":99},{"version":"29862235bb48e3e8892a5e95aa464810a6c0282ca549f4c0f65cc2329c4ed90a","impliedFormat":99},{"version":"f865992ea8a69f28d58dd1c276d5721df7fd32acb1baac46ee9f2ab1b4ac7148","impliedFormat":99},{"version":"3ec9cc0d5ff3509a3800802248b56f72d0bd4ddbbf4ced7238ced162f6792bf9","impliedFormat":99},{"version":"b09e328891c9b6c1e363a0dabc2b7e9bbab7ce95f4c1a42e3ebc1cb957aebe2e","impliedFormat":99},{"version":"9989a9063fc9c82bc1c1d1fc3363b90a2e9874f625d044dcc2f726b4ac0eff74","impliedFormat":99},{"version":"a861ffb4131dc6c01a9918b0c2d9eb907963a363019c8cf8441c195cc7271eb3","impliedFormat":99},{"version":"7dbfd2dc59802603b4d9d9cd35bfa777da1cd030ffc78f618701772d70c44d7a","impliedFormat":99},{"version":"5c62f873da6df6521abedd307fc544d6736d04604ae168233a63e4ee38ddce51","impliedFormat":99},{"version":"441d1761b0cdea56381964395929a7dc78cc8294f07550a4a7cbd7a471982d49","impliedFormat":99},{"version":"0a5ea01b61f08bb7fe4aee10e148a43bd63cd09c0e48c80c81853a31c63e81f1","impliedFormat":99},{"version":"0765436722d07c50dd64a72cb2ca2b828ae4d8b6c58cce1c7d69b16ed69b911f","impliedFormat":99},{"version":"a99b58cde0c933aafa9a6d539796dd39a2b6faa5868b9329611b7820e4813ed2","impliedFormat":99},{"version":"b70468dd5cce06b4500b9c744b46645bb0810bbb3f16d6f6d8a6ba099d3e3db3","impliedFormat":99},{"version":"fcad406a5312d678f0e3d9ce37e175fc3108075dda7507b33de434d815db8c3a","impliedFormat":99},{"version":"637470d7618d80acc44ce21720e911b1956fb8f35fcd7c29fca8b676569257fd","impliedFormat":99},{"version":"bbc35778ba8327cc2595d22a0492b38a4f5a23c156fe83a4f6c16e16d771a80d","impliedFormat":99},{"version":"1bf505b116e5c3adb7a621d3177726ec218b39b6fbb343a5ca9131bb4c4e4a2e","impliedFormat":99},{"version":"0d40d64f4e5b821a820ca61cd3338fed6feaea4734081098ab99bf8b22b7a558","impliedFormat":99},{"version":"f8f793150b733a84ba31dc32b764f914c2b9f7ba3da22392c8700729556311de","impliedFormat":99},{"version":"45a86d3d3cb4c51d3ef64d2e0f5551ed913ab36f5a522a1e683859b963b20864","impliedFormat":99},{"version":"1e5ac74ec58a751a57547db79f5d0c7f55de7103b3cd608df9b865f1c20e6ec0","impliedFormat":99},{"version":"fa31117b2f9329bcbaa72c5be895a75b74c1a4d8f2c3d2efe5483679e3e21e34","impliedFormat":99},{"version":"b784c2ceea6c1279bff4ab353e5a5c5b358fde3c734fdecf85cc1db5cb44c93d","impliedFormat":99},{"version":"c08fb9233e497eb092616e3081963b6dd70103bba3ff633c072d6d944eae134e","impliedFormat":99},{"version":"22ca8010367254aeee193d066acb7beba74fcb28c8e197bc4a4b4e4a6c3cbd54","impliedFormat":99},{"version":"36623fa5d097e9cfd56c9e12174d4d597f11946e8a1768441aada243dd2c6ad8","impliedFormat":99},{"version":"8dc7ed869ebc983e11a1efd9b696c863b51d6546d225d7b22ae86a892bfb75cb","impliedFormat":99},{"version":"44eac542e0103f7afded458f607f26a7f3c2ddaf8214fb417955e76158f843f9","impliedFormat":99},{"version":"0e5bf871c5afa81fd718a5b276f6a7670846ed459db52fa477267d6b9584e5d8","impliedFormat":99},{"version":"cb816d30908c10eac8d05be80c6f57eddc311deb8fb7e67f712d72445e36562e","impliedFormat":99},{"version":"a4965dec5a8d5a1bd151f788d8e1e2300c4314907adc4b70e205df9bf1de1846","impliedFormat":99},{"version":"757b25663615b67539b212022e464ab8738fe9584798abd2f1dfee3ae2bed28a","impliedFormat":99},{"version":"02978cce808e17ec86ca7f339aaf18665f59122fa99788c07f58f3d0242d7458","impliedFormat":99},{"version":"58e0c95210443e453ee55336f21bb03e770430bd19722041a77a2e86fc73df95","impliedFormat":99},{"version":"3217478b66cbc150f70691f22995b9f47d37706a904299a00cb293f8bed70a5b","impliedFormat":99},{"version":"aba7430768196c0d2dda6ad7660d4bd1ce5abb9394d5ec506fddf897cd055c17","impliedFormat":99},{"version":"ee866da8002c997f01f44fea43acb5289d41b63dbeafab73989ea94bc24284b8","impliedFormat":99},{"version":"bdf8e7a5231d55fb3d4e630c0b278b07a340858bef4bd92aa8688ab17aae26a2","impliedFormat":99},{"version":"4d0d48b4534a83b374888c23427400974ad8e61c7d0e20c8b6e9f1ee1bc7a264","impliedFormat":99},{"version":"c89ecda51758810cde711384913cef5a52a609b120f7ff5b1b158781e8ef4a8c","impliedFormat":99},{"version":"24c42aeeb11009fb88b3dcd9e1f3712794f470b9455f3a0c088582c77c59e1af","impliedFormat":99},{"version":"4771b79f499e7e11ea5fb73b3f0c753e3a581ab3979ff79ef11f557598648ad4","impliedFormat":99},{"version":"686a8e7fccdc6134d9cda4c086dbdbd47c39e6d61283f799fa59926df1fc9cc3","impliedFormat":99},{"version":"b7406c56308e89d5b252d086c59dd576649a90a6df3d6e902898794fb39068a2","impliedFormat":99},{"version":"085eb3daaaa37b9fc38e714066405e6d07c2daf49dd7c1675e51b35c43183b43","impliedFormat":99},{"version":"c41ebe0a43da393b746ae9ff7e614cca4f2429de76f08f5a1d722f49ad1874d4","impliedFormat":99},{"version":"d9fadd424e1e942f0bd948b93b98daf5f64db718fd51a2e63abea12a6b592179","impliedFormat":99},{"version":"485f3bc3d532f74a54b2a8ef285e4c367cbc6e97a41d76a5f2f3e25ee4c30f9c","impliedFormat":99},{"version":"54e9f026eb79d1b19176166ad9a8e087983fcb5deba42b7bde3f869093382693","impliedFormat":99},{"version":"d91e9adbac77e36164dc1ae518de21c45e6250086669a68768752029fb14f8cb","impliedFormat":99},{"version":"816caf3469d8486812807a1eecf3b2bff4fa654abbbf07a97c4f553819ec5106","impliedFormat":99},{"version":"5474a2ddb1d1509609b4d0b6ca5efc3659001a41b499952e9e80dec94b83a324","impliedFormat":99},{"version":"9cbb71f9d9c5ca7817fafee5714930de62d5bd9e935415733dcb41058ffbd95b","impliedFormat":99},{"version":"3240b3195a4a6f07397873c3d3d781d6bdac6daffef7d0e9404df25696b83821","impliedFormat":99},{"version":"8f15effea4aaabc51743128521875aba6e565e414f6d7d3311b8c2d2578e18a4","impliedFormat":99},{"version":"bd03a8a341fd6c86470267cdb4ffad025d1e31e2930c7b1b99cea0ea8ab1104c","impliedFormat":99},{"version":"dd393055b0154d9a66dc722e51fbfa4e147c86d2d0e8e289516eaabdde558057","impliedFormat":99},{"version":"f0c704f2d6e9a1c1af817d64c475e3060a6b61bdfe839b5d2080ea9305f09887","impliedFormat":99},{"version":"ba4471d25a0c25e54f245fbf35359e420fcd148594041a984ed021ac12c515c9","impliedFormat":99},{"version":"7ecccd7c8eb4c52bccfb5e30db1a681e6df544ffdb2e23c565b0e2765fa0c5bc","impliedFormat":99},{"version":"814ff646ef9d7ec28c867d20acdb6ab2ecc2e7620c4f06c8f5412c83e3518e7e","impliedFormat":99},{"version":"361753ee88631c6d574eceef6db3a2b73424517609fb289b37ee2b2f44762a3c","impliedFormat":99},{"version":"79dcfe755d32c5fb77051770d6b4d2b693dee0989d130e6dff14c7f655f97905","impliedFormat":99},{"version":"5f95099d59b083dee76d572422c8024ef6fd0d6c4dea3aaf4bd722385e113efa","impliedFormat":99},{"version":"e220fb4bed90fbfa989802ceeb8750d121f5c16ccb878959c601a54334a4cdbc","impliedFormat":99},{"version":"f673abb24aaa4a63c541eef767d22e443799ddc5ab30a2269d646682a4946394","impliedFormat":99},{"version":"0c1d42ef8bcac5f74e1113e96712f5fded4971c452911263db62d98f9f51cb82","impliedFormat":99},{"version":"b67ec1a98713742f49348d7ca2368e7ba20f5b6395bc96afdb96e99347321366","impliedFormat":99},{"version":"f0ca722c0c74e4ac885706e69e65291f8947ac5e7fae8df529cf70248bcee262","impliedFormat":99},{"version":"a90c4ed5b632a156a7682988502d5bfefc4048ff4c41d0fa505badc0c3892545","impliedFormat":99},{"version":"376eef489231c1d626a6f24d89c1029d907ad7918c0a7191419ee6be69cf90ab","impliedFormat":99},{"version":"84a68486a1e143e34a165bdc64707e74d33118a1c6adde37591223503d4e8870","impliedFormat":99},{"version":"71d6cca9ebf54d9b498f684827c00002b1cead83eb441356d49d4ce1c9759301","impliedFormat":99},{"version":"9d69a63f8f1291547b0cca886f411ee81409a4c4ed11b30f3ca0d62b2c7d011f","impliedFormat":99},{"version":"e56c9d974fc0576b8dc0828175ae02b2586a71662290ecfb7fce0b674e66ab8a","impliedFormat":99},{"version":"cc0af6c56da3ab10ddac0b3c805d652bf0521be6b04f83afb9baa4df1415b313","impliedFormat":99},{"version":"b7aeb363b1649acac16d5b469685e2a067ff4dc8b0b2125bca941dbb6d63e7c0","impliedFormat":99},{"version":"b59a03bf860b1a674b58e831293ce1e2e24ed82d99740aa72e6a11040da9f01c","impliedFormat":99},{"version":"a677ed4d34f7277672e6900be1a0f6d9a58c918ae8a27049b3371828beb8ca47","impliedFormat":99},{"version":"c700c12ca238ac0353519457fba7f7778435d63774ed7dd92877923d7096dde3","impliedFormat":99},{"version":"0192e23340ffd7728fdb1afe9467bd9ff5b9781a7f4db7e887b35ca3530f97f7","impliedFormat":99},{"version":"bc740847a63f5ec6966b84b463b6cf01a991cc12c44bfe0348ea6a81cd19b35b","impliedFormat":99},{"version":"27a2f50f54467594bb1e868224a8797388708742d44b3145fbbc3320a6c8b094","impliedFormat":99},{"version":"56e8d4cd2453b11cb2c618d1b9bbc38b8bcb70eccf7e27e3623a29928dfb1ca1","impliedFormat":99},{"version":"067917a51b18cbea081c237c1c40797c597e8aea855ed9b6916f5a9550ecc002","impliedFormat":99},{"version":"732a8272b91add5d02f8edf9b11a8b415ad2cda5ccba60117cbbe47e9058a6e8","impliedFormat":99},{"version":"5a72a1a08a5a56f38b2ef6a39dd31c59e0e9ba59c7d480dbdec8cac0c3d2c9c5","impliedFormat":99},{"version":"41dc9805e5387625abb6466f9dad47048aab6cfc4a49885a17a65e662ca6d055","impliedFormat":99},{"version":"aa39ccd035dcf30f31ae0cd380e4d9e265c24e4e0914cd2e7862a392d74314b3","impliedFormat":99},{"version":"fde1d645673ad1273c0a347e97528e7830f4877c1fc58966a4a7ff386977aaac","impliedFormat":99},{"version":"aed8029500a40d0b604a1925f0ad677e9b2319a95afbf38168689c5a771389af","impliedFormat":99},{"version":"41931e7f38f9d140b01f98af2234df54cd48e640012fc7ec781e8d49bef24ba5","impliedFormat":99},{"version":"07703ad6a4d604ff6e9c5174012622f7c50e6fe9bb5887cce185a526809f4dad","impliedFormat":99},{"version":"55a07d10fbddbe53638a77ffa085849a50af65edf8eb670a33d5be8b9ee25fd5","impliedFormat":99},{"version":"5d2bd3f265e2d9f1f7dd2d465e64a0c418d0b0bd5673f6dcf5ab5b0709946ae9","impliedFormat":99},{"version":"b9c289167bc15bfbd04b01165d9ba6794ff9c633d72d7da8b990d359ca8d7e2b","impliedFormat":99},{"version":"10259f5668f1fa9f2a97a74015d9afb5dd15cc8c66f5fe49a399fca55c5f1dad","impliedFormat":99},{"version":"feaeadcfe3c44fbf3dd427110db8adf8cefe45dffde44c5ba6a743e15b39a366","impliedFormat":99},{"version":"6944a8f65e43f69e025dd6c9c9c812d34be4544ea9bc7b7c02a5b7ba2f558d84","impliedFormat":99},{"version":"eb2e01c778bf6a3f486afd2d7dcfaf901026934f05a1f3454711689ca48424d8","impliedFormat":99},{"version":"e26d86344fd4cc53836775c5e0674700d69d5015079e8c98f13cebaa944c9315","impliedFormat":99},{"version":"402aa7b07284961beb87aa330ab30f60b3b9d378640a5a451f20555bec349ee0","impliedFormat":99},{"version":"c9725424318766a173194979413b408a807a0a5714cd69e5e51b520bde2c52b8","impliedFormat":99},{"version":"c57697d3e7e7fbb325ceeee238cb5a8876ed8e471f678d280069e164da4c5c1e","impliedFormat":99},{"version":"9764aef246ae9c1f9a5e4993df2ca338fa2c1431fccb4da88c197782e74e2b5e","impliedFormat":99},{"version":"752de46112146307379db6263890bf0a48c47f87a33335fabf53543e246e60d9","impliedFormat":99},{"version":"d9e55de2e36ed1d789753b2890ead19a590406c934bf15f5c7ea43ce6fa78ac6","impliedFormat":99},{"version":"06b7ca3e1c5036f619676330c1f754b1fcab751bbf42edce96bf1819cb6986b4","impliedFormat":99},{"version":"06829e5eed0e849a8252349f72b39b0a64ab0d74e07512c567c2ac7c3fe24bff","impliedFormat":99},{"version":"2ea629a5a83f71f726649dcf0a159a11ae1f552ad7b443b2a0b8fa3340246be2","impliedFormat":99},{"version":"f7eb2e49492915c67a813d1789fed2855319e7e13dd2d55e6efb7aae421abeb9","impliedFormat":99},{"version":"0f2039589483249286cd2e42e8c75e5ecb0bd9ee85ca8e895a157ee3238df634","impliedFormat":99},{"version":"29d02be45ca6a4a3e5ff116d005bc3c8b0349cc855ab0451cebff02858c5dc2a","impliedFormat":99},{"version":"ee1a2bbd2002638a9625fd7fba1ab1e183559bfb68146f571ed7e4f4cf72d009","impliedFormat":99},{"version":"6ec96e6005ceaa870aedd4a2f0ad6e1a9e96982ac3b50de05bf3495abf0a8869","impliedFormat":99},{"version":"c7741d898b0bbb21e03d0b8b12bf5baffe664c862b4d4425c998cc6b7a990705","impliedFormat":99},{"version":"de15f01052140852a9f9d141338c464af482c450db75a081ac78a8fb632609b6","impliedFormat":99},{"version":"c28401f7e250fd756718138e83679c06f35f105e48992e65eb0ae86e191637cb","impliedFormat":99},{"version":"f8019962e492f57c915e7715175929fd357d97e4c01568de0c1babecccee6113","impliedFormat":99},{"version":"dc0843ab204253271a7a4c2f9257a82fa9cb453060f7b60c1b788bfde473d0e0","impliedFormat":99},{"version":"6c3393492c9dd87bdc15e1be2b2120bb163f0cc4be2930f86054efec8b6d3fd3","impliedFormat":99},{"version":"54dfbe8c796abd6d65e478bd791ea7b84085bdd23ead6dd0991ebeb824e6b806","impliedFormat":99},{"version":"9eaac18db6d588dd1202bbac766dab1d7561f33253fbac9b5d503787d9ea451d","impliedFormat":99},{"version":"fbf4f337d8cee2619f24317ad5abfc2015b8006fbef668d7fac5e919033be975","impliedFormat":99},{"version":"86ebb0cdb36cc752597ae8d300148180d8eec489f6025ea5911fa2cbecece081","impliedFormat":99},{"version":"727a4bf89e28dc475c5f9316eece04b14a4b6b9ab277834364239e2f1d2cd9f7","impliedFormat":99},{"version":"4f77f53ffc88fc4afd8f89559f6ebc7c78eb96c3cb6d321b37f398a7a7c911be","impliedFormat":99},{"version":"2fb26f7701fbd742c355cc65f5bdd11a1700d0c34c72b9dc16550016a2fcc3a5","impliedFormat":99},{"version":"aa59534cf8e215f3ed236dafec9353ebd11037bb5b908837825b098f7d364a1c","impliedFormat":99},{"version":"394d1bd06ac39d580db73938e084b22a832381cbcec002715a7119a4b8d2a692","impliedFormat":99},{"version":"a2d8025ac4f51cb494dba9d65b3be176b3eb297bd174cbcb856a2a76eb0df874","impliedFormat":99},{"version":"4cc3862ec78e9b7783f567742f47dd6d6838e646708a512a11b8d27aa9c74130","impliedFormat":99},{"version":"010ba8a40f13ea3f55af47072d1937a6daedbffccc5c507b8cfb33ed45f1e815","impliedFormat":99},{"version":"116c79190f08958c32c45a4f72fdcdf58df72416b32b1d54d6947b13c850201c","impliedFormat":99},{"version":"08ded000262ff0a2ad5d3ef95a0dd90e9505e08bea7ee8e18dc8fccba1bce55a","impliedFormat":99},{"version":"c3e2dbf9a763326f9e03744ead8e07cbd118d52b40813100aa2b716f158606e4","impliedFormat":99},{"version":"51dacfdf9476eca7002cb3a75089dd4fed37c0027abbf3380214119a9aa62fe4","impliedFormat":99},{"version":"050a0677931689dcaa7cd72dec5144256a8e8662e07c313479e7b09471dd8d7a","impliedFormat":99},{"version":"b19c40d229c131754b22173023b333ac2fbaa9317b0a8348ea97dbc7ddf5da75","impliedFormat":99},{"version":"5681612b1dc37cf330b971d4f1f77fc48cbadc18c654f34e1a0416a99fa2c709","impliedFormat":99},{"version":"903c5c6df619e2b85d3bbc7dd881ce90b415b90b7bd4674d025606f1c962f54a","impliedFormat":99},{"version":"46603c02eb1cb18f3be9886a8c04f3162c5e4c1fb7912f04caf80c2109e1e89f","impliedFormat":99},{"version":"bd677fa2528eea20a8b71aaa62f64cf2610c2b3541239da69b41a92c44813111","impliedFormat":99},{"version":"25247edf0256bf357d25178d3e46d90e5199684e4fc7837886d40aba90022b64","impliedFormat":99},{"version":"3106b775494342e60566941c9dd32bcd3380179bf525edf6626da1ddcbcd3632","impliedFormat":99},{"version":"74d3d469b1cecb5dafd09afafaf2829b05bd3a219bc88f19458d3768b07a7e2b","impliedFormat":99},{"version":"e3b15eeed6240702c063be50ce8e933856ae72c1814ae4d36c62f97f288054ee","impliedFormat":99},{"version":"8fa64844cb79114ad676e59db56a5e903c5c43b84ede7e8af3622ab6014f8fe8","impliedFormat":99},{"version":"bc91699dd47e0414a62fbd5df0362f0868bbdc360b189085ca65f271123186c7","impliedFormat":99},{"version":"7283ac5c7df6620f505cf6a64d92b0fb3a6eceac0764c6b3550969b98519a705","impliedFormat":99},{"version":"fdbc4014159458cfcd72a8c3e221e6e21cc44bdc5f670e667acb7ce56bfb8da9","impliedFormat":99},{"version":"941a69d94e5e072ecce094c833ab59434256271361509f4960af1f009aa430b7","impliedFormat":99},{"version":"fc5145b9186234bd41a03b93cb9b956752453056f56e1c36f163f85a5717ae6b","impliedFormat":99},{"version":"2c85bc627145116f3df21f3ed407cc99f5655ad2fcc427bbf57e3b3a0341ea47","impliedFormat":99},{"version":"420739326941762fdf50e14dee4b21a291c06b30cbc58430665ffee9bcbb4b6d","impliedFormat":99},{"version":"90a0a34f6792df8718d8c8d6ed77cf7051d9965a85c0d12cce38f61d706691c0","impliedFormat":99},{"version":"d9cfc4635923eb5c22406f97afdaa0272115af9cfe0fa3f33cd96fa5589187e6","impliedFormat":99},{"version":"a1ade9e632507960b944757f14f836872e567c1e23927eda1c1bcd6b49dce932","impliedFormat":99},{"version":"1fc7bc7871ce771290e11568dcde444ad70fcf8533c1d4fc4ac3a96a4b9ee69e","impliedFormat":99},{"version":"d7cbf83a92ab17f946f155886d55fd14b2e3426ba21fdc6430858ff03735eddb","impliedFormat":99},{"version":"3312143e8158416f98f28b3fedb5bde6c25bc73e46a95451680159eb88868d58","impliedFormat":99},{"version":"3a50148ffaa42c4e23e88522b47c4defd902657ee9eec365979f70625b2e43ac","impliedFormat":99},{"version":"82ab37de5dad558cf74f37a6a033f189480181f8ddf2ea096a60ac28925e1869","impliedFormat":99},{"version":"be055428284687d327cab5cd348976b8ddc588c0ce7de4355437c569ee17556d","impliedFormat":99},{"version":"69f233a54425829456296ec42ab6e23c9a473570d8b084ad52f2421d70ed17e8","impliedFormat":99},{"version":"61f7544cc8d1fad9fa7936304584ce314d3918a31f43d7738f187b9cd1799283","impliedFormat":99},{"version":"0fe6c53bfea404986540d104103db46224830f6912963c90d20f4c195c7000aa","impliedFormat":99},{"version":"bbaa79ab6b210412f9c5befa186d257c181557b819b765f81349c2c593663084","impliedFormat":99},{"version":"e1f6de16c583124f18d59c672f96272fa1662a05f834075c7ca899c1095ab29e","impliedFormat":99},{"version":"66c5847742803134b02bf07c53997c8dab3e4bb4ff428ef861a2450bf7744f61","impliedFormat":99},{"version":"3e80ac50e17c60be70575505005c9c28fd69150273ced8d50d73eed68cfdbf16","impliedFormat":99},{"version":"67022bb9c3b2174baf06917f426d832e447b2e6865be713b9fc18082ea437a51","impliedFormat":99},{"version":"1f3a97a978eaaf934f1f92682bf05bcfc11b8b4a00821d6e4d8c7d6bcff0fc79","impliedFormat":99},{"version":"a771f93d971c945eacad088d558d2015aca8ac0bc533ada8e317f3883f105f32","impliedFormat":99},{"version":"d5d9ba4cdb84bb2cb3207bb01e4ba70ac6ba3432cf6963b028c06388b0cd8656","impliedFormat":99},{"version":"cdb6410d699f7e0833b9e30c344c541c7ee94abe6959a4b714eb98dcda4bfa29","impliedFormat":99},{"version":"9fc6a5e9bb59cf074c5f26e636291aca55429165b98a5ecff9aa4830518f6588","impliedFormat":99},{"version":"1d96a4321e615ed3f7f49351803f592bbabed2edbef1bda6b3ca000b2d684964","impliedFormat":99},{"version":"1067134f9a5c26d079705b4c39112060809b57e481dc6ff954709eeddffe7b46","impliedFormat":99},{"version":"a67a88f62e9948f5cbe6dfc3be4ddb620308f230604e790b5c36a8892b0a5f41","impliedFormat":99},{"version":"0e6ef2d24419cca5b5f020f5f926c24a8a50fb77062feb87f0d759b4455c31b3","impliedFormat":99},{"version":"5b67e62aa4c0817a18ed22992e3a328f2b6402bd2ee4f9ae2dd66a3c3486529a","impliedFormat":99},{"version":"07d6c4bd82310842450b13c63ed0df3ef083ba72a714da9034b815aba390964a","impliedFormat":99},{"version":"74d927443bacd8d7d92a6a377a728e74b1a3ced3c5d96bc04634abb234ed3a8e","impliedFormat":99},{"version":"94c3242169324a0b2212dc12395d17aab5a96b23267f03e0e4142e2cc134c7ec","impliedFormat":99},{"version":"809497b80815e115f27c9b890800931546635a66248b0872332ed47271b6b5a1","impliedFormat":99},{"version":"066f08fd6c8dfe113a509eeb436cdd387747ba544522118c4b6ab6de03e9bfdb","impliedFormat":99},{"version":"abbffa103d638428f06bb6c7bd66b4df1a263846a109881fd9cd6f9402eef25a","impliedFormat":99},{"version":"b85c0b46394017e55622fa7006777655604ebbc87a3b8d1cacf91fb643626f42","impliedFormat":99},{"version":"50596833b2659cbe98f138d233ab3da041734f73a82e96873ccb5056a94f3389","impliedFormat":99},{"version":"75dd74b7c8bde65a3fe491d088b671b75c60ea6a5795c651d8f929dec7bfd0d8","impliedFormat":99},{"version":"7c0a712adc8b64053a0cabf69da09e852f2c64c6a69a662a8648e76de10fdebb","impliedFormat":99},{"version":"7a4369be79b072e7aaa9db48893ab0ef903713cadab764b876b0322ccb213986","impliedFormat":99},{"version":"cbbf88f53c2d00ec848ea9781ff435afbd6776f9dae08ba685e6f64a33711984","impliedFormat":99},{"version":"678d5374d492b91f6d50e6b2f1d4316a131dd6369a1db694e6dcb3569e2aa280","impliedFormat":99},{"version":"3adb720c0fb748257083b6e533d094cb87e7ea330b5d5808588366a181e3432b","impliedFormat":99},{"version":"c9b878138e7dc0f9147ab1ed01cf08533635e50b44d4dbc30345b83ba1237a73","impliedFormat":99},{"version":"da116c018987e5391a646bf242f63305c1afed4dbdc477783f56aca76ed108b7","impliedFormat":99},{"version":"5e96285ab528ff0ddf3393a5d04d8c68b3e881e1fe7ae0fee92966a98112d327","impliedFormat":99},{"version":"8615e46872d20ffe0a8ff44b9ce593f64f79a8d309ac4859e8b59906f9aa8762","impliedFormat":99},{"version":"59d97bc6e943ee2771965639aa795a7ae38b4be58fa26b392720d982786e25a6","impliedFormat":99},{"version":"57ecafef6c1584972a47dc439ddbf5d4cf7ca8891c38847a50562b288c806bb9","impliedFormat":99},{"version":"25a333b9b2020a43a5c4a75c277741c7ede6c01461105b5d0768aaa461de6938","impliedFormat":99},{"version":"964c9bbcfc4a0ca4bc58e1e68341497d8f9bd8ae85c92b33c8b9ab2f0b561775","impliedFormat":99},{"version":"7a32ba7e3b2a4b4e2c71ff2e054c39b73b1e75f1bce260488c2a375797a12e3f","impliedFormat":99},{"version":"7eb276f1e044aeac0873eebcfa0b526bae347809cfa5894dfaf565bb8c2da530","impliedFormat":99},{"version":"1432cbf6c940718ca09b6b458243a9b9cb26bc21c4fed5bbfa199aedf7494e9b","impliedFormat":99},{"version":"9e2ec128354b9c4d3791a82f8ec753739c1716eb73f6ad9d4d6626e733dc7280","impliedFormat":99},{"version":"ab5dcdc2177280000506e0fb519c5fe5c886c9b19c4736886e697d3fb9d59f40","impliedFormat":99},{"version":"0ff58c9fd971479765373fe7f9a5050aea113369701300402698e1b046eda2ab","impliedFormat":99},{"version":"8f5dfad393e0abcdeec04e6a2537e2b385933e7492ced75b2f856b6e36e9e2c2","impliedFormat":99},{"version":"5bf4fe2e8a20e5bdd4626f9b98a092dc3bd3bf28e1dacd3048738a5d28dfe136","impliedFormat":99},{"version":"6879a9db76b09870db16d997fdcb7a752c1f8b6fc6a6d11d9d9aa983258cbeec","impliedFormat":99},{"version":"a5b30514ffe27bad364000d64fe92e9ea518dace05333e2dafc396c9c96058a7","impliedFormat":99},{"version":"62b0a3b99d523ebb4616702063db025c1a153fa21e154fa43305478db8162739","impliedFormat":99},{"version":"d3774ffc91b1ea70a5c2d23487c23dc19cef4b28f41485d21b65498f41d8f9fe","impliedFormat":99},"c43a9b979c1f6894e645143f4fc98fb0f843e1f0d614be9222de66983496cb1c","dcba0b71b1b8d5e1b383cd81a0c114aada239836d91d5214a3ff1f83a928bcf8","3a10d7583ef06dac102b511b79a29d31ae5a9965c9268a6eeb9b1817d55226c2","e391c230bf31f65482c03ef68a0362b8e482f560e7d59b3bf670f5ce75a6054a","8bc1f39223b02722a7134f2e30ca9356ab49cef6b22117c6a43a637da1dfa7ab","22eb7a4efcd4b8290334bd61912dc22d9ac23be9662a23b450c8be36cac3f53a","03fe198123bc59117d587be0fc9caf55388b6415a70d8fa6e1186e398af64e46","cb38a6ab1929e8e62cf133e5e36ded6f7643f65b6a585615363d915ebf55e65c","0adcb7c513194fd1e18b44af5b4952572400d8469a3cb7501811933031b22fe9","d24954c86fbb73b6701eac55a191351d4206387b0c8de98ce882bc80c7fefdd8","31a359c46de53145f3444f9ada81553b9a511e77947d420e034cbd117c21ea77","c8265765a8f5048fbf213ad20e74032bd11f5012bb7a6900787791869e2917d9","c4e603f851e4cd6aafdd39167aec22f8fc95dc583438c1eaa1d6b30ad8c7a2b3","645d7ff926affd52f491b333b9ee8b37fcdf4f71e3aa3d1000e7161360cd345d",{"version":"a615d0c04ae69b96d55cd90efa1a77494f071df627fe5167041cb919ef19b6cf","impliedFormat":99},{"version":"a35121f6047a1f154928237eb65143edb36e68db21ed7eb20e56864f233f67e0","impliedFormat":99},{"version":"3b400cbb502b4cadebd37c63011bd2a170e5ea53c9ba1e23d3ae471c885653d3","impliedFormat":99},{"version":"dd8a53ec9553017589246322f0ea29decfa9bfabd78515ec603f30204387c94c","impliedFormat":99},{"version":"e19d0668b66908541bf0c241c4e7c17038f730983c0618ee645aab4b68aee5a7","impliedFormat":99},{"version":"7bd6aa35e0b7ab7330b3f576c25273164d2bc215d4e41ea94fca0bebc6b75369","impliedFormat":99},{"version":"6d3d3b72ee83b834ad433b63691ad87a18915ae2a6fdd5a85b0b467831c35fa4","impliedFormat":99},{"version":"ecb6d6f4165c611793f289f582f1fbfa76b4f5f68d1353509c536f5c69ae3fac","impliedFormat":99},{"version":"e46cf250ea18d419593c3d20e3cab8465158dd7b891a46f30ca382a109a55131","impliedFormat":1},{"version":"91eeaec45d906c1bc628d22d389e89e74150321b3f35bc2b37a19b4901d0d6e0","impliedFormat":99},{"version":"c9773786e75b0ded73e2ab34046d819af0531c64d68a093e8033c3a0b1e4c4bf","impliedFormat":99},{"version":"e4b58a13476454cc2ace74d33cb3389cc0921ae71f487ee550d893284e658838","impliedFormat":99},{"version":"012c55d5b5e0576d2abfcc26337a27c2eec0961bc9a8430984aea74cf006dfbf","impliedFormat":99},{"version":"e44ddd97427f4228d71ee03310cebc1c9ab470d0fc1f563ebffcc4e203b16336","impliedFormat":99},{"version":"a1a000dd60f69a7a77d9002657b8be109149ff209a9c0409e410b1525b05cb68","impliedFormat":99},{"version":"2cf9ddaf692a373bdabc3ee8466ca58e2c370955b701c01abdae7520f5b23056","impliedFormat":99},{"version":"40ba2b305727890eb433098d66eef24912595b9237ae9aa1e721adae0ae4670d","impliedFormat":99},{"version":"4ba7b35ab1bff4eda6393af7c013328a1a0b1606df054766081b072efeca383f","impliedFormat":99},{"version":"60b94b08c0a841959841d0224efbaa2eb825bc9d268bd51b9b78b8a54d7f8ef8","impliedFormat":99},{"version":"edf88d8976250bccc7984ceedc5db9745659dee5a98d37d14b9608a233d57bdf","impliedFormat":99},{"version":"59537759db64219ce18e76ab9fb5578377d3cde2181076d5fc2c583a393f9180","impliedFormat":99},{"version":"ba87adc0cd6422fde7d6345bef1330b3ec4cfa9d4719aa2ac25614e1d60be05c","impliedFormat":99},{"version":"71f2367b572304c5f0db075f730bfc29d41e94f6723c47dc5b59db63d62a1606","impliedFormat":99},{"version":"9a0202c73232fbb60f2b4f3adaa21849c3c593472074a258ce96ba49021e8ea2","impliedFormat":99},"2c2a4f048a11fa4729c11ecd34172889d592d9e63a3f68ec515cb39625a767cb","34f1feeb98f7bf1a4f372fe1a662dbb874b7f9d1ab0ab46891777bca505e3bc7",{"version":"97a9ddf781a25e4b67c52a6ab069b3ed9a7f8c3878d7a908824a8797bebe8c0e","impliedFormat":1},"512ef4b06a95ca06cd060b967e0c3f8a2c36233df38509d1f9714dd7457da7eb","d3e4aa453464faa6893ce97db72dfc49da3d9b7348701f8bc26e91ba86f4f709","91fab8577b7d8ece31cc653202fee7297ba26a85dab356647af6f25a97d50ac1","a06d20a517471d3bd218d2f918399b6700c7df6886ca2993729eb1b55f26b41e",{"version":"663266b8782a8b327a5196efa1b3627805e3e4fc712d6a4380f5e6571e45a813","impliedFormat":1},{"version":"5aa42b32993e161aaf93d992300494377d38c8883e15fde44d5c7949313058af","impliedFormat":1},{"version":"b75dd83280bdfd4880c04cadd7f5edf6b23305850e436b1e5b92c3847090d031","impliedFormat":1},{"version":"eae784573a5c4c55c65b86accb356b21b5f597c3484c1bd344e647bc92ebe572","impliedFormat":1},{"version":"827eb54656695635a6e25543f711f0fe86d1083e5e1c0e84f394ffc122bd3ad7","impliedFormat":1},{"version":"2309cee540edc190aa607149b673b437cb8807f4e8d921bf7f5a50e6aa8d609c","impliedFormat":1},{"version":"901de16fbacf42f8cbe7fb2e3dc7d33cd91548a54459438fdface0b30a6a29cd","impliedFormat":1},{"version":"90071b0bc39a1aee56e64a5ee1a94065f010d80a0d5124ff50b13e62adee8996","impliedFormat":1},{"version":"243248596db650ce6f8907cbb3a8076a5ab6888a39c37debc11a81c2f9f9d247","impliedFormat":1},{"version":"1460f16c4b7fc66d2dde3ce1a4ab97d480c27fb84a4e429355a21e76cd471e19","impliedFormat":1},{"version":"c5d73bf762b7b0e75fcdf691e21e31c9db9913931b200b9990f07f49ab2edff3","impliedFormat":1},{"version":"de38157a9f1be75a02ea8358be48a4d50ba31785fedd6a4f9ce7387d77ac9a22","impliedFormat":1},{"version":"76a5f88a99d386a1ea9209a9f8f33a3f2c2f17bc445a4078950a49c0624bae3d","impliedFormat":1},{"version":"65357b3849688962f59c625718650ad31ff59e6c23f244b4086f0d96558405d6","impliedFormat":1},{"version":"3f2fed2d0130ee5356cc1cb8782d7c974d37eccce4f1de871f7744ce61463eb4","impliedFormat":1},{"version":"471486ab7c5c95c3df63c0fbebe6871b9535eedff8b582557dfd66fcbf946d5b","impliedFormat":1},{"version":"45e82f28a80d855bab2355d5e46cc8edd7f2679fc5bfb0905dcf01ce59a5c347","impliedFormat":1},{"version":"48f7cd72c6f8ec5b2f70f50a8d4e6f47494e0d228015efb50c36fc6eab33c7ff","impliedFormat":1},{"version":"a8aa7a344599265ef9c2aba0433a805227b2c9b0e743106fab4d6f0c6966f536","impliedFormat":1},{"version":"806bed2ed4bf1c6ebb74a391531e98d361a0e23a31601fddb33dd90e31436b6d","impliedFormat":1},{"version":"9b92a4d989efc3eeefdca5f95f10267504abc7748ecff400b533cdf54dcdbd68","impliedFormat":1},{"version":"16e6feb2ea29757a0cdd16c8fe2bdf059a612a5474ea30019ae60d9fe309442a","impliedFormat":1},{"version":"2f45dc6e152333f5d28bb660e4543bfd41412b5af16b9a6331b7fd0b4982885e","impliedFormat":1},{"version":"ea4eadfe3d8b0447ecea1cbbf7aad70423cca9350bc9103a1d80cebc37e6bdb3","impliedFormat":1},{"version":"b88645280562793af76ab59052d87e4846ac5ef19af054c729fbb87c73481a59","impliedFormat":1},{"version":"a1f43b06dd37b1f6c5c7821881960dfe55038b468eafb324ad90ce5e9b448d2a","impliedFormat":1},{"version":"15b142d522e96e1962bd54c75560f6994cc8fe9a1640a36de2268fdb95e58fb5","impliedFormat":1},{"version":"de79263f32ea34b3f9282b19251626eeb3a3aef8d96491b731a3c0fb5cca2e77","impliedFormat":1},{"version":"332680a9475bd631519399f9796c59502aa499aa6f6771734eec82fa40c6d654","impliedFormat":1},{"version":"191bee6605de2b5210f29f22df04f5b5e6bdcc1f6e21fb07091d40eeeb75fd72","impliedFormat":1},{"version":"d83f3c0362467589b3a65d3a83088c068099c665a39061bf9b477f16708fa0f9","impliedFormat":1},{"version":"180e527dbc1f5ae2bbb79d0a3db1ada49258783d7e6299559e0f2ed663b4afec","impliedFormat":1},{"version":"29994a97447d10d003957bcc0c9355c272d8cf0f97143eb1ade331676e860945","impliedFormat":1},{"version":"f4260022f7af38e533d364ea62eb7ae01b0a32050033d7f6772073e1dc908025","impliedFormat":1},{"version":"9cddf06f2bc6753a8628670a737754b5c7e93e2cfe982a300a0b43cf98a7d032","impliedFormat":1},{"version":"3f8e68bd94e82fe4362553aa03030fcf94c381716ce3599d242535b0d9953e49","impliedFormat":1},{"version":"63e628515ec7017458620e1624c594c9bd76382f606890c8eebf2532bcab3b7c","impliedFormat":1},{"version":"355d5e2ba58012bc059e347a70aa8b72d18d82f0c3491e9660adaf852648f032","impliedFormat":1},{"version":"311cc121259b3e0c3c08304fc25b525aa02ba0f9bf55b3e7c60b0dbb7422014e","impliedFormat":1},{"version":"74c269b43d39e5ece20b2cca49c14e64c05b01e46407200d7558301d0fcaabf4","impliedFormat":1},{"version":"ec09bd95866efe38cd00ebb79dfa7a26563d600fa4a30db0f7c6d68f8f6d2b06","impliedFormat":1},{"version":"482d0ac70d56aa79941be30da6df28e926a007f835eed70cf7b5f3135368d1f6","impliedFormat":1},{"version":"7dd19397d5a090c9f8cd762bae67bd0ad6f782abe422594fb71168fb578673b0","impliedFormat":1},{"version":"84cbf6204ada0ee2f80493e55e45befa079954788718efd6dcc103183104e3c0","impliedFormat":1},{"version":"9a0a0af04065ddfecc29d2b090659fce57f46f64c7a04a9ba63835ef2b2d0efa","impliedFormat":1},{"version":"10297d22a9209a718b9883a384db19249b206a0897e95f2b9afeed3144601cb0","impliedFormat":1},{"version":"034b8b5912823744c986986f24432bf3fa7bfa671e69316b672f3f2db5166ce4","impliedFormat":1},{"version":"34d206f6ba993e601dade2791944bdf742ab0f7a8caccc661106c87438f4f904","impliedFormat":1},{"version":"05ca49cc7ba9111f6c816ecfadb9305fffeb579840961ee8286cc89749f06ebd","impliedFormat":1},{"version":"14bad5bea17b4e0f2495b5dac89a936e139338e2c87716bffd3c281ae7a9fec6","impliedFormat":1},{"version":"b8a122e51c2ee902b44d86ff806011d216af54be75844a4d3c366d80776a4d33","impliedFormat":1},{"version":"0850c98ca2cccae6ce2aad363f6eb370c401fbc279a64607fff90c0f87973a91","impliedFormat":1},{"version":"d0f62192ec787f1592a5b86760a44350d1c925883a573eadc12d60862890dffe","impliedFormat":1},{"version":"4ef34562ac49a16a1681d51d6e8ece677657782cf1a464e010224cbbe0bb071f","impliedFormat":1},{"version":"a66ad696f2785dd00374b8dee6fab5c58c049c0efe24b3c214fbe6aec3f53d6e","impliedFormat":1},{"version":"f226f29f5594bd479f27648f42423ffa1a1460cafc7b1ba04bd013b28cba710f","impliedFormat":1},{"version":"63f859a315e9711f383d06b7a2b940804e51078d85e896980816f46f1b6021a8","impliedFormat":1},{"version":"f8da2a3bec435c09f9a10d9f150949bf0ebb0c3508f074887dbb2d3e33ce302b","impliedFormat":1},{"version":"397b46c6a95826d26714b5481addc606de72d8229b092e236f0d78a9e7226d29","impliedFormat":1},{"version":"5f47fb5b000c03fdcae71e6e017261898a37f0892532cb713ce95c8950462d80","impliedFormat":1},{"version":"8142d5eaa44b4dbb68dbe87b5f05b148c5a74a6fa7abd3cb3aa80a7ed4a05150","impliedFormat":1},{"version":"6c66369276512eac5b53eaca735d7472b5ffca417977c3976a66b84059f2af2b","impliedFormat":1},{"version":"225deff02f4d1c91e2d6c71dec9f18feae510aa729a9774024f30278f4c6b8fe","impliedFormat":1},{"version":"6c24f6dcbb3bf8235bf8da995a7290ffbd9d557a760cf2deb380ce91a989b765","impliedFormat":1},{"version":"e48415a5a97a5e6c22cc4fdcb3172805ce68a1d41d0a056d71bff9ced2186d43","impliedFormat":1},{"version":"adec507ee458a691b72254991a7903a10c052019d8cdc7ffe359d9f373e7401f","impliedFormat":1},{"version":"9b74326515d17f03809cfbea6de789772ff7d0c759a08a59bfa5242bda98d35b","impliedFormat":1},{"version":"09788d0d992a6d2471f35019ab68b39105c44ebf17f2051cf3e228a39e91885a","impliedFormat":1},{"version":"0ea47413eaffe144782a44058205c31130b382dee0e2f66b62b5188eac57039e","impliedFormat":1},{"version":"c0591738dbfe11a36959f16ab40bc98b2a430c4565770ef6257574546079d791","impliedFormat":1},{"version":"3cf3dc0f53d71795cd7c461346e9aa3c713f8a5138015776aa6d4b8ff9e0cb26","impliedFormat":1},{"version":"ca73451ec7771379b6b1271dcda0d0b2146da80b329136a09ad692529a073965","impliedFormat":1},{"version":"fad74233657c4e0346822942ac3716a20b16fb053ca00c1260a08a81cc76df89","impliedFormat":1},{"version":"43f0a7dead8b25e1c101a060ea31d6df548a9303c58aa7498d0285fd4ecaac1c","impliedFormat":1},{"version":"fced7c59acecb0ac631505fcbc5a1ce0c6420e2494a256321e9359093efb7a1f","impliedFormat":1},{"version":"8c42fbcae55a41f9c48f644ff9743fab827a9d38f5a6bd486f17c6460f8a099b","impliedFormat":1},{"version":"793c2b5a225ca7569320b2f9f3a43cc20a08e83fbd6587f5c24c7a05feaee6d0","impliedFormat":1},{"version":"cf841c4bfb05b4b1d3826773ff77a47bb0dc17c665a4dbff7d6c4a6d9042d50c","impliedFormat":1},{"version":"597b9bd9363840016d7e8c6839cccd22f85079484bae7e444e80cf24645529af","impliedFormat":1},{"version":"bd15222c3f016a97d7062a0018f7fe0d130be508ca276b43dcafa8c9032a3ea4","impliedFormat":1},{"version":"4f5f11b73282262904f4c1bc5ffb76631b40ac8b54ae01bde274cb9242d6cb2f","impliedFormat":1},{"version":"9e6dcb736749cc84304b38c5a1101b299659dbc3871bab5d1544ee8f8dc73e5b","impliedFormat":1},{"version":"3f8f36996bff2e0d4f6bb2b11e1a684489b511032473180f44d0b23f38a53800","impliedFormat":1},{"version":"4e4559e8e4ea7d87f914014074559e515de78308bacc733a7ea76f795de178a3","impliedFormat":1},{"version":"13ecb31795209aa56b1837b9d46cc5494da392f594132bc5b3a56c067e12ea1c","impliedFormat":1},{"version":"e34a28e978cf430e062c91d03987f2b42360b33e6207738b40494acd4a97004b","impliedFormat":1},{"version":"5cc10d0295e594c961bd020cc76845097928f550fa3d58468114e5225054f76c","impliedFormat":1},{"version":"99c4cd704c85c3b9a215977d1d10ad34f1c6bbc5784e0ddaaf6fe8090030eaf3","impliedFormat":1},{"version":"7dc695c4ab01309d1d1b43201700560054feadddf8d0bbfc79d981bff03c1db0","impliedFormat":1},{"version":"ab0db8d8a821582e3f49739e5267466d964b64f4aeea5ba379ac7759c7adc531","impliedFormat":1},{"version":"f6e9e0411de308207892802c52be06bf25df281ace623cbf7870583e28b3f12b","impliedFormat":1},{"version":"307067699cff7c3c8a77d9e69aef5291f0141cfbbbeb0954804589e6701238cc","impliedFormat":1},{"version":"11741962da8818dfe175a7e01a483149d085b569dc5e021c83a94203d686996a","impliedFormat":1},{"version":"43e4de859903a03dfc018748ca5cb673df9cf43df17f379fda7da85eabf7883f","impliedFormat":1},{"version":"e3e78772154f790f8b0a6eaeaba5b4c816567d9d30f9c8655ed29cb9438e5455","impliedFormat":1},{"version":"e17369650fdfac36437e8559b86b2d6172d090594696976082903ba856a2a979","impliedFormat":1},{"version":"69cab7f70e702f3a517d6e47428b4d2d76b56bc355e6f85e305d1b6f6d700f7b","impliedFormat":1},{"version":"8a95a499afe7cd2aa6161b68aa3f7599e9ae7d12697171384f540e268d846746","impliedFormat":1},{"version":"2967840927e96b345f7b8250ad35e7436aae73c77d9767a2b43f2606ab107cf3","impliedFormat":1},{"version":"0e6387b87925a10ba52cd0de685a4f7e2d9dd402dbac560dce8934e8e34007d0","impliedFormat":1},{"version":"77515d8e0ceb4f4bae7d0c9aafe9fd764a5f25601569ecbac3240cacfe136f14","impliedFormat":1},{"version":"b07d72a408bfcf125c24cfba3db38207687711b800b98ab417e5ada59438c554","impliedFormat":1},{"version":"ef5aa9871f3b8dac96d4ef93e22eec539527d739c6a7e0c7fa7101fa343bfd77","impliedFormat":1},{"version":"47507ff33fbe83627bdf11136400594a249e8012508425bb2846b7268f966f00","impliedFormat":1},{"version":"4a1a0f21b3c4fc0d217392d82445a34fcc8c9ed6f79fdc4d14b8353e3c74eaf3","impliedFormat":1},{"version":"e041d566f765b48ddf66ffd085fb120951cf28e92d129751351e72f8c96d99fa","impliedFormat":1},{"version":"5a59c1315ed5ca8f899fc6527f23a15dc9a38107175a5fffd473db25bcd1fd4a","impliedFormat":1},{"version":"20a5515b81a828fc10b066aa5f88a5eb68323d23b8a10d8e9dc7edb6ebdd2bd7","impliedFormat":1},{"version":"f2c24a1e4bc555e203dab5b749b718b1cdf73ecf57d8a8872ff163cbc03b1a68","impliedFormat":1},{"version":"0dcea4e3a40e7408ec9a6aeacb721ce8289fc99d5f2be600146a472d6d1590b8","impliedFormat":1},{"version":"2093f341c5cba3058c29f9344e59ecfa22dc6559c7eb9f00497a108e09301a55","impliedFormat":1},{"version":"15aba6a4199ce9e4f3c1ec397a468f6aaaeba973649ca4f1c016225b46a5feaf","impliedFormat":1},{"version":"a1ca7f7788853a2ff3670bf1112a92fa503686b10d58339318fec5862bd209a6","impliedFormat":1},"e548f2e9c8bf375b79791b9bd5577c2ae52099e6094f64741ab7465b368bf607","e2372397561a54d52fd69e651af6ef21c57427ae37a5ee0275e445a6b50c2451","80a1b7271f4a66581257d624f5dee203a980bae22ca81039edb205665b6ab855","e6d6cc5987ca14fcd39e332562edd3762f0b46578d2bcd0114446cb44a3a75a9","d393b63a9361dab4cab186706924dd56a89c5cc25bd68d3c5b99a7a8a66b83de","95faf7271afbefe99e579999fef85991292f455621af4b20136247c159dffc2b","17114a6d6d1c2a791c716ff22525568cf06c7ee3b1d3080bc05c682472e7709e","c70a0b383622a14fc4c74b9128abb58d8fb07da95e3f4c1403872d375ac650f2","9269a5d58ba6022ad1d3cc4e7dcfa3d11f8e65a3fb92ff90eb73e0c95fbb8cf0","38c9c8fee1a25102d1fed20e3f93991c70459a7eae6c54ed70451b02ce979a69","c56cb306a044e5c966a43d5531763bc50a2dbe4a9b38d16f29c0c670737ee4ce","47f42bc21cf5e00964e84186e3ebd94befc7a4dae13b14cf0af6d411d50aac54","8db8da3d23cfe6ed101e1267ae35bd5edba3fcb2ae8221cfee228c00bb2bc6bc","eabc8f103dbab6d22b12a0641ca9f670ede91ea3b1938662df6904652f25f355","a1bcb28a4cccca961ea8b0e780fe65c186a9197c5f6e7d4168ec39adf17443b0","ab83448699bb7bed5c8f3a2cfaf852dbd9dcd397d59818a97e5e4e0b1d88a163","0ee774c9561a717c9821383349196f4d7191b625fd4643c5c4b230259e67d941","5a242913fa041089fc74ae5346fd90529f56db76367e610011c00309ed890e72","56f49237fc82a5f0721827106512c731dce51221ca9935a3288cdaeddbe94a5b","80bd0ebe43a06f5bc0de77813592444e2fadeb4947ea81c5f70a4f29667ef440","6918f13583cdf851e82ef25dd757c1446a6a0ce5f1ffcb92946584602bd9bdd1","8ae2cd431ec2c1722722b4c89553608c3a941750dca2f302b226e245218b14fa","2a5be91a9294e96d19c61e1dbf6f90bb42dd245512ed6d830ff2a23ab46e0592",{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"476e83e2c9e398265eed2c38773ae9081932b08ea5597b579a7d2e0c690ead56","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},{"version":"c3d577953f04c0188d8b9c63b2748b814efda6440336fa49557f0079f5cf748a","impliedFormat":1},{"version":"787fe950e18951b7970ec98cb05b3d0b11fcdfeb2091a7ea481ac9e52bf6c086","impliedFormat":1},{"version":"13ceda04874f09091da1994ba5f58bf1e9439af93336616257691863560b3f13","impliedFormat":1},"1d1e3fc7d5074fb7ff2c8a886fa46f0c5a09b740711f6201667800a46ed5b97a","23402655eee7ed5e511aa2edb733732d8838e2030cf16d3079ead1d9a5d158e5","0188f7050365372d9d930e4b552c119ce55143d67451f514e75e27b6cbf706fe","b36f7dca6ae5a145bb0dabb585c5850982258b178102924445b2cdb3bd21130e","b7be0f0324685f950300a13d5c7819b1a3bc43b4cc6b9b50b0e236e2a4e1a213","f32a4caeee5c9464f7b4a6868725ba6ef0cb33ebb89399f62869506b288347b2","6e22651d2a37286108205b7e77388e9c04ca22b8e55f486a8084552b413ca94c","561203f3b6cc031e72295f91e74f98cf29feddaac3b299f57b04b63227f7a50f","66b7601e332c5c7e78d5422999dbc9d80e0fdf39eafec93f8fb89f6860c0fc25","9e3ae9df007f6efd788a3d250a53125ad7acace563995d21be9ab81e40168916","158bccb23ef0e4221062eebccef0a6fa27babbdf7279ab418e6b35dd2d8779db","d94eb82793f49b10a7224a5f4fdc30def1816e111ac665516da221616b2e944e","24943e048b40c6c0ea9e973db4a5945aa99fdaf02b247e4b22343fff98d3b8b0","2c43015df809b3eca40b4d8833c77ef5c404b2fe4924434bca7410f17aa03670","ca929693143e3306bc9e61da89e0550ff5c3edecaa5572e06dcda5122bc44f84","e46e139a5bc327dcc332439b7349a95730806e0491620eced4a3b3196c7b8441","5629089a8ce5ba5af988ad7437a52af2b743bba5f6a304fccf253d46a985f0fe","87303cff60bdf82ab91104ec03f0b1fed33d07bc6c5f05d6697ab98b1816816f","570e81ceb277435bdc7fc67b0e70a8d90e872cee981e462d9d44691f7501bccd","7d90e7b154bbca06c5905b2b80589c6ad24ec87a96829eb9f97adb5496bf6e47","e0602f77e68ad586d969d3b8c8045ad17dee7d47a302f8e92590200d7554d576","152fb5d6fd1016fb596639154b804e03f107c551f3f358663866192e6e15be6c","d44b065643841e9db83c110bc40e9be21632fc0db486b8fabd28ffe7bf1602a0","6d167f16ead6c5d7f35da4962c505973abdc3164f5faee73722bffd938ed5ace","f4b103f39a8acac768731ac5465fc6f4cfa143ec0cd3ac786df8eb59dbbf50e5","68ac1653d2102690c528749e5b363954a8260103cfb873fcc2a89651fb4f4529","d483a15e5e9c15154eadcd7b6fdfbdc658e28090fdf8dc6594b0edcc7f8b5738","af816ec1f6e2d6feec283352ee2dca1a7d19f98d483d09d11e6d488e36d9a493","e185f6151fc782dd42dfd69886273bea608191a3dc2c1a66c5d558165f492647","9fa329a520177a447c23f5fa1098bf9f06e43f585826a55ad195f13121cb38f7","cfecef32deefcabd8d7ee02bbd3136632204c1dfae2dae2eef1a0a96b7593b99","5d73404a106cece0e5898f8c2864f1c3cd86c13b457be98123caf855ddf7c8ef","71c7cea4c24194ff65c8ee71db28cfcad4a65823f7e1b83759f59dca056ef7fc","aee5ba17b4b3c4bfb2211677acbc31e38f26ea14940ad67ceaa95a990797c1eb","0d27a72df364d777a1b45afaf35ebd4744c97427584be173e3997abae38dd28c","bbb33ef43558bf19c7f1fa856927bef2293689c7a7d55d44a8366b2ee831c5a1","748fba3fb265fc471e8b199b0ddea6697bf24b88cf0dc079283062f45c2baff6","0f8e879a797fa230e0973e4194a791ec58e92707ae81b29377d481578c0a5d54","d4d282ee5fc0b3c9e7461f2608faa325afc03c90beaf301078e46a6d817fbf0b","6269036e1e16b1c530fc031eaf68407fdc5c3b6ee98df93f2c7a426f049eff57","f0d2e86ed84760deebd4100433f0e8d2bc187ab49d72e011375320f0ce7feb53","61749bc2925ec57e55007cb09ed53990d09f809067d525ab0009ca9badb100ed","8434188e3ad7c70e2656b90881b00c4893ea9794d34d38573b8961c78e2f52eb","85b1c0920c47c254ba809b7fcbb4559e7630b6e84eb84820573fae24b85f1d7d","b90197712a8c37fec266db77d802e0c136fba53c5fa8ee03ec0c5cd0739d2208","2552a31fad45a9ed1bde87e51b038dc0e786cd364b597162263abbf57018949b","d1637aaf8927861be9cffe5159d18afadcfb86c6e532e9f1f0111a41238c7fc8","4b6933b57ae47a95c697819c0358ec9a2131f784a0a2ad59dc07541524dded0d","3635377c14f4b46b43db9abcb9da7ae28d60f9231269727e7f2ffdd50a0daa76","83fb239e36697fef0567839be41af71b05acecafa723cfc9673523582062d5f2","94f96b491ff05aee70d8abcfef4bf25cd412e7ac5b143326aaad0f875dbca846","3778e0d23a48683db5d709df25fac61bd8d31f31ba9901808a6751b2e2e93dff","3b5b6d4dd348623a210d329b73ab881412d4a73b3371fd5d4cbebde050814e64","cc2d7fd3ecae4eb9bf3d1c495968999399701f504a6848396da07f5bd2ef208c","50765584d97dce5ceffddd510c4436f9e287890c3c2a9e297f5266297ad63495","95928e15dc838dea701e34b3075889eff76fbccf38d8bee656dd7074ad78c949","5c7f2bd2181d57ad12b3c208a03bd1e9383169caf929243bb5db06bbbc0525fc","03b22167ea82e331553894c254f94df16fda63cb689334cdb8b616f2666b10a4","4996d57e286292df51b7f67937cef5ea9cd933f88d8b714ec9fa407f12b7e0da","537744970546b87a662cc02164768f8b47c92b7c0542968300beed0aefd4ba12","292b7479a7be491a9f1074451531fe85ebcbba0c200ca4704065b92a9397beac",{"version":"751764bb94219b4ce8f5475dc35d3de2e432fea01a0c9610cd7f69ad05e398c6","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1}],"root":[83,502,503,529,[534,536],[607,612],[1484,1488],[1512,1515],[1742,1755],1780,1781,[1783,1786],[1900,1922],[1929,1989]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[1978,1],[1979,2],[1980,3],[1981,4],[1982,5],[1983,6],[1984,7],[1985,8],[1986,9],[1987,10],[1988,11],[1989,12],[1976,13],[1977,14],[1974,15],[83,16],[1975,17],[1488,18],[1515,19],[1513,20],[1743,21],[1744,22],[1746,23],[1747,24],[1748,25],[1749,23],[1750,26],[1751,27],[1752,28],[1753,29],[1904,24],[1903,30],[1905,31],[1906,32],[1907,33],[1912,34],[1913,35],[1911,36],[1914,37],[1908,38],[1915,39],[1916,40],[1959,41],[1961,42],[1958,43],[1966,44],[1968,45],[1930,46],[1943,47],[1970,48],[1929,49],[1971,50],[1972,50],[1962,51],[1965,52],[1933,53],[1950,54],[1963,55],[1945,56],[1947,57],[1934,58],[1941,59],[1960,60],[1967,60],[1937,61],[1946,62],[1969,63],[1935,64],[1936,52],[1973,65],[1964,66],[1953,67],[1939,68],[1954,69],[1949,70],[1955,71],[1931,52],[1932,52],[1938,49],[1944,49],[1940,72],[1942,58],[1951,73],[1952,74],[1957,75],[1956,76],[1948,77],[1917,52],[1918,52],[1909,78],[535,79],[1512,80],[1781,81],[1486,82],[611,83],[1783,16],[609,16],[608,16],[607,84],[534,69],[536,69],[1755,85],[1785,86],[1786,87],[1902,88],[1910,89],[1919,90],[610,91],[1900,92],[1514,93],[612,94],[1487,95],[1784,96],[1745,97],[1742,98],[1780,99],[1901,100],[1754,16],[1484,16],[1485,101],[502,102],[503,103],[532,104],[531,105],[557,106],[547,107],[545,108],[543,16],[546,109],[539,109],[544,110],[540,16],[542,111],[551,112],[553,113],[556,114],[552,115],[554,16],[555,116],[541,117],[548,118],[249,16],[533,119],[530,16],[528,16],[1764,16],[537,16],[1990,16],[1991,16],[1992,16],[146,120],[147,120],[148,121],[100,122],[149,123],[150,124],[151,125],[95,16],[98,126],[96,16],[97,16],[152,127],[153,128],[154,129],[155,130],[156,131],[157,132],[158,132],[159,133],[160,134],[161,135],[162,136],[101,16],[99,16],[163,137],[164,138],[165,139],[199,140],[166,141],[167,16],[168,142],[169,143],[170,144],[171,96],[172,145],[173,146],[174,147],[175,148],[176,149],[177,149],[178,150],[179,16],[180,151],[181,152],[183,153],[182,154],[184,155],[185,156],[186,157],[187,158],[188,159],[189,160],[190,161],[191,162],[192,163],[193,164],[194,165],[195,166],[196,167],[102,16],[103,16],[104,16],[142,168],[143,16],[144,16],[145,155],[197,169],[198,170],[203,171],[359,52],[204,172],[202,173],[361,174],[360,175],[200,176],[357,16],[201,177],[84,16],[86,178],[356,52],[267,52],[1887,179],[1787,16],[1803,180],[1884,181],[1867,182],[1868,183],[1866,184],[1869,16],[1870,16],[1875,185],[1871,16],[1872,16],[1873,16],[1874,16],[1881,186],[1896,187],[1882,188],[1885,189],[1880,190],[1888,191],[1883,181],[1878,192],[1889,193],[1879,194],[1890,195],[1850,16],[1892,196],[1877,197],[1891,189],[1893,198],[1876,183],[1895,199],[1837,16],[1838,16],[1841,200],[1839,16],[1806,16],[1840,16],[1899,201],[1805,202],[1788,16],[1794,203],[1807,204],[1809,205],[1844,206],[1865,207],[1845,16],[1799,208],[1846,209],[1847,210],[1848,16],[1849,16],[1801,211],[1852,212],[1853,213],[1790,16],[1798,214],[1854,16],[1843,215],[1855,16],[1864,16],[1808,216],[1836,188],[1856,16],[1793,217],[1857,16],[1858,16],[1859,16],[1861,218],[1860,219],[1862,220],[1851,221],[1842,222],[1863,223],[1802,224],[1810,16],[1795,16],[1811,16],[1814,225],[1800,226],[1796,227],[1797,16],[1812,214],[1813,228],[1789,16],[1894,229],[1804,230],[1898,231],[1897,232],[1829,233],[1830,234],[1828,235],[1816,236],[1821,237],[1822,238],[1825,239],[1824,240],[1823,241],[1826,242],[1832,243],[1835,244],[1834,245],[1833,246],[1827,247],[1817,248],[1831,249],[1819,250],[1815,251],[1820,252],[1818,236],[1791,16],[1792,253],[85,16],[1505,16],[1782,16],[613,254],[615,255],[616,256],[614,257],[638,16],[639,258],[621,259],[633,260],[632,261],[630,262],[640,263],[618,16],[643,264],[625,16],[636,265],[635,266],[637,267],[641,16],[631,268],[624,269],[629,270],[642,271],[627,272],[622,16],[623,273],[644,274],[634,275],[628,271],[619,16],[645,276],[617,261],[620,16],[648,277],[649,278],[650,279],[651,280],[652,281],[647,282],[653,283],[646,16],[655,284],[654,285],[657,286],[656,285],[660,287],[658,285],[659,285],[663,288],[661,285],[662,285],[665,289],[664,285],[667,290],[666,285],[671,291],[668,285],[669,285],[670,285],[673,292],[672,285],[675,293],[674,285],[676,285],[677,285],[679,294],[678,285],[682,295],[680,285],[681,285],[685,296],[683,285],[684,285],[687,297],[686,285],[690,298],[688,285],[689,285],[692,299],[691,285],[695,300],[693,285],[694,285],[697,301],[696,285],[699,302],[698,285],[703,303],[700,285],[701,285],[702,285],[705,304],[704,285],[708,305],[706,285],[707,285],[711,306],[709,285],[710,285],[714,307],[712,285],[713,285],[716,308],[715,285],[718,309],[717,285],[720,310],[719,285],[722,311],[721,285],[727,312],[723,285],[724,278],[725,285],[726,285],[730,313],[728,285],[729,285],[732,314],[731,285],[734,315],[733,285],[736,316],[735,285],[740,317],[737,285],[738,285],[739,285],[743,318],[741,285],[742,285],[745,319],[744,285],[747,320],[746,285],[751,321],[748,285],[749,285],[750,285],[754,322],[752,285],[753,285],[757,323],[755,285],[756,285],[759,324],[758,285],[763,325],[760,285],[761,285],[762,285],[765,326],[764,285],[768,327],[766,285],[767,285],[770,328],[769,285],[772,329],[771,285],[775,330],[773,285],[774,285],[777,331],[776,285],[779,332],[778,285],[783,333],[780,285],[781,285],[782,285],[786,334],[784,278],[785,285],[789,335],[787,285],[788,285],[792,336],[790,285],[791,285],[794,337],[793,285],[797,338],[795,285],[796,285],[799,339],[798,285],[801,340],[800,285],[803,341],[802,285],[805,342],[804,285],[807,343],[806,285],[809,344],[808,285],[811,345],[810,285],[813,346],[812,285],[815,347],[814,285],[817,348],[816,285],[819,349],[818,285],[826,350],[820,285],[821,285],[822,285],[823,285],[824,285],[825,285],[829,351],[827,285],[828,285],[835,352],[830,285],[831,285],[832,285],[833,285],[834,285],[837,353],[836,285],[840,354],[838,285],[839,285],[842,355],[841,285],[844,356],[843,285],[846,357],[845,285],[852,358],[847,285],[848,285],[849,285],[850,285],[851,285],[855,359],[853,285],[854,285],[857,360],[856,285],[859,361],[858,285],[861,362],[860,285],[867,363],[862,285],[863,285],[864,285],[865,285],[866,285],[870,364],[868,285],[869,285],[872,365],[871,285],[875,366],[873,285],[874,285],[878,367],[876,285],[877,285],[882,368],[879,285],[880,285],[881,285],[886,369],[883,285],[884,285],[885,285],[889,370],[887,285],[888,285],[890,285],[891,285],[893,371],[892,285],[895,372],[894,285],[898,373],[896,285],[897,285],[900,374],[899,285],[902,375],[901,285],[905,376],[903,285],[904,285],[909,377],[906,285],[907,285],[908,285],[912,378],[910,285],[911,285],[914,379],[913,285],[916,380],[915,285],[918,381],[917,285],[921,382],[919,285],[920,285],[923,383],[922,285],[925,384],[924,285],[928,385],[926,285],[927,285],[930,386],[929,285],[932,387],[931,285],[935,388],[933,285],[934,285],[937,389],[936,285],[939,390],[938,285],[942,391],[940,285],[941,285],[945,392],[943,285],[944,285],[949,393],[946,285],[947,285],[948,285],[952,394],[950,285],[951,285],[953,285],[956,395],[954,285],[955,285],[958,396],[957,285],[963,397],[959,285],[960,285],[961,285],[962,285],[968,398],[964,285],[965,285],[966,285],[967,285],[970,399],[969,285],[972,400],[971,285],[976,401],[973,285],[974,285],[975,285],[984,402],[977,285],[978,285],[979,285],[980,285],[981,285],[982,285],[983,285],[986,403],[985,285],[991,404],[987,285],[988,285],[989,285],[990,285],[993,405],[992,285],[997,406],[994,285],[995,285],[996,285],[1001,407],[998,285],[999,285],[1000,285],[1003,408],[1002,285],[1007,409],[1004,285],[1005,278],[1006,285],[1009,410],[1008,285],[1012,411],[1010,285],[1011,285],[1014,412],[1013,285],[1017,413],[1015,285],[1016,285],[1019,414],[1018,285],[1022,415],[1020,285],[1021,285],[1024,416],[1023,285],[1026,417],[1025,285],[1028,418],[1027,285],[1031,419],[1029,285],[1030,285],[1033,420],[1032,285],[1036,421],[1034,285],[1035,285],[1039,422],[1037,285],[1038,285],[1041,423],[1040,285],[1043,424],[1042,285],[1046,425],[1044,285],[1045,285],[1050,426],[1047,285],[1048,285],[1049,285],[1052,427],[1051,285],[1054,428],[1053,285],[1058,429],[1055,285],[1056,285],[1057,285],[1060,430],[1059,285],[1062,431],[1061,285],[1064,432],[1063,285],[1066,433],[1065,285],[1071,434],[1069,285],[1070,285],[1068,435],[1067,285],[1075,436],[1072,278],[1073,285],[1074,285],[1077,437],[1076,285],[1086,438],[1078,285],[1079,285],[1080,285],[1081,285],[1082,285],[1083,285],[1084,285],[1085,285],[1088,439],[1087,285],[1090,440],[1089,285],[1093,441],[1091,285],[1092,285],[1095,442],[1094,285],[1097,443],[1096,285],[1100,444],[1098,285],[1099,285],[1102,445],[1101,285],[1106,446],[1103,285],[1104,285],[1105,285],[1108,447],[1107,285],[1111,448],[1109,285],[1110,285],[1114,449],[1112,285],[1113,285],[1117,450],[1115,285],[1116,285],[1119,451],[1118,285],[1481,452],[1121,453],[1120,285],[1123,454],[1122,285],[1128,455],[1124,285],[1125,285],[1126,285],[1127,285],[1130,456],[1129,285],[1132,457],[1131,285],[1134,458],[1133,285],[1139,459],[1135,285],[1136,285],[1137,285],[1138,285],[1141,460],[1140,285],[1143,461],[1142,285],[1145,462],[1144,285],[1147,463],[1146,285],[1149,464],[1148,285],[1151,465],[1150,285],[1155,466],[1152,285],[1153,285],[1154,285],[1157,467],[1156,285],[1159,468],[1158,285],[1161,469],[1160,285],[1164,470],[1162,285],[1163,285],[1165,285],[1166,285],[1167,285],[1175,471],[1168,285],[1169,285],[1170,285],[1171,285],[1172,285],[1173,285],[1174,285],[1179,472],[1176,285],[1177,285],[1178,285],[1182,473],[1180,285],[1181,285],[1184,474],[1183,285],[1187,475],[1185,285],[1186,285],[1189,476],[1188,285],[1191,477],[1190,285],[1193,478],[1192,285],[1195,479],[1194,285],[1197,480],[1196,285],[1199,481],[1198,285],[1201,482],[1200,285],[1203,483],[1202,285],[1206,484],[1204,285],[1205,285],[1209,485],[1207,285],[1208,285],[1212,486],[1210,285],[1211,285],[1215,487],[1213,285],[1214,285],[1218,488],[1216,285],[1217,285],[1220,489],[1219,285],[1223,490],[1221,285],[1222,285],[1225,491],[1224,285],[1229,492],[1226,285],[1227,285],[1228,285],[1233,493],[1230,285],[1231,285],[1232,285],[1235,494],[1234,285],[1237,495],[1236,285],[1239,496],[1238,285],[1241,497],[1240,285],[1243,498],[1242,285],[1245,499],[1244,285],[1248,500],[1246,285],[1247,285],[1250,501],[1249,285],[1252,502],[1251,285],[1254,503],[1253,285],[1257,504],[1255,285],[1256,285],[1262,505],[1258,285],[1259,285],[1260,285],[1261,285],[1265,506],[1263,285],[1264,285],[1267,507],[1266,285],[1269,508],[1268,285],[1272,509],[1270,285],[1271,285],[1274,510],[1273,285],[1278,511],[1275,285],[1276,285],[1277,285],[1282,512],[1279,285],[1280,285],[1281,285],[1284,513],[1283,285],[1286,514],[1285,285],[1288,515],[1287,285],[1291,516],[1289,285],[1290,285],[1293,517],[1292,285],[1295,518],[1294,285],[1298,519],[1296,285],[1297,285],[1301,520],[1299,285],[1300,285],[1305,521],[1302,285],[1303,285],[1304,285],[1307,522],[1306,285],[1309,523],[1308,285],[1313,524],[1310,285],[1311,285],[1312,285],[1318,525],[1314,285],[1315,285],[1316,285],[1317,285],[1321,526],[1319,285],[1320,285],[1324,527],[1322,285],[1323,285],[1326,528],[1325,285],[1328,529],[1327,285],[1330,530],[1329,285],[1332,531],[1331,285],[1336,532],[1333,285],[1334,285],[1335,285],[1342,533],[1337,285],[1338,285],[1339,285],[1340,285],[1341,285],[1345,534],[1343,285],[1344,285],[1348,535],[1346,285],[1347,285],[1351,536],[1349,285],[1350,285],[1353,537],[1352,285],[1356,538],[1354,285],[1355,285],[1359,539],[1357,285],[1358,285],[1361,540],[1360,285],[1363,541],[1362,285],[1365,542],[1364,285],[1367,543],[1366,285],[1369,544],[1368,285],[1371,545],[1370,285],[1373,546],[1372,285],[1377,547],[1374,285],[1375,285],[1376,285],[1379,548],[1378,285],[1382,549],[1380,285],[1381,285],[1385,550],[1383,285],[1384,285],[1387,551],[1386,285],[1389,552],[1388,285],[1392,553],[1390,285],[1391,285],[1395,554],[1393,285],[1394,285],[1397,555],[1396,285],[1399,556],[1398,285],[1402,557],[1400,285],[1401,285],[1404,558],[1403,285],[1409,559],[1405,285],[1406,285],[1407,285],[1408,285],[1412,560],[1410,285],[1411,285],[1415,561],[1413,285],[1414,285],[1419,562],[1416,285],[1417,285],[1418,285],[1421,563],[1420,285],[1423,564],[1422,285],[1425,565],[1424,285],[1428,566],[1426,285],[1427,285],[1430,567],[1429,285],[1436,568],[1431,285],[1432,285],[1433,285],[1434,285],[1435,285],[1440,569],[1437,285],[1438,285],[1439,285],[1443,570],[1441,285],[1442,285],[1445,571],[1444,285],[1448,572],[1446,285],[1447,285],[1450,573],[1449,285],[1452,574],[1451,285],[1454,575],[1453,285],[1456,576],[1455,285],[1460,577],[1457,285],[1458,285],[1459,285],[1463,578],[1461,285],[1462,285],[1466,579],[1464,285],[1465,285],[1468,580],[1467,285],[1470,581],[1469,285],[1473,582],[1471,285],[1472,285],[1475,583],[1474,285],[1478,584],[1476,278],[1477,285],[1480,585],[1479,285],[1482,586],[1483,587],[626,261],[1503,588],[1504,589],[1502,235],[1490,590],[1495,591],[1496,592],[1499,593],[1498,594],[1497,595],[1500,596],[1507,597],[1511,598],[1510,599],[1509,600],[1501,601],[1491,248],[1506,602],[1508,591],[1493,603],[1489,251],[1494,604],[1492,590],[591,605],[560,606],[570,606],[561,606],[571,606],[562,606],[563,606],[578,606],[577,606],[579,606],[580,606],[572,606],[564,606],[573,606],[565,606],[574,606],[566,606],[568,606],[576,607],[569,606],[575,607],[581,607],[567,606],[582,606],[587,606],[588,606],[583,606],[559,16],[589,16],[585,606],[584,606],[586,606],[590,606],[1772,608],[1771,609],[1775,609],[1779,610],[1773,16],[1776,611],[1774,612],[1778,16],[1777,613],[558,614],[1926,615],[597,616],[596,617],[603,618],[605,619],[601,620],[600,621],[604,617],[598,622],[595,623],[606,624],[599,625],[593,16],[594,626],[1928,627],[1927,628],[602,16],[93,629],[448,630],[453,15],[455,631],[225,632],[253,633],[431,634],[248,635],[236,16],[217,16],[223,16],[421,636],[284,637],[224,16],[390,638],[258,639],[259,640],[355,641],[418,642],[373,643],[425,644],[426,645],[424,646],[423,16],[422,647],[255,648],[226,649],[305,16],[306,650],[221,16],[237,651],[227,652],[289,651],[286,651],[210,651],[251,653],[250,16],[430,654],[440,16],[216,16],[331,655],[332,656],[326,52],[476,16],[334,16],[335,657],[327,658],[482,659],[480,660],[475,16],[417,661],[416,16],[474,662],[328,52],[369,663],[367,664],[477,16],[481,16],[479,665],[478,16],[368,666],[469,667],[472,668],[296,669],[295,670],[294,671],[485,52],[293,672],[278,16],[488,16],[1924,673],[1923,16],[491,16],[490,52],[492,674],[206,16],[427,675],[428,676],[429,677],[239,16],[215,678],[205,16],[347,52],[208,679],[346,680],[345,681],[336,16],[337,16],[344,16],[339,16],[342,682],[338,16],[340,683],[343,684],[341,683],[222,16],[213,16],[214,651],[268,685],[269,686],[266,687],[264,688],[265,689],[261,16],[353,657],[375,657],[447,690],[456,691],[460,692],[434,693],[433,16],[281,16],[493,694],[443,695],[329,696],[330,697],[321,698],[311,16],[352,699],[312,700],[354,701],[349,702],[348,16],[350,16],[366,703],[435,704],[436,705],[314,706],[318,707],[309,708],[413,709],[442,710],[288,711],[391,712],[211,713],[441,714],[207,635],[262,16],[270,715],[402,716],[260,16],[401,717],[94,16],[396,718],[238,16],[307,719],[392,16],[212,16],[271,16],[400,720],[220,16],[276,721],[317,722],[432,723],[316,16],[399,16],[263,16],[404,724],[405,725],[218,16],[407,726],[409,727],[408,728],[241,16],[398,713],[411,729],[397,730],[403,731],[229,16],[232,16],[230,16],[234,16],[231,16],[233,16],[235,732],[228,16],[383,733],[382,16],[388,734],[384,735],[387,736],[386,736],[389,734],[385,735],[275,737],[376,738],[439,739],[495,16],[464,740],[466,741],[313,16],[465,742],[437,704],[494,743],[333,704],[219,16],[315,744],[272,745],[273,746],[274,747],[304,748],[412,748],[290,748],[377,749],[291,749],[257,750],[256,16],[381,751],[380,752],[379,753],[378,754],[438,755],[325,756],[363,757],[324,758],[358,759],[362,760],[420,761],[419,762],[415,763],[372,764],[374,765],[371,766],[410,767],[365,16],[452,16],[364,768],[414,16],[277,769],[310,675],[308,770],[279,771],[282,772],[489,16],[280,773],[283,773],[450,16],[449,16],[451,16],[487,16],[285,774],[323,52],[92,16],[370,775],[254,16],[243,776],[319,16],[458,52],[468,777],[303,52],[462,657],[302,778],[445,779],[301,777],[209,16],[470,780],[299,52],[300,52],[292,16],[242,16],[298,781],[297,782],[240,783],[320,148],[287,148],[406,16],[394,784],[393,16],[454,16],[351,785],[322,52],[446,786],[87,52],[90,787],[91,788],[88,52],[89,16],[252,84],[247,789],[246,16],[245,790],[244,16],[444,791],[457,792],[459,793],[461,794],[1925,795],[463,796],[467,797],[501,798],[471,798],[500,799],[473,800],[483,801],[484,802],[486,803],[496,804],[499,678],[498,16],[497,805],[1886,16],[538,16],[592,806],[520,807],[518,808],[519,809],[507,810],[508,808],[515,811],[506,812],[511,813],[521,16],[512,814],[517,815],[523,816],[522,817],[505,818],[513,819],[514,820],[509,821],[516,807],[510,822],[550,823],[549,824],[395,248],[504,16],[1518,16],[1521,16],[1524,16],[1740,825],[1519,826],[1539,827],[1516,828],[1523,829],[1739,830],[1709,831],[1710,832],[1695,833],[1545,834],[1696,833],[1697,835],[1559,836],[1543,16],[1712,837],[1711,835],[1688,833],[1689,835],[1577,838],[1576,839],[1535,840],[1635,841],[1641,842],[1636,843],[1638,844],[1637,845],[1642,846],[1640,833],[1639,833],[1526,16],[1527,847],[1643,848],[1645,849],[1644,850],[1534,851],[1536,840],[1632,16],[1558,852],[1630,853],[1629,854],[1649,855],[1648,856],[1647,857],[1646,835],[1589,858],[1560,851],[1698,835],[1528,835],[1532,859],[1626,860],[1631,861],[1561,862],[1634,863],[1699,843],[1550,864],[1530,865],[1562,866],[1580,867],[1581,868],[1579,835],[1582,869],[1700,833],[1693,870],[1701,835],[1537,871],[1533,872],[1540,873],[1541,874],[1650,16],[1651,875],[1652,876],[1655,877],[1653,878],[1654,835],[1714,879],[1713,835],[1633,880],[1658,881],[1656,835],[1657,882],[1690,883],[1621,884],[1623,885],[1702,835],[1625,886],[1574,887],[1567,873],[1570,888],[1572,889],[1575,890],[1569,891],[1568,835],[1571,892],[1573,893],[1627,894],[1538,16],[1547,895],[1703,896],[1704,897],[1546,16],[1555,898],[1628,899],[1705,835],[1706,835],[1553,858],[1622,897],[1563,900],[1542,901],[1587,902],[1584,902],[1583,903],[1586,904],[1529,905],[1691,906],[1659,907],[1663,908],[1660,909],[1661,835],[1662,910],[1578,911],[1666,912],[1664,873],[1665,833],[1668,913],[1670,914],[1667,880],[1669,915],[1564,16],[1554,907],[1552,916],[1551,917],[1624,918],[1672,919],[1671,873],[1692,920],[1549,921],[1548,16],[1588,922],[1620,923],[1619,924],[1673,833],[1674,880],[1675,925],[1680,926],[1676,835],[1677,835],[1678,880],[1679,927],[1585,835],[1565,16],[1544,928],[1531,835],[1681,873],[1682,833],[1684,929],[1599,835],[1683,833],[1600,930],[1590,931],[1591,932],[1618,933],[1594,934],[1595,935],[1598,936],[1596,937],[1597,938],[1592,939],[1602,940],[1601,941],[1593,835],[1612,942],[1617,943],[1613,944],[1614,945],[1615,946],[1616,947],[1707,948],[1566,949],[1556,950],[1557,951],[1603,952],[1604,952],[1685,16],[1686,953],[1611,954],[1687,955],[1605,954],[1606,954],[1607,956],[1608,952],[1609,957],[1610,958],[1720,959],[1717,833],[1716,833],[1718,833],[1719,833],[1724,960],[1722,961],[1723,962],[1721,880],[1731,833],[1726,880],[1728,16],[1730,963],[1727,964],[1729,965],[1732,966],[1734,967],[1733,968],[1735,969],[1715,16],[1736,970],[1725,16],[1708,835],[1525,971],[1737,972],[1741,972],[1517,16],[1522,827],[1520,973],[1738,974],[1694,975],[1766,976],[1769,977],[1768,977],[1770,978],[1767,979],[1757,16],[1756,16],[1763,980],[1758,981],[1760,982],[1761,983],[1759,983],[1762,984],[1765,985],[526,986],[525,16],[524,16],[527,987],[81,16],[82,16],[13,16],[14,16],[16,16],[15,16],[2,16],[17,16],[18,16],[19,16],[20,16],[21,16],[22,16],[23,16],[24,16],[3,16],[25,16],[26,16],[4,16],[27,16],[31,16],[28,16],[29,16],[30,16],[32,16],[33,16],[34,16],[5,16],[35,16],[36,16],[37,16],[38,16],[6,16],[42,16],[39,16],[40,16],[41,16],[43,16],[7,16],[44,16],[49,16],[50,16],[45,16],[46,16],[47,16],[48,16],[8,16],[54,16],[51,16],[52,16],[53,16],[55,16],[9,16],[56,16],[57,16],[58,16],[60,16],[59,16],[61,16],[62,16],[10,16],[63,16],[64,16],[65,16],[11,16],[66,16],[67,16],[68,16],[69,16],[70,16],[1,16],[71,16],[72,16],[12,16],[76,16],[74,16],[79,16],[78,16],[73,16],[77,16],[75,16],[80,16],[120,988],[130,989],[119,988],[140,990],[111,991],[110,992],[139,805],[133,993],[138,994],[113,995],[127,996],[112,997],[136,998],[108,999],[107,805],[137,1000],[109,1001],[114,1002],[115,16],[118,1002],[105,16],[141,1003],[131,1004],[122,1005],[123,1006],[125,1007],[121,1008],[124,1009],[134,805],[116,1010],[117,1011],[126,1012],[106,216],[129,1004],[128,1002],[132,16],[135,1013],[1920,1014],[529,1015],[1921,1016],[1922,1017]],"affectedFilesPendingEmit":[1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1976,1977,1975,1488,1515,1513,1743,1744,1746,1747,1748,1749,1750,1751,1752,1753,1904,1903,1905,1906,1907,1912,1913,1911,1914,1908,1915,1916,1959,1961,1958,1966,1968,1930,1943,1970,1929,1971,1972,1962,1965,1933,1950,1963,1945,1947,1934,1941,1960,1967,1937,1946,1969,1935,1936,1973,1964,1953,1939,1954,1949,1955,1931,1932,1938,1944,1940,1942,1951,1952,1957,1956,1948,1917,1918,1909,535,1512,1781,1486,611,1783,609,608,607,534,536,1755,1785,1786,1902,1910,1919,610,1900,1514,612,1487,1784,1745,1742,1780,1901,1754,1484,1485,503,1920,529,1922],"version":"5.9.3"} \ No newline at end of file diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000..323d6a4 --- /dev/null +++ b/website/README.md @@ -0,0 +1,27 @@ +# Songs2VID documentation + +Docusaurus site for Songs2VID. + +## Local development + +From the **repo root**: + +```bash +npm run docs:dev +``` + +Or from this folder: + +```bash +npm start -- --port 3001 +``` + +Open http://localhost:3001. + +## Build + +```bash +npm run docs:build +``` + +Static output is written to `build/`. diff --git a/website/docs/api/endpoints.md b/website/docs/api/endpoints.md new file mode 100644 index 0000000..2b22622 --- /dev/null +++ b/website/docs/api/endpoints.md @@ -0,0 +1,420 @@ +--- +sidebar_position: 2 +--- + +# Endpoints + +Set these for the examples below: + +```bash +export BASE_URL="http://localhost:3000" # local / self-hosted app +export API_KEY="s2yt_live_your_key_here" +``` + +Local API docs: with `npm run dev:all` (or `npm run docs:dev`) open [http://localhost:3001/docs/api/overview](http://localhost:3001/docs/api/overview). + +## Discovery + +```bash +curl "$BASE_URL/api/v1" +``` + +Returns the endpoint list and requirements (**no auth**). + +## Upload a file (two-step) + +```bash +curl -X POST "$BASE_URL/api/v1/upload" \ + -H "Authorization: Bearer $API_KEY" \ + -F "file=@cover.jpg" \ + -F "type=image" +``` + +```bash +curl -X POST "$BASE_URL/api/v1/upload" \ + -H "Authorization: Bearer $API_KEY" \ + -F "file=@track1.mp3" \ + -F "type=audio" +``` + +```bash +# Optional: PNG watermark logo +curl -X POST "$BASE_URL/api/v1/upload" \ + -H "Authorization: Bearer $API_KEY" \ + -F "file=@logo.png" \ + -F "type=logo" +``` + +```bash +# Optional: custom watermark font (.ttf / .otf, max 10 MB) +curl -X POST "$BASE_URL/api/v1/upload" \ + -H "Authorization: Bearer $API_KEY" \ + -F "file=@Brand.ttf" \ + -F "type=font" +``` + +### Request fields + +| Field | Required | Notes | +|-------|----------|--------| +| `file` | Yes | Multipart file | +| `type` | Yes | `image` \| `audio` \| `logo` \| `font` | + +### Allowed files (self-hosted) + +| `type` | Formats | Max size | +|--------|---------|----------| +| `image` | JPEG, PNG, WebP, GIF | 500 MB | +| `audio` | MP3, WAV, FLAC (also accepts related MIME types) | 500 MB | +| `logo` | PNG only | 500 MB | +| `font` | `.ttf` / `.otf` | **10 MB** | + +### Response + +```json +{ + "path": "/uploads/.../track.mp3", + "filename": "track.mp3", + "size": 4123456, + "audioTags": { + "title": "Song Title", + "artist": "Artist Name", + "album": "Album", + "genre": "Electronic", + "year": "2024" + } +} +``` + +| Field | Notes | +|-------|--------| +| `path` | Absolute path on the server — pass this into job create | +| `filename` | Original filename | +| `size` | Bytes | +| `audioTags` | Present for MP3 when tags are readable; otherwise `null`. Fields may be omitted when missing in the file | + +Upload the shared cover once (`type=image`), each audio (`type=audio`), optionally a PNG logo (`type=logo`), and optionally a custom font (`type=font`) for text watermarks. + +## Create job from paths (recommended) + +Use the exact `path` strings returned by upload. Add one `items[]` entry per track. + +Self-hosted deployments unlock per-track covers, custom watermarks/fonts, and art-track layouts. Max batch size: **100**. + +```bash +curl -X POST "$BASE_URL/api/v1/jobs" \ + -H "Authorization: Bearer $API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "imagePath": "/uploads/.../cover.jpg", + "items": [{ + "audioPath": "/uploads/.../track.mp3", + "audioFilename": "track.mp3", + "metadata": { + "title": "My Track", + "artist": "My Artist", + "description": "", + "tags": "electronic", + "privacy": "PUBLIC", + "categoryId": "10", + "resolution": "1920x1080", + "notifySubscribers": true, + "madeForKids": false, + "embeddable": true, + "creativeCommons": false, + "includeWatermark": true, + "imagePath": "/uploads/.../track-cover.jpg", + "layout": { + "template": "COVER_LEFT_TEXT_RIGHT", + "blurAmount": 60, + "blurOpacity": 85, + "textPadding": 48, + "titleArtistGap": 12, + "textOffsetX": 0, + "textOffsetY": 0 + }, + "watermark": { + "mode": "text", + "text": "My Label", + "fontKey": "montserrat", + "position": "bottom-right", + "offsetX": 24, + "offsetY": 24 + }, + "playlistId": null + } + }] + }' +``` + +### Success response + +```json +{ + "jobId": "clxxxxxxxx", + "itemCount": 1, + "status": "PENDING", + "playlist": null +} +``` + +`playlist` is set when you pass `createPlaylist` (see [YouTube playlists](#youtube-playlists)). + +### Metadata fields + +| Field | Type | Notes | +|-------|------|--------| +| `title` | string | Video title | +| `artist` | string \| null | On-video artist line (max **80**) | +| `description` | string | YouTube description | +| `tags` | string | Comma-separated (quoted tags supported) | +| `privacy` | string | `PUBLIC` \| `PRIVATE` \| `UNLISTED` | +| `categoryId` | string | YouTube category ID (see below) | +| `resolution` | string | One of the supported values (see below) | +| `notifySubscribers` | boolean | YouTube upload notify flag | +| `madeForKids` | boolean | COPPA / made for kids | +| `embeddable` | boolean | Allow embedding | +| `creativeCommons` | boolean | CC license vs standard YouTube | +| `includeWatermark` | boolean | Apply watermark settings | +| `imagePath` | string \| null | Per-track cover (overrides job `imagePath`) | +| `playlistId` | string \| null | Existing playlist ID | +| `layout` | object | Art-track layout (see below) | +| `watermark` | object | Watermark settings (see below) | + +Snake_case aliases are accepted for layout/watermark fields (e.g. `blur_amount`, `layout_template`). + +### Resolutions + +| Value | Aspect | +|-------|--------| +| `1920x1080` | 16:9 | +| `1280x720` | 16:9 | +| `854x480` | 16:9 | +| `720x720` | 1:1 | +| `640x360` | 16:9 | +| `426x240` | 16:9 | + +Self-hosted allows all of these. + +### YouTube categories + +Pass `categoryId` as a string ID. Common values: + +| ID | Name | +|----|------| +| `1` | Film & Animation | +| `2` | Autos & Vehicles | +| `10` | Music | +| `15` | Pets & Animals | +| `17` | Sports | +| `19` | Travel & Events | +| `20` | Gaming | +| `22` | People & Blogs | +| `23` | Comedy | +| `24` | Entertainment | +| `25` | News & Politics | +| `26` | Howto & Style | +| `27` | Education | +| `28` | Science & Technology | +| `29` | Nonprofits & Activism | + +Official reference: [YouTube Data API — VideoCategories](https://developers.google.com/youtube/v3/docs/videoCategories/list). + +### Watermark fields + +`watermark.position`: `top-left` | `top-right` | `bottom-left` | `bottom-right` | `center`. + +`watermark.mode`: `none` | `default` | `text` | `logo` (logo requires prior `type=logo` upload; set `logoPath`). + +`watermark.offsetX` / `offsetY`: `0`–`200` (default `20`) — pixels from the chosen anchor. + +`watermark.fontKey` (text mode): `system` | `inter` | `montserrat` | `roboto` | `oswald` | `playfair` | `custom`. For `custom`, upload with `type=font` first and set `fontPath` to the returned path. Text max length: **80**. + +For a full walkthrough of composition controls, see [Video editing](../video-editing.md). + +### Art-track layouts + +`metadata.layout.template` (or flat `layout_template` / `layoutTemplate`): + +| Enum | Description | +|------|-------------| +| `COVER_LEFT_TEXT_RIGHT` | Cover left, title & artist right | +| `COVER_TOP_TEXT_BOTTOM` | Cover top, title & artist below | +| `COVER_RIGHT_TEXT_LEFT` | Cover right, title & artist left | +| `CENTERED_COMPACT` | Centered cover + text stack | + +Optional fine-tuning (clamped; camelCase or snake_case): + +| Field | Range | Default | Purpose | +|-------|-------|---------|---------| +| `blurAmount` / `blur_amount` | 0–100 | 55 | Background `boxblur` intensity | +| `blurOpacity` / `blur_opacity` | 0–100 | 100 | Blurred fill vs black | +| `textPadding` / `text_padding` | 16–120 | 48 | Padding around cover and text | +| `titleArtistGap` / `title_artist_gap` | 0–64 | 10 | Space between title and artist | +| `textOffsetX` / `text_offset_x` | −120–120 | 0 | Shift text block horizontally | +| `textOffsetY` / `text_offset_y` | −120–120 | 0 | Shift text block vertically | + +Also set `metadata.artist` (max 80) for the on-video artist line. + +Omit `layout.template` (or use classic letterbox) when you only want a black-padded cover. Free-form cover coordinates (`x`, `y`, `coverX`, …) and layout-level `offsetX`/`offsetY` are **rejected** (use `textOffsetX`/`textOffsetY` instead; watermark offsets stay under `watermark`). + +Invalid template strings return **400**: + +```json +{ "error": "Invalid layout template. Refer to API documentation for valid enum values." } +``` + +## YouTube playlists + +List existing playlists, create a new one, or create one inline when starting a job. Pass `playlistId` in item metadata / batch `defaults`, or use `createPlaylist` to make a playlist and attach all videos to it. + +Privacy may be `public`, `unlisted`, or `private`. If playlist permission was just added, sign out and sign in again so OAuth includes `youtube.force-ssl`. + +YouTube playlist API reference: [Playlists: insert](https://developers.google.com/youtube/v3/docs/playlists/insert). + +```bash +# List playlists +curl "$BASE_URL/api/v1/playlists" \ + -H "Authorization: Bearer $API_KEY" +``` + +```bash +# Create a playlist +curl -X POST "$BASE_URL/api/v1/playlists" \ + -H "Authorization: Bearer $API_KEY" \ + -H "Content-Type: application/json" \ + -d '{"title":"My Album","description":"From Songs2VID","privacy":"unlisted"}' +``` + +```json +{ + "playlistId": "PLxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +} +``` + +Or create one inline with a job / batch request: + +```json +{ + "createPlaylist": { + "title": "My Album", + "description": "Uploaded via Songs2VID", + "privacy": "private" + }, + "defaults": { "privacy": "PUBLIC" }, + "items": [{ "title": "Track One" }] +} +``` + +## One-shot batch (small packs only) + +Upload one cover image and a few audio files in a single multipart request. **Not recommended for large batches** — use two-step if you see FormData parse errors. + +```bash +curl -X POST "$BASE_URL/api/v1/jobs/batch" \ + -H "Authorization: Bearer $API_KEY" \ + -F "image=@cover.jpg" \ + -F "audio=@track1.mp3" \ + -F "audio=@track2.mp3" \ + -F 'metadata={"createPlaylist":{"title":"My Album","privacy":"unlisted"},"defaults":{"privacy":"PUBLIC"},"items":[{"title":"Track One"},{"title":"Track Two"}]}' +``` + +Optional `metadata` JSON supports `defaults` applied to every item and per-item overrides in `items`. Item order should match the order of `audio` files. + +When item metadata is omitted, batch defaults include privacy `PUBLIC`, resolution `1920x1080`, and watermark off unless overridden in `defaults`. + +**Multipart tips** + +- Do not set `Content-Type` manually for multipart; the client must include the boundary +- In Postman: Body → form-data; each audio field key must be exactly `audio` (type File) +- If a file field shows a warning, re-select the file from disk + +## Poll job status + +```bash +curl "$BASE_URL/api/v1/jobs/JOB_ID" \ + -H "Authorization: Bearer $API_KEY" +``` + +```bash +curl "$BASE_URL/api/v1/jobs?limit=10" \ + -H "Authorization: Bearer $API_KEY" +``` + +`GET /api/v1/jobs` accepts `limit` (default **20**, max **100**). + +### Job response + +```json +{ + "id": "clxxxxxxxx", + "status": "PROCESSING", + "createdAt": "2026-07-25T12:00:00.000Z", + "completedAt": null, + "items": [ + { + "id": "clitemxxx", + "audioFilename": "track.mp3", + "title": "My Track", + "description": "", + "tags": "electronic", + "privacy": "PUBLIC", + "categoryId": "10", + "resolution": "1920x1080", + "status": "ENCODING", + "youtubeVideoId": null, + "error": null + } + ] +} +``` + +### Job statuses + +| Status | Meaning | +|--------|---------| +| `PENDING` | Queued; worker has not started | +| `PROCESSING` | At least one item is encoding or uploading | +| `COMPLETED` | All items succeeded | +| `FAILED` | All items failed | +| `PARTIAL` | Mix of completed and failed items | + +### Item statuses + +| Status | Meaning | +|--------|---------| +| `PENDING` | Waiting in the queue | +| `ENCODING` | FFmpeg is building the video | +| `UPLOADING` | Uploading to YouTube | +| `COMPLETED` | Live on YouTube (`youtubeVideoId` set) | +| `FAILED` | Failed (`error` contains a message) | + +### Pipeline notes + +- Each item is encoded, then uploaded; the local MP4 is removed after a successful upload +- Queue retries: **2** attempts with exponential backoff (5s base) +- Worker concurrency: **2** items in parallel +- On item failure, reserved allowance for that item is released + +YouTube upload limits (channel daily caps, etc.) are enforced by Google, not Songs2VID. See [YouTube Data API — Quota and compliance](https://developers.google.com/youtube/v3/guides/quota_and_compliance_audits). + +## HTTP errors + +| Status | When | +|--------|------| +| `400` | Validation error (bad file type, invalid layout, missing fields, bad JSON) | +| `401` | Missing or invalid API key | +| `403` | YouTube not connected, or edition/plan does not allow API features | +| `404` | Job not found | +| `429` | API rate limit exceeded — body includes `retryAfterSeconds`; header `Retry-After` is set | + +Example rate-limit body: + +```json +{ + "error": "API rate limit exceeded. Try again shortly.", + "retryAfterSeconds": 42 +} +``` + +Self-hosted rate limits are effectively unlimited for normal use. See [API overview](./overview.md). diff --git a/website/docs/api/overview.md b/website/docs/api/overview.md new file mode 100644 index 0000000..47067e1 --- /dev/null +++ b/website/docs/api/overview.md @@ -0,0 +1,75 @@ +--- +sidebar_position: 1 +--- + +# API overview + +Programmatic uploads and batch jobs for self-hosted Songs2VID. Generate your API key under **Dashboard → Settings → API access**. + +Keys start with `s2yt_live_` and are shown once at creation. + +## Authentication + +Send the key on every request: + +```http +Authorization: Bearer s2yt_live_your_key_here +``` + +Requirements: + +- `S2VID_EDITION=selfhosted` (Compose sets this by default) +- YouTube channel connected (sign in with Google OAuth that includes YouTube scopes) + +OAuth setup: [Getting started](../getting-started.md) and Google’s [OAuth 2.0 for Web Server Applications](https://developers.google.com/identity/protocols/oauth2/web-server). YouTube scopes/API: [YouTube Data API Overview](https://developers.google.com/youtube/v3/getting-started). + +## Rate limits + +Self-hosted editions use a very high per-account ceiling (effectively unlimited for normal automation). You will rarely see `429`. + +If a limit is hit, the response is **429** with `retryAfterSeconds` and a `Retry-After` header. See [Endpoints — HTTP errors](./endpoints.md#http-errors). + +## Choosing a flow + +### Recommended: two-step (especially 5+ audio files) + +1. Upload each file with `POST /api/v1/upload` +2. Create the job with `POST /api/v1/jobs` (JSON paths) + +This avoids huge multipart bodies. Self-hosted max batch size is **100** tracks per job. + +### One-shot batch: small packs only + +`POST /api/v1/jobs/batch` accepts one cover image and a few audio files in a single multipart request. Large bodies often fail with: + +```text +failed to parse body as FormData +``` + +Prefer two-step for albums or long tracklists. + +### Multipart tips + +- Do not set `Content-Type` manually for multipart; the client must include the boundary +- In Postman: Body → form-data; each audio field key must be exactly `audio` (type File) +- If a file field shows a warning, re-select the file from disk + +## Job lifecycle + +1. Create job → status `PENDING` +2. Worker picks items → `ENCODING` → `UPLOADING` → `COMPLETED` or `FAILED` +3. Job rolls up to `COMPLETED`, `FAILED`, or `PARTIAL` + +Poll with `GET /api/v1/jobs/:id`. Full status tables and response shapes: [Endpoints — Poll job status](./endpoints.md#poll-job-status). + +## Discovery + +```http +GET /api/v1 +``` + +Returns the endpoint list and requirements (no auth). + +## Next + +See [Endpoints](./endpoints.md) for curl examples covering upload, jobs, layouts, watermarks, playlists, batch, resolutions, categories, and errors. For composition concepts (templates, blur, fine-tuning, fonts), see [Video editing](../video-editing.md). diff --git a/website/docs/deploy.md b/website/docs/deploy.md new file mode 100644 index 0000000..396f747 --- /dev/null +++ b/website/docs/deploy.md @@ -0,0 +1,82 @@ +--- +sidebar_position: 4 +--- + +# Production notes + +Self-hosting in production means running the **web app** and the **worker** against shared Postgres, Redis, and upload storage, with a public HTTPS URL for OAuth. + +How you package that (bare metal, systemd, Kubernetes, Docker, a PaaS) is up to you. The Compose files in this repo are **optional examples**, not a required stack. + +## What you must configure + +| Requirement | Notes | +|-------------|--------| +| `S2VID_EDITION=selfhosted` | Unlimited allowance, API, and Pro layout features. Root Compose injects this when you use that example. | +| `NEXTAUTH_URL` | Exact public origin users open (e.g. `https://songs2vid.example.com`), no trailing slash | +| `NEXTAUTH_SECRET` | Strong random secret | +| `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` | OAuth Web client from Google Cloud | +| OAuth redirect URI | `https://YOUR_DOMAIN/api/auth/callback/google` — must match `NEXTAUTH_URL` | +| YouTube Data API v3 | Enabled on the same Google Cloud project | +| Worker process | Same `DATABASE_URL`, `REDIS_URL`, and `UPLOAD_DIR` as the web app | +| Persistent uploads | Shared volume or disk for both web and worker | + +Env reference: [Environment variables](./environment.md). Local setup: [Getting started](./getting-started.md). + +### Google OAuth (required) + +1. Create a project in [Google Cloud Console](https://console.cloud.google.com/) +2. Enable [YouTube Data API v3](https://developers.google.com/youtube/v3/getting-started) +3. Create OAuth 2.0 Web credentials ([guide](https://developers.google.com/identity/protocols/oauth2/web-server)) +4. Add the authorized redirect URI ([URI rules](https://developers.google.com/identity/protocols/oauth2/web-server#uri-validation)): + +```text +https://YOUR_DOMAIN/api/auth/callback/google +``` + +Users sign in with Google; they do not need their own Cloud credentials. + +### After go-live + +1. Open `NEXTAUTH_URL` and sign in +2. Confirm the YouTube channel connects +3. Generate an API key under **Dashboard → Settings → API access** if you automate uploads +4. Run a small test job (dashboard or [API](./api/overview.md)) + +### Common issues + +| Symptom | Check | +|---------|--------| +| OAuth redirect mismatch | Redirect URI must match `NEXTAUTH_URL` + `/api/auth/callback/google` exactly | +| Jobs stuck in `PENDING` | Worker is running and shares Redis + upload storage with web | +| Encode / upload failures | FFmpeg available where the worker runs; disk space for uploads | +| YouTube errors | Channel permissions or Google limits — [YouTube quota & compliance](https://developers.google.com/youtube/v3/guides/quota_and_compliance_audits) | + +Put any reverse proxy you like in front (Caddy, nginx, Traefik, cloud load balancer) and terminate TLS there so `NEXTAUTH_URL` is HTTPS. + +## Optional examples in this repo + +These are starting points only. Adapt or ignore them. + +### Root `docker-compose.yml` + +Builds web + worker + Postgres + Redis with `S2VID_EDITION=selfhosted`. Useful for a quick all-in-one box. App port defaults to `${S2VID_PORT:-3000}`. + +```bash +docker compose up -d --build +``` + +Compose reference: [Docker Compose docs](https://docs.docker.com/compose/). + +### `deploy/songs2vid/` (Caddy sample) + +Sample layout under `deploy/songs2vid/`: Compose services plus a [Caddyfile](https://caddyserver.com/docs/caddyfile) that reverse-proxies the app, optionally serves a static docs build, and optionally puts Prisma Studio behind basic auth. + +Only relevant if you choose Caddy. Useful links: + +- [Caddy documentation](https://caddyserver.com/docs/) +- [Automatic HTTPS](https://caddyserver.com/docs/automatic-https) +- [`reverse_proxy`](https://caddyserver.com/docs/caddyfile/directives/reverse_proxy) +- [`basicauth`](https://caddyserver.com/docs/caddyfile/directives/basicauth) · [`caddy hash-password`](https://caddyserver.com/docs/command-line#caddy-hash-password) + +Edit hostnames in the sample Caddyfile to your domains. Do not commit real basic-auth password hashes. diff --git a/website/docs/environment.md b/website/docs/environment.md new file mode 100644 index 0000000..618d42a --- /dev/null +++ b/website/docs/environment.md @@ -0,0 +1,49 @@ +--- +sidebar_position: 3 +--- + +# Environment variables + +Two files exist on purpose — they are not duplicates you both fill with secrets. + +| File | Role | +|------|------| +| **`.env.example`** | Safe template committed to git. Shows names and placeholders. No real secrets. | +| **`.env`** | Your real local or production secrets. Gitignored. **The app reads only this.** | + +Workflow: copy once (`cp .env.example .env`), then edit **only** `.env`. Leave `.env.example` as the shared checklist. + +## Required for local development + +| Variable | Purpose | +|----------|---------| +| `DATABASE_URL` | Postgres connection string (Docker defaults work out of the box) | +| `REDIS_URL` | Redis for BullMQ and rate limiting | +| `NEXTAUTH_URL` | Public app URL, e.g. `http://localhost:3000` or `https://songs2vid.example.com` | +| `NEXTAUTH_SECRET` | Long random string (e.g. `openssl rand -base64 32`) | +| `GOOGLE_CLIENT_ID` | Google OAuth client ID | +| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | + +Create OAuth credentials in [Google Cloud Console](https://console.cloud.google.com/). Guide: [Setting up OAuth 2.0](https://support.google.com/cloud/answer/6158849). Enable [YouTube Data API v3](https://developers.google.com/youtube/v3/getting-started). + +## Optional + +| Variable | Purpose | +|----------|---------| +| `TOKEN_ENCRYPTION_KEY` | Encrypts YouTube tokens at rest; falls back to `NEXTAUTH_SECRET` if unset | +| `UPLOAD_DIR` | Upload storage path; defaults to `./uploads` (Compose uses `/app/uploads`) | +| `FFMPEG_PATH` | Override bundled `ffmpeg-static` binary | +| `S2VID_EDITION` | Set to `selfhosted` for unlimited video allowance, API access, and all layout features | +| `S2VID_PORT` | Host port for the optional root `docker-compose.yml` example (default `3000`) | +| `NEXT_PUBLIC_GITEA_URL` | Footer / open-source link | +| `NEXT_PUBLIC_GITEA_ISSUES_URL` | Bug report link | +| `NEXT_PUBLIC_DOCKER_HUB_URL` | Docker image link | +| `NEXT_PUBLIC_DOCS_URL` | Docusaurus docs site. Omit locally to use `http://localhost:3001` when `NEXTAUTH_URL` is localhost; production default `https://docs.songs2vid.com` | +| `ADMIN_API_KEY` | Optional Bearer token for internal admin HTTP routes. **Not required** for normal self-hosted operation | + +## Notes + +- User API keys are generated in Dashboard → Settings (hashed at rest). They are not env vars. +- Self-hosted deployments should set `S2VID_EDITION=selfhosted` (the optional root Compose example does this for you). +- In production, `NEXTAUTH_URL` must match the public HTTPS URL users open in the browser, and the same origin must be listed as an OAuth redirect URI (`…/api/auth/callback/google`). See [Production notes](./deploy.md). +- Never commit `.env` or put production secrets in `.env.example`. diff --git a/website/docs/getting-started.md b/website/docs/getting-started.md new file mode 100644 index 0000000..bbd30ff --- /dev/null +++ b/website/docs/getting-started.md @@ -0,0 +1,107 @@ +--- +sidebar_position: 2 +--- + +# Getting started + +Run Songs2VID locally for development or self-hosting. + +## 1. Environment file + +Copy the template, then edit **only** `.env` with your real values: + +```bash +cp .env.example .env +``` + +See [Environment variables](./environment.md) for required vs optional keys. + +## 2. PostgreSQL and Redis + +For local app development (infra only): + +```bash +docker compose -f docker-compose.dev.yml up -d +``` + +Or run the full stack (web + worker + DB) with the self-hosted edition — an optional Compose example: + +```bash +docker compose up -d --build +``` + +Compose is not required; any Postgres + Redis that match your `.env` works. See [Docker Compose](https://docs.docker.com/compose/) if you use the examples above. + +## 3. Install and migrate + +```bash +npm install +npm run db:push +``` + +## 4. Google OAuth + +In [Google Cloud Console](https://console.cloud.google.com/) (server-side only — end users never enter credentials): + +1. Enable [YouTube Data API v3](https://developers.google.com/youtube/v3/getting-started) +2. Create OAuth 2.0 Web credentials ([OAuth 2.0 for web server apps](https://developers.google.com/identity/protocols/oauth2/web-server)) +3. Add an authorized redirect URI ([URI validation](https://developers.google.com/identity/protocols/oauth2/web-server#uri-validation)): + - Local: `http://localhost:3000/api/auth/callback/google` + - Production: `https://YOUR_DOMAIN/api/auth/callback/google` +4. Set `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` in `.env` + +Also set `NEXTAUTH_URL` to the same origin users open in the browser. + +## 5. FFmpeg and fonts + +The worker needs FFmpeg. The `ffmpeg-static` npm package is used by default. Set `FFMPEG_PATH` only if you want a system binary instead. + +For curated watermark fonts (Inter, Montserrat, etc.), ensure files exist under `assets/fonts`: + +```bash +node scripts/fetch-watermark-fonts.mjs +``` + +Custom `.ttf` / `.otf` uploads work without this step. See [Video editing](./video-editing.md). + +## 6. Start app, worker, and docs + +One command for everything: + +```bash +npm run dev:all +``` + +| Process | URL / role | +|---------|------------| +| Next.js app | [http://localhost:3000](http://localhost:3000) | +| BullMQ worker | Encodes videos and uploads to YouTube | +| Docusaurus docs | [http://localhost:3001](http://localhost:3001) | + +Or run them separately: + +```bash +npm run dev +npm run worker +npm run docs:dev +``` + +## Authentication + +Users sign in with Google via OAuth 2.0. The app connects their YouTube channel automatically — end users do not need Google Cloud credentials or API keys. + +## Production + +For public HTTPS, OAuth redirect URIs, and worker checklist, see [Production notes](./deploy.md). Repo Compose/Caddy files there are optional examples only. + +## Useful scripts + +| Script | Purpose | +|--------|---------| +| `npm run dev:all` | App (3000) + worker + docs (3001) together | +| `npm run dev` | Next.js dev server only | +| `npm run worker` | Background job processor only | +| `npm run docs:dev` | Documentation site only (port 3001) | +| `npm run db:push` | Push Prisma schema to the database | +| `npm run build` | Production build | +| `npm run docs:build` | Build the documentation site | diff --git a/website/docs/intro.md b/website/docs/intro.md new file mode 100644 index 0000000..6dc5b97 --- /dev/null +++ b/website/docs/intro.md @@ -0,0 +1,43 @@ +--- +sidebar_position: 1 +slug: /intro +--- + +# Introduction + +**Songs2VID** turns a cover image and one or more audio files into YouTube-ready videos, then uploads them to your channel. + +This documentation is for **self-hosted / open-source** deployments (`S2VID_EDITION=selfhosted`). + +## What you can do + +- Combine one image with multiple tracks in a batch +- Set per-video metadata (title, artist, description, tags, privacy, resolution) +- Art-track layouts with blur backgrounds and fine-tuning (padding, title/artist gap, text offsets) +- Custom watermarks: text or logo, positions/offsets, curated or uploaded fonts +- Unique cover image per track +- Add uploads to YouTube playlists +- Use the REST API for automation + +See [Video editing](./video-editing.md) for composition controls in the dashboard and API. + +## Self-host + +Follow [Getting started](./getting-started.md). Set `S2VID_EDITION=selfhosted` for unlimited video allowance, API access, and all layout features (the optional root Compose example sets this for you). + +For local development, `npm run dev:all` starts the app (port 3000), worker, and this docs site (port 3001). + +Going to a public URL? See [Production notes](./deploy.md) (OAuth redirect, worker, HTTPS). Docker/Caddy samples in the repo are optional. + +## REST API + +Programmatic uploads and job creation. Generate an API key under **Dashboard → Settings → API access**. Start with [API overview](./api/overview.md). + +## Stack + +- Next.js 15 (App Router, TypeScript, Tailwind) +- PostgreSQL + Prisma +- Redis + BullMQ +- NextAuth (Google OAuth with YouTube scopes) +- FFmpeg for encoding +- YouTube Data API v3 diff --git a/website/docs/video-editing.md b/website/docs/video-editing.md new file mode 100644 index 0000000..02d57b3 --- /dev/null +++ b/website/docs/video-editing.md @@ -0,0 +1,130 @@ +--- +sidebar_position: 3 +--- + +# Video editing + +Self-hosted Songs2VID includes a **Layout Studio** on the dashboard upload form: art-track compositions, blur backgrounds, typography, and watermarks with live preview. The same options are available on the [REST API](./api/endpoints.md). + +## Classic vs art-track + +| Mode | Behavior | +|------|----------| +| **Classic** (no template) | Cover letterboxed on a black frame — simple and reliable | +| **Art-track template** | Cover + title/artist arranged by a fixed template, with a blurred cover fill behind | + +Templates are enum-based. Free-form cover coordinates (`x`, `y`, `coverX`, …) are rejected so encoding stays predictable. + +### Templates + +| Template | Layout | +|----------|--------| +| `COVER_LEFT_TEXT_RIGHT` | Cover on the left; title & artist on the right | +| `COVER_TOP_TEXT_BOTTOM` | Cover on top; title & artist below | +| `COVER_RIGHT_TEXT_LEFT` | Cover on the right; title & artist on the left | +| `CENTERED_COMPACT` | Centered cover with a compact title/artist stack | + +Pick a template in the UI under **Composition**, or set `metadata.layout.template` in the API. + +## Title and artist + +Each track can have: + +- **Title** — used on the video and as the YouTube title (often prefilled from the filename) +- **Artist** — drawn under the title on art-track layouts (max 80 characters) + +Artist is especially useful when ID3 tags or your API payload include it. + +## Blur background + +When an art-track template is active, the encoder builds a full-frame background from the cover: + +- **Blur amount** (`blurAmount`, `0`–`100`, default `55`) — FFmpeg `boxblur` intensity +- **Background opacity** (`blurOpacity`, `0`–`100`, default `100`) — how strong the blurred fill is versus solid black (`0` = black, `100` = full blur) + +Use lower opacity for a darker, more subdued frame; higher for a soft wash of the artwork. + +## Fine-tuning + +All values are clamped. These nudge the composition inside the template — they are not free-form canvas placement. + +| Control | Field | Range | Default | What it does | +|---------|-------|-------|---------|--------------| +| Padding | `textPadding` | 16–120 px | 48 | Space around cover and text | +| Title ↔ artist | `titleArtistGap` | 0–64 px | 10 | Vertical gap between title and artist | +| Text horizontal | `textOffsetX` | −120–120 px | 0 | Shift the text block left/right | +| Text vertical | `textOffsetY` | −120–120 px | 0 | Shift the text block up/down | + +In the dashboard, sliders update the live preview. Via API, nest them under `metadata.layout` (camelCase or snake_case aliases are accepted). + +## Per-track covers + +Upload a shared cover for the batch, then optionally set a different image per item (`metadata.imagePath` after uploading with `type=image`). Useful for singles that share an album batch but need distinct artwork. + +## Watermarks + +Modes: + +| Mode | Effect | +|------|--------| +| `none` | No watermark | +| `default` | Built-in Songs2VID branding | +| `text` | Custom text with optional typography | +| `logo` | Custom PNG (upload with `type=logo`, then set `logoPath`) | + +### Position and offset + +- **Position**: `top-left` · `top-right` · `bottom-left` · `bottom-right` · `center` +- **Offsets** (`offsetX` / `offsetY`): `0`–`200` px from the chosen anchor (default `20`) + +### Typography (text mode) + +Curated fonts (bundled under `assets/fonts` after fetch): + +- `system` — FFmpeg default +- `inter` · `montserrat` · `roboto` · `oswald` · `playfair` +- `custom` — your `.ttf` / `.otf` (max 10 MB; upload with `type=font`, set `fontKey: "custom"` and `fontPath`) + +Refresh curated files if missing: + +```bash +node scripts/fetch-watermark-fonts.mjs +``` + +Text length is capped at 80 characters. + +## Dashboard workflow + +1. Add audio (and optional per-track covers) +2. Open **Layout Studio** on a track +3. Choose classic or a template, then tune blur, padding, gaps, and text offsets +4. Configure watermark mode, font, and position +5. Preview updates live; submit to enqueue encoding + +## API + +See [Endpoints](./api/endpoints.md) for curl examples. Layout and watermark objects live under each item’s `metadata`: + +```json +{ + "title": "My Track", + "artist": "My Artist", + "layout": { + "template": "COVER_LEFT_TEXT_RIGHT", + "blurAmount": 60, + "blurOpacity": 85, + "textPadding": 48, + "titleArtistGap": 12, + "textOffsetX": 0, + "textOffsetY": 0 + }, + "watermark": { + "mode": "text", + "text": "My Label", + "fontKey": "montserrat", + "position": "bottom-right", + "offsetX": 24, + "offsetY": 24 + } +} +``` diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts new file mode 100644 index 0000000..4f07bbd --- /dev/null +++ b/website/docusaurus.config.ts @@ -0,0 +1,144 @@ +import {themes as prismThemes} from 'prism-react-renderer'; +import type {Config} from '@docusaurus/types'; +import type * as Preset from '@docusaurus/preset-classic'; + +const config: Config = { + title: 'Songs2VID', + tagline: 'Image + audio to YouTube', + favicon: 'img/favicon.png', + + future: { + v4: true, + }, + + url: 'https://docs.songs2vid.com', + baseUrl: '/', + + organizationName: 'songs2vid', + projectName: 's2yt', + + onBrokenLinks: 'throw', + + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, + + presets: [ + [ + 'classic', + { + docs: { + sidebarPath: './sidebars.ts', + routeBasePath: 'docs', + }, + blog: false, + theme: { + customCss: './src/css/custom.css', + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + image: 'img/docusaurus-social-card.jpg', + colorMode: { + defaultMode: 'dark', + respectPrefersColorScheme: true, + }, + navbar: { + title: '', + logo: { + alt: 'Songs2VID', + src: 'img/logo.png', + href: '/', + }, + items: [ + { + type: 'docSidebar', + sidebarId: 'docsSidebar', + position: 'left', + label: 'Docs', + }, + { + href: 'https://www.songs2vid.com', + label: 'App', + position: 'right', + }, + { + href: 'https://git.atakanozban.com/Songs2VID', + label: 'Gitea', + position: 'right', + }, + ], + }, + footer: { + style: 'dark', + links: [ + { + title: 'Docs', + items: [ + { + label: 'Introduction', + to: '/docs/intro', + }, + { + label: 'Getting started', + to: '/docs/getting-started', + }, + { + label: 'REST API', + to: '/docs/api/overview', + }, + ], + }, + { + title: 'Product', + items: [ + { + label: 'Songs2VID', + href: 'https://www.songs2vid.com', + }, + { + label: 'Docker Hub', + href: 'https://hub.docker.com/r/atakanozban/songs2vid', + }, + { + label: 'Gitea', + href: 'https://git.atakanozban.com/Songs2VID', + }, + { + label: 'Service Status', + href: 'https://status.atakanozban.com/status/2', + }, + ], + }, + { + title: 'Legal', + items: [ + { + label: 'Privacy Policy', + href: 'https://www.songs2vid.com/privacy', + }, + { + label: 'Terms of Service', + href: 'https://www.songs2vid.com/terms', + }, + { + label: 'Refund Policy', + href: 'https://www.songs2vid.com/refund', + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} Songs2VID. Built with Docusaurus.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: ['bash', 'json'], + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/website/package-lock.json b/website/package-lock.json new file mode 100644 index 0000000..23526e2 --- /dev/null +++ b/website/package-lock.json @@ -0,0 +1,19526 @@ +{ + "name": "website", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "website", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/faster": "3.10.2", + "@docusaurus/preset-classic": "3.10.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.10.2", + "@docusaurus/tsconfig": "3.10.2", + "@docusaurus/types": "3.10.2", + "@types/react": "^19.0.0", + "typescript": "~6.0.2" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@11ty/gray-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@11ty/gray-matter/-/gray-matter-1.0.0.tgz", + "integrity": "sha512-7mJJl+wf1AByoT0PknQiQfOPnVNT4fevGrUBVWO4HXsnYn1aQPyRyrELYrNUFleUBM++KzMKN6QaxHPk0t/6/g==", + "license": "MIT", + "dependencies": { + "js-yaml": "^4.1.0", + "kind-of": "^6.0.3", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=11" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.22.0.tgz", + "integrity": "sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.9.tgz", + "integrity": "sha512-4U2JKLMWlDu0CotYyUkWakDxr8AIav3QtIUXXRpfavYN29aVWfzlwJp9T0rPKEf/dO2QCPAUc0Kq1Tj1GJxo2A==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.19.9", + "@algolia/autocomplete-shared": "1.19.9" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.9.tgz", + "integrity": "sha512-6mExC6X7762s2SV3eJy3QOkB8bdMmnUhQ2agvGVDuzwoGyr3PquGSY/0vPQXCfiAiCaXUz1rXn+lwghgSi0l0w==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.19.9" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.9.tgz", + "integrity": "sha512-YosP9Uoek6y/Ur1r1qeogk4biMe/hzkyNcgMCciw0//3XpCM7VlYLSHnyt/vOnEOGhCCc0+3v+unEiH6zz+Z1A==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.56.0.tgz", + "integrity": "sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.56.0.tgz", + "integrity": "sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.56.0.tgz", + "integrity": "sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.56.0.tgz", + "integrity": "sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.56.0.tgz", + "integrity": "sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.56.0.tgz", + "integrity": "sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.56.0.tgz", + "integrity": "sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", + "license": "MIT" + }, + "node_modules/@algolia/ingestion": { + "version": "1.56.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.56.0.tgz", + "integrity": "sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.56.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.56.0.tgz", + "integrity": "sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.56.0.tgz", + "integrity": "sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.56.0.tgz", + "integrity": "sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.56.0.tgz", + "integrity": "sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.56.0.tgz", + "integrity": "sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q==", + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz", + "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz", + "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/traverse": "^7.29.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz", + "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz", + "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.11" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz", + "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz", + "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz", + "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-wrap-function": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz", + "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.29.7", + "@babel/helper-optimise-call-expression": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz", + "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz", + "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.29.7.tgz", + "integrity": "sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.29.7.tgz", + "integrity": "sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.29.7.tgz", + "integrity": "sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-rest-destructuring-rhs-array/-/plugin-bugfix-safari-rest-destructuring-rhs-array-7.29.7.tgz", + "integrity": "sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.29.7.tgz", + "integrity": "sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.29.7.tgz", + "integrity": "sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.29.7.tgz", + "integrity": "sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz", + "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz", + "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz", + "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-remap-async-to-generator": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.29.7.tgz", + "integrity": "sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz", + "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz", + "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz", + "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz", + "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.29.7.tgz", + "integrity": "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/template": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz", + "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.29.7.tgz", + "integrity": "sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.29.7.tgz", + "integrity": "sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.29.7.tgz", + "integrity": "sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.29.7.tgz", + "integrity": "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.29.7.tgz", + "integrity": "sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz", + "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz", + "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.29.7.tgz", + "integrity": "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.29.7.tgz", + "integrity": "sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.29.7.tgz", + "integrity": "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz", + "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.29.7.tgz", + "integrity": "sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.29.7.tgz", + "integrity": "sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz", + "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.7.tgz", + "integrity": "sha512-TM2ZcQLoG2/y4HODiStCo10DibYhWhGWAwVv+EQKmG/7GFl0N+AAmUiXOMKM+aiJ9XBJ9AHVZBvTzMnJ2sM3cQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.29.7.tgz", + "integrity": "sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz", + "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.29.7.tgz", + "integrity": "sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz", + "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.29.7.tgz", + "integrity": "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz", + "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.29.7.tgz", + "integrity": "sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-replace-supers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz", + "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz", + "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz", + "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz", + "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz", + "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.29.7.tgz", + "integrity": "sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.29.7.tgz", + "integrity": "sha512-J0wGhKan+rIiE2OhfhRptySLrJ6SjQYM6b6N1FMlhyhCcw1Mig8vQjWchyB+bgHGDvaWo6Diu6CLRMra2uMtmg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz", + "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz", + "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz", + "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz", + "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz", + "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.29.7.tgz", + "integrity": "sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.29.7.tgz", + "integrity": "sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz", + "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz", + "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.29.7.tgz", + "integrity": "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.29.7.tgz", + "integrity": "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.29.7.tgz", + "integrity": "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.29.7.tgz", + "integrity": "sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz", + "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.29.7", + "@babel/helper-create-class-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", + "@babel/plugin-syntax-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.29.7.tgz", + "integrity": "sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.29.7.tgz", + "integrity": "sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz", + "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.29.7.tgz", + "integrity": "sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.7.tgz", + "integrity": "sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.29.7", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.29.7", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.29.7", + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.7", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.29.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.29.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.29.7", + "@babel/plugin-syntax-import-attributes": "^7.29.7", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.29.7", + "@babel/plugin-transform-async-generator-functions": "^7.29.7", + "@babel/plugin-transform-async-to-generator": "^7.29.7", + "@babel/plugin-transform-block-scoped-functions": "^7.29.7", + "@babel/plugin-transform-block-scoping": "^7.29.7", + "@babel/plugin-transform-class-properties": "^7.29.7", + "@babel/plugin-transform-class-static-block": "^7.29.7", + "@babel/plugin-transform-classes": "^7.29.7", + "@babel/plugin-transform-computed-properties": "^7.29.7", + "@babel/plugin-transform-destructuring": "^7.29.7", + "@babel/plugin-transform-dotall-regex": "^7.29.7", + "@babel/plugin-transform-duplicate-keys": "^7.29.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-dynamic-import": "^7.29.7", + "@babel/plugin-transform-explicit-resource-management": "^7.29.7", + "@babel/plugin-transform-exponentiation-operator": "^7.29.7", + "@babel/plugin-transform-export-namespace-from": "^7.29.7", + "@babel/plugin-transform-for-of": "^7.29.7", + "@babel/plugin-transform-function-name": "^7.29.7", + "@babel/plugin-transform-json-strings": "^7.29.7", + "@babel/plugin-transform-literals": "^7.29.7", + "@babel/plugin-transform-logical-assignment-operators": "^7.29.7", + "@babel/plugin-transform-member-expression-literals": "^7.29.7", + "@babel/plugin-transform-modules-amd": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-modules-systemjs": "^7.29.7", + "@babel/plugin-transform-modules-umd": "^7.29.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.7", + "@babel/plugin-transform-new-target": "^7.29.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.29.7", + "@babel/plugin-transform-numeric-separator": "^7.29.7", + "@babel/plugin-transform-object-rest-spread": "^7.29.7", + "@babel/plugin-transform-object-super": "^7.29.7", + "@babel/plugin-transform-optional-catch-binding": "^7.29.7", + "@babel/plugin-transform-optional-chaining": "^7.29.7", + "@babel/plugin-transform-parameters": "^7.29.7", + "@babel/plugin-transform-private-methods": "^7.29.7", + "@babel/plugin-transform-private-property-in-object": "^7.29.7", + "@babel/plugin-transform-property-literals": "^7.29.7", + "@babel/plugin-transform-regenerator": "^7.29.7", + "@babel/plugin-transform-regexp-modifiers": "^7.29.7", + "@babel/plugin-transform-reserved-words": "^7.29.7", + "@babel/plugin-transform-shorthand-properties": "^7.29.7", + "@babel/plugin-transform-spread": "^7.29.7", + "@babel/plugin-transform-sticky-regex": "^7.29.7", + "@babel/plugin-transform-template-literals": "^7.29.7", + "@babel/plugin-transform-typeof-symbol": "^7.29.7", + "@babel/plugin-transform-unicode-escapes": "^7.29.7", + "@babel/plugin-transform-unicode-property-regex": "^7.29.7", + "@babel/plugin-transform-unicode-regex": "^7.29.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.29.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.2.tgz", + "integrity": "sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8", + "core-js-compat": "^3.48.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.29.7.tgz", + "integrity": "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-transform-react-display-name": "^7.29.7", + "@babel/plugin-transform-react-jsx": "^7.29.7", + "@babel/plugin-transform-react-jsx-development": "^7.29.7", + "@babel/plugin-transform-react-pure-annotations": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz", + "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "@babel/plugin-syntax-jsx": "^7.29.7", + "@babel/plugin-transform-modules-commonjs": "^7.29.7", + "@babel/plugin-transform-typescript": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/cascade-layer-name-parser": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", + "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", + "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/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", + "peer": true, + "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", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "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/postcss-alpha-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz", + "integrity": "sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", + "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz", + "integrity": "sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-function-display-p3-linear": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz", + "integrity": "sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-function": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz", + "integrity": "sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz", + "integrity": "sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-content-alt-text": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz", + "integrity": "sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-contrast-color-function": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz", + "integrity": "sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-exponential-functions": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", + "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", + "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gamut-mapping": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz", + "integrity": "sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-gradients-interpolation-method": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz", + "integrity": "sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz", + "integrity": "sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz", + "integrity": "sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-initial": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", + "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", + "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-light-dark-function": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz", + "integrity": "sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-float-and-clear": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", + "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overflow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", + "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-overscroll-behavior": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", + "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-resize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", + "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-logical-viewport-units": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", + "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-minmax": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", + "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", + "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", + "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.1.tgz", + "integrity": "sha512-TQUGBuRvxdc7TgNSTevYqrL8oItxiwPDixk20qCB5me/W8uF7BPbhRrAvFuhEoywQp/woRsUZ6SJ+sU5idZAIA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz", + "integrity": "sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-position-area-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-position-area-property/-/postcss-position-area-property-1.0.0.tgz", + "integrity": "sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz", + "integrity": "sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-property-rule-prelude-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-property-rule-prelude-list/-/postcss-property-rule-prelude-list-1.0.0.tgz", + "integrity": "sha512-IxuQjUXq19fobgmSSvUDO7fVwijDJaZMvWQugxfEUxmjBeDCVaDuMpsZ31MsTm5xbnhA+ElDi0+rQ7sQQGisFA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-random-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", + "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-relative-color-syntax": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz", + "integrity": "sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", + "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@csstools/postcss-sign-functions": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", + "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", + "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-syntax-descriptor-syntax-production": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-syntax-descriptor-syntax-production/-/postcss-syntax-descriptor-syntax-production-1.0.1.tgz", + "integrity": "sha512-GneqQWefjM//f4hJ/Kbox0C6f2T7+pi4/fqTqOFGTL3EjnvOReTqO1qUQ30CaUjkwjYq9qZ41hzarrAxCc4gow==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-system-ui-font-family": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-system-ui-font-family/-/postcss-system-ui-font-family-1.0.0.tgz", + "integrity": "sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz", + "integrity": "sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", + "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", + "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/utilities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", + "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/core": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.6.3.tgz", + "integrity": "sha512-rUOujwIpxJRgD7+kicVsI3D5sqBvdiRTquzWBpTEXZs8ZXfGbfzpus5HqumaNYTppN2HvH8E2yNuRwYdHJeOlA==", + "license": "MIT", + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/@docsearch/css": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.6.3.tgz", + "integrity": "sha512-nlOwcXcsNAptQl4vlL4MA78qNJKO0Qlds5GuBjCoePgkebTXLSf8Qt1oyZ3YBshYupKXG9VRGEsk1zr23d+bzQ==", + "license": "MIT" + }, + "node_modules/@docsearch/react": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.6.3.tgz", + "integrity": "sha512-Bg2wdDsoQVlNCcEKuEJAU04tvHCqgx8rIu+uIoM4pRtcx3TBKJuXutJik3LTA8LRc9YEyHkrYUrmcC0D7BYf+g==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "1.19.2", + "@docsearch/core": "4.6.3", + "@docsearch/css": "4.6.3" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 20.0.0", + "react": ">= 16.8.0 < 20.0.0", + "react-dom": ">= 16.8.0 < 20.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-core": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", + "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", + "@algolia/autocomplete-shared": "1.19.2" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", + "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-shared": "1.19.2" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/autocomplete-shared": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", + "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", + "license": "MIT", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.10.2.tgz", + "integrity": "sha512-aJ1hpGyvfkte3dDAfNbWM4biW4yWZBVz7TIGLZP+v+tWOBgxX3e0N5ZIXHIvmfNNXTI77pcHUx3KmtOk05Ze3Q==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.10.2", + "@docusaurus/utils": "3.10.2", + "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.10.2.tgz", + "integrity": "sha512-i0ZNcy0f0WhaOlYVgzLsWhIoEXO9kS3HRoKPtgE6vQtZUq7arKZaYdNBudr3mqCmd+TyOkwtwfHgs1ENj07r5g==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.10.2", + "@docusaurus/cssnano-preset": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.3", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.11.0", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.2", + "null-loader": "^4.0.1", + "postcss": "^8.5.4", + "postcss-loader": "^7.3.4", + "postcss-preset-env": "^10.2.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^7.0.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.10.2.tgz", + "integrity": "sha512-EYByj6nk+aD9KeVxV6Hmo2/nAAT79P21Y82ycTBOBtrmqilloIbIEhgL2/8Xpt2Jz/pgNqHAwyusOGwmbKeJmA==", + "license": "MIT", + "dependencies": { + "@docusaurus/babel": "3.10.2", + "@docusaurus/bundler": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "core-js": "^3.31.1", + "detect-port": "^2.1.0", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "execa": "^5.1.1", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "open": "^8.4.0", + "p-map": "^4.0.0", + "prompts": "^2.4.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.3", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.7", + "tinypool": "^1.0.2", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^5.2.2", + "webpack-merge": "^6.0.1" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*", + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.2.tgz", + "integrity": "sha512-4gCnHRbJLTloiwfvFAa92tgb2gI4KYhvjfQVYnEaiMO/EgvWfCo1LwytHXen+1oZAN0VAlS0JAPxp3MsvKDa3A==", + "license": "MIT", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.5.4", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/faster": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/faster/-/faster-3.10.2.tgz", + "integrity": "sha512-p/5E5/RyHv+QWusJMPN5i3OMJTqTgkhuwzVbB1AReDWTUHXQCmf5mlTFzGiDrWeQWIDOKsuOPn1jJh0s9LUOHA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@docusaurus/types": "3.10.2", + "@rspack/core": "^1.7.10", + "@swc/core": "^1.15.40", + "@swc/html": "^1.15.40", + "browserslist": "^4.24.2", + "lightningcss": "^1.27.0", + "semver": "^7.5.4", + "swc-loader": "^0.2.6", + "tslib": "^2.6.0", + "webpack": "^5.95.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.10.2.tgz", + "integrity": "sha512-gSEwqtPfCAnC3ZSJY6xL7tcIfgg0vFD39jbv93eakuweyvO2864xR0K+kmKwBhkTCtWRNjuGGnb5rdmkD/ndqw==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.10.2.tgz", + "integrity": "sha512-9Fd4V/SFjfrVQ0JH5EN0+iPWyFunvTeQE3gfyFeetqPaXMP0OylIjOw16dCuXG4NZJrYdBqwzjh18/h3gRi47w==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^2.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.2.tgz", + "integrity": "sha512-h/I5e4jaAhDHW4vaLENi1i2hnOEnXY1t9R+nnRTbgUl7ymVRzN/HF7dDfj8rKYGj8gfIge+Ef+iYRAMtbGvsrQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.10.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.2.tgz", + "integrity": "sha512-0cbEnNKf0InmLkhj/+nVRmqEnWEoOE8Mh+2x1qOXI0qYpCnphq4RXknVJ8BvybKRXqYVvbmdMfiJSup+k4tm5w==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/theme-common": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "cheerio": "1.0.0-rc.12", + "combine-promises": "^1.1.0", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.2.tgz", + "integrity": "sha512-Sqwl4FPoZBDrlY8I2VU2H8O0M91CHp9T8ToMSkTZmjvHCif+1laqfXi6sTk8IfyVS/trN5yNjcWd1bFsGB6W5Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/module-type-aliases": "3.10.2", + "@docusaurus/theme-common": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "schema-dts": "^1.1.2", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.2.tgz", + "integrity": "sha512-h5R12sZ/vV9EPiVjvIl9YFCOwkpwXes7dQMYt3EvP6Pphu4amHxxTqWxf08Fl5DR8h+oZMbWpFTNw5vKEYfvzQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-css-cascade-layers": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.2.tgz", + "integrity": "sha512-UkdvQby5OQUKWrw3lLnSTJXQ6VETaUVTuPQX9AABtmFm5h+ifEBx1OQ+LN726Q4byuwBf2ElHkf4qU4hTxdvRg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.10.2.tgz", + "integrity": "sha512-8vbZNOSCpnsT57EY6CgN7sgRVmx3KTYwO8Uvo2pbxOyb8tbqAwtT9SslqaQ41HbA1v1hpn5RP7u5s2KvRwAFpQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^2.3.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.2.tgz", + "integrity": "sha512-kMHMBK9j4VAtgd5owwrRLRIi0EjkrpXlX7ePj1+y68XfVZV9I1T4S+koPDm+Hfw2TtnyHvh0uNrDvjz+DjQGVA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.2.tgz", + "integrity": "sha512-Vt90nNFhtAChRe9+it1hcHFgFvETdSnOkL5Bma+p6E/yU2tAYrvvyk+gv+LJGM2ZUkyKuKXLRsZ2Lb0bO7+Vog==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.2.tgz", + "integrity": "sha512-MLCffCldysi/R0nzJQP7ZWd0xAoGNnSTiVOo6TTR6mKVGFhE+/XArGe67ZcaZv1uytgQXoXs92VJrgVDrz80rQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.2.tgz", + "integrity": "sha512-PODkwg5XetLML3hU/3xpCKJUZ9cqExLaBnD/Fzzwj2VHogLeqnDisLIujae87zuze7T4mCm2A6KEqZkyiz07EQ==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/plugin-svgr": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.2.tgz", + "integrity": "sha512-JgfT3jWM0TJ8Uw0cEcqxHpybngQY1vlBYpuuNO+gEh5iPh5Ar+vxq/u9CFrYsWeXy48BN7Db76Pzp2edNXUQ8A==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "@svgr/core": "8.1.0", + "@svgr/webpack": "^8.1.0", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.10.2.tgz", + "integrity": "sha512-a4B3VczmDl99zK0EufDQYomdJ186WDingjmDXxhN2PNPS9Ty/Y2M5CLFX1KQMRKqRTLiRDKfutzG5IY1FC/ceg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/plugin-content-blog": "3.10.2", + "@docusaurus/plugin-content-docs": "3.10.2", + "@docusaurus/plugin-content-pages": "3.10.2", + "@docusaurus/plugin-css-cascade-layers": "3.10.2", + "@docusaurus/plugin-debug": "3.10.2", + "@docusaurus/plugin-google-analytics": "3.10.2", + "@docusaurus/plugin-google-gtag": "3.10.2", + "@docusaurus/plugin-google-tag-manager": "3.10.2", + "@docusaurus/plugin-sitemap": "3.10.2", + "@docusaurus/plugin-svgr": "3.10.2", + "@docusaurus/theme-classic": "3.10.2", + "@docusaurus/theme-common": "3.10.2", + "@docusaurus/theme-search-algolia": "3.10.2", + "@docusaurus/types": "3.10.2" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.10.2.tgz", + "integrity": "sha512-JqTSLQmqmA9uKWZsD5iwBGJ4JyKB4/yTw6PsSXVPRJG/6GAm/u+add9Iip+hvwP12/AnPNztrdxsI14NJW4KeA==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/module-type-aliases": "3.10.2", + "@docusaurus/plugin-content-blog": "3.10.2", + "@docusaurus/plugin-content-docs": "3.10.2", + "@docusaurus/plugin-content-pages": "3.10.2", + "@docusaurus/theme-common": "3.10.2", + "@docusaurus/theme-translations": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.45", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.5.4", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.10.2.tgz", + "integrity": "sha512-R9b/vMpK1yye6hNZTA6x/ivRv+at6GhxnXcxkpzCGzO1R1RwiquqiFg2wMFh6aqlJTpWRFKpFD2TzCDQcyOU0A==", + "license": "MIT", + "dependencies": { + "@docusaurus/mdx-loader": "3.10.2", + "@docusaurus/module-type-aliases": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.2.tgz", + "integrity": "sha512-1msxllyhi/5m77JukXtp5UFnUAriwZIC1oJ7MTnpQpCwLTbclJi5BK5n28CTZuSXpQN2ewbbnqRgAhMM6c6ihg==", + "license": "MIT", + "dependencies": { + "@algolia/autocomplete-core": "^1.19.2", + "@docsearch/react": "^3.9.0 || ^4.3.2", + "@docusaurus/core": "3.10.2", + "@docusaurus/logger": "3.10.2", + "@docusaurus/plugin-content-docs": "3.10.2", + "@docusaurus/theme-common": "3.10.2", + "@docusaurus/theme-translations": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-validation": "3.10.2", + "algoliasearch": "^5.37.0", + "algoliasearch-helper": "^3.26.0", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=20.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.10.2.tgz", + "integrity": "sha512-iv20wrxnyXkY89LM3TzRlzGlt5fIGO5UnaR6UL1ZVfB9RRFjxQFQ6awDrwAc6Km8Y5gD8pInuwYPF+6/TiCxXA==", + "license": "MIT", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/tsconfig": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.10.2.tgz", + "integrity": "sha512-5GiB7h/nFsMFPO9mCqcRNE1yA5TSXXNCshNIgHPL6fCPOjcTDixs6qjQBu8ddkgPcicwCvOA7n3jeK2rGdJk6g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@docusaurus/types": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.10.2.tgz", + "integrity": "sha512-B6rvfwIFSapUqUJjMriZswX13K8l5Z7AcmVE6uTEJpYddQieSTR12DsGaFtcZAIDsQd4p+0WTl0Vc6jmZK0Trw==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/mdast": "^4.0.2", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.10.2.tgz", + "integrity": "sha512-xx0W3eav2uW1NRIpuHJWNwLTC15xPNjU4Uxi9NSnd3swYC96BE3vFiT93SD8s24kmAAWNwgZwfZ2fghGZ01Lcw==", + "license": "MIT", + "dependencies": { + "@11ty/gray-matter": "^1.0.0", + "@docusaurus/logger": "3.10.2", + "@docusaurus/types": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "escape-string-regexp": "^4.0.0", + "execa": "^5.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "p-queue": "^6.6.2", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.10.2.tgz", + "integrity": "sha512-x3Dz6jv6iQKBNjBmVTu8p57abMp/VNTUgKBMgRVXJc5444orBTsArv0+cdfrXTiz/VMmHfDRVkPbL7GH2B7T7w==", + "license": "MIT", + "dependencies": { + "@docusaurus/types": "3.10.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.10.2.tgz", + "integrity": "sha512-sn8unbDfUL585NtR3cwHefPicOyaHvPaX7VD0aOg/siIxUBoKyKKaGEqzJZDS64mM43TnxurkYDtmB1wsJlZsw==", + "license": "MIT", + "dependencies": { + "@docusaurus/logger": "3.10.2", + "@docusaurus/utils": "3.10.2", + "@docusaurus/utils-common": "3.10.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=20.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "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==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.64.0.tgz", + "integrity": "sha512-zs2TAq7Six5jgMuoMNjpspAvOP3mhtgq/k1UyQodEzCtQi/N83y2/y+zcvnZSGp/Rxq96DBN+bValOBQAyn/ew==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "@jsonjoy.com/fs-node-utils": "4.64.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.64.0.tgz", + "integrity": "sha512-nMWOVbkLFyEgmXZih3wyvxA9XpgyyqyfrINMHvEFqhi7uqfRl7c9ERJt6yX7vgMPrB9Uo+OJO+Spa0cFzPD01w==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.64.0", + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "@jsonjoy.com/fs-node-utils": "4.64.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.64.0.tgz", + "integrity": "sha512-dO+NNkODbUli4uV42bcNrrLvq5rE7SNpdZ5TNd0dtbLsAaNK3MDiIC9lUi+brboGoIjW6vd2fB1qao60nrk5xA==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.64.0", + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "@jsonjoy.com/fs-node-utils": "4.64.0", + "@jsonjoy.com/fs-print": "4.64.0", + "@jsonjoy.com/fs-snapshot": "4.64.0", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.64.0.tgz", + "integrity": "sha512-/o7WRFhUWaM/fOrslwLZGnzn4RmRILykn+lAL+mNObqqRNw+CQSiij6hpCeZ+C7buhdoVo7go/OYqzaSUfDYmA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.64.0.tgz", + "integrity": "sha512-WDD9WVs0hb7UAEKTgZW2f66WDrbj7gIIWwpP3spbLyXa0rghtUaFTB8L4gdR3ZCWwiKIsj38/CNijpVmpnuPUw==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.64.0", + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "@jsonjoy.com/fs-node-utils": "4.64.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.64.0.tgz", + "integrity": "sha512-k5Indsx9hWW9xSF7Y6oSKKwtCUNhzZxadub3owhIlitc+iMRVlPPdX2duTKQWBL3qNWpXya8jykgaaWpheeS4w==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "glob-to-regex.js": "^1.0.1" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.64.0.tgz", + "integrity": "sha512-PHZFccchvkhWrwPWHjmVAhbC3vSHCtyZvlZfJJ3ho2bnzl450hXri6/8e6pbkWdH+SkmLXNml0sV8e5HDAfxKw==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.64.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.64.0.tgz", + "integrity": "sha512-oM7UDeL83q6NBzzsfKAsYKXKVXlykKFqqOLh4xZZKAzzROTlInkPbc6LTDGThEOnPiFiUzA7tYziHG9xavd76Q==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.64.0", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/util": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "license": "MIT" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@module-federation/error-codes": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", + "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", + "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/runtime-core": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", + "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", + "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/webpack-bundler-runtime": "0.22.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", + "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", + "license": "MIT" + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", + "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", + "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz", + "integrity": "sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "@peculiar/asn1-x509-attr": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.8.0.tgz", + "integrity": "sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.8.0.tgz", + "integrity": "sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.8.0.tgz", + "integrity": "sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.8.0", + "@peculiar/asn1-pkcs8": "^2.8.0", + "@peculiar/asn1-rsa": "^2.8.0", + "@peculiar/asn1-schema": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.8.0.tgz", + "integrity": "sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.8.0.tgz", + "integrity": "sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.8.0", + "@peculiar/asn1-pfx": "^2.8.0", + "@peculiar/asn1-pkcs8": "^2.8.0", + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "@peculiar/asn1-x509-attr": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.8.0.tgz", + "integrity": "sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz", + "integrity": "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==", + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.8.0.tgz", + "integrity": "sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.8.0.tgz", + "integrity": "sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.3.tgz", + "integrity": "sha512-//0sR/cow/s4ICQaYoAobOl4aU8cjU6x/V24V7XkKotb9+O+3zySIYp146vpaobYHnxa4pZX8NkV54Z5AwbDKA==", + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "license": "MIT" + }, + "node_modules/@rspack/binding": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.7.12.tgz", + "integrity": "sha512-f4HHuLbvuld8Ba4iB/4ibse5XrKxFrgmM3S4P2AOKnPlekAFlBjmltCuaTL/W2ggYvILaVY+YcFXrEH1rrKeQA==", + "license": "MIT", + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.7.12", + "@rspack/binding-darwin-x64": "1.7.12", + "@rspack/binding-linux-arm64-gnu": "1.7.12", + "@rspack/binding-linux-arm64-musl": "1.7.12", + "@rspack/binding-linux-x64-gnu": "1.7.12", + "@rspack/binding-linux-x64-musl": "1.7.12", + "@rspack/binding-wasm32-wasi": "1.7.12", + "@rspack/binding-win32-arm64-msvc": "1.7.12", + "@rspack/binding-win32-ia32-msvc": "1.7.12", + "@rspack/binding-win32-x64-msvc": "1.7.12" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.7.12.tgz", + "integrity": "sha512-rbFprJaJiqrmfy8SHth8EsoRS0wg4bXcucwj9NiMzpGFq14Opw8c04iQ6H9BECYzgmN0PKZ9rh41LdVvhdZe4A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.7.12.tgz", + "integrity": "sha512-jnOp+/UXOJa9xqUb8KXH03sysoO2e4Ij6tw6MqDdmdj8n/A8PQENRPUbW9AwXpPtVDJPus9r4fi7b3+6e4B8Hg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.7.12.tgz", + "integrity": "sha512-C8owWG+yvo7X0oVLIXetkoJhIFBP1LYNcAQqtgLmJnQLQDklGuP83dKC+zISGQWpjawHfZ1ER96vLgoTrxKZdw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.7.12.tgz", + "integrity": "sha512-i51WWI64aRpsfSki6rN0aepPqXkVfS+vZM7+4bWDcmnhUmdMvhIPcYg0QRk3DtyJnu33jqNLM0WHY78k00NyfA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.7.12.tgz", + "integrity": "sha512-MSos0FuPEefqo9V92ULd5hggKG29EkSNg1zDcypy0OkpsKh5pfjVxTLYFXgTcVyFoUQQbdG8zFBzYbwmJ8V4ew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.7.12.tgz", + "integrity": "sha512-JcAMVKXOnjfpC3coWjCFPWD3Yl8RBw6a+IXQQ8mfRlHaHMIiOv8IfZqx15XRxMUn49CtP7Z0Na8iiAg2aKrcfw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-wasm32-wasi": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.7.12.tgz", + "integrity": "sha512-n+ZqP6ZMc0nhOgvadg5VhEs9ojtbES80AcWeFnmGkbzIszvGSO63GKNiRkXtjJ9KFuRzytbbmsCqkUVH+Tywxg==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "1.0.7" + } + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.7.12.tgz", + "integrity": "sha512-8+h5fYDXYdmugbdfZ+D1y8IQ3rv2EhSfyGP7vBe+bjNyaMa4jWrpucmZbtxojUL1AzaeuHbvMdj9UO/gelk/+g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.7.12.tgz", + "integrity": "sha512-cDMGwTRSa2p9fNBVe1wTRkF2AEXZ9ARWW36QeC5CkLaI0Ezz8lvhF2+CSOPnhaQ1O1qtn0L0SF+lFnrY+I7xGQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.7.12.tgz", + "integrity": "sha512-wIqFvlgFqrgUyj/6S/FJcvShnkZOmIeXTfqvheLY67MGq8qd8jb1YimQVKAIrmWB3yuJKUFACI3Ag1UBtEedEA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.7.12.tgz", + "integrity": "sha512-6CwFIHlhRmXfZoMj3v9MZ1SMTPBn+cHVXeMIeaGp5sufqinKsISbsqHu6ZMJu2wDSmZLdmQJX6zLxkhcAUlhkQ==", + "license": "MIT", + "dependencies": { + "@module-federation/runtime-tools": "0.22.0", + "@rspack/binding": "1.7.12", + "@rspack/lite-tapable": "1.1.0" + }, + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.1.0.tgz", + "integrity": "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw==", + "license": "MIT" + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "license": "BSD-3-Clause" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", + "license": "MIT" + }, + "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/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@swc/core": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.43.tgz", + "integrity": "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.27" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.15.43", + "@swc/core-darwin-x64": "1.15.43", + "@swc/core-linux-arm-gnueabihf": "1.15.43", + "@swc/core-linux-arm64-gnu": "1.15.43", + "@swc/core-linux-arm64-musl": "1.15.43", + "@swc/core-linux-ppc64-gnu": "1.15.43", + "@swc/core-linux-s390x-gnu": "1.15.43", + "@swc/core-linux-x64-gnu": "1.15.43", + "@swc/core-linux-x64-musl": "1.15.43", + "@swc/core-win32-arm64-msvc": "1.15.43", + "@swc/core-win32-ia32-msvc": "1.15.43", + "@swc/core-win32-x64-msvc": "1.15.43" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.43.tgz", + "integrity": "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.43.tgz", + "integrity": "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.43.tgz", + "integrity": "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.43.tgz", + "integrity": "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.43.tgz", + "integrity": "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.43.tgz", + "integrity": "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.43.tgz", + "integrity": "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.43.tgz", + "integrity": "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.43.tgz", + "integrity": "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.43.tgz", + "integrity": "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.43.tgz", + "integrity": "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.43.tgz", + "integrity": "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/html": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html/-/html-1.15.43.tgz", + "integrity": "sha512-SKbkbdGi9SDO9cTdV+6H0/AYifnb2nDOlz5BlWxlWMXACV3kmX6WwZDo0bBdyGlO/G4jCVWdR5r84qfotU2now==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@swc/html-darwin-arm64": "1.15.43", + "@swc/html-darwin-x64": "1.15.43", + "@swc/html-linux-arm-gnueabihf": "1.15.43", + "@swc/html-linux-arm64-gnu": "1.15.43", + "@swc/html-linux-arm64-musl": "1.15.43", + "@swc/html-linux-ppc64-gnu": "1.15.43", + "@swc/html-linux-s390x-gnu": "1.15.43", + "@swc/html-linux-x64-gnu": "1.15.43", + "@swc/html-linux-x64-musl": "1.15.43", + "@swc/html-win32-arm64-msvc": "1.15.43", + "@swc/html-win32-ia32-msvc": "1.15.43", + "@swc/html-win32-x64-msvc": "1.15.43" + } + }, + "node_modules/@swc/html-darwin-arm64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-darwin-arm64/-/html-darwin-arm64-1.15.43.tgz", + "integrity": "sha512-+PFbHbeeN+zB0zfvR1V1NmvPriuWPI+sijQXpI+wq/nLIujxvtENWjOKVHgouC9TIN/uKmL2zu9HAq6L6YxnPA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-darwin-x64": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-darwin-x64/-/html-darwin-x64-1.15.43.tgz", + "integrity": "sha512-LQJ2U8Oxcx4T1rRF25y4h+/p05nn58FugTe/uGxC5OT3K83c2MftcSZLYaahOu4GVHRZeS1NI94CkSvQV++TVw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm-gnueabihf": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm-gnueabihf/-/html-linux-arm-gnueabihf-1.15.43.tgz", + "integrity": "sha512-DKIen6DuIRO7Xc5gAbgBT5QyRHJGEGXreIdM1VBosYWTGnnrQ//Hwd7bLD6UbT8X8eU1vqvpXwQ1E24QRqRaBQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.15.43.tgz", + "integrity": "sha512-0AuHiyfcE86CZ/CajFIszLzZVzbM2wn5p01oet8Q9RikflCGwyH79Nv9TrAKD1Cx7juUrONzDk+f2b/x73wLTg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-arm64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-musl/-/html-linux-arm64-musl-1.15.43.tgz", + "integrity": "sha512-TweIdl/g9ugkoiYvcL/qbu+gbglDY3TqNxfXH84WXc4rSqEP20owVlxLya2NjVct8LIP2wDrtutpOwAXWC+Eew==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-ppc64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-ppc64-gnu/-/html-linux-ppc64-gnu-1.15.43.tgz", + "integrity": "sha512-4oue1pB38/W6mbudp+w0q1jbwxuwdbdbaOj85ay0pisCs213WkgP+MPN8Zqa5VVPjQnVk2CTY9kmEc74XQI/sA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-s390x-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-s390x-gnu/-/html-linux-s390x-gnu-1.15.43.tgz", + "integrity": "sha512-/tceMNvAxK70SKUZtcn3X+K0vcElMGk3i8Sz0CmPdtooso8MZ7WfAvVP1qi3TWgh1rpQ3cC+Al3433AHlET6+w==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-x64-gnu": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.15.43.tgz", + "integrity": "sha512-YE7ltlTt5ZFl59GsoHTDrIHnCBY8EDBio66CVj4bqkElFXbE/28xmpVE5ksdGoI5c5aQ/8byUCfHxqzCzQQSVg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-linux-x64-musl": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-musl/-/html-linux-x64-musl-1.15.43.tgz", + "integrity": "sha512-nS20HmbOk+dEEzdosJqqxAeyjMIiS5yrCAti8LUf0+dgr4eRmjkH4MlkjfPjf49aayR8o+eMJ1jsDZ7whx4zog==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-win32-arm64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-win32-arm64-msvc/-/html-win32-arm64-msvc-1.15.43.tgz", + "integrity": "sha512-Yz7aQQhXT/Yc6QcuMDQDZP9jqf2phkVyU+qSu8ZRWEcJgIorrPL6q7YLqMk+MB5PpZyu5XJEODvc1/UVDE1Kyg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-win32-ia32-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-win32-ia32-msvc/-/html-win32-ia32-msvc-1.15.43.tgz", + "integrity": "sha512-muUgfsSQRZk6YBRuhaGKSLvXy0bV9BW6/mHLI0N/06btWuf0hekoHhIzR7dUmS98NXKCA7Hv+buBPE/0vXUwyA==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/html-win32-x64-msvc": { + "version": "1.15.43", + "resolved": "https://registry.npmjs.org/@swc/html-win32-x64-msvc/-/html-win32-x64-msvc-1.15.43.tgz", + "integrity": "sha512-tuLDy4MxPXsLi6jW+ozCdFWO61AoMMnlhePWJxMafefC2Ojm+iILxP2zI2Hgfu6F16y1q7ITdXdpEuqptu5fHw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/types": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.27.tgz", + "integrity": "sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "^1" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.9", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.9.tgz", + "integrity": "sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "license": "MIT" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.14.tgz", + "integrity": "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz", + "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", + "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==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0" + }, + "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/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/accepts/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/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.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/address/-/address-2.0.3.tgz", + "integrity": "sha512-XNAb/a6TCqou+TufU8/u11HCu9x1gYvOoxLwtlXgIqmkrYQADVv6ljyW2zwiPhHz9R1gItAWpuDrdJMmrOBFEA==", + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "5.56.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.56.0.tgz", + "integrity": "sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@algolia/abtesting": "1.22.0", + "@algolia/client-abtesting": "5.56.0", + "@algolia/client-analytics": "5.56.0", + "@algolia/client-common": "5.56.0", + "@algolia/client-insights": "5.56.0", + "@algolia/client-personalization": "5.56.0", + "@algolia/client-query-suggestions": "5.56.0", + "@algolia/client-search": "5.56.0", + "@algolia/ingestion": "1.56.0", + "@algolia/monitoring": "1.56.0", + "@algolia/recommend": "5.56.0", + "@algolia/requester-browser-xhr": "5.56.0", + "@algolia/requester-fetch": "5.56.0", + "@algolia/requester-node-http": "5.56.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.29.2", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.29.2.tgz", + "integrity": "sha512-SaV+rZM3drExb0punEYYjT+sNcH74YFwN8ocjya7IDOyQvKWeQpEaSMVG3+IGTVos+feuatj7ljQ4BXlXdUp3w==", + "license": "MIT", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/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/ansi-align/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/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "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/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "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==", + "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/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "license": "MIT", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz", + "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.8", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz", + "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.8" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/baseline-browser-mapping": { + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/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/body-parser/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/body-parser/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/bonjour-service": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.4.3.tgz", + "integrity": "sha512-2Kd5UYlFUVgAKMTyuBLl6w49wqfOnbxHqmuH0oCl/n7TfAikR0zoowNOP5BU4dfXmm+Vr9JyEN370auSMx+CNg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "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", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, + "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": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "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/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "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/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/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": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/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/cli-table3/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/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "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/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "license": "ISC" + }, + "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/compressible/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/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/compression/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/compression/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/compression/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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "license": "BSD-2-Clause", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", + "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/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "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/copy-text-to-clipboard": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz", + "integrity": "sha512-T6SqyLd1iLuqPA90J5N4cTalrtovCySh58iiZDGJ6FGznbclKh4UI+FGacQSgFzwKG77W7XT5gwbVEbd9cIH1A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/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==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz", + "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-blank-pseudo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", + "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz", + "integrity": "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==", + "license": "ISC", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz", + "integrity": "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", + "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "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-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "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/cssdb": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.9.0.tgz", + "integrity": "sha512-J8jOU/hLjaXcO1LldOLraJSQpfLXRKof0I7mtbRyOy2AAXgqst0x9rlgi2qXeD6d0ou3ZLqcPAMqYVbpCbrxEw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "license": "MIT", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "license": "MIT" + }, + "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/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT" + }, + "node_modules/detect-port": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-2.1.0.tgz", + "integrity": "sha512-epZuWb/6Q62L+nDHJc/hQAqf8pylsqgk3BpZXVBx1CDnr3nkrVNn73Uu1rXcFzkNcc+hkP3whuOg7JZYaQB65Q==", + "license": "MIT", + "dependencies": { + "address": "^2.0.1" + }, + "bin": { + "detect": "dist/commonjs/bin/detect-port.js", + "detect-port": "dist/commonjs/bin/detect-port.js" + }, + "engines": { + "node": ">= 16.0.0" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", + "dependencies": { + "utila": "~0.4" + } + }, + "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-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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/dot-prop/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/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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "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.392", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz", + "integrity": "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/enhanced-resolve": { + "version": "5.24.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.2.tgz", + "integrity": "sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.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/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.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": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", + "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "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==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "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/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "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/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.5", + "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.15.1", + "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/express/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/express/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/express/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/express/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/express/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/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-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==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz", + "integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "peer": true, + "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/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/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==", + "license": "MIT" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/finalhandler/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/finalhandler/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/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "license": "MIT", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "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/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "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/fs-extra": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.6.tgz", + "integrity": "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==", + "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.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/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/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "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-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "license": "ISC" + }, + "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": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regex.js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", + "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "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": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/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/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/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "license": "MIT" + }, + "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-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.7", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.7.tgz", + "integrity": "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==", + "license": "MIT", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "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/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-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.10.tgz", + "integrity": "sha512-RKzRWNPxUZqbuk3BC5mGVJbBnWgr+diEnjJexIOytFbBzDy88Fbh/YvBr3DsNrl1jYAfjWfpATEv0NO35FDuPQ==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "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/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.4.0.tgz", + "integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "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==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "license": "MIT", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz", + "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz", + "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.4", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.4.tgz", + "integrity": "sha512-1RuuER6kmt8K8I3nIWvPZKi5RQCb568ZPyY4Pwjlua+yo+63ZTmIwxLZH0heBmiKN4uxjvCiarDrjaeH84xicQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "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.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "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==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "license": "MIT", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.8.4" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/loader-runner": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", + "integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==", + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "license": "CC0-1.0" + }, + "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/memfs": { + "version": "4.64.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.64.0.tgz", + "integrity": "sha512-Kw72fgY7Wn+sD8KmtNWSafl1dz0UvAsE/PHs3YVfLiaZuA3HxNm9sRLqAu0ATiBGJvME1PxZXbBZPv5GycDeAw==", + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.64.0", + "@jsonjoy.com/fs-fsa": "4.64.0", + "@jsonjoy.com/fs-node": "4.64.0", + "@jsonjoy.com/fs-node-builtins": "4.64.0", + "@jsonjoy.com/fs-node-to-fsa": "4.64.0", + "@jsonjoy.com/fs-node-utils": "4.64.0", + "@jsonjoy.com/fs-print": "4.64.0", + "@jsonjoy.com/fs-snapshot": "4.64.0", + "@jsonjoy.com/json-pack": "^1.11.0", + "@jsonjoy.com/util": "^1.9.0", + "glob-to-regex.js": "^1.0.1", + "thingies": "^2.5.0", + "tree-dump": "^1.0.3", + "tslib": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/merge-descriptors": { + "version": "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/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.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.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "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/mini-css-extract-plugin": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.10.2.tgz", + "integrity": "sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==", + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/minimizer-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/minimizer-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "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/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/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, + "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/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "peer": true, + "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/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/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==", + "license": "MIT" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "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/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "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/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/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "license": "MIT", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", + "license": "ISC" + }, + "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/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/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "license": "(WTFPL OR MIT)" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkijs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", + "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "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", + "peer": true, + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", + "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz", + "integrity": "sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", + "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", + "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-custom-media": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", + "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-properties": { + "version": "14.0.6", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", + "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", + "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/cascade-layer-name-parser": "^2.0.5", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", + "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz", + "integrity": "sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", + "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-focus-within": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", + "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", + "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-image-set-function": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", + "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/utilities": "^2.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-lab-function": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz", + "integrity": "sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/utilities": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", + "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "license": "MIT", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nesting": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", + "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/selector-resolve-nested": "^3.1.0", + "@csstools/selector-specificity": "^5.0.0", + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", + "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "peer": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", + "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "license": "MIT", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", + "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", + "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-preset-env": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.6.1.tgz", + "integrity": "sha512-yrk74d9EvY+W7+lO9Aj1QmjWY9q5NsKjK2V9drkOPZB/X6KZ0B3igKsHUYakb7oYVhnioWypQX3xGuePf89f3g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "@csstools/postcss-alpha-function": "^1.0.1", + "@csstools/postcss-cascade-layers": "^5.0.2", + "@csstools/postcss-color-function": "^4.0.12", + "@csstools/postcss-color-function-display-p3-linear": "^1.0.1", + "@csstools/postcss-color-mix-function": "^3.0.12", + "@csstools/postcss-color-mix-variadic-function-arguments": "^1.0.2", + "@csstools/postcss-content-alt-text": "^2.0.8", + "@csstools/postcss-contrast-color-function": "^2.0.12", + "@csstools/postcss-exponential-functions": "^2.0.9", + "@csstools/postcss-font-format-keywords": "^4.0.0", + "@csstools/postcss-gamut-mapping": "^2.0.11", + "@csstools/postcss-gradients-interpolation-method": "^5.0.12", + "@csstools/postcss-hwb-function": "^4.0.12", + "@csstools/postcss-ic-unit": "^4.0.4", + "@csstools/postcss-initial": "^2.0.1", + "@csstools/postcss-is-pseudo-class": "^5.0.3", + "@csstools/postcss-light-dark-function": "^2.0.11", + "@csstools/postcss-logical-float-and-clear": "^3.0.0", + "@csstools/postcss-logical-overflow": "^2.0.0", + "@csstools/postcss-logical-overscroll-behavior": "^2.0.0", + "@csstools/postcss-logical-resize": "^3.0.0", + "@csstools/postcss-logical-viewport-units": "^3.0.4", + "@csstools/postcss-media-minmax": "^2.0.9", + "@csstools/postcss-media-queries-aspect-ratio-number-values": "^3.0.5", + "@csstools/postcss-nested-calc": "^4.0.0", + "@csstools/postcss-normalize-display-values": "^4.0.1", + "@csstools/postcss-oklab-function": "^4.0.12", + "@csstools/postcss-position-area-property": "^1.0.0", + "@csstools/postcss-progressive-custom-properties": "^4.2.1", + "@csstools/postcss-property-rule-prelude-list": "^1.0.0", + "@csstools/postcss-random-function": "^2.0.1", + "@csstools/postcss-relative-color-syntax": "^3.0.12", + "@csstools/postcss-scope-pseudo-class": "^4.0.1", + "@csstools/postcss-sign-functions": "^1.1.4", + "@csstools/postcss-stepped-value-functions": "^4.0.9", + "@csstools/postcss-syntax-descriptor-syntax-production": "^1.0.1", + "@csstools/postcss-system-ui-font-family": "^1.0.0", + "@csstools/postcss-text-decoration-shorthand": "^4.0.3", + "@csstools/postcss-trigonometric-functions": "^4.0.9", + "@csstools/postcss-unset-value": "^4.0.0", + "autoprefixer": "^10.4.23", + "browserslist": "^4.28.1", + "css-blank-pseudo": "^7.0.1", + "css-has-pseudo": "^7.0.3", + "css-prefers-color-scheme": "^10.0.0", + "cssdb": "^8.6.0", + "postcss-attribute-case-insensitive": "^7.0.1", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^7.0.12", + "postcss-color-hex-alpha": "^10.0.0", + "postcss-color-rebeccapurple": "^10.0.0", + "postcss-custom-media": "^11.0.6", + "postcss-custom-properties": "^14.0.6", + "postcss-custom-selectors": "^8.0.5", + "postcss-dir-pseudo-class": "^9.0.1", + "postcss-double-position-gradients": "^6.0.4", + "postcss-focus-visible": "^10.0.1", + "postcss-focus-within": "^9.0.1", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^6.0.0", + "postcss-image-set-function": "^7.0.0", + "postcss-lab-function": "^7.0.12", + "postcss-logical": "^8.1.0", + "postcss-nesting": "^13.0.2", + "postcss-opacity-percentage": "^3.0.0", + "postcss-overflow-shorthand": "^6.0.0", + "postcss-page-break": "^3.0.4", + "postcss-place": "^10.0.0", + "postcss-pseudo-class-any-link": "^10.0.1", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^8.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", + "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "license": "MIT", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", + "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "license": "MIT", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "license": "ISC" + }, + "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-addr/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/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/pupa": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", + "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==", + "license": "MIT", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", + "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/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/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "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/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/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet-async": { + "name": "@slorber/react-helmet-async", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-json-view-lite": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz", + "integrity": "sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.3.tgz", + "integrity": "sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "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": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz", + "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==", + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^3.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", + "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", + "license": "MIT" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/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/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/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/schema-dts": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", + "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", + "license": "Apache-2.0" + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", + "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", + "license": "MIT", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", + "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", + "license": "MIT", + "dependencies": { + "@peculiar/x509": "^1.14.2", + "pkijs": "^3.3.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/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/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.5", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/serve-index": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.8.0", + "mime-types": "~2.1.35", + "parseurl": "~1.3.3" + }, + "engines": { + "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-index/node_modules/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/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "license": "MIT" + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "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/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/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sitemap": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.3.tgz", + "integrity": "sha512-tAjEd+wt/YwnEbfNB2ht51ybBJxbEWwe5ki/Z//Wh0rpBFTCUSj46GnxUKEWzhfuJTsee8x3lybHxFgUMig2hw==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "license": "MIT", + "engines": { + "node": ">= 6.3.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==", + "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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "license": "MIT" + }, + "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-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.4.tgz", + "integrity": "sha512-GsNRis4e8jxn2Y9ENz/8lbJ93CstG8svtMnuRaHbiF2LTJ5tK0/q3t/URPq9Zc7zVWBJnNnJMIp6bevK7bSmNg==", + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/swc-loader": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz", + "integrity": "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w==", + "license": "MIT", + "dependencies": { + "@swc/counter": "^0.1.3" + }, + "peerDependencies": { + "@swc/core": "^1.2.147", + "webpack": ">=2" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz", + "integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/thingies": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", + "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", + "license": "MIT", + "engines": { + "node": ">=10.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "license": "MIT" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-dump": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", + "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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", + "peer": true + }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "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/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/type-is/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/type-is/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/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "devOptional": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "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/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "license": "BSD-2-Clause", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "peer": true, + "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/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/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==", + "license": "MIT" + }, + "node_modules/url-loader/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/url-loader/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/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "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/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", + "license": "MIT" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "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/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", + "license": "MIT" + }, + "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/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.108.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.4.tgz", + "integrity": "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.22.2", + "es-module-lexer": "^2.1.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "graceful-fs": "^4.2.11", + "loader-runner": "^4.3.2", + "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.0" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", + "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.43.1", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.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/webpack-dev-middleware/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.6.tgz", + "integrity": "sha512-HNLRmamRvVavZQ+avceZifmv8hmdUjg43t6MI4SqJDwFdW7RPQwH5vzGhDRZSX59SgfbeHhLnq3g+uooWo7pVw==", + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.25", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.8.1", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.22.1", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.14.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^5.5.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "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/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/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/webpackbar": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-7.0.0.tgz", + "integrity": "sha512-aS9soqSO2iCHgqHoCrj4LbfGQUboDCYJPSFOAchEK+9psIjNrfSWW4Y0YEz67MKURNvMmfo0ycOg9d/+OOf9/Q==", + "license": "MIT", + "dependencies": { + "ansis": "^3.2.0", + "consola": "^3.2.3", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@rspack/core": "*", + "webpack": "3 || 4 || 5" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/websocket-driver": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz", + "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.12", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.12.tgz", + "integrity": "sha512-1xGnbYN3zbog9CwuNDQULNRrTCLIn46/WmpR1f0w6PsCYQHkylZr5vkd6kfMZYV6pRnQkcPNRyiA8LsrNKyhpg==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wsl-utils/node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..4e43af3 --- /dev/null +++ b/website/package.json @@ -0,0 +1,49 @@ +{ + "name": "website", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.10.2", + "@docusaurus/faster": "3.10.2", + "@docusaurus/preset-classic": "3.10.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.10.2", + "@docusaurus/tsconfig": "3.10.2", + "@docusaurus/types": "3.10.2", + "@types/react": "^19.0.0", + "typescript": "~6.0.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=20.0" + } +} diff --git a/website/sidebars.ts b/website/sidebars.ts new file mode 100644 index 0000000..d678603 --- /dev/null +++ b/website/sidebars.ts @@ -0,0 +1,20 @@ +import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; + +const sidebars: SidebarsConfig = { + docsSidebar: [ + { + type: 'category', + label: 'Guides', + collapsed: false, + items: ['intro', 'getting-started', 'video-editing', 'environment', 'deploy'], + }, + { + type: 'category', + label: 'REST API', + collapsed: false, + items: ['api/overview', 'api/endpoints'], + }, + ], +}; + +export default sidebars; diff --git a/website/src/css/custom.css b/website/src/css/custom.css new file mode 100644 index 0000000..c23e479 --- /dev/null +++ b/website/src/css/custom.css @@ -0,0 +1,26 @@ +/** + * Songs2VID docs theme accent aligned with the main app (#4a9eff). + */ + +:root { + --ifm-color-primary: #3b82f6; + --ifm-color-primary-dark: #2563eb; + --ifm-color-primary-darker: #1d4ed8; + --ifm-color-primary-darkest: #1e40af; + --ifm-color-primary-light: #60a5fa; + --ifm-color-primary-lighter: #93c5fd; + --ifm-color-primary-lightest: #bfdbfe; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +[data-theme='dark'] { + --ifm-color-primary: #4a9eff; + --ifm-color-primary-dark: #3b8eef; + --ifm-color-primary-darker: #2f7fd9; + --ifm-color-primary-darkest: #2563b0; + --ifm-color-primary-light: #6bb0ff; + --ifm-color-primary-lighter: #8cc2ff; + --ifm-color-primary-lightest: #add4ff; + --docusaurus-highlighted-code-line-bg: rgba(74, 158, 255, 0.15); +} diff --git a/website/src/pages/index.module.css b/website/src/pages/index.module.css new file mode 100644 index 0000000..9f71a5d --- /dev/null +++ b/website/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx new file mode 100644 index 0000000..c902da2 --- /dev/null +++ b/website/src/pages/index.tsx @@ -0,0 +1,58 @@ +import type {ReactNode} from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import Heading from '@theme/Heading'; + +import styles from './index.module.css'; + +function HomepageHeader() { + const {siteConfig} = useDocusaurusContext(); + return ( +
      +
      + + {siteConfig.title} + +

      {siteConfig.tagline}

      +
      + + Read the docs + +
      +
      +
      + ); +} + +export default function Home(): ReactNode { + return ( + + +
      +
      +
      +
      + Get started +

      Run Postgres, Redis, OAuth, and the worker locally.

      + Getting started → +
      +
      + Video editing +

      Art-track layouts, blur, typography, and watermark fine-tuning.

      + Composition guide → +
      +
      + REST API +

      Upload, jobs, batch, layouts, and playlists.

      + API overview → +
      +
      +
      +
      +
      + ); +} diff --git a/website/src/pages/markdown-page.mdx b/website/src/pages/markdown-page.mdx new file mode 100644 index 0000000..9756c5b --- /dev/null +++ b/website/src/pages/markdown-page.mdx @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/website/src/theme/Logo/index.tsx b/website/src/theme/Logo/index.tsx new file mode 100644 index 0000000..4bf421b --- /dev/null +++ b/website/src/theme/Logo/index.tsx @@ -0,0 +1,36 @@ +import React, {type ReactNode} from 'react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import {useThemeConfig} from '@docusaurus/theme-common'; +import type {Props} from '@theme/Logo'; + +import styles from './styles.module.css'; + +export default function Logo(props: Props): ReactNode { + const { + navbar: {logo}, + } = useThemeConfig(); + + const {imageClassName: _imageClassName, titleClassName: _titleClassName, ...propsRest} = + props; + const logoLink = useBaseUrl(logo?.href || '/'); + + return ( + + + + Songs + 2VID + + + + + ); +} diff --git a/website/src/theme/Logo/styles.module.css b/website/src/theme/Logo/styles.module.css new file mode 100644 index 0000000..285e669 --- /dev/null +++ b/website/src/theme/Logo/styles.module.css @@ -0,0 +1,51 @@ +.brand { + display: inline-flex; + align-items: center; + margin-right: 1rem; + text-decoration: none !important; +} + +.wordmarkWrap { + position: relative; + display: inline-flex; + align-items: baseline; + padding-right: 0.15rem; +} + +.wordmark { + display: inline-flex; + align-items: baseline; + font-size: 1.5rem; + font-weight: 700; + letter-spacing: -0.025em; + line-height: 1; +} + +.beta { + position: absolute; + left: 100%; + top: 0; + margin-left: 0.2rem; + transform: translateY(-45%); + font-size: 0.55rem; + font-weight: 700; + letter-spacing: 0.04em; + line-height: 1; + text-transform: uppercase; + color: #f87171; + pointer-events: none; + user-select: none; + white-space: nowrap; +} + +.songs { + color: #ffffff; +} + +.yt { + color: #f87171; +} + +[data-theme='light'] .songs { + color: #111827; +} diff --git a/website/static/.nojekyll b/website/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/website/static/img/docusaurus-social-card.jpg b/website/static/img/docusaurus-social-card.jpg new file mode 100644 index 0000000..ffcb448 Binary files /dev/null and b/website/static/img/docusaurus-social-card.jpg differ diff --git a/website/static/img/docusaurus.png b/website/static/img/docusaurus.png new file mode 100644 index 0000000..f458149 Binary files /dev/null and b/website/static/img/docusaurus.png differ diff --git a/website/static/img/favicon.ico b/website/static/img/favicon.ico new file mode 100644 index 0000000..dc0557d Binary files /dev/null and b/website/static/img/favicon.ico differ diff --git a/website/static/img/favicon.png b/website/static/img/favicon.png new file mode 100644 index 0000000..e77737f Binary files /dev/null and b/website/static/img/favicon.png differ diff --git a/website/static/img/favicon.svg b/website/static/img/favicon.svg new file mode 100644 index 0000000..50509a2 --- /dev/null +++ b/website/static/img/favicon.svg @@ -0,0 +1,23 @@ + + + S2 + + YT + diff --git a/website/static/img/logo.png b/website/static/img/logo.png new file mode 100644 index 0000000..09e67cb Binary files /dev/null and b/website/static/img/logo.png differ diff --git a/website/static/img/logo.svg b/website/static/img/logo.svg new file mode 100644 index 0000000..9db6d0d --- /dev/null +++ b/website/static/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/static/img/undraw_docusaurus_mountain.svg b/website/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 0000000..af961c4 --- /dev/null +++ b/website/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/img/undraw_docusaurus_react.svg b/website/static/img/undraw_docusaurus_react.svg new file mode 100644 index 0000000..94b5cf0 --- /dev/null +++ b/website/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/static/img/undraw_docusaurus_tree.svg b/website/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 0000000..d9161d3 --- /dev/null +++ b/website/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/tsconfig.json b/website/tsconfig.json new file mode 100644 index 0000000..405d777 --- /dev/null +++ b/website/tsconfig.json @@ -0,0 +1,12 @@ +// This file is not used by "docusaurus start/build" commands. +// It is here to improve your IDE experience (type-checking, autocompletion...), +// and can also run the package.json "typecheck" script manually. +{ + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": ".", + "ignoreDeprecations": "6.0", + "strict": true + }, + "exclude": [".docusaurus", "build"] +} diff --git a/worker/index.ts b/worker/index.ts index 0c573fb..c57c9a9 100644 --- a/worker/index.ts +++ b/worker/index.ts @@ -1,14 +1,15 @@ import { Worker } from "bullmq"; import path from "path"; import { JobItemStatus, JobStatus } from "@prisma/client"; -import { QUEUE_NAME } from "./lib/constants"; -import { prisma } from "./lib/db"; -import { cleanupFiles, encodeVideo } from "./lib/ffmpeg/encode"; -import { getRedisConnection } from "./lib/queue/client"; -import { incrementQuota } from "./lib/quota"; -import { getJobDir } from "./lib/storage"; -import type { VideoJobData } from "./lib/types"; -import { uploadToYouTube } from "./lib/youtube/upload"; +import { QUEUE_NAME } from "../lib/constants"; +import { prisma } from "../lib/db"; +import { cleanupFiles, encodeVideo, getFfmpegPath } from "../lib/ffmpeg/encode"; +import { getRedisConnection } from "../lib/queue/client"; +import { releaseReservation } from "../lib/quota"; +import { getJobDir } from "../lib/storage"; +import type { VideoJobData } from "../lib/types"; +import { formatYouTubeErrorForUser } from "../lib/youtube/errors"; +import { uploadToYouTube } from "../lib/youtube/upload"; async function updateJobStatus(jobId: string) { const items = await prisma.jobItem.findMany({ where: { jobId } }); @@ -30,7 +31,6 @@ async function updateJobStatus(jobId: string) { completedAt: completed + failed === total ? new Date() : null, }, }); - } async function processJobItem(data: VideoJobData) { @@ -39,6 +39,18 @@ async function processJobItem(data: VideoJobData) { include: { job: true }, }); + if (item.job.userId !== data.userId || item.jobId !== data.jobId) { + const message = "Job ownership mismatch"; + console.error(`[security] ${message} for item ${item.id}`); + await prisma.jobItem.update({ + where: { id: item.id }, + data: { status: JobItemStatus.FAILED, error: message }, + }); + await releaseReservation(item.job.userId, item.billingSource, 1).catch(() => {}); + await updateJobStatus(item.jobId); + throw new Error(message); + } + const jobDir = getJobDir(data.userId, data.jobId); const outputPath = path.join(jobDir, `${item.id}.mp4`); @@ -53,11 +65,51 @@ async function processJobItem(data: VideoJobData) { }); await encodeVideo({ - imagePath: item.job.imagePath, + imagePath: item.itemImagePath || item.job.imagePath, audioPath: item.audioPath, outputPath, resolution: item.resolution, includeWatermark: item.includeWatermark, + songTitle: item.songTitle || item.title, + artist: item.artist, + layout: item.layoutTemplate + ? { + template: item.layoutTemplate as + | "COVER_LEFT_TEXT_RIGHT" + | "COVER_TOP_TEXT_BOTTOM" + | "COVER_RIGHT_TEXT_LEFT" + | "CENTERED_COMPACT", + blurAmount: item.blurAmount ?? 55, + blurOpacity: item.blurOpacity ?? 100, + textPadding: item.textPadding ?? 48, + titleArtistGap: item.titleArtistGap ?? 10, + textOffsetX: item.textOffsetX ?? 0, + textOffsetY: item.textOffsetY ?? 0, + } + : null, + watermark: { + mode: (item.watermarkMode as "none" | "default" | "text" | "logo") || "default", + text: item.watermarkText, + logoPath: item.watermarkLogoPath, + fontKey: (item.watermarkFontKey as + | "system" + | "custom" + | "inter" + | "montserrat" + | "roboto" + | "oswald" + | "playfair") || "system", + fontPath: item.watermarkFontPath, + position: + (item.watermarkPosition as + | "top-left" + | "top-right" + | "bottom-left" + | "bottom-right" + | "center") || "bottom-right", + offsetX: item.watermarkOffsetX ?? 20, + offsetY: item.watermarkOffsetY ?? 20, + }, }); await prisma.jobItem.update({ @@ -72,18 +124,21 @@ async function processJobItem(data: VideoJobData) { data: { status: JobItemStatus.COMPLETED, youtubeVideoId, + error: null, }, }); - await incrementQuota(data.userId, 1); + // Quota was reserved at job creation; do not increment again on success. await cleanupFiles([outputPath]); } catch (err) { - const message = err instanceof Error ? err.message : "Unknown error"; + const message = formatYouTubeErrorForUser(err); + console.error(`[youtube] Job item ${item.id} ("${item.title}") failed: ${message}`); await prisma.jobItem.update({ where: { id: item.id }, data: { status: JobItemStatus.FAILED, error: message }, }); - throw err; + await releaseReservation(data.userId, item.billingSource, 1).catch(() => {}); + throw new Error(message); } finally { await updateJobStatus(data.jobId); } @@ -108,4 +163,4 @@ worker.on("failed", (job, err) => { console.error(`Job item ${job?.data.jobItemId} failed:`, err.message); }); -console.log("s2yt worker started, waiting for jobs..."); +console.log(`Songs2VID worker started (ffmpeg: ${getFfmpegPath()}), waiting for jobs...`);