From c420711caa70619a733e1437f36562004b646aab Mon Sep 17 00:00:00 2001 From: cpengilly <29023967+cpengilly@users.noreply.github.com> Date: Fri, 21 Feb 2025 20:51:48 -0800 Subject: [PATCH 1/5] metadata-keyword-generator - metadata keyword generator for page front matter - has some automation functionality built in - set to only run on active files in the PR to allow us to slowly update using smaller PRs - provides suggestions in coderabbit - details are in notes/metadata-update.md --- .circleci/config.yml | 13 +- .coderabbit.yaml | 28 ++ keywords.config.yaml | 237 ++++++++++++ notes/README.md | 6 + notes/metadata-update.md | 203 ++++++++++ package.json | 12 +- pnpm-lock.yaml | 14 +- tsconfig.json | 13 +- utils/metadata-analyzer.ts | 683 ++++++++++++++++++++++++++++++++++ utils/metadata-batch-cli.ts | 211 +++++++++++ utils/metadata-manager.ts | 168 +++++++++ utils/types/metadata-types.ts | 119 ++++++ 12 files changed, 1696 insertions(+), 11 deletions(-) create mode 100644 keywords.config.yaml create mode 100644 notes/metadata-update.md create mode 100644 utils/metadata-analyzer.ts create mode 100644 utils/metadata-batch-cli.ts create mode 100644 utils/metadata-manager.ts create mode 100644 utils/types/metadata-types.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index bac82b6b8..18428c09a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -65,14 +65,25 @@ jobs: name: Run breadcrumb check command: pnpm check-breadcrumbs lint: - description: Lint Markdown files + description: Lint Markdown files and validate metadata executor: ubuntu steps: - checkout - setup-node + - run: + name: Get changed files + command: | + if [ -n "$CIRCLE_PULL_REQUEST" ]; then + PR_NUMBER=$(echo $CIRCLE_PULL_REQUEST | rev | cut -d'/' -f1 | rev) + CHANGED_FILES=$(curl -s "https://api.github.com/repos/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pulls/$PR_NUMBER/files" | jq -r '.[].filename' | grep '\.mdx$' || true) + echo "export CHANGED_FILES=\"$CHANGED_FILES\"" >> $BASH_ENV + fi - run: name: Lint Markdown files command: pnpm lint + - run: + name: Validate metadata + command: pnpm validate-pr-metadata links: executor: rust diff --git a/.coderabbit.yaml b/.coderabbit.yaml index a313f94de..3833c0cb2 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -10,6 +10,34 @@ reviews: - path: "**/*.mdx" instructions: | "ALWAYS review Markdown content THOROUGHLY with the following criteria: + - First, check the frontmatter section at the top of the file: + 1. For regular pages, ensure ALL these fields are present and not empty: + ```yaml + --- + title: [non-empty] + lang: [non-empty] + description: [non-empty] + topic: [non-empty] + personas: [non-empty array] + categories: [non-empty array] + content_type: [valid type] + --- + ``` + 2. For landing pages (index.mdx or files with ), only these fields are required: + ```yaml + --- + title: [non-empty] + lang: [non-empty] + description: [non-empty] + topic: [non-empty] + --- + ``` + 3. If any required fields are missing or empty, comment: + 'This file appears to be missing required metadata. You can fix this by running: + ```bash + pnpm metadata-batch-cli:dry "path/to/this/file.mdx" + ``` + Review the changes, then run without :dry to apply them.' - Use proper nouns in place of personal pronouns like 'We' and 'Our' to maintain consistency in communal documentation. - Avoid gender-specific language and use the imperative form. - Monitor capitalization for emphasis. Avoid using all caps, italics, or bold for emphasis. diff --git a/keywords.config.yaml b/keywords.config.yaml new file mode 100644 index 000000000..55ad121a1 --- /dev/null +++ b/keywords.config.yaml @@ -0,0 +1,237 @@ +# Metadata Configuration for Documentation +metadata_rules: + # PERSONA + persona: + required: true + multiple: true + min: 1 + validation_rules: + - enum: + - app-developer + - node-operator + - chain-operator + - protocol-developer + - partner + description: "Must select at least one valid persona" + + # CONTENT TYPE + content_type: + required: true + multiple: false + validation_rules: + - enum: + - tutorial # step-by-step instructions + - landing-page # navigation and overview pages + - guide # general how-to content and concept exlainers + - reference # technical specifications and API docs + - troubleshooting # problem-solution focused + - notice # Technical updates: breaking changes, upgrades, deprecations + - announcement # Community/Governance updates: new programs, initiatives + description: "Must select exactly one content type" + + # TOPIC + topic: + required: true + multiple: false + validation_rules: + - pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$ + description: "Must be kebab-case, derived from page title" + examples: ["standard-bridge", "account-abstraction", "ecotone-upgrade"] + - unique: true + description: "Topic must be unique across all pages" + - max_length: 100 + description: "Topic should be concise" + + # CATEGORIES + categories: + required: true + multiple: true + min: 1 + max: 5 + validation_rules: + - no_duplicates: true + description: "Categories must not repeat" + - no_metadata_overlap: + fields: ["topic", "content_type", "persona"] + description: "Categories cannot repeat values used in topic, content_type, or persona" + values: + # Data Availability Layer + - eth-da + - alt-da + - permissionless-batch-submission + - block-times + + # Sequencing Layer + - sequencer + - sequencer-pbs + - sequencer-decentralization + - sequencer-in-a-box + - op-batcher + + # Derivation Layer + - rollup-node + - fault-proofs + - fp-contracts + - op-challenger + - cannon + - zk + - op-workbench # Tool: derivation testing & simulation + + # Execution Layer + - op-geth + - op-reth + - op-erigon + - op-nethermind + - evm-equivalence + - precompiles + - predeploys + - preinstalls + - custom-gas-token + - l2-contracts + - dev-console # Tool: execution layer interaction + + # Settlement Layer + - l1-contracts + - standard-bridge + - teleportr + - interop + - interoperability + - cross-chain-messaging + - interoperable-assets + - op-deployer # Tool: contract deployment + - op-supervisor + + # Governance Layer + - security-council + - op-token + - blockspace-charters + - retro-funding + - revshare-enshrinement + - superchain-registry + + # Cross-layer Development Tools + - supersim # Tests across multiple layers + - devnets # Full-stack local environment + - performance-tooling # Stack-wide performance testing + - superchain-registry # Chain management across layers + - l1-deployment-upgrade-tooling # Cross-layer deployment + - l2-deployment-upgrade-tooling # Cross-layer deployment + + # Chain Management (Cross-layer) + - protocol + - infrastructure + - op-proposer + - op-supervisor + - op-conductor + - op-signer + - mcp + - mcp-l2 + - upgrade-standard-chains-stage-1 + - launch-new-chains-stage-1 + - automated-pause + - dispute-mon + - monitorism + - vertical-scaling + + # Protocol Releases + - granite + - holocene + - isthmus + - canyon + - delta + - ecotone + - fjord + - network-upgrade + - hard-fork + + # Infrastructure & Operations + - kubernetes-infrastructure + - devops-tooling + - artifacts-packaging + - peer-management-service + - proxyd + - zdd-service + - snapman + - op-beat + - security-monitoring-response + - stability-monitoring + - security + + # Development Languages & SDKs + - solidity + - typescript + - javascript + - go + - rust + - python + - foundry + - hardhat + - ethers + - viem + - web3js + - wagmi + + # Development Environments + - local-devnet + - testnet + - mainnet + + # TIMEFRAME + timeframe: + required_for: + - announcement + - notice + required: false + multiple: false + validation_rules: + # Component versions + - pattern: ^(op-\w+|cannon)/v\d+\.\d+\.\d+$ + description: "Component releases must be in format component/vX.Y.Z" + examples: ["op-node/v1.11.0", "op-batcher/v1.11.1"] + + # Release candidates + - pattern: ^(op-\w+)/v\d+\.\d+\.\d+-rc\.\d+$ + description: "Release candidates must be in format component/vX.Y.Z-rc.N" + examples: ["op-node/v1.11.0-rc.2"] + + # Alpha/Beta versions + - pattern: ^(op-\w+|cannon)/v\d+\.\d+\.\d+-(alpha|beta)\.\d+$ + description: "Alpha/Beta releases must be in format component/vX.Y.Z-{alpha|beta}.N" + examples: ["cannon/v1.4.0-alpha.1"] + + # Season format + - pattern: ^S[6-9]|S[1-9][0-9]+$ + description: "Season numbers must start with 'S' followed by a number 6 or greater" + examples: ["S6", "S7", "S8", "S10"] + + # Calendar year + - pattern: ^20(2[4-9]|[3-9][0-9])$ + description: "Years must be 2024 or later" + examples: ["2024", "2025", "2026"] + + # Half year + - pattern: ^20(2[4-9]|[3-9][0-9])H[1-2]$ + description: "Half years must be in format YYYYH1 or YYYYH2" + examples: ["2024H1", "2024H2", "2025H1"] + + # Quarter + - pattern: ^20(2[4-9]|[3-9][0-9])Q[1-4]$ + description: "Quarters must be in format YYYYQ1-Q4" + examples: ["2024Q1", "2024Q2", "2025Q3"] + + # Month + - pattern: ^20(2[4-9]|[3-9][0-9])-(0[1-9]|1[0-2])$ + description: "Months must be in format YYYY-MM" + examples: ["2024-01", "2024-12", "2025-06"] + + # Protocol upgrades + - enum: + - bedrock + - canyon + - delta + - ecotone + - fjord + - granite + - holocene + - isthmus + description: "Protocol upgrade names must match exactly" \ No newline at end of file diff --git a/notes/README.md b/notes/README.md index aaa03c30d..8cfdd8511 100644 --- a/notes/README.md +++ b/notes/README.md @@ -7,4 +7,10 @@ The Optimism Docs are internal docs to help you understand how the Optimism Docs - [GitHub Actions](./actions.md) - [Algolia Search](./algolia-search.md) - [Lychee Link Checking](./lychee.md) +- [Kapa AI Assistance](./kapa-ai-assistant.md) +- [Breadcrumbs](./breadcrumbs.md) +- [Content reuse](./content-reuse.md) +- [Fix redirects](./fix-redirects.md) +- [WIP callout](./wip-callout.md) +- [Metadata batch update](./metadata-update.md) - [Public Resources Folder](./resources.md) diff --git a/notes/metadata-update.md b/notes/metadata-update.md new file mode 100644 index 000000000..fdf7f325c --- /dev/null +++ b/notes/metadata-update.md @@ -0,0 +1,203 @@ +# Metadata Management System + +Quick guide on using our metadata management system for the OP Stack documentation. + +## What the System Does + +* Validates and updates metadata in .mdx documentation files +* Ensures consistent metadata across documentation +* Generates a manifest of processed files +* Supports dry run mode for previewing changes +* Automatically detects content categories and types + +## Using the Scripts + +1. Run a dry run to preview changes: + * Process all .mdx files in a directory +```bash +pnpm metadata-batch-cli:dry "pages/app-developers/**/*.mdx" +``` + * Process a specific file with verbose output +```bash +pnpm metadata-batch-cli:verbose "pages/app-developers/example.mdx" +``` + * Process multiple directories +```bash +pnpm metadata-batch-cli:dry "pages/app-developers/**/*.mdx" "pages/node-operators/**/*.mdx" +``` + +2. Apply the changes (remove :dry): +```bash +pnpm metadata-batch-cli "pages/app-developers/**/*.mdx" +``` + +### Important Note About File Patterns + +* Use `**/*.mdx` to match all .mdx files in a directory and its subdirectories +* The double asterisk `**` is required for recursive directory matching +* Single `/` patterns will not work correctly + +### Configuration Files + +1. **keywords.config.yaml** + * Located in the project root + * **Single source of truth** for all valid metadata values + * Defines validation rules for metadata fields + * Specifies required fields for different content types + * Contains keyword mappings for category detection + * Example configuration: +```yaml +metadata_rules: + topic: + required: true + validation_rules: + - pattern: "^[a-z0-9-]+$" + description: "Must be lowercase with hyphens" + personas: + required: true + multiple: true + validation_rules: + - enum: + - app-developer + - node-operator + - chain-operator + - protocol-developer + - partner + content_type: + required: true + validation_rules: + - enum: + - tutorial + - guide + - reference + - landing-page + - troubleshooting + - notice + categories: + required: true + multiple: true + validation_rules: + - enum: + - protocol + - security + - governance + - tokens + - standard-bridge + - interoperable-message-passing + - devnets + - infrastructure +``` + +2. **metadata-types.ts** + * Defines TypeScript interfaces for metadata + * Imports and validates valid values from keywords.config.yaml + * Provides type-safe exports for use throughout the system + * Used for type checking and validation + +## What to Watch For + +1. **Before Running** + * Commit your current changes + * Ensure you're in the docs root directory + * Check that keywords.config.yaml exists and is properly configured + * **Important**: All valid metadata values must be defined in keywords.config.yaml + +2. **After Running** + * Review the manifest file + * Check validation messages in console output + * Verify metadata changes in files + * Review any files flagged for category review + +## Content Analysis + +The `metadata-analyzer.ts` script handles automatic content analysis and categorization. + +### How It Works + +1. **Category Detection** + * Analyzes file content and paths for relevant keywords + * Detects appropriate categories based on context + * Handles special cases for chain operators and node operators + * Supports parent category inheritance for landing pages + +2. **Content Type Detection** + * Identifies content type (guide, reference, tutorial, etc.) + * Uses filename patterns and content signals + * Considers component usage (e.g., , ) + * Scores content against multiple type indicators + +### Valid Categories + +Categories are defined in `keywords.config.yaml`. Check this file for the current list of valid categories. The metadata validation system uses these definitions to ensure consistency across all documentation. + +Example of how categories are defined: +```yaml +metadata_rules: + categories: + required: true + multiple: true + validation_rules: + - enum: + - protocol + - security + - governance + # ... see keywords.config.yaml for complete list +``` + +### Example Analysis + +Input file with chain operator content: +```yaml +--- +title: Genesis Creation +description: Learn how to create a genesis file. +--- +``` + +Detected categories: +```yaml +categories: + - protocol + - devnets + - governance + - security +``` + +### Special Cases + +* **Landing Pages**: Categories are determined by analyzing the child content they link to (typically via `` components) +* **Chain Operators**: Additional category detection for specific features +* **Node Operators**: Special handling for node operation content +* **Imported Content**: Skip category review flags for imported content + +## Implementation Files + +* `utils/metadata-manager.ts`: Main metadata management system +* `utils/metadata-analyzer.ts`: Content analysis and categorization logic +* `utils/metadata-batch-cli.ts`: CLI tool for batch updates +* `utils/types/metadata-types.ts`: TypeScript type definitions +* `keywords.config.yaml`: Validation rules and keyword mappings + +## Automated PR Checks + +The documentation repository includes automated checks for metadata completeness: + +1. **CircleCI Validation** + * Automatically runs on all PRs + * Checks metadata in modified .mdx files + * Fails if required metadata is missing + * Run locally with: `pnpm validate-pr-metadata` + +2. **CodeRabbit Review** + * Reviews frontmatter in modified files + * Checks for required fields based on content type + * Suggests running metadata-batch-cli when metadata is incomplete + +### When to Run Metadata Updates + +* When CircleCI metadata validation fails +* When CodeRabbit suggests missing metadata +* When adding new documentation files +* When specifically asked to update metadata + +Do not run the script on files that already have correct metadata, as this may overwrite manual customizations. diff --git a/package.json b/package.json index 525cfc6e0..d91cf0950 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,10 @@ "name": "op-docs", "version": "0.0.1", "description": "Optimism Docs", + "type": "module", "scripts": { - "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs && pnpm check-redirects", - "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm breadcrumbs && pnpm fix-redirects", + "lint": "eslint . --ext mdx --max-warnings 0 && pnpm spellcheck:lint && pnpm check-breadcrumbs && pnpm check-redirects && pnpm validate-metadata", + "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm breadcrumbs && pnpm fix-redirects && pnpm metadata-batch-cli", "spellcheck:lint": "cspell lint \"**/*.mdx\"", "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", "linkcheck": "lychee --config ./lychee.toml --quiet \"./pages\"", @@ -13,6 +14,11 @@ "fix-redirects": "npx ts-node --skip-project utils/fix-redirects.ts", "check-breadcrumbs": "npx ts-node --skip-project utils/breadcrumbs.ts", "index:docs": "npx ts-node --skip-project utils/algolia-indexer.ts", + "metadata-batch-cli": "node --loader ts-node/esm utils/metadata-batch-cli.ts", + "metadata-batch-cli:dry": "pnpm metadata-batch-cli --dry-run", + "metadata-batch-cli:verbose": "pnpm metadata-batch-cli --verbose", + "validate-metadata": "npx ts-node --skip-project utils/metadata-manager.ts", + "validate-pr-metadata": "npx ts-node --skip-project utils/metadata-manager.ts --pr", "dev": "next dev", "build": "next build", "start": "next start", @@ -29,6 +35,7 @@ "clsx": "^2.1.1", "dotenv": "^16.4.7", "escape-string-regexp": "^5.0.0", + "js-yaml": "^4.1.0", "next": "14.2.21", "next-sitemap": "^4.2.3", "nextra": "2.13.2", @@ -44,6 +51,7 @@ "@eth-optimism/core-utils": "^0.13.1", "@eth-optimism/sdk": "^3.1.6", "@types/dotenv": "^8.2.3", + "@types/js-yaml": "^4.0.9", "@types/node": "18.11.10", "cspell": "^8.1.3", "eslint": "^8.53.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b912c9e94..1c598a364 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,6 +49,9 @@ importers: escape-string-regexp: specifier: ^5.0.0 version: 5.0.0 + js-yaml: + specifier: ^4.1.0 + version: 4.1.0 next: specifier: 14.2.21 version: 14.2.21(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -89,6 +92,9 @@ importers: '@types/dotenv': specifier: ^8.2.3 version: 8.2.3 + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 '@types/node': specifier: 18.11.10 version: 18.11.10 @@ -1013,8 +1019,8 @@ packages: '@types/is-empty@1.2.3': resolution: {integrity: sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==} - '@types/js-yaml@4.0.8': - resolution: {integrity: sha512-m6jnPk1VhlYRiLFm3f8X9Uep761f+CK8mHyS65LutH2OhmBF0BeMEjHgg05usH8PLZMWWc/BUR9RPmkvpWnyRA==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -5047,7 +5053,7 @@ snapshots: '@types/is-empty@1.2.3': {} - '@types/js-yaml@4.0.8': {} + '@types/js-yaml@4.0.9': {} '@types/json-schema@7.0.15': {} @@ -8773,7 +8779,7 @@ snapshots: vfile-matter@3.0.1: dependencies: - '@types/js-yaml': 4.0.8 + '@types/js-yaml': 4.0.9 is-buffer: 2.0.5 js-yaml: 4.1.0 diff --git a/tsconfig.json b/tsconfig.json index df26076ee..532f0a431 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,16 +6,17 @@ "skipLibCheck": true, "strict": false, "forceConsistentCasingInFileNames": true, - "noEmit": false, // Set to false to allow emitting JS files + "noEmit": false, "incremental": true, "esModuleInterop": true, + "allowSyntheticDefaultImports": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "baseUrl": "./", - "outDir": "./dist", // Output compiled JS files to the "dist" directory + "outDir": "./dist", "paths": { "@/components/*": ["components/*"], "@/content/*": ["content/*"], @@ -25,5 +26,9 @@ } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] -} + "exclude": ["node_modules"], + "ts-node": { + "esm": true, + "experimentalSpecifierResolution": "node" + } +} \ No newline at end of file diff --git a/utils/metadata-analyzer.ts b/utils/metadata-analyzer.ts new file mode 100644 index 000000000..eba78f1f0 --- /dev/null +++ b/utils/metadata-analyzer.ts @@ -0,0 +1,683 @@ +import fs from 'fs' +import path from 'path' +import { MetadataResult, VALID_CATEGORIES, VALID_CONTENT_TYPES } from './types/metadata-types' + +/** + * Returns default personas for app developer content + */ +export function getDefaultPersonas(filepath: string): string[] { + // Chain operator content + if (filepath.includes('/chain-operators/')) { + return ['chain-operator']; + } + + // Node operator content + if (filepath.includes('/node-operators/')) { + return ['node-operator']; + } + + // Default to app developer + return ['app-developer']; +} + +/** + * Generates a topic from a title + */ +export function generateTopic(title: string): string { + return title.toLowerCase() + .replace(/[^a-z0-9\s-]/g, '') + .trim() + .replace(/\s+/g, '-') || 'general'; +} + +// Fix duplicate landing page detection +let detectedLandingPages = new Set(); + +/** + * Enhanced landing page detection with Cards component awareness + */ +function isLandingPage(content: string, filepath: string): boolean { + // If we've already detected this file, return false + if (detectedLandingPages.has(filepath)) { + return false; + } + + // Only consider root-level operator pages as landing pages + const isOperatorLanding = filepath.endsWith('chain-operators.mdx') || + filepath.endsWith('node-operators.mdx'); + + // Only consider overview pages in first-level subdirectories + const isOverviewPage = filepath.match(/\/operators\/[^/]+\/overview\.mdx$/); + + // Exclude deeper subdirectories from being landing pages + const isTooDeep = (filepath.match(/\//g) || []).length > 3; + + const hasMultipleCards = content.includes('') && + content.includes('') && + (content.match(/ 1; + + // Exclude specific paths that look like landing pages but aren't + const notLandingPage = [ + 'get-started.mdx', + 'building-apps.mdx', + 'testing-apps.mdx', + '/tutorials/', + '/reference/', + '/chain-env/', + '/getting-started/' + ].some(path => filepath.includes(path)); + + const isLanding = (isOperatorLanding || (isOverviewPage && hasMultipleCards)) && !isTooDeep && !notLandingPage; + + if (isLanding) { + detectedLandingPages.add(filepath); + console.log(`Landing page detected: ${filepath}`); + } + + return isLanding; +} + +/** + * Get categories for landing pages based on their location and content + */ +function getLandingPageCategories(filepath: string, content: string): Set { + const categories = new Set(); + + // Add categories based on directory path + if (filepath.includes('/bridging/')) { + categories.add('standard-bridge'); + categories.add('interoperable-message-passing'); + } + + if (filepath.includes('/tutorials/')) { + // Don't automatically add devnets to tutorial landing pages + if (content.toLowerCase().includes('testnet') || + content.toLowerCase().includes('local development')) { + categories.add('devnets'); + } + } + + if (filepath.includes('/tools/')) { + // Add relevant categories based on tool type + if (filepath.includes('/build/')) { + categories.add('hardhat'); + categories.add('foundry'); + } + if (filepath.includes('/connect/')) { + categories.add('ethers'); + categories.add('viem'); + } + } + + if (filepath.includes('/supersim/')) { + categories.add('supersim'); + } + + // Add categories based on content keywords + if (content.toLowerCase().includes('security') || + content.toLowerCase().includes('secure')) { + categories.add('security'); + } + + return categories; +} + +/** + * Detects categories based on content signals + */ +function detectCategories(content: string, filepath: string, detectionLog: string[]): string[] { + detectionLog.push(`Analyzing categories for: ${filepath}`); + + const categories = new Set(); + + // Connect section categories + if (filepath.includes('/connect/')) { + if (filepath.includes('/contribute/')) { + if (filepath.includes('docs-contribute')) { + categories.add('typescript'); + categories.add('javascript'); + } + if (filepath.includes('stack-contribute')) { + categories.add('go'); + categories.add('rust'); + } + } + if (filepath.includes('/resources/')) { + categories.add('protocol'); + } + return Array.from(categories); + } + + // Notice categories + if (filepath.includes('/notices/')) { + if (filepath.includes('holocene')) { + categories.add('holocene'); + categories.add('network-upgrade'); + } + if (filepath.includes('pectra')) { + categories.add('security'); + categories.add('protocol'); + } + if (filepath.includes('sdk')) { + categories.add('typescript'); + categories.add('javascript'); + } + return Array.from(categories); + } + + // Get started categories + if (filepath.includes('/get-started/')) { + if (filepath.includes('interop')) { + categories.add('interop'); + categories.add('cross-chain-messaging'); + } + if (filepath.includes('op-stack')) { + categories.add('protocol'); + categories.add('devnets'); + } + if (filepath.includes('superchain')) { + categories.add('blockspace-charters'); + categories.add('superchain-registry'); + } + return Array.from(categories); + } + + // Stack-specific categories + if (filepath.includes('/stack/')) { + // Base protocol content + if (filepath.match(/\/(rollup|transactions|components|differences|smart-contracts)\//)) { + categories.add('protocol'); + } + + // Research and specs + if (filepath.includes('/research/')) { + categories.add('protocol'); + if (content.toLowerCase().includes('block time')) { + categories.add('block-times'); + } + } + + // Root stack pages + if (filepath.match(/\/stack\/[^/]+\.mdx$/)) { + // Landing pages + if (filepath.endsWith('features.mdx') || + filepath.endsWith('beta-features.mdx')) { + categories.add('protocol'); + if (content.toLowerCase().includes('gas')) { + categories.add('custom-gas-token'); + } + if (content.toLowerCase().includes('data availability')) { + categories.add('alt-da'); + } + } + + // Core protocol pages + if (filepath.endsWith('rollup.mdx') || + filepath.endsWith('transactions.mdx') || + filepath.endsWith('components.mdx') || + filepath.endsWith('differences.mdx') || + filepath.endsWith('smart-contracts.mdx')) { + categories.add('protocol'); + } + + // Development pages + if (filepath.endsWith('dev-node.mdx') || + filepath.endsWith('getting-started.mdx') || + filepath.endsWith('public-devnets.mdx')) { + categories.add('devnets'); + } + + // Security pages + if (filepath.endsWith('security.mdx')) { + categories.add('security'); + } + + // Research pages + if (filepath.endsWith('research.mdx') || + filepath.endsWith('fact-sheet.mdx')) { + categories.add('protocol'); + } + + // Design pages + if (filepath.endsWith('design-principles.mdx')) { + categories.add('protocol'); + } + + // Interop pages + if (filepath.endsWith('interop.mdx')) { + categories.add('interop'); + categories.add('cross-chain-messaging'); + } + } + + // Rollup content + if (filepath.includes('/rollup/')) { + categories.add('protocol'); + categories.add('rollup-node'); + if (content.toLowerCase().includes('sequencer')) { + categories.add('sequencer'); + } + } + + // Features and beta features + if (filepath.includes('/features/') || filepath.includes('/beta-features/')) { + categories.add('protocol'); + if (content.toLowerCase().includes('gas')) { + categories.add('custom-gas-token'); + } + if (content.toLowerCase().includes('data availability')) { + categories.add('alt-da'); + } + } + + // Interop content + if (filepath.includes('/interop/')) { + categories.add('interop'); + categories.add('cross-chain-messaging'); + if (content.toLowerCase().includes('supervisor')) { + categories.add('op-supervisor'); + } + if (content.toLowerCase().includes('bridge') || + content.toLowerCase().includes('erc20')) { + categories.add('interoperable-assets'); + } + } + + // Fault proof content + if (filepath.includes('/fault-proofs/') || content.toLowerCase().includes('fault proof')) { + categories.add('fault-proofs'); + categories.add('op-challenger'); + if (content.toLowerCase().includes('cannon')) { + categories.add('cannon'); + } + } + + // Protocol content + if (filepath.includes('/protocol/')) { + categories.add('protocol'); + if (content.toLowerCase().includes('sequencer')) { + categories.add('sequencer'); + } + if (content.toLowerCase().includes('batcher')) { + categories.add('op-batcher'); + } + if (content.toLowerCase().includes('derivation')) { + categories.add('rollup-node'); + } + } + + // Bridge content + if (filepath.includes('/bridge/')) { + categories.add('standard-bridge'); + categories.add('cross-chain-messaging'); + if (content.toLowerCase().includes('message passing')) { + categories.add('interoperable-message-passing'); + } + } + + // Security content + if (filepath.includes('/security/')) { + categories.add('security'); + if (content.toLowerCase().includes('pause')) { + categories.add('automated-pause'); + } + } + + // Node content + if (filepath.includes('/node/')) { + categories.add('rollup-node'); + categories.add('op-geth'); + if (content.toLowerCase().includes('derivation')) { + categories.add('protocol'); + } + } + + // Transaction content + if (filepath.includes('/transactions/')) { + categories.add('protocol'); + if (content.toLowerCase().includes('cross') || + content.toLowerCase().includes('deposit') || + content.toLowerCase().includes('withdrawal')) { + categories.add('cross-chain-messaging'); + } + } + + return Array.from(categories); + } + + // App developer categories - simpler version + if (filepath.includes('/app-developers/')) { + // Bridging content + if (filepath.includes('/bridging/') || + content.toLowerCase().includes('bridge') || + content.toLowerCase().includes('token transfer')) { + categories.add('standard-bridge'); + categories.add('cross-chain-messaging'); + } + + // Tools content + if (filepath.includes('/tools/')) { + if (filepath.includes('/build/')) { + categories.add('hardhat'); + categories.add('foundry'); + } + if (filepath.includes('/connect/')) { + categories.add('ethers'); + categories.add('viem'); + } + } + + // SuperSim content + if (filepath.includes('/supersim/')) { + categories.add('supersim'); + } + + // Add devnets for tutorials + if (filepath.includes('/tutorials/')) { + categories.add('devnets'); + } + + return Array.from(categories); + } + + // Chain operator categories - keep existing logic + if (filepath.endsWith('chain-operators.mdx')) { + categories.add('protocol'); + categories.add('sequencer'); + categories.add('op-batcher'); + categories.add('fault-proofs'); + categories.add('op-challenger'); + return Array.from(categories); + } + + if (filepath.endsWith('node-operators.mdx')) { + categories.add('infrastructure'); + categories.add('rollup-node'); + categories.add('op-geth'); + categories.add('monitorism'); + return Array.from(categories); + } + + // Chain operator content + if (filepath.includes('/chain-operators/')) { + categories.add('protocol'); + + if (content.toLowerCase().includes('sequencer') || + content.toLowerCase().includes('batch') || + content.toLowerCase().includes('proposer')) { + categories.add('sequencer'); + categories.add('op-batcher'); + } + + if (content.toLowerCase().includes('fault proof') || + content.toLowerCase().includes('challenger')) { + categories.add('fault-proofs'); + categories.add('op-challenger'); + } + + if (content.toLowerCase().includes('deploy') || + content.toLowerCase().includes('genesis') || + content.toLowerCase().includes('configuration')) { + categories.add('l1-deployment-upgrade-tooling'); + categories.add('l2-deployment-upgrade-tooling'); + } + } + + // Node operator content + if (filepath.includes('/node-operators/')) { + categories.add('infrastructure'); + + if (content.toLowerCase().includes('rollup node') || + content.toLowerCase().includes('op-node')) { + categories.add('rollup-node'); + } + + if (content.toLowerCase().includes('op-geth')) { + categories.add('op-geth'); + } + + if (content.toLowerCase().includes('monitoring') || + content.toLowerCase().includes('metrics') || + content.toLowerCase().includes('health')) { + categories.add('monitorism'); + } + } + + // Common categories + if (content.toLowerCase().includes('kubernetes') || + content.toLowerCase().includes('k8s')) { + categories.add('kubernetes-infrastructure'); + } + + // Superchain content + if (filepath.includes('/superchain/')) { + if (filepath.includes('blockspace')) { + categories.add('blockspace-charters'); + } + if (filepath.includes('registry') || + filepath.includes('addresses') || + filepath.includes('networks')) { + categories.add('superchain-registry'); + } + if (content.toLowerCase().includes('security') || + content.toLowerCase().includes('privileged')) { + categories.add('security-council'); + } + } + + // Limit to 5 most relevant categories + const priorityOrder = [ + 'protocol', + 'infrastructure', + 'sequencer', + 'op-batcher', + 'rollup-node', + 'op-geth', + 'fault-proofs', + 'op-challenger', + 'cannon', + 'l1-deployment-upgrade-tooling', + 'l2-deployment-upgrade-tooling', + 'monitorism', + 'security', + 'automated-pause', + 'kubernetes-infrastructure', + 'cross-chain-messaging', + 'standard-bridge', + 'interoperable-message-passing', + 'hardhat', + 'foundry', + 'ethers', + 'viem', + 'supersim', + 'devnets', + 'mainnet', + 'testnet' + ]; + + const sortedCategories = Array.from(categories) + .sort((a, b) => priorityOrder.indexOf(a) - priorityOrder.indexOf(b)) + .slice(0, 5); + + detectionLog.push(`Final categories: ${sortedCategories.join(', ')}`); + return sortedCategories; +} + +/** + * Counts signals that indicate reference content + */ +function countReferenceSignals(content: string, filepath: string): number { + let score = 0; + + // Technical content indicators + score += (content.match(/\|.*\|/g) || []).length * 2; // Tables + score += (content.match(/```[^`]+```/g) || []).length; // Code blocks + score += (content.match(/\{.*?\}/g) || []).length; // Special syntax + score += (content.match(/\b(API|RPC|SDK|JSON|HTTP|URL|ETH)\b/g) || []).length; + + // Reference structure indicators + score += (content.match(/^Parameters:/gm) || []).length * 3; + score += (content.match(/^Returns:/gm) || []).length * 3; + score += (content.match(/^Type:/gm) || []).length * 2; + score += (content.match(/^Endpoint:/gm) || []).length * 2; + + // API-specific indicators + score += (content.match(/\bend?points?\b/gi) || []).length * 2; + score += content.includes('## API Reference') ? 5 : 0; + score += filepath.includes('/api/') ? 5 : 0; + + return score; +} + +/** + * Counts signals that indicate guide content + */ +function countGuideSignals(content: string): number { + let score = 0; + + // Tutorial/How-to structure indicators + score += content.includes('') ? 5 : 0; + score += content.toLowerCase().includes('how to') ? 3 : 0; + score += (content.match(/^\d+\.\s/gm) || []).length * 2; // Numbered steps + + // Instructional content indicators + score += (content.match(/^First|Next|Then|Finally/gm) || []).length * 2; + score += (content.match(/you'll need to|you will need to|you need to/g) || []).length * 2; + score += (content.match(/let's|we'll|we will/g) || []).length; + + // Explainer content indicators + score += content.toLowerCase().includes('overview') ? 3 : 0; + score += content.toLowerCase().includes('architecture') ? 3 : 0; + score += content.toLowerCase().includes('understand') ? 2 : 0; + score += content.toLowerCase().includes('concept') ? 2 : 0; + score += (content.match(/\bis\b|\bare\b|\bmeans\b/g) || []).length; + score += (content.match(/for example|such as|like/g) || []).length; + score += (content.match(/consists of|composed of|comprises/g) || []).length; + + // Visual explanation indicators + score += (content.match(/ 2) { + detectionLog.push("Detected as troubleshooting content"); + return 'troubleshooting'; + } + + // Check for notices/announcements + if (content.toLowerCase().includes('breaking change') || + content.toLowerCase().includes('deprecation notice') || + content.toLowerCase().includes('upgrade notice')) { + detectionLog.push("Detected as technical notice"); + return 'notice'; + } + + // Reference vs Guide scoring + const referenceScore = countReferenceSignals(content, filepath); + const guideScore = countGuideSignals(content); + + if (referenceScore > guideScore * 1.5) { + detectionLog.push(`Detected as reference (scores: ref=${referenceScore}, guide=${guideScore})`); + return 'reference'; + } + + detectionLog.push(`Detected as guide (scores: ref=${referenceScore}, guide=${guideScore})`); + return 'guide'; +} + +/** + * Analyzes content to determine metadata + */ +export function analyzeContent(content: string, filepath: string, verbose: boolean = false): MetadataResult { + const detectionLog: string[] = []; + const warnings: string[] = []; + + const contentType = detectContentType(content, detectionLog, filepath); + const categories = detectCategories(content, filepath, detectionLog); + + // Track files needing review + if (contentType === 'NEEDS_REVIEW') { + warnings.push('Content type needs manual review'); + global.filesNeedingContentTypeReview = (global.filesNeedingContentTypeReview || 0) + 1; + } + if (categories.length === 0) { + warnings.push('Categories may need manual review'); + global.filesNeedingCategoryReview = (global.filesNeedingCategoryReview || 0) + 1; + } + + // Track total files processed + global.totalFiles = (global.totalFiles || 0) + 1; + + if (verbose) { + console.log(`\n📄 ${filepath}`); + console.log(` Type: ${contentType}`); + console.log(` Categories: ${categories.length ? categories.join(', ') : 'none'}`); + warnings.forEach(warning => { + console.log(` ⚠️ ${warning}`); + }); + } + + return { + content_type: contentType as typeof VALID_CONTENT_TYPES[number], + categories, + detectionLog, + title: '', + lang: 'en-US', + description: '', + topic: '', + personas: getDefaultPersonas(filepath), + is_imported_content: 'false' + }; +} + +// Export the summary function to be called at the end of processing +export function printSummary(): void { + console.log(` +Final Summary: +✓ Processed ${global.totalFiles} files +⚠️ ${global.filesNeedingCategoryReview || 0} files may need category review +⚠️ ${global.filesNeedingContentTypeReview || 0} files may need content type review +(Dry run - no changes made) +`); +} \ No newline at end of file diff --git a/utils/metadata-batch-cli.ts b/utils/metadata-batch-cli.ts new file mode 100644 index 000000000..4789252f3 --- /dev/null +++ b/utils/metadata-batch-cli.ts @@ -0,0 +1,211 @@ +#!/usr/bin/env node + +import { promises as fs } from 'fs' +import path from 'path' +import matter from 'gray-matter' +import globby from 'globby' +import { updateMetadata } from './metadata-manager.js' +import { MetadataResult } from './types/metadata-types.js' + +// Interface for processing summary +interface ProcessingSummary { + path: string + categories: string[] + uncertainCategories: boolean + contentType: string + isImported: boolean +} + +// Simplified color constants for CLI output +const colors = { + reset: '\x1b[0m', + blue: '\x1b[34m', // for file paths + yellow: '\x1b[33m', // for warnings + red: '\x1b[31m', // for errors + green: '\x1b[32m' // for success counts +} + +// File system related interfaces +interface ParentMetadata { + path: string + categories: string[] +} + +async function findMdxFiles(pattern: string): Promise { + const files = await globby(pattern, { + absolute: true, + expandDirectories: { + files: ['*.mdx'], + extensions: ['mdx'] + } + }) + return files +} + +async function findParentMetadata(filePath: string): Promise { + try { + // First check for index.mdx in the same directory + const dir = path.dirname(filePath) + const parentFiles = ['index.mdx', 'README.mdx'] + + // Try same directory first + for (const file of parentFiles) { + const sameDirPath = path.join(dir, file) + try { + const content = await fs.readFile(sameDirPath, 'utf8') + const { data } = matter(content) + return { + path: sameDirPath, + categories: data.categories || [] + } + } catch (e) { + continue + } + } + + // Try parent directory + const parentDir = path.dirname(dir) + for (const file of parentFiles) { + const parentPath = path.join(parentDir, file) + try { + const content = await fs.readFile(parentPath, 'utf8') + const { data } = matter(content) + return { + path: parentPath, + categories: data.categories || [] + } + } catch (e) { + continue + } + } + + return null + } catch (e) { + return null + } +} + +async function updateFrontmatter(filePath: string, dryRun: boolean = false, verbose: boolean = false): Promise<{ + categories: string[] + contentType: string + isImported: boolean +}> { + if (verbose) { + console.log(`\nProcessing: ${filePath}`) + } + + const result = await updateMetadata(filePath, { + dryRun, + validateOnly: false + }) + + if (!result.metadata) { + throw new Error(`Failed to process ${filePath}: ${result.errors.join(', ')}`) + } + + if (verbose) { + console.log('New metadata:', result.metadata) + if (result.errors.length > 0) { + console.log('Validation warnings:', result.errors) + } + if (dryRun) { + console.log('Dry run - no changes made') + } + } + + return { + categories: result.metadata.categories, + contentType: result.metadata.content_type, + isImported: result.metadata.is_imported_content === 'true' + } +} + +async function main() { + try { + const args = process.argv.slice(2) + const dryRun = args.includes('--dry-run') + const verbose = args.includes('--verbose') + + const targetPaths = args.filter(arg => !arg.startsWith('--')) + if (targetPaths.length === 0) { + console.error(`${colors.red}Please provide at least one path to process${colors.reset}`) + process.exit(1) + } + + const allMdxFiles = Array.from( + new Set( + (await Promise.all(targetPaths.map(pattern => findMdxFiles(pattern)))) + .flat() + ) + ) + + console.log(`Found ${allMdxFiles.length} .mdx files to process\n`) + + const summaries: ProcessingSummary[] = [] + + // Process each file + for (const file of allMdxFiles) { + try { + const result = await updateFrontmatter(file, dryRun, verbose) + const relativePath = path.relative(process.cwd(), file) + + // Determine if categorization is uncertain + const hasUncertainCategories = + !result.categories.length || + (result.categories.length === 1 && result.categories[0] === 'protocol') + + summaries.push({ + path: relativePath, + categories: result.categories, + uncertainCategories: hasUncertainCategories && !result.isImported, // Don't flag imported content + contentType: result.contentType, + isImported: result.isImported + }) + } catch (error) { + console.error(`${colors.red}Error processing ${file}:${colors.reset}`, error) + } + } + + // Print summary + console.log('\nProcessing Summary:') + console.log('==================') + + summaries.forEach(summary => { + // File path in blue + console.log(`\n📄 ${colors.blue}${summary.path}${colors.reset}`) + // Type in default color + console.log(` Type: ${summary.contentType}`) + if (summary.isImported) { + console.log(' Status: Imported content') + } + // Categories in default color + console.log(` Categories: ${summary.categories.join(', ') || 'none'}`) + + if (summary.uncertainCategories) { + console.log(` ${colors.yellow}⚠️ Categories may need manual review${colors.reset}`) + } + }) + + const needsReview = summaries.filter(s => s.uncertainCategories).length + const importedCount = summaries.filter(s => s.isImported).length + + console.log('\n=================') + console.log('Final Summary:') + console.log(`${colors.green}✓ Processed ${summaries.length} files${colors.reset}`) + if (importedCount > 0) { + console.log(`ℹ️ ${importedCount} imported files`) + } + if (needsReview > 0) { + console.log(`${colors.yellow}⚠️ ${needsReview} files may need category review${colors.reset}`) + } + if (dryRun) { + console.log(`${colors.blue}(Dry run - no changes made)${colors.reset}`) + } + } catch (error) { + console.error(`${colors.red}Fatal error:${colors.reset}`, error) + process.exit(1) + } +} + +// Run the script +main() \ No newline at end of file diff --git a/utils/metadata-manager.ts b/utils/metadata-manager.ts new file mode 100644 index 000000000..9b16d674c --- /dev/null +++ b/utils/metadata-manager.ts @@ -0,0 +1,168 @@ +import { promises as fs } from 'fs' +import path from 'path' +import matter from 'gray-matter' +import yaml from 'js-yaml' +import { analyzeContent } from './metadata-analyzer' +import { + MetadataResult, + VALID_PERSONAS, + VALID_CONTENT_TYPES, + VALID_CATEGORIES +} from './types/metadata-types' + +// Validation functions +export function validateMetadata(metadata: MetadataResult, filePath: string): string[] { + const errors: string[] = [] + const isLandingPage = filePath.includes('index.mdx') || + (metadata.content && metadata.content.includes('')) + + // Required fields for all pages + if (!metadata.title) errors.push('Missing title') + if (!metadata.lang) errors.push('Missing lang') + if (!metadata.description) errors.push('Missing description') + if (!metadata.topic) errors.push('Missing topic') + + // Additional validations for non-landing pages + if (!isLandingPage) { + // Validate personas + if (!metadata.personas || metadata.personas.length === 0) { + errors.push('Missing personas') + } else { + const invalidPersonas = metadata.personas.filter(p => !VALID_PERSONAS.includes(p as any)) + if (invalidPersonas.length > 0) { + errors.push(`Invalid personas: ${invalidPersonas.join(', ')}`) + } + } + + // Validate content_type + if (!metadata.content_type) { + errors.push('Missing content_type') + } else if (!VALID_CONTENT_TYPES.includes(metadata.content_type as any)) { + errors.push(`Invalid content_type: ${metadata.content_type}`) + } + + // Validate categories + if (!metadata.categories || metadata.categories.length === 0) { + errors.push('Missing categories') + } else { + const invalidCategories = metadata.categories.filter(c => !VALID_CATEGORIES.includes(c as any)) + if (invalidCategories.length > 0) { + errors.push(`Invalid categories: ${invalidCategories.join(', ')}`) + } + } + } + + return errors +} + +// Generation functions +export async function generateMetadata(filePath: string): Promise { + const content = await fs.readFile(filePath, 'utf8') + const { data: existingMetadata } = matter(content) + const analysis = analyzeContent(content, filePath) + + const metadata: MetadataResult = { + ...existingMetadata, + ...analysis, + title: existingMetadata.title || '', + lang: existingMetadata.lang || 'en', + description: existingMetadata.description || '', + topic: existingMetadata.topic || '', + personas: existingMetadata.personas || [], + content_type: existingMetadata.content_type || analysis.content_type || 'guide', + categories: existingMetadata.categories || analysis.categories || [], + is_imported_content: existingMetadata.is_imported_content || 'false', + content: content // Include content for landing page detection + } + + return metadata +} + +// Combined update function with validation +export async function updateMetadata(filePath: string, options: { + dryRun?: boolean + validateOnly?: boolean + prMode?: boolean +} = {}): Promise<{ + isValid: boolean + errors: string[] + metadata?: MetadataResult +}> { + try { + const content = await fs.readFile(filePath, 'utf8') + const { data: currentMetadata } = matter(content) + + // If validate only, just return validation results + if (options.validateOnly) { + const errors = validateMetadata(currentMetadata as MetadataResult, filePath) + return { + isValid: errors.length === 0, + errors + } + } + + // Generate new metadata + const newMetadata = await generateMetadata(filePath) + + // Validate the new metadata + const errors = validateMetadata(newMetadata, filePath) + + // If not dry run and valid, update the file + if (!options.dryRun && errors.length === 0) { + const updatedContent = matter.stringify(content, newMetadata) + await fs.writeFile(filePath, updatedContent) + } + + return { + isValid: errors.length === 0, + errors, + metadata: newMetadata + } + } catch (error) { + return { + isValid: false, + errors: [`Error processing file: ${error.message}`] + } + } +} + +// PR validation function +export async function validatePRChanges(): Promise { + try { + const gitOutput = process.env.CHANGED_FILES || '' + const modifiedFiles = gitOutput + .split('\n') + .filter(file => file.endsWith('.mdx')) + .map(file => path.resolve(process.cwd(), file)) + + if (modifiedFiles.length === 0) { + console.log('No .mdx files modified') + return true + } + + let hasErrors = false + for (const file of modifiedFiles) { + const result = await updateMetadata(file, { validateOnly: true, prMode: true }) + if (!result.isValid) { + hasErrors = true + console.error(`\n${file}:`) + result.errors.forEach(error => console.error(` - ${error}`)) + } + } + + return !hasErrors + } catch (error) { + console.error('Error:', error) + return false + } +} + +// CLI support - update to use import.meta.url instead of require.main +if (import.meta.url === `file://${process.argv[1]}`) { + const args = process.argv.slice(2) + if (args.includes('--pr')) { + validatePRChanges().then(success => { + process.exit(success ? 0 : 1) + }) + } +} \ No newline at end of file diff --git a/utils/types/metadata-types.ts b/utils/types/metadata-types.ts new file mode 100644 index 000000000..3080b57b1 --- /dev/null +++ b/utils/types/metadata-types.ts @@ -0,0 +1,119 @@ +import yaml from 'js-yaml' +import fs from 'fs' +import path from 'path' + +// Load and parse keywords.config.yaml +const configPath = path.join(process.cwd(), 'keywords.config.yaml') +const yamlContent = yaml.load(fs.readFileSync(configPath, 'utf8')) + +// Add debug logging +console.log('Config structure:', JSON.stringify(yamlContent, null, 2)) + +// Type guard to ensure the config has the expected structure +function isValidConfig(config: any): config is { + metadata_rules: { + persona: { + required: boolean + multiple: boolean + min: number + validation_rules: Array<{ + enum: string[] + description: string + }> + } + content_type: { + required: boolean + multiple: boolean + validation_rules: Array<{ + enum: string[] + description: string + }> + } + categories: { + required: boolean + multiple: boolean + min: number + max: number + validation_rules: Array<{ + no_duplicates: boolean + description: string + no_metadata_overlap?: { + fields: string[] + } + }> + values: string[] + } + } +} { + // Add debug logging + console.log('Checking config structure...') + console.log('Has metadata_rules:', !!config?.metadata_rules) + console.log('Has persona:', !!config?.metadata_rules?.persona) + console.log('Has content_type:', !!config?.metadata_rules?.content_type) + console.log('Has categories:', !!config?.metadata_rules?.categories) + + return ( + config && + config.metadata_rules && + config.metadata_rules.persona?.validation_rules?.[0]?.enum && + config.metadata_rules.content_type?.validation_rules?.[0]?.enum && + config.metadata_rules.categories?.values + ) +} + +if (!isValidConfig(yamlContent)) { + throw new Error('Invalid keywords.config.yaml structure') +} + +// Define the arrays with their literal types +export const VALID_PERSONAS: readonly string[] = yamlContent.metadata_rules.persona.validation_rules[0].enum +export const VALID_CONTENT_TYPES: readonly string[] = yamlContent.metadata_rules.content_type.validation_rules[0].enum +export const VALID_CATEGORIES: readonly string[] = yamlContent.metadata_rules.categories.values + +export interface ValidationRule { + pattern?: string + description?: string + enum?: string[] +} + +export interface MetadataField { + required?: boolean + multiple?: boolean + validation_rules?: ValidationRule[] +} + +export interface MetadataConfig { + metadata_rules?: { + topic?: MetadataField + persona?: MetadataField + content_type?: MetadataField + categories?: MetadataField + timeframe?: MetadataField + } +} + +// Type for metadata results +export interface MetadataResult { + title: string + lang: string + description: string + topic: string + personas: typeof VALID_PERSONAS[number][] + content_type: typeof VALID_CONTENT_TYPES[number] + categories: typeof VALID_CATEGORIES[number][] + is_imported_content: string + content?: string // Added for landing page detection + timeframe?: string + detectionLog?: string[] // Added for content analysis logging +} + +export interface ProcessedFile { + file: string + topic: string + is_imported: boolean +} + +export interface Manifest { + timestamp: string + processed_files: ProcessedFile[] +} \ No newline at end of file From 7fcd6dd8d1223dfc810c331c50685c8fdd140880 Mon Sep 17 00:00:00 2001 From: cpengilly <29023967+cpengilly@users.noreply.github.com> Date: Fri, 21 Feb 2025 22:43:38 -0800 Subject: [PATCH 2/5] lint-fixes --- .eslintrc.js => .eslintrc.cjs | 0 dist/tsconfig.tsbuildinfo | 1 + package.json | 14 ++- utils/breadcrumbs.ts | 21 ++-- utils/metadata-analyzer.ts | 120 +++++++-------------- utils/metadata-batch-cli.ts | 151 +++++++++++--------------- utils/metadata-manager.ts | 198 +++++++++++++++++++++++----------- utils/types/metadata-types.ts | 94 +++++++--------- 8 files changed, 290 insertions(+), 309 deletions(-) rename .eslintrc.js => .eslintrc.cjs (100%) create mode 100644 dist/tsconfig.tsbuildinfo diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/dist/tsconfig.tsbuildinfo b/dist/tsconfig.tsbuildinfo new file mode 100644 index 000000000..8768db2c4 --- /dev/null +++ b/dist/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"program":{"fileNames":["../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es5.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2016.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2021.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2023.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.esnext.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.dom.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.dom.iterable.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.core.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.collection.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.generator.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.promise.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.date.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.object.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.string.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.promise.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.array.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.object.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.string.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2019.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.date.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.promise.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.string.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2020.number.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2021.promise.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2021.string.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2021.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.array.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.error.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.object.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.string.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2023.array.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.es2023.collection.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.esnext.intl.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.esnext.disposable.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.esnext.decorators.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.decorators.d.ts","../node_modules/.pnpm/typescript@5.3.2/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/styled-jsx/types/css.d.ts","../node_modules/.pnpm/@types+react@18.2.36/node_modules/@types/react/global.d.ts","../node_modules/.pnpm/csstype@3.1.2/node_modules/csstype/index.d.ts","../node_modules/.pnpm/@types+prop-types@15.7.9/node_modules/@types/prop-types/index.d.ts","../node_modules/.pnpm/@types+scheduler@0.16.5/node_modules/@types/scheduler/tracing.d.ts","../node_modules/.pnpm/@types+react@18.2.36/node_modules/@types/react/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/styled-jsx/types/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/styled-jsx/types/macro.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/styled-jsx/types/style.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/styled-jsx/types/global.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/amp.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/amp.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/assert.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/assert/strict.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/globals.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/async_hooks.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/buffer.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/child_process.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/cluster.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/console.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/constants.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/crypto.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/dgram.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/diagnostics_channel.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/dns.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/dns/promises.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/domain.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/dom-events.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/events.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/fs.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/fs/promises.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/http.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/http2.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/https.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/inspector.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/module.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/net.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/os.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/path.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/perf_hooks.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/process.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/punycode.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/querystring.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/readline.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/readline/promises.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/repl.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/stream.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/stream/promises.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/stream/consumers.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/stream/web.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/string_decoder.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/test.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/timers.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/timers/promises.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/tls.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/trace_events.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/tty.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/url.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/util.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/v8.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/vm.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/wasi.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/worker_threads.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/zlib.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/globals.global.d.ts","../node_modules/.pnpm/@types+node@18.11.10/node_modules/@types/node/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/get-page-files.d.ts","../node_modules/.pnpm/@types+react@18.2.36/node_modules/@types/react/canary.d.ts","../node_modules/.pnpm/@types+react@18.2.36/node_modules/@types/react/experimental.d.ts","../node_modules/.pnpm/@types+react-dom@18.2.16/node_modules/@types/react-dom/index.d.ts","../node_modules/.pnpm/@types+react-dom@18.2.16/node_modules/@types/react-dom/canary.d.ts","../node_modules/.pnpm/@types+react-dom@18.2.16/node_modules/@types/react-dom/experimental.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/webpack/webpack.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/config.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/load-custom-routes.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/image-config.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/body-streams.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-kind.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-definitions/route-definition.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-matches/route-match.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/app-router-headers.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/request-meta.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/revalidate.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/config-shared.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/base-http/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/api-utils/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/node-environment.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/require-hook.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/node-polyfill-crypto.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/page-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/analysis/get-page-static-info.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/render-result.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/helpers/i18n-provider.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/next-url.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/cookies.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/request.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/response.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/setup-exception-listeners.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/constants.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/base-http/node.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/font-utils.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/route-module.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/deep-readonly.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/load-components.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-definitions/locale-route-definition.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-definitions/pages-route-definition.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/mitt.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/with-router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/route-loader.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/page-loader.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/bloom-filter.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-definitions/app-page-route-definition.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/constants.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/page-extensions-type.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/loaders/next-app-loader.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/app-dir-module.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/response-cache/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/response-cache/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/incremental-cache/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/hooks-server-context.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/static-generation-async-storage-instance.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/static-generation-async-storage.external.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/request-async-storage-instance.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/request-async-storage.external.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/create-error-handler.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/app-render.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/entrypoints.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/app-page/module.compiled.d.ts","../node_modules/.pnpm/@types+react@18.2.36/node_modules/@types/react/jsx-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/error-boundary.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/router-reducer/create-initial-router-state.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/app-router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/layout-router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/render-from-template-context.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/action-async-storage-instance.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/action-async-storage.external.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/client-page.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/search-params.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/not-found-boundary.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/rsc/preloads.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/rsc/postpone.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/rsc/taint.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/entry-base.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/templates/app-page.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/app-page/module.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/app-render/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/entrypoints.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/pages/module.compiled.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/templates/pages.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-modules/pages/module.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/render.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-definitions/pages-api-route-definition.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-matches/pages-api-route-match.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-matchers/route-matcher.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-matcher-providers/route-matcher-provider.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/route-matcher-managers/route-matcher-manager.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/normalizer.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/locale-route-normalizer.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/pathname-normalizer.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/suffix.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/rsc.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/prefix.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/postponed.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/action.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/prefetch-rsc.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/future/normalizers/request/next-data.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/base-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/image-optimizer.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/next-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/coalesced-function.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/router-utils/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/trace/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/trace/trace.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/trace/shared.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/trace/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/load-jsconfig.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack-config.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/webpack/plugins/define-env-plugin.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/build/swc/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/dev/parse-version-info.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/dev/hot-reloader-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/telemetry/storage.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/render-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/router-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/lib/dev-bundler-service.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/dev/static-paths-worker.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/dev/next-dev-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/next.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/extra-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/types/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","../node_modules/.pnpm/@next+env@14.2.21/node_modules/@next/env/dist/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/utils.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/pages/_app.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/app.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/cache.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/runtime-config.external.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/config.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/pages/_document.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/document.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/dynamic.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dynamic.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/pages/_error.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/error.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/head.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/head.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/draft-mode.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/headers.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/headers.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/get-img-props.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/image-component.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/shared/lib/image-external.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/image.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/link.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/link.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/redirect-status-code.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/redirect.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/not-found.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/navigation.react-server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/components/navigation.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/navigation.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/router.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/client/script.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/script.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/server/web/spec-extension/image-response.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/dist/compiled/@vercel/og/types.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/server.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/types/global.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/types/compiled.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/index.d.ts","../node_modules/.pnpm/next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next/image-types/global.d.ts","../next-env.d.ts","../components/calculator/inputs/textinput.tsx","../components/calculator/inputs/selectinput.tsx","../components/calculator/inputs/checkboxinput.tsx","../components/calculator/inputs/index.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/types/mongrule.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/types/growthbook.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/feature-repository.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/growthbook.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/sticky-bucket-service.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/growthbookclient.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/mongrule.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/util.d.ts","../node_modules/.pnpm/@growthbook+growthbook@1.3.1/node_modules/@growthbook/growthbook/dist/index.d.ts","../node_modules/.pnpm/@growthbook+growthbook-react@1.3.1_react@18.2.0/node_modules/@growthbook/growthbook-react/dist/growthbookreact.d.ts","../node_modules/.pnpm/@growthbook+growthbook-react@1.3.1_react@18.2.0/node_modules/@growthbook/growthbook-react/dist/index.d.ts","../lib/growthbook.ts","../node_modules/.pnpm/gray-matter@4.0.3/node_modules/gray-matter/gray-matter.d.ts","../node_modules/.pnpm/@algolia+cache-common@4.23.3/node_modules/@algolia/cache-common/dist/cache-common.d.ts","../node_modules/.pnpm/@algolia+logger-common@4.23.3/node_modules/@algolia/logger-common/dist/logger-common.d.ts","../node_modules/.pnpm/@algolia+requester-common@4.23.3/node_modules/@algolia/requester-common/dist/requester-common.d.ts","../node_modules/.pnpm/@algolia+transporter@4.23.3/node_modules/@algolia/transporter/dist/transporter.d.ts","../node_modules/.pnpm/@algolia+client-common@4.23.3/node_modules/@algolia/client-common/dist/client-common.d.ts","../node_modules/.pnpm/@algolia+client-search@4.23.3/node_modules/@algolia/client-search/dist/client-search.d.ts","../node_modules/.pnpm/@algolia+client-analytics@4.23.3/node_modules/@algolia/client-analytics/dist/client-analytics.d.ts","../node_modules/.pnpm/@algolia+client-personalization@4.23.3/node_modules/@algolia/client-personalization/dist/client-personalization.d.ts","../node_modules/.pnpm/@algolia+recommend@4.23.3/node_modules/@algolia/recommend/dist/recommend.d.ts","../node_modules/.pnpm/@algolia+recommend@4.23.3/node_modules/@algolia/recommend/index.d.ts","../node_modules/.pnpm/algoliasearch@4.23.3/node_modules/algoliasearch/dist/algoliasearch.d.ts","../node_modules/.pnpm/algoliasearch@4.23.3/node_modules/algoliasearch/index.d.ts","../utils/algolia-indexer.ts","../utils/breadcrumbs.ts","../utils/transaction-types.ts","../utils/calculator-helpers.ts","../utils/constants.ts","../utils/create-breadcrumbs.ts","../utils/fix-redirects.ts","../utils/gtag.ts","../utils/link-checker.ts","../node_modules/.pnpm/@types+js-yaml@4.0.9/node_modules/@types/js-yaml/index.d.ts","../utils/types/metadata-types.ts","../utils/metadata-analyzer.ts","../utils/metadata-manager.ts","../../../../node_modules/.pnpm/minipass@7.1.2/node_modules/minipass/dist/commonjs/index.d.ts","../../../../node_modules/.pnpm/lru-cache@11.0.2/node_modules/lru-cache/dist/commonjs/index.d.ts","../../../../node_modules/.pnpm/path-scurry@2.0.0/node_modules/path-scurry/dist/commonjs/index.d.ts","../../../../node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/commonjs/ast.d.ts","../../../../node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/commonjs/escape.d.ts","../../../../node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/commonjs/unescape.d.ts","../../../../node_modules/.pnpm/minimatch@10.0.1/node_modules/minimatch/dist/commonjs/index.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/pattern.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/processor.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/walker.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/ignore.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/glob.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/has-magic.d.ts","../../../../node_modules/.pnpm/glob@11.0.1/node_modules/glob/dist/commonjs/index.d.ts","../utils/metadata-batch-cli.ts","../utils/networks.ts","../utils/redirects.ts","../utils/contexts/algoliacontext.ts","../node_modules/.pnpm/@types+unist@2.0.9/node_modules/@types/unist/index.d.ts","../node_modules/.pnpm/@types+hast@2.3.7/node_modules/@types/hast/index.d.ts","../node_modules/.pnpm/@types+mdast@3.0.14/node_modules/@types/mdast/index.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/state.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/blockquote.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/break.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/code.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/delete.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/emphasis.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/footnote-reference.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/footnote.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/heading.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/html.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/image-reference.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/image.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/inline-code.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/link-reference.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/link.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/list-item.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/list.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/paragraph.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/root.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/strong.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/table.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/table-cell.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/table-row.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/text.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/thematic-break.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/handlers/index.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/lib/index.d.ts","../node_modules/.pnpm/mdast-util-to-hast@12.3.0/node_modules/mdast-util-to-hast/index.d.ts","../node_modules/.pnpm/vfile-message@3.1.4/node_modules/vfile-message/lib/index.d.ts","../node_modules/.pnpm/vfile-message@3.1.4/node_modules/vfile-message/index.d.ts","../node_modules/.pnpm/vfile@5.3.7/node_modules/vfile/lib/minurl.shared.d.ts","../node_modules/.pnpm/vfile@5.3.7/node_modules/vfile/lib/index.d.ts","../node_modules/.pnpm/vfile@5.3.7/node_modules/vfile/index.d.ts","../node_modules/.pnpm/unified@10.1.2/node_modules/unified/index.d.ts","../node_modules/.pnpm/remark-rehype@10.1.0/node_modules/remark-rehype/lib/index.d.ts","../node_modules/.pnpm/remark-rehype@10.1.0/node_modules/remark-rehype/index.d.ts","../node_modules/.pnpm/@types+unist@3.0.1/node_modules/@types/unist/index.d.ts","../node_modules/.pnpm/@types+hast@3.0.2/node_modules/@types/hast/index.d.ts","../node_modules/.pnpm/@types+estree@1.0.5/node_modules/@types/estree/index.d.ts","../node_modules/.pnpm/@types+estree-jsx@1.0.3/node_modules/@types/estree-jsx/index.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/plugin/rehype-recma.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/plugin/recma-document.d.ts","../node_modules/.pnpm/source-map@0.7.4/node_modules/source-map/source-map.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/plugin/recma-stringify.d.ts","../node_modules/.pnpm/periscopic@3.1.0/node_modules/periscopic/types/index.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/plugin/recma-jsx-rewrite.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/core.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/node-types.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/compile.d.ts","../node_modules/.pnpm/@types+mdx@2.0.9/node_modules/@types/mdx/types.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/util/resolve-evaluate-options.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/evaluate.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/lib/run.d.ts","../node_modules/.pnpm/@mdx-js+mdx@2.3.0/node_modules/@mdx-js/mdx/index.d.ts","../node_modules/.pnpm/@types+mdast@4.0.2/node_modules/@types/mdast/index.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/utils.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/oniglib.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/rule.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/rawgrammar.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/theme.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/encodedtokenattributes.d.ts","../node_modules/.pnpm/vscode-textmate@8.0.0/node_modules/vscode-textmate/release/main.d.ts","../node_modules/.pnpm/shiki@0.14.5/node_modules/shiki/dist/index.d.ts","../node_modules/.pnpm/rehype-pretty-code@0.9.11_shiki@0.14.5/node_modules/rehype-pretty-code/index.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/types-c8e621b7.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/types.d.mts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/types.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/meta/defaultseo.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/meta/nextseo.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/jsonld.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/carousel.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/newsarticle.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/jobposting.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/localbusiness.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/qapage.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/profilepage.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/sitelinkssearchbox.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/recipe.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/event.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/corporatecontact.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/collectionpage.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/product.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/softwareapp.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/video.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/videogame.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/organization.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/faqpage.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/logo.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/dataset.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/course.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/breadcrumb.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/brand.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/article.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/webpage.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/socialprofile.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/howto.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/image.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/campground.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/jsonld/park.d.ts","../node_modules/.pnpm/next-seo@6.4.0_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-seo/lib/index.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/typealiases.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/util.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/zoderror.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/locales/en.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/errors.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/parseutil.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/enumutil.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/errorutil.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/helpers/partialutil.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/types.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/external.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/lib/index.d.ts","../node_modules/.pnpm/zod@3.22.4/node_modules/zod/index.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/types-2e9b0ab5.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/normalize-pages.d.mts","../node_modules/.pnpm/@mdx-js+react@2.3.0_react@18.2.0/node_modules/@mdx-js/react/lib/index.d.ts","../node_modules/.pnpm/@mdx-js+react@2.3.0_react@18.2.0/node_modules/@mdx-js/react/index.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/mdx.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/button.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/callout.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/copy-to-clipboard.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/code.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/pre.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/steps.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/tabs.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/td.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/table.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/th.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/tr.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/cards.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/file-tree.d.mts","../node_modules/.pnpm/@theguild+remark-mermaid@0.0.5_react@18.2.0/node_modules/@theguild/remark-mermaid/dist/mermaid.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/components/index.d.mts","../node_modules/.pnpm/next-themes@0.2.1_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-themes/dist/types.d.ts","../node_modules/.pnpm/next-themes@0.2.1_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/next-themes/dist/index.d.ts","../node_modules/.pnpm/nextra-theme-docs@2.13.2_next@14.2.21_react-dom@18.2.0_react@18.2.0__react@18.2.0__next_bd34b1842cf97c85c6d0f270f0ac49ca/node_modules/nextra-theme-docs/dist/index.d.mts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/types.d.ts","../node_modules/.pnpm/@feelback+js@0.3.4/node_modules/@feelback/js/dist/content.d.ts","../node_modules/.pnpm/@feelback+js@0.3.4/node_modules/@feelback/js/dist/store.d.ts","../node_modules/.pnpm/@feelback+js@0.3.4/node_modules/@feelback/js/dist/feelback.d.ts","../node_modules/.pnpm/@feelback+js@0.3.4/node_modules/@feelback/js/dist/index.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/hooks/feelback.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/hooks/index-external.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/utils.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/buttonvalue.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/buttonvaluelist.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/radiovalue.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/radiovaluelist.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/question.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/answer.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/feelbackbuttonlist.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/feelbackbuttonform.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/form.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/parts/index.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/presets.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbackcontext.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbackpulse.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbackyesno.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbackreaction.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbackmessage.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/utils/types.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/utils/effects.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/utils/index.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/feelbacktaggedmessage.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/components/index.d.ts","../node_modules/.pnpm/@feelback+react@0.3.4_react@18.2.0/node_modules/@feelback/react/dist/index.d.ts","../node_modules/.pnpm/escape-string-regexp@5.0.0/node_modules/escape-string-regexp/index.d.ts","../components/search/highlight-matches.tsx","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/types.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/utils/render.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/button/button.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/checkbox/checkbox.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/close-button/close-button.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/hooks/use-by-comparator.d.ts","../node_modules/.pnpm/@floating-ui+utils@0.2.8/node_modules/@floating-ui/utils/dist/floating-ui.utils.d.ts","../node_modules/.pnpm/@floating-ui+core@1.6.8/node_modules/@floating-ui/core/dist/floating-ui.core.d.ts","../node_modules/.pnpm/@floating-ui+utils@0.2.8/node_modules/@floating-ui/utils/dom/floating-ui.utils.dom.d.ts","../node_modules/.pnpm/@floating-ui+dom@1.6.11/node_modules/@floating-ui/dom/dist/floating-ui.dom.d.ts","../node_modules/.pnpm/@floating-ui+react-dom@2.1.2_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.d.ts","../node_modules/.pnpm/@floating-ui+react@0.26.25_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@floating-ui/react/dist/floating-ui.react.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/internal/floating.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/label/label.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/combobox/combobox.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/data-interactive/data-interactive.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/description/description.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/dialog/dialog.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/disclosure/disclosure.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/field/field.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/fieldset/fieldset.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/focus-trap/focus-trap.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/input/input.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/legend/legend.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/listbox/listbox.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/menu/menu.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/popover/popover.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/portal/portal.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/radio-group/radio-group.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/select/select.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/switch/switch.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/tabs/tabs.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/textarea/textarea.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/internal/close-provider.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/components/transition/transition.d.ts","../node_modules/.pnpm/@headlessui+react@2.1.8_react-dom@18.2.0_react@18.2.0__react@18.2.0/node_modules/@headlessui/react/dist/index.d.ts","../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/clsx.d.ts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/hooks/use-mounted.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/hooks/use-fs-route.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/hooks/index.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/arrow-right.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/check.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/copy.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/discord.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/expand.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/github.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/globe.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/information-circle.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/menu.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/moon.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/spinner.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/sun.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/word-wrap.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/x.d.mts","../node_modules/.pnpm/nextra@2.13.2_patch_hash=81936321c37741ec218dc19817c4a4939f4655b8371e793561fc236bebccc2_8f36b33dad9342e2972e606d16883e48/node_modules/nextra/dist/icons/index.d.mts","../components/search/input.tsx","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_algoliaagent.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_getversion.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_tokenutils.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/extractadditionalparams.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/featuredetection.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/objectquerytracker.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/index.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/click.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/conversion.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/init.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/view.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/types.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/request.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_sendevent.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/insights.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_getfunctionalinterface.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/_processqueue.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/utils/getrequesterfornode.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/dist/entry-node-cjs.d.ts","../node_modules/.pnpm/search-insights@2.15.0/node_modules/search-insights/index-node.cjs.d.ts","../components/search/docsearch.tsx","../components/search/index.tsx","../components/footer.tsx","../node_modules/.pnpm/@remixicon+react@4.6.0_react@18.2.0/node_modules/@remixicon/react/index.d.ts","../components/askaibutton.tsx","../theme.config.tsx","../components/addresstable.tsx","../components/l1contracttable.tsx","../components/l2contracttable.tsx","../node_modules/.pnpm/toml@3.0.0/node_modules/toml/index.d.ts","../components/superchaincontracttable.tsx","../node_modules/.pnpm/@eth-optimism+tokenlist@9.0.9/node_modules/@eth-optimism/tokenlist/dist/optimism.tokenlist-d52a9b3a.d.ts","../node_modules/.pnpm/@eth-optimism+tokenlist@9.0.9/node_modules/@eth-optimism/tokenlist/dist/index.d.ts","../components/tokenlisttable.tsx","../components/wipcallout.tsx","../components/scrolldispatcher/index.tsx","../components/calculator/resultstable.tsx","../components/calculator/loader.tsx","../components/calculator/chainparametersform.tsx","../providers/growthbookprovider.tsx","../pages/_app.tsx","../pages/_document.tsx","../node_modules/.pnpm/dotenv@16.4.7/node_modules/dotenv/lib/main.d.ts","../../../../node_modules/.pnpm/@types+minimatch@5.1.2/node_modules/@types/minimatch/index.d.ts","../../../../node_modules/.pnpm/@types+glob@8.1.0/node_modules/@types/glob/index.d.ts","../../../../node_modules/.pnpm/marked@15.0.7/node_modules/marked/lib/marked.d.ts"],"fileInfos":[{"version":"f33e5332b24c3773e930e212cbb8b6867c8ba3ec4492064ea78e55a524d57450","affectsGlobalScope":true},"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","26f2f787e82c4222710f3b676b4d83eb5ad0a72fa7b746f03449e7a026ce5073","9a68c0c07ae2fa71b44384a839b7b8d81662a236d4b9ac30916718f7510b1b2d","5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","5514e54f17d6d74ecefedc73c504eadffdeda79c7ea205cf9febead32d45c4bc","1c0cdb8dc619bc549c3e5020643e7cf7ae7940058e8c7e5aefa5871b6d86f44b","bed7b7ba0eb5a160b69af72814b4dde371968e40b6c5e73d3a9f7bee407d158c",{"version":"21e41a76098aa7a191028256e52a726baafd45a925ea5cf0222eb430c96c1d83","affectsGlobalScope":true},{"version":"35299ae4a62086698444a5aaee27fc7aa377c68cbb90b441c9ace246ffd05c97","affectsGlobalScope":true},{"version":"138fb588d26538783b78d1e3b2c2cc12d55840b97bf5e08bca7f7a174fbe2f17","affectsGlobalScope":true},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true},{"version":"4443e68b35f3332f753eacc66a04ac1d2053b8b035a0e0ac1d455392b5e243b3","affectsGlobalScope":true},{"version":"bc47685641087c015972a3f072480889f0d6c65515f12bd85222f49a98952ed7","affectsGlobalScope":true},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true},{"version":"93495ff27b8746f55d19fcbcdbaccc99fd95f19d057aed1bd2c0cafe1335fbf0","affectsGlobalScope":true},{"version":"6fc23bb8c3965964be8c597310a2878b53a0306edb71d4b5a4dfe760186bcc01","affectsGlobalScope":true},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true},{"version":"bb42a7797d996412ecdc5b2787720de477103a0b2e53058569069a0e2bae6c7e","affectsGlobalScope":true},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true},{"version":"61c37c1de663cf4171e1192466e52c7a382afa58da01b1dc75058f032ddf0839","affectsGlobalScope":true},{"version":"b541a838a13f9234aba650a825393ffc2292dc0fc87681a5d81ef0c96d281e7a","affectsGlobalScope":true},{"version":"e0275cd0e42990dc3a16f0b7c8bca3efe87f1c8ad404f80c6db1c7c0b828c59f","affectsGlobalScope":true},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true},{"version":"49ed889be54031e1044af0ad2c603d627b8bda8b50c1a68435fe85583901d072","affectsGlobalScope":true},{"version":"e93d098658ce4f0c8a0779e6cab91d0259efb88a318137f686ad76f8410ca270","affectsGlobalScope":true},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true},{"version":"ec0104fee478075cb5171e5f4e3f23add8e02d845ae0165bfa3f1099241fa2aa","affectsGlobalScope":true},{"version":"2b72d528b2e2fe3c57889ca7baef5e13a56c957b946906d03767c642f386bbc3","affectsGlobalScope":true},{"version":"acae90d417bee324b1372813b5a00829d31c7eb670d299cd7f8f9a648ac05688","affectsGlobalScope":true},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true},{"version":"51e547984877a62227042850456de71a5c45e7fe86b7c975c6e68896c86fa23b","affectsGlobalScope":true},{"version":"62a4966981264d1f04c44eb0f4b5bdc3d81c1a54725608861e44755aa24ad6a5","affectsGlobalScope":true},{"version":"4fa6ed14e98aa80b91f61b9805c653ee82af3502dc21c9da5268d3857772ca05","affectsGlobalScope":true},{"version":"e6633e05da3ff36e6da2ec170d0d03ccf33de50ca4dc6f5aeecb572cedd162fb","affectsGlobalScope":true},{"version":"86a34c7a13de9cabc43161348f663624b56871ed80986e41d214932ddd8d6719","affectsGlobalScope":true},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true},{"version":"caccc56c72713969e1cfe5c3d44e5bab151544d9d2b373d7dbe5a1e4166652be","affectsGlobalScope":true},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true},{"version":"50d53ccd31f6667aff66e3d62adf948879a3a16f05d89882d1188084ee415bbc","affectsGlobalScope":true},{"version":"08a58483392df5fcc1db57d782e87734f77ae9eab42516028acbfe46f29a3ef7","affectsGlobalScope":true},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true},{"version":"13f6e6380c78e15e140243dc4be2fa546c287c6d61f4729bc2dd7cf449605471","affectsGlobalScope":true},{"version":"4350e5922fecd4bedda2964d69c213a1436349d0b8d260dd902795f5b94dc74b","affectsGlobalScope":true},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true},{"version":"33358442698bb565130f52ba79bfd3d4d484ac85fe33f3cb1759c54d18201393","affectsGlobalScope":true},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true},"0990a7576222f248f0a3b888adcb7389f957928ce2afb1cd5128169086ff4d29",{"version":"0bd5e7096c7bc02bf70b2cc017fc45ef489cb19bd2f32a71af39ff5787f1b56a","affectsGlobalScope":true},"4c68749a564a6facdf675416d75789ee5a557afda8960e0803cf6711fa569288","8c6aac56e9dddb1f02d8e75478b79da0d25a1d0e38e75d5b8947534f61f3785e","5f8f00356f6a82e21493b2d57b2178f11b00cf8960df00bd37bdcae24c9333ca",{"version":"26ec95a0b0ebe0e216b7e9a64a26d943a0f9ea3dac4b546385fb6092e0e9ceb9","affectsGlobalScope":true},"cc69795d9954ee4ad57545b10c7bf1a7260d990231b1685c147ea71a6faa265c","8bc6c94ff4f2af1f4023b7bb2379b08d3d7dd80c698c9f0b07431ea16101f05f","1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","57194e1f007f3f2cbef26fa299d4c6b21f4623a2eddc63dfeef79e38e187a36e","0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","7e771891adaa85b690266bc37bd6eb43bc57eecc4b54693ead36467e7369952a","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"ca72190df0eb9b09d4b600821c8c7b6c9747b75a1c700c4d57dc0bb72abc074c","affectsGlobalScope":true},"21a167fec8f933752fb8157f06d28fab6817af3ad9b0bdb1908a10762391eab9",{"version":"bb65c6267c5d6676be61acbf6604cf0a4555ac4b505df58ac15c831fcbff4e3e","affectsGlobalScope":true},"0c0cee62cb619aed81133b904f644515ba3064487002a7da83fd8aa07b1b4abd","5a94487653355b56018122d92392beb2e5f4a6c63ba5cef83bbe1c99775ef713",{"version":"d5135ad93b33adcce80b18f8065087934cdc1730d63db58562edcf017e1aad9b","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","afcc1c426b76db7ec80e563d4fb0ba9e6bcc6e63c2d7e9342e649dc56d26347f","bb9c4ffa5e6290c6980b63c815cdd1625876dadb2efaf77edbe82984be93e55e","75ecef44f126e2ae018b4abbd85b6e8a2e2ba1638ebec56cc64274643ce3567b","f30bb836526d930a74593f7b0f5c1c46d10856415a8f69e5e2fc3db80371e362","14b5aa23c5d0ae1907bc696ac7b6915d88f7d85799cc0dc2dcf98fbce2c5a67c","5c439dafdc09abe4d6c260a96b822fa0ba5be7203c71a63ab1f1423cd9e838ea",{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true},{"version":"816ad2e607a96de5bcac7d437f843f5afd8957f1fa5eefa6bba8e4ed7ca8fd84","affectsGlobalScope":true},"cec36af22f514322f870e81d30675c78df82ae8bf4863f5fd4e4424c040c678d","d903fafe96674bc0b2ac38a5be4a8fc07b14c2548d1cdb165a80ea24c44c0c54","b01a80007e448d035a16c74b5c95a5405b2e81b12fabcf18b75aa9eb9ef28990","04eb6578a588d6a46f50299b55f30e3a04ef27d0c5a46c57d8fcc211cd530faa","dbe5aa5a5dd8bd1c6a8d11b1310c3f0cdabaacc78a37b394a8c7b14faeb5fb84","2c828a5405191d006115ab34e191b8474bc6c86ffdc401d1a9864b1b6e088a58",{"version":"e8b18c6385ff784228a6f369694fcf1a6b475355ba89090a88de13587a9391d5","affectsGlobalScope":true},"d076fede3cb042e7b13fc29442aaa03a57806bc51e2b26a67a01fbc66a7c0c12","7c013aa892414a7fdcfd861ae524a668eaa3ede8c7c0acafaf611948122c8d93","b0973c3cbcdc59b37bf477731d468696ecaf442593ec51bab497a613a580fe30",{"version":"4989e92ba5b69b182d2caaea6295af52b7dc73a4f7a2e336a676722884e7139d","affectsGlobalScope":true},{"version":"b3624aed92dab6da8484280d3cb3e2f4130ec3f4ef3f8201c95144ae9e898bb6","affectsGlobalScope":true},"5153a2fd150e46ce57bb3f8db1318d33f6ad3261ed70ceeff92281c0608c74a3","210d54cd652ec0fec8c8916e4af59bb341065576ecda039842f9ffb2e908507c","36b03690b628eab08703d63f04eaa89c5df202e5f1edf3989f13ad389cd2c091","0effadd232a20498b11308058e334d3339cc5bf8c4c858393e38d9d4c0013dcf","25846d43937c672bab7e8195f3d881f93495df712ee901860effc109918938cc","fd93cee2621ff42dabe57b7be402783fd1aa69ece755bcba1e0290547ae60513","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","69ee23dd0d215b09907ad30d23f88b7790c93329d1faf31d7835552a10cf7cbf","44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","23b89798789dffbd437c0c423f5d02d11f9736aea73d6abf16db4f812ff36eda","213fc4f2b172d8beb74b77d7c1b41488d67348066d185e4263470cbb010cd6e8",{"version":"970a90f76d4d219ad60819d61f5994514087ba94c985647a3474a5a3d12714ed","affectsGlobalScope":true},"664d8f2d59164f2e08c543981453893bc7e003e4dfd29651ce09db13e9457980","4c8525f256873c7ba3135338c647eaf0ca7115a1a2805ae2d0056629461186ce","3c13ef48634e7b5012fcf7e8fce7496352c2d779a7201389ca96a2a81ee4314d","5d0a25ec910fa36595f85a67ac992d7a53dd4064a1ba6aea1c9f14ab73a023f2",{"version":"f0900cd5d00fe1263ff41201fb8073dbeb984397e4af3b8002a5c207a30bdc33","affectsGlobalScope":true},{"version":"f7db71191aa7aac5d6bc927ed6e7075c2763d22c7238227ec0c63c8cf5cb6a8b","affectsGlobalScope":true},"06d7c42d256f0ce6afe1b2b6cfbc97ab391f29dadb00dd0ae8e8f23f5bc916c3","ec4bd1b200670fb567920db572d6701ed42a9641d09c4ff6869768c8f81b404c","e59a892d87e72733e2a9ca21611b9beb52977be2696c7ba4b216cbbb9a48f5aa",{"version":"da26af7362f53d122283bc69fed862b9a9fe27e01bc6a69d1d682e0e5a4df3e6","affectsGlobalScope":true},"8a300fa9b698845a1f9c41ecbe2c5966634582a8e2020d51abcace9b55aa959e",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"e9a8d4274033cb520ee12d6f68d161ba2b9128b87399645d3916b71187032836","8caa5c86be1b793cd5f599e27ecb34252c41e011980f7d61ae4989a149ff6ccc","481231c1fc9d8efbceb62a6265af69d5cd5a49676df9c4214ecb5b81f0077a75","3303f49a2c7c25d8b5dbe0f93be5dccbb62dbea43bca9565c35c4737934dc2a4","4355c807c60f6b8a69ee3307c5f9adde7d8303172bcfa4805fa804511a6c3ce2","59cf0ee776606259a2a159b0e94a254098bb2b1202793e3f0723a04009d59f4b","bb7a61dd55dc4b9422d13da3a6bb9cc5e89be888ef23bbcf6558aa9726b89a1c","db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","cfe4ef4710c3786b6e23dae7c086c70b4f4835a2e4d77b75d39f9046106e83d3","cbea99888785d49bb630dcbb1613c73727f2b5a2cf02e1abcaab7bcf8d6bf3c5","3989ccb24f2526f7e82cf54268e23ce9e1df5b9982f8acd099ddd4853c26babd","a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","2dad084c67e649f0f354739ec7df7c7df0779a28a4f55c97c6b6883ae850d1ce","fa5bbc7ab4130dd8cdc55ea294ec39f76f2bc507a0f75f4f873e38631a836ca7","df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","cf86de1054b843e484a3c9300d62fbc8c97e77f168bbffb131d560ca0474d4a8","196c960b12253fde69b204aa4fbf69470b26daf7a430855d7f94107a16495ab0","ee15ea5dd7a9fc9f5013832e5843031817a880bf0f24f37a29fd8337981aae07","bf24f6d35f7318e246010ffe9924395893c4e96d34324cde77151a73f078b9ad","805c5db07d4b131bede36cc2dbded64cc3c8e49594e53119f4442af183f97935","10595c7ff5094dd5b6a959ccb1c00e6a06441b4e10a87bc09c15f23755d34439","9620c1ff645afb4a9ab4044c85c26676f0a93e8c0e4b593aea03a89ccb47b6d0","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","a9af0e608929aaf9ce96bd7a7b99c9360636c31d73670e4af09a09950df97841","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","08ed0b3f0166787f84a6606f80aa3b1388c7518d78912571b203817406e471da","47e5af2a841356a961f815e7c55d72554db0c11b4cba4d0caab91f8717846a94","65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","f5f541902bf7ae0512a177295de9b6bcd6809ea38307a2c0a18bfca72212f368","b0decf4b6da3ebc52ea0c96095bdfaa8503acc4ac8e9081c5f2b0824835dd3bd","ca1b882a105a1972f82cc58e3be491e7d750a1eb074ffd13b198269f57ed9e1b","fc3e1c87b39e5ba1142f27ec089d1966da168c04a859a4f6aab64dceae162c2b","3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","61888522cec948102eba94d831c873200aa97d00d8989fdfd2a3e0ee75ec65a2","4e10622f89fea7b05dd9b52fb65e1e2b5cbd96d4cca3d9e1a60bb7f8a9cb86a1","74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","59bf32919de37809e101acffc120596a9e45fdbab1a99de5087f31fdc36e2f11","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","3c4b45e48c56c17fb44b3cab4e2a6c8f64c4fa2c0306fe27d33c52167c0b7fa7","c40c848daad198266370c1c72a7a8c3d18d2f50727c7859fcfefd3ff69a7f288","ac60bbee0d4235643cc52b57768b22de8c257c12bd8c2039860540cab1fa1d82","6428e6edd944ce6789afdf43f9376c1f2e4957eea34166177625aaff4c0da1a0","ada39cbb2748ab2873b7835c90c8d4620723aedf323550e8489f08220e477c7f","6e5f5cee603d67ee1ba6120815497909b73399842254fc1e77a0d5cdc51d8c9c","8dba67056cbb27628e9b9a1cba8e57036d359dceded0725c72a3abe4b6c79cd4","70f3814c457f54a7efe2d9ce9d2686de9250bb42eb7f4c539bd2280a42e52d33","154dd2e22e1e94d5bc4ff7726706bc0483760bae40506bdce780734f11f7ec47","ef61792acbfa8c27c9bd113f02731e66229f7d3a169e3c1993b508134f1a58e0","9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","15e3409b8397457d761d8d6f8c524795845c3aeb5dd0d4291ca0c54fec670b72","f6404e7837b96da3ea4d38c4f1a3812c96c9dcdf264e93d5bdb199f983a3ef4b","c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027",{"version":"8b8f00491431fe82f060dfe8c7f2180a9fb239f3d851527db909b83230e75882","affectsGlobalScope":true},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true},"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369",{"version":"903e299a28282fa7b714586e28409ed73c3b63f5365519776bf78e8cf173db36","affectsGlobalScope":true},"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b",{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true},"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","dd3900b24a6a8745efeb7ad27629c0f8a626470ac229c1d73f1fe29d67e44dca","ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","ec29be0737d39268696edcec4f5e97ce26f449fa9b7afc2f0f99a86def34a418","aeab39e8e0b1a3b250434c3b2bb8f4d17bbec2a9dbce5f77e8a83569d3d2cbc2","ec6cba1c02c675e4dd173251b156792e8d3b0c816af6d6ad93f1a55d674591aa","b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","d729408dfde75b451530bcae944cf89ee8277e2a9df04d1f62f2abfd8b03c1e1","e15d3c84d5077bb4a3adee4c791022967b764dc41cb8fa3cfa44d4379b2c95f5","5f58e28cd22e8fc1ac1b3bc6b431869f1e7d0b39e2c21fbf79b9fa5195a85980","e1fc1a1045db5aa09366be2b330e4ce391550041fc3e925f60998ca0b647aa97","63533978dcda286422670f6e184ac516805a365fb37a086eeff4309e812f1402","43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","31fb49ef3aa3d76f0beb644984e01eab0ea222372ea9b49bb6533be5722d756c","33cd131e1461157e3e06b06916b5176e7a8ec3fce15a5cfe145e56de744e07d2","889ef863f90f4917221703781d9723278db4122d75596b01c429f7c363562b86","3556cfbab7b43da96d15a442ddbb970e1f2fc97876d055b6555d86d7ac57dae5","437751e0352c6e924ddf30e90849f1d9eb00ca78c94d58d6a37202ec84eb8393","48e8af7fdb2677a44522fd185d8c87deff4d36ee701ea003c6c780b1407a1397","d11308de5a36c7015bb73adb5ad1c1bdaac2baede4cc831a05cf85efa3cc7f2f","38e4684c22ed9319beda6765bab332c724103d3a966c2e5e1c5a49cf7007845f",{"version":"f9812cfc220ecf7557183379531fa409acd249b9e5b9a145d0d52b76c20862de","affectsGlobalScope":true},"0a403c4aeeb153bc0c1f11458d005f8e5a0af3535c4c93eedc6f7865a3593f8e","2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","680793958f6a70a44c8d9ae7d46b7a385361c69ac29dcab3ed761edce1c14ab8","6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","2879a055439b6c0c0132a1467120a0f85b56b5d735c973ad235acd958b1b5345","913ddbba170240070bd5921b8f33ea780021bdf42fbdfcd4fcb2691b1884ddde","b4e6d416466999ff40d3fe5ceb95f7a8bfb7ac2262580287ac1a8391e5362431","5fe23bd829e6be57d41929ac374ee9551ccc3c44cee893167b7b5b77be708014","0a626484617019fcfbfc3c1bc1f9e84e2913f1adb73692aa9075817404fb41a1","438c7513b1df91dcef49b13cd7a1c4720f91a36e88c1df731661608b7c055f10","cf185cc4a9a6d397f416dd28cca95c227b29f0f27b160060a95c0e5e36cda865","0086f3e4ad898fd7ca56bb223098acfacf3fa065595182aaf0f6c4a6a95e6fbd","efaa078e392f9abda3ee8ade3f3762ab77f9c50b184e6883063a911742a4c96a","54a8bb487e1dc04591a280e7a673cdfb272c83f61e28d8a64cf1ac2e63c35c51","021a9498000497497fd693dd315325484c58a71b5929e2bbb91f419b04b24cea","9385cdc09850950bc9b59cca445a3ceb6fcca32b54e7b626e746912e489e535e","2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","84124384abae2f6f66b7fbfc03862d0c2c0b71b826f7dbf42c8085d31f1d3f95","63a8e96f65a22604eae82737e409d1536e69a467bb738bec505f4f97cce9d878","3fd78152a7031315478f159c6a5872c712ece6f01212c78ea82aef21cb0726e2","250f9a1f11580b6b8a0a86835946f048eb605b3a596196741bfe72dc8f6c69cc","512fc15cca3a35b8dbbf6e23fe9d07e6f87ad03c895acffd3087ce09f352aad0","9a0946d15a005832e432ea0cd4da71b57797efb25b755cc07f32274296d62355","a52ff6c0a149e9f370372fc3c715d7f2beee1f3bab7980e271a7ab7d313ec677","fd933f824347f9edd919618a76cdb6a0c0085c538115d9a287fa0c7f59957ab3","6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","6a1aa3e55bdc50503956c5cd09ae4cd72e3072692d742816f65c66ca14f4dfdd","ab75cfd9c4f93ffd601f7ca1753d6a9d953bbedfbd7a5b3f0436ac8a1de60dfa","f95180f03d827525ca4f990f49e17ec67198c316dd000afbe564655141f725cd","b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","1364f64d2fb03bbb514edc42224abd576c064f89be6a990136774ecdd881a1da","c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","950fb67a59be4c2dbe69a5786292e60a5cb0e8612e0e223537784c731af55db1","e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","07ca44e8d8288e69afdec7a31fa408ce6ab90d4f3d620006701d5544646da6aa","70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","4e4475fba4ed93a72f167b061cd94a2e171b82695c56de9899275e880e06ba41","97c5f5d580ab2e4decd0a3135204050f9b97cd7908c5a8fbc041eadede79b2fa","c99a3a5f2215d5b9d735aa04cec6e61ed079d8c0263248e298ffe4604d4d0624","49b2375c586882c3ac7f57eba86680ff9742a8d8cb2fe25fe54d1b9673690d41","802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","9ff1e8df66450af44161c1bfe34bc92c43074cfeec7a0a75f721830e9aabe379","3ecfccf916fea7c6c34394413b55eb70e817a73e39b4417d6573e523784e3f8e","1630192eac4188881201c64522cd3ef08209d9c4db0f9b5f0889b703dc6d936a","6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","f416c9c3eee9d47ff49132c34f96b9180e50485d435d5748f0e8b72521d28d2e","05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","14e5cdec6f8ae82dfd0694e64903a0a54abdfe37e1d966de3d4128362acbf35f","bbc183d2d69f4b59fd4dd8799ffdf4eb91173d1c4ad71cce91a3811c021bf80c","7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","8dbc4134a4b3623fc476be5f36de35c40f2768e2e3d9ed437e0d5f1c4cd850f6","4e06330a84dec7287f7ebdd64978f41a9f70a668d3b5edc69d5d4a50b9b376bb","65bfa72967fbe9fc33353e1ac03f0480aa2e2ea346d61ff3ea997dfd850f641a","c06f0bb92d1a1a5a6c6e4b5389a5664d96d09c31673296cb7da5fe945d54d786","f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","872caaa31423f4345983d643e4649fb30f548e9883a334d6d1c5fff68ede22d4","94404c4a878fe291e7578a2a80264c6f18e9f1933fbb57e48f0eb368672e389c","5c1b7f03aa88be854bc15810bfd5bd5a1943c5a7620e1c53eddd2a013996343e","09dfc64fcd6a2785867f2368419859a6cc5a8d4e73cbe2538f205b1642eb0f51","bcf6f0a323653e72199105a9316d91463ad4744c546d1271310818b8cef7c608","01aa917531e116485beca44a14970834687b857757159769c16b228eb1e49c5f","351475f9c874c62f9b45b1f0dc7e2704e80dfd5f1af83a3a9f841f9dfe5b2912","ac457ad39e531b7649e7b40ee5847606eac64e236efd76c5d12db95bf4eacd17","187a6fdbdecb972510b7555f3caacb44b58415da8d5825d03a583c4b73fde4cf","d4c3250105a612202289b3a266bb7e323db144f6b9414f9dea85c531c098b811","95b444b8c311f2084f0fb51c616163f950fb2e35f4eaa07878f313a2d36c98a4","741067675daa6d4334a2dc80a4452ca3850e89d5852e330db7cb2b5f867173b1","f8acecec1114f11690956e007d920044799aefeb3cece9e7f4b1f8a1d542b2c9","178071ccd043967a58c5d1a032db0ddf9bd139e7920766b537d9783e88eb615e","3a17f09634c50cce884721f54fd9e7b98e03ac505889c560876291fcf8a09e90","32531dfbb0cdc4525296648f53b2b5c39b64282791e2a8c765712e49e6461046","0ce1b2237c1c3df49748d61568160d780d7b26693bd9feb3acb0744a152cd86d","e489985388e2c71d3542612685b4a7db326922b57ac880f299da7026a4e8a117","5cad4158616d7793296dd41e22e1257440910ea8d01c7b75045d4dfb20c5a41a",{"version":"04d3aad777b6af5bd000bfc409907a159fe77e190b9d368da4ba649cdc28d39e","affectsGlobalScope":true},"74efc1d6523bd57eb159c18d805db4ead810626bc5bc7002a2c7f483044b2e0f","19252079538942a69be1645e153f7dbbc1ef56b4f983c633bf31fe26aeac32cd","bc11f3ac00ac060462597add171220aed628c393f2782ac75dd29ff1e0db871c","616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","3b0b1d352b8d2e47f1c4df4fb0678702aee071155b12ef0185fce9eb4fa4af1e","77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","a344403e7a7384e0e7093942533d309194ad0a53eca2a3100c0b0ab4d3932773","b7fff2d004c5879cae335db8f954eb1d61242d9f2d28515e67902032723caeab","5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","bb18bf4a61a17b4a6199eb3938ecfa4a59eb7c40843ad4a82b975ab6f7e3d925","4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","e9b6fc05f536dfddcdc65dbcf04e09391b1c968ab967382e48924f5cb90d88e1","a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","2b664c3cc544d0e35276e1fb2d4989f7d4b4027ffc64da34ec83a6ccf2e5c528","a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","3cd8f0464e0939b47bfccbb9bb474a6d87d57210e304029cd8eb59c63a81935d","47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","3026abd48e5e312f2328629ede6e0f770d21c3cd32cee705c450e589d015ee09","8b140b398a6afbd17cc97c38aea5274b2f7f39b1ae5b62952cfe65bf493e3e75","7663d2c19ce5ef8288c790edba3d45af54e58c84f1b37b1249f6d49d962f3d91","5cce3b975cdb72b57ae7de745b3c5de5790781ee88bcb41ba142f07c0fa02e97","00bd6ebe607246b45296aa2b805bd6a58c859acecda154bfa91f5334d7c175c6","ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","0d28b974a7605c4eda20c943b3fa9ae16cb452c1666fc9b8c341b879992c7612","cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","87ac2fb61e629e777f4d161dff534c2023ee15afd9cb3b1589b9b1f014e75c58","13c8b4348db91e2f7d694adc17e7438e6776bc506d5c8f5de9ad9989707fa3fe","3c1051617aa50b38e9efaabce25e10a5dd9b1f42e372ef0e8a674076a68742ed","07a3e20cdcb0f1182f452c0410606711fbea922ca76929a41aacb01104bc0d27","1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","4cd4b6b1279e9d744a3825cbd7757bbefe7f0708f3f1069179ad535f19e8ed2c","5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","c0eeaaa67c85c3bb6c52b629ebbfd3b2292dc67e8c0ffda2fc6cd2f78dc471e6","4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","b95a6f019095dd1d48fd04965b50dfd63e5743a6e75478343c46d2582a5132bf","c2008605e78208cfa9cd70bd29856b72dda7ad89df5dc895920f8e10bcb9cd0a","b97cb5616d2ab82a98ec9ada7b9e9cabb1f5da880ec50ea2b8dc5baa4cbf3c16",{"version":"d23df9ff06ae8bf1dcb7cc933e97ae7da418ac77749fecee758bb43a8d69f840","affectsGlobalScope":true},{"version":"040c71dde2c406f869ad2f41e8d4ce579cc60c8dbe5aa0dd8962ac943b846572","affectsGlobalScope":true},"3586f5ea3cc27083a17bd5c9059ede9421d587286d5a47f4341a4c2d00e4fa91","a6df929821e62f4719551f7955b9f42c0cd53c1370aec2dd322e24196a7dfe33","b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","daeb16c108ebc4ae4551a4e71cf50ab66430b0908d8637d9e3f08122ca030ba0","7ea3d7570a5b9143b621bb0975b0c83b525dec773fd786bc46bddac8f2f83443","144f48f065aec73d0b8bc13eaf3aab0d8967adb723352f54a8e87d270f59c38b","c9881df13d3b83e39a3dd10095c81e0259a7e6abf69e1b830258cb078a05997f","66d7e78620a60360099b121ac10b3b5e0d4d09abddcaa29dff48aa001337a759","d3d979bd49df9f29d3dd87af72dd69d901ea25a8d0d5d95d69c486a2da95a60f",{"version":"6dd89f1e0cf56974505ae5bfaa5dff7d0943fd0212e8dbd36214c26fa0c7df22","affectsGlobalScope":true},"d38504f05d7d48c4c180db2e904ce1e8feb711ecdfc2fa449176dfc339356e53","0bee232f47de396031244df3155c0528c663c908750367a5d7129e954a916e05","3a2aa153bbf2ab337c3b203a8b796994f52f29a91226f38766f2d35ed4e19036","9104959cd2ae96936b5c9ddcb64a00005eb0e78ed8ca794e82fe5db27f549102","c4ed26d7fbca04a543526576dab6d0cb4ede0358df830eb580162aa05c76a9a2","fc07cd4c34f58e07d27aa8e1962c77318b5a17b38e7864a720165eb3e5272ab3","210e2a4f746faba9f51e961f84880cc51c8a86b518717f7242a573214df0793d","d84a32ce484b39f5b7bf1ffeb7968cf835e81dc3209a7f5a42e5a0bc7c07dfa7","3693047afa2a0ab6dc3accf98583a628ecccc0243296455b1f90ac1c67c686f6","e53477e727e3174cfd58283e25589a1d33160a01bd5b2a5cbdb719a3ad2686ae","a52c5f687d788d283ea1fa38bdc2fabe0eac863135a7dfe175ec52b309f61892","1c63d5b41e9d3fed9eb0410c75425d66392a397cc3bcb99311b9d770940b6c71","71a8f7be5e1124c9b7e9b627ee6427978d138a6e924b52df7baf098e2aa6c360","a62304125fdfb135b3bfe8285f9de0a1e7ad4eb4e7a1dee2193789ba10bd2aa9","d06a001cba9b383f004d6bb7092514fc1f9316ea5ffa692a47614df0a54917fd","b6f0cb20d23b726c3b30dbf7c30ce55755270efed7aa522b7cd49021cec2f1fb","76de10456713070bfdc5d4e7ccbf993e1b245e1dc4537b44ac4cfae7ed9e54af","7c1008c9f2d92ac691ed3bd251b2ca1e1a6bc57a7fbeb1d2c60659d501b28934","4a65bd0d86eb8ca3d230793eb504b97da8d00c16deaa75ebe45beae60756af0a","d864c9468e8095ad5108d87ad99417cdb640028c36637424a4e497f363617988","d18bf9bcf758d2829cc67507fab7f42f6e2c081a4b5ed4c0f1a544418d8ab86d","991f961026deb1f58801ec5250dac259e1516ede3e55d4b60cb1466ad756a499","0e4609fa4248dafecf5cf00d0cf0c62d72d3c8e4d7b087887f0936b66c46e7dd","e052f5cf4a84587df82f79a3f8d3fef05c5a5c852658cac8101850383961b7e5","3f02dc797fcd799b2afb51acbaa425f287ead4d7a4a013928311bc86495f8d08","ac118e52fa63115d15e11a8570d316f3a33f2b1f57bb1bf30eb292dc1f3a5b0f","5a6fb9ea5a20479bfa2b85cd25c7cb204817495db8e4d5d33a80cecc99ebc76a","1beafcdb3782ace2aa9407c3d2a361d38642d416ee49f3f953e91e720424eb73","c120b3dd184f8d32d4530d753b94d35e5e59368992a21a22d01c7be16dc82a98","e3ed954db53897c287ab7b96eac3597d47f9ae678e88132f0a66cdece5fdaff1","0f079d36b137c14f97d1fe55a942e897a3d11395d6f71892feb1f1d7f203e526","f7e11830fcaa8b65fb0426f99432c7a3b343c76d19001a10b2e3bcd2a1fa13b4","7a1dd1e9c8bf5e23129495b10718b280340c7500570e0cfe5cffcdee51e13e48","5386427d1c80cfa63800d46818d83813afff0b19bf1dc6fa3da77832ff9b965f","b7886d10d6d11902dde7fa6006245418ec46c026b7fcb1c70c851ae426feb9a0","55f172d110bac1a456570a4e5d6e3577829f26a7bd7a4b0508dcec48951fff1d","041597c12abeaa2ef07766775955fc87cfc65c43e0fe86c836071bea787e967c","d50a79748095284de5c093814c97c21a5c4849abf505161fe70d8ee6989e4142","072f583571d6e3d30cd9760ee3485d29484fb7b54ba772ac135c747a380096a1","7212c2d58855b8df35275180e97903a4b6093d4fbaefea863d8d028da63938c6","5bd0f306b4a9dc65bccf38d9295bc52720d2fa455e06f604529d981b5eb8d9dc","f30992084e86f4b4c223c558b187cb0a9e83071592bd830d8ff2a471ee2bf2d4","854045924626ba585f454b53531c42aed4365f02301aa8eca596423f4675b71f","dd9faff42b456b5f03b85d8fbd64838eb92f6f7b03b36322cbc59c005b7033d3","6ff702721d87c0ba8e7f8950e7b0a3b009dfd912fab3997e0b63fab8d83919c3","9dce9fc12e9a79d1135699d525aa6b44b71a45e32e3fa0cf331060b980b16317","586b2fd8a7d582329658aaceec22f8a5399e05013deb49bcfde28f95f093c8ee","59c44b081724d4ab8039988aba34ee6b3bd41c30fc2d8686f4ed06588397b2f7","ef1f3eadd7bed282de45bafd7c2c00105cf1db93e22f6cd763bec8a9c2cf6df1","3d8885d13f76ff35b7860039e83c936ff37553849707c2fd1d580d193a52be5b","8764baaf09e26543b7d0bf98304bfccd8da0a1de170ba43f7a20f3806abf3d26","f8aba62449b7106d4c83bbeb64fb325ebf5de068f944699096445afc25db3fe4","a9d68ddc185a8401a98b0855ce3858951b4ec1ccdf14de2fa49213f04769593e","e895ff3f54eac7e704ba0781d5b8d442aa1fdf9231b120e365a34147f57a8522","6d09838b65c3c780513878793fc394ae29b8595d9e4729246d14ce69abc71140","68ca20e199b40a7ad73a1cc3b7f53123ab2dbc6c36d15413b2cce8c0212edd4c","202f8582ee3cd89e06c4a17d8aabb925ff8550370559c771d1cc3ec3934071c2","8b0a2400ba7522569871331988f820ba4cfc386f845b01058c63a62ad9db8d03","d3e29566a694a4068d450a58f59e3a3662fc12f74345343d441ef4d954984503","f7b3e68f7972250809e5b0cbd8f0e1f9da8c1dbf70244f289b204f1b49c2d398","4c7c99f7787c5c2ea6cbd911a7b5c7c2a4ee1cb9d7f538805ee2550cf1f1fb99","1557bf37fc8d5f129436caa0212f25d6cbeaf9d20e2e3a60b13306ff62a1d7a0","9a1e77270d63875c9a38630f9a7a9126f9a8df0245d5eb220832a65d408079eb","e48d0036e626bb40f236e236670722445ffff854908c2d9515b2b5b7f677794f","30f9018873d6d80256298011161a664a14b927f719f8a7605ceb8b49bc8808da","f543ea0fe820064a2cdbb39d2b2846c507467c4771eafcda2091da43b05c077b","9066d02264a67aae05410c340c8fa41a79bb076c33d1c6ae3ec29a05828f4c05","00435c177c3da6998c2f95b9e71239f00cfabd3461401cc4d8606ee3afb732b1","d432a2956d1efa172e1c60a8186a81657f2f9f4ba449c6abdfa9d057d484c45d","bc6679207eccaa45e49b930ad45ec8e7903bd8b0868e086d8bad91f79c914ca0","4dd35e71d52007465787dd2f374cc756a29e6c9b96dc237d0465d0294170c529","7ebf1f440efe6efebeb58a44000820cbe959da9d9496621fa6dcbc02666e3002","08a9e70641597e23d00be62e3a94b69ad93c5cf5541ec7bfdeb5e9f69c845507","ded59c554118589a8729fb70429318e41e7e8155b2aff5f3d7a77933e49dbc10","3af507089e65c1472a87e5f7345ec18838d7e923c2c06fdad3d31543278af762","c867e6d7de78f96eb55b534b3aca1da4e029a6ab0e4ea9d0610acf11d737f8a0","2df075b38e2135201202640fe92bce8d03fb319fece410b088a22ab4e1be7702","b9f07153f8e881c4cca036abccaa134df30cf09a3381772d089d1eeabe45770d","88213e972b5989f217627bdcb79a697f66821e8ff135265712346d532243084f","bf6122555f34582e6d5424a88676d90f2333e0e920764895c15d39b6c856053c","bf04a1c9ccfeabf521b7b97f388d05bc5f628422253399eb157fec0d9cd213ce","3c6ecfcc6ac82b5866368d1efbddeeb3bfae03962747bf6928d8faa092e5b369","06d19317f4c8474255b3ceab7102763faf7ff0aa4cc305384b13ccb6d27b2e50","ebe1694b3a7a0265b9cf8fb3bfed6575907247b61add671ea9771fd6715d1b29","bdf4a7242e5cce621b5ba689351af780b0b665d97ea88c71f50801aa80560236","e0c7d85789b8811c90a8d21e25021349e8a756a256ae42d9e816ecd392f00f71","bb8aba28c9589792407d6ae0c1a6568f3ddc40be20da25bc1939e2c9d76436bb","8fa1868ab5af3818ff4746f383ea84206596e284f7dc5ffd40a0fac08ed093f9","8d4537ea6fcdde620af5bfb4e19f88db40d44073f76f567283aa043b81ef8a3e","0bb848976eff244e33741d63372cbfb4d15153a92c171d0a374a3c0ef327a175","af79b166f5d41ec2ebae57e9b67df564452b90ae3f0af4cb3c2d8ad5adbfd2db","6bd6ae32288500128ae355de57d6bc3b5884f37e1e5d5ac597b142f63b3c8121","a6634dbc56e3d75efac697e59fef032aa15cc537acf7f6ad3a045001f48483f8","89121c1bf2990f5219bfd802a3e7fc557de447c62058d6af68d6b6348d64499a","79b4369233a12c6fa4a07301ecb7085802c98f3a77cf9ab97eee27e1656f82e6","ee7d8894904b465b072be0d2e4b45cf6b887cdba16a467645c4e200982ece7ea","446b5dbbcbd8b9b1676f0ed77cb6bcd0d3adec82feddfd2f9d99ce9174126bd3","16504c568924627fcf340804a3a1d3845490194df479983147007d83ba347a18","7253cdf6610e2d0b08b7f368bee406b28572f0764de87c1c68309ac713a4d6f5","b90c59ac4682368a01c83881b814738eb151de8a58f52eb7edadea2bcffb11b9","32e1fb333973369500d670e1a6adfbb3314d6b582b58062a46dc108789c183eb","e040fa1afb9b8d5bc1fde03bbf3cf82a42f35f7b03a088819011a87d5dab6e74","5156efecb13dffb9aefc31569a4e5a5c51c81a2063099a13e6f6780a283f94fd","585a7fca7507dd0d5fa46a5ec10b7b70c0cea245b72fc3d796286f04dacf96e4","7bc925c163a15f97148704174744d032f28ad153ff9d7485e109a22b5de643dc","c3dc433c0306a75261a665a4d8fd6d73d7274625e9665befd1c8d7641faeddd7","45b6a651b5e502cdfa93dc2f23779752def4ada323ebcfc34e4a4d22e9589971","9fc9575d1a0e89596012c6f5876b5c9654e1392fbd5d6d3d436bc9198ead87a0","f158579f034415f0bad9f6f41ed3ac0768dfe57dc36776d52e09c96a901c5e45","8e6a2d23d02da219dc17ca819efce29e1099883425f56e6c803c19d913b11173","bb2f509fedbf353c2dbb5626f25751308dda2cd304be0c1dfb7cf77f47fc56b3","1af1f2c02132bafa25c4c4b7c415e0a59ba959d6db6bd1800a43fb5d943e3f77","e617a4e3425c1c4f6337f9065c844fee758eb60f2befe40f87d6bc295fe3dd6c","84cc254263404913255f7ed1ac7bdd05d5f1f2c233f6b48915f64aca2321ec17","67a4f653163df230b46606a9b97b568b5150d0e0e1ae1d613c59f7a3b0512449","3b1c2ccfa2572201a53e54008e1a2a321ef826f4260264749ed5158643cad6c0","0b30b078f688f2b4f4e378fa383e02e2d4c4213a1b22aebb020461e36e34aa92","7f204c0b47583a898e6dbe667ad290b837cd99822bf133d0ff23ba072becec52","df8ac16e33db5d15a25a0a175e8a5d5bd3d3b2f1d5d0edff099ac26e619932b6",{"version":"fee36a36f11807ecc58ff9b5e40377b4c87a2e7210c15556556911a9ca44014b","affectsGlobalScope":true},"9e8ee7decd5b936e590bbd71e37cab2d85c15902bbaaaba675cfe4af50d1b2b0","cf1f6345eae1f612cdae0ef3d0472849ff6285ff13861b99bed2d0750984308d","d9b3c4ce82ccf7f4df08cd6d6cc7c66dba5aea3fc22c199a70a4edddc8af3f71","ef1c7640858c3d968db2a4ba2d6af6e5778d5dc4fb7a9aba0de8794a5391168e","551fc0eb86f1c32d429545a28f6cea36960e7449e3f003f567b43780f19e29ba","e9296024b1f962bccaf6af2120421490a2ae96af598ab1f740be3efe42d3274e","24c084e7c30c2a45f7ef44933ffe5df3a5ffa501c33149a7dafa5682ab72e25b","1c24f0f8c95764612715e568243055e8002af0a3885dc455df5147fdf3cb55b7","bf5549ea7ebd90752123a8aec28415df15bf400a3898299e7c947611b5f537f4","da53d43a473a212647531cf91ea1beb2f49b5a9106be657f0385deb9a6139180","c9314385f46d1521bb2bb23e3984acb1d68e5fa56120e2b5d424272a9f2c708e","c60943067ef04762046e5c19329df8558dd2ba47f1a1ed2f0711181b73704c44","099584b823cf52b0e7e097c6d5006398d31e68c5cd9d8967e3df2e8c1eb881f8","d91d6795544bfb8e06f1f04545545f228ed36f2c444cb554ac51d4de2fbd2e74","58310c0ff2a79c46049f336deb1589373b0a1b122fab2e101d79a6f47a1b52d2","6df5b1d1fac5dceea1dd1a666ed8fe292957255c095e4ba00adca8bdd2d74c1f","a611845f980fbd68435294c90cafcb3976d0d66493e23a25ca0425bb13861468","d3e6fb547238040ca1e7f4486fb3a0b8f9a657160ed033efc79dc657b7320803","f0f7ed6671f0843c05a5f05980e00637e469e8530c5784bf2e20c7d7deb6e391","1eef89f94fe39c014d6de34f4d6e92f40d11f0c7e46777c3be3fb13d34c6c464","0da9be43f4983bb61d54e7bb2afd9cb86b270ec719e956ab803f76eddef6b52e","2dfa8762fbfc585e4395356a5141ecca6440821bf5e9cb4227d0f919bac661b1","e59f78e8e87999e5728353aad12b29403e0b6e81c47ae8146c934e6b1edb8de3","e411a4302a10047bbd27764c12be7808b766644741610546db9c3e2acf12471c","136d94c701ac5c60de14b174c822adc1f0f576dec94950be9fa1d8a09c66c4aa","eaeec2777122caa844a03fccf833d866cd840d0a1f8101c537b44e35a0cab3ca","3b55611a53a9a09a45a822c249891fd7f9d5ac3009e9c584220ca7236629438c","8b7743de32649972bb9c25076c0171edf9515a955c75a5cba1d7b79c3dfe2117","b07a0f6ad535d7ebd64e9fa1ca8ddc32c0fc88763eb6e74c2f6cc02dbcc45fee","350e8e85bd49d40bf357e729b1a4451e7ef6e81adfc9d77bad705f0a81e63b0b","c7413fa9b60bfd12f1c099f652762389019fa053cb2d0aa6df59836f181cdd15","827ca57c20c1198a16184f9d96c56cf46b9bb843e04d1b0860169c0fbed08b1d","1a9d8af521b900c6e91e1267dfbd5b12638be1a89f2f8a589926dac298ca2372","6479e587577acdf8da5bac2fcfbd23c974380814562b1980e8ac472d398cb895","19b5194066a9faa7e6ee9a2d39ec541589f2fa4619dc70da0bbf9fdadac52388","17f4f092dc1acabdf5d9a27fad52ed4e2be94f027c01fb66ef7bd8900d1434ac","1de6485c3440f05bafef76b1504c97b672b216182544884529a1063e0d40a307","5487b97cfa28b26b4a9ef0770f872bdbebd4c46124858de00f242c3eed7519f4","7a01f546ace66019156e4232a1bee2fabc2f8eabeb052473d926ee1693956265","fb53b1c6a6c799b7e3cc2de3fb5c9a1c04a1c60d4380a37792d84c5f8b33933b","8485b6da53ec35637d072e516631d25dae53984500de70a6989058f24354666f","ebe80346928736532e4a822154eb77f57ef3389dbe2b3ba4e571366a15448ef2","c2cb3c8ff388781258ea9ddbcd8a947f751bddd6886e1d3b3ea09ddaa895df80","f672c876c1a04a223cf2023b3d91e8a52bb1544c576b81bf64a8fec82be9969c","98a9cc18f661d28e6bd31c436e1984f3980f35e0f0aa9cf795c54f8ccb667ffe","c76b0c5727302341d0bdfa2cc2cee4b19ff185b554edb6e8543f0661d8487116","2a317fff5810a628d205a507998a77521120b462b03d36babf6eb387da991bee","f5ef066942e4f0bd98200aa6a6694b831e73200c9b3ade77ad0aa2409e8fe1b1","b9e99cd94f4166a245f5158f7286c05406e2a4c694619bceb7a4f3519d1d768e","5568d7c32e5cf5f35e092649f4e5e168c3114c800b1d7545b7ae5e0415704802","1025a8797451b15ae6459c934c6a05ea89e253264c0c3f4a53aaa41f3cc22c1e","179d0bd93eb1bea670d770dd3740eb883c017c11a6e1b1868acb388c00acc6ca","a6e59cf99535a6853e64662f20c7701f2c95c0eecb7e4be7307ef207253f73e9","482ff635ea42cc671ba1e5729f57dd784759acd60fc26d31d676ae522cf3e2f5","0c6d28905b5df653881971b7803ffd5651216474cfa51f87ca0038d0142a3e30","36d56a8c47602941ec4fe3b828a057c00b27b1ea77b3ca46f3b176e0f3096545","fee7ceff89d4c699ae7ec065456d6b9760eaa004221b2aaa9999af4a14d5989c","a41c8ae7dab7ce988301a36ef6112ccff03599033b5c75f6a7252cd0c68e1569","74ed4f598c9812e34017655595151fc58bde81267cecd72cc1095d9cd6e98d26","087f3a6fe7a10ac11427df55b96cfa3835f13790ef78b85db58de3a30bd88123","3689b9724852cba36660e3a154a73016035822a0140e2c00dd8de20c2820c36d","a70c8c1d38ca7cb5049b43c1b71f20b802b5254469ff2a530fe550afe8722622","47bf4b1eea1179a5ec044fd452aa9a4b96bdb69977347b50f82a6517a7c1f7ae","6d68a50774a65bb4bda64c49a7a544db53746b5eaa745643279d9d212ed97b63","9a36858d4b60d1548f89b6c1f22cfab603f222cc1909bf83d1f773c49e3fe281","04af33c935a611b404adda1d971642eee709a5ce3bd087a414f9036e702b12a2","0fbc01686625c909e256f240d3d07a667bc55198e6ad1174a4b47178c1419d90","99d63dcb2d168454bebfed98d8df3f1530a1bcaa65c756398896bed904b79541","f66ddc4c537b76c0d69a08094a77dc3d5cae860ae9a549612cd738e67aa2ab6e","8bbcf62d08ce4b01f02938ca0e2825930880f141291ea7294a4da8162e17bf47","ae0d70b4f8a3a43cb0a5a89859aca3611f2789a3bca6a387f9deab912b7605b0","966b0f7789547bb149ad553f5a8c0d7b4406eceac50991aaad8a12643f3aec71","a97f8eb2cabdf5e2317b68d169eb7df52f6b473f913bcd74c7879baf762e8f9f","f495c61209d0e72b8663a46a399ce25c5b60ada1cf45d789f2053ee85c10a45d","f4f0a9ba8c90b7c722432cd97a6d61c5704366a49ebaffd258c224027fb7894e","c21f855e39d24aa882ee0ac64593476b50569286012651f75e10ab525005b064","7f38a10b9bfa33c12fc85898b4b30b42900fdfe713972a0b5be4d7b2efa505a6","c880bb9254ecc331a4c932da59b8d06ba26e17c36ce789dbc5fee9cce806ed48","c3b5a4d27503a9b253abcd973bbae9ccfa3afc9ac6dd652ec3c6757e7071bb5d","bbf5b34e6d1efd48698aaab17c7f7ac9fed872de5cb865444d05571dbf6a36e2","782f40c70dbb9a4f902812586b6f2e143302408ad2d00f26f9bd5198295a7845","e222024d493173f6e18f3ad770e86dd99f00b3512742b69ff244db4dec33a8e8","8a610d112cad6ef9fc0ffa33245a3cd17cd23ec78fec679a31faa7a9ae2c1722","200314d6e66a1a4301584141c518ab36f8544d0b1d0dedcf569f6efb0ed0c9af","21e32553c45afbe8e0aed633cc7b338a7fd33a2e3b1541f9c901fd28456025bb","b9d60f5175a963d2558126e51fb99f93677b6c59937dcbc398717f720fcc8d30","f4d59fcec1819d14518eca58b43bf0a0cf51e06d498f3cef3b8a627910ab4dd9","21c3c683460eb4408ae6cec7617aefa7607152329d9126019fa02ac1a0bc345c","2d56000f3a06b01d99a6f9f4e95396e8712c2a81e423439de38e1a64d0409042","900cab547c1459e25cafbd3181b14683dc7a4f61cf99f0bab0f6679df8e570ca","14cbbd933fade36b12e8be4c1fde036c985f61e3fb565592ec81a46fb7342a38","611148425fc5c5837a7e316995fb6cfe5538c182f95cb901594e7cc1ccc2a393","f8c6575db5aa7109d81ad2d05d1ee0f7735b25e736b8354038abe6eb90eda3f2","5cbb29ce51ea59a1e5f91ddd76393f191c4e46f5d26b570c08f3ff089b9a9649","9cdadba9c7f24aeee77bfe19a44cf52c46863bddc13b7f53d143de92be5c12f4","879027ed0a4de349461863fc1de901a5b3a290dda9db5e779c96f1aa1414f39a","820a55a447173d3bee701293bc1aafdb50f0a4d530b437aa9982d6a71fbb0baa","17af9440f45c63a2c188454849a864e4a37515d20c37415f522a83474bbfc7aa","d0cebc7d00d35bc27dc9ba3956a7000dae4688170c9ad9dfcac351b67fc61017","3e71e5446948adfd0ae51a4bc1936519693fd099c9e8381f4416f575a226df84","0c165f610247840001da342e5e33506b8156b8c0c5bd063a8a7b610391bc2775","ba9ce4f65e18a7d9211675294091e01ab58837e2f0567212e3f52dd526dab168","816aa86fde19f0a1f5469ef9aa98cb47895c40aa0869e54ceb2d2f7902dc49f4","6049d315e1aa3f39a48f06cbccd77dbe2d85dc28e79638dd91adc37280c6d97e","7e4cbf501961c7bb1ef33aa3eace64f09e9977c14e65cda57759dfda18ef555c","06e6fbf2a92b1a928a3bcd39126edeb56f6d266c06479b289f1da3d5eea0262d","3bc7d7ff5ddfa35d08003cb34748765a1f134db09cec2f288e0bbaee2cc1cd51","0772704617f9ce9f1c3ad63302349afa2319ce77ffcdb4f78b02bc4659411141","40a219660722eff24fb73f6f1b705b4dc5c14b6545f1fef542668eadaeff8642","2401f5d61e82a35b49f8e89fe5e826682d82273714d86454b5d8ff74838efa7a","87ba3ab05e8e23618cd376562d0680ddd0c00a29569ddddb053b9862ef73e159","2b4276dde46aa2faf0dd86119999c76b81e6488cd6b0d0fcf9fb985769cd11c0","56a37fc13e7a1756e3964204c146a056b48cbec22f74d8253b67901b271f9900","5ecea63968444d55f7c3cf677cbec9525db9229953b34f06be0386a24b0fffd2","b50ee4bde16b52ecb08e2407dca49a5649b38e046e353485335aa024f6efb8ef","0eb4089c3ae7e97d85c04dc70d78bac4b1e8ada6e9510f109fe8a86cdb42bb69","9d6d2e300614afc39d1d5dffe52913b760278b43abf4de077a005cfd6b063152","82956f1c7cac420ecb5676371cb66236ccbc0b121e7122be8062bfd70ea26704","c2e47cbf7752112164c6526b2f606d1eb3922299ec073d27168975d476c6a702","6760208eb2d4a4ec526893cd3788d294cb81b8f3c6814d1abd2715609000b76b","3d2e009a949474abdf4186fc6dca59464479ba526367330c6a9addb01804380c","cfaa77102000ea21dc8e038f193006ca8dcb7779f7c28e930408bf4e903d8350","8fad9472640bceb98c7f0400aa9e6ba0f4e5f8d2aa969cd4eb11fdd7f82caa28","f4112950d4fd921758c8d59f44f7a3620a1abd1ba9b3070ff4191d84234a7c67","320e0c6c38284f2e1ce93aa916bfd288098de6a73bc31cbff151bada73d3f13c","07bf03e0dd98af9e49dfd66abfc8d41379d6066b4297ac675022ab5332049699","1aeebda04375c0762faf2d36ebd8434de617fbdbf476caef7197e53131653f9c","caa816b62534941063ff618aa93aa9344ae6b752cadcdbc929b5ce49ac355480","d97b3e1f1bcb3cbbf39cb533cd185b31198c18c072d468f4349a3462af68c08b","ada4597755fc8344976834a1a6d0b54a74465c9b0341ae74dc786920b5d9aa5d","36a8c3503928e5b2fbf4c071390b3640c2b918b1412a769ef496218c4a6fa73a","b34f4c9b1aaf4a669908750d106ea3e27e5e934f36f000e1210c5c2764462d8b","7ce8d310bc04ec86db75e5c4c5b8cb808281c1da62c275d30cfbb487576ea216","cc42ccdbfdc8fdc8cbfeb6e62dc614e6980ee020196fcd7d68496e05ced4d9d2","fae0ea86a316c64ed5377e50e219977dc8f653fbc97e3f09ff8d4e8129bf03cb","c1c1f2903ee06bcf709b1da8fa7e98dec4d4545e839c1a954e88736b8ea4b0fd","1891f03bc9d1e207fcf06fefa964ecb725eced867dd32c2b1b992ec885a9dda8","e5d9fca75d5f1c6214713c670ffe30496bde351be6715f2052f0f32cc8619e71","f86c6ba182a8b3e2042a61b7e4740413ddca1b68ed72d95758355d53dac232d4","557e774e9013eb18a29028f45ee53bf9e75efc2f8737a83b0750ca5478f96066","20cb0921e0f2580cb2878b4379eedab15a7013197a1126a3df34ea7838999039","ef73bcfef9907c8b772a30e5a64a6bd86a5669cba3d210fcdcc6b625e3312459","dae85062301b398045a4cd5d84efb9069fff92a9eadb9c6dc02368ea435fd1dd","e780453ead2df015e36bd388cbc2cbe1970e3da260ded6a0c1d53de5bc8adc3d","ab8ea681e85fbcfef5cdd4cf1421a83fbe4c7966dc65d867d824a5504dc6453f","3a265f1135bee38c915cf0973c3a11ae494a3a34969d117876b82c70b343a4c0","df8be305f247bdcd048ae733c601b4f0d0210907dde403fdb507e13c89611737","1ac4ef901df4fd20164359996707163b702f309421c0f6e49b6234eb8b4f2747","802c265e5352ce66906c0dc8ce7c7e2325daa48b9e811ad1e605eaf847d70041","b69ba377a4dd41ed7b62db5d56ada8d44a02439700b02c2339dff8c25dc44410","c3b6ab1cd47979321f77ad9c28e0698942a0e2851a7f1ef2f666d36e3358f450","9a9eee4ba0dd529abd1e6788cc1c6a3f7eb24f925c41f5346fe77d02ab2606a5","90c8e0388d931580506d1f55f6e038dbe473a7028912b774a268794013db5051","a91d4c3fcc7a4bb58d766741007344516977acbf25c85af0ac36b8a3d06c7638","5cd61aabef84c19b3997eebc52c38f05f1dc8ca7dfd651369c33e1688930f569","5addf54466515c188287cd4fc0372bd1c7edf2b7c3d15c92f50c04ad50a19121","133a88166318c841427d3c7afc9be550e14f36d0b5096f482fa89a762760dc55","0aa05a06ba9087cd6c2a9f33ed1e557d5b1d11705c85d56fed2f40bda681b535","0bf6dd135753ed8e7b352d894a8d184fcfd5c6d9f224c2b01e394422ee2a414b","1fbd3bbd7af582b514b054cc3464f4d1a07010f4b115e5ce67b4a63a3c3dbac6","d1ff2133bea9fd539c3cb1945f4aed02d3ab6fb2a1a0c7f234c0e3adafed0ae6","31eccb65118f01bf9f759b1715d73f4c5c0bc1aa8d22ef6c1e4b49f3e82e2445","6119092db2a7cc44918001597c41b671389299ecdbdb05c12cc964a83141ac88","9e36291790310e2125629c73298312aefea412af94f6fe4ec22b83cf62dfe238","4bea1b58743d0cb0bedbc4c1964951a6024afe67a6e03949560fe144386fcf12","59674302c8915a926a4f1f1ff32616d82e642deb6909dd38f7a1b80352878a40","f7012017f137e5a72d4776dc8463fd29bfd049775fa8cb60fb9a902cedb2fdd8","879aff253ce8bc5f13dbf214c8457e0e9548c49de48b7eed256e44e445ebcd25","aead19a3f04d8386bbeb8402f6f24a9796820c761281b1efc5360ab0b99eac61","c98a415ceaee6c54e061cf66af07955d55fc4def905e55bd5d2bc7fdd5b60227","b3834898415581402b23948defac11c38d393384a19a6dccae8a67a2e72a7871","a886ad70115082bdd29c7fe9e96ca7c6c57a452950ce545158ba8c1e039d7d92","6a4990b406c22be31b2704959379dcdfc8700f753f13a16a801ae78b13b6c194","ea9174994da101aac11c1a2ee68b04d3512ec4a44cebdde5bf6559552fc4d04f","5c6065e5e6f79bc7b10427ea0b82445742f1d33823d458b416fb01c05e854ee1",{"version":"d38847e436b486528d83ca602a5fe6a995c0b691b29c6046ef87567f5fff38e4","affectsGlobalScope":true},"03bd1e2788b01eac84e0ded9a9c858183f8fc5a65ceb7e16bb52a52ddcc6d578","2b58d91c9c65ac81c4c77c91c54a5885769e50ac84d3e997c64209113e3c400f","29f813cad34fb4813e868314e537e55b0c6ccd1056ec3e27aca47aa311a67941","6aef1604aa60b075a19519b33dd41b7100286c789acb0953875b815dfe1a441d","8b92b41602012df284edb950d98c01acb80baaa92606fb83cf7ce4b9c8c610ac","cdb41e5dde54afa21a192680cb9905744068eeed27cd53070704d3bd9af85f6c","71727c0229617e358bf7dbd3de27db6ba981d82a18423fae01b542362b637202","ea470306a663c5ef7da6c3bcf0915aeeb213ec5a950040425839b217cfd5a9bf","62931d8d3c639be6b55a7a781a14d17d2fada5b5487c4cc66b050fd3393d23e3","7a3a54c2c6227a67d3b2e057247a52370970fa6e0c9ecc3203780f1961d512ae","0a54116e2dfb82fc6d47ae24114eafaf07bd32b4b1d50ee691fc2b64780b3fad","843dc7f5a340cb4f44ded96aef4e331553f44346b6e44b368963474d988e1ae6","9c05ad7d3e5c73e39eaf8454f6255167cb37f42f8d29b33ad4f500bf3049cd6f","dc282c96796853e70f48e65c88d5976c7b35cff3cd6cbaecdf5ead06c3fdcf0c","a7fe7e88c50608567af53c49d3c59ea5f33bf5f59126d67b2a25f85eb41297ba","a949aa0a5642b641cf789b4f7dff12383797da2ed7f1b15baa7fba96865e5904","21aa43dba003ea203f21a65312af565a2d8710bded1f23ac0809e6f48ded1148","a4db8af569d569b92fde669a559db0cc520e2eb6a5c9cb947bddf58cec9295a0","46b836d46357ab2903bd7f2feb576798ffb7fd811c13f6018202657154dd2ae8","3f094b6963c54dbf2ce37fbe39a1c964d44d34f0477571142694c394b66742c6","6d26a677a7bdeacf824de59d9b4bc6c622d41b6c2adc246ea38f9ea320a353c7","cb01cdf951a8d999fbcd566951e4792afa8519f39653fd9db81e04946b1fd051","044166b234de05e38b9409a1e383e28cbd76b125aa9cef8dff7ba69f2a35dedf","8100da3051fd6727a0928ea91ba1016bde3754076033dd415fdda5c3daa59a0f","9d38b7e219d3965e528e88103e08fe0a93645e3a05ba3cd0af4413329b0dd14d","6acf83c2536cfef0a42b948be886b4cca29d05c0773f5ff91eb41153ab2e5448","9266196e9969622265339034e2f1eab5ffcdda42ce1aa9b1cc15b73d8417e374","f634e4c7d5cdba8e092d98098033b311c8ef304038d815c63ffdb9f78f3f7bb7","963d59066dd6742da1918a6213a209bcc205b8ee53b1876ee2b4e6d80f97c85e","9c5c92b7fb8c38ff1b46df69701f2d1ea8e2d6468e3cd8f73d8af5e6f7864576","031c6747d66455eb73ef55c7799d73932f13513782806e11c5095f29c90de3e3"],"root":[[347,351],363,[377,385],[387,389],[404,407],578,634,[655,657],[659,663],665,[668,676]],"options":{"allowJs":true,"allowSyntheticDefaultImports":true,"esModuleInterop":true,"jsx":1,"module":99,"outDir":"./","skipLibCheck":true,"strict":false,"target":1},"fileIdsList":[[124,381],[124,362,658],[124,351,380,671,672],[124],[124,348,349,350],[124,380],[124,546],[124,661],[124,381,661],[124,407,654],[124,326,333,407,614,615,618,633,634,654],[124,577],[124,376,407,525,578,655],[124,615],[124,661,664],[124,667],[124,362],[124,345,346],[124,365],[124,368,369,370],[124,368],[124,368,369],[124,367,368,369,370,374],[124,373],[124,365,366,367],[124,666],[124,548,549],[124,548,549,550],[124,548],[71,124,224,551],[71,124,224,551,564],[124,224,547,551],[71,124,224,547,551,564,573],[124,224,564],[124,566,567,568,569,570,574],[124,551],[124,552],[124,547,553,564,565,575],[124,224],[124,224,547],[71,124,551,564],[71,124],[124,554,555,556,557,558,559,560,561,562,563],[71,124,224,564],[71,124,224,547],[71,124,547],[124,547],[124,571,572],[124,585],[124,586,587],[71,124,588],[71,124,589],[71,124,360],[124,360,361],[124,353,360],[124,353],[124,353,356],[124,352,353,354,355,356,357,358,359],[124,352,353],[124,352,360],[71,124,579,580],[71,124,581],[71,124,579,580,584,591,592],[71,124,579,580,595],[71,124,579,580,592],[71,124,579,580,591],[71,124,579,580,584,592,595],[71,124,579,580,592,595],[124,581,582,583,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613],[71,124,589,590],[71,124,579],[124,457,458,459,462,463],[124,443,457],[124,444,446,451,452,454,456],[124,443,460,461],[124,444,449,450],[124,444,449,450,455],[124,444,449,450,453],[124,444,448,449,450],[124,457],[124,526],[71,124,460],[124,449,450],[124,408],[124,447],[78,124],[81,124],[82,87,115,124],[83,94,95,102,112,123,124],[83,84,94,102,124],[85,124],[86,87,95,103,124],[87,112,120,124],[88,90,94,102,124],[89,124],[90,91,124],[94,124],[92,94,124],[94,95,96,112,123,124],[94,95,96,109,112,115,124],[124,128],[97,102,112,123,124],[94,95,97,98,102,112,120,123,124],[97,99,112,120,123,124],[78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130],[94,100,124],[101,123,124],[90,94,102,112,124],[103,124],[104,124],[81,105,124],[106,122,124,128],[107,124],[108,124],[94,109,110,124],[109,111,124,126],[82,94,112,113,114,115,124],[82,112,114,124],[112,113,124],[115,124],[116,124],[94,118,119,124],[118,119,124],[87,102,112,120,124],[121,124],[102,122,124],[82,97,108,123,124],[87,124],[112,124,125],[124,126],[124,127],[82,87,94,96,105,112,123,124,126,128],[112,124,129],[71,124,135,136,137],[71,124,135,136],[71,75,124,134,298,341],[71,75,124,133,298,341],[67,68,69,70,124],[124,367,368,369,370,371,372,374],[124,375],[123,124,131],[124,409,411,436,437,438],[124,409,410,411,438],[124,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435],[124,409,410,438],[124,477,478,479,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509],[71,124,480],[71,124,477,480],[71,124,477],[71,124,544],[76,124],[124,302],[124,304,305,306],[124,308],[124,140,150,156,158,298],[124,140,147,149,152,170],[124,150],[124,150,152,276],[124,205,223,238,344],[124,246],[124,140,150,157,191,201,273,274,344],[124,157,344],[124,150,201,202,203,344],[124,150,157,191,344],[124,344],[124,140,157,158,344],[124,231],[81,124,131,230],[71,124,224,225,226,243,244],[71,124,224],[124,214],[124,213,215,318],[71,124,224,225,241],[124,220,244,330],[124,328,329],[124,164,327],[124,217],[81,124,131,164,180,213,214,215,216],[71,124,241,243,244],[124,241,243],[124,241,242,244],[108,124,131],[124,212],[81,124,131,149,151,208,209,210,211],[71,124,141,321],[71,123,124,131],[71,124,157,189],[71,124,157],[124,187,192],[71,124,188,301],[71,75,97,124,131,133,134,298,339,340],[124,298],[124,139],[124,291,292,293,294,295,296],[124,293],[71,124,188,224,301],[71,124,224,299,301],[71,124,224,301],[97,124,131,151,301],[97,124,131,148,149,160,178,180,212,217,218,240,241],[124,209,212,217,225,227,228,229,231,232,233,234,235,236,237,344],[124,210],[71,108,124,131,149,150,178,180,181,183,208,240,244,298,344],[97,124,131,151,152,164,165,213],[97,124,131,150,152],[97,112,124,131,148,151,152],[97,108,123,124,131,148,149,150,151,152,157,160,161,171,172,174,177,178,180,181,182,183,207,208,241,249,251,254,256,259,261,262,263,264],[97,112,124,131],[124,140,141,142,148,149,298,301,344],[97,112,123,124,131,145,275,277,278,344],[108,123,124,131,145,148,151,168,172,174,175,176,181,208,254,265,267,273,287,288],[124,150,154,208],[124,148,150],[124,161,255],[124,257,258],[124,257],[124,255],[124,257,260],[124,144,145],[124,144,184],[124,144],[124,146,161,253],[124,252],[124,145,146],[124,146,250],[124,145],[124,240],[97,124,131,148,160,179,199,205,219,222,239,241],[124,193,194,195,196,197,198,220,221,244,299],[124,248],[97,124,131,148,160,179,185,245,247,249,298,301],[97,123,124,131,141,148,150,207],[124,204],[97,124,131,281,286],[124,171,180,207,301],[124,269,273,287,290],[97,124,154,273,281,282,290],[124,140,150,171,182,284],[97,124,131,150,157,182,268,269,279,280,283,285],[124,132,178,179,180,298,301],[97,108,123,124,131,146,148,149,151,154,159,160,168,171,172,174,175,176,177,181,183,207,208,251,265,266,301],[97,124,131,148,150,154,267,289],[97,124,131,149,151],[71,97,108,124,131,139,141,148,149,152,160,177,178,180,181,183,248,298,301],[97,108,123,124,131,143,146,147,151],[124,144,206],[97,124,131,144,149,160],[97,124,131,150,161],[97,124,131],[124,164],[124,163],[124,165],[124,150,162,164,168],[124,150,162,164],[97,124,131,143,150,151,157,165,166,167],[71,124,241,242,243],[124,200],[71,124,141],[71,124,174],[71,124,132,177,180,183,298,301],[124,141,321,322],[71,124,192],[71,108,123,124,131,139,186,188,190,191,301],[124,151,157,174],[124,173],[71,95,97,108,124,131,139,192,201,298,299,300],[66,71,72,73,74,124,133,134,298,341],[124,270,271,272],[124,270],[124,310],[124,312],[124,314],[124,316],[124,319],[124,323],[75,77,124,298,303,307,309,311,313,315,317,320,324,326,332,333,335,342,343,344],[124,325],[124,331],[124,188],[124,334],[81,124,165,166,167,168,336,337,338,341],[124,131],[71,75,97,99,108,124,131,133,134,135,137,139,152,290,297,301,341],[71,124,224,476,510,523,525,528,543,545],[71,124,224,529,530,531,532,533,534,535,536,537,538,539,540,541,542],[124,616,617],[71,124,619,620,621,622,623,624,625,626,627,628,629,630,631,632],[124,526,527],[124,364,465,523,524],[124,364,465],[71,124,345,364,464,465,474],[71,124,345,364,464,465,474,475],[124,409,438,444,473],[124,438,445],[124,409,410,437,438,444],[124,649],[124,646,649],[124,646,647,649],[124,641,649],[124,641,646,649],[124,646,649,650,651,652],[124,635,636,637,642,643,644,645,647,648],[124,635,636,637,642,643,644,645,648],[124,646],[124,647],[124,638,639,640],[124,653],[124,472],[124,408,443],[124,439],[124,442],[124,408,440,441,443],[124,470],[124,467,469,470,471],[124,466],[124,468],[124,466,467,469],[124,467],[124,522],[124,513,514],[124,511,512,513,515,516,520],[124,512,513],[124,521],[124,513],[124,511,512,513,516,517,518,519],[124,511,512,522],[124,333,384,407,654,670,674],[124,311,384],[124,362,363],[124,333,362,546,576,656,657,659],[96,124,364,376],[95,104,123,124,364],[124,379],[96,104,124,364],[96,104,124],[95,104,124],[95,104,124,387],[95,104,123,124,364,389,403],[95,104,124,364,386,387,388],[95,104,124,386],[94,95,124,131,678],[124,390,392,396,397,400],[124,401],[124,392,396,399],[124,390,392,396,399,400,401,402],[124,396],[124,392,396,397,399],[124,390,392,397,398,400],[124,393,394,395],[94,116,124,131],[95,104,124,390,391]],"referencedMap":[[661,1],[659,2],[673,3],[350,4],[351,5],[349,4],[348,4],[672,4],[671,6],[657,7],[662,8],[663,9],[670,10],[655,11],[578,12],[656,13],[634,14],[665,15],[668,16],[669,4],[363,17],[347,18],[365,19],[371,20],[369,21],[372,22],[370,22],[366,4],[373,23],[374,24],[367,4],[368,25],[667,26],[666,4],[548,4],[550,27],[551,28],[549,29],[566,30],[570,31],[567,32],[569,32],[574,33],[568,34],[575,35],[552,36],[553,37],[576,38],[560,39],[555,40],[556,40],[562,41],[561,32],[563,42],[564,43],[559,44],[557,39],[558,45],[554,46],[565,47],[547,42],[572,4],[573,48],[571,4],[586,49],[588,50],[589,51],[590,52],[585,4],[587,4],[361,53],[362,54],[354,55],[355,56],[357,57],[360,58],[358,59],[356,56],[353,60],[352,4],[359,56],[581,61],[582,61],[583,62],[593,63],[594,61],[595,61],[596,64],[597,61],[598,61],[599,61],[600,61],[601,61],[592,61],[602,65],[603,63],[604,66],[605,66],[606,61],[607,67],[608,61],[609,68],[610,61],[611,61],[613,61],[584,4],[614,69],[612,42],[591,70],[579,42],[580,71],[464,72],[459,73],[457,74],[462,75],[458,4],[452,76],[456,77],[454,78],[451,79],[463,4],[461,80],[527,81],[526,82],[300,4],[658,42],[542,42],[450,83],[449,4],[409,84],[448,85],[386,4],[410,84],[465,85],[460,4],[78,86],[79,86],[81,87],[82,88],[83,89],[84,90],[85,91],[86,92],[87,93],[88,94],[89,95],[90,96],[91,96],[93,97],[92,98],[94,97],[95,99],[96,100],[80,101],[130,4],[97,102],[98,103],[99,104],[131,105],[100,106],[101,107],[102,108],[103,109],[104,110],[105,111],[106,112],[107,113],[108,114],[109,115],[110,115],[111,116],[112,117],[114,118],[113,119],[115,120],[116,121],[117,4],[118,122],[119,123],[120,124],[121,125],[122,126],[123,127],[124,128],[125,129],[126,130],[127,131],[128,132],[129,133],[69,4],[136,134],[137,135],[135,42],[133,136],[134,137],[67,4],[71,138],[224,42],[70,4],[408,4],[447,4],[375,139],[376,140],[615,4],[68,4],[677,141],[577,4],[364,4],[438,142],[412,143],[413,143],[414,143],[415,143],[416,143],[417,143],[418,143],[419,143],[420,143],[421,143],[422,143],[436,144],[423,143],[424,143],[425,143],[426,143],[427,143],[428,143],[429,143],[430,143],[432,143],[433,143],[431,143],[434,143],[435,143],[437,143],[411,145],[510,146],[503,147],[502,147],[501,147],[508,147],[481,147],[491,147],[490,147],[500,147],[499,147],[489,147],[497,147],[506,147],[507,147],[483,147],[480,42],[484,147],[498,147],[482,148],[496,147],[509,147],[492,147],[486,147],[485,147],[488,147],[487,147],[505,147],[493,147],[494,147],[495,147],[504,147],[478,149],[479,149],[477,4],[545,150],[544,42],[77,151],[303,152],[307,153],[309,154],[157,155],[171,156],[274,157],[203,4],[277,158],[239,159],[247,160],[275,161],[158,162],[202,4],[204,163],[276,164],[178,165],[159,166],[183,165],[172,165],[142,165],[230,167],[231,168],[147,4],[227,169],[232,170],[318,171],[225,170],[319,172],[209,4],[228,173],[331,174],[330,175],[234,170],[329,4],[327,4],[328,176],[229,42],[216,177],[217,178],[226,179],[242,180],[243,181],[233,182],[211,183],[212,184],[322,185],[325,186],[190,187],[189,188],[188,189],[334,42],[187,190],[163,4],[337,4],[340,4],[339,42],[341,191],[138,4],[268,4],[170,192],[140,193],[291,4],[292,4],[294,4],[297,194],[293,4],[295,195],[296,195],[156,4],[169,4],[302,196],[310,197],[314,198],[152,199],[219,200],[218,4],[210,183],[238,201],[236,202],[235,4],[237,4],[241,203],[214,204],[151,205],[176,206],[265,207],[143,208],[150,209],[139,157],[279,210],[289,211],[278,4],[288,212],[177,4],[161,213],[256,214],[255,4],[262,215],[264,216],[257,217],[261,218],[263,215],[260,217],[259,215],[258,217],[199,219],[184,219],[250,220],[185,220],[145,221],[144,4],[254,222],[253,223],[252,224],[251,225],[146,226],[223,227],[240,228],[222,229],[246,230],[248,231],[245,229],[179,226],[132,4],[266,232],[205,233],[287,234],[208,235],[282,236],[149,4],[283,237],[285,238],[286,239],[269,4],[281,208],[181,240],[267,241],[290,242],[153,4],[155,4],[160,243],[249,244],[148,245],[154,4],[207,246],[206,247],[162,248],[215,249],[213,250],[164,251],[166,252],[338,4],[165,253],[167,254],[305,4],[304,4],[306,4],[336,4],[168,255],[221,42],[76,4],[244,256],[191,4],[201,257],[180,4],[312,42],[321,258],[198,42],[316,170],[197,259],[299,260],[196,258],[141,4],[323,261],[194,42],[195,42],[186,4],[200,4],[193,262],[192,263],[182,264],[175,182],[284,4],[174,265],[173,4],[308,4],[220,42],[301,266],[66,4],[75,267],[72,42],[73,4],[74,4],[280,128],[273,268],[272,4],[271,269],[270,4],[311,270],[313,271],[315,272],[317,273],[320,274],[346,275],[324,275],[345,276],[326,277],[332,278],[333,279],[335,280],[342,281],[344,4],[343,282],[298,283],[546,284],[529,42],[530,170],[540,170],[532,42],[531,42],[541,42],[543,285],[533,42],[534,42],[537,170],[535,42],[536,170],[538,170],[539,170],[618,286],[617,4],[616,4],[619,42],[620,42],[621,42],[622,42],[623,42],[624,42],[625,42],[633,287],[626,42],[627,42],[628,42],[629,42],[630,42],[631,42],[632,42],[528,288],[525,289],[524,290],[475,291],[476,292],[455,83],[474,293],[446,294],[445,295],[635,296],[650,297],[636,296],[651,296],[648,298],[637,296],[642,299],[643,300],[653,301],[644,296],[649,302],[646,303],[638,304],[639,4],[652,305],[641,306],[640,4],[647,4],[645,299],[654,307],[473,308],[453,4],[664,4],[64,4],[65,4],[12,4],[13,4],[15,4],[14,4],[2,4],[16,4],[17,4],[18,4],[19,4],[20,4],[21,4],[22,4],[23,4],[3,4],[4,4],[24,4],[28,4],[25,4],[26,4],[27,4],[29,4],[30,4],[31,4],[5,4],[32,4],[33,4],[34,4],[35,4],[6,4],[39,4],[36,4],[37,4],[38,4],[40,4],[7,4],[41,4],[46,4],[47,4],[42,4],[43,4],[44,4],[45,4],[8,4],[51,4],[48,4],[49,4],[50,4],[52,4],[9,4],[53,4],[54,4],[55,4],[58,4],[56,4],[57,4],[59,4],[60,4],[10,4],[1,4],[11,4],[63,4],[62,4],[61,4],[444,309],[440,310],[439,84],[443,311],[442,312],[441,4],[471,313],[472,314],[467,315],[469,316],[468,317],[470,315],[466,318],[523,319],[515,320],[521,321],[517,4],[518,4],[516,322],[519,319],[511,4],[512,4],[522,323],[514,324],[520,325],[513,326],[675,327],[676,328],[674,329],[660,330],[377,331],[378,332],[380,333],[381,4],[407,4],[382,334],[383,335],[384,4],[385,336],[388,337],[404,338],[389,339],[405,4],[406,335],[379,4],[387,340],[679,341],[678,4],[401,342],[402,343],[400,344],[403,345],[397,346],[398,347],[399,348],[391,4],[680,4],[393,346],[394,346],[396,349],[395,346],[390,350],[392,351]],"exportedModulesMap":[[661,1],[659,2],[673,3],[350,4],[351,5],[349,4],[348,4],[672,4],[671,6],[657,7],[662,8],[663,9],[670,10],[655,11],[578,12],[656,13],[634,14],[665,15],[668,16],[669,4],[363,17],[347,18],[365,19],[371,20],[369,21],[372,22],[370,22],[366,4],[373,23],[374,24],[367,4],[368,25],[667,26],[666,4],[548,4],[550,27],[551,28],[549,29],[566,30],[570,31],[567,32],[569,32],[574,33],[568,34],[575,35],[552,36],[553,37],[576,38],[560,39],[555,40],[556,40],[562,41],[561,32],[563,42],[564,43],[559,44],[557,39],[558,45],[554,46],[565,47],[547,42],[572,4],[573,48],[571,4],[586,49],[588,50],[589,51],[590,52],[585,4],[587,4],[361,53],[362,54],[354,55],[355,56],[357,57],[360,58],[358,59],[356,56],[353,60],[352,4],[359,56],[581,61],[582,61],[583,62],[593,63],[594,61],[595,61],[596,64],[597,61],[598,61],[599,61],[600,61],[601,61],[592,61],[602,65],[603,63],[604,66],[605,66],[606,61],[607,67],[608,61],[609,68],[610,61],[611,61],[613,61],[584,4],[614,69],[612,42],[591,70],[579,42],[580,71],[464,72],[459,73],[457,74],[462,75],[458,4],[452,76],[456,77],[454,78],[451,79],[463,4],[461,80],[527,81],[526,82],[300,4],[658,42],[542,42],[450,83],[449,4],[409,84],[448,85],[386,4],[410,84],[465,85],[460,4],[78,86],[79,86],[81,87],[82,88],[83,89],[84,90],[85,91],[86,92],[87,93],[88,94],[89,95],[90,96],[91,96],[93,97],[92,98],[94,97],[95,99],[96,100],[80,101],[130,4],[97,102],[98,103],[99,104],[131,105],[100,106],[101,107],[102,108],[103,109],[104,110],[105,111],[106,112],[107,113],[108,114],[109,115],[110,115],[111,116],[112,117],[114,118],[113,119],[115,120],[116,121],[117,4],[118,122],[119,123],[120,124],[121,125],[122,126],[123,127],[124,128],[125,129],[126,130],[127,131],[128,132],[129,133],[69,4],[136,134],[137,135],[135,42],[133,136],[134,137],[67,4],[71,138],[224,42],[70,4],[408,4],[447,4],[375,139],[376,140],[615,4],[68,4],[677,141],[577,4],[364,4],[438,142],[412,143],[413,143],[414,143],[415,143],[416,143],[417,143],[418,143],[419,143],[420,143],[421,143],[422,143],[436,144],[423,143],[424,143],[425,143],[426,143],[427,143],[428,143],[429,143],[430,143],[432,143],[433,143],[431,143],[434,143],[435,143],[437,143],[411,145],[510,146],[503,147],[502,147],[501,147],[508,147],[481,147],[491,147],[490,147],[500,147],[499,147],[489,147],[497,147],[506,147],[507,147],[483,147],[480,42],[484,147],[498,147],[482,148],[496,147],[509,147],[492,147],[486,147],[485,147],[488,147],[487,147],[505,147],[493,147],[494,147],[495,147],[504,147],[478,149],[479,149],[477,4],[545,150],[544,42],[77,151],[303,152],[307,153],[309,154],[157,155],[171,156],[274,157],[203,4],[277,158],[239,159],[247,160],[275,161],[158,162],[202,4],[204,163],[276,164],[178,165],[159,166],[183,165],[172,165],[142,165],[230,167],[231,168],[147,4],[227,169],[232,170],[318,171],[225,170],[319,172],[209,4],[228,173],[331,174],[330,175],[234,170],[329,4],[327,4],[328,176],[229,42],[216,177],[217,178],[226,179],[242,180],[243,181],[233,182],[211,183],[212,184],[322,185],[325,186],[190,187],[189,188],[188,189],[334,42],[187,190],[163,4],[337,4],[340,4],[339,42],[341,191],[138,4],[268,4],[170,192],[140,193],[291,4],[292,4],[294,4],[297,194],[293,4],[295,195],[296,195],[156,4],[169,4],[302,196],[310,197],[314,198],[152,199],[219,200],[218,4],[210,183],[238,201],[236,202],[235,4],[237,4],[241,203],[214,204],[151,205],[176,206],[265,207],[143,208],[150,209],[139,157],[279,210],[289,211],[278,4],[288,212],[177,4],[161,213],[256,214],[255,4],[262,215],[264,216],[257,217],[261,218],[263,215],[260,217],[259,215],[258,217],[199,219],[184,219],[250,220],[185,220],[145,221],[144,4],[254,222],[253,223],[252,224],[251,225],[146,226],[223,227],[240,228],[222,229],[246,230],[248,231],[245,229],[179,226],[132,4],[266,232],[205,233],[287,234],[208,235],[282,236],[149,4],[283,237],[285,238],[286,239],[269,4],[281,208],[181,240],[267,241],[290,242],[153,4],[155,4],[160,243],[249,244],[148,245],[154,4],[207,246],[206,247],[162,248],[215,249],[213,250],[164,251],[166,252],[338,4],[165,253],[167,254],[305,4],[304,4],[306,4],[336,4],[168,255],[221,42],[76,4],[244,256],[191,4],[201,257],[180,4],[312,42],[321,258],[198,42],[316,170],[197,259],[299,260],[196,258],[141,4],[323,261],[194,42],[195,42],[186,4],[200,4],[193,262],[192,263],[182,264],[175,182],[284,4],[174,265],[173,4],[308,4],[220,42],[301,266],[66,4],[75,267],[72,42],[73,4],[74,4],[280,128],[273,268],[272,4],[271,269],[270,4],[311,270],[313,271],[315,272],[317,273],[320,274],[346,275],[324,275],[345,276],[326,277],[332,278],[333,279],[335,280],[342,281],[344,4],[343,282],[298,283],[546,284],[529,42],[530,170],[540,170],[532,42],[531,42],[541,42],[543,285],[533,42],[534,42],[537,170],[535,42],[536,170],[538,170],[539,170],[618,286],[617,4],[616,4],[619,42],[620,42],[621,42],[622,42],[623,42],[624,42],[625,42],[633,287],[626,42],[627,42],[628,42],[629,42],[630,42],[631,42],[632,42],[528,288],[525,289],[524,290],[475,291],[476,292],[455,83],[474,293],[446,294],[445,295],[635,296],[650,297],[636,296],[651,296],[648,298],[637,296],[642,299],[643,300],[653,301],[644,296],[649,302],[646,303],[638,304],[639,4],[652,305],[641,306],[640,4],[647,4],[645,299],[654,307],[473,308],[453,4],[664,4],[64,4],[65,4],[12,4],[13,4],[15,4],[14,4],[2,4],[16,4],[17,4],[18,4],[19,4],[20,4],[21,4],[22,4],[23,4],[3,4],[4,4],[24,4],[28,4],[25,4],[26,4],[27,4],[29,4],[30,4],[31,4],[5,4],[32,4],[33,4],[34,4],[35,4],[6,4],[39,4],[36,4],[37,4],[38,4],[40,4],[7,4],[41,4],[46,4],[47,4],[42,4],[43,4],[44,4],[45,4],[8,4],[51,4],[48,4],[49,4],[50,4],[52,4],[9,4],[53,4],[54,4],[55,4],[58,4],[56,4],[57,4],[59,4],[60,4],[10,4],[1,4],[11,4],[63,4],[62,4],[61,4],[444,309],[440,310],[439,84],[443,311],[442,312],[441,4],[471,313],[472,314],[467,315],[469,316],[468,317],[470,315],[466,318],[523,319],[515,320],[521,321],[517,4],[518,4],[516,322],[519,319],[511,4],[512,4],[522,323],[514,324],[520,325],[513,326],[675,327],[676,328],[674,329],[660,330],[377,331],[378,332],[380,333],[381,4],[407,4],[382,334],[383,335],[384,4],[385,336],[388,337],[404,338],[389,339],[405,4],[406,335],[379,4],[387,340],[679,341],[678,4],[401,342],[402,343],[400,344],[403,345],[397,346],[398,347],[399,348],[391,4],[680,4],[393,346],[394,346],[396,349],[395,346],[390,350],[392,351]],"semanticDiagnosticsPerFile":[661,659,673,350,351,349,348,672,671,657,662,663,670,655,578,656,634,665,668,669,363,347,365,371,369,372,370,366,373,374,367,368,667,666,548,550,551,549,566,570,567,569,574,568,575,552,553,576,560,555,556,562,561,563,564,559,557,558,554,565,547,572,573,571,586,588,589,590,585,587,361,362,354,355,357,360,358,356,353,352,359,581,582,583,593,594,595,596,597,598,599,600,601,592,602,603,604,605,606,607,608,609,610,611,613,584,614,612,591,579,580,464,459,457,462,458,452,456,454,451,463,461,527,526,300,658,542,450,449,409,448,386,410,465,460,78,79,81,82,83,84,85,86,87,88,89,90,91,93,92,94,95,96,80,130,97,98,99,131,100,101,102,103,104,105,106,107,108,109,110,111,112,114,113,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,69,136,137,135,133,134,67,71,224,70,408,447,375,376,615,68,677,577,364,438,412,413,414,415,416,417,418,419,420,421,422,436,423,424,425,426,427,428,429,430,432,433,431,434,435,437,411,510,503,502,501,508,481,491,490,500,499,489,497,506,507,483,480,484,498,482,496,509,492,486,485,488,487,505,493,494,495,504,478,479,477,545,544,77,303,307,309,157,171,274,203,277,239,247,275,158,202,204,276,178,159,183,172,142,230,231,147,227,232,318,225,319,209,228,331,330,234,329,327,328,229,216,217,226,242,243,233,211,212,322,325,190,189,188,334,187,163,337,340,339,341,138,268,170,140,291,292,294,297,293,295,296,156,169,302,310,314,152,219,218,210,238,236,235,237,241,214,151,176,265,143,150,139,279,289,278,288,177,161,256,255,262,264,257,261,263,260,259,258,199,184,250,185,145,144,254,253,252,251,146,223,240,222,246,248,245,179,132,266,205,287,208,282,149,283,285,286,269,281,181,267,290,153,155,160,249,148,154,207,206,162,215,213,164,166,338,165,167,305,304,306,336,168,221,76,244,191,201,180,312,321,198,316,197,299,196,141,323,194,195,186,200,193,192,182,175,284,174,173,308,220,301,66,75,72,73,74,280,273,272,271,270,311,313,315,317,320,346,324,345,326,332,333,335,342,344,343,298,546,529,530,540,532,531,541,543,533,534,537,535,536,538,539,618,617,616,619,620,621,622,623,624,625,633,626,627,628,629,630,631,632,528,525,524,475,476,455,474,446,445,635,650,636,651,648,637,642,643,653,644,649,646,638,639,652,641,640,647,645,654,473,453,664,64,65,12,13,15,14,2,16,17,18,19,20,21,22,23,3,4,24,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,58,56,57,59,60,10,1,11,63,62,61,444,440,439,443,442,441,471,472,467,469,468,470,466,523,515,521,517,518,516,519,511,512,522,514,520,513,675,676,674,660,377,378,380,381,407,382,383,384,385,388,404,[389,[{"file":"../utils/metadata-manager.ts","start":3379,"length":6,"code":2339,"category":1,"messageText":"Property 'length' does not exist on type 'Promise'."},{"file":"../utils/metadata-manager.ts","start":3401,"length":6,"code":2740,"category":1,"messageText":"Type 'Promise' is missing the following properties from type 'string[]': length, pop, push, concat, and 35 more.","relatedInformation":[{"file":"../utils/metadata-manager.ts","start":3056,"length":6,"messageText":"The expected type comes from property 'errors' which is declared here on type '{ isValid: boolean; errors: string[]; metadata?: MetadataResult; }'","category":3,"code":6500}]},{"file":"../utils/metadata-manager.ts","start":3574,"length":6,"code":2339,"category":1,"messageText":"Property 'length' does not exist on type 'Promise'."},{"file":"../utils/metadata-manager.ts","start":4027,"length":6,"code":2339,"category":1,"messageText":"Property 'length' does not exist on type 'Promise'."},{"file":"../utils/metadata-manager.ts","start":4139,"length":7,"code":2339,"category":1,"messageText":"Property 'forEach' does not exist on type 'Promise'."},{"file":"../utils/metadata-manager.ts","start":4225,"length":6,"code":2339,"category":1,"messageText":"Property 'length' does not exist on type 'Promise'."},{"file":"../utils/metadata-manager.ts","start":4245,"length":6,"code":2322,"category":1,"messageText":"Type 'Promise' is not assignable to type 'string[]'.","relatedInformation":[{"file":"../utils/metadata-manager.ts","start":3056,"length":6,"messageText":"The expected type comes from property 'errors' which is declared here on type '{ isValid: boolean; errors: string[]; metadata?: MetadataResult; }'","category":3,"code":6500}]}]],405,406,379,387,679,678,401,402,400,403,397,398,399,391,680,393,394,396,395,390,392],"affectedFilesPendingEmit":[661,659,673,350,351,349,348,672,671,657,662,663,670,655,578,656,634,665,668,669,363,675,676,674,660,377,378,380,381,407,382,383,384,385,388,404,389,405,406,379,387]},"version":"5.3.2"} \ No newline at end of file diff --git a/package.json b/package.json index 26f0a0f09..e7656ebbe 100644 --- a/package.json +++ b/package.json @@ -8,17 +8,15 @@ "fix": "eslint . --ext mdx --fix && pnpm spellcheck:fix && pnpm breadcrumbs && pnpm fix-redirects && pnpm metadata-batch-cli", "spellcheck:lint": "cspell lint \"**/*.mdx\"", "spellcheck:fix": "cspell --words-only --unique \"**/*.mdx\" | sort --ignore-case | uniq > words.txt", - "breadcrumbs": "npx ts-node --skip-project utils/create-breadcrumbs.ts", - "check-redirects": "npx ts-node --skip-project utils/redirects.ts", - "link-checker": "npx ts-node --skip-project utils/link-checker.ts", - "fix-redirects": "npx ts-node --skip-project utils/fix-redirects.ts", - "check-breadcrumbs": "npx ts-node --skip-project utils/breadcrumbs.ts", - "index:docs": "npx ts-node --skip-project utils/algolia-indexer.ts", + "breadcrumbs": "npx ts-node-esm --skip-project utils/create-breadcrumbs.ts", + "check-breadcrumbs": "node --loader ts-node/esm utils/breadcrumbs.ts", + "check-redirects": "node --loader ts-node/esm utils/redirects.ts", + "fix-redirects": "node --loader ts-node/esm utils/fix-redirects.ts", "metadata-batch-cli": "node --loader ts-node/esm utils/metadata-batch-cli.ts", "metadata-batch-cli:dry": "pnpm metadata-batch-cli --dry-run", "metadata-batch-cli:verbose": "pnpm metadata-batch-cli --verbose", - "validate-metadata": "npx ts-node --skip-project utils/metadata-manager.ts", - "validate-pr-metadata": "npx ts-node --skip-project utils/metadata-manager.ts --pr", + "validate-metadata": "CHANGED_FILES=$(git diff --name-only HEAD) node --loader ts-node/esm utils/metadata-manager.ts", + "validate-pr-metadata": "node --loader ts-node/esm utils/metadata-manager.ts --pr", "dev": "next dev", "build": "next build", "start": "next start", diff --git a/utils/breadcrumbs.ts b/utils/breadcrumbs.ts index 54c6bbd2c..921655513 100644 --- a/utils/breadcrumbs.ts +++ b/utils/breadcrumbs.ts @@ -1,8 +1,13 @@ -import * as fs from 'fs/promises'; -import * as path from 'path'; +import { fileURLToPath } from 'url' +import path from 'path' +import fs from 'fs' import matter from 'gray-matter'; -const rootDir: string = path.join(__dirname, '..', 'pages'); +// Get current file path in ESM +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +const rootDir = path.join(__dirname, '..', 'pages'); const warnings: string[] = []; // ANSI color codes @@ -37,7 +42,7 @@ const excludedPages = [ ]; async function getContentFiles(folderPath: string): Promise { - const files = await fs.readdir(folderPath, { withFileTypes: true }); + const files = await fs.promises.readdir(folderPath, { withFileTypes: true }); const fileInfos: FileInfo[] = []; const folderName = path.basename(folderPath); @@ -52,7 +57,7 @@ async function getContentFiles(folderPath: string): Promise { if (file.isFile() && (file.name.endsWith('.md') || file.name.endsWith('.mdx'))) { try { - const content = await fs.readFile(filePath, 'utf-8'); + const content = await fs.promises.readFile(filePath, 'utf-8'); const { data: frontMatter } = matter(content); const fileName = path.basename(file.name, path.extname(file.name)); const fileTitle = frontMatter.title || fileName; @@ -75,7 +80,7 @@ async function getContentFiles(folderPath: string): Promise { async function getBreadcrumbCards(breadcrumbPath: string): Promise> { try { - const content = await fs.readFile(breadcrumbPath, 'utf-8'); + const content = await fs.promises.readFile(breadcrumbPath, 'utf-8'); const cardMatches = content.match(/]*href="([^"]+)"[^>]*>/g) || []; return new Set( cardMatches.map(match => { @@ -89,7 +94,7 @@ async function getBreadcrumbCards(breadcrumbPath: string): Promise> } async function checkDirectory(dirPath: string): Promise { - const entries = await fs.readdir(dirPath, { withFileTypes: true }); + const entries = await fs.promises.readdir(dirPath, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory() && !entry.name.startsWith('_') && !entry.name.startsWith('.')) { @@ -127,7 +132,7 @@ async function main() { for (const section of mainSections) { const sectionPath = path.join(rootDir, section); try { - await fs.access(sectionPath); + await fs.promises.access(sectionPath); await checkDirectory(sectionPath); console.log(`Completed checking ${section} section`); } catch (error) { diff --git a/utils/metadata-analyzer.ts b/utils/metadata-analyzer.ts index eba78f1f0..9b2eb135d 100644 --- a/utils/metadata-analyzer.ts +++ b/utils/metadata-analyzer.ts @@ -30,15 +30,12 @@ export function generateTopic(title: string): string { .replace(/\s+/g, '-') || 'general'; } -// Fix duplicate landing page detection -let detectedLandingPages = new Set(); - /** * Enhanced landing page detection with Cards component awareness */ -function isLandingPage(content: string, filepath: string): boolean { +function isLandingPage(content: string, filepath: string, detectedPages: Set): boolean { // If we've already detected this file, return false - if (detectedLandingPages.has(filepath)) { + if (detectedPages.has(filepath)) { return false; } @@ -70,7 +67,7 @@ function isLandingPage(content: string, filepath: string): boolean { const isLanding = (isOperatorLanding || (isOverviewPage && hasMultipleCards)) && !isTooDeep && !notLandingPage; if (isLanding) { - detectedLandingPages.add(filepath); + detectedPages.add(filepath); console.log(`Landing page detected: ${filepath}`); } @@ -126,10 +123,20 @@ function getLandingPageCategories(filepath: string, content: string): Set(); + // Add categories without logging + if (filepath.includes('/notices/')) { + if (content.toLowerCase().includes('network') || + content.toLowerCase().includes('upgrade')) { + categories.add('network-upgrade'); + categories.add('holocene'); + } + if (content.toLowerCase().includes('security')) { + categories.add('security'); + } + } + // Connect section categories if (filepath.includes('/connect/')) { if (filepath.includes('/contribute/')) { @@ -148,23 +155,6 @@ function detectCategories(content: string, filepath: string, detectionLog: strin return Array.from(categories); } - // Notice categories - if (filepath.includes('/notices/')) { - if (filepath.includes('holocene')) { - categories.add('holocene'); - categories.add('network-upgrade'); - } - if (filepath.includes('pectra')) { - categories.add('security'); - categories.add('protocol'); - } - if (filepath.includes('sdk')) { - categories.add('typescript'); - categories.add('javascript'); - } - return Array.from(categories); - } - // Get started categories if (filepath.includes('/get-started/')) { if (filepath.includes('interop')) { @@ -499,7 +489,6 @@ function detectCategories(content: string, filepath: string, detectionLog: strin .sort((a, b) => priorityOrder.indexOf(a) - priorityOrder.indexOf(b)) .slice(0, 5); - detectionLog.push(`Final categories: ${sortedCategories.join(', ')}`); return sortedCategories; } @@ -564,66 +553,34 @@ function countGuideSignals(content: string): number { /** * Detects content type based on content structure and signals */ -function detectContentType(content: string, detectionLog: string[], filepath: string): typeof VALID_CONTENT_TYPES[number] { +function detectContentType( + content: string, + detectionLog: string[], + filepath: string, + detectedPages: Set +): typeof VALID_CONTENT_TYPES[number] { // Check for landing pages first - if (isLandingPage(content, filepath)) { - detectionLog.push("Detected as landing page based on structure"); - return 'landing-page'; - } - - // Check for configuration content - if (filepath.includes('/configuration/') || - filepath.match(/config\.(mdx?|tsx?)$/)) { - detectionLog.push("Detected as reference based on configuration content"); - return 'reference'; + if (isLandingPage(content, filepath, detectedPages)) { + return 'landing-page' } - // Check for overview/landing pages - if (filepath.match(/\/(overview|index)\.(mdx?|tsx?)$/) || - filepath.endsWith('chain-operators.mdx') || - filepath.endsWith('node-operators.mdx') || - filepath.endsWith('tools.mdx') || - filepath.endsWith('features.mdx')) { - detectionLog.push("Detected as landing page based on path"); - return 'landing-page'; + // Check for notices + if (filepath.includes('/notices/')) { + return 'notice' } // Check for tutorials - if (filepath.includes('/tutorials/') || - content.toLowerCase().includes('step-by-step') || - content.match(/Step \d+:/g)) { - detectionLog.push("Detected as tutorial based on content structure"); - return 'tutorial'; - } - - // Check for troubleshooting content - if (filepath.includes('/troubleshooting') || - content.toLowerCase().includes('common problems') || - content.toLowerCase().includes('common issues') || - (content.match(/problem:|solution:|error:|warning:/gi) || []).length > 2) { - detectionLog.push("Detected as troubleshooting content"); - return 'troubleshooting'; - } - - // Check for notices/announcements - if (content.toLowerCase().includes('breaking change') || - content.toLowerCase().includes('deprecation notice') || - content.toLowerCase().includes('upgrade notice')) { - detectionLog.push("Detected as technical notice"); - return 'notice'; + if (filepath.includes('/tutorials/')) { + return 'tutorial' } - // Reference vs Guide scoring - const referenceScore = countReferenceSignals(content, filepath); - const guideScore = countGuideSignals(content); - - if (referenceScore > guideScore * 1.5) { - detectionLog.push(`Detected as reference (scores: ref=${referenceScore}, guide=${guideScore})`); - return 'reference'; + // Check for reference docs + if (filepath.includes('/reference/')) { + return 'reference' } - detectionLog.push(`Detected as guide (scores: ref=${referenceScore}, guide=${guideScore})`); - return 'guide'; + // Default to guide + return 'guide' } /** @@ -632,23 +589,20 @@ function detectContentType(content: string, detectionLog: string[], filepath: st export function analyzeContent(content: string, filepath: string, verbose: boolean = false): MetadataResult { const detectionLog: string[] = []; const warnings: string[] = []; + const detectedPages = new Set(); - const contentType = detectContentType(content, detectionLog, filepath); + const contentType = detectContentType(content, detectionLog, filepath, detectedPages); const categories = detectCategories(content, filepath, detectionLog); - // Track files needing review + // Only track warnings if verbose mode is on if (contentType === 'NEEDS_REVIEW') { warnings.push('Content type needs manual review'); - global.filesNeedingContentTypeReview = (global.filesNeedingContentTypeReview || 0) + 1; } if (categories.length === 0) { warnings.push('Categories may need manual review'); - global.filesNeedingCategoryReview = (global.filesNeedingCategoryReview || 0) + 1; } - - // Track total files processed - global.totalFiles = (global.totalFiles || 0) + 1; + // Only log if verbose mode is on if (verbose) { console.log(`\n📄 ${filepath}`); console.log(` Type: ${contentType}`); diff --git a/utils/metadata-batch-cli.ts b/utils/metadata-batch-cli.ts index 4789252f3..45e67df10 100644 --- a/utils/metadata-batch-cli.ts +++ b/utils/metadata-batch-cli.ts @@ -2,10 +2,14 @@ import { promises as fs } from 'fs' import path from 'path' +import { fileURLToPath } from 'url' +import { updateMetadata } from './metadata-manager' import matter from 'gray-matter' -import globby from 'globby' -import { updateMetadata } from './metadata-manager.js' -import { MetadataResult } from './types/metadata-types.js' + +// @ts-ignore +const globModule = await import('glob') +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) // Interface for processing summary interface ProcessingSummary { @@ -32,13 +36,7 @@ interface ParentMetadata { } async function findMdxFiles(pattern: string): Promise { - const files = await globby(pattern, { - absolute: true, - expandDirectories: { - files: ['*.mdx'], - extensions: ['mdx'] - } - }) + const files = await globModule.glob(pattern, { ignore: ['pages/_*.mdx'] }) return files } @@ -96,10 +94,10 @@ async function updateFrontmatter(filePath: string, dryRun: boolean = false, verb const result = await updateMetadata(filePath, { dryRun, - validateOnly: false + prMode: !verbose }) - if (!result.metadata) { + if (!result.isValid) { throw new Error(`Failed to process ${filePath}: ${result.errors.join(', ')}`) } @@ -120,92 +118,65 @@ async function updateFrontmatter(filePath: string, dryRun: boolean = false, verb } } -async function main() { - try { - const args = process.argv.slice(2) - const dryRun = args.includes('--dry-run') - const verbose = args.includes('--verbose') - - const targetPaths = args.filter(arg => !arg.startsWith('--')) - if (targetPaths.length === 0) { - console.error(`${colors.red}Please provide at least one path to process${colors.reset}`) - process.exit(1) - } +async function processFiles(files: string[]): Promise { + let hasErrors = false + let processedCount = 0 - const allMdxFiles = Array.from( - new Set( - (await Promise.all(targetPaths.map(pattern => findMdxFiles(pattern)))) - .flat() - ) - ) - - console.log(`Found ${allMdxFiles.length} .mdx files to process\n`) - - const summaries: ProcessingSummary[] = [] - - // Process each file - for (const file of allMdxFiles) { - try { - const result = await updateFrontmatter(file, dryRun, verbose) - const relativePath = path.relative(process.cwd(), file) - - // Determine if categorization is uncertain - const hasUncertainCategories = - !result.categories.length || - (result.categories.length === 1 && result.categories[0] === 'protocol') - - summaries.push({ - path: relativePath, - categories: result.categories, - uncertainCategories: hasUncertainCategories && !result.isImported, // Don't flag imported content - contentType: result.contentType, - isImported: result.isImported + for (const file of files) { + try { + const result = await updateMetadata(file, { dryRun: true, prMode: true }) + if (!result.isValid) { + hasErrors = true + console.log(`\n${colors.red}Error in ${file}:${colors.reset}`) + result.errors.forEach(error => { + console.log(` ${colors.yellow}→${colors.reset} ${error}`) }) - } catch (error) { - console.error(`${colors.red}Error processing ${file}:${colors.reset}`, error) } + processedCount++ + } catch (e) { + console.log(`\n${colors.red}Failed to process ${file}: ${e}${colors.reset}`) + hasErrors = true } + } + + console.log( + hasErrors + ? `\n${colors.red}✖ Found metadata issues in some files${colors.reset}` + : `\n${colors.green}✓ Validated ${processedCount} files successfully${colors.reset}` + ) + + return hasErrors +} + +async function main() { + try { + console.log('Checking metadata...') - // Print summary - console.log('\nProcessing Summary:') - console.log('==================') - - summaries.forEach(summary => { - // File path in blue - console.log(`\n📄 ${colors.blue}${summary.path}${colors.reset}`) - // Type in default color - console.log(` Type: ${summary.contentType}`) - if (summary.isImported) { - console.log(' Status: Imported content') - } - // Categories in default color - console.log(` Categories: ${summary.categories.join(', ') || 'none'}`) - - if (summary.uncertainCategories) { - console.log(` ${colors.yellow}⚠️ Categories may need manual review${colors.reset}`) - } - }) - - const needsReview = summaries.filter(s => s.uncertainCategories).length - const importedCount = summaries.filter(s => s.isImported).length - - console.log('\n=================') - console.log('Final Summary:') - console.log(`${colors.green}✓ Processed ${summaries.length} files${colors.reset}`) - if (importedCount > 0) { - console.log(`ℹ️ ${importedCount} imported files`) - } - if (needsReview > 0) { - console.log(`${colors.yellow}⚠️ ${needsReview} files may need category review${colors.reset}`) - } - if (dryRun) { - console.log(`${colors.blue}(Dry run - no changes made)${colors.reset}`) + // Get modified files from git + const gitOutput = process.env.CHANGED_FILES || '' + const modifiedFiles = gitOutput + .split('\n') + .filter(file => file.endsWith('.mdx')) + .map(file => path.resolve(process.cwd(), file)) + + if (modifiedFiles.length === 0) { + console.log(`${colors.green}✓ No MDX files modified${colors.reset}`) + process.exit(0) } + + console.log(`Found ${modifiedFiles.length} modified files to check`) + + const hasErrors = await processFiles(modifiedFiles) + process.exit(hasErrors ? 1 : 0) } catch (error) { - console.error(`${colors.red}Fatal error:${colors.reset}`, error) + console.error(`${colors.red}Error: ${error}${colors.reset}`) process.exit(1) } } -// Run the script -main() \ No newline at end of file +// Force output buffering +console.log = console.log.bind(console) +main().catch(error => { + console.error(`${colors.red}Fatal error: ${error}${colors.reset}`) + process.exit(1) +}) \ No newline at end of file diff --git a/utils/metadata-manager.ts b/utils/metadata-manager.ts index 9b16d674c..6ea2fe6c8 100644 --- a/utils/metadata-manager.ts +++ b/utils/metadata-manager.ts @@ -3,56 +3,83 @@ import path from 'path' import matter from 'gray-matter' import yaml from 'js-yaml' import { analyzeContent } from './metadata-analyzer' -import { - MetadataResult, - VALID_PERSONAS, - VALID_CONTENT_TYPES, - VALID_CATEGORIES -} from './types/metadata-types' +import type { MetadataResult } from './types/metadata-types' + +// Add the interfaces at the top of the file +interface ValidationOptions { + prMode?: boolean + dryRun?: boolean + validateOnly?: boolean +} + +interface ValidationResult { + isValid: boolean + errors: string[] +} // Validation functions -export function validateMetadata(metadata: MetadataResult, filePath: string): string[] { - const errors: string[] = [] - const isLandingPage = filePath.includes('index.mdx') || - (metadata.content && metadata.content.includes('')) - - // Required fields for all pages - if (!metadata.title) errors.push('Missing title') - if (!metadata.lang) errors.push('Missing lang') - if (!metadata.description) errors.push('Missing description') - if (!metadata.topic) errors.push('Missing topic') - - // Additional validations for non-landing pages - if (!isLandingPage) { - // Validate personas +async function validateMetadata(metadata: MetadataResult, filepath: string, options: ValidationOptions = {}): Promise { + const errors = [] as string[] + const config = await loadConfig('keywords.config.yaml') + + // Required field checks based on config + if (!metadata.topic) { + errors.push('Missing required field: topic') + } + + // Check personas + if (config.metadata_rules.persona.required) { if (!metadata.personas || metadata.personas.length === 0) { - errors.push('Missing personas') - } else { - const invalidPersonas = metadata.personas.filter(p => !VALID_PERSONAS.includes(p as any)) - if (invalidPersonas.length > 0) { - errors.push(`Invalid personas: ${invalidPersonas.join(', ')}`) - } + errors.push('Missing required field: personas') + } else if (metadata.personas.length < config.metadata_rules.persona.min) { + errors.push(`Personas must have at least ${config.metadata_rules.persona.min} value(s)`) } + } + + // Check content_type + if (config.metadata_rules.content_type.required && !metadata.content_type) { + errors.push('Missing required field: content_type') + } + + // Check categories + if (config.metadata_rules.categories.required) { + if (!metadata.categories || metadata.categories.length === 0) { + errors.push('Missing required field: categories') + } else if (metadata.categories.length < config.metadata_rules.categories.min) { + errors.push(`Categories must have at least ${config.metadata_rules.categories.min} value(s)`) + } + } - // Validate content_type - if (!metadata.content_type) { - errors.push('Missing content_type') - } else if (!VALID_CONTENT_TYPES.includes(metadata.content_type as any)) { + // Validate enum values if present + if (metadata.personas?.length > 0) { + const validPersonas = config.metadata_rules.persona.validation_rules[0].enum + metadata.personas.forEach(p => { + if (!validPersonas.includes(p)) { + errors.push(`Invalid persona: ${p}`) + } + }) + } + + if (metadata.content_type) { + const validTypes = config.metadata_rules.content_type.validation_rules[0].enum + if (!validTypes.includes(metadata.content_type)) { errors.push(`Invalid content_type: ${metadata.content_type}`) } + } - // Validate categories - if (!metadata.categories || metadata.categories.length === 0) { - errors.push('Missing categories') - } else { - const invalidCategories = metadata.categories.filter(c => !VALID_CATEGORIES.includes(c as any)) - if (invalidCategories.length > 0) { - errors.push(`Invalid categories: ${invalidCategories.join(', ')}`) + if (metadata.categories?.length > 0) { + const validCategories = config.metadata_rules.categories.values + metadata.categories.forEach(c => { + if (!validCategories.includes(c)) { + errors.push(`Invalid category: ${c}`) } - } + }) } - return errors + return { + isValid: errors.length === 0, + errors + } } // Generation functions @@ -69,16 +96,16 @@ export async function generateMetadata(filePath: string): Promise 0 && !options.prMode) { + console.log(`\nMetadata validation errors in ${filePath}:`) + validationResult.errors.forEach(error => console.log(`- ${error}`)) } return { - isValid: errors.length === 0, - errors, + isValid: validationResult.isValid, + errors: validationResult.errors, metadata: newMetadata } } catch (error) { @@ -136,7 +175,6 @@ export async function validatePRChanges(): Promise { .map(file => path.resolve(process.cwd(), file)) if (modifiedFiles.length === 0) { - console.log('No .mdx files modified') return true } @@ -157,12 +195,46 @@ export async function validatePRChanges(): Promise { } } -// CLI support - update to use import.meta.url instead of require.main +// CLI support if (import.meta.url === `file://${process.argv[1]}`) { - const args = process.argv.slice(2) - if (args.includes('--pr')) { - validatePRChanges().then(success => { - process.exit(success ? 0 : 1) - }) + const gitOutput = process.env.CHANGED_FILES || '' + const modifiedFiles = gitOutput + .split('\n') + .filter(file => file.endsWith('.mdx')) + .map(file => path.resolve(process.cwd(), file)) + + if (modifiedFiles.length === 0) { + console.log('\x1b[32m✓ Metadata validation: no files to check\x1b[0m') + process.exit(0) + } + + const validateFiles = async () => { + for (const file of modifiedFiles) { + const result = await updateMetadata(file, { validateOnly: true, prMode: true }) + if (!result.isValid) { + console.log('\x1b[31m✖ Metadata validation: errors found\x1b[0m') + process.exit(1) + } + } + console.log('\x1b[32m✓ Metadata validation: all files valid\x1b[0m') + process.exit(0) + } + + validateFiles().catch(error => { + console.error('\x1b[31m✖ Metadata validation: error occurred\x1b[0m') + process.exit(1) + }) +} + +async function loadConfig(configPath: string): Promise { + const content = await fs.readFile(configPath, 'utf8') + return yaml.load(content) +} + +async function validateConfig(configPath: string): Promise { + const config = await loadConfig(configPath) + if (!config.metadata_rules) { + throw new Error('Invalid config: missing metadata_rules') } + // Silently validate - no console output at all } \ No newline at end of file diff --git a/utils/types/metadata-types.ts b/utils/types/metadata-types.ts index 3080b57b1..543c114f2 100644 --- a/utils/types/metadata-types.ts +++ b/utils/types/metadata-types.ts @@ -4,13 +4,40 @@ import path from 'path' // Load and parse keywords.config.yaml const configPath = path.join(process.cwd(), 'keywords.config.yaml') -const yamlContent = yaml.load(fs.readFileSync(configPath, 'utf8')) - -// Add debug logging -console.log('Config structure:', JSON.stringify(yamlContent, null, 2)) +const yamlContent = yaml.load(fs.readFileSync(configPath, 'utf8')) as MetadataConfig // Type guard to ensure the config has the expected structure -function isValidConfig(config: any): config is { +function isValidConfig(config: any): config is MetadataConfig { + return ( + config && + config.metadata_rules && + config.metadata_rules.persona?.validation_rules?.[0]?.enum && + config.metadata_rules.content_type?.validation_rules?.[0]?.enum && + config.metadata_rules.categories?.values + ) +} + +if (!isValidConfig(yamlContent)) { + throw new Error('Invalid keywords.config.yaml structure') +} + +export const VALID_PERSONAS = yamlContent.metadata_rules.persona.validation_rules[0].enum as readonly string[] +export const VALID_CONTENT_TYPES = yamlContent.metadata_rules.content_type.validation_rules[0].enum as readonly string[] +export const VALID_CATEGORIES = yamlContent.metadata_rules.categories.values as readonly string[] + +export interface ValidationRule { + pattern?: string + description?: string + enum?: string[] +} + +export interface MetadataField { + required?: boolean + multiple?: boolean + validation_rules?: ValidationRule[] +} + +export interface MetadataConfig { metadata_rules: { persona: { required: boolean @@ -44,52 +71,6 @@ function isValidConfig(config: any): config is { values: string[] } } -} { - // Add debug logging - console.log('Checking config structure...') - console.log('Has metadata_rules:', !!config?.metadata_rules) - console.log('Has persona:', !!config?.metadata_rules?.persona) - console.log('Has content_type:', !!config?.metadata_rules?.content_type) - console.log('Has categories:', !!config?.metadata_rules?.categories) - - return ( - config && - config.metadata_rules && - config.metadata_rules.persona?.validation_rules?.[0]?.enum && - config.metadata_rules.content_type?.validation_rules?.[0]?.enum && - config.metadata_rules.categories?.values - ) -} - -if (!isValidConfig(yamlContent)) { - throw new Error('Invalid keywords.config.yaml structure') -} - -// Define the arrays with their literal types -export const VALID_PERSONAS: readonly string[] = yamlContent.metadata_rules.persona.validation_rules[0].enum -export const VALID_CONTENT_TYPES: readonly string[] = yamlContent.metadata_rules.content_type.validation_rules[0].enum -export const VALID_CATEGORIES: readonly string[] = yamlContent.metadata_rules.categories.values - -export interface ValidationRule { - pattern?: string - description?: string - enum?: string[] -} - -export interface MetadataField { - required?: boolean - multiple?: boolean - validation_rules?: ValidationRule[] -} - -export interface MetadataConfig { - metadata_rules?: { - topic?: MetadataField - persona?: MetadataField - content_type?: MetadataField - categories?: MetadataField - timeframe?: MetadataField - } } // Type for metadata results @@ -98,13 +79,12 @@ export interface MetadataResult { lang: string description: string topic: string - personas: typeof VALID_PERSONAS[number][] + personas: Array // Explicitly typed array content_type: typeof VALID_CONTENT_TYPES[number] - categories: typeof VALID_CATEGORIES[number][] + categories: Array // Explicitly typed array is_imported_content: string - content?: string // Added for landing page detection - timeframe?: string - detectionLog?: string[] // Added for content analysis logging + content?: string + detectionLog?: Array // Explicitly typed array } export interface ProcessedFile { @@ -115,5 +95,5 @@ export interface ProcessedFile { export interface Manifest { timestamp: string - processed_files: ProcessedFile[] + processed_files: Array // Explicitly typed array } \ No newline at end of file From 4a4dfa54fe5f19e9f9697606d653170987ca9901 Mon Sep 17 00:00:00 2001 From: cpengilly <29023967+cpengilly@users.noreply.github.com> Date: Fri, 21 Feb 2025 22:55:05 -0800 Subject: [PATCH 3/5] coderabbit-fixes --- package.json | 1 + utils/metadata-analyzer.ts | 353 ++++++++++++------------------------ utils/metadata-batch-cli.ts | 48 ++++- 3 files changed, 159 insertions(+), 243 deletions(-) diff --git a/package.json b/package.json index e7656ebbe..e2012b05e 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "check-breadcrumbs": "node --loader ts-node/esm utils/breadcrumbs.ts", "check-redirects": "node --loader ts-node/esm utils/redirects.ts", "fix-redirects": "node --loader ts-node/esm utils/fix-redirects.ts", + "link-checker": "node --loader ts-node/esm utils/link-checker.ts", "metadata-batch-cli": "node --loader ts-node/esm utils/metadata-batch-cli.ts", "metadata-batch-cli:dry": "pnpm metadata-batch-cli --dry-run", "metadata-batch-cli:verbose": "pnpm metadata-batch-cli --verbose", diff --git a/utils/metadata-analyzer.ts b/utils/metadata-analyzer.ts index 9b2eb135d..f2a6eb873 100644 --- a/utils/metadata-analyzer.ts +++ b/utils/metadata-analyzer.ts @@ -119,138 +119,26 @@ function getLandingPageCategories(filepath: string, content: string): Set { const categories = new Set(); - - // Add categories without logging - if (filepath.includes('/notices/')) { - if (content.toLowerCase().includes('network') || - content.toLowerCase().includes('upgrade')) { - categories.add('network-upgrade'); - categories.add('holocene'); - } - if (content.toLowerCase().includes('security')) { - categories.add('security'); - } - } - - // Connect section categories - if (filepath.includes('/connect/')) { - if (filepath.includes('/contribute/')) { - if (filepath.includes('docs-contribute')) { - categories.add('typescript'); - categories.add('javascript'); - } - if (filepath.includes('stack-contribute')) { - categories.add('go'); - categories.add('rust'); - } - } - if (filepath.includes('/resources/')) { - categories.add('protocol'); - } - return Array.from(categories); + + // Base protocol content + if (filepath.match(/\/(rollup|transactions|components|differences|smart-contracts)\//)) { + categories.add('protocol'); } - // Get started categories - if (filepath.includes('/get-started/')) { - if (filepath.includes('interop')) { - categories.add('interop'); - categories.add('cross-chain-messaging'); - } - if (filepath.includes('op-stack')) { - categories.add('protocol'); - categories.add('devnets'); - } - if (filepath.includes('superchain')) { - categories.add('blockspace-charters'); - categories.add('superchain-registry'); + // Research and specs + if (filepath.includes('/research/')) { + categories.add('protocol'); + if (content.toLowerCase().includes('block time')) { + categories.add('block-times'); } - return Array.from(categories); } - // Stack-specific categories - if (filepath.includes('/stack/')) { - // Base protocol content - if (filepath.match(/\/(rollup|transactions|components|differences|smart-contracts)\//)) { - categories.add('protocol'); - } - - // Research and specs - if (filepath.includes('/research/')) { - categories.add('protocol'); - if (content.toLowerCase().includes('block time')) { - categories.add('block-times'); - } - } - - // Root stack pages - if (filepath.match(/\/stack\/[^/]+\.mdx$/)) { - // Landing pages - if (filepath.endsWith('features.mdx') || - filepath.endsWith('beta-features.mdx')) { - categories.add('protocol'); - if (content.toLowerCase().includes('gas')) { - categories.add('custom-gas-token'); - } - if (content.toLowerCase().includes('data availability')) { - categories.add('alt-da'); - } - } - - // Core protocol pages - if (filepath.endsWith('rollup.mdx') || - filepath.endsWith('transactions.mdx') || - filepath.endsWith('components.mdx') || - filepath.endsWith('differences.mdx') || - filepath.endsWith('smart-contracts.mdx')) { - categories.add('protocol'); - } - - // Development pages - if (filepath.endsWith('dev-node.mdx') || - filepath.endsWith('getting-started.mdx') || - filepath.endsWith('public-devnets.mdx')) { - categories.add('devnets'); - } - - // Security pages - if (filepath.endsWith('security.mdx')) { - categories.add('security'); - } - - // Research pages - if (filepath.endsWith('research.mdx') || - filepath.endsWith('fact-sheet.mdx')) { - categories.add('protocol'); - } - - // Design pages - if (filepath.endsWith('design-principles.mdx')) { - categories.add('protocol'); - } - - // Interop pages - if (filepath.endsWith('interop.mdx')) { - categories.add('interop'); - categories.add('cross-chain-messaging'); - } - } - - // Rollup content - if (filepath.includes('/rollup/')) { - categories.add('protocol'); - categories.add('rollup-node'); - if (content.toLowerCase().includes('sequencer')) { - categories.add('sequencer'); - } - } - - // Features and beta features - if (filepath.includes('/features/') || filepath.includes('/beta-features/')) { + // Root stack pages + if (filepath.match(/\/stack\/[^/]+\.mdx$/)) { + if (filepath.endsWith('features.mdx') || filepath.endsWith('beta-features.mdx')) { categories.add('protocol'); if (content.toLowerCase().includes('gas')) { categories.add('custom-gas-token'); @@ -260,135 +148,43 @@ function detectCategories(content: string, filepath: string, detectionLog: strin } } - // Interop content - if (filepath.includes('/interop/')) { - categories.add('interop'); - categories.add('cross-chain-messaging'); - if (content.toLowerCase().includes('supervisor')) { - categories.add('op-supervisor'); - } - if (content.toLowerCase().includes('bridge') || - content.toLowerCase().includes('erc20')) { - categories.add('interoperable-assets'); - } - } - - // Fault proof content - if (filepath.includes('/fault-proofs/') || content.toLowerCase().includes('fault proof')) { - categories.add('fault-proofs'); - categories.add('op-challenger'); - if (content.toLowerCase().includes('cannon')) { - categories.add('cannon'); - } - } - - // Protocol content - if (filepath.includes('/protocol/')) { + // Core protocol pages + if (['rollup.mdx', 'transactions.mdx', 'components.mdx', 'differences.mdx', 'smart-contracts.mdx'] + .some(file => filepath.endsWith(file))) { categories.add('protocol'); - if (content.toLowerCase().includes('sequencer')) { - categories.add('sequencer'); - } - if (content.toLowerCase().includes('batcher')) { - categories.add('op-batcher'); - } - if (content.toLowerCase().includes('derivation')) { - categories.add('rollup-node'); - } } - // Bridge content - if (filepath.includes('/bridge/')) { - categories.add('standard-bridge'); - categories.add('cross-chain-messaging'); - if (content.toLowerCase().includes('message passing')) { - categories.add('interoperable-message-passing'); - } + // Development pages + if (['dev-node.mdx', 'getting-started.mdx', 'public-devnets.mdx'] + .some(file => filepath.endsWith(file))) { + categories.add('devnets'); } - // Security content - if (filepath.includes('/security/')) { + // Security pages + if (filepath.endsWith('security.mdx')) { categories.add('security'); - if (content.toLowerCase().includes('pause')) { - categories.add('automated-pause'); - } } - // Node content - if (filepath.includes('/node/')) { - categories.add('rollup-node'); - categories.add('op-geth'); - if (content.toLowerCase().includes('derivation')) { - categories.add('protocol'); - } - } - - // Transaction content - if (filepath.includes('/transactions/')) { + // Research pages + if (['research.mdx', 'fact-sheet.mdx', 'design-principles.mdx'] + .some(file => filepath.endsWith(file))) { categories.add('protocol'); - if (content.toLowerCase().includes('cross') || - content.toLowerCase().includes('deposit') || - content.toLowerCase().includes('withdrawal')) { - categories.add('cross-chain-messaging'); - } } - return Array.from(categories); - } - - // App developer categories - simpler version - if (filepath.includes('/app-developers/')) { - // Bridging content - if (filepath.includes('/bridging/') || - content.toLowerCase().includes('bridge') || - content.toLowerCase().includes('token transfer')) { - categories.add('standard-bridge'); + // Interop pages + if (filepath.endsWith('interop.mdx')) { + categories.add('interop'); categories.add('cross-chain-messaging'); } - - // Tools content - if (filepath.includes('/tools/')) { - if (filepath.includes('/build/')) { - categories.add('hardhat'); - categories.add('foundry'); - } - if (filepath.includes('/connect/')) { - categories.add('ethers'); - categories.add('viem'); - } - } - - // SuperSim content - if (filepath.includes('/supersim/')) { - categories.add('supersim'); - } - - // Add devnets for tutorials - if (filepath.includes('/tutorials/')) { - categories.add('devnets'); - } - - return Array.from(categories); } - // Chain operator categories - keep existing logic - if (filepath.endsWith('chain-operators.mdx')) { - categories.add('protocol'); - categories.add('sequencer'); - categories.add('op-batcher'); - categories.add('fault-proofs'); - categories.add('op-challenger'); - return Array.from(categories); - } + return categories; +} - if (filepath.endsWith('node-operators.mdx')) { - categories.add('infrastructure'); - categories.add('rollup-node'); - categories.add('op-geth'); - categories.add('monitorism'); - return Array.from(categories); - } +function detectOperatorCategories(filepath: string, content: string): Set { + const categories = new Set(); - // Chain operator content + // Chain operator categories if (filepath.includes('/chain-operators/')) { categories.add('protocol'); @@ -413,7 +209,7 @@ function detectCategories(content: string, filepath: string, detectionLog: strin } } - // Node operator content + // Node operator categories if (filepath.includes('/node-operators/')) { categories.add('infrastructure'); @@ -433,7 +229,51 @@ function detectCategories(content: string, filepath: string, detectionLog: strin } } - // Common categories + return categories; +} + +function detectAppDeveloperCategories(filepath: string, content: string): Set { + const categories = new Set(); + + if (filepath.includes('/app-developers/')) { + // Bridging content + if (filepath.includes('/bridging/') || + content.toLowerCase().includes('bridge') || + content.toLowerCase().includes('token transfer')) { + categories.add('standard-bridge'); + categories.add('cross-chain-messaging'); + } + + // Tools content + if (filepath.includes('/tools/')) { + if (filepath.includes('/build/')) { + categories.add('hardhat'); + categories.add('foundry'); + } + if (filepath.includes('/connect/')) { + categories.add('ethers'); + categories.add('viem'); + } + } + + // SuperSim content + if (filepath.includes('/supersim/')) { + categories.add('supersim'); + } + + // Add devnets for tutorials + if (filepath.includes('/tutorials/')) { + categories.add('devnets'); + } + } + + return categories; +} + +function detectCommonCategories(content: string, filepath: string): Set { + const categories = new Set(); + + // Common infrastructure if (content.toLowerCase().includes('kubernetes') || content.toLowerCase().includes('k8s')) { categories.add('kubernetes-infrastructure'); @@ -455,6 +295,39 @@ function detectCategories(content: string, filepath: string, detectionLog: strin } } + return categories; +} + +/** + * Detects categories based on content signals + */ +function detectCategories(content: string, filepath: string, detectionLog: string[]): string[] { + const categories = new Set(); + + // Landing page categories + if (isLandingPage(content, filepath, new Set())) { + const landingCategories = getLandingPageCategories(filepath, content); + landingCategories.forEach(category => categories.add(category)); + } + + // Stack categories + if (filepath.includes('/stack/')) { + const stackCategories = detectStackCategories(filepath, content); + stackCategories.forEach(category => categories.add(category)); + } + + // Operator categories + const operatorCategories = detectOperatorCategories(filepath, content); + operatorCategories.forEach(category => categories.add(category)); + + // App developer categories + const appDevCategories = detectAppDeveloperCategories(filepath, content); + appDevCategories.forEach(category => categories.add(category)); + + // Common categories + const commonCategories = detectCommonCategories(content, filepath); + commonCategories.forEach(category => categories.add(category)); + // Limit to 5 most relevant categories const priorityOrder = [ 'protocol', diff --git a/utils/metadata-batch-cli.ts b/utils/metadata-batch-cli.ts index 45e67df10..a2112f81f 100644 --- a/utils/metadata-batch-cli.ts +++ b/utils/metadata-batch-cli.ts @@ -118,6 +118,34 @@ async function updateFrontmatter(filePath: string, dryRun: boolean = false, verb } } +async function validateFilePaths(files: string[]): Promise { + const validFiles = [] + const errors = [] + + for (const file of files) { + try { + // Check if file exists and is readable + await fs.access(file, fs.constants.R_OK) + // Check if it's actually a file (not a directory) + const stats = await fs.stat(file) + if (stats.isFile()) { + validFiles.push(file) + } else { + errors.push(`${file} is not a file`) + } + } catch (error) { + errors.push(`Cannot access ${file}: ${error.message}`) + } + } + + if (errors.length > 0) { + console.log(`${colors.yellow}Warning: Some files were skipped:${colors.reset}`) + errors.forEach(error => console.log(` ${colors.yellow}→${colors.reset} ${error}`)) + } + + return validFiles +} + async function processFiles(files: string[]): Promise { let hasErrors = false let processedCount = 0 @@ -152,10 +180,16 @@ async function main() { try { console.log('Checking metadata...') - // Get modified files from git + // Get modified files from git and validate input const gitOutput = process.env.CHANGED_FILES || '' + if (!gitOutput.trim()) { + console.log(`${colors.green}✓ No files to check${colors.reset}`) + process.exit(0) + } + const modifiedFiles = gitOutput .split('\n') + .filter(file => file.trim()) // Remove empty lines .filter(file => file.endsWith('.mdx')) .map(file => path.resolve(process.cwd(), file)) @@ -164,9 +198,17 @@ async function main() { process.exit(0) } - console.log(`Found ${modifiedFiles.length} modified files to check`) + // Validate file paths + const validFiles = await validateFilePaths(modifiedFiles) + + if (validFiles.length === 0) { + console.log(`${colors.red}✖ No valid files to check${colors.reset}`) + process.exit(1) + } + + console.log(`Found ${validFiles.length} valid files to check`) - const hasErrors = await processFiles(modifiedFiles) + const hasErrors = await processFiles(validFiles) process.exit(hasErrors ? 1 : 0) } catch (error) { console.error(`${colors.red}Error: ${error}${colors.reset}`) From 0cdacbb19e14d0db60e528a72412c6edb1bef510 Mon Sep 17 00:00:00 2001 From: cpengilly <29023967+cpengilly@users.noreply.github.com> Date: Fri, 21 Feb 2025 23:12:12 -0800 Subject: [PATCH 4/5] Update metadata-analyzer.ts --- utils/metadata-analyzer.ts | 128 ++++++++++++++++++++++++------------- 1 file changed, 84 insertions(+), 44 deletions(-) diff --git a/utils/metadata-analyzer.ts b/utils/metadata-analyzer.ts index f2a6eb873..6d95c0d69 100644 --- a/utils/metadata-analyzer.ts +++ b/utils/metadata-analyzer.ts @@ -2,6 +2,52 @@ import fs from 'fs' import path from 'path' import { MetadataResult, VALID_CATEGORIES, VALID_CONTENT_TYPES } from './types/metadata-types' +// Add interfaces for configuration +interface AnalyzerConfig { + defaultLang: string; + defaultTitle: string; + defaultDescription: string; + maxCategories: number; + logger: (message: string) => void; + priorityOrder: string[]; +} + +const DEFAULT_CONFIG: AnalyzerConfig = { + defaultLang: 'en-US', + defaultTitle: '', + defaultDescription: '', + maxCategories: 5, + logger: console.log, + priorityOrder: [ + 'protocol', + 'infrastructure', + 'sequencer', + 'op-batcher', + 'rollup-node', + 'op-geth', + 'fault-proofs', + 'op-challenger', + 'cannon', + 'l1-deployment-upgrade-tooling', + 'l2-deployment-upgrade-tooling', + 'monitorism', + 'security', + 'automated-pause', + 'kubernetes-infrastructure', + 'cross-chain-messaging', + 'standard-bridge', + 'interoperable-message-passing', + 'hardhat', + 'foundry', + 'ethers', + 'viem', + 'supersim', + 'devnets', + 'mainnet', + 'testnet' + ] +}; + /** * Returns default personas for app developer content */ @@ -301,7 +347,12 @@ function detectCommonCategories(content: string, filepath: string): Set /** * Detects categories based on content signals */ -function detectCategories(content: string, filepath: string, detectionLog: string[]): string[] { +function detectCategories( + content: string, + filepath: string, + detectionLog: string[], + config: AnalyzerConfig +): string[] { const categories = new Set(); // Landing page categories @@ -328,39 +379,10 @@ function detectCategories(content: string, filepath: string, detectionLog: strin const commonCategories = detectCommonCategories(content, filepath); commonCategories.forEach(category => categories.add(category)); - // Limit to 5 most relevant categories - const priorityOrder = [ - 'protocol', - 'infrastructure', - 'sequencer', - 'op-batcher', - 'rollup-node', - 'op-geth', - 'fault-proofs', - 'op-challenger', - 'cannon', - 'l1-deployment-upgrade-tooling', - 'l2-deployment-upgrade-tooling', - 'monitorism', - 'security', - 'automated-pause', - 'kubernetes-infrastructure', - 'cross-chain-messaging', - 'standard-bridge', - 'interoperable-message-passing', - 'hardhat', - 'foundry', - 'ethers', - 'viem', - 'supersim', - 'devnets', - 'mainnet', - 'testnet' - ]; - + // Sort by priority and limit categories const sortedCategories = Array.from(categories) - .sort((a, b) => priorityOrder.indexOf(a) - priorityOrder.indexOf(b)) - .slice(0, 5); + .sort((a, b) => config.priorityOrder.indexOf(a) - config.priorityOrder.indexOf(b)) + .slice(0, config.maxCategories); return sortedCategories; } @@ -459,13 +481,18 @@ function detectContentType( /** * Analyzes content to determine metadata */ -export function analyzeContent(content: string, filepath: string, verbose: boolean = false): MetadataResult { +export function analyzeContent( + content: string, + filepath: string, + verbose: boolean = false, + config: AnalyzerConfig = DEFAULT_CONFIG +): MetadataResult { const detectionLog: string[] = []; const warnings: string[] = []; const detectedPages = new Set(); const contentType = detectContentType(content, detectionLog, filepath, detectedPages); - const categories = detectCategories(content, filepath, detectionLog); + const categories = detectCategories(content, filepath, detectionLog, config); // Only track warnings if verbose mode is on if (contentType === 'NEEDS_REVIEW') { @@ -477,11 +504,11 @@ export function analyzeContent(content: string, filepath: string, verbose: boole // Only log if verbose mode is on if (verbose) { - console.log(`\n📄 ${filepath}`); - console.log(` Type: ${contentType}`); - console.log(` Categories: ${categories.length ? categories.join(', ') : 'none'}`); + config.logger(`\n📄 ${filepath}`); + config.logger(` Type: ${contentType}`); + config.logger(` Categories: ${categories.length ? categories.join(', ') : 'none'}`); warnings.forEach(warning => { - console.log(` ⚠️ ${warning}`); + config.logger(` ⚠️ ${warning}`); }); } @@ -489,10 +516,10 @@ export function analyzeContent(content: string, filepath: string, verbose: boole content_type: contentType as typeof VALID_CONTENT_TYPES[number], categories, detectionLog, - title: '', - lang: 'en-US', - description: '', - topic: '', + title: config.defaultTitle, + lang: config.defaultLang, + description: config.defaultDescription, + topic: generateTopic(config.defaultTitle), personas: getDefaultPersonas(filepath), is_imported_content: 'false' }; @@ -507,4 +534,17 @@ Final Summary: ⚠️ ${global.filesNeedingContentTypeReview || 0} files may need content type review (Dry run - no changes made) `); -} \ No newline at end of file +} + +// Export for testing +export const testing = { + DEFAULT_CONFIG, + detectStackCategories, + detectOperatorCategories, + detectAppDeveloperCategories, + detectCommonCategories, + detectCategories, + detectContentType, + isLandingPage, + getLandingPageCategories +}; \ No newline at end of file From b3344106e7325bcefd8f69b161ec6bbecdeba819 Mon Sep 17 00:00:00 2001 From: cpengilly <29023967+cpengilly@users.noreply.github.com> Date: Fri, 21 Feb 2025 23:24:42 -0800 Subject: [PATCH 5/5] Update metadata-analyzer.ts --- utils/metadata-analyzer.ts | 105 ++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/utils/metadata-analyzer.ts b/utils/metadata-analyzer.ts index 6d95c0d69..eb459e048 100644 --- a/utils/metadata-analyzer.ts +++ b/utils/metadata-analyzer.ts @@ -48,6 +48,21 @@ const DEFAULT_CONFIG: AnalyzerConfig = { ] }; +// Add interfaces for summary stats +interface AnalysisSummary { + totalFiles: number; + filesNeedingCategoryReview: number; + filesNeedingContentTypeReview: number; +} + +// Add error types +class MetadataAnalysisError extends Error { + constructor(message: string) { + super(message); + this.name = 'MetadataAnalysisError'; + } +} + /** * Returns default personas for app developer content */ @@ -487,51 +502,68 @@ export function analyzeContent( verbose: boolean = false, config: AnalyzerConfig = DEFAULT_CONFIG ): MetadataResult { + // Validate inputs + if (!filepath || typeof filepath !== 'string') { + throw new MetadataAnalysisError('Invalid file path provided'); + } + if (!content || typeof content !== 'string') { + throw new MetadataAnalysisError('Invalid content provided'); + } + if (typeof verbose !== 'boolean') { + throw new MetadataAnalysisError('Invalid verbose flag provided'); + } + const detectionLog: string[] = []; const warnings: string[] = []; const detectedPages = new Set(); - const contentType = detectContentType(content, detectionLog, filepath, detectedPages); - const categories = detectCategories(content, filepath, detectionLog, config); + try { + const contentType = detectContentType(content, detectionLog, filepath, detectedPages); + const categories = detectCategories(content, filepath, detectionLog, config); - // Only track warnings if verbose mode is on - if (contentType === 'NEEDS_REVIEW') { - warnings.push('Content type needs manual review'); - } - if (categories.length === 0) { - warnings.push('Categories may need manual review'); - } + // Only track warnings if verbose mode is on + if (contentType === 'NEEDS_REVIEW') { + warnings.push('Content type needs manual review'); + } + if (categories.length === 0) { + warnings.push('Categories may need manual review'); + } - // Only log if verbose mode is on - if (verbose) { - config.logger(`\n📄 ${filepath}`); - config.logger(` Type: ${contentType}`); - config.logger(` Categories: ${categories.length ? categories.join(', ') : 'none'}`); - warnings.forEach(warning => { - config.logger(` ⚠️ ${warning}`); - }); - } + // Only log if verbose mode is on + if (verbose) { + config.logger(`\n📄 ${filepath}`); + config.logger(` Type: ${contentType}`); + config.logger(` Categories: ${categories.length ? categories.join(', ') : 'none'}`); + warnings.forEach(warning => { + config.logger(` ⚠️ ${warning}`); + }); + } - return { - content_type: contentType as typeof VALID_CONTENT_TYPES[number], - categories, - detectionLog, - title: config.defaultTitle, - lang: config.defaultLang, - description: config.defaultDescription, - topic: generateTopic(config.defaultTitle), - personas: getDefaultPersonas(filepath), - is_imported_content: 'false' - }; + return { + content_type: contentType as typeof VALID_CONTENT_TYPES[number], + categories, + detectionLog, + title: config.defaultTitle, + lang: config.defaultLang, + description: config.defaultDescription, + topic: generateTopic(config.defaultTitle), + personas: getDefaultPersonas(filepath), + is_imported_content: 'false' + }; + } catch (error) { + throw new MetadataAnalysisError(`Failed to analyze ${filepath}: ${error.message}`); + } } -// Export the summary function to be called at the end of processing -export function printSummary(): void { - console.log(` +/** + * Prints a summary of the analysis results + */ +export function printSummary(summary: AnalysisSummary, config: AnalyzerConfig = DEFAULT_CONFIG): void { + config.logger(` Final Summary: -✓ Processed ${global.totalFiles} files -⚠️ ${global.filesNeedingCategoryReview || 0} files may need category review -⚠️ ${global.filesNeedingContentTypeReview || 0} files may need content type review +✓ Processed ${summary.totalFiles} files +⚠️ ${summary.filesNeedingCategoryReview} files may need category review +⚠️ ${summary.filesNeedingContentTypeReview} files may need content type review (Dry run - no changes made) `); } @@ -546,5 +578,6 @@ export const testing = { detectCategories, detectContentType, isLandingPage, - getLandingPageCategories + getLandingPageCategories, + MetadataAnalysisError }; \ No newline at end of file