@ijonis/geo-lint 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/cli.cjs +128 -19
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +128 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +128 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +128 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/index.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/adapters/mdx.ts","../src/utils/link-extractor.ts","../src/utils/slug-resolver.ts","../src/utils/display-path.ts","../src/utils/resolve-thresholds.ts","../src/rules/title-rules.ts","../src/rules/description-rules.ts","../src/rules/duplicate-rules.ts","../src/utils/heading-extractor.ts","../src/rules/heading-rules.ts","../src/utils/image-extractor.ts","../src/rules/image-rules.ts","../src/utils/word-counter.ts","../src/utils/readability.ts","../src/rules/content-rules.ts","../src/rules/og-rules.ts","../src/rules/performance-rules.ts","../src/rules/robots-rules.ts","../src/rules/slug-rules.ts","../src/rules/i18n-rules.ts","../src/rules/date-rules.ts","../src/utils/geo-analyzer.ts","../src/utils/geo-advanced-analyzer.ts","../src/rules/schema-rules.ts","../src/rules/keyword-coherence-rules.ts","../src/rules/link-rules.ts","../src/rules/external-link-rules.ts","../src/rules/orphan-rules.ts","../src/data/frequency-en.ts","../src/data/frequency-de.ts","../src/data/transition-words-en.ts","../src/data/transition-words-de.ts","../src/data/first-word-exceptions-en.ts","../src/data/first-word-exceptions-de.ts","../src/data/index.ts","../src/utils/word-complexity.ts","../src/utils/content-quality-analyzer.ts","../src/rules/geo-rules.ts","../src/rules/category-rules.ts","../src/rules/canonical-rules.ts","../src/rules/geo-eeat-rules.ts","../src/rules/geo-structure-rules.ts","../src/rules/geo-freshness-rules.ts","../src/rules/geo-rag-rules.ts","../src/utils/transition-word-analyzer.ts","../src/utils/sentence-beginnings-analyzer.ts","../src/rules/content-quality-rules.ts","../src/rules/technical-site-rules.ts","../src/rules/index.ts","../src/reporter.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\n\n/**\n * @ijonis/geo-lint CLI\n * Command-line interface for the SEO/GEO content linter\n */\n\nimport { createRequire } from 'node:module';\nimport { lint } from './index.js';\nimport { loadConfig } from './config/loader.js';\nimport { DEFAULT_CONFIG } from './config/defaults.js';\nimport { buildRules } from './rules/index.js';\nimport type { GeoLintConfig } from './config/types.js';\nimport { createLinkExtractor } from './utils/link-extractor.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\nconst args = process.argv.slice(2);\n\nfunction getFlag(name: string): string | undefined {\n const arg = args.find(a => a.startsWith(`--${name}=`));\n return arg?.split('=').slice(1).join('=');\n}\n\nfunction hasFlag(name: string): boolean {\n return args.includes(`--${name}`) || args.includes(`-${name.charAt(0)}`);\n}\n\nfunction printHelp(): void {\n console.log(`\n@ijonis/geo-lint — SEO & GEO linter for Markdown/MDX content\n\nUsage:\n geo-lint [options]\n\nOptions:\n --root=<path> Project root directory (default: cwd)\n --config=<path> Explicit config file path\n --format=pretty Human-readable colored output (default)\n --format=json Machine-readable JSON output (for AI agents)\n --rules List all registered rules with fix strategies\n -h, --help Show this help message\n -v, --version Show version\n\nExamples:\n geo-lint # Lint with default config\n geo-lint --format=json # JSON output for agent consumption\n geo-lint --rules # List all available rules\n geo-lint --root=./my-project # Lint a different project\n`);\n}\n\nfunction printVersion(): void {\n console.log(version);\n}\n\nasync function printRules(): Promise<void> {\n const projectRoot = getFlag('root') ?? process.cwd();\n\n let config: GeoLintConfig;\n try {\n config = await loadConfig(projectRoot);\n } catch {\n config = { siteUrl: 'https://example.com', ...DEFAULT_CONFIG } as GeoLintConfig;\n }\n\n const linkExtractor = createLinkExtractor(config.siteUrl);\n const rules = buildRules(config, linkExtractor);\n\n const ruleList = rules.map(r => ({\n name: r.name,\n severity: r.severity,\n category: r.category ?? 'uncategorized',\n fixStrategy: r.fixStrategy ?? null,\n }));\n\n console.log(JSON.stringify(ruleList, null, 2));\n}\n\nasync function main(): Promise<void> {\n if (hasFlag('help') || hasFlag('h')) {\n printHelp();\n process.exit(0);\n }\n\n if (hasFlag('version') || hasFlag('v')) {\n printVersion();\n process.exit(0);\n }\n\n if (hasFlag('rules')) {\n await printRules();\n process.exit(0);\n }\n\n const format = (getFlag('format') ?? 'pretty') as 'pretty' | 'json';\n const projectRoot = getFlag('root');\n\n const exitCode = await lint({ projectRoot, format });\n process.exit(exitCode);\n}\n\nmain().catch(error => {\n console.error('geo-lint failed:', error.message);\n process.exit(1);\n});\n","/**\n * @ijonis/geo-lint\n * SEO and GEO (Generative Engine Optimization) linter for Markdown/MDX content\n *\n * The first open-source linter that checks your content for AI search visibility.\n */\n\nimport { resolve } from 'node:path';\nimport { loadConfig, mergeWithDefaults, defineConfig } from './config/loader.js';\nimport type { GeoLintConfig, GeoLintUserConfig } from './config/types.js';\nimport { loadContentItems } from './adapters/mdx.js';\nimport type { ContentAdapter } from './adapters/types.js';\nimport { createLinkExtractor } from './utils/link-extractor.js';\nimport { buildSlugRegistry, buildImageRegistry } from './utils/slug-resolver.js';\nimport { buildRules, runAllRules } from './rules/index.js';\nimport { formatResults, formatResultsJson, printProgress } from './reporter.js';\nimport type { LintResult, Rule, ContentItem, RuleContext, GlobalRule } from './types.js';\n\n/** Options for the lint() function */\nexport interface LintOptions {\n /** Project root directory (defaults to cwd) */\n projectRoot?: string;\n /** Explicit config (skips file loading) */\n config?: GeoLintUserConfig;\n /** Custom content adapter (skips default MDX scanning) */\n adapter?: ContentAdapter;\n /** Global rules to run after per-item rules */\n globalRules?: GlobalRule[];\n /** Output format: 'pretty' for terminal, 'json' for machine consumption */\n format?: 'pretty' | 'json';\n}\n\n/**\n * Run the complete GEO lint process.\n * Returns exit code: 0 for success (no errors), 1 for errors found.\n */\nexport async function lint(options: LintOptions = {}): Promise<number> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n\n // Load config\n const config: GeoLintConfig = options.config\n ? mergeWithDefaults(options.config)\n : await loadConfig(projectRoot);\n\n const isPretty = (options.format ?? 'pretty') === 'pretty';\n\n if (isPretty) printProgress('Loading content...');\n\n // Load content items\n const contentItems = options.adapter\n ? await options.adapter.loadItems(projectRoot)\n : loadContentItems(config.contentPaths, projectRoot);\n\n // Separate excluded items (still included in context for link validation)\n const excludeSlugs = new Set(config.excludeSlugs);\n const excludeCategories = new Set(config.excludeCategories);\n\n const isExcluded = (item: ContentItem): boolean => {\n if (item.category && excludeCategories.has(item.category)) return true;\n return excludeSlugs.has(item.slug);\n };\n\n const excludedItems = contentItems.filter(isExcluded);\n const lintableItems = contentItems.filter(item => !isExcluded(item));\n\n if (isPretty) {\n printProgress(`Loaded ${contentItems.length} content files (${excludedItems.length} excluded)`);\n printProgress('Building validation context...');\n }\n\n // Build validation context with ALL items (excluded are still valid link targets)\n const linkExtractor = createLinkExtractor(config.siteUrl);\n const context: RuleContext = {\n allContent: contentItems,\n validSlugs: buildSlugRegistry(contentItems, config.staticRoutes, config.contentPaths),\n validImages: buildImageRegistry(config.imageDirectories),\n thresholds: config.thresholds,\n geoEnabledContentTypes: config.geo.enabledContentTypes ?? ['blog'],\n defaultLocale: config.i18n.defaultLocale,\n };\n\n if (isPretty) {\n printProgress(`Found ${context.validSlugs.size} valid URLs, ${context.validImages.size} images`);\n printProgress('Running validation rules...');\n }\n\n // Build and run rules\n const rules = buildRules(config, linkExtractor);\n const results: LintResult[] = runAllRules(lintableItems, context, rules);\n\n // Run global rules (user-provided, e.g., service registry checks)\n if (options.globalRules) {\n for (const globalRule of options.globalRules) {\n try {\n results.push(...globalRule.run());\n } catch (error) {\n if (isPretty) console.error(`Global rule ${globalRule.name} failed:`, error);\n }\n }\n }\n\n // Output results\n if (options.format === 'json') {\n console.log(formatResultsJson(results));\n } else {\n formatResults(results, lintableItems.length, excludedItems.length);\n }\n\n return 0;\n}\n\n/**\n * Run the linter and return raw results (no console output).\n * Useful for programmatic integration.\n */\nexport async function lintQuiet(options: LintOptions = {}): Promise<LintResult[]> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n\n const config: GeoLintConfig = options.config\n ? mergeWithDefaults(options.config)\n : await loadConfig(projectRoot);\n\n const contentItems = options.adapter\n ? await options.adapter.loadItems(projectRoot)\n : loadContentItems(config.contentPaths, projectRoot);\n\n const excludeSlugs = new Set(config.excludeSlugs);\n const excludeCategories = new Set(config.excludeCategories);\n\n const isExcluded = (item: ContentItem): boolean => {\n if (item.category && excludeCategories.has(item.category)) return true;\n return excludeSlugs.has(item.slug);\n };\n\n const lintableItems = contentItems.filter(item => !isExcluded(item));\n const linkExtractor = createLinkExtractor(config.siteUrl);\n\n const context: RuleContext = {\n allContent: contentItems,\n validSlugs: buildSlugRegistry(contentItems, config.staticRoutes, config.contentPaths),\n validImages: buildImageRegistry(config.imageDirectories),\n thresholds: config.thresholds,\n geoEnabledContentTypes: config.geo.enabledContentTypes ?? ['blog'],\n defaultLocale: config.i18n.defaultLocale,\n };\n\n const rules = buildRules(config, linkExtractor);\n return runAllRules(lintableItems, context, rules);\n}\n\n// Re-export public API\nexport { defineConfig } from './config/loader.js';\nexport type {\n GeoLintUserConfig,\n GeoLintConfig,\n GeoConfig,\n ContentPathConfig,\n ThresholdConfig,\n TechnicalConfig,\n I18nConfig,\n} from './config/types.js';\nexport type {\n LintResult,\n Rule,\n GlobalRule,\n ContentItem,\n RuleContext,\n ContentType,\n Severity,\n Heading,\n ExtractedLink,\n ExtractedImage,\n} from './types.js';\nexport type { ContentAdapter } from './adapters/types.js';\nexport { createAdapter } from './adapters/types.js';\nexport { loadContentItems } from './adapters/mdx.js';\n","/**\n * @ijonis/geo-lint Configuration Loader\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { GeoLintUserConfig, GeoLintConfig } from './types.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\n\nconst CONFIG_FILENAMES = [\n 'geo-lint.config.ts',\n 'geo-lint.config.mts',\n 'geo-lint.config.mjs',\n 'geo-lint.config.js',\n];\n\n/**\n * Helper for TypeScript-aware config files. Provides autocomplete in user configs.\n */\nexport function defineConfig(config: GeoLintUserConfig): GeoLintUserConfig {\n return config;\n}\n\n/**\n * Try to load a config file from the project root using jiti for TS support\n */\nasync function tryLoadConfigFile(projectRoot: string): Promise<GeoLintUserConfig | null> {\n for (const filename of CONFIG_FILENAMES) {\n const configPath = join(projectRoot, filename);\n if (!existsSync(configPath)) continue;\n\n try {\n // Use jiti for TypeScript config loading (works without tsx/ts-node)\n const { createJiti } = await import('jiti');\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(configPath) as Record<string, unknown>;\n const config = (mod.default ?? mod) as GeoLintUserConfig;\n\n if (config && typeof config === 'object' && 'siteUrl' in config) {\n return config;\n }\n } catch {\n // Try next file\n }\n }\n return null;\n}\n\n/**\n * Try to load config from package.json geoLint key\n */\nfunction tryLoadPackageJsonConfig(projectRoot: string): GeoLintUserConfig | null {\n try {\n const pkgPath = join(projectRoot, 'package.json');\n if (!existsSync(pkgPath)) return null;\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const config = pkg.geoLint;\n if (config && typeof config === 'object' && 'siteUrl' in config) {\n return config as GeoLintUserConfig;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Merge user config with defaults\n */\nexport function mergeWithDefaults(user: GeoLintUserConfig): GeoLintConfig {\n return {\n siteUrl: user.siteUrl,\n contentPaths: user.contentPaths ?? DEFAULT_CONFIG.contentPaths,\n staticRoutes: user.staticRoutes ?? DEFAULT_CONFIG.staticRoutes,\n imageDirectories: user.imageDirectories ?? DEFAULT_CONFIG.imageDirectories,\n categories: user.categories ?? DEFAULT_CONFIG.categories,\n excludeSlugs: user.excludeSlugs ?? DEFAULT_CONFIG.excludeSlugs,\n excludeCategories: user.excludeCategories ?? DEFAULT_CONFIG.excludeCategories,\n geo: {\n brandName: user.geo?.brandName ?? DEFAULT_CONFIG.geo.brandName,\n brandCity: user.geo?.brandCity ?? DEFAULT_CONFIG.geo.brandCity,\n keywordsPath: user.geo?.keywordsPath ?? DEFAULT_CONFIG.geo.keywordsPath,\n enabledContentTypes: user.geo?.enabledContentTypes ?? DEFAULT_CONFIG.geo.enabledContentTypes,\n fillerPhrases: user.geo?.fillerPhrases ?? DEFAULT_CONFIG.geo.fillerPhrases,\n extractionTriggers: user.geo?.extractionTriggers ?? DEFAULT_CONFIG.geo.extractionTriggers,\n acronymAllowlist: user.geo?.acronymAllowlist ?? DEFAULT_CONFIG.geo.acronymAllowlist,\n vagueHeadings: user.geo?.vagueHeadings ?? DEFAULT_CONFIG.geo.vagueHeadings,\n genericAuthorNames: user.geo?.genericAuthorNames ?? DEFAULT_CONFIG.geo.genericAuthorNames,\n allowedHtmlTags: user.geo?.allowedHtmlTags ?? DEFAULT_CONFIG.geo.allowedHtmlTags,\n organizationSameAs: user.geo?.organizationSameAs ?? DEFAULT_CONFIG.geo.organizationSameAs,\n servicePagePatterns: user.geo?.servicePagePatterns ?? DEFAULT_CONFIG.geo.servicePagePatterns,\n },\n i18n: {\n locales: user.i18n?.locales ?? DEFAULT_CONFIG.i18n.locales,\n defaultLocale: user.i18n?.defaultLocale ?? DEFAULT_CONFIG.i18n.defaultLocale,\n },\n technical: {\n feedUrls: user.technical?.feedUrls ?? DEFAULT_CONFIG.technical.feedUrls,\n llmsTxtUrl: user.technical?.llmsTxtUrl ?? DEFAULT_CONFIG.technical.llmsTxtUrl,\n },\n rules: { ...DEFAULT_CONFIG.rules, ...(user.rules ?? {}) },\n thresholds: {\n title: { ...DEFAULT_CONFIG.thresholds.title, ...(user.thresholds?.title ?? {}) },\n description: { ...DEFAULT_CONFIG.thresholds.description, ...(user.thresholds?.description ?? {}) },\n slug: { ...DEFAULT_CONFIG.thresholds.slug, ...(user.thresholds?.slug ?? {}) },\n content: { ...DEFAULT_CONFIG.thresholds.content, ...(user.thresholds?.content ?? {}) },\n byContentType: user.thresholds?.byContentType,\n },\n };\n}\n\n/**\n * Load configuration from the project root.\n * Searches for geo-lint.config.{ts,mjs,js} or package.json#geoLint\n */\nexport async function loadConfig(projectRoot?: string): Promise<GeoLintConfig> {\n const root = resolve(projectRoot ?? process.cwd());\n\n const userConfig = await tryLoadConfigFile(root) ?? tryLoadPackageJsonConfig(root);\n\n if (!userConfig) {\n throw new Error(\n 'geo-lint: No configuration found.\\n' +\n 'Create a geo-lint.config.ts in your project root with at least:\\n\\n' +\n ' import { defineConfig } from \"@ijonis/geo-lint\";\\n' +\n ' export default defineConfig({ siteUrl: \"https://example.com\" });\\n\\n' +\n 'See https://github.com/ijonis/geo-lint#configuration'\n );\n }\n\n return mergeWithDefaults(userConfig);\n}\n","/**\n * @ijonis/geo-lint Default Configuration\n */\n\nimport type { GeoLintConfig } from './types.js';\n\n/** Default configuration values (no project-specific data) */\nexport const DEFAULT_CONFIG: Omit<GeoLintConfig, 'siteUrl'> = {\n contentPaths: [\n { dir: 'content/blog', type: 'blog', urlPrefix: '/blog/' },\n { dir: 'content/pages', type: 'page', urlPrefix: '/' },\n { dir: 'content/projects', type: 'project', urlPrefix: '/projects/' },\n ],\n staticRoutes: [],\n imageDirectories: ['public/images'],\n categories: [],\n excludeSlugs: [],\n excludeCategories: ['legal'],\n geo: {\n brandName: '',\n brandCity: '',\n keywordsPath: '',\n fillerPhrases: [\n 'in this article', 'in this post', 'in this guide',\n 'in diesem artikel', 'in diesem beitrag',\n 'welcome to', 'willkommen zu',\n 'today we will', 'heute werden wir',\n \"let me tell you\", 'lass mich dir erzählen',\n \"in today's world\", 'in der heutigen welt',\n \"it's no secret\", 'es ist kein geheimnis',\n 'in the ever-changing', 'in der sich ständig verändernden',\n ],\n extractionTriggers: [\n 'key takeaway', 'in summary', 'the bottom line',\n 'tl;dr', 'to summarize', 'in short', 'put simply',\n 'the short answer', \"here's what you need to know\",\n 'zusammenfassend', 'fazit', 'das wichtigste',\n 'kurz gesagt', 'anders gesagt',\n ],\n acronymAllowlist: [\n 'HTML', 'CSS', 'API', 'URL', 'SDK', 'CLI', 'UI', 'UX',\n 'JSON', 'XML', 'HTTP', 'HTTPS', 'SQL', 'SEO', 'GEO', 'AEO',\n 'AI', 'ML', 'LLM', 'FAQ', 'CMS', 'CRM', 'SaaS', 'B2B', 'B2C',\n 'ROI', 'KPI', 'PDF', 'CEO', 'CTO', 'VP', 'HR', 'PR', 'IT',\n 'US', 'EU', 'UK', 'DE', 'MDX', 'JSX', 'TSX', 'RSS', 'DNS',\n ],\n vagueHeadings: [\n 'introduction', 'overview', 'background', 'details',\n 'summary', 'conclusion', 'more', 'other', 'misc',\n 'einleitung', 'überblick', 'hintergrund', 'details',\n 'zusammenfassung', 'fazit', 'weiteres', 'sonstiges',\n ],\n genericAuthorNames: [\n 'admin', 'administrator', 'team', 'editor', 'author',\n 'webmaster', 'staff', 'contributor',\n 'redaktion', 'redakteur', 'herausgeber',\n ],\n allowedHtmlTags: [\n 'Callout', 'CalloutBox', 'Note', 'Warning', 'Tip',\n 'CodeBlock', 'Image', 'Video', 'Embed', 'Tabs', 'Tab',\n ],\n enabledContentTypes: ['blog'],\n organizationSameAs: [],\n servicePagePatterns: [],\n },\n technical: {\n feedUrls: [],\n llmsTxtUrl: '',\n },\n i18n: {\n locales: ['de', 'en'],\n defaultLocale: 'de',\n },\n rules: {},\n thresholds: {\n title: { minLength: 30, maxLength: 60, warnLength: 55 },\n description: { minLength: 70, maxLength: 160, warnLength: 150 },\n slug: { maxLength: 75 },\n content: { minWordCount: 300, minReadabilityScore: 30 },\n },\n};\n","/**\n * @ijonis/geo-lint MDX Content Adapter\n * Scans directories for MDX/Markdown files and parses them with gray-matter\n */\n\nimport { readdirSync, statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport type { ContentItem, ContentType } from '../types.js';\nimport type { ContentPathConfig } from '../config/types.js';\n\n/**\n * Derive permalink from slug, locale, and URL prefix config\n */\nfunction derivePermalink(\n slug: string,\n locale: string | undefined,\n pathConfig: ContentPathConfig,\n): string {\n const prefix = pathConfig.urlPrefix ?? '/';\n\n // Pages use root-level URLs\n if (pathConfig.type === 'page') {\n return `/${slug}`.replace(/\\/\\/+/g, '/');\n }\n\n // Non-default locale gets locale prefix\n const defaultLocale = pathConfig.defaultLocale ?? 'de';\n if (locale && locale !== defaultLocale) {\n return `/${locale}${prefix}${slug}`.replace(/\\/\\/+/g, '/');\n }\n\n return `${prefix}${slug}`.replace(/\\/\\/+/g, '/');\n}\n\n/**\n * Recursively find all MDX/Markdown files in a directory\n */\nfunction findContentFiles(dir: string): string[] {\n const files: string[] = [];\n if (!existsSync(dir)) return files;\n\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n try {\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n files.push(...findContentFiles(fullPath));\n } else if (entry.endsWith('.mdx') || entry.endsWith('.md')) {\n files.push(fullPath);\n }\n } catch {\n // Skip files that can't be read\n }\n }\n return files;\n}\n\n/**\n * Parse a single content file into a ContentItem\n */\nfunction parseContentFile(\n filePath: string,\n pathConfig: ContentPathConfig,\n): ContentItem | null {\n try {\n const { data: fm, content: body, orig } = matter.read(filePath);\n\n const slug = fm.slug as string | undefined;\n if (!slug) return null;\n\n // Skip drafts\n if (fm.draft === true) return null;\n\n const locale = fm.locale as string | undefined;\n const permalink =\n (fm.permalink as string | undefined) ??\n derivePermalink(slug, locale, pathConfig);\n\n return {\n title: (fm.title as string) ?? '',\n slug,\n description: (fm.description as string) ?? '',\n permalink,\n image: (fm.image as string | undefined) ?? (fm.thumbnail as string | undefined),\n imageAlt: fm.imageAlt as string | undefined,\n categories: fm.categories as string[] | undefined,\n date: fm.date ? String(fm.date) : undefined,\n category: fm.category as string | undefined,\n locale,\n translationKey: fm.translationKey as string | undefined,\n updatedAt: fm.updatedAt ? String(fm.updatedAt) : undefined,\n noindex: fm.noindex as boolean | undefined,\n draft: fm.draft as boolean | undefined,\n author: fm.author as string | undefined,\n contentType: pathConfig.type as ContentType,\n filePath,\n rawContent: orig?.toString() ?? '',\n body,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Load all content items from configured content paths.\n * Uses gray-matter for robust YAML frontmatter parsing.\n */\nexport function loadContentItems(\n contentPaths: ContentPathConfig[],\n projectRoot: string,\n): ContentItem[] {\n const items: ContentItem[] = [];\n\n for (const pathConfig of contentPaths) {\n const fullDir = join(projectRoot, pathConfig.dir);\n const files = findContentFiles(fullDir);\n\n for (const filePath of files) {\n const item = parseContentFile(filePath, pathConfig);\n if (item) items.push(item);\n }\n }\n\n return items;\n}\n","/**\n * Link Extractor Utility\n * Extracts and classifies links from MDX content\n */\n\nimport type { ExtractedLink } from '../types.js';\n\n/** Link extraction utilities bound to a specific site URL */\nexport interface LinkExtractor {\n isInternalUrl: (url: string) => boolean;\n normalizeInternalUrl: (url: string) => string;\n isAbsoluteInternalLink: (url: string) => boolean;\n extractLinks: (mdxBody: string) => ExtractedLink[];\n getInternalLinks: (links: ExtractedLink[]) => ExtractedLink[];\n}\n\n/**\n * Create a link extractor bound to a specific site URL.\n * All internal URL detection derives from the provided siteUrl.\n */\nexport function createLinkExtractor(siteUrl: string): LinkExtractor {\n const { hostname } = new URL(siteUrl);\n const escapedDomain = hostname.replace(/\\./g, '\\\\.');\n\n const internalPatterns = [\n new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}(\\\\/|$)`, 'i'),\n new RegExp(`^\\\\/\\\\/${escapedDomain}(\\\\/|$)`, 'i'),\n /^\\/(?!\\/)/, // Relative paths starting with single /\n ];\n\n function isInternalUrl(url: string): boolean {\n return internalPatterns.some(pattern => pattern.test(url));\n }\n\n function normalizeInternalUrl(url: string): string {\n let normalized = url;\n normalized = normalized.replace(new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}`, 'i'), '');\n normalized = normalized.replace(new RegExp(`^\\\\/\\\\/${escapedDomain}`, 'i'), '');\n if (!normalized.startsWith('/')) {\n normalized = '/' + normalized;\n }\n normalized = normalized.split('?')[0].split('#')[0];\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n }\n\n function isAbsoluteInternalLink(url: string): boolean {\n return new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}`, 'i').test(url);\n }\n\n function isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n return inCodeBlock;\n }\n\n function extractLinks(mdxBody: string): ExtractedLink[] {\n const links: ExtractedLink[] = [];\n const lines = mdxBody.split('\\n');\n const markdownLinkRegex = /(?<!!)\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n const hrefRegex = /href=[\"']([^\"']+)[\"']/g;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (isInCodeBlock(lines, i)) continue;\n\n let match;\n while ((match = markdownLinkRegex.exec(line)) !== null) {\n const [, text, url] = match;\n if (url.startsWith('mailto:') || url.startsWith('tel:') || url === '#') continue;\n const internal = isInternalUrl(url);\n links.push({\n text: text.trim(),\n url: internal ? normalizeInternalUrl(url) : url,\n originalUrl: url,\n line: i + 1,\n isInternal: internal,\n });\n }\n markdownLinkRegex.lastIndex = 0;\n\n while ((match = hrefRegex.exec(line)) !== null) {\n const [, url] = match;\n if (url.startsWith('mailto:') || url.startsWith('tel:') || url === '#') continue;\n const normalized = isInternalUrl(url) ? normalizeInternalUrl(url) : url;\n const alreadyCaptured = links.some(\n l => l.line === i + 1 && (l.url === normalized || l.originalUrl === url)\n );\n if (!alreadyCaptured) {\n const internal = isInternalUrl(url);\n links.push({\n text: '',\n url: internal ? normalizeInternalUrl(url) : url,\n originalUrl: url,\n line: i + 1,\n isInternal: internal,\n });\n }\n }\n hrefRegex.lastIndex = 0;\n }\n return links;\n }\n\n function getInternalLinks(links: ExtractedLink[]): ExtractedLink[] {\n return links.filter(l => l.isInternal);\n }\n\n return { isInternalUrl, normalizeInternalUrl, isAbsoluteInternalLink, extractLinks, getInternalLinks };\n}\n","/**\n * Slug Resolver Utility\n * Builds a registry of valid internal URLs for link validation\n */\n\nimport { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ContentItem } from '../types.js';\nimport type { ContentPathConfig } from '../config/types.js';\n\n/**\n * Extract frontmatter slug and locale from a raw MDX file\n * Returns null if the file has no valid frontmatter\n */\nfunction extractSlugFromFile(\n filePath: string,\n defaultLocale: string = 'de',\n): { slug: string; locale: string } | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n if (!content.startsWith('---')) return null;\n\n const endIndex = content.indexOf('---', 3);\n if (endIndex === -1) return null;\n\n const frontmatter = content.slice(3, endIndex);\n\n const slugMatch = frontmatter.match(/^slug:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n if (!slugMatch) return null;\n\n const localeMatch = frontmatter.match(/^locale:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n const draftMatch = frontmatter.match(/^draft:\\s*true\\s*$/m);\n\n if (draftMatch) return null;\n\n return {\n slug: slugMatch[1].trim(),\n locale: localeMatch ? localeMatch[1].trim() : defaultLocale,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Find all files with a given extension in a directory (recursive)\n */\nfunction findFilesInDir(dir: string, ext: string): string[] {\n const results: string[] = [];\n try {\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n results.push(...findFilesInDir(fullPath, ext));\n } else if (entry.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n return results;\n}\n\n/**\n * Scan raw MDX files to find permalinks not covered by content adapter output.\n * Handles cases where the content adapter fails to process certain files.\n *\n * @param knownSlugs - Set of already-known permalink slugs\n * @param contentPaths - Content directory configurations to scan\n */\nexport function scanRawContentPermalinks(\n knownSlugs: Set<string>,\n contentPaths: ContentPathConfig[],\n): string[] {\n const projectRoot = process.cwd();\n const additionalPermalinks: string[] = [];\n\n for (const pathConfig of contentPaths) {\n const contentDir = join(projectRoot, pathConfig.dir);\n if (!existsSync(contentDir)) continue;\n\n const urlPrefix = pathConfig.urlPrefix ?? '/';\n\n const defaultLocale = pathConfig.defaultLocale ?? 'de';\n\n for (const file of findFilesInDir(contentDir, '.mdx')) {\n const meta = extractSlugFromFile(file, defaultLocale);\n if (!meta) continue;\n\n // Build permalink based on locale and URL prefix\n let permalink: string;\n\n if (meta.locale !== defaultLocale) {\n // Non-default locale: prefix with locale\n permalink = `/${meta.locale}${urlPrefix}${meta.slug}`.replace(/\\/+/g, '/');\n } else {\n permalink = `${urlPrefix}${meta.slug}`.replace(/\\/+/g, '/');\n }\n\n // Ensure leading slash\n if (!permalink.startsWith('/')) {\n permalink = '/' + permalink;\n }\n\n // Remove trailing slash (except root)\n if (permalink.length > 1 && permalink.endsWith('/')) {\n permalink = permalink.slice(0, -1);\n }\n\n if (!knownSlugs.has(permalink)) {\n additionalPermalinks.push(permalink);\n }\n }\n }\n\n return additionalPermalinks;\n}\n\n/**\n * Build a set of all valid internal URL paths.\n * Combines content permalinks, static routes, and raw MDX file scan.\n *\n * @param allContent - Content items from the content adapter\n * @param staticRoutes - Array of static route paths (e.g. ['/about', '/contact'])\n * @param contentPaths - Content directory configurations for raw MDX fallback scan\n */\nexport function buildSlugRegistry(\n allContent: ContentItem[],\n staticRoutes: string[],\n contentPaths: ContentPathConfig[],\n): Set<string> {\n const slugs = new Set<string>();\n\n // Add static routes\n for (const route of staticRoutes) {\n slugs.add(route);\n }\n\n // Add content permalinks from adapter output\n for (const item of allContent) {\n slugs.add(item.permalink);\n\n // Also add without trailing slash if present\n if (item.permalink.endsWith('/') && item.permalink.length > 1) {\n slugs.add(item.permalink.slice(0, -1));\n }\n }\n\n // Scan raw MDX files for any permalinks the adapter missed\n const additional = scanRawContentPermalinks(slugs, contentPaths);\n for (const permalink of additional) {\n slugs.add(permalink);\n }\n\n return slugs;\n}\n\n/**\n * Check if a normalized internal URL is valid\n */\nexport function isValidInternalLink(url: string, validSlugs: Set<string>): boolean {\n // Direct match\n if (validSlugs.has(url)) {\n return true;\n }\n\n // Try with trailing slash\n if (validSlugs.has(url + '/')) {\n return true;\n }\n\n // Try without trailing slash\n if (url.endsWith('/') && validSlugs.has(url.slice(0, -1))) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Recursively scan directory for files\n */\nfunction scanDirectory(dir: string): string[] {\n const files: string[] = [];\n\n try {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n files.push(...scanDirectory(fullPath));\n } else {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Build a set of all valid image paths.\n * Scans the provided image directories.\n *\n * @param imageDirectories - Array of image directory paths relative to project root\n * (e.g. ['public/images'])\n */\nexport function buildImageRegistry(imageDirectories: string[]): Set<string> {\n const images = new Set<string>();\n const projectRoot = process.cwd();\n\n for (const imageDir of imageDirectories) {\n const fullDir = join(projectRoot, imageDir);\n\n if (!existsSync(fullDir)) {\n continue;\n }\n\n const files = scanDirectory(fullDir);\n\n for (const file of files) {\n // Get path relative to public directory\n const relativePath = file.replace(join(projectRoot, 'public'), '');\n // Normalize to forward slashes and ensure leading slash\n const normalizedPath = relativePath.replace(/\\\\/g, '/');\n images.add(normalizedPath.startsWith('/') ? normalizedPath : '/' + normalizedPath);\n }\n }\n\n return images;\n}\n\n/**\n * Check if an image path exists\n */\nexport function isValidImagePath(imagePath: string, validImages: Set<string>): boolean {\n // Normalize the path\n let normalized = imagePath;\n\n // Handle paths without leading slash\n if (!normalized.startsWith('/')) {\n normalized = '/' + normalized;\n }\n\n // Direct match\n if (validImages.has(normalized)) {\n return true;\n }\n\n // Try URL-decoded version\n try {\n const decoded = decodeURIComponent(normalized);\n if (validImages.has(decoded)) {\n return true;\n }\n } catch {\n // Invalid URL encoding, ignore\n }\n\n return false;\n}\n","import type { ContentItem } from '../types.js';\n\n/** Get the relative file path for display in lint results */\nexport function getDisplayPath(item: ContentItem): string {\n return `${item.contentType}/${item.slug}`;\n}\n","/**\n * Per-content-type threshold resolution\n * Merges base thresholds with optional per-type overrides\n */\n\nimport type { ThresholdConfig } from '../config/types.js';\nimport type { ContentType } from '../types.js';\n\n/** Resolved thresholds for a specific content type (no byContentType nesting) */\nexport interface ResolvedThresholds {\n title: { minLength: number; maxLength: number; warnLength: number };\n description: { minLength: number; maxLength: number; warnLength: number };\n slug: { maxLength: number };\n content: { minWordCount: number; minReadabilityScore: number };\n}\n\n/**\n * Resolve thresholds for a specific content type.\n * Merges per-type overrides on top of base values.\n *\n * @example\n * resolveThresholds(config.thresholds, 'page')\n * // Returns base thresholds with any page-specific overrides applied\n */\nexport function resolveThresholds(\n thresholds: ThresholdConfig,\n contentType: ContentType,\n): ResolvedThresholds {\n const override = thresholds.byContentType?.[contentType];\n if (!override) {\n return {\n title: thresholds.title,\n description: thresholds.description,\n slug: thresholds.slug,\n content: thresholds.content,\n };\n }\n\n return {\n title: { ...thresholds.title, ...override.title },\n description: { ...thresholds.description, ...override.description },\n slug: { ...thresholds.slug, ...override.slug },\n content: { ...thresholds.content, ...override.content },\n };\n}\n","/**\n * Title Validation Rules\n * Validates title presence and length\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default title length thresholds (used when context has no thresholds) */\nconst TITLE_DEFAULTS = { minLength: 30, maxLength: 60, warnLength: 55 };\n\n/**\n * Rule: Title must be present\n */\nexport const titleMissing: Rule = {\n name: 'title-missing',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add a title field to the frontmatter',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || item.title.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-missing',\n severity: 'error',\n message: 'Missing title',\n suggestion: 'Add a title field to the frontmatter',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title should not be too short\n */\nexport const titleTooShort: Rule = {\n name: 'title-too-short',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Expand the title to meet minimum length',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > 0 && length < t.minLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-too-short',\n severity: 'warning',\n message: `Title is too short (${length}/${t.minLength} chars minimum)`,\n suggestion: `Expand the title to at least ${t.minLength} characters for better SEO`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title must not exceed maximum length\n */\nexport const titleTooLong: Rule = {\n name: 'title-too-long',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Shorten the title to avoid truncation in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > t.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-too-long',\n severity: 'error',\n message: `Title is too long (${length}/${t.maxLength} chars)`,\n suggestion: `Shorten the title to ${t.maxLength} characters or less to avoid truncation in search results`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Warn when title is approaching maximum length\n */\nexport const titleApproachingLimit: Rule = {\n name: 'title-approaching-limit',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Consider shortening to leave room for site name suffix',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > t.warnLength && length <= t.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-approaching-limit',\n severity: 'warning',\n message: `Title is approaching maximum length (${length}/${t.maxLength} chars)`,\n suggestion: 'Consider shortening to leave room for site name suffix in search results',\n }];\n }\n return [];\n },\n};\n\n/**\n * All title rules\n */\nexport const titleRules: Rule[] = [\n titleMissing,\n titleTooShort,\n titleTooLong,\n titleApproachingLimit,\n];\n","/**\n * Description Validation Rules\n * Validates meta description presence and length\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default description length thresholds (used when context has no thresholds) */\nconst DESC_DEFAULTS = { minLength: 70, maxLength: 160, warnLength: 150 };\n\n/**\n * Rule: Description must be present\n */\nexport const descriptionMissing: Rule = {\n name: 'description-missing',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add a description field to the frontmatter (max 160 chars)',\n run: (item: ContentItem): LintResult[] => {\n if (!item.description || item.description.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-missing',\n severity: 'error',\n message: 'Missing description',\n suggestion: 'Add a description field to the frontmatter (max 160 chars)',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Description must not exceed maximum length\n */\nexport const descriptionTooLong: Rule = {\n name: 'description-too-long',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Shorten the description to avoid truncation in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length > d.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-too-long',\n severity: 'error',\n message: `Description is too long (${length}/${d.maxLength} chars)`,\n suggestion: `Shorten to ${d.maxLength} characters to avoid truncation in search results`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Warn when description is approaching maximum length\n */\nexport const descriptionApproachingLimit: Rule = {\n name: 'description-approaching-limit',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Consider shortening to ensure full display in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length > d.warnLength && length <= d.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-approaching-limit',\n severity: 'warning',\n message: `Description is approaching maximum length (${length}/${d.maxLength} chars)`,\n suggestion: 'Consider shortening to ensure full display in search results',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Description should meet minimum length for effective SEO\n */\nexport const descriptionTooShort: Rule = {\n name: 'description-too-short',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Expand the description for better search result snippets',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description || item.description.trim().length === 0) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length < d.minLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-too-short',\n severity: 'warning',\n message: `Description is too short (${length}/${d.minLength} chars minimum)`,\n suggestion: `Expand the description to at least ${d.minLength} characters for better search result snippets`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All description rules\n */\nexport const descriptionRules: Rule[] = [\n descriptionMissing,\n descriptionTooLong,\n descriptionApproachingLimit,\n descriptionTooShort,\n];\n","/**\n * Duplicate Detection Rules\n * Validates that titles and descriptions are unique across all content\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Build a map of value -> list of files using that value\n */\nfunction buildDuplicateMap(\n items: ContentItem[],\n getValue: (item: ContentItem) => string | undefined\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n\n for (const item of items) {\n const value = getValue(item);\n if (!value || value.trim().length === 0) continue;\n\n // Normalize for comparison (lowercase, trim)\n const normalized = value.toLowerCase().trim();\n const files = map.get(normalized) || [];\n files.push(getDisplayPath(item));\n map.set(normalized, files);\n }\n\n return map;\n}\n\n/**\n * Rule: Titles must be unique across all content\n */\nexport const duplicateTitle: Rule = {\n name: 'duplicate-title',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Use a unique title that differentiates this content from others',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const titleMap = buildDuplicateMap(context.allContent, c => c.title);\n const normalizedTitle = item.title?.toLowerCase().trim();\n\n if (!normalizedTitle) return [];\n\n const filesWithSameTitle = titleMap.get(normalizedTitle);\n if (!filesWithSameTitle || filesWithSameTitle.length <= 1) return [];\n\n // Filter out the current file\n const otherFiles = filesWithSameTitle.filter(f => f !== getDisplayPath(item));\n if (otherFiles.length === 0) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'duplicate-title',\n severity: 'error',\n message: `Duplicate title found`,\n suggestion: `Also used by: ${otherFiles.join(', ')}`,\n }];\n },\n};\n\n/**\n * Rule: Descriptions must be unique across all content\n */\nexport const duplicateDescription: Rule = {\n name: 'duplicate-description',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Write a unique description that differentiates this content',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const descMap = buildDuplicateMap(context.allContent, c => c.description);\n const normalizedDesc = item.description?.toLowerCase().trim();\n\n if (!normalizedDesc) return [];\n\n const filesWithSameDesc = descMap.get(normalizedDesc);\n if (!filesWithSameDesc || filesWithSameDesc.length <= 1) return [];\n\n // Filter out the current file\n const otherFiles = filesWithSameDesc.filter(f => f !== getDisplayPath(item));\n if (otherFiles.length === 0) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'duplicate-description',\n severity: 'error',\n message: `Duplicate description found`,\n suggestion: `Also used by: ${otherFiles.join(', ')}`,\n }];\n },\n};\n\n/**\n * All duplicate rules\n */\nexport const duplicateRules: Rule[] = [\n duplicateTitle,\n duplicateDescription,\n];\n","/**\n * Heading Extractor Utility\n * Extracts and analyzes heading structure from MDX content\n */\n\nimport type { Heading } from '../types.js';\n\n/**\n * Check if a line is inside a code block\n * Tracks ``` and ~~~ fenced code blocks\n */\nfunction isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n\n return inCodeBlock;\n}\n\n/**\n * Extract all headings from MDX body content\n * Handles markdown-style headings (# H1, ## H2, etc.)\n */\nexport function extractHeadings(mdxBody: string): Heading[] {\n const headings: Heading[] = [];\n const lines = mdxBody.split('\\n');\n\n // Regex for markdown headings: # to ######\n const headingRegex = /^(#{1,6})\\s+(.+)$/;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(headingRegex);\n\n if (match && !isInCodeBlock(lines, i)) {\n const [, hashes, text] = match;\n headings.push({\n level: hashes.length,\n text: text.trim(),\n line: i + 1, // 1-indexed for display\n });\n }\n }\n\n return headings;\n}\n\n/**\n * Count H1 headings in the content\n */\nexport function countH1s(headings: Heading[]): number {\n return headings.filter(h => h.level === 1).length;\n}\n\n/**\n * Find H1 headings (for error reporting)\n */\nexport function findH1s(headings: Heading[]): Heading[] {\n return headings.filter(h => h.level === 1);\n}\n\n/**\n * Check for heading hierarchy violations\n * A violation occurs when a heading level is skipped (e.g., H1 -> H3 without H2)\n */\nexport function findHierarchyViolations(headings: Heading[]): Array<{\n heading: Heading;\n previousLevel: number;\n expectedMaxLevel: number;\n}> {\n const violations: Array<{\n heading: Heading;\n previousLevel: number;\n expectedMaxLevel: number;\n }> = [];\n\n let previousLevel = 0;\n\n for (const heading of headings) {\n // A heading should be at most 1 level deeper than previous\n // e.g., H1 can be followed by H1 or H2, not H3+\n if (heading.level > previousLevel + 1 && previousLevel > 0) {\n violations.push({\n heading,\n previousLevel,\n expectedMaxLevel: previousLevel + 1,\n });\n }\n\n previousLevel = heading.level;\n }\n\n return violations;\n}\n\n/**\n * Get a summary of heading structure for debugging\n */\nexport function getHeadingSummary(headings: Heading[]): string {\n if (headings.length === 0) {\n return 'No headings found';\n }\n\n const counts: Record<number, number> = {};\n for (const h of headings) {\n counts[h.level] = (counts[h.level] || 0) + 1;\n }\n\n return Object.entries(counts)\n .sort(([a], [b]) => Number(a) - Number(b))\n .map(([level, count]) => `H${level}: ${count}`)\n .join(', ');\n}\n","/**\n * Heading Structure Rules\n * Validates H1 presence, count, and heading hierarchy\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport {\n extractHeadings,\n countH1s,\n findH1s,\n findHierarchyViolations,\n} from '../utils/heading-extractor.js';\n\n/**\n * Rule: Content must have exactly one H1 heading\n * Exceptions:\n * - Pages with category 'legal' or 'service' use ServicePageHeader (H1 via title prop)\n * - Blog posts use BlogHeader component which renders the H1 from frontmatter title\n */\nexport const missingH1: Rule = {\n name: 'missing-h1',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an H1 heading (# Heading) at the start of the content',\n run: (item: ContentItem): LintResult[] => {\n // Skip H1 check for blog posts — BlogHeader renders the H1 from frontmatter title\n if (item.contentType === 'blog') {\n return [];\n }\n\n // Skip H1 check for pages that use ServicePageHeader component\n // These pages get their H1 from the title prop in the header\n if (item.category === 'legal' || item.category === 'service') {\n return [];\n }\n\n const headings = extractHeadings(item.body);\n const h1Count = countH1s(headings);\n\n if (h1Count === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'missing-h1',\n severity: 'warning',\n message: 'No H1 heading found in content',\n suggestion: 'Add an H1 heading (# Heading) at the start of your content',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Content must not have multiple H1 headings\n * Blog posts are exempt — BlogHeader provides the page H1,\n * and MDX # headings are rendered as <h2> via mdx-components.tsx.\n */\nexport const multipleH1: Rule = {\n name: 'multiple-h1',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Convert extra H1s to H2s',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'blog') {\n return [];\n }\n\n const headings = extractHeadings(item.body);\n const h1s = findH1s(headings);\n\n if (h1s.length > 1) {\n const locations = h1s.map(h => `line ${h.line}`).join(', ');\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'multiple-h1',\n severity: 'error',\n message: `Found ${h1s.length} H1 headings (expected 1)`,\n suggestion: `H1 headings at: ${locations}. Convert extra H1s to H2s.`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Heading hierarchy should not skip levels\n * e.g., H1 -> H3 without H2 is a violation\n */\nexport const headingHierarchySkip: Rule = {\n name: 'heading-hierarchy-skip',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Adjust heading levels to avoid skipping (e.g., H2 before H3)',\n run: (item: ContentItem): LintResult[] => {\n const headings = extractHeadings(item.body);\n const violations = findHierarchyViolations(headings);\n\n return violations.map(v => ({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'heading-hierarchy-skip',\n severity: 'warning' as const,\n message: `Heading level skipped: H${v.previousLevel} → H${v.heading.level}`,\n suggestion: `At line ${v.heading.line}: \"${v.heading.text}\". Expected H${v.expectedMaxLevel} or lower.`,\n line: v.heading.line,\n }));\n },\n};\n\n/**\n * Rule: Heading text should not be duplicated within the same page\n * Duplicate headings confuse readers and dilute SEO signal\n */\nexport const duplicateHeadingText: Rule = {\n name: 'duplicate-heading-text',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Use unique heading text for each section',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const headings = extractHeadings(item.body);\n\n const seen = new Map<string, number>();\n\n for (const heading of headings) {\n const normalized = heading.text.toLowerCase();\n const previousLine = seen.get(normalized);\n\n if (previousLine !== undefined) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'duplicate-heading-text',\n severity: 'warning',\n message: `Duplicate heading text: \"${heading.text}\"`,\n suggestion: `Same heading appears at line ${previousLine} and line ${heading.line}. Use unique headings for better structure.`,\n line: heading.line,\n });\n } else {\n seen.set(normalized, heading.line);\n }\n }\n\n return results;\n },\n};\n\n/**\n * All heading rules\n */\nexport const headingRules: Rule[] = [\n missingH1,\n multipleH1,\n headingHierarchySkip,\n duplicateHeadingText,\n];\n","/**\n * Image Extractor Utility\n * Extracts images and their alt text from MDX content\n */\n\nimport type { ExtractedImage } from '../types.js';\n\n/**\n * Check if a line is inside a code block\n */\nfunction isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n\n return inCodeBlock;\n}\n\n/**\n * Extract all images from MDX body content\n * Handles markdown images  and JSX/HTML img tags\n */\nexport function extractImages(mdxBody: string): ExtractedImage[] {\n const images: ExtractedImage[] = [];\n const lines = mdxBody.split('\\n');\n\n // Regex patterns\n // Markdown:  or \n const markdownImageRegex = /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g;\n\n // JSX/HTML: <img src=\"...\" alt=\"...\" /> or <Image src=\"...\" alt=\"...\" />\n const jsxImageRegex = /<(?:img|Image)\\s+[^>]*src=[\"']([^\"']+)[\"'][^>]*>/gi;\n const altAttrRegex = /alt=[\"']([^\"']*)[\"']/i;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip lines inside code blocks\n if (isInCodeBlock(lines, i)) {\n continue;\n }\n\n // Find markdown images: \n let match;\n while ((match = markdownImageRegex.exec(line)) !== null) {\n const [, alt, src] = match;\n\n images.push({\n src,\n alt: alt.trim(),\n line: i + 1,\n hasAlt: alt.trim().length > 0,\n source: 'inline',\n });\n }\n\n // Reset regex lastIndex for reuse\n markdownImageRegex.lastIndex = 0;\n\n // Find JSX/HTML images: <img src=\"...\" /> or <Image src=\"...\" />\n while ((match = jsxImageRegex.exec(line)) !== null) {\n const [fullMatch, src] = match;\n\n // Extract alt attribute if present\n const altMatch = fullMatch.match(altAttrRegex);\n const alt = altMatch ? altMatch[1] : '';\n\n // Skip if this src was already captured by markdown regex\n const alreadyCaptured = images.some(\n img => img.line === i + 1 && img.src === src\n );\n\n if (!alreadyCaptured) {\n images.push({\n src,\n alt: alt.trim(),\n line: i + 1,\n hasAlt: alt.trim().length > 0,\n source: 'inline',\n });\n }\n }\n\n // Reset regex lastIndex for reuse\n jsxImageRegex.lastIndex = 0;\n }\n\n return images;\n}\n\n/**\n * Get images missing alt text\n */\nexport function getImagesMissingAlt(images: ExtractedImage[]): ExtractedImage[] {\n return images.filter(img => !img.hasAlt);\n}\n\n/**\n * Create an ExtractedImage from frontmatter data\n */\nexport function createFrontmatterImage(\n imagePath: string | undefined,\n imageAlt: string | undefined\n): ExtractedImage | null {\n if (!imagePath) {\n return null;\n }\n\n return {\n src: imagePath,\n alt: imageAlt || '',\n line: 0, // Frontmatter doesn't have a specific line\n hasAlt: !!imageAlt && imageAlt.trim().length > 0,\n source: 'frontmatter',\n };\n}\n\n/**\n * Normalize image path for comparison\n */\nexport function normalizeImagePath(src: string): string {\n let normalized = src;\n\n // Handle relative paths\n if (!normalized.startsWith('/') && !normalized.startsWith('http')) {\n normalized = '/' + normalized;\n }\n\n // Remove query strings\n normalized = normalized.split('?')[0];\n\n return normalized;\n}\n","/**\n * Image Validation Rules\n * Validates image alt text presence and image file existence\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport {\n extractImages,\n createFrontmatterImage,\n normalizeImagePath,\n} from '../utils/image-extractor.js';\nimport { isValidImagePath } from '../utils/slug-resolver.js';\n\n/**\n * Rule: Inline images must have alt text\n */\nexport const inlineImageMissingAlt: Rule = {\n name: 'inline-image-missing-alt',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add descriptive alt text for accessibility and SEO',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const images = extractImages(item.body);\n\n for (const img of images) {\n if (!img.hasAlt) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'inline-image-missing-alt',\n severity: 'error',\n message: `Image missing alt text: ${img.src}`,\n suggestion: 'Add descriptive alt text for accessibility and SEO',\n line: img.line,\n });\n }\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Featured image in frontmatter should have alt text\n */\nexport const frontmatterImageMissingAlt: Rule = {\n name: 'frontmatter-image-missing-alt',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an imageAlt field to the frontmatter for the featured image',\n run: (item: ContentItem): LintResult[] => {\n // Only check if there's an image but no imageAlt\n if (item.image && (!item.imageAlt || item.imageAlt.trim().length === 0)) {\n return [{\n file: getDisplayPath(item),\n field: 'imageAlt',\n rule: 'frontmatter-image-missing-alt',\n severity: 'warning',\n message: 'Featured image missing alt text',\n suggestion: 'Add an imageAlt field to the frontmatter for the featured image',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Referenced images should exist in public directory\n */\nexport const imageNotFound: Rule = {\n name: 'image-not-found',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Check that the image path is correct and the file exists in public/',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const results: LintResult[] = [];\n\n // Check frontmatter image\n if (item.image) {\n const normalizedPath = normalizeImagePath(item.image);\n // Only check local images, not external URLs\n if (!item.image.startsWith('http') && !isValidImagePath(normalizedPath, context.validImages)) {\n results.push({\n file: getDisplayPath(item),\n field: 'image',\n rule: 'image-not-found',\n severity: 'warning',\n message: `Featured image not found: ${item.image}`,\n suggestion: 'Check that the image path is correct and the file exists in public/',\n });\n }\n }\n\n // Check inline images\n const images = extractImages(item.body);\n for (const img of images) {\n // Only check local images\n if (!img.src.startsWith('http')) {\n const normalizedPath = normalizeImagePath(img.src);\n if (!isValidImagePath(normalizedPath, context.validImages)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'image-not-found',\n severity: 'warning',\n message: `Inline image not found: ${img.src}`,\n suggestion: 'Check that the image path is correct and the file exists in public/',\n line: img.line,\n });\n }\n }\n }\n\n return results;\n },\n};\n\n/**\n * All image rules\n */\nexport const imageRules: Rule[] = [\n inlineImageMissingAlt,\n frontmatterImageMissingAlt,\n imageNotFound,\n];\n","/**\n * Word Counter Utility\n * Counts words in MDX content, stripping markdown syntax\n */\n\n/**\n * Strip markdown syntax to get plain text\n */\nexport function stripMarkdown(text: string): string {\n let result = text;\n\n // Remove code blocks (``` ... ```)\n result = result.replace(/```[\\s\\S]*?```/g, '');\n\n // Remove inline code (`code`)\n result = result.replace(/`[^`]+`/g, '');\n\n // Remove images \n result = result.replace(/!\\[[^\\]]*\\]\\([^)]+\\)/g, '');\n\n // Remove links but keep text [text](url) -> text\n result = result.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n\n // Remove HTML/JSX tags\n result = result.replace(/<[^>]+>/g, '');\n\n // Remove headings markers (#)\n result = result.replace(/^#{1,6}\\s+/gm, '');\n\n // Remove bold/italic markers\n result = result.replace(/\\*\\*([^*]+)\\*\\*/g, '$1');\n result = result.replace(/\\*([^*]+)\\*/g, '$1');\n result = result.replace(/__([^_]+)__/g, '$1');\n result = result.replace(/_([^_]+)_/g, '$1');\n\n // Remove blockquotes\n result = result.replace(/^>\\s+/gm, '');\n\n // Remove horizontal rules\n result = result.replace(/^[-*_]{3,}$/gm, '');\n\n // Remove list markers\n result = result.replace(/^[\\s]*[-*+]\\s+/gm, '');\n result = result.replace(/^[\\s]*\\d+\\.\\s+/gm, '');\n\n // Remove frontmatter-style content (import statements, etc.)\n result = result.replace(/^import\\s+.*$/gm, '');\n result = result.replace(/^export\\s+.*$/gm, '');\n\n // Remove JSX component tags (like <CalloutBox>...</CalloutBox>)\n result = result.replace(/<\\w+[^>]*>[\\s\\S]*?<\\/\\w+>/g, (match) => {\n // Try to extract text content from JSX\n return match.replace(/<[^>]+>/g, ' ');\n });\n\n return result;\n}\n\n/**\n * Count words in text\n * Splits on whitespace and counts non-empty tokens\n */\nexport function countWords(text: string): number {\n const stripped = stripMarkdown(text);\n\n // Split on whitespace and filter empty strings\n const words = stripped\n .split(/\\s+/)\n .filter(word => word.length > 0)\n // Filter out remaining non-word characters\n .filter(word => /\\w/.test(word));\n\n return words.length;\n}\n\n/**\n * Count sentences in text\n * Looks for sentence-ending punctuation\n */\nexport function countSentences(text: string): number {\n const stripped = stripMarkdown(text);\n\n // Count sentence-ending punctuation\n // This is a simplified approach - handles . ! ? followed by space or end\n const sentences = stripped.match(/[.!?]+(?:\\s|$)/g);\n\n return sentences ? sentences.length : 0;\n}\n\n/**\n * Get word count statistics for content\n */\nexport function getWordStats(mdxBody: string): {\n wordCount: number;\n sentenceCount: number;\n avgWordsPerSentence: number;\n} {\n const wordCount = countWords(mdxBody);\n const sentenceCount = countSentences(mdxBody);\n\n return {\n wordCount,\n sentenceCount,\n avgWordsPerSentence: sentenceCount > 0 ? wordCount / sentenceCount : 0,\n };\n}\n","/**\n * Readability Utility\n * Calculates locale-aware Flesch Reading Ease scores for content.\n *\n * Supports English and German with their respective formulas:\n * - English: 206.835 - 1.015*ASL - 84.6*ASW\n * - German: 180 - ASL - 58.5*ASW\n */\n\nimport { stripMarkdown, countWords, countSentences } from './word-counter.js';\n\n/**\n * Estimate syllable count for a word using locale-specific heuristics.\n * English: applies silent-e discount. German: applies compound word adjustment.\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'de'.\n */\nexport function estimateSyllables(word: string, locale: string = 'de'): number {\n const lower = word.toLowerCase();\n\n // Count vowel groups (including umlauts)\n const vowelPattern = /[aeiouyäöü]+/gi;\n const matches = lower.match(vowelPattern);\n\n if (!matches) {\n return 1; // Assume at least 1 syllable\n }\n\n let count = matches.length;\n const lang = locale.toLowerCase().slice(0, 2);\n\n if (lang === 'en') {\n // English: silent-e discount\n if (lower.endsWith('e') && count > 1) {\n count -= 0.5;\n }\n } else {\n // German (and fallback): compound word adjustment for long words\n if (word.length > 12) {\n count = Math.max(count, Math.ceil(word.length / 4));\n }\n }\n\n return Math.max(1, Math.round(count));\n}\n\n/**\n * Count total syllables in text\n */\nfunction countSyllables(text: string, locale: string): number {\n const words = text\n .split(/\\s+/)\n .filter(word => word.length > 0)\n .filter(word => /\\w/.test(word));\n\n return words.reduce((total, word) => total + estimateSyllables(word, locale), 0);\n}\n\n/**\n * Calculate average word length in characters\n */\nfunction averageWordLength(text: string): number {\n const words = text\n .split(/\\s+/)\n .filter(word => word.length > 0)\n .filter(word => /\\w/.test(word));\n\n if (words.length === 0) return 0;\n\n const totalLength = words.reduce((sum, word) => sum + word.length, 0);\n return totalLength / words.length;\n}\n\n/**\n * Calculate locale-aware Flesch Reading Ease score.\n * Score range: 0-100 (higher = easier to read).\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'de'.\n */\n/** Flesch Reading Ease coefficients per locale */\nconst FLESCH_COEFFICIENTS = {\n en: { intercept: 206.835, aslWeight: 1.015, aswWeight: 84.6 },\n de: { intercept: 180, aslWeight: 1.0, aswWeight: 58.5 },\n} as const;\n\ntype FleschLocale = keyof typeof FLESCH_COEFFICIENTS;\n\n/** Interpretation bands per locale (score thresholds differ between formulas) */\nconst INTERPRETATION_BANDS: Record<FleschLocale, ReadonlyArray<{ min: number; label: string }>> = {\n en: [\n { min: 90, label: 'Very easy to read' },\n { min: 80, label: 'Easy to read' },\n { min: 70, label: 'Fairly easy to read' },\n { min: 60, label: 'Standard' },\n { min: 50, label: 'Fairly difficult' },\n { min: 30, label: 'Difficult' },\n { min: 0, label: 'Very difficult' },\n ],\n de: [\n { min: 70, label: 'Very easy to read' },\n { min: 60, label: 'Easy to read' },\n { min: 50, label: 'Fairly easy to read' },\n { min: 40, label: 'Standard' },\n { min: 30, label: 'Fairly difficult' },\n { min: 20, label: 'Difficult' },\n { min: 0, label: 'Very difficult' },\n ],\n};\n\nexport function calculateReadability(mdxBody: string, locale: string = 'de'): {\n score: number;\n avgSentenceLength: number;\n avgSyllablesPerWord: number;\n avgWordLength: number;\n interpretation: string;\n} {\n const plainText = stripMarkdown(mdxBody);\n\n const wordCount = countWords(mdxBody);\n const sentenceCount = countSentences(mdxBody);\n const syllableCount = countSyllables(plainText, locale);\n\n // Avoid division by zero\n if (wordCount === 0 || sentenceCount === 0) {\n return {\n score: 0,\n avgSentenceLength: 0,\n avgSyllablesPerWord: 0,\n avgWordLength: 0,\n interpretation: 'No content to analyze',\n };\n }\n\n const avgSentenceLength = wordCount / sentenceCount;\n const avgSyllablesPerWord = syllableCount / wordCount;\n const avgWordLen = averageWordLength(plainText);\n\n const lang = locale.toLowerCase().slice(0, 2) as FleschLocale;\n const coefficients = FLESCH_COEFFICIENTS[lang] ?? FLESCH_COEFFICIENTS.de;\n const score = Math.round(\n coefficients.intercept\n - coefficients.aslWeight * avgSentenceLength\n - coefficients.aswWeight * avgSyllablesPerWord,\n );\n\n const clampedScore = Math.max(0, Math.min(100, score));\n\n return {\n score: clampedScore,\n avgSentenceLength: Math.round(avgSentenceLength * 10) / 10,\n avgSyllablesPerWord: Math.round(avgSyllablesPerWord * 100) / 100,\n avgWordLength: Math.round(avgWordLen * 10) / 10,\n interpretation: getInterpretation(clampedScore, locale),\n };\n}\n\n/**\n * Get human-readable interpretation of readability score\n */\nfunction getInterpretation(score: number, locale: string = 'de'): string {\n const lang = locale.toLowerCase().slice(0, 2) as FleschLocale;\n const bands = INTERPRETATION_BANDS[lang] ?? INTERPRETATION_BANDS.de;\n\n for (const band of bands) {\n if (score >= band.min) return band.label;\n }\n return 'Very difficult';\n}\n\n/**\n * Check if readability score meets minimum threshold\n */\nexport function isReadable(score: number, threshold: number): boolean {\n return score >= threshold;\n}\n","/**\n * Content Quality Rules\n * Validates word count and readability\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { calculateReadability, isReadable } from '../utils/readability.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default content thresholds (used when context has no thresholds) */\nconst CONTENT_DEFAULTS = { minWordCount: 300, minReadabilityScore: 30 };\n\n/**\n * Rule: Content should have minimum word count\n */\nexport const contentTooShort: Rule = {\n name: 'content-too-short',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Expand the content for better SEO performance',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const c = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).content\n : CONTENT_DEFAULTS;\n const wordCount = countWords(item.body);\n\n if (wordCount < c.minWordCount) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-too-short',\n severity: 'warning',\n message: `Content is too short (${wordCount} words, minimum ${c.minWordCount})`,\n suggestion: 'Consider expanding the content for better SEO performance',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Content should meet minimum readability threshold\n */\nexport const lowReadability: Rule = {\n name: 'low-readability',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Use shorter sentences for easier reading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n\n if (wordCount < 100) {\n return [];\n }\n\n const c = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).content\n : CONTENT_DEFAULTS;\n const locale = item.locale ?? context.defaultLocale ?? 'de';\n const readability = calculateReadability(item.body, locale);\n\n if (!isReadable(readability.score, c.minReadabilityScore)) {\n /** Escalate to error for extremely unreadable content (score < 20) */\n const isExtreme = readability.score < 20;\n const severity = isExtreme ? 'error' : 'warning';\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'low-readability',\n severity,\n message: `${isExtreme ? 'Extremely low' : 'Low'} readability score (${readability.score}/100 - ${readability.interpretation})`,\n suggestion: `Avg sentence length: ${readability.avgSentenceLength} words. ${isExtreme ? 'Content is nearly unreadable. Drastically simplify sentence structure and vocabulary.' : 'Consider shorter sentences for easier reading.'}`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All content rules\n */\nexport const contentRules: Rule[] = [\n contentTooShort,\n lowReadability,\n];\n","/**\n * Open Graph Rules\n * Validates Open Graph / social sharing metadata\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Blog posts should have a featured image for social sharing\n */\nexport const blogMissingOgImage: Rule = {\n name: 'blog-missing-og-image',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an image field to the frontmatter for social sharing previews',\n run: (item: ContentItem): LintResult[] => {\n // Only apply to blog posts\n if (item.contentType !== 'blog') {\n return [];\n }\n\n if (!item.image || item.image.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'image',\n rule: 'blog-missing-og-image',\n severity: 'warning',\n message: 'Blog post missing featured image',\n suggestion: 'Add an image field for better social media sharing previews.',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Project pages should have a thumbnail/featured image for social sharing\n */\nexport const projectMissingOgImage: Rule = {\n name: 'project-missing-og-image',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a thumbnail image for social media sharing previews',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'project') {\n return [];\n }\n\n if (!item.image || item.image.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'image',\n rule: 'project-missing-og-image',\n severity: 'warning',\n message: 'Project missing thumbnail/featured image',\n suggestion: 'Add a thumbnail image for better social media sharing previews.',\n }];\n }\n return [];\n },\n};\n\n/**\n * All Open Graph rules\n */\nexport const ogRules: Rule[] = [\n blogMissingOgImage,\n projectMissingOgImage,\n];\n","/**\n * Performance Validation Rules\n * Checks image file sizes and other performance-related concerns\n */\n\nimport { statSync } from 'fs';\nimport { join } from 'path';\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { extractImages } from '../utils/image-extractor.js';\n\n/** Default max image size in KB */\nconst MAX_IMAGE_SIZE_KB = 500;\n\n/**\n * Rule: Image files should not exceed the configured size limit\n * Large images degrade page load performance and Core Web Vitals\n */\nexport const imageFileTooLarge: Rule = {\n name: 'image-file-too-large',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Compress the image or convert to WebP/AVIF format',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const maxBytes = MAX_IMAGE_SIZE_KB * 1024;\n const imagesToCheck: Array<{ src: string; line?: number; source: string }> = [];\n\n // Check featured image from frontmatter\n if (item.image && !item.image.startsWith('http')) {\n imagesToCheck.push({ src: item.image, source: 'frontmatter' });\n }\n\n // Check inline images from body\n const inlineImages = extractImages(item.body);\n for (const img of inlineImages) {\n if (!img.src.startsWith('http')) {\n imagesToCheck.push({ src: img.src, line: img.line, source: 'inline' });\n }\n }\n\n for (const image of imagesToCheck) {\n try {\n const imagePath = join(process.cwd(), 'public', image.src);\n const stats = statSync(imagePath);\n const sizeKB = Math.round(stats.size / 1024);\n\n if (stats.size > maxBytes) {\n results.push({\n file: getDisplayPath(item),\n field: image.source === 'frontmatter' ? 'image' : 'body',\n rule: 'image-file-too-large',\n severity: 'warning',\n message: `Image file too large: ${image.src} (${sizeKB}KB > ${MAX_IMAGE_SIZE_KB}KB)`,\n suggestion: 'Compress the image or convert to WebP/AVIF format to improve page load speed',\n line: image.line,\n });\n }\n } catch {\n // File not found is handled by image-not-found rule\n }\n }\n\n return results;\n },\n};\n\n/**\n * All performance rules\n */\nexport const performanceRules: Rule[] = [\n imageFileTooLarge,\n];\n","/**\n * Robots / Indexing Validation Rules\n * Validates noindex and robots-related settings\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Published (non-draft) content with noindex may be unintentional\n * Warns when content is publicly available but hidden from search engines\n */\nexport const publishedNoindex: Rule = {\n name: 'published-noindex',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Remove noindex if content should be discoverable, or set draft: true to hide it',\n run: (item: ContentItem): LintResult[] => {\n if (!item.draft && item.noindex === true) {\n return [{\n file: getDisplayPath(item),\n field: 'noindex',\n rule: 'published-noindex',\n severity: 'warning',\n message: 'Published content has noindex set — it will not appear in search results',\n suggestion: 'Remove noindex if this content should be discoverable, or set draft: true if it should be hidden entirely',\n }];\n }\n return [];\n },\n};\n\n/**\n * All robots/indexing rules\n */\nexport const robotsRules: Rule[] = [\n publishedNoindex,\n];\n","/**\n * Slug Validation Rules\n * Validates slug format and length for SEO-friendly URLs\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default slug threshold (used when context has no thresholds) */\nconst SLUG_DEFAULTS = { maxLength: 75 };\nconst SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Rule: Slug must contain only valid characters (lowercase alphanumeric + hyphens)\n */\nexport const slugInvalidCharacters: Rule = {\n name: 'slug-invalid-characters',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Use lowercase alphanumeric characters with hyphens only (e.g., \"my-blog-post\")',\n run: (item: ContentItem): LintResult[] => {\n if (!item.slug) return [];\n\n const hasUppercase = /[A-Z]/.test(item.slug);\n const matchesPattern = SLUG_PATTERN.test(item.slug);\n\n if (hasUppercase || !matchesPattern) {\n return [{\n file: getDisplayPath(item),\n field: 'slug',\n rule: 'slug-invalid-characters',\n severity: 'error',\n message: `Slug \"${item.slug}\" contains invalid characters`,\n suggestion: 'Slugs must be lowercase alphanumeric with hyphens only (e.g., \"my-blog-post\")',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Slug should not exceed maximum length\n */\nexport const slugTooLong: Rule = {\n name: 'slug-too-long',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Shorten the slug for better URL readability',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.slug) return [];\n\n const s = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).slug\n : SLUG_DEFAULTS;\n const length = item.slug.length;\n if (length > s.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'slug',\n rule: 'slug-too-long',\n severity: 'warning',\n message: `Slug is too long (${length}/${s.maxLength} chars)`,\n suggestion: `Shorten the slug to ${s.maxLength} characters or less for better URL readability`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All slug rules\n */\nexport const slugRules: Rule[] = [\n slugInvalidCharacters,\n slugTooLong,\n];\n","/**\n * Internationalization Validation Rules\n * Validates translation completeness, locale metadata, and hreflang x-default readiness\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { I18nConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Create a translation-pair-missing rule for the configured locales.\n * Checks that every translation group has versions for all configured locales.\n */\nfunction createTranslationPairMissingRule(i18n: I18nConfig): Rule {\n return {\n name: 'translation-pair-missing',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: 'Create the missing translation version with the same translationKey',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.translationKey) return [];\n if (!item.locale) return [];\n\n const siblings = context.allContent.filter(\n c => c.translationKey === item.translationKey && c.slug !== item.slug,\n );\n const presentLocales = new Set([item.locale, ...siblings.map(s => s.locale)]);\n const results: LintResult[] = [];\n\n for (const locale of i18n.locales) {\n if (!presentLocales.has(locale)) {\n results.push({\n file: getDisplayPath(item),\n field: 'translationKey',\n rule: 'translation-pair-missing',\n severity: 'warning',\n message: `Missing \"${locale}\" translation for translationKey \"${item.translationKey}\"`,\n suggestion: `Create a ${locale} version with the same translationKey value.`,\n });\n }\n }\n\n return results;\n },\n };\n}\n\n/**\n * Create a missing-locale rule that lists all configured locales in the suggestion.\n */\nfunction createMissingLocaleRule(i18n: I18nConfig): Rule {\n const localeList = i18n.locales.join(' / ');\n\n return {\n name: 'missing-locale',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: `Add a locale field (${localeList}) to the frontmatter`,\n run: (item: ContentItem): LintResult[] => {\n if (!item.locale) {\n return [{\n file: getDisplayPath(item),\n field: 'locale',\n rule: 'missing-locale',\n severity: 'warning',\n message: 'Missing locale field',\n suggestion: `Add a locale field (${localeList}) to the frontmatter for proper i18n support.`,\n }];\n }\n return [];\n },\n };\n}\n\n/**\n * Create an x-default-missing rule.\n * Checks that each translation group has a version in the default locale.\n * Fires once per group (on the first non-default item, sorted by slug).\n */\nfunction createXDefaultMissingRule(i18n: I18nConfig): Rule {\n return {\n name: 'x-default-missing',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: `Create a ${i18n.defaultLocale} version so hreflang x-default resolves correctly`,\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.translationKey) return [];\n if (item.locale === i18n.defaultLocale) return [];\n\n const groupItems = context.allContent.filter(\n c => c.translationKey === item.translationKey,\n );\n\n const hasDefaultLocale = groupItems.some(c => c.locale === i18n.defaultLocale);\n if (hasDefaultLocale) return [];\n\n // Fire only on the first non-default item (sorted by slug for determinism)\n const sortedNonDefault = groupItems\n .filter(c => c.locale !== i18n.defaultLocale)\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n if (sortedNonDefault.length === 0 || sortedNonDefault[0].slug !== item.slug) {\n return [];\n }\n\n return [{\n file: getDisplayPath(item),\n field: 'translationKey',\n rule: 'x-default-missing',\n severity: 'warning',\n message: `Translation group \"${item.translationKey}\" has no ${i18n.defaultLocale} version — hreflang x-default will not resolve`,\n suggestion: `Create a ${i18n.defaultLocale} version with translationKey \"${item.translationKey}\".`,\n }];\n },\n };\n}\n\n/**\n * Create all i18n rules from configuration.\n * Supports configurable locales and default locale.\n */\nexport function createI18nRules(i18n: I18nConfig): Rule[] {\n return [\n createTranslationPairMissingRule(i18n),\n createMissingLocaleRule(i18n),\n createXDefaultMissingRule(i18n),\n ];\n}\n\n/** Static export for backward compatibility (DE/EN defaults) */\nexport const i18nRules: Rule[] = createI18nRules({\n locales: ['de', 'en'],\n defaultLocale: 'de',\n});\n","/**\n * Date Validation Rules\n * Validates date presence and correctness for blog and project content\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Blog and project content must have a date field\n */\nexport const missingDate: Rule = {\n name: 'missing-date',\n severity: 'error',\n category: 'content',\n fixStrategy: 'Add a date field (e.g., \"2025-01-15\") to the frontmatter',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'page') return [];\n\n if (!item.date) {\n return [{\n file: getDisplayPath(item),\n field: 'date',\n rule: 'missing-date',\n severity: 'error',\n message: 'Missing date field',\n suggestion: 'Add a date field (e.g., \"2025-01-15\") to the frontmatter',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Date should not be in the future\n */\nexport const futureDate: Rule = {\n name: 'future-date',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Verify the publish date is correct or set it to today',\n run: (item: ContentItem): LintResult[] => {\n if (!item.date) return [];\n\n const dateValue = new Date(item.date);\n const now = new Date();\n\n if (dateValue > now) {\n return [{\n file: getDisplayPath(item),\n field: 'date',\n rule: 'future-date',\n severity: 'warning',\n message: `Date \"${item.date}\" is in the future`,\n suggestion: 'Verify the publish date is correct or set it to today',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Blog and project content should have an updatedAt field\n */\nexport const missingUpdatedAt: Rule = {\n name: 'missing-updated-at',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add an updatedAt field to help search engines identify fresh content',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'page') return [];\n\n if (!item.updatedAt) {\n return [{\n file: getDisplayPath(item),\n field: 'updatedAt',\n rule: 'missing-updated-at',\n severity: 'warning',\n message: 'Missing updatedAt field',\n suggestion: 'Add an updatedAt field to help search engines identify fresh content',\n }];\n }\n return [];\n },\n};\n\n/**\n * All date rules\n */\nexport const dateRules: Rule[] = [\n missingDate,\n futureDate,\n missingUpdatedAt,\n];\n","/**\n * GEO (Generative Engine Optimization) Analyzer\n * Utilities for analyzing content readiness for LLM visibility\n */\n\nimport { extractHeadings } from './heading-extractor.js';\nimport { countWords } from './word-counter.js';\n\n/**\n * Question words in English and German (case-insensitive matching)\n */\nconst QUESTION_WORDS = [\n 'was', 'wie', 'warum', 'wann', 'wo', 'wer', 'welche',\n 'how', 'what', 'why', 'when', 'where', 'who', 'which',\n 'can', 'do', 'does', 'is', 'are', 'should',\n];\n\n/**\n * Weak lead sentence patterns (case-insensitive)\n * These indicate introductory filler rather than direct answers\n */\nconst WEAK_LEAD_STARTS = [\n // English — generic filler openings\n 'in this', 'the following', 'this section', 'this article',\n 'this post', 'this guide', 'this chapter',\n 'as we discussed', 'as mentioned', 'as noted', 'as stated',\n 'it is important to', 'it should be noted', 'it is worth noting',\n 'it is well known', 'it goes without saying',\n 'in the following', 'in this section', 'in this article',\n 'there are many', 'there are several', 'there are a number of',\n 'we will discuss', 'we will explore', 'we will examine',\n \"let's\", \"let's take a look\",\n // German — generische Fülleröffnungen\n 'dieser abschnitt', 'dieser artikel', 'dieser beitrag',\n 'diesem', 'lass uns', 'im folgenden',\n 'wie bereits erwähnt', 'wie oben erwähnt',\n 'es ist wichtig', 'es sei darauf hingewiesen',\n 'es gibt viele', 'es gibt zahlreiche',\n 'wir werden', 'schauen wir uns',\n];\n\n/**\n * Markdown table separator pattern\n * Matches `|---`, `| ---`, `|:---`, `| :---:` and similar variants\n */\nconst TABLE_SEPARATOR_PATTERN = /\\|\\s*:?-{2,}/;\n\n/**\n * Count headings that are formatted as questions\n * A question heading either ends with '?' or starts with a question word\n */\nexport function countQuestionHeadings(body: string): number {\n const headings = extractHeadings(body);\n let count = 0;\n\n for (const heading of headings) {\n const text = heading.text.trim();\n\n // Check if heading ends with question mark\n if (text.endsWith('?')) {\n count++;\n continue;\n }\n\n // Check if heading starts with a question word\n const firstWord = text.split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (QUESTION_WORDS.includes(firstWord)) {\n count++;\n }\n }\n\n return count;\n}\n\n/**\n * Analyze lead sentences across content sections\n * Splits on H2/H3 headings and checks if the first sentence in each\n * section is a direct answer (not a weak intro)\n */\nexport function analyzeLeadSentences(body: string): {\n totalSections: number;\n sectionsWithDirectAnswers: number;\n} {\n // Split body on H2/H3 heading patterns\n const sectionPattern = /^#{2,3}\\s+.+$/m;\n const sections = body.split(sectionPattern);\n\n // First element is content before the first heading (skip it)\n const contentSections = sections.slice(1);\n\n let totalSections = 0;\n let sectionsWithDirectAnswers = 0;\n\n for (const section of contentSections) {\n const trimmed = section.trim();\n if (!trimmed) continue;\n\n totalSections++;\n\n // Extract first sentence (ends with . ! or ?)\n const sentenceMatch = trimmed.match(/^([^.!?]+[.!?])/);\n if (!sentenceMatch) continue;\n\n const firstSentence = sentenceMatch[1].trim();\n\n // Skip if too short to be meaningful\n if (firstSentence.length <= 20) continue;\n\n // Skip if ends with question mark (not a direct answer)\n if (firstSentence.endsWith('?')) continue;\n\n // Check for weak lead patterns\n const lowerSentence = firstSentence.toLowerCase();\n const isWeakLead = WEAK_LEAD_STARTS.some(\n pattern => lowerSentence.startsWith(pattern)\n );\n\n if (!isWeakLead) {\n sectionsWithDirectAnswers++;\n }\n }\n\n return { totalSections, sectionsWithDirectAnswers };\n}\n\n/**\n * Count statistical data points in the content body\n * Looks for percentages, multipliers, currency values, large numbers, and scales\n */\nexport function countStatistics(body: string): number {\n const patterns: RegExp[] = [\n /\\d+\\s*%/g, // Percentages: 50%, 23 %\n /\\d+(?:\\.\\d+)?\\s*(?:x|mal|times)/gi, // Multipliers: 3x, 2.5 mal, 10 times\n /(?:€|\\$|USD|EUR)\\s*\\d+/g, // Currency: €500, $1000, USD 50\n /\\d{4,}/g, // Large numbers: 10000, 2024 (4+ digits)\n /\\d+(?:\\.\\d+)?\\s*(?:million|billion|mrd|mio)/gi, // Scales: 5 million, 2.3 Mrd\n ];\n\n const matches = new Set<string>();\n\n for (const pattern of patterns) {\n const found = body.matchAll(pattern);\n for (const match of found) {\n // Use position as key to avoid double-counting overlapping matches\n matches.add(`${match.index}:${match[0]}`);\n }\n }\n\n return matches.size;\n}\n\n/**\n * Check if the content body contains a FAQ section\n * Matches common FAQ heading patterns in English and German\n */\nexport function hasFAQSection(body: string): boolean {\n const faqPattern = /#{2,3}\\s*(FAQ|Häufige Fragen|Frequently Asked|Fragen und Antworten)/i;\n return faqPattern.test(body);\n}\n\n/**\n * Check if the content body contains at least one Markdown table\n * Detects the table separator row pattern (e.g., `|---|---`)\n */\nexport function hasMarkdownTable(body: string): boolean {\n return TABLE_SEPARATOR_PATTERN.test(body);\n}\n\n/**\n * Count case-insensitive occurrences of an entity string in the body\n *\n * @example\n * countEntityMentions(\"ACME builds software in Berlin\", \"acme\") // 1\n * countEntityMentions(\"Visit Berlin, the best city. Berlin rocks.\", \"berlin\") // 2\n */\nexport function countEntityMentions(body: string, entity: string): number {\n const escapedEntity = entity.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(escapedEntity, 'gi');\n const matches = body.match(pattern);\n return matches ? matches.length : 0;\n}\n\n/**\n * Analyze citation blocks after H2 headings\n * For each H2 section, checks whether the first paragraph is substantial\n * (40+ words), which improves AI system extraction and citation likelihood\n *\n * @example\n * analyzeCitationBlocks(\"## Heading\\n\\nA long first paragraph...\") // { totalSections: 1, sectionsWithAdequateBlocks: 1 }\n */\nexport function analyzeCitationBlocks(body: string): {\n totalSections: number;\n sectionsWithAdequateBlocks: number;\n} {\n // Split on H2 headings specifically (not H3+)\n const h2Pattern = /^##\\s+.+$/gm;\n const h2Matches = [...body.matchAll(h2Pattern)];\n\n if (h2Matches.length === 0) {\n return { totalSections: 0, sectionsWithAdequateBlocks: 0 };\n }\n\n let totalSections = 0;\n let sectionsWithAdequateBlocks = 0;\n\n for (let i = 0; i < h2Matches.length; i++) {\n const matchStart = h2Matches[i].index! + h2Matches[i][0].length;\n const nextHeadingStart = i + 1 < h2Matches.length\n ? h2Matches[i + 1].index!\n : body.length;\n\n const sectionContent = body.slice(matchStart, nextHeadingStart).trim();\n if (!sectionContent) continue;\n\n totalSections++;\n\n // Extract the first paragraph: text before the first blank line\n // followed by a heading, or before a sub-heading (### ...)\n const firstParagraph = extractFirstParagraph(sectionContent);\n if (!firstParagraph) continue;\n\n const wordCount = countWords(firstParagraph);\n if (wordCount >= 40) {\n sectionsWithAdequateBlocks++;\n }\n }\n\n return { totalSections, sectionsWithAdequateBlocks };\n}\n\n/**\n * Extract the first paragraph from a section content block\n * A paragraph ends at a blank line or at the next heading\n */\nfunction extractFirstParagraph(sectionContent: string): string {\n const lines = sectionContent.split('\\n');\n const paragraphLines: string[] = [];\n let foundContent = false;\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n // Skip leading empty lines\n if (!foundContent && !trimmedLine) continue;\n\n // Stop at a heading line\n if (trimmedLine.startsWith('#')) break;\n\n // Stop at a blank line after content has started\n if (foundContent && !trimmedLine) break;\n\n // Skip import/export statements and JSX component lines\n if (trimmedLine.startsWith('import ') || trimmedLine.startsWith('export ')) continue;\n if (trimmedLine.startsWith('<') && !trimmedLine.startsWith('<a')) continue;\n\n foundContent = true;\n paragraphLines.push(trimmedLine);\n }\n\n return paragraphLines.join(' ');\n}\n\n/**\n * Citation attribution patterns (case-insensitive)\n */\nconst CITATION_PHRASES = [\n /according to\\b/gi,\n /a study by\\b/gi,\n /research by\\b/gi,\n /data from\\b/gi,\n];\n\n/**\n * Count source citations in content body.\n * Matches: \"according to [Source]\", markdown links [text](url),\n * blockquote attributions (> ... -- Name), footnote markers [^1]\n *\n * @example\n * countSourceCitations(\"According to [ACME](https://acme.com), results improved by 30%.\") // 2\n */\nexport function countSourceCitations(body: string): number {\n let count = 0;\n\n // Count attribution phrases\n for (const pattern of CITATION_PHRASES) {\n const matches = body.match(pattern);\n if (matches) count += matches.length;\n }\n\n // Count markdown links with HTTP URLs\n const linkPattern = /\\[[^\\]]+\\]\\(https?:\\/\\/[^)]+\\)/g;\n const linkMatches = body.match(linkPattern);\n if (linkMatches) count += linkMatches.length;\n\n // Count blockquote attributions: lines starting with > containing em-dash or double-dash attribution\n const attributionPattern = /^>\\s*.*(?:\\u2014|--)\\s*\\S+/gm;\n const attrMatches = body.match(attributionPattern);\n if (attrMatches) count += attrMatches.length;\n\n // Count footnote markers [^1], [^note], etc.\n const footnotePattern = /\\[\\^[^\\]]+\\]/g;\n const footnoteMatches = body.match(footnotePattern);\n if (footnoteMatches) count += footnoteMatches.length;\n\n return count;\n}\n\n/**\n * Check if content has at least one attributed expert quote.\n * Attributed: blockquote (>) followed by em-dash + name, or \"said [Name]\"\n *\n * @example\n * hasExpertQuote('> AI will transform everything.\\n> \\u2014 Dr. Smith') // true\n */\nexport function hasExpertQuote(body: string): boolean {\n const lines = body.split('\\n');\n let inBlockquote = false;\n let blockquoteText = '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('>')) {\n inBlockquote = true;\n blockquoteText += ' ' + trimmed.slice(1).trim();\n } else {\n if (inBlockquote && blockquoteText) {\n // Check for em-dash or double-dash attribution within the blockquote\n if (/(?:\\u2014|--)\\s*[A-Z]/.test(blockquoteText)) {\n return true;\n }\n }\n inBlockquote = false;\n blockquoteText = '';\n }\n }\n\n // Check final blockquote if body ends with one\n if (inBlockquote && /(?:\\u2014|--)\\s*[A-Z]/.test(blockquoteText)) {\n return true;\n }\n\n // Check for \"said [Name]\" pattern anywhere\n if (/(?:said|says)\\s+[A-Z][a-z]+/.test(body)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Extract H2 sections from body, returning heading text, section body, and line number.\n *\n * @example\n * extractH2Sections(\"## Intro\\n\\nHello world\\n\\n## Next\\n\\nMore text\")\n * // [{ heading: \"Intro\", body: \"Hello world\", line: 1 }, { heading: \"Next\", body: \"More text\", line: 5 }]\n */\nexport function extractH2Sections(body: string): Array<{ heading: string; body: string; line: number }> {\n const h2Pattern = /^##\\s+(.+)$/gm;\n const matches = [...body.matchAll(h2Pattern)];\n const sections: Array<{ heading: string; body: string; line: number }> = [];\n\n for (let i = 0; i < matches.length; i++) {\n const match = matches[i];\n const headingText = match[1].trim();\n const lineNumber = body.slice(0, match.index!).split('\\n').length;\n\n const contentStart = match.index! + match[0].length;\n const contentEnd = i + 1 < matches.length ? matches[i + 1].index! : body.length;\n const sectionBody = body.slice(contentStart, contentEnd).trim();\n\n sections.push({ heading: headingText, body: sectionBody, line: lineNumber });\n }\n\n return sections;\n}\n\n/**\n * Split body into paragraphs (text between blank lines), with word counts.\n * Skips code blocks, import/export lines, JSX components, and heading lines.\n *\n * @example\n * getParagraphs(\"Hello world.\\n\\nAnother paragraph.\") // [{ text: \"Hello world.\", line: 1, wordCount: 2 }, ...]\n */\nexport function getParagraphs(body: string): Array<{ text: string; line: number; wordCount: number }> {\n const lines = body.split('\\n');\n const paragraphs: Array<{ text: string; line: number; wordCount: number }> = [];\n let inCodeBlock = false;\n let currentLines: string[] = [];\n let paragraphStartLine = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // Track code block state\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n // Flush current paragraph before code block\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n currentLines = [];\n }\n continue;\n }\n\n if (inCodeBlock) continue;\n\n // Skip import/export lines, JSX components, and heading lines\n if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) continue;\n if (trimmed.startsWith('<') && !trimmed.startsWith('<a')) continue;\n if (/^#{1,6}\\s+/.test(trimmed)) continue;\n\n // Blank line: flush current paragraph\n if (!trimmed) {\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n currentLines = [];\n }\n continue;\n }\n\n // Start new paragraph if needed\n if (currentLines.length === 0) {\n paragraphStartLine = i;\n }\n currentLines.push(trimmed);\n }\n\n // Flush final paragraph\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n }\n\n return paragraphs;\n}\n\n/**\n * Check if body contains at least one bulleted or numbered markdown list.\n * Matches: \"- \", \"* \", \"1. \" at start of line (outside code blocks).\n *\n * @example\n * hasMarkdownList(\"Some text\\n- item one\\n- item two\") // true\n */\nexport function hasMarkdownList(body: string): boolean {\n const lines = body.split('\\n');\n let inCodeBlock = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n\n if (inCodeBlock) continue;\n\n // Check for unordered list items\n if (/^[-*]\\s+/.test(trimmed)) return true;\n\n // Check for ordered list items\n if (/^\\d+\\.\\s+/.test(trimmed)) return true;\n }\n\n return false;\n}\n\n/**\n * Count internal markdown links (relative paths starting with /).\n * Only counts markdown link syntax [text](/path), not bare URLs.\n *\n * @example\n * countInternalLinks(\"See [our blog](/blog) and [about](/about) pages.\") // 2\n */\nexport function countInternalLinks(body: string): number {\n const pattern = /\\[([^\\]]+)\\]\\(\\/[^)]+\\)/g;\n const matches = body.match(pattern);\n return matches ? matches.length : 0;\n}\n","/**\n * GEO Advanced Analyzer\n * Complex analysis utilities for LLM citation optimization rules\n */\n\nimport { countWords, stripMarkdown } from './word-counter.js';\nimport { extractHeadings } from './heading-extractor.js';\n\n/** FAQ quality analysis result */\nexport interface FaqQualityResult {\n pairCount: number;\n questionsWithMark: number;\n answersInRange: number;\n answerWordCounts: number[];\n}\n\n/** Passive voice analysis result */\nexport interface PassiveVoiceResult {\n totalSentences: number;\n passiveSentences: number;\n passiveRatio: number;\n}\n\n/**\n * Common irregular past participles for passive voice detection\n */\nconst IRREGULAR_PAST_PARTICIPLES = new Set([\n 'written', 'known', 'made', 'done', 'seen', 'taken', 'given',\n 'found', 'built', 'shown', 'broken', 'chosen', 'driven', 'spoken',\n 'stolen', 'worn', 'torn', 'frozen', 'hidden', 'forgotten', 'risen',\n 'fallen', 'begun', 'run', 'come', 'become', 'grown', 'drawn',\n 'thrown', 'blown', 'flown', 'sworn', 'shaken', 'mistaken', 'proven', 'woven',\n]);\n\n/**\n * Forms of \"to be\" used in passive voice constructions\n */\nconst BE_FORMS = new Set(['is', 'are', 'was', 'were', 'been', 'being', 'be']);\n\n/**\n * Attribution markers that provide context for statistics\n */\nconst ATTRIBUTION_MARKERS = [\n 'according to', 'study', 'survey', 'report', 'research',\n 'source', 'data from', 'published',\n];\n\n/**\n * Pronouns/references that indicate unresolved section openings\n */\nconst UNRESOLVED_WORDS = new Set([\n 'this', 'it', 'that', 'these', 'those', 'they', 'such', 'here', 'there',\n]);\n\nconst UNRESOLVED_PHRASES = [\n 'as mentioned', 'as noted', 'as discussed', 'previously',\n];\n\n/**\n * Standard HTML tags that should be flagged when found in markdown.\n */\nconst STANDARD_HTML_TAGS = new Set([\n 'div', 'span', 'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li',\n 'table', 'tr', 'td', 'th', 'thead', 'tbody', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'img', 'hr', 'blockquote', 'pre', 'code', 'section', 'article', 'nav', 'header',\n 'footer', 'main', 'aside', 'figure', 'figcaption', 'details', 'summary',\n]);\n\n/**\n * Analyze FAQ section quality: count Q&A pairs, answer lengths, question formatting.\n *\n * @example\n * analyzeFaqQuality(\"## FAQ\\n\\n### What is SEO?\\n\\nSEO stands for...\") // { pairCount: 1, ... }\n */\nexport function analyzeFaqQuality(body: string): FaqQualityResult {\n const result: FaqQualityResult = {\n pairCount: 0,\n questionsWithMark: 0,\n answersInRange: 0,\n answerWordCounts: [],\n };\n\n // Find FAQ section start\n const faqPattern = /^#{2,3}\\s*(FAQ|H\\u00e4ufige Fragen|Frequently Asked|Fragen und Antworten)/im;\n const faqMatch = body.match(faqPattern);\n if (!faqMatch || faqMatch.index === undefined) return result;\n\n // Get content after FAQ heading until next H2 or end\n const afterFaq = body.slice(faqMatch.index + faqMatch[0].length);\n const nextH2Match = afterFaq.match(/^##\\s+(?!#)/m);\n const faqContent = nextH2Match && nextH2Match.index !== undefined\n ? afterFaq.slice(0, nextH2Match.index)\n : afterFaq;\n\n // Extract H3 headings as questions within the FAQ section\n const h3Pattern = /^###\\s+(.+)$/gm;\n const h3Matches = [...faqContent.matchAll(h3Pattern)];\n\n for (let i = 0; i < h3Matches.length; i++) {\n const questionText = h3Matches[i][1].trim();\n result.pairCount++;\n\n if (questionText.endsWith('?')) {\n result.questionsWithMark++;\n }\n\n // Extract answer: content between this H3 and the next H3 (or end of FAQ)\n const answerStart = h3Matches[i].index! + h3Matches[i][0].length;\n const answerEnd = i + 1 < h3Matches.length ? h3Matches[i + 1].index! : faqContent.length;\n const answerText = faqContent.slice(answerStart, answerEnd).trim();\n const answerWords = countWords(answerText);\n result.answerWordCounts.push(answerWords);\n\n if (answerWords >= 30 && answerWords <= 75) {\n result.answersInRange++;\n }\n }\n\n return result;\n}\n\n/**\n * German passive voice auxiliary verbs (all conjugations of \"werden\")\n */\nconst GERMAN_PASSIVE_AUXILIARIES = new Set([\n 'werde', 'wirst', 'wird', 'werden', 'werdet',\n 'wurde', 'wurdest', 'wurden', 'wurdet',\n 'worden', 'würde', 'würdest', 'würden', 'würdet',\n]);\n\n/**\n * German past participle regex patterns.\n * German participles typically follow: ge-...-t, ge-...-en, or -iert.\n * Separable prefixes (ab-, an-, auf-, etc.) insert \"ge\" after the prefix.\n * Inseparable prefixes (be-, ent-, er-, ver-, zer-, über-) have no \"ge-\".\n */\nconst GERMAN_PARTICIPLE_PATTERNS: RegExp[] = [\n /^ge\\S+t$/i, // gemacht, gesagt\n /^ge\\S+en$/i, // geschrieben, gefunden\n /^\\S+iert$/i, // organisiert, implementiert\n /^(ab|an|auf|aus|vor|wieder|zurück)ge\\S+(t|en)$/i, // aufgemacht, angenommen\n /^(be|ent|er|her|ver|zer|über)\\S+([^s]t|en)$/i, // bearbeitet, verstanden\n];\n\n/**\n * Detect passive voice sentences with locale support.\n * English: \"be\" form + past participle within 3 words.\n * German: \"werden\" conjugation + past participle within 5 words.\n *\n * @example\n * analyzePassiveVoice(\"The report was written by the team.\") // passiveRatio: 1.0\n * analyzePassiveVoice(\"Der Bericht wurde geschrieben.\", \"de\") // passiveRatio: 1.0\n */\nexport function analyzePassiveVoice(body: string, locale?: string): PassiveVoiceResult {\n const sentences = extractSentences(body);\n const lang = (locale ?? 'en').toLowerCase();\n let passiveCount = 0;\n\n for (const { text } of sentences) {\n if (lang === 'de' ? isGermanPassiveSentence(text) : isEnglishPassiveSentence(text)) {\n passiveCount++;\n }\n }\n\n const total = sentences.length;\n return {\n totalSentences: total,\n passiveSentences: passiveCount,\n passiveRatio: total > 0 ? passiveCount / total : 0,\n };\n}\n\n/**\n * Check if a single English sentence contains passive voice construction.\n * Heuristic: a form of \"be\" followed within 3 words by a past participle.\n */\nfunction isEnglishPassiveSentence(sentence: string): boolean {\n const words = sentence.toLowerCase().split(/\\s+/).filter(w => w.length > 0);\n\n for (let i = 0; i < words.length; i++) {\n const cleaned = words[i].replace(/[^a-z]/g, '');\n if (!BE_FORMS.has(cleaned)) continue;\n\n // Check next 3 words for a past participle\n const searchEnd = Math.min(i + 4, words.length);\n for (let j = i + 1; j < searchEnd; j++) {\n const candidate = words[j].replace(/[^a-z]/g, '');\n if (candidate.endsWith('ed') || IRREGULAR_PAST_PARTICIPLES.has(candidate)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Check if a single German sentence contains passive voice construction.\n * Heuristic: a \"werden\" conjugation followed within 5 words by a past participle.\n * German word order is more flexible than English, so the window is wider.\n */\nfunction isGermanPassiveSentence(sentence: string): boolean {\n const words = sentence.toLowerCase().split(/\\s+/).filter(w => w.length > 0);\n\n for (let i = 0; i < words.length; i++) {\n const cleaned = words[i].replace(/[^a-zäöüß]/g, '');\n if (!GERMAN_PASSIVE_AUXILIARIES.has(cleaned)) continue;\n\n // Check next 5 words for a German past participle\n const searchEnd = Math.min(i + 6, words.length);\n for (let j = i + 1; j < searchEnd; j++) {\n const candidate = words[j].replace(/[^a-zäöüß]/g, '');\n if (candidate.length < 3) continue;\n if (GERMAN_PARTICIPLE_PATTERNS.some(p => p.test(candidate))) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Extract sentences with word counts from stripped markdown.\n *\n * @example\n * extractSentences(\"Hello world. How are you?\")\n * // [{ text: \"Hello world\", wordCount: 2 }, { text: \"How are you\", wordCount: 3 }]\n */\nexport function extractSentences(body: string): Array<{ text: string; wordCount: number }> {\n const stripped = stripMarkdown(body);\n const rawSentences = stripped.split(/(?<=[.!?])\\s+/);\n const sentences: Array<{ text: string; wordCount: number }> = [];\n\n for (const raw of rawSentences) {\n const text = raw.trim().replace(/[.!?]+$/, '').trim();\n if (!text) continue;\n const wordCount = text.split(/\\s+/).filter(w => w.length > 0 && /\\w/.test(w)).length;\n if (wordCount > 0) {\n sentences.push({ text, wordCount });\n }\n }\n\n return sentences;\n}\n\n/**\n * Find year references in body that are stale (>18 months from currentDate).\n *\n * @example\n * findStaleYearReferences(\"In 2020, things changed.\", new Date('2025-06-01'))\n * // [{ year: 2020, line: 1, isStale: true }]\n */\nexport function findStaleYearReferences(\n body: string,\n currentDate: Date,\n): Array<{ year: number; line: number; isStale: boolean }> {\n const lines = body.split('\\n');\n const yearPattern = /\\b((?:19|20)\\d{2})\\b/g;\n const results: Array<{ year: number; line: number; isStale: boolean }> = [];\n\n const cutoffDate = new Date(currentDate);\n cutoffDate.setMonth(cutoffDate.getMonth() - 18);\n\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n yearPattern.lastIndex = 0;\n\n while ((match = yearPattern.exec(line)) !== null) {\n const year = parseInt(match[1], 10);\n const yearEnd = new Date(year, 11, 31);\n const isStale = yearEnd < cutoffDate;\n results.push({ year, line: i + 1, isStale });\n }\n }\n\n return results;\n}\n\n/**\n * Detect sections opening with unresolved pronouns or back-references.\n * Flags sections whose first word is a pronoun like \"this\", \"it\", \"that\", etc.\n *\n * @example\n * detectUnresolvedOpenings([{ heading: \"Benefits\", body: \"This is important...\" }])\n * // [{ heading: \"Benefits\", firstWord: \"this\" }]\n */\nexport function detectUnresolvedOpenings(\n sections: Array<{ heading: string; body: string }>,\n): Array<{ heading: string; firstWord: string }> {\n const flagged: Array<{ heading: string; firstWord: string }> = [];\n\n for (const section of sections) {\n const bodyTrimmed = section.body.trim();\n if (!bodyTrimmed) continue;\n\n const firstLine = bodyTrimmed.split('\\n').find(l => l.trim().length > 0);\n if (!firstLine) continue;\n\n const lineText = firstLine.trim().toLowerCase();\n\n // Check phrase matches first\n const matchedPhrase = UNRESOLVED_PHRASES.find(p => lineText.startsWith(p));\n if (matchedPhrase) {\n flagged.push({ heading: section.heading, firstWord: matchedPhrase });\n continue;\n }\n\n // Check single-word pronouns\n const firstWord = lineText.split(/\\s+/)[0]?.replace(/[^a-z]/g, '') ?? '';\n if (UNRESOLVED_WORDS.has(firstWord)) {\n flagged.push({ heading: section.heading, firstWord });\n }\n }\n\n return flagged;\n}\n\n/**\n * Find acronyms not expanded on first use (not in allowlist).\n * Searches for uppercase sequences (2+ chars) and checks if the body\n * contains a parenthetical expansion pattern like \"Full Name (ACRONYM)\".\n *\n * @example\n * findUnexpandedAcronyms(\"Use GEO to improve visibility.\", [\"URL\", \"HTML\"])\n * // [{ acronym: \"GEO\", line: 1 }]\n */\nexport function findUnexpandedAcronyms(\n body: string,\n allowlist: string[],\n): Array<{ acronym: string; line: number }> {\n const allowSet = new Set(allowlist);\n const lines = body.split('\\n');\n const acronymPattern = /\\b([A-Z]{2,})\\b/g;\n const found = new Map<string, number>();\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n acronymPattern.lastIndex = 0;\n\n while ((match = acronymPattern.exec(line)) !== null) {\n const acronym = match[1];\n if (allowSet.has(acronym)) continue;\n if (!found.has(acronym)) {\n found.set(acronym, i + 1);\n }\n }\n }\n\n const results: Array<{ acronym: string; line: number }> = [];\n\n for (const [acronym, line] of found) {\n const expansionPattern = new RegExp(`\\\\(${acronym}\\\\)`, 'i');\n if (!expansionPattern.test(body)) {\n results.push({ acronym, line });\n }\n }\n\n return results;\n}\n\n/**\n * Find statistics/numbers without source context.\n * Checks for percentages and multipliers that lack nearby attribution.\n *\n * @example\n * findContextlessStatistics(\"Revenue grew 45% last year.\")\n * // [{ statistic: \"45%\", line: 1 }]\n */\nexport function findContextlessStatistics(\n body: string,\n): Array<{ statistic: string; line: number }> {\n const lines = body.split('\\n');\n const results: Array<{ statistic: string; line: number }> = [];\n const statPatterns = [/\\d+%/g, /\\d+x\\b/gi];\n const yearPattern = /\\b(?:19|20)\\d{2}\\b/;\n const linkPattern = /\\[[^\\]]+\\]\\([^)]+\\)/;\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n for (const pattern of statPatterns) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(line)) !== null) {\n const position = match.index;\n const contextStart = Math.max(0, position - 100);\n const contextEnd = Math.min(line.length, position + match[0].length + 100);\n const surrounding = line.slice(contextStart, contextEnd).toLowerCase();\n\n const hasAttribution = ATTRIBUTION_MARKERS.some(m => surrounding.includes(m));\n const hasYear = yearPattern.test(surrounding);\n const hasLink = linkPattern.test(line.slice(contextStart, contextEnd));\n\n if (!hasAttribution && !hasYear && !hasLink) {\n results.push({ statistic: match[0], line: i + 1 });\n }\n }\n }\n }\n\n return results;\n}\n\n/**\n * Count structural elements in markdown: tables, lists, blockquotes, code blocks.\n * Returns total count of distinct structural element types found.\n *\n * @example\n * countStructuralElements(\"- item\\n\\n| col |\\n|---|\\n\\n> quote\") // 3\n */\nexport function countStructuralElements(body: string): number {\n const lines = body.split('\\n');\n let hasTable = false;\n let hasUnorderedList = false;\n let hasOrderedList = false;\n let hasBlockquote = false;\n let hasCodeBlock = false;\n let inCodeBlock = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n hasCodeBlock = true;\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n if (/\\|\\s*:?-{2,}/.test(trimmed)) hasTable = true;\n if (/^[-*]\\s+/.test(trimmed)) hasUnorderedList = true;\n if (/^\\d+\\.\\s+/.test(trimmed)) hasOrderedList = true;\n if (trimmed.startsWith('>')) hasBlockquote = true;\n }\n\n let count = 0;\n if (hasTable) count++;\n if (hasUnorderedList) count++;\n if (hasOrderedList) count++;\n if (hasBlockquote) count++;\n if (hasCodeBlock) count++;\n\n return count;\n}\n\n/**\n * Find raw HTML tags in markdown (excluding allowed MDX component tags).\n * MDX components are PascalCase; standard HTML tags (div, span, etc.) are flagged.\n *\n * @example\n * findInlineHtml(\"<div>text</div>\", [\"CustomComponent\"])\n * // [{ tag: \"div\", line: 1 }]\n */\nexport function findInlineHtml(\n body: string,\n allowedTags: string[],\n): Array<{ tag: string; line: number }> {\n const allowedSet = new Set(allowedTags);\n const lines = body.split('\\n');\n const results: Array<{ tag: string; line: number }> = [];\n const tagPattern = /<\\/?([a-zA-Z][a-zA-Z0-9]*)[^>]*>/g;\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n tagPattern.lastIndex = 0;\n\n while ((match = tagPattern.exec(line)) !== null) {\n const tagName = match[1];\n\n // Skip allowed tags (case-sensitive for MDX components)\n if (allowedSet.has(tagName)) continue;\n\n // Flag standard HTML tags (lowercase)\n if (STANDARD_HTML_TAGS.has(tagName.toLowerCase()) && tagName === tagName.toLowerCase()) {\n results.push({ tag: tagName, line: i + 1 });\n }\n }\n }\n\n return results;\n}\n\n/**\n * Analyze heading density -- find gaps > 300 words without a heading.\n * Returns gaps where the word count between consecutive headings exceeds 300.\n *\n * @example\n * analyzeHeadingDensity(\"## Intro\\n\\n\" + \"word \".repeat(350) + \"\\n\\n## Next\")\n * // { gaps: [{ afterHeading: \"Intro\", wordCount: 350, line: 1 }] }\n */\nexport function analyzeHeadingDensity(\n body: string,\n): { gaps: Array<{ afterHeading: string; wordCount: number; line: number }> } {\n const headings = extractHeadings(body);\n const lines = body.split('\\n');\n const gaps: Array<{ afterHeading: string; wordCount: number; line: number }> = [];\n\n if (headings.length === 0) {\n const totalWords = countWords(body);\n if (totalWords > 300) {\n gaps.push({ afterHeading: '(start)', wordCount: totalWords, line: 1 });\n }\n return { gaps };\n }\n\n // Check content before first heading\n const beforeFirst = lines.slice(0, headings[0].line - 1).join('\\n');\n const beforeWords = countWords(beforeFirst);\n if (beforeWords > 300) {\n gaps.push({ afterHeading: '(start)', wordCount: beforeWords, line: 1 });\n }\n\n // Check content between each heading pair\n for (let i = 0; i < headings.length; i++) {\n const currentLine = headings[i].line; // 1-indexed\n const nextLine = i + 1 < headings.length ? headings[i + 1].line : lines.length + 1;\n\n const sectionLines = lines.slice(currentLine, nextLine - 1);\n const sectionText = sectionLines.join('\\n');\n const wordCount = countWords(sectionText);\n\n if (wordCount > 300) {\n gaps.push({\n afterHeading: headings[i].text,\n wordCount,\n line: headings[i].line,\n });\n }\n }\n\n return { gaps };\n}\n","/**\n * Schema Rules\n * Validates structured data (schema.org) readiness for content frontmatter\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { hasFAQSection, hasMarkdownTable } from '../utils/geo-analyzer.js';\nimport { analyzeFaqQuality } from '../utils/geo-advanced-analyzer.js';\n\nconst MIN_FAQ_PAIRS_FOR_SCHEMA = 3;\nconst MIN_DATASET_DESCRIPTION_LENGTH = 100;\n\n/**\n * Rule: Blog posts should have fields required for rich BlogPosting schema\n * Checks for date, author, updatedAt, and image\n */\nexport const blogMissingSchemaFields: Rule = {\n name: 'blog-missing-schema-fields',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add date, author, updatedAt, and image fields to frontmatter for complete schema.org data',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') return [];\n\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'blog-missing-schema-fields';\n\n if (!item.date) {\n results.push({\n file, field: 'date', rule, severity: 'warning',\n message: 'Missing date — BlogPosting schema datePublished will be empty',\n suggestion: 'Add a date field (ISO format) for schema.org datePublished.',\n });\n }\n\n if (!item.author) {\n results.push({\n file, field: 'author', rule, severity: 'warning',\n message: 'Missing author — BlogPosting schema author will be empty',\n suggestion: 'Add an author field for complete Article/BlogPosting structured data.',\n });\n }\n\n if (!item.updatedAt) {\n results.push({\n file, field: 'updatedAt', rule, severity: 'warning',\n message: 'Missing updatedAt — BlogPosting schema dateModified will fall back to datePublished',\n suggestion: 'Add updatedAt field to frontmatter for accurate schema.org dateModified.',\n });\n }\n\n if (!item.image || item.image.trim().length === 0) {\n results.push({\n file, field: 'image', rule, severity: 'warning',\n message: 'Missing featured image — BlogPosting schema image will be empty',\n suggestion: 'Add an image field for complete BlogPosting structured data.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Content with FAQ sections should meet FAQPage schema requirements\n * Validates structure is sufficient for schema.org FAQPage emission\n */\nexport const faqpageSchemaReadiness: Rule = {\n name: 'faqpage-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add at least 3 Q&A pairs with question marks to the FAQ section',\n run: (item: ContentItem): LintResult[] => {\n if (!hasFAQSection(item.body)) return [];\n\n const faq = analyzeFaqQuality(item.body);\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'faqpage-schema-readiness';\n\n if (faq.pairCount < MIN_FAQ_PAIRS_FOR_SCHEMA) {\n results.push({\n file, field: 'body', rule, severity: 'warning',\n message: `FAQ section has ${faq.pairCount} Q&A pairs — FAQPage schema needs at least ${MIN_FAQ_PAIRS_FOR_SCHEMA}`,\n suggestion: `Add more Q&A pairs (H3 headings with answers) to enable FAQPage structured data.`,\n });\n }\n\n if (faq.pairCount > 0 && faq.questionsWithMark < faq.pairCount) {\n results.push({\n file, field: 'body', rule, severity: 'warning',\n message: `${faq.pairCount - faq.questionsWithMark}/${faq.pairCount} FAQ headings lack question marks — FAQPage schema expects questions`,\n suggestion: 'End all FAQ headings with a question mark for valid FAQPage structured data.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Content should have category data for BreadcrumbList schema\n * Checks that categories or category is populated for breadcrumb generation\n */\nexport const breadcrumblistSchemaReadiness: Rule = {\n name: 'breadcrumblist-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a categories array or category field to frontmatter for breadcrumb navigation',\n run: (item: ContentItem): LintResult[] => {\n const hasCategories = item.categories && item.categories.length > 0;\n const hasCategory = !!item.category;\n\n if (!hasCategories && !hasCategory) {\n return [{\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'breadcrumblist-schema-readiness',\n severity: 'warning',\n message: 'No category data — BreadcrumbList schema will lack breadcrumb path',\n suggestion: 'Add a categories array or category field for BreadcrumbList structured data.',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Data-heavy content with tables should have fields for Dataset schema\n * Only fires on project/page content that contains markdown tables\n */\nexport const datasetSchemaReadiness: Rule = {\n name: 'dataset-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a detailed description (100+ chars) and date field for Dataset schema readiness',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'blog') return [];\n if (!hasMarkdownTable(item.body)) return [];\n\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'dataset-schema-readiness';\n\n if (item.description.length < MIN_DATASET_DESCRIPTION_LENGTH) {\n results.push({\n file, field: 'description', rule, severity: 'warning',\n message: `Description is too short for Dataset schema (${item.description.length}/${MIN_DATASET_DESCRIPTION_LENGTH} chars)`,\n suggestion: `Expand description to at least ${MIN_DATASET_DESCRIPTION_LENGTH} characters for rich Dataset structured data.`,\n });\n }\n\n if (!item.date) {\n results.push({\n file, field: 'date', rule, severity: 'warning',\n message: 'Missing date — Dataset schema dateModified will be empty',\n suggestion: 'Add a date field for Dataset schema temporal metadata.',\n });\n }\n\n return results;\n },\n};\n\nconst MIN_SAMEAS_ENTRIES = 2;\n\n/**\n * Rule: Organization schema sameAs array should have 2+ entries\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createSchemaSameAsRule(\n organizationSameAs: string[] | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'seo-schema-sameas-incomplete',\n severity: 'warning',\n category: 'seo',\n fixStrategy:\n 'Add social profiles (LinkedIn, GitHub, Twitter), Wikidata QID, and Crunchbase URL to Organization schema sameAs array',\n run: (_item: ContentItem): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // Not configured = skip (user hasn't declared sameAs)\n if (!organizationSameAs || organizationSameAs.length === 0) return [];\n\n if (organizationSameAs.length < MIN_SAMEAS_ENTRIES) {\n return [\n {\n file: '_site',\n field: 'schema',\n rule: 'seo-schema-sameas-incomplete',\n severity: 'warning',\n message: `Organization sameAs has ${organizationSameAs.length} entry — include at least ${MIN_SAMEAS_ENTRIES} for entity verification`,\n suggestion:\n 'AI models use sameAs to verify entity identity. Include at least LinkedIn + one other profile (GitHub, Wikidata QID, Crunchbase).',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/**\n * Rule: Service pages should have Service structured data\n * Checks if page URL matches a service page pattern and flags it for schema markup\n */\nexport function createServicePageSchemaRule(\n servicePagePatterns: string[] | undefined\n): Rule {\n return {\n name: 'seo-service-page-no-schema',\n severity: 'warning',\n category: 'seo',\n fixStrategy:\n 'Add Service structured data (JSON-LD) to service pages with name, description, provider, and areaServed.',\n run: (item: ContentItem): LintResult[] => {\n if (!servicePagePatterns || servicePagePatterns.length === 0) return [];\n\n const matchesPattern = servicePagePatterns.some((pattern) =>\n item.permalink.includes(pattern)\n );\n\n if (!matchesPattern) return [];\n\n return [\n {\n file: getDisplayPath(item),\n field: 'schema',\n rule: 'seo-service-page-no-schema',\n severity: 'warning',\n message: `Service page \"${item.permalink}\" should have Service structured data`,\n suggestion:\n 'Service pages need schema markup to appear in AI answers for \"[service] provider in [city]\" queries. Add Service JSON-LD with name, description, provider, and areaServed.',\n },\n ];\n },\n };\n}\n\n/** Static schema rules (no config dependency) */\nexport const schemaStaticRules: Rule[] = [\n blogMissingSchemaFields,\n faqpageSchemaReadiness,\n breadcrumblistSchemaReadiness,\n datasetSchemaReadiness,\n];\n\n/** Build the complete schema rule set from config */\nexport function createSchemaRules(geo: GeoConfig): Rule[] {\n return [\n ...schemaStaticRules,\n createSchemaSameAsRule(geo.organizationSameAs),\n createServicePageSchemaRule(geo.servicePagePatterns),\n ];\n}\n\n// Keep backward-compatible export\nexport const schemaRules = schemaStaticRules;\n","/**\n * Keyword Coherence Rules\n * Validates that title keywords appear in description and headings\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport { countWords } from '../utils/word-counter.js';\n\n/** Keyword coherence thresholds */\nconst MIN_SIGNIFICANT_WORDS = 2;\nconst MIN_WORD_LENGTH = 3;\nconst MIN_CONTENT_WORDS = 300;\n\n/**\n * Combined DE + EN stopwords (articles, prepositions, conjunctions, pronouns)\n * These are filtered out when extracting significant keywords from titles\n */\nconst STOPWORDS = new Set([\n // German\n 'der', 'die', 'das', 'ein', 'eine', 'einer', 'eines', 'einem', 'einen',\n 'und', 'oder', 'aber', 'als', 'auch', 'auf', 'aus', 'bei', 'bis',\n 'für', 'mit', 'nach', 'über', 'von', 'vor', 'wie', 'zum', 'zur',\n 'den', 'dem', 'des', 'ist', 'sind', 'war', 'hat', 'ihr', 'wir',\n 'sie', 'ich', 'nicht', 'sich', 'man', 'nur', 'noch', 'mehr',\n // English\n 'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can',\n 'her', 'was', 'one', 'our', 'out', 'has', 'had', 'its', 'his',\n 'how', 'who', 'what', 'why', 'when', 'where', 'which', 'with',\n 'this', 'that', 'from', 'they', 'been', 'have', 'will', 'your',\n 'into', 'than', 'them', 'then', 'some', 'each', 'make',\n]);\n\n/**\n * Extract significant words from text\n * Filters out stopwords and short words, normalizes to lowercase\n */\nfunction extractSignificantWords(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(word =>\n word.length >= MIN_WORD_LENGTH && !STOPWORDS.has(word)\n );\n}\n\n/**\n * Check if any keyword appears in a target text (case-insensitive)\n */\nfunction findMatchingKeywords(keywords: string[], targetText: string): string[] {\n const normalizedTarget = targetText.toLowerCase();\n return keywords.filter(keyword => normalizedTarget.includes(keyword));\n}\n\n/**\n * Rule: At least one title keyword should appear in the meta description\n * Improves click-through rate by ensuring title/description alignment\n */\nexport const keywordNotInDescription: Rule = {\n name: 'keyword-not-in-description',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Include at least one title keyword in the meta description',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || !item.description) return [];\n\n const keywords = extractSignificantWords(item.title);\n if (keywords.length < MIN_SIGNIFICANT_WORDS) return [];\n\n const matches = findMatchingKeywords(keywords, item.description);\n if (matches.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'keyword-not-in-description',\n severity: 'warning',\n message: `Description contains none of the title keywords: ${keywords.join(', ')}`,\n suggestion: 'Include at least one keyword from the title in the meta description for better SEO coherence',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: At least one title keyword should appear in H2/H3 headings\n * Only applies to blog/project content with sufficient length\n */\nexport const keywordNotInHeadings: Rule = {\n name: 'keyword-not-in-headings',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Include at least one title keyword in subheadings',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog' && item.contentType !== 'project') return [];\n if (!item.title || !item.body) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < MIN_CONTENT_WORDS) return [];\n\n const keywords = extractSignificantWords(item.title);\n if (keywords.length < MIN_SIGNIFICANT_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n if (subHeadings.length === 0) return [];\n\n const allHeadingText = subHeadings.map(h => h.text).join(' ');\n const matches = findMatchingKeywords(keywords, allHeadingText);\n\n if (matches.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'keyword-not-in-headings',\n severity: 'warning',\n message: `No title keywords found in H2/H3 headings: ${keywords.join(', ')}`,\n suggestion: 'Include at least one title keyword in your subheadings to reinforce topical relevance',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title and description must share at least one significant word\n * Catches completely disconnected metadata that confuses search engines\n */\nexport const titleDescriptionNoOverlap: Rule = {\n name: 'title-description-no-overlap',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Ensure title and description share at least one keyword',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || !item.description) return [];\n\n const titleWords = extractSignificantWords(item.title);\n const descWords = new Set(extractSignificantWords(item.description));\n\n if (titleWords.length < MIN_SIGNIFICANT_WORDS) return [];\n if (descWords.size < MIN_SIGNIFICANT_WORDS) return [];\n\n const overlap = titleWords.filter(word => descWords.has(word));\n if (overlap.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'title-description-no-overlap',\n severity: 'warning',\n message: 'Title and description share no significant words',\n suggestion: 'Title and description should be thematically connected. Ensure they share at least one keyword.',\n }];\n }\n return [];\n },\n};\n\n/**\n * All keyword coherence rules\n */\nexport const keywordCoherenceRules: Rule[] = [\n keywordNotInDescription,\n keywordNotInHeadings,\n titleDescriptionNoOverlap,\n];\n","/**\n * Link Validation Rules\n * Validates internal links resolve to existing pages\n *\n * These rules require a LinkExtractor instance (created per-project\n * with the site's internal URL patterns). Use the createLinkRules()\n * factory to build the rule set.\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { isValidInternalLink } from '../utils/slug-resolver.js';\n\n/**\n * Factory: Create link validation rules that use the provided LinkExtractor\n */\nexport function createLinkRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks, getInternalLinks, isAbsoluteInternalLink } = linkExtractor;\n\n /**\n * Rule: Internal links must resolve to existing pages\n */\n const brokenInternalLink: Rule = {\n name: 'broken-internal-link',\n severity: 'error',\n category: 'technical',\n fixStrategy: 'Fix the link target to point to an existing page',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n if (!isValidInternalLink(link.url, context.validSlugs)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'broken-internal-link',\n severity: 'error',\n message: `Broken internal link: ${link.url}`,\n suggestion: `Link \"${link.originalUrl}\" does not resolve to any known page`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links should use relative paths instead of absolute URLs\n */\n const absoluteInternalLink: Rule = {\n name: 'absolute-internal-link',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Use a relative path instead of an absolute URL',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal && isAbsoluteInternalLink(link.originalUrl)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'absolute-internal-link',\n severity: 'warning',\n message: `Absolute internal URL: ${link.originalUrl}`,\n suggestion: `Use relative path \"${link.url}\" instead for better portability`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links must not point to draft or noindex pages\n * Prevents publishing content that links to hidden pages\n */\n const draftLinkLeak: Rule = {\n name: 'draft-link-leak',\n severity: 'error',\n category: 'technical',\n fixStrategy: 'Remove or update link — the target page is not publicly visible',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n // Skip draft/noindex items — they aren't publicly visible\n if (item.draft || item.noindex) {\n return [];\n }\n\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n // Build set of permalinks for draft/noindex content\n const draftPermalinks = new Set<string>(\n context.allContent\n .filter(c => c.draft === true || c.noindex === true)\n .map(c => c.permalink)\n );\n\n for (const link of internalLinks) {\n if (draftPermalinks.has(link.url)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'draft-link-leak',\n severity: 'error',\n message: `Internal link points to draft/noindex page: ${link.url}`,\n suggestion: `Remove or update link \"${link.originalUrl}\" — the target page is not publicly visible`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links should not have trailing slashes\n * Ensures consistent URL formatting across the site\n */\n const trailingSlashInconsistency: Rule = {\n name: 'trailing-slash-inconsistency',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Remove the trailing slash from the internal link',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n // Check original URL (before normalization) for trailing slash\n // Skip root \"/\" which is fine\n const originalPath = link.originalUrl.split('?')[0].split('#')[0];\n if (originalPath !== '/' && originalPath.endsWith('/')) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'trailing-slash-inconsistency',\n severity: 'warning',\n message: `Internal link has trailing slash: ${link.originalUrl}`,\n suggestion: `Remove trailing slash: \"${originalPath.slice(0, -1)}\"`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n return [\n brokenInternalLink,\n absoluteInternalLink,\n draftLinkLeak,\n trailingSlashInconsistency,\n ];\n}\n","/**\n * External Link Validation Rules\n * Validates external URLs for correctness, security, and density\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\n\n/**\n * Outbound link density thresholds.\n * Minimum external links required scales with word count.\n */\nconst OUTBOUND_MIN_BASE = 3;\nconst OUTBOUND_WORDS_PER_EXTRA_LINK = 500;\nconst OUTBOUND_MIN_WORDS_TO_APPLY = 300;\n\n/**\n * Factory: Create external link validation rules that use the provided LinkExtractor\n */\nexport function createExternalLinkRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks } = linkExtractor;\n\n /**\n * Rule: External links must be well-formed URLs\n * Catches typos and malformed URLs before they reach production\n */\n const externalLinkMalformed: Rule = {\n name: 'external-link-malformed',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Check the URL for typos or missing protocol (https://)',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal) {\n continue;\n }\n\n try {\n new URL(link.url);\n } catch {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-malformed',\n severity: 'warning',\n message: `Malformed external URL: ${link.url}`,\n suggestion: 'Check the URL for typos or missing protocol (https://)',\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: External links should use HTTPS instead of HTTP\n * HTTP links are insecure and may trigger browser warnings\n */\n const externalLinkHttp: Rule = {\n name: 'external-link-http',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Replace http:// with https://',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal) {\n continue;\n }\n\n // Check for http:// but exclude localhost for development links\n if (link.url.startsWith('http://') && !link.url.startsWith('http://localhost')) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-http',\n severity: 'warning',\n message: `Insecure HTTP link: ${link.url}`,\n suggestion: `Use HTTPS instead: \"${link.url.replace('http://', 'https://')}\"`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Content should include enough outbound links to cite sources.\n * Minimum scales with article length: 3 for short articles,\n * +1 for every additional 500 words.\n */\n const externalLinkMinDensity: Rule = {\n name: 'external-link-low-density',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add outbound links to cite sources, reference tools, or link to studies',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') {\n return [];\n }\n\n const wordCount = countWords(item.body);\n if (wordCount < OUTBOUND_MIN_WORDS_TO_APPLY) {\n return [];\n }\n\n const links = extractLinks(item.body);\n const externalLinks = links.filter(link => !link.isInternal);\n const externalCount = externalLinks.length;\n\n const extraLinks = Math.max(\n 0,\n Math.floor((wordCount - OUTBOUND_MIN_WORDS_TO_APPLY) / OUTBOUND_WORDS_PER_EXTRA_LINK)\n );\n const requiredMin = OUTBOUND_MIN_BASE + extraLinks;\n\n if (externalCount < requiredMin) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-low-density',\n severity: 'warning',\n message: `Only ${externalCount} outbound link(s) for ${wordCount} words (minimum: ${requiredMin})`,\n suggestion: `Add ${requiredMin - externalCount} more outbound link(s) to cite sources, reference tools, or link to studies that support your claims.`,\n }];\n }\n\n return [];\n },\n };\n\n return [\n externalLinkMalformed,\n externalLinkHttp,\n externalLinkMinDensity,\n ];\n}\n","/**\n * Orphan Content Detection Rules\n * Identifies content that is not linked from any other page\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Normalize a permalink for comparison by removing trailing slashes\n */\nfunction normalizePermalink(permalink: string): string {\n if (permalink.length > 1 && permalink.endsWith('/')) {\n return permalink.slice(0, -1);\n }\n return permalink;\n}\n\n/**\n * Factory: Create orphan content detection rules that use the provided LinkExtractor\n */\nexport function createOrphanRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks, getInternalLinks } = linkExtractor;\n\n /**\n * Rule: Blog and project content should be linked from at least one other page\n * Orphan pages are hard to discover and receive less search engine traffic\n */\n const orphanContent: Rule = {\n name: 'orphan-content',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an internal link to this page from a related page',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n // Only check blog posts and projects\n if (item.contentType !== 'blog' && item.contentType !== 'project') {\n return [];\n }\n\n // Skip drafts and noindex content\n if (item.draft || item.noindex) {\n return [];\n }\n\n const itemPermalink = normalizePermalink(item.permalink);\n\n // Check if any other content item links to this item\n for (const other of context.allContent) {\n // Skip self\n if (other.slug === item.slug && other.contentType === item.contentType) {\n continue;\n }\n\n const links = extractLinks(other.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n const normalizedLink = normalizePermalink(link.url);\n if (normalizedLink === itemPermalink) {\n // Found a link to this item — not orphaned\n return [];\n }\n }\n }\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'orphan-content',\n severity: 'warning',\n message: `No other content links to this ${item.contentType} post`,\n suggestion: `Add an internal link to \"${item.permalink}\" from a related page to improve discoverability`,\n }];\n },\n };\n\n return [orphanContent];\n}\n","/**\n * Top 5,000 most common English words\n * Source: google-10000-english (first20hours/google-10000-english)\n * Used for word complexity analysis — common words are not flagged as jargon.\n */\nexport const FREQUENCY_EN: ReadonlySet<string> = new Set([\n 'the', 'of', 'and', 'to', 'a', 'in', 'for', 'is', 'on', 'that', 'by', 'this', 'with', 'i', 'you', 'it', 'not', 'or', 'be', 'are', 'from', 'at', 'as', 'your', 'all', 'have', 'new', 'more', 'an', 'was', 'we', 'will', 'home', 'can', 'us', 'about', 'if', 'page', 'my', 'has',\n 'search', 'free', 'but', 'our', 'one', 'other', 'do', 'no', 'information', 'time', 'they', 'site', 'he', 'up', 'may', 'what', 'which', 'their', 'news', 'out', 'use', 'any', 'there', 'see', 'only', 'so', 'his', 'when', 'contact', 'here', 'business', 'who', 'web', 'also', 'now', 'help', 'get', 'pm', 'view', 'online',\n 'c', 'e', 'first', 'am', 'been', 'would', 'how', 'were', 'me', 's', 'services', 'some', 'these', 'click', 'its', 'like', 'service', 'x', 'than', 'find', 'price', 'date', 'back', 'top', 'people', 'had', 'list', 'name', 'just', 'over', 'state', 'year', 'day', 'into', 'email', 'two', 'health', 'n', 'world', 're',\n 'next', 'used', 'go', 'b', 'work', 'last', 'most', 'products', 'music', 'buy', 'data', 'make', 'them', 'should', 'product', 'system', 'post', 'her', 'city', 't', 'add', 'policy', 'number', 'such', 'please', 'available', 'copyright', 'support', 'message', 'after', 'best', 'software', 'then', 'jan', 'good', 'video', 'well', 'd', 'where', 'info',\n 'rights', 'public', 'books', 'high', 'school', 'through', 'm', 'each', 'links', 'she', 'review', 'years', 'order', 'very', 'privacy', 'book', 'items', 'company', 'r', 'read', 'group', 'need', 'many', 'user', 'said', 'de', 'does', 'set', 'under', 'general', 'research', 'university', 'january', 'mail', 'full', 'map', 'reviews', 'program', 'life', 'know',\n 'games', 'way', 'days', 'management', 'p', 'part', 'could', 'great', 'united', 'hotel', 'real', 'f', 'item', 'international', 'center', 'ebay', 'must', 'store', 'travel', 'comments', 'made', 'development', 'report', 'off', 'member', 'details', 'line', 'terms', 'before', 'hotels', 'did', 'send', 'right', 'type', 'because', 'local', 'those', 'using', 'results', 'office',\n 'education', 'national', 'car', 'design', 'take', 'posted', 'internet', 'address', 'community', 'within', 'states', 'area', 'want', 'phone', 'dvd', 'shipping', 'reserved', 'subject', 'between', 'forum', 'family', 'l', 'long', 'based', 'w', 'code', 'show', 'o', 'even', 'black', 'check', 'special', 'prices', 'website', 'index', 'being', 'women', 'much', 'sign', 'file',\n 'link', 'open', 'today', 'technology', 'south', 'case', 'project', 'same', 'pages', 'uk', 'version', 'section', 'own', 'found', 'sports', 'house', 'related', 'security', 'both', 'g', 'county', 'american', 'photo', 'game', 'members', 'power', 'while', 'care', 'network', 'down', 'computer', 'systems', 'three', 'total', 'place', 'end', 'following', 'download', 'h', 'him',\n 'without', 'per', 'access', 'think', 'north', 'resources', 'current', 'posts', 'big', 'media', 'law', 'control', 'water', 'history', 'pictures', 'size', 'art', 'personal', 'since', 'including', 'guide', 'shop', 'directory', 'board', 'location', 'change', 'white', 'text', 'small', 'rating', 'rate', 'government', 'children', 'during', 'usa', 'return', 'students', 'v', 'shopping', 'account',\n 'times', 'sites', 'level', 'digital', 'profile', 'previous', 'form', 'events', 'love', 'old', 'john', 'main', 'call', 'hours', 'image', 'department', 'title', 'description', 'non', 'k', 'y', 'insurance', 'another', 'why', 'shall', 'property', 'class', 'cd', 'still', 'money', 'quality', 'every', 'listing', 'content', 'country', 'private', 'little', 'visit', 'save', 'tools',\n 'low', 'reply', 'customer', 'december', 'compare', 'movies', 'include', 'college', 'value', 'article', 'york', 'man', 'card', 'jobs', 'provide', 'j', 'food', 'source', 'author', 'different', 'press', 'u', 'learn', 'sale', 'around', 'print', 'course', 'job', 'canada', 'process', 'teen', 'room', 'stock', 'training', 'too', 'credit', 'point', 'join', 'science', 'men',\n 'categories', 'advanced', 'west', 'sales', 'look', 'english', 'left', 'team', 'estate', 'box', 'conditions', 'select', 'windows', 'photos', 'gay', 'thread', 'week', 'category', 'note', 'live', 'large', 'gallery', 'table', 'register', 'however', 'june', 'october', 'november', 'market', 'library', 'really', 'action', 'start', 'series', 'model', 'features', 'air', 'industry', 'plan', 'human',\n 'provided', 'tv', 'yes', 'required', 'second', 'hot', 'accessories', 'cost', 'movie', 'forums', 'march', 'la', 'september', 'better', 'say', 'questions', 'july', 'yahoo', 'going', 'medical', 'test', 'friend', 'come', 'dec', 'server', 'pc', 'study', 'application', 'cart', 'staff', 'articles', 'san', 'feedback', 'again', 'play', 'looking', 'issues', 'april', 'never', 'users',\n 'complete', 'street', 'topic', 'comment', 'financial', 'things', 'working', 'against', 'standard', 'tax', 'person', 'below', 'mobile', 'less', 'got', 'blog', 'party', 'payment', 'equipment', 'login', 'student', 'let', 'programs', 'offers', 'legal', 'above', 'recent', 'park', 'stores', 'side', 'act', 'problem', 'red', 'give', 'memory', 'performance', 'social', 'q', 'august', 'quote',\n 'language', 'story', 'sell', 'options', 'experience', 'rates', 'create', 'key', 'body', 'young', 'america', 'important', 'field', 'few', 'east', 'paper', 'single', 'ii', 'age', 'activities', 'club', 'example', 'girls', 'additional', 'password', 'z', 'latest', 'something', 'road', 'gift', 'question', 'changes', 'night', 'ca', 'hard', 'texas', 'oct', 'pay', 'four', 'poker',\n 'status', 'browse', 'issue', 'range', 'building', 'seller', 'court', 'february', 'always', 'result', 'audio', 'light', 'write', 'war', 'nov', 'offer', 'blue', 'groups', 'al', 'easy', 'given', 'files', 'event', 'release', 'analysis', 'request', 'fax', 'china', 'making', 'picture', 'needs', 'possible', 'might', 'professional', 'yet', 'month', 'major', 'star', 'areas', 'future',\n 'space', 'committee', 'hand', 'sun', 'cards', 'problems', 'london', 'washington', 'meeting', 'rss', 'become', 'interest', 'id', 'child', 'keep', 'enter', 'california', 'share', 'similar', 'garden', 'schools', 'million', 'added', 'reference', 'companies', 'listed', 'baby', 'learning', 'energy', 'run', 'delivery', 'net', 'popular', 'term', 'film', 'stories', 'put', 'computers', 'journal', 'reports',\n 'co', 'try', 'welcome', 'central', 'images', 'president', 'notice', 'original', 'head', 'radio', 'until', 'cell', 'color', 'self', 'council', 'away', 'includes', 'track', 'australia', 'discussion', 'archive', 'once', 'others', 'entertainment', 'agreement', 'format', 'least', 'society', 'months', 'log', 'safety', 'friends', 'sure', 'faq', 'trade', 'edition', 'cars', 'messages', 'marketing', 'tell',\n 'further', 'updated', 'association', 'able', 'having', 'provides', 'david', 'fun', 'already', 'green', 'studies', 'close', 'common', 'drive', 'specific', 'several', 'gold', 'feb', 'living', 'sep', 'collection', 'called', 'short', 'arts', 'lot', 'ask', 'display', 'limited', 'powered', 'solutions', 'means', 'director', 'daily', 'beach', 'past', 'natural', 'whether', 'due', 'et', 'electronics',\n 'five', 'upon', 'period', 'planning', 'database', 'says', 'official', 'weather', 'mar', 'land', 'average', 'done', 'technical', 'window', 'france', 'pro', 'region', 'island', 'record', 'direct', 'microsoft', 'conference', 'environment', 'records', 'st', 'district', 'calendar', 'costs', 'style', 'url', 'front', 'statement', 'update', 'parts', 'aug', 'ever', 'downloads', 'early', 'miles', 'sound',\n 'resource', 'present', 'applications', 'either', 'ago', 'document', 'word', 'works', 'material', 'bill', 'apr', 'written', 'talk', 'federal', 'hosting', 'rules', 'final', 'adult', 'tickets', 'thing', 'centre', 'requirements', 'via', 'cheap', 'kids', 'finance', 'true', 'minutes', 'else', 'mark', 'third', 'rock', 'gifts', 'europe', 'reading', 'topics', 'bad', 'individual', 'tips', 'plus',\n 'auto', 'cover', 'usually', 'edit', 'together', 'videos', 'percent', 'fast', 'function', 'fact', 'unit', 'getting', 'global', 'tech', 'meet', 'far', 'economic', 'en', 'player', 'projects', 'lyrics', 'often', 'subscribe', 'submit', 'germany', 'amount', 'watch', 'included', 'feel', 'though', 'bank', 'risk', 'thanks', 'everything', 'deals', 'various', 'words', 'linux', 'jul', 'production',\n 'commercial', 'james', 'weight', 'town', 'heart', 'advertising', 'received', 'choose', 'treatment', 'newsletter', 'archives', 'points', 'knowledge', 'magazine', 'error', 'camera', 'jun', 'girl', 'currently', 'construction', 'toys', 'registered', 'clear', 'golf', 'receive', 'domain', 'methods', 'chapter', 'makes', 'protection', 'policies', 'loan', 'wide', 'beauty', 'manager', 'india', 'position', 'taken', 'sort', 'listings',\n 'models', 'michael', 'known', 'half', 'cases', 'step', 'engineering', 'florida', 'simple', 'quick', 'none', 'wireless', 'license', 'paul', 'friday', 'lake', 'whole', 'annual', 'published', 'later', 'basic', 'sony', 'shows', 'corporate', 'google', 'church', 'method', 'purchase', 'customers', 'active', 'response', 'practice', 'hardware', 'figure', 'materials', 'fire', 'holiday', 'chat', 'enough', 'designed',\n 'along', 'among', 'death', 'writing', 'speed', 'html', 'countries', 'loss', 'face', 'brand', 'discount', 'higher', 'effects', 'created', 'remember', 'standards', 'oil', 'bit', 'yellow', 'political', 'increase', 'advertise', 'kingdom', 'base', 'near', 'environmental', 'thought', 'stuff', 'french', 'storage', 'oh', 'japan', 'doing', 'loans', 'shoes', 'entry', 'stay', 'nature', 'orders', 'availability',\n 'africa', 'summary', 'turn', 'mean', 'growth', 'notes', 'agency', 'king', 'monday', 'european', 'activity', 'copy', 'although', 'drug', 'pics', 'western', 'income', 'force', 'cash', 'employment', 'overall', 'bay', 'river', 'commission', 'ad', 'package', 'contents', 'seen', 'players', 'engine', 'port', 'album', 'regional', 'stop', 'supplies', 'started', 'administration', 'bar', 'institute', 'views',\n 'plans', 'double', 'dog', 'build', 'screen', 'exchange', 'types', 'soon', 'sponsored', 'lines', 'electronic', 'continue', 'across', 'benefits', 'needed', 'season', 'apply', 'someone', 'held', 'ny', 'anything', 'printer', 'condition', 'effective', 'believe', 'organization', 'effect', 'asked', 'eur', 'mind', 'sunday', 'selection', 'casino', 'pdf', 'lost', 'tour', 'menu', 'volume', 'cross', 'anyone',\n 'mortgage', 'hope', 'silver', 'corporation', 'wish', 'inside', 'solution', 'mature', 'role', 'rather', 'weeks', 'addition', 'came', 'supply', 'nothing', 'certain', 'usr', 'executive', 'running', 'lower', 'necessary', 'union', 'jewelry', 'according', 'dc', 'clothing', 'mon', 'com', 'particular', 'fine', 'names', 'robert', 'homepage', 'hour', 'gas', 'skills', 'six', 'bush', 'islands', 'advice',\n 'career', 'military', 'rental', 'decision', 'leave', 'british', 'teens', 'pre', 'huge', 'sat', 'woman', 'facilities', 'zip', 'bid', 'kind', 'sellers', 'middle', 'move', 'cable', 'opportunities', 'taking', 'values', 'division', 'coming', 'tuesday', 'object', 'lesbian', 'appropriate', 'machine', 'logo', 'length', 'actually', 'nice', 'score', 'statistics', 'client', 'ok', 'returns', 'capital', 'follow',\n 'sample', 'investment', 'sent', 'shown', 'saturday', 'christmas', 'england', 'culture', 'band', 'flash', 'ms', 'lead', 'george', 'choice', 'went', 'starting', 'registration', 'fri', 'thursday', 'courses', 'consumer', 'hi', 'airport', 'foreign', 'artist', 'outside', 'furniture', 'levels', 'channel', 'letter', 'mode', 'phones', 'ideas', 'wednesday', 'structure', 'fund', 'summer', 'allow', 'degree', 'contract',\n 'button', 'releases', 'wed', 'homes', 'super', 'male', 'matter', 'custom', 'virginia', 'almost', 'took', 'located', 'multiple', 'asian', 'distribution', 'editor', 'inn', 'industrial', 'cause', 'potential', 'song', 'cnet', 'ltd', 'los', 'hp', 'focus', 'late', 'fall', 'featured', 'idea', 'rooms', 'female', 'responsible', 'inc', 'communications', 'win', 'associated', 'thomas', 'primary', 'cancer',\n 'numbers', 'reason', 'tool', 'browser', 'spring', 'foundation', 'answer', 'voice', 'eg', 'friendly', 'schedule', 'documents', 'communication', 'purpose', 'feature', 'bed', 'comes', 'police', 'everyone', 'independent', 'ip', 'approach', 'cameras', 'brown', 'physical', 'operating', 'hill', 'maps', 'medicine', 'deal', 'hold', 'ratings', 'chicago', 'forms', 'glass', 'happy', 'tue', 'smith', 'wanted', 'developed',\n 'thank', 'safe', 'unique', 'survey', 'prior', 'telephone', 'sport', 'ready', 'feed', 'animal', 'sources', 'mexico', 'population', 'pa', 'regular', 'secure', 'navigation', 'operations', 'therefore', 'simply', 'evidence', 'station', 'christian', 'round', 'paypal', 'favorite', 'understand', 'option', 'master', 'valley', 'recently', 'probably', 'thu', 'rentals', 'sea', 'built', 'publications', 'blood', 'cut', 'worldwide',\n 'improve', 'connection', 'publisher', 'hall', 'larger', 'anti', 'networks', 'earth', 'parents', 'nokia', 'impact', 'transfer', 'introduction', 'kitchen', 'strong', 'tel', 'carolina', 'wedding', 'properties', 'hospital', 'ground', 'overview', 'ship', 'accommodation', 'owners', 'disease', 'tx', 'excellent', 'paid', 'italy', 'perfect', 'hair', 'opportunity', 'kit', 'classic', 'basis', 'command', 'cities', 'william', 'express',\n 'award', 'distance', 'tree', 'peter', 'assessment', 'ensure', 'thus', 'wall', 'ie', 'involved', 'el', 'extra', 'especially', 'interface', 'partners', 'budget', 'rated', 'guides', 'success', 'maximum', 'ma', 'operation', 'existing', 'quite', 'selected', 'boy', 'amazon', 'patients', 'restaurants', 'beautiful', 'warning', 'wine', 'locations', 'horse', 'vote', 'forward', 'flowers', 'stars', 'significant', 'lists',\n 'technologies', 'owner', 'retail', 'animals', 'useful', 'directly', 'manufacturer', 'ways', 'est', 'son', 'providing', 'rule', 'mac', 'housing', 'takes', 'iii', 'gmt', 'bring', 'catalog', 'searches', 'max', 'trying', 'mother', 'authority', 'considered', 'told', 'xml', 'traffic', 'programme', 'joined', 'input', 'strategy', 'feet', 'agent', 'valid', 'bin', 'modern', 'senior', 'ireland', 'teaching',\n 'door', 'grand', 'testing', 'trial', 'charge', 'units', 'instead', 'canadian', 'cool', 'normal', 'wrote', 'enterprise', 'ships', 'entire', 'educational', 'md', 'leading', 'metal', 'positive', 'fl', 'fitness', 'chinese', 'opinion', 'mb', 'asia', 'football', 'abstract', 'uses', 'output', 'funds', 'mr', 'greater', 'likely', 'develop', 'employees', 'artists', 'alternative', 'processing', 'responsibility', 'resolution',\n 'java', 'guest', 'seems', 'publication', 'pass', 'relations', 'trust', 'van', 'contains', 'session', 'multi', 'photography', 'republic', 'fees', 'components', 'vacation', 'century', 'academic', 'assistance', 'completed', 'skin', 'graphics', 'indian', 'prev', 'ads', 'mary', 'il', 'expected', 'ring', 'grade', 'dating', 'pacific', 'mountain', 'organizations', 'pop', 'filter', 'mailing', 'vehicle', 'longer', 'consider',\n 'int', 'northern', 'behind', 'panel', 'floor', 'german', 'buying', 'match', 'proposed', 'default', 'require', 'iraq', 'boys', 'outdoor', 'deep', 'morning', 'otherwise', 'allows', 'rest', 'protein', 'plant', 'reported', 'hit', 'transportation', 'mm', 'pool', 'mini', 'politics', 'partner', 'disclaimer', 'authors', 'boards', 'faculty', 'parties', 'fish', 'membership', 'mission', 'eye', 'string', 'sense',\n 'modified', 'pack', 'released', 'stage', 'internal', 'goods', 'recommended', 'born', 'unless', 'richard', 'detailed', 'japanese', 'race', 'approved', 'background', 'target', 'except', 'character', 'usb', 'maintenance', 'ability', 'maybe', 'functions', 'ed', 'moving', 'brands', 'places', 'php', 'pretty', 'trademarks', 'phentermine', 'spain', 'southern', 'yourself', 'etc', 'winter', 'battery', 'youth', 'pressure', 'submitted',\n 'boston', 'debt', 'keywords', 'medium', 'television', 'interested', 'core', 'break', 'purposes', 'throughout', 'sets', 'dance', 'wood', 'msn', 'itself', 'defined', 'papers', 'playing', 'awards', 'fee', 'studio', 'reader', 'virtual', 'device', 'established', 'answers', 'rent', 'las', 'remote', 'dark', 'programming', 'external', 'apple', 'le', 'regarding', 'instructions', 'min', 'offered', 'theory', 'enjoy',\n 'remove', 'aid', 'surface', 'minimum', 'visual', 'host', 'variety', 'teachers', 'isbn', 'martin', 'manual', 'block', 'subjects', 'agents', 'increased', 'repair', 'fair', 'civil', 'steel', 'understanding', 'songs', 'fixed', 'wrong', 'beginning', 'hands', 'associates', 'finally', 'az', 'updates', 'desktop', 'classes', 'paris', 'ohio', 'gets', 'sector', 'capacity', 'requires', 'jersey', 'un', 'fat',\n 'fully', 'father', 'electric', 'saw', 'instruments', 'quotes', 'officer', 'driver', 'businesses', 'dead', 'respect', 'unknown', 'specified', 'restaurant', 'mike', 'trip', 'pst', 'worth', 'mi', 'procedures', 'poor', 'teacher', 'eyes', 'relationship', 'workers', 'farm', 'georgia', 'peace', 'traditional', 'campus', 'tom', 'showing', 'creative', 'coast', 'benefit', 'progress', 'funding', 'devices', 'lord', 'grant',\n 'sub', 'agree', 'fiction', 'hear', 'sometimes', 'watches', 'careers', 'beyond', 'goes', 'families', 'led', 'museum', 'themselves', 'fan', 'transport', 'interesting', 'blogs', 'wife', 'evaluation', 'accepted', 'former', 'implementation', 'ten', 'hits', 'zone', 'complex', 'th', 'cat', 'galleries', 'references', 'die', 'presented', 'jack', 'flat', 'flow', 'agencies', 'literature', 'respective', 'parent', 'spanish',\n 'michigan', 'columbia', 'setting', 'dr', 'scale', 'stand', 'economy', 'highest', 'helpful', 'monthly', 'critical', 'frame', 'musical', 'definition', 'secretary', 'angeles', 'networking', 'path', 'australian', 'employee', 'chief', 'gives', 'kb', 'bottom', 'magazines', 'packages', 'detail', 'francisco', 'laws', 'changed', 'pet', 'heard', 'begin', 'individuals', 'colorado', 'royal', 'clean', 'switch', 'russian', 'largest',\n 'african', 'guy', 'titles', 'relevant', 'guidelines', 'justice', 'connect', 'bible', 'dev', 'cup', 'basket', 'applied', 'weekly', 'vol', 'installation', 'described', 'demand', 'pp', 'suite', 'vegas', 'na', 'square', 'chris', 'attention', 'advance', 'skip', 'diet', 'army', 'auction', 'gear', 'lee', 'os', 'difference', 'allowed', 'correct', 'charles', 'nation', 'selling', 'lots', 'piece',\n 'sheet', 'firm', 'seven', 'older', 'illinois', 'regulations', 'elements', 'species', 'jump', 'cells', 'module', 'resort', 'facility', 'random', 'pricing', 'dvds', 'certificate', 'minister', 'motion', 'looks', 'fashion', 'directions', 'visitors', 'documentation', 'monitor', 'trading', 'forest', 'calls', 'whose', 'coverage', 'couple', 'giving', 'chance', 'vision', 'ball', 'ending', 'clients', 'actions', 'listen', 'discuss',\n 'accept', 'automotive', 'naked', 'goal', 'successful', 'sold', 'wind', 'communities', 'clinical', 'situation', 'sciences', 'markets', 'lowest', 'highly', 'publishing', 'appear', 'emergency', 'developing', 'lives', 'currency', 'leather', 'determine', 'temperature', 'palm', 'announcements', 'patient', 'actual', 'historical', 'stone', 'bob', 'commerce', 'ringtones', 'perhaps', 'persons', 'difficult', 'scientific', 'satellite', 'fit', 'tests', 'village',\n 'accounts', 'amateur', 'ex', 'met', 'pain', 'xbox', 'particularly', 'factors', 'coffee', 'www', 'settings', 'buyer', 'cultural', 'steve', 'easily', 'oral', 'ford', 'poster', 'edge', 'functional', 'root', 'au', 'fi', 'closed', 'holidays', 'ice', 'pink', 'zealand', 'balance', 'monitoring', 'graduate', 'replies', 'shot', 'nc', 'architecture', 'initial', 'label', 'thinking', 'scott', 'llc',\n 'sec', 'recommend', 'canon', 'league', 'waste', 'minute', 'bus', 'provider', 'optional', 'dictionary', 'cold', 'accounting', 'manufacturing', 'sections', 'chair', 'fishing', 'effort', 'phase', 'fields', 'bag', 'fantasy', 'po', 'letters', 'motor', 'va', 'professor', 'context', 'install', 'shirt', 'apparel', 'generally', 'continued', 'foot', 'mass', 'crime', 'count', 'breast', 'techniques', 'ibm', 'rd',\n 'johnson', 'sc', 'quickly', 'dollars', 'websites', 'religion', 'claim', 'driving', 'permission', 'surgery', 'patch', 'heat', 'wild', 'measures', 'generation', 'kansas', 'miss', 'chemical', 'doctor', 'task', 'reduce', 'brought', 'himself', 'nor', 'component', 'enable', 'exercise', 'bug', 'santa', 'mid', 'guarantee', 'leader', 'diamond', 'israel', 'se', 'processes', 'soft', 'servers', 'alone', 'meetings',\n 'seconds', 'jones', 'arizona', 'keyword', 'interests', 'flight', 'congress', 'fuel', 'username', 'walk', 'produced', 'italian', 'paperback', 'classifieds', 'wait', 'supported', 'pocket', 'saint', 'rose', 'freedom', 'argument', 'competition', 'creating', 'jim', 'drugs', 'joint', 'premium', 'providers', 'fresh', 'characters', 'attorney', 'upgrade', 'di', 'factor', 'growing', 'thousands', 'km', 'stream', 'apartments', 'pick',\n 'hearing', 'eastern', 'auctions', 'therapy', 'entries', 'dates', 'generated', 'signed', 'upper', 'administrative', 'serious', 'prime', 'samsung', 'limit', 'began', 'louis', 'steps', 'errors', 'shops', 'del', 'efforts', 'informed', 'ga', 'ac', 'thoughts', 'creek', 'ft', 'worked', 'quantity', 'urban', 'practices', 'sorted', 'reporting', 'essential', 'myself', 'tours', 'platform', 'load', 'affiliate', 'labor',\n 'immediately', 'admin', 'nursing', 'defense', 'machines', 'designated', 'tags', 'heavy', 'covered', 'recovery', 'joe', 'guys', 'integrated', 'configuration', 'merchant', 'comprehensive', 'expert', 'universal', 'protect', 'drop', 'solid', 'cds', 'presentation', 'languages', 'became', 'orange', 'compliance', 'vehicles', 'prevent', 'theme', 'rich', 'im', 'campaign', 'marine', 'improvement', 'vs', 'guitar', 'finding', 'pennsylvania', 'examples',\n 'ipod', 'saying', 'spirit', 'ar', 'claims', 'challenge', 'motorola', 'acceptance', 'strategies', 'mo', 'seem', 'affairs', 'touch', 'intended', 'towards', 'sa', 'goals', 'hire', 'election', 'suggest', 'branch', 'charges', 'serve', 'affiliates', 'reasons', 'magic', 'mount', 'smart', 'talking', 'gave', 'ones', 'latin', 'multimedia', 'xp', 'avoid', 'certified', 'manage', 'corner', 'rank', 'computing',\n 'oregon', 'element', 'birth', 'virus', 'abuse', 'interactive', 'requests', 'separate', 'quarter', 'procedure', 'leadership', 'tables', 'define', 'racing', 'religious', 'facts', 'breakfast', 'kong', 'column', 'plants', 'faith', 'chain', 'developer', 'identify', 'avenue', 'missing', 'died', 'approximately', 'domestic', 'sitemap', 'recommendations', 'moved', 'houston', 'reach', 'comparison', 'mental', 'viewed', 'moment', 'extended', 'sequence',\n 'inch', 'attack', 'sorry', 'centers', 'opening', 'damage', 'lab', 'reserve', 'recipes', 'cvs', 'gamma', 'plastic', 'produce', 'snow', 'placed', 'truth', 'counter', 'failure', 'follows', 'eu', 'weekend', 'dollar', 'camp', 'ontario', 'automatically', 'des', 'minnesota', 'films', 'bridge', 'native', 'fill', 'williams', 'movement', 'printing', 'baseball', 'owned', 'approval', 'draft', 'chart', 'played',\n 'contacts', 'cc', 'jesus', 'readers', 'clubs', 'lcd', 'wa', 'jackson', 'equal', 'adventure', 'matching', 'offering', 'shirts', 'profit', 'leaders', 'posters', 'institutions', 'assistant', 'variable', 'ave', 'dj', 'advertisement', 'expect', 'parking', 'headlines', 'yesterday', 'compared', 'determined', 'wholesale', 'workshop', 'russia', 'gone', 'codes', 'kinds', 'extension', 'seattle', 'statements', 'golden', 'completely', 'teams',\n 'fort', 'cm', 'wi', 'lighting', 'senate', 'forces', 'funny', 'brother', 'gene', 'turned', 'portable', 'tried', 'electrical', 'applicable', 'disc', 'returned', 'pattern', 'ct', 'boat', 'named', 'theatre', 'laser', 'earlier', 'manufacturers', 'sponsor', 'classical', 'icon', 'warranty', 'dedicated', 'indiana', 'direction', 'harry', 'basketball', 'objects', 'ends', 'delete', 'evening', 'assembly', 'nuclear', 'taxes',\n 'mouse', 'signal', 'criminal', 'issued', 'brain', 'sexual', 'wisconsin', 'powerful', 'dream', 'obtained', 'false', 'da', 'cast', 'flower', 'felt', 'personnel', 'passed', 'supplied', 'identified', 'falls', 'pic', 'soul', 'aids', 'opinions', 'promote', 'stated', 'stats', 'hawaii', 'professionals', 'appears', 'carry', 'flag', 'decided', 'nj', 'covers', 'hr', 'em', 'advantage', 'hello', 'designs',\n 'maintain', 'tourism', 'priority', 'newsletters', 'adults', 'clips', 'savings', 'iv', 'graphic', 'atom', 'payments', 'rw', 'estimated', 'binding', 'brief', 'ended', 'winning', 'eight', 'anonymous', 'iron', 'straight', 'script', 'served', 'wants', 'miscellaneous', 'prepared', 'void', 'dining', 'alert', 'integration', 'atlanta', 'dakota', 'tag', 'interview', 'mix', 'framework', 'disk', 'installed', 'queen', 'vhs',\n 'credits', 'clearly', 'fix', 'handle', 'sweet', 'desk', 'criteria', 'pubmed', 'dave', 'massachusetts', 'diego', 'hong', 'vice', 'associate', 'ne', 'truck', 'behavior', 'enlarge', 'ray', 'frequently', 'revenue', 'measure', 'changing', 'votes', 'du', 'duty', 'looked', 'discussions', 'bear', 'gain', 'festival', 'laboratory', 'ocean', 'flights', 'experts', 'signs', 'lack', 'depth', 'iowa', 'whatever',\n 'logged', 'laptop', 'vintage', 'train', 'exactly', 'dry', 'explore', 'maryland', 'spa', 'concept', 'nearly', 'eligible', 'checkout', 'reality', 'forgot', 'handling', 'origin', 'knew', 'gaming', 'feeds', 'billion', 'destination', 'scotland', 'faster', 'intelligence', 'dallas', 'bought', 'con', 'ups', 'nations', 'route', 'followed', 'specifications', 'broken', 'tripadvisor', 'frank', 'alaska', 'zoom', 'blow', 'battle',\n 'residential', 'anime', 'speak', 'decisions', 'industries', 'protocol', 'query', 'clip', 'partnership', 'editorial', 'nt', 'expression', 'es', 'equity', 'provisions', 'speech', 'wire', 'principles', 'suggestions', 'rural', 'shared', 'sounds', 'replacement', 'tape', 'strategic', 'judge', 'spam', 'economics', 'acid', 'bytes', 'cent', 'forced', 'compatible', 'fight', 'apartment', 'height', 'null', 'zero', 'speaker', 'filed',\n 'gb', 'netherlands', 'obtain', 'bc', 'consulting', 'recreation', 'offices', 'designer', 'remain', 'managed', 'pr', 'failed', 'marriage', 'roll', 'korea', 'banks', 'fr', 'participants', 'secret', 'bath', 'aa', 'kelly', 'leads', 'negative', 'austin', 'favorites', 'toronto', 'theater', 'springs', 'missouri', 'andrew', 'var', 'perform', 'healthy', 'translation', 'estimates', 'font', 'assets', 'injury', 'mt',\n 'joseph', 'ministry', 'drivers', 'lawyer', 'figures', 'married', 'protected', 'proposal', 'sharing', 'philadelphia', 'portal', 'waiting', 'birthday', 'beta', 'fail', 'gratis', 'banking', 'officials', 'brian', 'toward', 'won', 'slightly', 'assist', 'conduct', 'contained', 'lingerie', 'legislation', 'calling', 'parameters', 'jazz', 'serving', 'bags', 'profiles', 'miami', 'comics', 'matters', 'houses', 'doc', 'postal', 'relationships',\n 'tennessee', 'wear', 'controls', 'breaking', 'combined', 'ultimate', 'wales', 'representative', 'frequency', 'introduced', 'minor', 'finish', 'departments', 'residents', 'noted', 'displayed', 'mom', 'reduced', 'physics', 'rare', 'spent', 'performed', 'extreme', 'samples', 'davis', 'daniel', 'bars', 'reviewed', 'row', 'oz', 'forecast', 'removed', 'helps', 'singles', 'administrator', 'cycle', 'amounts', 'contain', 'accuracy', 'dual',\n 'rise', 'usd', 'sleep', 'mg', 'bird', 'pharmacy', 'brazil', 'creation', 'static', 'scene', 'hunter', 'addresses', 'lady', 'crystal', 'famous', 'writer', 'chairman', 'violence', 'fans', 'oklahoma', 'speakers', 'drink', 'academy', 'dynamic', 'gender', 'eat', 'permanent', 'agriculture', 'dell', 'cleaning', 'constitutes', 'portfolio', 'practical', 'delivered', 'collectibles', 'infrastructure', 'exclusive', 'seat', 'concerns', 'colour',\n 'vendor', 'originally', 'intel', 'utilities', 'philosophy', 'regulation', 'officers', 'reduction', 'aim', 'bids', 'referred', 'supports', 'nutrition', 'recording', 'regions', 'junior', 'toll', 'les', 'cape', 'ann', 'rings', 'meaning', 'tip', 'secondary', 'wonderful', 'mine', 'ladies', 'henry', 'ticket', 'announced', 'guess', 'agreed', 'prevention', 'whom', 'ski', 'soccer', 'math', 'import', 'posting', 'presence',\n 'instant', 'mentioned', 'automatic', 'healthcare', 'viewing', 'maintained', 'ch', 'increasing', 'majority', 'connected', 'christ', 'dan', 'dogs', 'sd', 'directors', 'aspects', 'austria', 'ahead', 'moon', 'participation', 'scheme', 'utility', 'preview', 'fly', 'manner', 'matrix', 'containing', 'combination', 'devel', 'amendment', 'despite', 'strength', 'guaranteed', 'turkey', 'libraries', 'proper', 'distributed', 'degrees', 'singapore', 'enterprises',\n 'delta', 'fear', 'seeking', 'inches', 'phoenix', 'rs', 'convention', 'shares', 'principal', 'daughter', 'standing', 'comfort', 'colors', 'wars', 'cisco', 'ordering', 'kept', 'alpha', 'appeal', 'cruise', 'bonus', 'certification', 'previously', 'hey', 'bookmark', 'buildings', 'specials', 'beat', 'disney', 'household', 'batteries', 'adobe', 'smoking', 'bbc', 'becomes', 'drives', 'arms', 'alabama', 'tea', 'improved',\n 'trees', 'avg', 'achieve', 'positions', 'dress', 'subscription', 'dealer', 'contemporary', 'sky', 'utah', 'nearby', 'rom', 'carried', 'happen', 'exposure', 'panasonic', 'hide', 'permalink', 'signature', 'gambling', 'refer', 'miller', 'provision', 'outdoors', 'clothes', 'caused', 'luxury', 'babes', 'frames', 'certainly', 'indeed', 'newspaper', 'toy', 'circuit', 'layer', 'printed', 'slow', 'removal', 'easier', 'src',\n 'liability', 'trademark', 'hip', 'printers', 'faqs', 'nine', 'adding', 'kentucky', 'mostly', 'eric', 'spot', 'taylor', 'trackback', 'prints', 'spend', 'factory', 'interior', 'revised', 'grow', 'americans', 'optical', 'promotion', 'relative', 'amazing', 'clock', 'dot', 'hiv', 'identity', 'suites', 'conversion', 'feeling', 'hidden', 'reasonable', 'victoria', 'serial', 'relief', 'revision', 'broadband', 'influence', 'ratio',\n 'pda', 'importance', 'rain', 'onto', 'dsl', 'planet', 'webmaster', 'copies', 'recipe', 'zum', 'permit', 'seeing', 'proof', 'dna', 'diff', 'tennis', 'bass', 'prescription', 'bedroom', 'empty', 'instance', 'hole', 'pets', 'ride', 'licensed', 'orlando', 'specifically', 'tim', 'bureau', 'maine', 'sql', 'represent', 'conservation', 'pair', 'ideal', 'specs', 'recorded', 'don', 'pieces', 'finished',\n 'parks', 'dinner', 'lawyers', 'sydney', 'stress', 'cream', 'ss', 'runs', 'trends', 'yeah', 'discover', 'ap', 'patterns', 'boxes', 'louisiana', 'hills', 'javascript', 'fourth', 'nm', 'advisor', 'mn', 'marketplace', 'nd', 'evil', 'aware', 'wilson', 'shape', 'evolution', 'irish', 'certificates', 'objectives', 'stations', 'suggested', 'gps', 'op', 'remains', 'acc', 'greatest', 'firms', 'concerned',\n 'euro', 'operator', 'structures', 'generic', 'encyclopedia', 'usage', 'cap', 'ink', 'charts', 'continuing', 'mixed', 'census', 'interracial', 'peak', 'tn', 'competitive', 'exist', 'wheel', 'transit', 'suppliers', 'salt', 'compact', 'poetry', 'lights', 'tracking', 'angel', 'bell', 'keeping', 'preparation', 'attempt', 'receiving', 'matches', 'accordance', 'width', 'noise', 'engines', 'forget', 'array', 'discussed', 'accurate',\n 'stephen', 'elizabeth', 'climate', 'reservations', 'pin', 'playstation', 'alcohol', 'greek', 'instruction', 'managing', 'annotation', 'sister', 'raw', 'differences', 'walking', 'explain', 'smaller', 'newest', 'establish', 'gnu', 'happened', 'expressed', 'jeff', 'extent', 'sharp', 'lesbians', 'ben', 'lane', 'paragraph', 'kill', 'mathematics', 'aol', 'compensation', 'ce', 'export', 'managers', 'aircraft', 'modules', 'sweden', 'conflict',\n 'conducted', 'versions', 'employer', 'occur', 'percentage', 'knows', 'mississippi', 'describe', 'concern', 'backup', 'requested', 'citizens', 'connecticut', 'heritage', 'personals', 'immediate', 'holding', 'trouble', 'spread', 'coach', 'kevin', 'agricultural', 'expand', 'supporting', 'audience', 'assigned', 'jordan', 'collections', 'ages', 'participate', 'plug', 'specialist', 'cook', 'affect', 'virgin', 'experienced', 'investigation', 'raised', 'hat', 'institution',\n 'directed', 'dealers', 'searching', 'sporting', 'helping', 'perl', 'affected', 'lib', 'bike', 'totally', 'plate', 'expenses', 'indicate', 'blonde', 'ab', 'proceedings', 'favourite', 'transmission', 'anderson', 'utc', 'characteristics', 'der', 'lose', 'organic', 'seek', 'experiences', 'albums', 'cheats', 'extremely', 'verzeichnis', 'contracts', 'guests', 'hosted', 'diseases', 'concerning', 'developers', 'equivalent', 'chemistry', 'tony', 'neighborhood',\n 'nevada', 'kits', 'thailand', 'variables', 'agenda', 'anyway', 'continues', 'tracks', 'advisory', 'cam', 'curriculum', 'logic', 'template', 'prince', 'circle', 'soil', 'grants', 'anywhere', 'psychology', 'responses', 'atlantic', 'wet', 'circumstances', 'edward', 'investor', 'identification', 'ram', 'leaving', 'wildlife', 'appliances', 'matt', 'elementary', 'cooking', 'speaking', 'sponsors', 'fox', 'unlimited', 'respond', 'sizes', 'plain',\n 'exit', 'entered', 'iran', 'arm', 'keys', 'launch', 'wave', 'checking', 'costa', 'belgium', 'printable', 'holy', 'acts', 'guidance', 'mesh', 'trail', 'enforcement', 'symbol', 'crafts', 'highway', 'buddy', 'hardcover', 'observed', 'dean', 'setup', 'poll', 'booking', 'glossary', 'fiscal', 'celebrity', 'styles', 'denver', 'unix', 'filled', 'bond', 'channels', 'ericsson', 'appendix', 'notify', 'blues',\n 'chocolate', 'pub', 'portion', 'scope', 'hampshire', 'supplier', 'cables', 'cotton', 'bluetooth', 'controlled', 'requirement', 'authorities', 'biology', 'dental', 'killed', 'border', 'ancient', 'debate', 'representatives', 'starts', 'pregnancy', 'causes', 'arkansas', 'biography', 'leisure', 'attractions', 'learned', 'transactions', 'notebook', 'explorer', 'historic', 'attached', 'opened', 'tm', 'husband', 'disabled', 'authorized', 'crazy', 'upcoming', 'britain',\n 'concert', 'retirement', 'scores', 'financing', 'efficiency', 'sp', 'comedy', 'adopted', 'efficient', 'weblog', 'linear', 'commitment', 'specialty', 'bears', 'jean', 'hop', 'carrier', 'edited', 'constant', 'visa', 'mouth', 'jewish', 'meter', 'linked', 'portland', 'interviews', 'concepts', 'nh', 'gun', 'reflect', 'pure', 'deliver', 'wonder', 'lessons', 'fruit', 'begins', 'qualified', 'reform', 'lens', 'alerts',\n 'treated', 'discovery', 'draw', 'mysql', 'classified', 'relating', 'assume', 'confidence', 'alliance', 'fm', 'confirm', 'warm', 'neither', 'lewis', 'howard', 'offline', 'leaves', 'engineer', 'lifestyle', 'consistent', 'replace', 'clearance', 'connections', 'inventory', 'converter', 'organisation', 'babe', 'checks', 'reached', 'becoming', 'safari', 'objective', 'indicated', 'sugar', 'crew', 'legs', 'sam', 'stick', 'securities', 'allen',\n 'pdt', 'relation', 'enabled', 'genre', 'slide', 'montana', 'volunteer', 'tested', 'rear', 'democratic', 'enhance', 'switzerland', 'exact', 'bound', 'parameter', 'adapter', 'processor', 'node', 'formal', 'dimensions', 'contribute', 'lock', 'hockey', 'storm', 'micro', 'colleges', 'laptops', 'mile', 'showed', 'challenges', 'editors', 'mens', 'threads', 'bowl', 'supreme', 'brothers', 'recognition', 'presents', 'ref', 'tank',\n 'submission', 'dolls', 'estimate', 'encourage', 'navy', 'kid', 'regulatory', 'inspection', 'consumers', 'cancel', 'limits', 'territory', 'transaction', 'manchester', 'weapons', 'paint', 'delay', 'pilot', 'outlet', 'contributions', 'continuous', 'db', 'czech', 'resulting', 'cambridge', 'initiative', 'novel', 'pan', 'execution', 'disability', 'increases', 'ultra', 'winner', 'idaho', 'contractor', 'ph', 'episode', 'examination', 'potter', 'dish',\n 'plays', 'bulletin', 'ia', 'pt', 'indicates', 'modify', 'oxford', 'adam', 'truly', 'epinions', 'painting', 'committed', 'extensive', 'affordable', 'universe', 'candidate', 'databases', 'patent', 'slot', 'psp', 'outstanding', 'ha', 'eating', 'perspective', 'planned', 'watching', 'lodge', 'messenger', 'mirror', 'tournament', 'consideration', 'ds', 'discounts', 'sterling', 'sessions', 'kernel', 'stocks', 'buyers', 'journals', 'gray',\n 'catalogue', 'ea', 'jennifer', 'antonio', 'charged', 'broad', 'taiwan', 'und', 'chosen', 'demo', 'greece', 'lg', 'swiss', 'sarah', 'clark', 'labour', 'hate', 'terminal', 'publishers', 'nights', 'behalf', 'caribbean', 'liquid', 'rice', 'nebraska', 'loop', 'salary', 'reservation', 'foods', 'gourmet', 'guard', 'properly', 'orleans', 'saving', 'nfl', 'remaining', 'empire', 'resume', 'twenty', 'newly',\n 'raise', 'prepare', 'avatar', 'gary', 'depending', 'illegal', 'expansion', 'vary', 'hundreds', 'rome', 'arab', 'lincoln', 'helped', 'premier', 'tomorrow', 'purchased', 'milk', 'decide', 'consent', 'drama', 'visiting', 'performing', 'downtown', 'keyboard', 'contest', 'collected', 'nw', 'bands', 'boot', 'suitable', 'ff', 'absolutely', 'millions', 'lunch', 'audit', 'push', 'chamber', 'guinea', 'findings', 'muscle',\n 'featuring', 'iso', 'implement', 'clicking', 'scheduled', 'polls', 'typical', 'tower', 'yours', 'sum', 'misc', 'calculator', 'significantly', 'chicken', 'temporary', 'attend', 'shower', 'alan', 'sending', 'jason', 'tonight', 'dear', 'sufficient', 'holdem', 'shell', 'province', 'catholic', 'oak', 'vat', 'awareness', 'vancouver', 'governor', 'beer', 'seemed', 'contribution', 'measurement', 'swimming', 'spyware', 'formula', 'constitution',\n 'packaging', 'solar', 'jose', 'catch', 'jane', 'pakistan', 'ps', 'reliable', 'consultation', 'northwest', 'sir', 'doubt', 'earn', 'finder', 'unable', 'periods', 'classroom', 'tasks', 'democracy', 'attacks', 'kim', 'wallpaper', 'merchandise', 'const', 'resistance', 'doors', 'symptoms', 'resorts', 'biggest', 'memorial', 'visitor', 'twin', 'forth', 'insert', 'baltimore', 'gateway', 'ky', 'dont', 'alumni', 'drawing',\n 'candidates', 'charlotte', 'ordered', 'biological', 'fighting', 'transition', 'happens', 'preferences', 'spy', 'romance', 'instrument', 'bruce', 'split', 'themes', 'powers', 'heaven', 'br', 'bits', 'pregnant', 'twice', 'classification', 'focused', 'egypt', 'physician', 'hollywood', 'bargain', 'wikipedia', 'cellular', 'norway', 'vermont', 'asking', 'blocks', 'normally', 'lo', 'spiritual', 'hunting', 'diabetes', 'suit', 'ml', 'shift',\n 'chip', 'res', 'sit', 'bodies', 'photographs', 'cutting', 'wow', 'simon', 'writers', 'marks', 'flexible', 'loved', 'favourites', 'mapping', 'numerous', 'relatively', 'birds', 'satisfaction', 'represents', 'char', 'indexed', 'pittsburgh', 'superior', 'preferred', 'saved', 'paying', 'cartoon', 'shots', 'intellectual', 'moore', 'granted', 'choices', 'carbon', 'spending', 'comfortable', 'magnetic', 'interaction', 'listening', 'effectively', 'registry',\n 'crisis', 'outlook', 'massive', 'denmark', 'employed', 'bright', 'treat', 'header', 'cs', 'poverty', 'formed', 'piano', 'echo', 'que', 'grid', 'sheets', 'patrick', 'experimental', 'puerto', 'revolution', 'consolidation', 'displays', 'plasma', 'allowing', 'earnings', 'voip', 'mystery', 'landscape', 'dependent', 'mechanical', 'journey', 'delaware', 'bidding', 'consultants', 'risks', 'banner', 'applicant', 'charter', 'fig', 'barbara',\n 'cooperation', 'counties', 'acquisition', 'ports', 'implemented', 'sf', 'directories', 'recognized', 'dreams', 'blogger', 'notification', 'kg', 'licensing', 'stands', 'teach', 'occurred', 'textbooks', 'rapid', 'pull', 'hairy', 'diversity', 'cleveland', 'ut', 'reverse', 'deposit', 'seminar', 'investments', 'latina', 'nasa', 'wheels', 'specify', 'accessibility', 'dutch', 'sensitive', 'templates', 'formats', 'tab', 'depends', 'boots', 'holds',\n 'router', 'concrete', 'si', 'editing', 'poland', 'folder', 'womens', 'css', 'completion', 'upload', 'pulse', 'universities', 'technique', 'contractors', 'voting', 'courts', 'notices', 'subscriptions', 'calculate', 'mc', 'detroit', 'alexander', 'broadcast', 'converted', 'metro', 'toshiba', 'anniversary', 'improvements', 'strip', 'specification', 'pearl', 'accident', 'nick', 'accessible', 'accessory', 'resident', 'plot', 'qty', 'possibly', 'airline',\n 'typically', 'representation', 'regard', 'pump', 'exists', 'arrangements', 'smooth', 'conferences', 'uniprotkb', 'strike', 'consumption', 'birmingham', 'flashing', 'lp', 'narrow', 'afternoon', 'threat', 'surveys', 'sitting', 'putting', 'consultant', 'controller', 'ownership', 'committees', 'legislative', 'researchers', 'vietnam', 'trailer', 'anne', 'castle', 'gardens', 'missed', 'malaysia', 'unsubscribe', 'antique', 'labels', 'willing', 'bio', 'molecular', 'acting',\n 'heads', 'stored', 'exam', 'logos', 'residence', 'attorneys', 'antiques', 'density', 'hundred', 'ryan', 'operators', 'strange', 'sustainable', 'philippines', 'statistical', 'beds', 'mention', 'innovation', 'pcs', 'employers', 'grey', 'parallel', 'honda', 'amended', 'operate', 'bills', 'bold', 'bathroom', 'stable', 'opera', 'definitions', 'von', 'doctors', 'lesson', 'cinema', 'asset', 'ag', 'scan', 'elections', 'drinking',\n 'reaction', 'blank', 'enhanced', 'entitled', 'severe', 'generate', 'stainless', 'newspapers', 'hospitals', 'vi', 'deluxe', 'humor', 'aged', 'monitors', 'exception', 'lived', 'duration', 'bulk', 'successfully', 'indonesia', 'pursuant', 'sci', 'fabric', 'edt', 'visits', 'primarily', 'tight', 'domains', 'capabilities', 'pmid', 'contrast', 'recommendation', 'flying', 'recruitment', 'sin', 'berlin', 'cute', 'organized', 'ba', 'para',\n 'siemens', 'adoption', 'improving', 'cr', 'expensive', 'meant', 'capture', 'pounds', 'buffalo', 'organisations', 'plane', 'pg', 'explained', 'seed', 'programmes', 'desire', 'expertise', 'mechanism', 'camping', 'ee', 'jewellery', 'meets', 'welfare', 'peer', 'caught', 'eventually', 'marked', 'driven', 'measured', 'medline', 'bottle', 'agreements', 'considering', 'innovative', 'marshall', 'massage', 'rubber', 'conclusion', 'closing', 'tampa',\n 'thousand', 'meat', 'legend', 'grace', 'susan', 'ing', 'ks', 'adams', 'python', 'monster', 'alex', 'bang', 'villa', 'bone', 'columns', 'disorders', 'bugs', 'collaboration', 'hamilton', 'detection', 'ftp', 'cookies', 'inner', 'formation', 'tutorial', 'med', 'engineers', 'entity', 'cruises', 'gate', 'holder', 'proposals', 'moderator', 'sw', 'tutorials', 'settlement', 'portugal', 'lawrence', 'roman', 'duties',\n 'valuable', 'tone', 'collectables', 'ethics', 'forever', 'dragon', 'busy', 'captain', 'fantastic', 'imagine', 'brings', 'heating', 'leg', 'neck', 'hd', 'wing', 'governments', 'purchasing', 'scripts', 'abc', 'stereo', 'appointed', 'taste', 'dealing', 'commit', 'tiny', 'operational', 'rail', 'airlines', 'liberal', 'livecam', 'jay', 'trips', 'gap', 'sides', 'tube', 'turns', 'corresponding', 'descriptions', 'cache',\n 'belt', 'jacket', 'determination', 'animation', 'oracle', 'er', 'matthew', 'lease', 'productions', 'aviation', 'hobbies', 'proud', 'excess', 'disaster', 'console', 'commands', 'jr', 'telecommunications', 'instructor', 'giant', 'achieved', 'injuries', 'shipped', 'seats', 'approaches', 'biz', 'alarm', 'voltage', 'anthony', 'nintendo', 'usual', 'loading', 'stamps', 'appeared', 'franklin', 'angle', 'rob', 'vinyl', 'highlights', 'mining',\n 'designers', 'melbourne', 'ongoing', 'worst', 'imaging', 'betting', 'scientists', 'liberty', 'wyoming', 'blackjack', 'argentina', 'era', 'convert', 'possibility', 'analyst', 'commissioner', 'dangerous', 'garage', 'exciting', 'reliability', 'thongs', 'gcc', 'unfortunately', 'respectively', 'volunteers', 'attachment', 'ringtone', 'finland', 'morgan', 'derived', 'pleasure', 'honor', 'asp', 'oriented', 'eagle', 'desktops', 'pants', 'columbus', 'nurse', 'prayer',\n 'appointment', 'workshops', 'hurricane', 'quiet', 'luck', 'postage', 'producer', 'represented', 'mortgages', 'dial', 'responsibilities', 'cheese', 'comic', 'carefully', 'jet', 'productivity', 'investors', 'crown', 'par', 'underground', 'diagnosis', 'maker', 'crack', 'principle', 'picks', 'vacations', 'gang', 'semester', 'calculated', 'fetish', 'applies', 'casinos', 'appearance', 'smoke', 'apache', 'filters', 'incorporated', 'nv', 'craft', 'cake',\n 'notebooks', 'apart', 'fellow', 'blind', 'lounge', 'mad', 'algorithm', 'semi', 'coins', 'andy', 'gross', 'strongly', 'cafe', 'valentine', 'hilton', 'ken', 'proteins', 'horror', 'su', 'exp', 'familiar', 'capable', 'douglas', 'debian', 'till', 'involving', 'pen', 'investing', 'christopher', 'admission', 'epson', 'shoe', 'elected', 'carrying', 'victory', 'sand', 'madison', 'terrorism', 'joy', 'editions',\n 'cpu', 'mainly', 'ethnic', 'ran', 'parliament', 'actor', 'finds', 'seal', 'situations', 'fifth', 'allocated', 'citizen', 'vertical', 'corrections', 'structural', 'municipal', 'describes', 'prize', 'sr', 'occurs', 'jon', 'absolute', 'disabilities', 'consists', 'anytime', 'substance', 'prohibited', 'addressed', 'lies', 'pipe', 'soldiers', 'nr', 'guardian', 'lecture', 'simulation', 'layout', 'initiatives', 'ill', 'concentration', 'classics',\n 'lbs', 'lay', 'interpretation', 'horses', 'lol', 'dirty', 'deck', 'wayne', 'donate', 'taught', 'bankruptcy', 'mp', 'worker', 'optimization', 'alive', 'temple', 'substances', 'prove', 'discovered', 'wings', 'breaks', 'genetic', 'restrictions', 'participating', 'waters', 'promise', 'thin', 'exhibition', 'prefer', 'ridge', 'cabinet', 'modem', 'harris', 'mph', 'bringing', 'sick', 'dose', 'evaluate', 'tiffany', 'tropical',\n 'collect', 'bet', 'composition', 'toyota', 'streets', 'nationwide', 'vector', 'definitely', 'shaved', 'turning', 'buffer', 'purple', 'existence', 'commentary', 'larry', 'limousines', 'developments', 'def', 'immigration', 'destinations', 'lets', 'mutual', 'pipeline', 'necessarily', 'syntax', 'li', 'attribute', 'prison', 'skill', 'chairs', 'nl', 'everyday', 'apparently', 'surrounding', 'mountains', 'moves', 'popularity', 'inquiry', 'ethernet', 'checked',\n 'exhibit', 'throw', 'trend', 'sierra', 'visible', 'cats', 'desert', 'postposted', 'ya', 'oldest', 'rhode', 'nba', 'coordinator', 'obviously', 'mercury', 'steven', 'handbook', 'greg', 'navigate', 'worse', 'summit', 'victims', 'epa', 'spaces', 'fundamental', 'burning', 'escape', 'coupons', 'somewhat', 'receiver', 'substantial', 'tr', 'progressive', 'cialis', 'bb', 'boats', 'glance', 'scottish', 'championship', 'arcade',\n 'richmond', 'sacramento', 'impossible', 'ron', 'russell', 'tells', 'obvious', 'fiber', 'depression', 'graph', 'covering', 'platinum', 'judgment', 'bedrooms', 'talks', 'filing', 'foster', 'modeling', 'passing', 'awarded', 'testimonials', 'trials', 'tissue', 'nz', 'memorabilia', 'clinton', 'masters', 'bonds', 'cartridge', 'alberta', 'explanation', 'folk', 'org', 'commons', 'cincinnati', 'subsection', 'fraud', 'electricity', 'permitted', 'spectrum',\n 'arrival', 'okay', 'pottery', 'emphasis', 'roger', 'aspect', 'workplace', 'awesome', 'mexican', 'confirmed', 'counts', 'priced', 'wallpapers', 'hist', 'crash', 'lift', 'desired', 'inter', 'closer', 'assumes', 'heights', 'shadow', 'riding', 'infection', 'firefox', 'lisa', 'expense', 'grove', 'eligibility', 'venture', 'clinic', 'korean', 'healing', 'princess', 'mall', 'entering', 'packet', 'spray', 'studios', 'involvement',\n 'dad', 'buttons', 'placement', 'observations', 'vbulletin', 'funded', 'thompson', 'winners', 'extend', 'roads', 'subsequent', 'pat', 'dublin', 'rolling', 'fell', 'motorcycle', 'yard', 'disclosure', 'establishment', 'memories', 'nelson', 'te', 'arrived', 'creates', 'faces', 'tourist', 'av', 'mayor', 'murder', 'sean', 'adequate', 'senator', 'yield', 'presentations', 'grades', 'cartoons', 'pour', 'digest', 'reg', 'lodging',\n 'tion', 'dust', 'hence', 'wiki', 'entirely', 'replaced', 'radar', 'rescue', 'undergraduate', 'losses', 'combat', 'reducing', 'stopped', 'occupation', 'lakes', 'donations', 'associations', 'citysearch', 'closely', 'radiation', 'diary', 'seriously', 'kings', 'shooting', 'kent', 'adds', 'nsw', 'ear', 'flags', 'pci', 'baker', 'launched', 'elsewhere', 'pollution', 'conservative', 'guestbook', 'shock', 'effectiveness', 'walls', 'abroad',\n 'ebony', 'tie', 'ward', 'drawn', 'arthur', 'ian', 'visited', 'roof', 'walker', 'demonstrate', 'atmosphere', 'suggests', 'kiss', 'beast', 'ra', 'operated', 'experiment', 'targets', 'overseas', 'purchases', 'dodge', 'counsel', 'federation', 'pizza', 'invited', 'yards', 'assignment', 'chemicals', 'gordon', 'mod', 'farmers', 'rc', 'queries', 'bmw', 'rush', 'ukraine', 'absence', 'nearest', 'cluster', 'vendors',\n 'mpeg', 'whereas', 'yoga', 'serves', 'woods', 'surprise', 'lamp', 'rico', 'partial', 'shoppers', 'phil', 'everybody', 'couples', 'nashville', 'ranking', 'jokes', 'cst', 'http', 'ceo', 'simpson', 'twiki', 'sublime', 'counseling', 'palace', 'acceptable', 'satisfied', 'glad', 'wins', 'measurements', 'verify', 'globe', 'trusted', 'copper', 'milwaukee', 'rack', 'medication', 'warehouse', 'shareware', 'ec', 'rep',\n 'dicke', 'kerry', 'receipt', 'supposed', 'ordinary', 'nobody', 'ghost', 'violation', 'configure', 'stability', 'mit', 'applying', 'southwest', 'boss', 'pride', 'institutional', 'expectations', 'independence', 'knowing', 'reporter', 'metabolism', 'keith', 'champion', 'cloudy', 'linda', 'ross', 'personally', 'chile', 'anna', 'plenty', 'solo', 'sentence', 'throat', 'ignore', 'maria', 'uniform', 'excellence', 'wealth', 'tall', 'rm',\n 'somewhere', 'vacuum', 'dancing', 'attributes', 'recognize', 'brass', 'writes', 'plaza', 'pdas', 'outcomes', 'survival', 'quest', 'publish', 'sri', 'screening', 'toe', 'thumbnail', 'trans', 'jonathan', 'whenever', 'nova', 'lifetime', 'api', 'pioneer', 'booty', 'forgotten', 'acrobat', 'plates', 'acres', 'venue', 'athletic', 'thermal', 'essays', 'behaviour', 'vital', 'telling', 'fairly', 'coastal', 'config', 'cf',\n 'charity', 'intelligent', 'edinburgh', 'vt', 'excel', 'modes', 'obligation', 'campbell', 'wake', 'stupid', 'harbor', 'hungary', 'traveler', 'urw', 'segment', 'realize', 'regardless', 'lan', 'enemy', 'puzzle', 'rising', 'aluminum', 'wells', 'wishlist', 'opens', 'insight', 'sms', 'restricted', 'republican', 'secrets', 'lucky', 'latter', 'merchants', 'thick', 'trailers', 'repeat', 'syndrome', 'philips', 'attendance', 'penalty',\n 'drum', 'glasses', 'enables', 'nec', 'iraqi', 'builder', 'vista', 'jessica', 'chips', 'terry', 'flood', 'foto', 'ease', 'arguments', 'amsterdam', 'arena', 'adventures', 'pupils', 'stewart', 'announcement', 'tabs', 'outcome', 'appreciate', 'expanded', 'casual', 'grown', 'polish', 'lovely', 'extras', 'gm', 'centres', 'jerry', 'clause', 'smile', 'lands', 'ri', 'troops', 'indoor', 'bulgaria', 'armed',\n 'broker', 'charger', 'regularly', 'believed', 'pine', 'cooling', 'tend', 'gulf', 'rt', 'rick', 'trucks', 'cp', 'mechanisms', 'divorce', 'laura', 'shopper', 'tokyo', 'partly', 'nikon', 'customize', 'tradition', 'candy', 'pills', 'tiger', 'donald', 'folks', 'sensor', 'exposed', 'telecom', 'hunt', 'angels', 'deputy', 'indicators', 'sealed', 'thai', 'emissions', 'physicians', 'loaded', 'fred', 'complaint',\n 'scenes', 'experiments', 'afghanistan', 'dd', 'boost', 'spanking', 'scholarship', 'governance', 'mill', 'founded', 'supplements', 'chronic', 'icons', 'moral', 'den', 'catering', 'aud', 'finger', 'keeps', 'pound', 'locate', 'camcorder', 'pl', 'trained', 'burn', 'implementing', 'roses', 'labs', 'ourselves', 'bread', 'tobacco', 'wooden', 'motors', 'tough', 'roberts', 'incident', 'gonna', 'dynamics', 'lie', 'crm',\n 'rf', 'conversation', 'decrease', 'chest', 'pension', 'billy', 'revenues', 'emerging', 'worship', 'capability', 'ak', 'fe', 'craig', 'herself', 'producing', 'churches', 'precision', 'damages', 'reserves', 'contributed', 'solve', 'shorts', 'reproduction', 'minority', 'td', 'diverse', 'amp', 'ingredients', 'sb', 'ah', 'johnny', 'sole', 'franchise', 'recorder', 'complaints', 'facing', 'sm', 'nancy', 'promotions', 'tones',\n 'passion', 'rehabilitation', 'maintaining', 'sight', 'laid', 'clay', 'defence', 'patches', 'weak', 'refund', 'usc', 'towns', 'environments', 'trembl', 'divided', 'blvd', 'reception', 'amd', 'wise', 'emails', 'cyprus', 'wv', 'odds', 'correctly', 'insider', 'seminars', 'consequences', 'makers', 'hearts', 'geography', 'appearing', 'integrity', 'worry', 'ns', 'discrimination', 'eve', 'carter', 'legacy', 'marc', 'pleased',\n 'danger', 'vitamin', 'widely', 'processed', 'phrase', 'genuine', 'raising', 'implications', 'functionality', 'paradise', 'hybrid', 'reads', 'roles', 'intermediate', 'emotional', 'sons', 'leaf', 'pad', 'glory', 'platforms', 'ja', 'bigger', 'billing', 'diesel', 'versus', 'combine', 'overnight', 'geographic', 'exceed', 'bs', 'rod', 'saudi', 'fault', 'cuba', 'hrs', 'preliminary', 'districts', 'introduce', 'silk', 'promotional',\n]);\n","/**\n * Top 5,000 most common German words\n * Source: FrequencyWords (hermitdave/FrequencyWords, Leipzig Corpora)\n * Used for word complexity analysis — common words are not flagged as jargon.\n */\nexport const FREQUENCY_DE: ReadonlySet<string> = new Set([\n 'ich', 'sie', 'das', 'ist', 'du', 'nicht', 'die', 'es', 'und', 'der', 'wir', 'was', 'zu', 'er', 'ein', 'in', 'ja', 'mir', 'mit', 'wie', 'den', 'mich', 'auf', 'dass', 'aber', 'eine', 'so', 'hat', 'hier', 'haben', 'für', 'sind', 'war', 'von', 'wenn', 'dich', 'ihr', 'nein', 'habe', 'an',\n 'bin', 'noch', 'nur', 'da', 'dir', 'sich', 'einen', 'uns', 'hast', 'dem', 'kann', 'gut', 'auch', 'schon', 'als', 'sein', 'mal', 'jetzt', 'ihn', 'dann', 'aus', 'meine', 'um', 'im', 'wird', 'mein', 'bist', 'doch', 'alles', 'weiß', 'keine', 'oder', 'nach', 's', 'nichts', 'man', 'muss', 'werden', 'will', 'ihnen',\n 'geht', 'wo', 'etwas', 'oh', 'mehr', 'bei', 'also', 'bitte', 'immer', 'hab', 'warum', 'vor', 'los', 'können', 'wieder', 'sagen', 'machen', 'danke', 'sehr', 'alle', 'denn', 'mann', 'tun', 'ihm', 'zum', 'gehen', 'sehen', 'vielleicht', 'einem', 'wer', 'ihre', 'diese', 'euch', 'einer', 'komm', 'über', 'gibt', 'okay', 'wissen', 'deine',\n 'müssen', 'soll', 'werde', 'nie', 'wirklich', 'hey', 'kein', 'viel', 'weg', 'würde', 'tut', 'am', 'des', 'einfach', 'leben', 'hatte', 'zeit', 'weil', 'willst', 'kommen', 'dein', 'heute', 'kommt', 'wollen', 'damit', 'ganz', 'wäre', 'wollte', 'weißt', 'ok', 'sicher', 'gesagt', 'frau', 'nun', 'bis', 'wurde', 'leid', 'na', 'kannst', 'macht',\n 'dieser', 'zurück', 'lassen', 'hallo', 'meinen', 'gott', 'seine', 'hätte', 'zwei', 'könnte', 'genau', 'waren', 'zur', 'lass', 'klar', 'morgen', 'leute', 'vater', 'schön', 'glaube', 'mr.', 'ab', 'gerade', 'tag', 'gesehen', 'reden', 'wohl', 'liebe', 'sollte', 'sagte', 'unsere', 'jemand', 'geld', 'durch', 'ob', 'keinen', 'mutter', 'raus', 'gemacht', 'paar',\n 'mach', 'passiert', 'dachte', 'besser', 'musst', 'wieso', 'sir', 'dieses', 'selbst', 'gehört', 'möchte', 'ohne', 'hör', 'her', 'sag', 'meiner', 'anderen', 'helfen', 'nacht', 'finden', 'diesen', 'gute', 'wirst', 'lange', 'natürlich', 'ach', 'meinem', 'gar', 'ins', 'sei', 'dort', 'weiter', 'geben', 'seit', 'gleich', 'sagt', 'recht', 'ihren', 'richtig', 'ordnung',\n 'vom', 'hören', 'sieht', 'davon', 'dafür', 'geh', 'diesem', 'wegen', 'hause', 'sollten', 'mädchen', 'hin', 'sollen', 'abend', 'haus', 'denke', 'viele', 'drei', 'deinen', 'freund', 'guten', 'unser', 'warte', 'machst', 'menschen', 'essen', 'angst', 'bleiben', 'zusammen', 'welt', 'unter', 'habt', 'schnell', 'andere', 'tot', 'getan', 'darf', 'erst', 'rein', 'stimmt',\n 'nehmen', 'kinder', 'eines', 'glauben', 'bringen', 'ganze', 'genug', 'scheiße', 'brauchen', 'gegen', 'moment', 'junge', 'steht', 'sonst', 'musik', 'arbeit', 'seid', 'ihrer', 'fragen', 'herr', 'dabei', 'heißt', 'familie', 'warten', 'niemand', 'sofort', 'bevor', 'jahre', 'einmal', 'problem', 'sohn', 'wann', 'brauche', 'fertig', 'halt', 'allein', 'beim', 'sprechen', 'beide', 'gefunden',\n 'hatten', 'sache', 'hilfe', 'verdammt', 'ne', 'jeder', 'warst', 'gern', 'konnte', 'darüber', 'halten', 'siehst', 'verstehe', 'jahren', 'kam', 'kind', 'wusste', 'wahr', 'seinen', 'dazu', 'bruder', 'daran', 'ihrem', 'denken', 'könnten', 'dank', 'würden', 'lieber', 'fall', 'deiner', 'sehe', 'egal', 'kennen', 'deinem', 'vergessen', 'frage', 'mache', 'komme', 'sage', 'mag',\n 'sieh', 'echt', 'gib', 'eigentlich', 'jeden', 'dad', 'gab', 'uhr', 'stadt', 'männer', 'baby', 'fahren', 'namen', 'bekommen', 'kopf', 'hi', 'gehe', 'kleine', 'später', 'glück', 'letzte', 'freunde', 'n', 'all', 'darauf', 'ende', 'dr.', 'bald', 'töten', 'dinge', 'meinst', 'toll', 'eins', 'minuten', 'vielen', 'bereit', 'weit', 'ahnung', 'seiner', 'bisschen',\n 'tür', 'auto', 'jungs', 'eure', 'augen', 'polizei', 'stehen', 'sterben', 'hätten', 'draußen', 'kenne', 'fast', 'runter', 'vorbei', 'treffen', 'gerne', 'dran', 'wurden', 'arbeiten', 'mom', 'verrückt', 'neue', 'ging', 'hinter', 'sorgen', 'einzige', 'jemanden', 'darum', 'tochter', 'braucht', 'idee', 'schwester', 'drin', 'ruhig', 'sah', 'ganzen', 'spät', 'ziemlich', 'solltest', 'name',\n 'sogar', 'kurz', 'kerl', 'frauen', 'liegt', 'suchen', 'finde', 'je', 'woher', 'lang', 'job', 'keiner', 'seinem', 'hört', 'verstehen', 'spielen', 's.', 'überhaupt', 'teufel', 'verstanden', 'verloren', 'große', 'hand', 'grund', 'jahr', 'kommst', 'mama', 'ruhe', 'gewesen', 'tod', 'stunden', 'hoffe', 'denkst', 'oben', 'gestern', 'versuchen', 'art', 'letzten', 'schatz', 'endlich',\n 'he', 'nimm', 'etwa', 'erzählt', 'läuft', 'schwer', 'anders', 'miss', 'musste', 'fünf', 'wasser', 'lässt', 'erste', 'versucht', 'gekommen', 'geschichte', 'wenig', 'holen', 'bedeutet', 'nett', 'wahrheit', 'woche', 'bringt', 'deshalb', 'welche', 'bestimmt', 'hoch', 'alter', 'sagst', 'schau', 'ah', 'land', 'zimmer', 'wagen', 'vier', 'gefallen', 'spaß', 'niemals', 'schuld', 'getötet',\n 'wollten', 'verlassen', 'zeigen', 'beste', 'ernst', 'unserer', 'denen', 'ort', 'bleibt', 'würdest', 'manchmal', 'glaubst', 'seite', 'lasst', 'zwischen', 'eben', 'während', 'spiel', 'nehme', 'ersten', 'guter', 'chance', 'freundin', 'krieg', 'gefällt', 'kleinen', 'erzählen', 'anderes', 'tage', 'entschuldigen', 'wichtig', 'gehst', 'allen', 'bett', 'mrs.', 'sachen', 'the', 'schlecht', 'schule', 'entschuldigung',\n 'wort', 'john', 'hättest', 'wären', 'typ', 'schlafen', 'äh', 'tu', 'euer', 'captain', 'gesicht', 'falls', 'neuen', 'bloß', 'unten', 'teil', 'beiden', 'mensch', 'kleiner', 'stellen', 'oft', 'sorge', 'gedacht', 'tust', 'trinken', 'einige', 'dies', 'ding', 'unseren', 'kriegen', 'blut', 'ehrlich', 'eltern', 'scheint', 'herz', 'jack', 'glücklich', 'alte', 'alt', 'bleib',\n 'wiedersehen', 'frei', 'wen', 'drauf', 'möglich', 'irgendwie', 'reicht', 'fest', 'besten', 'waffe', 'kaum', 'irgendwas', 'klingt', 'platz', 'brauchst', 'rede', 'papa', 'falsch', 'sondern', 'alten', 'nummer', 'früher', 'jungen', 'wohin', 'außer', 'früh', 'setzen', 'zuerst', 'wahrscheinlich', 'dürfen', 'jede', 'arsch', 'telefon', 'tue', 'kennst', 'willkommen', 'plan', 'großen', 'retten', 'hierher',\n 'wär', 'bring', 'fehler', 'wollt', 'dollar', 'zehn', 'allem', 'pass', 'nächste', 'stunde', 'hände', 'gegeben', 'menge', 'langsam', 'bereits', 'wartet', 'sechs', 'lieben', 'meines', 'büro', 'nächsten', 'gebe', 'wochen', 'ruf', 'schaffen', 'leider', 'scheiß', 'hölle', 'trotzdem', 'doktor', 'tja', 'new', 'voll', 'film', 'überall', 'hund', 'geworden', 'direkt', 'wolltest', 'tat',\n 'denkt', 'schiff', 'neues', 'wem', 'könig', 'danach', 'funktioniert', 'hattest', 'lernen', 'deswegen', 'wow', 'nennen', 'hm', 'feuer', 'laufen', 'alleine', 'erinnern', 'völlig', 'kleines', 'könnt', 'stelle', 'kumpel', 'verlieren', 'probleme', 'spricht', 'kaffee', 'luft', 'fand', 'i', 'entschuldige', 'ziehen', 'verschwinden', 'könntest', 'seht', 'aufhören', 'eigenen', 'richtige', 'unserem', 'suche', 'zwar',\n 'groß', 'hol', 'buch', 'krank', 'fühle', 'jedes', 'verstehst', 'wert', 'arzt', 'froh', 'versuche', 'straße', 'rufen', 'heiraten', 'super', 'sam', 'lebt', 'gutes', 'lasse', 'onkel', 'total', 'gebracht', 'party', 'erklären', 'spielt', 'wahl', 'vertrauen', 'damals', 'tagen', 'leicht', 'nachdem', 'gegangen', 'gefühl', 'kaufen', 'geschafft', 'typen', 'interessiert', 'möchten', 'halte', 'hält',\n 'glaub', 'irgendwo', 'stück', 'genauso', 'kennt', 'genommen', 'zukunft', 'weniger', 'cool', 'licht', 'getroffen', 'himmel', 'nachricht', 'drüben', 'passt', 'sagten', 'kümmern', 'laut', 'vergiss', 'angerufen', 'sitzen', 'daß', 'erde', 'großer', 'schlüssel', 'rest', 'passieren', 'eher', 'gefragt', 'gefängnis', 'opfer', 'körper', 'solche', 'mist', 'mr', 'findet', 'schreiben', 'böse', 'gesprochen', 'versuch',\n 'vorstellen', 'wovon', 'sobald', 'nochmal', 'herren', 'sex', 'waffen', 'wohnung', 'weh', 'heißen', 'krankenhaus', 'bringe', 'höre', 'millionen', 'klasse', 'hart', 'worden', 'sinn', 'außerdem', 'verletzt', 'ändern', 'erfahren', 'tragen', 'wenigstens', 'vorsichtig', 'daddy', 'stolz', 'stark', 'fällt', 'möchtest', 'leuten', 'besonders', 'schöne', 'schicken', 'person', 'schätze', 'solange', 'länger', 'großartig', 'lacht',\n 'anrufen', 'stand', 'redest', 'fühlen', 'erwartet', 'boden', 'boss', 'stimme', 'glaubt', 'still', 'sicherheit', 'setz', 'ma', 'mund', 'kämpfen', 'wisst', 'lachen', 'hörst', 'zeug', 'lustig', 'umbringen', 'sollst', 'hasse', 'schlimm', 'o', 'unglaublich', 'wärst', 'laden', 'führen', 'gestorben', 'schauen', 'meinung', 'lesen', 'mörder', 'frank', 'ähm', 'geschehen', 'geschäft', 'idiot', 'verzeihung',\n 'fliegen', 'zeig', 'team', 'general', 'mike', 'aufs', 'york', 'vorher', 'schluss', 'schneller', 'liebt', 'verdient', 'mögen', 'meisten', 'denk', 'umgebracht', 'perfekt', 'versprochen', 'handy', 'hinten', 'monate', 'erinnere', 'acht', 'arbeitet', 'fallen', 'rufe', 'nötig', 'a', 'mord', 'heraus', 'tages', 'unmöglich', 'liebling', 'charlie', 'tatsächlich', 'folgen', 'bitten', 'behalten', 'nähe', 'arbeite',\n 'joe', 'verdammte', 'plötzlich', 'lebens', 'hole', 'tisch', 'michael', 'hörte', 'jemals', 'liegen', 'verkaufen', 'gefährlich', 'anfangen', 'bekommt', 'machte', 'ha', 'hotel', 'hilft', 'werdet', 'meister', 'kampf', 'antwort', 'konnten', 'geschickt', 'jedem', 'obwohl', 'sieben', 'komisch', 'gewinnen', 'ihres', 'bezahlt', 'you', 'voller', 'unterwegs', 'dumm', 'ärger', 'bild', 'george', 'neu', 'bezahlen',\n 'dagegen', 'seien', 'starb', 'tom', 'monaten', 'leiche', 'niemanden', 'auge', 'arschloch', 'verheiratet', 'peter', 'zieh', 'nimmt', 'gerettet', 'agent', 'traum', 'entscheidung', 'schlimmer', 'regeln', 'fenster', 'fangen', 'fort', 'ständig', 'findest', 'gefahr', 'absolut', 'mary', 'augenblick', 'bescheid', 'rum', 'gedanken', 'werd', 'ziel', 'benutzt', 'bewegung', 'jemandem', 'wünschte', 'worte', 'kamen', 'welcher',\n 'zahlen', 'anfang', 'legen', 'erinnerst', 'anwalt', 'fahr', 'sitzt', 'hilf', 'offen', 'schönen', 'monsieur', 'müsste', 'arme', 'bier', 'fürs', 'partner', 'klein', 'david', 'klappe', 'süß', 'herum', 'finger', 'ehe', 'rolle', 'ließ', 'gleiche', 'monat', 'hochzeit', 'max', 'führt', 'paris', 'wach', 'wozu', 'arm', 'geschrieben', 'chef', 'benutzen', 'informationen', 'erledigt', 'hoffentlich',\n 'müsst', 'fühlt', 'tanzen', 'ansehen', 'darfst', 'zuhause', 'wunderbar', 'hältst', 'reise', 'gewonnen', 'dame', 'irgendwann', 'chffffff', 'alex', 'steckt', 'jedenfalls', 'schreit', 'tolle', 'rüber', 'tschüss', 'nennt', 'raum', 'heiß', 'foto', 'kalt', 'paul', 'irgendetwas', 'weile', 'bisher', 'minute', 'unbedingt', 'zug', 'sekunden', 'wofür', 'erzähl', 'nen', 'beweise', 'nahm', 'aller', 'freut',\n 'seele', 'schießen', 'müde', 'dauert', 'magst', 'harry', 'brief', 'gelernt', 'sucht', 'bekannt', 'weitere', 'unfall', 'dahin', 'kontrolle', 'beispiel', 'lady', 'dasselbe', 'herzen', 'schlagen', 'wütend', 'weise', 'damen', 'darin', 'gottes', 'holt', 'fehlt', 'vorsicht', 'heiße', 'beweisen', 'gehabt', 'zumindest', 'vermisst', 'hübsch', 'kriegt', 'verbindung', 'tief', 'richtung', 'lage', 'sowieso', 'kraft',\n 'normal', 'lauf', 'ehre', 'stell', 'geschenk', 'bar', 'tasche', 'gelesen', 'gekauft', 'wussten', 'gestohlen', 'hunger', 'leg', 'lügen', 'beziehung', 'ben', 'verschwunden', 'steh', 'nächstes', 'gearbeitet', 'preis', 'witz', 'meinte', 'liste', 'geist', 'neben', 'gesucht', 'firma', 'süße', 'rücken', 'schrecklich', 'letzter', 'verliebt', 'öffnen', 'redet', 'boot', 'seltsam', 'versteckt', 'fürchte', 'verschwinde',\n 'erwischt', 'verkauft', 'tante', 'erwarten', 'pferd', 'wunder', 'sauer', 'vermutlich', 'näher', 'major', 'jung', 'majestät', 'aussehen', 'ans', 'de', 'and', 'links', 'großes', 'welches', 'beschützen', 'geboren', 'erreichen', 'punkt', 'kindern', 'kirche', 'verraten', 'selber', 'befehl', 'colonel', 'fährt', 'zieht', 'geburtstag', 'haut', 'wette', 'reich', 'sekunde', 'fahre', 'schwöre', 'geredet', 'james',\n 'madame', 'eigene', 'zeiten', 'traurig', 'anruf', 'nachrichten', 'frieden', 'karte', 'güte', 'euren', 'diesmal', 'schade', 'persönlich', 'kriege', 'stirbt', 'bleibe', 'verändert', 'sonne', 'lieb', 'nämlich', 'letztes', 'bekam', 'ruft', 'professor', 'gericht', 'nase', 'ewig', 'singen', 'bank', 'beschäftigt', 'computer', 'yeah', 'toten', 'weihnachten', 'offensichtlich', 'naja', 'henry', 'gefühle', 'fuß', 'show',\n 'überraschung', 'geheimnis', 'fbi', 'kontakt', 'gold', 'drogen', 'regierung', 'wein', 'kriegst', 'ermordet', 'fotos', 'entfernt', 'geschlafen', 'manche', 'erledigen', 'ran', 'gegenüber', 'schlaf', 'lust', 'wunderschön', 'witzig', 'nick', 'zerstört', 'übrigens', 'willen', 'heim', 'richtigen', 'deines', 'namens', 'zeigt', 'geliebt', 'gehören', 'brachte', 'herrn', 'blick', 'besuch', 'schlechte', 'bewegen', 'haare', 'antworten',\n 'präsident', 'sagtest', 'hoffnung', 'stecken', 'lebe', 'rechts', 'interessant', 'entscheiden', 'miteinander', 'meint', 'liebst', 'indem', 'bleibst', 'kümmere', 'wohnen', 'weder', 'möglichkeit', 'kaputt', 'bekomme', 'flugzeug', 'vergangenheit', 'anderer', 'zweite', 'armee', 'jim', 'tee', 'entweder', 'weiss', 'don', 'detective', 'aufhalten', 'stellt', 'verspreche', 'überrascht', 'sauber', 'hau', 'mark', 'schlag', 'sheriff', 'untertitel',\n 'setzt', 'frag', 'vaters', 'nervös', 'gesellschaft', 'verstecken', 'schuldig', 'hals', 'schützen', 'besuchen', 'of', 'passen', 'überleben', 'erhalten', 'teilen', 'gebäude', 'schicksal', 'zeichen', 'richter', 'besorgt', 'küche', 'lief', 'vergnügen', 'wüsste', 'volk', 'lhr', 'herausfinden', 'königin', 'soldaten', 'feiern', 'situation', 'lag', 'gelassen', 'allerdings', 'soweit', 'gefahren', 'verstand', 'bord', 'schönes', 'jimmy',\n 'billy', 'angefangen', 'lee', 'fühlst', 'bob', 'mussten', 'rat', 'worauf', 'gebeten', 'tony', 'kamera', 'achtung', 'lieutenant', 'ganzes', 'schuhe', 'sarah', 'glückwunsch', 'niemandem', 'gibst', 'statt', 'übernehmen', 'gegend', 'wald', 'al', 'la', 'nimmst', 'danny', 'erkennen', 'glas', 'falsche', 'verantwortlich', 'jesus', 'stöhnt', 'herein', 'kleid', 'zerstören', 'jawohl', 'london', 'gegessen', 'abendessen',\n 'gesetz', 'gemeinsam', 'geholfen', 'erster', 'wohnt', 'schritt', 'guck', 'nahe', 'aussieht', 'beginnen', 'dachten', 'band', 'ungefähr', 'aufgabe', 'neun', 'furchtbar', 'drinnen', 'zuvor', 'charles', 'freue', 'amerika', 'übrig', 'spur', 'falschen', 'sergeant', 'melden', 'helfe', 'werfen', 'bill', 'haltet', 'erinnert', 'hängt', 'freude', 'ehemann', 'erschossen', 'verzeihen', 'schwein', 'uh', 'monster', 'entschieden',\n 'mission', 'verdammten', 'brauch', 'gewusst', 'vorne', 'stopp', 'übel', 'schlampe', 'schöner', 'adresse', 'unsinn', 'messer', 'gesund', 'respekt', 'pro', 'leisten', 'davor', 'richard', 'bedeuten', 'ball', 'mitnehmen', 'gespielt', 'to', 'schwierigkeiten', 'hälfte', 'kannte', 'stehe', 'maria', 'planeten', 'schwanger', 'gruppe', 'anna', 'verhaftet', 'deal', 'seines', 'irgendwelche', 'händen', 'versteht', 'drehen', 'eis',\n 'danken', 'erfolg', 'zufrieden', 'schließen', 'besorgen', 'wochenende', 'worüber', 'stimmen', 'nehmt', 'martin', 'm', 'witze', 'beine', 'verbrechen', 'bericht', 'nachts', 'eurer', 'prinzessin', 'schmerz', 'klingelt', 'position', 'echte', 'gleichen', 'fernsehen', 'wünsche', 'schließlich', 'gefangen', 'schätzchen', 'seh', 'schwierig', 'angebot', 'nah', 'jane', 'gewartet', 'kümmert', 'ring', 'rennen', 'lied', 'eier', 'welchen',\n 'sorry', 'fantastisch', 'schaut', 'hielt', 'falle', 'drink', 'insel', 'dauern', 'daher', 'zufällig', 'dorf', 'clark', 'bewegt', 'mitten', 'bullen', 'feind', 'einverstanden', 'neuer', 'bauen', 'trägt', 'hängen', 'freunden', 'deren', 'halb', 'verpasst', 'sprach', 'leise', 'armen', 'wusstest', 'fanden', 'unternehmen', 'träume', 'schläft', 'kostet', 'spiele', 'unseres', 'entlang', 'johnny', 'versprechen', 'tiere',\n 'freiheit', 'verdienen', 'aha', 'unterhalten', 'eingeladen', 'schaden', 'genannt', 'beenden', 'ray', 'geändert', 'thomas', 'lächerlich', 'geschlagen', 'park', 'schätzen', 'männern', 't', 'beginnt', 'ehren', 'größte', 'energie', 'fleisch', 'besonderes', 'besteht', 'reichen', 'robert', 'zeitung', 'worum', 'nachgedacht', 'betrunken', 'sowas', 'patienten', 'gespräch', 'leiden', 'taxi', 'tötet', 'see', 'unterschied', 'wind', 'singt',\n 'schreien', 'daniel', 'sahen', 'wand', 'bus', 'lhre', 'angriff', 'verhalten', 'loch', 'interesse', 'treten', 'quatsch', 'trifft', 'polizist', 'blumen', 'neuigkeiten', 'bringst', 'flasche', 'rief', 'schuss', 'fassen', 'meer', 'konntest', 'schafft', 'maschine', 'spreche', 'bein', 'eddie', 'bekommst', 'verbringen', 'bücher', 'blöd', 'frühstück', 'tommy', 'meter', 'bilder', 'aufpassen', 'claire', 'dessen', 'muß',\n 'freuen', 'engel', 'offenbar', 'gelegenheit', 'fang', 'lüge', 'ohren', 'au', 'angetan', 'beeil', 'brechen', 'brüder', 'zeitpunkt', 'keinem', 'ecke', 'brücke', 'druck', 'mitgebracht', 'seufzt', 'date', 'haufen', 'oma', 'auftrag', 'leer', 'entkommen', 'bobby', 'weißen', 'lösung', 'wart', 'pause', 'irre', 'gestellt', 'keller', 'gebrochen', 'weinen', 'nutzen', 'wünschen', 'fragt', 'maul', 'verantwortung',\n 'schloss', 'hut', 'lächeln', 'ryan', 'red', 'grad', 'zweiten', 'hinaus', 'mitkommen', 'vorhin', 'fahrt', 'gemeint', 'ernsthaft', 'gebaut', 'bombe', 'hasst', 'versteh', 'kosten', 'zeige', 'traf', 'eigenes', 'haar', 'fragte', 'jason', 'operation', 'befehle', 'schmerzen', 'erklärt', 'steve', 'dach', 'folge', 'gelaufen', 'schwarze', 'dankbar', 'gehirn', 'töte', 'mädels', 'mut', 'heilige', 'laura',\n 'tier', 'system', 'mannes', 'wahnsinn', 'nee', 'rose', 'club', 'geschlossen', 'hintern', 'is', 'thema', 'fiel', 'gehalten', 'dorthin', 'urlaub', 'steig', 'vorwärts', 'überprüfen', 'besseres', 'beweis', 'baum', 'gebt', 'funktionieren', 'anscheinend', 'lehrer', 'hoffen', 'bessere', 'isst', 'nachmittag', 'nem', 'risiko', 'chuck', 'knast', 'entschuldigt', 'gilt', 'held', 'daraus', 'erstes', 'fräulein', 'rachel',\n 'prima', 'brauchte', 'gewalt', 'dean', 'liebes', 'schaffst', 'nachdenken', 'tor', 'erfahrung', 'pläne', 'jagen', 'katze', 'runde', 'deutsche', 'schwanz', 'taten', 'lord', 'dringend', 'commander', 'großvater', 'sommer', 'gezeigt', 'hinterlassen', 'gewissen', 'getrunken', 'wahre', 'luke', 'kunden', 'kate', 'zeugen', 'geplant', 'amanda', 'erreicht', 'stören', 'stein', 'atmen', 'hose', 'weiße', 'sprichst', 'größer',\n 'schickt', 'city', 'prinz', 'behandelt', 'tote', 'überlegen', 'karten', 'it', 'd', 'restaurant', 'welchem', 'roger', 'natur', 'carter', 'emily', 'mami', 'verschwindet', 'lautet', 'streit', 'küssen', 'sprich', 'längst', 'fängt', 'drüber', 'gingen', 'erlaubt', 'einzigen', 'bad', 'schmeckt', 'kugel', 'normalerweise', 'schwarzen', 'rauf', 'flug', 'beruhigen', 'walter', 'halbe', 'dan', 'geschieht', 'einiges',\n 'entdeckt', 'morgens', 'schlechter', 'vollkommen', 'gelogen', 'verfolgt', 'college', 'weiteren', 'chris', 'louis', 'eh', 'schwert', 'hunde', 'steigen', 'verdammter', 'dürfte', 'riecht', 'labor', 'bat', 'tim', 'arthur', 'mindestens', 'fisch', 'eurem', 'füße', 'stehst', 'erschießen', 'kuchen', 'versuchte', 'zustand', 'wunsch', 'gäste', 'erwähnt', 'farbe', 'van', 'einigen', 'zufall', 'garten', 'junger', 'autos',\n 'abgesehen', 'fair', 'vertraut', 'koffer', 'hieß', 'kurs', 'wirkt', 'idioten', 'netter', 'seitdem', 'angegriffen', 'geschichten', 'wahnsinnig', 'ähnlich', 'lily', 'aufgeben', 'england', 'entführt', 'ms.', 'mistkerl', 'solchen', 'ner', 'geschossen', 'lager', 'besprechen', 'reihe', 'polizisten', 'vogel', 'legt', 'strand', 'amerikaner', 'schwarz', 'fern', 'fick', 'scherz', 'san', 'erzählte', 'wichser', 'jake', 'langweilig',\n 'womit', 'geschäfte', 'my', 'kapiert', 'nachher', 'verlangt', 'schlägt', 'überzeugt', 'irgendjemand', 'rot', 'soldat', 'vorbereitet', 'geschah', 'reisen', 'termin', 'gang', 'stehlen', 'rechte', 'rache', 'bemerkt', 'frankreich', 'stört', 'radio', 'beruhige', 'pferde', 'vertrag', 'arbeitest', 'dienst', 'zählt', 'fragst', 'wesen', 'bürgermeister', 'emma', 'fluss', 'woran', 'geblieben', 'durcheinander', 'me', 'ted', 'nette',\n 'test', 'mister', 'dadurch', 'direktor', 'wichtiger', 'kevin', 'scott', 'karriere', 'akte', 'erinnerung', 'großmutter', 'erzähle', 'lösen', 'bravo', 'griff', 'verfolgen', 'zweifel', 'such', 'sprache', 'nerven', 'officer', 'andy', 'langer', 'ziehe', 'entlassen', 'zweimal', 'abholen', 'washington', 'kollegen', 'doc', 'fass', 'szene', 'robin', 'scheinen', 'bösen', 'schaffe', 'pflicht', 'wache', 'neulich', 'beeilen',\n 'knie', 'alice', 'lauter', 'spannende', 'unschuldig', 'folgt', 'schutz', 'weshalb', 'geheiratet', 'woanders', 'wurdest', 'kuss', 'verhindern', 'erklärung', 'video', 'rom', 'klug', 'kräfte', 'verlangen', 'außerhalb', 'opa', 'selbstverständlich', 'aufstehen', 'hassen', 'pete', 'gebrauchen', 'geglaubt', 'milch', 'trink', 'gefeuert', 'erinnerungen', 'müssten', 'suchst', 'fährst', 'kochen', 'schwach', 'schreibt', 'schulden', 'hinein', 'simon',\n 'grenze', 'braut', 'gebraucht', 'peinlich', 'klappt', 'geheimnisse', 'joey', 'aufmerksamkeit', 'form', 'umsonst', 'kennenzulernen', 'überlebt', 'nirgendwo', 'meilen', 'einfacher', 'blöde', 'mond', 'ergibt', 'daten', 'merken', 'schande', 'fuck', 'fühlte', 'jenny', 'sieg', 'satt', 'blödsinn', 'adam', 'lisa', 'pfund', 'handeln', 'lois', 'enden', 'warm', 'raten', 'übersetzung', 'kunst', 'kapitän', 'desto', 'einsatz',\n 'schweigen', 'krankheit', 'toller', 'schatten', 'wachen', 'tatsache', 'eric', 'stock', 'chief', 'hingehen', 'verboten', 'gäbe', 'anzug', 'leichen', 'high', 'beendet', 'freitag', 'million', 'verflucht', 'dunkel', 'geb', 'enttäuscht', 'klopfen', 'spuren', 'dreck', 'seiten', 'mühe', 'gezogen', 'brian', 'kontrollieren', 'knochen', 'schick', 'getrennt', 'programm', 'grab', 'ebenso', 'trage', 'nachbarn', 'bieten', 'bestes',\n 'elizabeth', 'fuhr', 'verlässt', 'freundlich', 'dennoch', 'rauchen', 'dick', 'stuhl', 'dreh', 'bester', 'schicke', 'vergeben', 'ausgehen', 'behandeln', 'trotz', 'gast', 'ändert', 'passierte', 'toilette', 'annehmen', 'herzlichen', 'hexe', 'erwachsen', 'jerry', 'pistole', 'saß', 'dreht', 'aussage', 'liebte', 'street', 'genießen', 'eifersüchtig', 'derjenige', 'teuer', 'leo', 'zähne', 'beobachtet', 'gentlemen', 'wählen', 'helft',\n 'fliegt', 'theater', 'regen', 'feinde', 'william', 'erlauben', 'zulassen', 'schnappen', 'komplett', 'panik', 'flughafen', 'bewusst', 'deutschen', 'voraus', 'sterbe', 'solltet', 'begleiten', 'einander', 'fred', 'erlebt', 'weiterhin', 'stärker', 'fahrer', 'konzentrieren', 'streiten', 'angeht', 'selben', 'star', 'überzeugen', 'alkohol', 'übersetzt', 'verrückte', 'lch', 'king', 'begann', 'angenommen', 'weitermachen', 'echter', 'jackson', 'post',\n 'mitgenommen', 'botschaft', 'ideen', 'fehlen', 'aufgeregt', 'selbstmord', 'dumme', 'zurückkommen', 'irgendein', 'magie', 'phil', 'schlage', 'handelt', 'treffe', 'untersuchen', 'flucht', 'verliert', 'irgendeine', 'gegenteil', 'betrifft', 'scharf', 'gehofft', 'kennengelernt', 'schlimmste', 'projekt', 'trottel', 'immerhin', 'mehrere', 'erwarte', 'mochte', 'schwimmen', 'zählen', 'innerhalb', 'matt', 'blind', 'schwestern', 'code', 'alan', 'schlau', 'absicht',\n 'barry', 'spielst', 'zuletzt', 'oliver', 'art.', 'englisch', 'ohr', 'verletzen', 'song', 'schüler', 'schien', 'gewinnt', 'älter', 'merkwürdig', 'judy', 'vermisse', 'größe', 'tritt', 'trauen', 'präsidenten', 'trick', 'harvey', 'doug', 'roten', 'überlegt', 'größten', 'sonntag', 'zwölf', 'vorstellung', 'schrieb', 'reinkommen', 'killer', 'unterstützung', 'antun', 'rechnung', 'dieselbe', 'verändern', 'möglicherweise', 'definitiv', 'locker',\n 'ed', 'vincent', 'ums', 'abends', 'frisch', 'kohle', 'fing', 'hure', 'cousin', 'familien', 'einsam', 'lebendig', 'heiligen', 'knapp', 'ebenfalls', 'überprüft', 'artikel', 'gesetzt', 'jederzeit', 'kompliziert', 'spüren', 'signal', 'amy', 'stich', 'kino', 'probieren', 'tode', 'wundervoll', 'tanz', 'geöffnet', 'kerle', 'begraben', 'prozent', 'stoppen', 'hoheit', 'riesen', 'rote', 'zugang', 'liest', 'vorn',\n 'wichtige', 'aufmachen', 'kelly', 'sexy', 'erlaubnis', 'grace', 'big', 'story', 'madam', 'leichter', 'halben', 'filme', 'priester', 'herauszufinden', 'packen', 'dritte', 'inzwischen', 'larry', 'presse', 'sitze', 'machten', 'geklaut', 'helden', 'susan', 'geduld', 'bühne', 'reparieren', 'hä', 'usa', 'gerechtigkeit', 'fälle', 'selten', 'anrufe', 'unterschreiben', 'julia', 'drücken', 'mrs', 'lügner', 'endet', 'dave',\n 'medizin', 'schreibe', 'verhaften', 'prozess', 'samstag', 'amen', 'motor', 'marie', 'abhauen', 'chaos', 'schönheit', 'beinahe', 'lebst', 'tolles', 'anhalten', 'fremden', 'hof', 'akzeptieren', 'norden', 'ärzte', 'anziehen', 'dingen', 'umgehen', 'bauch', 'gesamte', 'hübsche', 'ertragen', 'kiste', 'brennt', 'teile', 'deckung', 'landen', 'berg', 'straßen', 'aufgenommen', 'gerufen', 'untersuchung', 'alarm', 'blieb', 'vertraue',\n 'extra', 'entspann', 'beobachten', 'eindruck', 'tschüs', 'babys', 'wehtun', 'zog', 'iss', 'herrgott', 'echten', 'springen', 'nackt', 'existiert', 'befreien', 'gerät', 'montag', 'gezwungen', 'perfekte', 'erzählst', 'bastard', 'interessieren', 'schlechten', 'hank', 'steigt', 'st.', 'on', 'carl', 'gekriegt', 'fliehen', 'trug', 'freundschaft', 'rate', 'papiere', 'abgeschlossen', 'schnauze', 'beruf', 'gebiet', 'jeff', 'jedoch',\n 'beten', 'verbunden', 'sprachen', 'verräter', 'wichtigste', 'prost', 'brust', 'aufgehört', 'kleider', 'jacke', 'bestellt', 'herkommen', 'wild', 'nenne', 'angesehen', 'zuhören', 'trennen', 'schlafzimmer', 'vorschlag', 'meins', 'gift', 'ton', 'vermissen', 'angekommen', 'beantworten', 'deutlich', 'träumen', 'verwirrt', 'akten', 'riskieren', 'b', 'victor', 'find', 'erkannt', 'beerdigung', 'müll', 'weisst', 'möge', 'stellte', 'mitte',\n 'erleben', 'geburt', 'decke', 'ch00ffff', 'wege', 'schritte', 'gibts', 'gemeldet', 'hilfst', 'mittagessen', 'weint', 'vernichten', 'rock', 'chicago', 'ellen', 'crew', 'roy', 'türen', 'gewehr', 'elena', 'arbeitete', 'spiegel', 'hauen', 'geraten', 'dritten', 'ross', 'julie', 'wetter', 'schwul', 'regel', 'befindet', 'einheit', 'german', 'armer', 'gucken', 'anstatt', 'champagner', 'gründe', 'strafe', 'smith',\n 'öfter', 'anne', 'zelle', 'langen', 'altes', 'ruiniert', 'jonathan', 'kleidung', 'gras', 'kenn', 'agenten', 'herausgefunden', 'annie', 'rechten', 'brot', 'berlin', 'erfreut', 'lügt', 'nehm', 'harte', 'staaten', 'station', 'gaben', 'hinterher', 'verpassen', 'geholt', 'jesse', 'hemd', 'trinke', 'klären', 'praktisch', 'theorie', 'zunge', 'notfall', 'besseren', 'winter', 'c', 'versuchst', 'dahinter', 'schwere',\n 'feuern', 'lucy', 'schießt', 'anführer', 'schief', 'blau', 'bestens', 'wartest', 'gehts', 'morgan', 'unrecht', 'leck', 'wonach', 'entwickelt', 'bedeutung', 'strom', 'krebs', 'gemein', 'wessen', 'minister', 'lhnen', 'quelle', 'zahl', 'schiffe', 'schüsse', 'bricht', 'talent', 'spitze', 'fernseher', 'treiben', 'ausgezeichnet', 'tatort', 'möglichkeiten', 'trinkt', 'esse', 'cop', 'details', 'täter', 'wahren', 'dieb',\n 'offiziell', 'dienen', 'westen', 'entscheidungen', 'dauernd', 'geschmack', 'gegenseitig', 'gewählt', 'charlotte', 'pech', 'verteidigen', 'schauspieler', 'personen', 'überlassen', 'publikum', 'trägst', 'wechseln', 'begegnet', 'betrogen', 'besucht', 'vertrau', 'europa', 'carrie', 'patrick', 'deutschland', 'süßer', 'loswerden', 'melde', 'maggie', 'bestätigt', 'gas', 'sturm', 'setze', 'briefe', 'null', 'penny', 'schlafe', 'wirken', 'geführt', 'starten',\n 'götter', 'festhalten', 'geheim', 'übergeben', 'cia', 'abteilung', 'papier', 'wetten', 'gefolgt', 'verschiedene', 'gleichzeitig', 'genie', 'hungrig', 'inspektor', 'zwingen', 'atmet', 'kuh', 'unterstützen', 'geworfen', 'verlor', 'süden', 'pater', 'menschheit', 'versteck', 'tötete', 'fähigkeiten', 'beruhigt', 'rechtzeitig', 'streng', 'sendung', 'gelebt', 'treppe', 'kim', 'richtiger', 'aufnehmen', 'wolf', 'pa', 'öffnet', 'dämon', 'wut',\n 'schlange', 'medikamente', 'geschenkt', 'nenn', 'gelegt', 'anfassen', 'pizza', 'schlechtes', 'hütte', 'mantel', 'behauptet', 'kilometer', 'beeilung', 'angeblich', 'reiten', 'helen', 'mittag', 'gewarnt', 'wohne', 'las', 'dunkelheit', 'spazieren', 'angel', 'hiermit', 'schließt', 'phoebe', 'vieles', 'erfüllt', 'tausend', 'sack', 'eindeutig', 'unterhaltung', 'gründen', 'km', 'zugeben', 'mittel', 'explosion', 'gefangenen', 'taylor', 'frische',\n 'verdächtigen', 'neugierig', 'leitung', 'kennenlernen', 'fliege', 'lebte', 'menschliche', 'anderem', 'auseinander', 'fressen', 'beides', 'ficken', 'stoff', 'spüre', 'eilig', 'stammt', 'vorgestellt', 'linda', 'welch', 'wichtiges', 'no', 'gehörte', 'mhm', 'glaubte', 'oberst', 'schrank', 'fremde', 'gnade', 'chloe', 'yo', 'entspannen', 'virus', 'schläfst', 'einladung', 'krieger', 'vernünftig', 'fein', 'greifen', 'whoa', 'kyle',\n 'schickte', 'per', 'mitglied', 'einziger', 'umzubringen', 'zurückkehren', 'feld', 'mexiko', 'erschaffen', 'information', 'hergekommen', 'beweg', 'stärke', 'vermögen', 'verbracht', 'gewisse', 'waschen', 'howard', 'staat', 'geister', 'behaupten', 'schrei', 'würdet', 'vögel', 'warnen', 'albert', 'chancen', 'treibt', 'nannte', 'vermute', 'mitternacht', 'jones', 'freundinnen', 'lecker', 'klinik', 'dicht', 'befinden', 'ließen', 'bürger', 'verursacht',\n 'hammer', 'klang', 'internet', 'aufregend', 'grenzen', 'politik', 'superman', 'zurecht', 'besitz', 'cops', 'eingesperrt', 'irren', 'kommando', 'schlug', 'krankenwagen', 'love', 'öffne', 'karen', 'richten', 'mademoiselle', 'erfunden', 'schnee', 'fühl', 'behalte', 'beschützt', 'punkte', 'entfernen', 'abgehauen', 'geträumt', 'stefan', 'dämonen', 'tränen', 'erfolgreich', 'volle', 'wilson', 'caroline', 'höher', 'happy', 'brille', 'musstest',\n 'heimat', 'terry', 'liebsten', 'bye', 'leiter', 'sean', 'kauf', 'spinnst', 'werk', 'cent', 'schlacht', 'beziehungen', 'abgemacht', 'schreie', 'hmm', 'bestätigen', 'erschreckt', 'offizier', 'that', 'sara', 'affäre', 'empfangen', 'zweck', 'kämpfe', 'ergeben', 'china', 'fange', 'häuser', 'verliere', 'gedanke', 'tausende', 'heutzutage', 'gefühlt', 'schnitt', 'carlos', 'harold', 'lebend', 'real', 'holz', 'kaiser',\n 'spielte', 'begonnen', 'ziehst', 'gelandet', 'scheidung', 'bart', 'beschlossen', 'klo', 'riechen', 'vergisst', 'begeistert', 'ei', 'durchs', 'geil', 'nieder', 'erkläre', 'schreckliche', 'beeindruckt', 'vince', 'aufgegeben', 'aufgrund', 'momentan', 'solch', 'meistens', 'stress', 'sterne', 'heilen', 'soviel', 'kannten', 'stattdessen', 'aye', 'dinger', 'stimmung', 'bulle', 'aufgefallen', 'kämpft', 'geräusch', 'künstler', 'wachsen', 'verurteilt',\n 'himmels', 'tyler', 'urteil', 'schweine', 'nettes', 'house', 'verlust', 'verließ', 'wirf', 'wenige', 'willie', 'schulter', 'kalifornien', 'lernt', 'beigebracht', 'normale', 'anbieten', 'verwenden', 'gratuliere', 'fluch', 'rick', 'übers', 'grün', 'unterricht', 'dachtest', 'verarschen', 'gewöhnt', 'anklage', 'tollen', 'lippen', 'fett', 'lege', 'feigling', 'achten', 'gary', 'erfährt', 'gewohnt', 'jessica', 'äußerst', 'einladen',\n 'käse', 'aufwachen', 'verfügung', 'uniform', 'zusehen', 'board.tv4user.de', 'gesundheit', 'abenteuer', 'hosen', 'kurze', 'scheck', 'täglich', 'fresse', 'übernehme', 'wiederholen', 'bestellen', 'freiwillig', 'cole', 'universum', 'zeuge', 'west', 'marshall', 'fähig', 'revier', 'reifen', 'mum', 'führe', 'durchgemacht', 'tests', 'führte', 'schenken', 'schädel', 'realität', 'april', 'albern', 'brav', 'schwerer', 'jagd', 'versagt', 'truck',\n 'steckst', 'geschenke', 'sicherlich', 'öffentlichkeit', 'merkt', 'verbrecher', 'maske', 'verstärkung', 'liefern', 'jo', 'starke', 'grunde', 'gordon', 'würd', 'verschwand', 'schulde', 'russen', 'führer', 'gemerkt', 'ciao', 'loslassen', 'berichten', 'verabschieden', 'antrag', 'schieß', 'abby', 'benehmen', 'verdacht', 'hübsches', 'schreibtisch', 'e', 'vampir', 'rory', 'probe', 'schaff', 'verzeih', 'patient', 'geküsst', 'ertönt', 'nahmen',\n 'zahlt', 'vorbereiten', 'verbrannt', 'verdammtes', 'frankie', 'informiert', 'einziges', 'zucker', 'stinkt', 'schnappt', 'schreib', 'standen', 'klamotten', 'heil', 'besitzer', 'marcus', 'tess', 'drum', 'tasse', 'hinweis', 'verteidigung', 'lügst', 'lies', 'magen', 'enterprise', 'michelle', 'beeilt', 'tunnel', 'einst', 'behandlung', 'serie', 'applaus', 'markt', 'korrekt', 'besessen', 'bewahren', 'nr.', 'pack', 'gekämpft', 'black',\n 'angreifen', 'tiefer', 'huh', 'truppen', 'kommandant', 'osten', 'elf', 'beeindruckend', 'besitzt', 'ho', 'heut', 'clever', 'verrückten', 'freien', 'hass', 'antworte', 'posten', 'schneiden', 'sammeln', 'gesteckt', 'wissenschaft', 'ursache', 'gewiss', 'bereich', 'catherine', 'meinetwegen', 'l.a.', 'senator', 'ausziehen', 'verzweifelt', 'jess', 'anteil', 'stets', 'ritter', 'viertel', 'roman', 'pünktlich', 'erfüllen', 'kauft', 'molly',\n 'basis', 'eva', 'schock', 'empfang', 'wiederhole', 'wünscht', 'besondere', 'titel', 'stil', 'fingerabdrücke', 'einfluss', 'anweisungen', 'zahle', 'shield', 'opfern', 'blaue', 'sparen', 'weiteres', 'gehörst', 'farm', 'erstaunlich', 'schwachsinn', 'miete', 'verwandelt', 'daneben', 'klaus', 'bereiten', 'wüste', 'prüfen', 'gabe', 'hundert', 'erscheinen', 'laß', 'besiegen', 'verpiss', 'umständen', 'angelegenheit', 'landes', 'dienstag', 'folgendes',\n 'fürchten', 'mordes', 'nennst', 'angestellt', 'training', 'aufgetaucht', 'rausfinden', 'ächzt', 'rauskommen', 'planet', 'suppe', 'erwischen', 'sitz', 'johnson', 'vorteil', 'for', 'rosa', 'tour', 'amerikanische', 'schönste', 'rufst', 'berührt', 'französisch', 'gouverneur', 'angeles', 'kaufe', 'stern', 'gedächtnis', 'wirklichkeit', 'bestraft', 'kreis', 'reine', 'edward', 'schlimmes', 'bestehen', 'jeannie', 'erscheint', 'staatsanwalt', 'ewigkeit', 'störung',\n 'hässlich', 'lauft', 'angezogen', 'señor', 'half', 'sollt', 'martha', 'tiger', 'zigarette', 'mutig', 'ausruhen', 'andrew', 'linken', 'hauptmann', 'umstände', 'not', 'unglück', 'eng', 'white', 'lucas', 'üben', 'wissenschaftler', 'gelöst', 'reaktion', 'morde', 'dusche', 'mitarbeiter', 'your', 'bedroht', 'gehöre', 'befreit', 'stöhnen', 'reagiert', 'identität', 'rund', 'texas', 'fieber', 'hirn', 'leiten', 'donnerstag',\n 'leonard', 'unheimlich', 'mulder', 'jahrhundert', 'irgend', 'diener', 'bruce', 'extrem', 'ausweis', 'sicht', 'sport', 'juden', 'studiert', 'angelogen', 'schaue', 'little', 'sally', 'text', 'earl', 'nebenan', 'todd', 'lektion', 'mäuse', 'staub', 'sophie', 'kugeln', 'dutzend', 'ratte', 'mitleid', 'testen', 'auftritt', 'gegner', 'joseph', 'verdienst', 'langsamer', 'wunde', 'linie', 'bedrohung', 'bauer', 'kurzem',\n 'fische', 'einkaufen', 'kreuz', 'afrika', 'begangen', 'el', 'nachsehen', 'junior', 'bäume', 'leidenschaft', 'geliebte', 'bereuen', 'spieler', 'berge', 'verwendet', 'steuern', 'gekümmert', 'voran', 'wieviel', 'barney', 'graf', 'verabredung', 'verlasse', 'überfallen', 'donna', 'umdrehen', 'damon', 'kilo', 'diego', 'negativ', 'schild', 'tanzt', 'verbrennen', 'gefreut', 'penner', 'blauen', 'jay', 'stücke', 'angela', 'kühlschrank',\n 'identifizieren', 'lehrerin', 'francisco', 'kameras', 'zentrale', 'jäger', 'josh', 'wayne', 'wenden', 'we', 'holst', 'suchte', 'start', 'füßen', 'unglücklich', 'frohe', 'sand', 'pfarrer', 'plus', 'nancy', 'brachten', 'zauber', 'berühren', 'rückkehr', 'hafen', 'indianer', 'miller', 'verschwenden', 'untersucht', 'königs', 'jean', 'lese', 'stahl', 'hättet', 'affen', 'worten', 'kindheit', 'gewollt', 'op', 'vermeiden',\n 'fabrik', 'aussagen', 'wunderbare', 'grandpa', 'miststück', 'verrückter', 'lane', 'jungfrau', 'einfache', 'nate', 'laufe', 'reingelegt', 'seltsame', 'heiratet', 'angenehm', 'daheim', 'planen', 'klauen', 'geruch', 'marty', 'klingen', 'tina', 'nächster', 'hörten', 'jackie', 'trafen', 'ungern', 'abgelehnt', 'erstens', 'abmachung', 'appetit', 'miami', 'zeigte', 'fan', 'hohen', 'alf', 'ladys', 'sms', 'verkauf', 'jamie',\n 'verbergen', 'sorgt', 'karl', 'sohnes', 'berühmt', 'aussteigen', 'bonnie', 'ginge', 'reingehen', 'durfte', 'korrektur', 'wirft', 'titten', 'betreten', 'todes', 'one', 'doctor', 'blöden', 'miles', 'rausholen', 'hohe', 'aufnahme', 'by', 'holmes', 'hübscher', 'vegas', 'manager', 'stellung', 'höhle', 'schokolade', 'angeboten', 'befreundet', 'weib', 'ausgerechnet', 'walker', 'beibringen', 'nelson', 'ex', 'belohnung', 'seelen',\n 'steine', 'garage', 'scheißkerl', 'gestört', 'cooper', 'ruhen', 'pillen', 'gepäck', 'carol', 'norman', 'zoe', 'amerikanischen', 'telefonieren', 'heirate', 'erkenne', 'funk', 'grüß', 'hurensohn', 'mögliche', 'spring', 'uni', 'scheinbar', 'fakten', 'informieren', 'jugend', 'feier', 'wenigen', 'söhne', 'benzin', 'nix', 'vampire', 'erkennt', 'sicherer', 'zigaretten', 'dummes', 'mauer', 'erneut', 'flügel', 'schluck', 'hierbleiben',\n 'abschluss', 'christus', 'bezahle', 'böses', 'dummkopf', 'gerüchte', 'eingestellt', 'm.', 'weitergehen', 'technik', 'ali', 'bezweifle', 'piper', 'over', 'gekostet', 'anzeige', 'wohnst', 'hans', 'ergebnis', 'bedingungen', 'brad', 'aufzuhalten', 'versprich', 'verdiene', 'geschnappt', 'francis', 'eile', 'innen', 'italien', 'einig', 'verhandeln', 'weswegen', 'nützlich', 'inneren', 'gentleman', 'felix', 'vergesse', 'dunkle', 'warnung', 'gemeinde',\n 'diamanten', 'wächst', 'gewöhnlich', 'seil', 'bär', 'euro', 'großartige', 'beth', 'ware', 'traurige', 'persönliche', 'figur', 'time', 'roboter', 'anschauen', 'kürzlich', 'material', 'paula', 'käme', 'stellst', 'bereitet', 'einfallen', 'käfig', 'fantasie', 'brach', 'satz', 'kommissar', 'exzellenz', 'schuldest', 'nass', 'rächen', 'womöglich', 'begrüßen', 'lou', 'davis', 'überraschen', 'menschlichen', 'repariert', 'führung', 'gestanden',\n 'jacob', 'schütze', 'störe', 'nina', 'filmen', 'jobs', 'maschinen', 'unterlagen', 'palast', 'graben', 'kette', 'auftauchen', 'interessante', 'wovor', 'springt', 'terroristen', 'stan', 'bekämpfen', 'lärm', 'flehe', 'aufgewachsen', 'arbeiter', 'größere', 'humor', 'betrachten', 'be', 'organisation', 'widerstand', 'bergen', 'studio', 'hausaufgaben', 'vögeln', 'bescheuert', 'weggehen', 'teller', 'original', 'revolution', 'hitler', 'mädel', 'verbinden',\n 'nathan', 'ermittlungen', 'steck', 'wäsche', 'rätsel', 'besonderen', 'hunderte', 'versetzt', 'bibel', 'heiliger', 'reiß', 'kopie', 'besitzen', 'zeitungen', 'zurückgekommen', 'süßes', 'barbara', 'ungewöhnlich', 'höhe', 'geschaffen', 'beschreiben', 'ausgesucht', 'notwendig', 'dunklen', 'ignorieren', 'toter', 'deck', 'narr', 'scheißegal', 'höchstens', 'übersehen', 'geirrt', 'darunter', 'außen', 'einzig', 'stirbst', 'lhren', 'spielchen', 'girl', 'fahrrad',\n 'nutte', 'wilde', 'jordan', 'bequem', 'rauch', 'verschiedenen', 'kamst', 'l', 'betty', 'pool', 'hubschrauber', 'wüssten', 'erstmal', 'kollege', 'vernichtet', 'gesichter', 'derselbe', 'hattet', 'konto', 'freie', 'casey', 'haken', 'munition', 'sünde', 'militär', 'gefasst', 'anzeichen', 'geklappt', 'hintergrund', 'erwähnen', 'tipp', 'reißen', 'keins', 'genial', 'berichte', 'kram', 'schnapp', 'solle', 'randy', 'umziehen',\n 'zunächst', 'keinerlei', 'typisch', 'bietet', 'leb', 'technologie', 'john-boy', 'ruinieren', 'jünger', 'poirot', 'umso', 'starben', 'rette', 'triffst', 'unhöflich', 'safe', 'anzurufen', 'universität', 'mai', 'heben', 'koch', 'derselben', 'katastrophe', 'male', 'olivia', 'prüfung', 'brown', 'gesetze', 'meeting', 'versicherung', 'getragen', 'ehefrau', 'mitmachen', 'tauschen', 'ergebnisse', 'boston', 'reg', 'einstellen', 'reagieren', 'gefehlt',\n 'verwandeln', 'gedauert', 'senden', 'blair', 'reporter', 'abgeben', 'mm', 'parker', 'anhören', 'bibliothek', 'japan', 'hinsetzen', 'hannah', 'serena', 'motiv', 'paige', 'schalten', 'derek', 'gewöhnen', 'lernte', 'vereinigten', 'gewicht', 'zweiter', 'badezimmer', 'schieben', 'dreimal', 'weich', 'echtes', 'zweitens', 'drachen', 'bahnhof', 'erschöpft', 'genauer', 'verlange', 'spanisch', 'verrat', 'hexen', 'live', 'legende', 'taub',\n 'freu', 'konzert', 'hopp', 'wiederzusehen', 'doppelt', 'last', 'vergleich', 'böser', 'herzlich', 'monica', 'taschen', 'genügt', 'besucher', 'spanien', 'großzügig', 'teddy', 'hauses', 'leihen', 'scheiden', 'einstellung', 'köstlich', 'watson', 'einheiten', 'wichtigen', 'go', 'warne', 'russland', 'angeschossen', 'sammy', 'pierre', 'sklaven', 'laune', 'gesamten', 'stille', 'asche', 'geflogen', 'spion', 'what', 'aaron', 'weihnachtsmann',\n 'hervorragend', 'can', 'verärgert', 'puppe', 'überfall', 'unwichtig', 'santa', 'linke', 'übung', 'buffy', 'franzosen', 'wehgetan', 'schwäche', 'couch', 'cousine', 'grant', 'atme', 'irgendeinem', 'unterstützt', 'oscar', 'ausdruck', 'pleite', 'beleidigt', 'knopf', 'stop', 'schlimme', 'beweist', 'katie', 'dramatische', 'heutigen', 'leere', 'island', 'shane', 'daisy', 'trinkst', 'heimlich', 'eingehen', 'rad', 'greift', 'mächtig',\n 'williams', 'sinnlos', 'versaut', 'netz', 'atem', 'anstellen', 'milliarden', 'flotte', 'umgebung', 'mitbringen', 'beteiligt', 'dunkeln', 'entwickeln', 'schämen', 'erwachsene', 'zack', 'durchsuchen', 'hollywood', 'rollen', 'vergesst', 'tricks', 'plätze', 'gefangene', 'sünden', 'sender', 'verlass', 'räumen', 'lerne', 'rettet', 'hinweise', 'ausreden', 'alexander', 'mommy', 'diejenige', 'nächte', 'herrscht', 'bud', 'jahres', 'dna', 'romantisch',\n 'flüstert', 'drück', 'jeremy', 'bedanken', 'verabredet', 'pilot', 'colt', 'nigger', 'reizend', 'grade', 'stanley', 'leib', 'stecke', 'scheisse', 'ärztin', 'vergewaltigt', 'mußt', 'lieferung', 'botschafter', 'studieren', 'köpfe', 'duschen', 'kopfschmerzen', 'öl', 'knarre', 'sekretärin', 'phase', 'handschellen', 'lewis', 'versehen', 'bande', 'treu', 'positiv', 'meiste', 'museum', 'albtraum', 'margaret', 'verlobt', 'besiegt', 'existieren',\n 'könne', 'proben', 'beschissen', 'gewinne', 'personal', 'christian', 'bewaffnet', 'fällen', 'wecken', 'wirkung', 'kurt', 'connor', 'rebecca', 'therapie', 'travis', 'amüsieren', 'ordentlich', 'weglaufen', 'aufgewacht', 'nähern', 'decken', 'sinne', 'leutnant', 'zauberer', 'hogan', 'bittet', 'ankunft', 'klopft', 'abstand', 'bewusstsein', 'nation', 'kontrolliert', 'treffer', 'abnehmen', 'ratten', 'anwälte', 'tempel', 'vergiftet', 'kunde', 'august',\n 'wunden', 'unangenehm', 'ausrüstung', 'segen', 'präsentiert', 'schließ', 'kehle', 'krone', 'garantiert', 'durchsucht', 'president', 'tracy', 'verfluchte', 'bestimmten', 'clay', 'ladies', 'b.', 'ladung', 'beinen', 'hell', 'kent', 'kapitel', 'chase', 'benutze', 'alibi', 'ziele', 'bestie', 'gus', 'nirgends', 'wohnzimmer', 'beute', 'bau', 'brennen', 'lex', 'durst', 'logan', 'schwarzer', 'schmutzig', 'liebhaber', 'ersetzen',\n 'juli', 'verfahren', 'kirk', 'stiefel', 'inspector', 'allzu', 'camp', 'dürft', 'orten', 'hitze', 'spielzeug', 'tv', 'gloria', 'wolle', 'knurrt', 'meldet', 'rita', 'zone', 'trocken', 'lincoln', 'schreibst', 'audrey', 'quinn', 'probier', 'le', 'kids', 'unterschrieben', 'do', 'heulen', 'entschlossen', 'paket', 'gefiel', 'bekamen', 'netten', 'geheime', 'jennifer', 'aktiviert', 'ausweg', 'hinweg', 'schmuck',\n 'ausgang', 'wunderschöne', 'zurückkommt', 'ann', 'illegal', 'ferien', 'persönlichen', 'geiseln', 'segne', 'normaler', 'steuer', 'aufgepasst', 'murphy', 'raumschiff', 'dummen', 'weißer', 'ausbildung', 'klavier', 'hauptsache', 'admiral', 'entgegen', 'fasse', 'strecke', 'julian', 'version', 'hilfreich', 'schweren', 'h', 'jahrelang', 'leeren', 'küste', 'baron', 'behörden', 'grüße', 'geklärt', 'bruders', 'kaufte', 'stone', 'puls', 'blue',\n 'flur', 'denselben', 'rettung', 'widerlich', 'parkplatz', 'katzen', 'laster', 'sozusagen', 'mittwoch', 'unschuldige', 'abwarten', 'grandma', 'florida', 're', 'grünen', 'könntet', 'aufnahmen', 'vision', 'schauspielerin', 'passe', 'sing', 'glückliche', 'highschool', 'friedhof', 'irrtum', 'klienten', 'nervt', 'leidet', 'reverend', 'trainieren', 'gegenwart', 'zurückbringen', 'herman', 'protokoll', 'studenten', 'durchaus', 'grausam', 'höchste', 'verwickelt', 'schmecken',\n 'klappen', 'apropos', 'liz', 'alfred', 'ansonsten', 'wade', 'missverständnis', 'mitglieder', 'motorrad', 'mickey', 'blicken', 'glücklicher', 'hübschen', 'dicke', 'gewünscht', 'gejagt', 'diejenigen', 'diskutieren', 'pinkeln', 'huhn', 'erheben', 'paradies', 'tagebuch', 'möglichen', 'jenseits', 'arschlöcher', 'apartment', 'mason', 'pfeift', 'dieselben', 'wilden', 'vergaß', 'enttäuschen', 'greg', 'konsequenzen', 'fleck', 'macgyver', 'führerschein', 'online', 'bete',\n 'verdächtige', 'enkel', 'normalen', 'stift', 'interview', 'süßen', 'riesige', 'aussicht', 'ned', 'wiederkommen', 'werbung', 'warf', 'telefoniert', 'anblick', 'einzelnen', 'teppich', 'hielten', 'handel', 'gekannt', 'getrieben', 'trainer', 'scully', 'schuh', 'bomben', 'kämpfer', 'victoria', 'bedenken', 'sitzung', 'ken', 'sicheren', 'verkaufe', 'ron', 'tapfer', 'experiment', 'besorge', 'tiefe', 'narren', 'abgeholt', 'abhalten', 'bestimmte',\n 'laufenden', 'auftaucht', 'school', 'löschen', 'tara', 'sebastian', 'mies', 'sarg', 'r', 'vertragen', 'gebissen', 'geheimen', 'drinks', 'schlief', 'tradition', 'soeben', 'komische', 'schultz', 'aufgehalten', 'fähigkeit', 'attraktiv', 'begriff', 'versichere', 'schilde', 'legte', 'mitteilen', 'sdh', 'gemütlich', 'muster', 'versprach', 'überwachen', 'eingeschlafen', 'schlimmsten', 'verlierst', 'einzelne', 'vergib', 'vorbeikommen', 'aua', 'brüste', 'sandwich',\n 'gewinner', 'verständnis', 'g', 'raymond', 'papst', 'toast', 'matthew', 'einsteigen', 'löwen', 'einsetzen', 'gewinn', 'schüchtern', 'scheinst', 'pflanzen', 'green', 'sheldon', 'christopher', 'hätt', 'coach', 'werte', 'modell', 'übernimmt', 'walton', 'heftig', 'vorfall', 'motel', 'teams', 'irgendeinen', 'müsstest', 'freier', 'zirkus', 'ruhm', 'zurzeit', 'ausmachen', 'rezept', 'töchter', 'laute', 'akzeptiert', 'geschwindigkeit', 'beliebt',\n 'verpflichtet', 'betrüger', 'lohnt', 'märchen', 'blöder', 'becky', 'wille', 'hügel', 'königreich', 'dennis', 'kehren', 'baut', 'chinesen', 'gesichert', 'michel', 'ruth', 'block', 'belogen', 'malen', 'kofferraum', 'road', 'bursche', 'erin', 'geständnis', 'ausgegangen', 'begreifen', 'dana', 'blitz', 'löst', 'furcht', 'jersey', 'ernstes', 'verteilt', 'bezüglich', 'faszinierend', 'aufmerksam', 'aufregung', 'wendy', 'ethan', 'orte',\n 'entführung', 'keucht', 'erhielt', 'treue', 'felsen', 'malcolm', 'kurzen', 'zorn', 'taucht', 'bestimmen', 'ausgesetzt', 'zurückgeben', 'verkehr', 'bewiesen', 'generation', 'liebste', 'ausrichten', 'ausnahme', 'ebene', 'herrlich', 'stürzen', 'herausforderung', 'gefälligst', 'farben', 'geliebten', 'ankommen', 'tempo', 'unterbrechen', 'kindes', 'babe', 'erden', 'schrecklichen', 'falsches', 'täuschen', 'tal', 'irgendwer', 'deins', 'witwe', 'sichern', 'gerede',\n 'betrug', 'trauer', 'anwesenheit', 'bilden', 'gewachsen', 'ausflug', 'jill', 'verlaufen', 'rand', 'kenny', 'rechnen', 'aufzug', 'befragen', 'wegnehmen', 'abschied', 'benötigen', 'pst', 'amt', 'reiche', 'otto', 'beginn', 'daumen', 'bestrafen', 'clarence', 'weine', 'fremder', 'sachte', 'identifiziert', 'gestehen', 'mac', 'owen', 'morris', 'riesig', 'entscheide', 'koma', 'prinzen', 'bewusstlos', 'county', 'marke', 'harter',\n 'hill', 'höflich', 'jude', 'setzte', 'besorg', 'absichtlich', 'vermasselt', 'verschlossen', 'sowie', 'gesang', 'gedreht', 'ford', 'religion', 'ey', 'unterschrift', 'rosen', 'persönliches', 'queen', 'fortschritte', 'eingang', 'zugehört', 'biete', 'clara', 'vorhaben', 'kultur', 'patientin', 'stephen', 'explodiert', 'nichte', 'verzichten', 'steven', 'harris', 'existenz', 'drehbuch', 'football', 'anzusehen', 'ohnmächtig', 'zaun', 'anthony', 'geladen',\n 'guckt', 'privat', 'peg', 'brauchten', 'liam', 'heb', 'virginia', 'wächter', 'eimer', 'blasen', 'rakete', 'salz', 'unfair', 'verzeiht', 'esel', 'krankenschwester', 'symbol', 'entscheidet', 'fahrzeug', 'unterwäsche', 'betrachtet', 'bauern', 'engländer', 'wartete', 'schaust', 'genossen', 'tropfen', 'probiert', 'spock', 'café', 'verhungern', 'versuchten', 'mütter', 'september', 'aktion', 'bestanden', 'haaren', 'louise', 'schluchzt', 'übertrieben',\n 'heilmittel', 'apparat', 'vorm', 'friedlich', 'richtiges', 'zuschauer', 'teenager', 'geliefert', 'may', 'gestritten', 'maus', 'lediglich', 'charakter', 'riley', 'krass', 'weiterer', 'group', 'ricky', 'diana', 'geräusche', 'lichter', 'starken', 'dexter', 'staffel', 'flaschen', 'putzen', 'einbruch', 'geheilt', 'beißen', 'nicole', 'stammen', 'wände', 'befürchte', 'kostüm', 'warren', 'grüßen', 'versagen', 'übernommen', 'hoffte', 'verschieben',\n 'verspätung', 'whiskey', 'mars', 'media', 'entdecken', 'traue', 'thron', 'riesigen', 'zelt', 'akzent', 'truppe', 'übertragen', 'kompliment', 'flammen', 'erkennst', 'erschrecken', 'gemälde', 'ari', 'walt', 'chip', 'mannschaft', 'cindy', 'loyalität', 'benjamin', 'dankeschön', 'vertreten', 'verhandlung', 'lernst', 'brüllt', 'füllen', 'letztendlich', 'krise', 'verlierer', 'spencer', 'with', 'kekse', 'ausschalten', 'penis', 'profi', 'whisky',\n 'erledige', 'gelächter', 'fängst', 'erklär', 'einspruch', 'angeln', 'rausgehen', 'monk', 'kaution', 'eures', 'gesessen', 'verrate', 'kehrt', 'boy', 'summe', 'lade', 'billig', 'curtis', 'bernard', 'juni', 'gerissen', 'festgenommen', 'ralph', 'befohlen', 'überlege', 'koordinaten', 'flog', 'herzinfarkt', 'hinlegen', 'nahrung', 'liege', 'geflohen', 'knall', 'nebenbei', 'mylord', 'nachbar', 'küss', 'lhrem', 'geleistet', 'nutzt',\n 'fröhliche', 'nebel', 'front', 'veränderung', 'affe', 'kontaktieren', 'brand', 'fuhren', 'zwischenzeit', 'eingesetzt', 'anton', 'philip', 'megan', 'schlimmeres', 'rennt', 'anlegen', 'nachzudenken', 'schwör', 'übliche', 'kreatur', 'verderben', 'medizinische', 'besetzt', 'zugriff', 'kanal', 'blutdruck', 'grüne', 'ausgeben', 'papi', 'clown', 'lhrer', 'sonny', 'schwören', 'hühnchen', 'arten', 'aufgebaut', 'sydney', 'betrügen', 'steele', 'trank',\n 'glatt', 'trainiert', 'indien', 'autor', 'geweint', 'blume', 'verletzungen', 'special', 'zwillinge', 'mia', 'reißt', 'zeigst', 'stirb', 'justin', 'diane', 'gefickt', 'schlägst', 'moskau', 'erwartest', 'gestoßen', 'durchgehen', 'praxis', 'gründlich', 'benny', 'eingeschlossen', 'tragödie', 'vollständig', 'psychiater', 'rasse', 'lance', 'vertraust', 'kummer', 'eigener', 'christine', 'partei', 'zentrum', 'testament', 'entfernung', 'private', 'welten',\n 'verlegen', 'heroin', 'erfuhr', 'gelände', 'kutsche', 'dummer', 'homer', 'stabil', 'ausgeschlossen', 'out', 'draus', 'aufgehoben', 'single', 'regisseur', 'vielmals', 'dylan', 'bestand', 'k', 'erbe', 'weggelaufen', 'jim-bob', 'noah', 'leichte', 'zuständig', 'losgehen', 'long', 'hustet', 'brutal', 'besprochen', 'halbes', 'bargeld', 'peggy', 'action', 'zusammenarbeiten', 'beunruhigt', 'achte', 'innere', 'kanone', 'eklig', 'x',\n 'armes', 'avenue', 'öffentlich', 'nützt', 'marine', 'brillant', 'köder', 'gespräche', 'nähert', 'vorgehen', 'kleinigkeit', 'kissen', 'manny', 'geisel', 'gerecht', 'trost', 'gehasst', 'a.', 'gesorgt', 'archer', 'spinner', 'vergebung', 'vieh', 'schnelle', 'normales', 'gefesselt', 'lautes', 'kalte', 'leitet', 'angehen', 'ekelhaft', 'salat', 'schicht', 'intelligent', 'meg', 'verhältnis', 'socken', 'brieftasche', 'holly', 'packt',\n 'eventuell', 'nirgendwohin', 'methode', 'gelangen', 'gespannt', 'vernunft', 'zurückgehen', 'regnet', 'drama', 'entspannt', 'wörter', 'klingeln', 'ruhige', 'sprung', 'anständig', 'gangster', 'harten', 'aufzeichnungen', 'ofen', 'cowboy', 'endgültig', 'aufgaben', 'ruh', 'deutsch', 'neil', 'wodka', 'know', 'air', 'respektieren', 'riskant', 'lohn', 'zuviel', 'zustimmen', 'schnaps', 'troy', 'stufe', 'erleichtert', 'scheune', 'vanessa', 'klink',\n 'spaziergang', 'katherine', 'zettel', 'kotzen', 'blödmann', 'hurra', 'lana', 'symptome', 'vorfahren', 'nutzlos', 'shaw', 'telefonnummer', 'nochmals', 'grey', 'medien', 'faul', 'dient', 'russell', 'ereignisse', 'aussuchen', 'verprügelt', 'zweites', 'sherlock', 'fabelhaft', 'klinge', 'leistung', 'beileid', 'castle', 'durchführen', 'mitchell', 'eröffnen', 'unschuld', 'seist', 'stoßen', 'palmer', 'like', 'genügend', 'sofa', 'gestatten', 'gekocht',\n 'biest', 'lydia', 'bräuchte', 'ausgelöst', 'väter', 'verarscht', 'butter', 'nachbarschaft', 'villa', 'data', 'goldene', 'schließe', 'saft', 'begehen', 'hauptquartier', 'geschworen', 'abgenommen', 'werkstatt', 'überreden', 'nannten', 'gemüse', 'schläger', 'frisst', 'bewundere', 'geschieden', 'assistentin', 'wettbewerb', 'lebten', 'sieger', 'verfassung', 'küsst', 'fußball', 'geschnitten', 'master', 'quietschen', 'füttern', 'gürtel', 'unschuldigen', 'menschlich', 'eigenartig',\n 'oje', 'hanna', 'kabel', 'duke', 'franz', 'zahn', 'landet', 'kisten', 'liegst', 'mona', 'krankenstation', 'leine', 'beschreibung', 'ausmacht', 'beschädigt', 'grundstück', 'steckte', 'bahn', 'turm', 'mine', 'sauerstoff', 'nö', 'angesichts', 'll', 'versager', 'deinetwegen', 'vic', 'angeklagt', 'aufhört', 'baden', 'knacken', 'verbindungen', 'panzer', 'marcel', 'bach', 'leiser', 'stimmengewirr', 'zerstörung', 'stirn', 'finn',\n 'sanft', 'kloster', 'charmant', 'aufbauen', 'thanksgiving', 'anlass', 'zähle', 'verlieben', 'atmosphäre', 'ronnie', 'samantha', 'leber', 'jener', 'begegnen', 'dämlich', 'krawatte', 'juan', 'tarnung', 'kanada', 'alpha', 'baker', 'tabletten', 'faust', 'auftreten', 'monroe', 'blatt', 'gelöscht', 'dschungel', 'alison', 'niedlich', 'c.', 'klage', 'wolltet', 'jonas', 'akt', 'schießerei', 'anwältin', 'überleg', 'frisur', 'spruch',\n 'jene', 'moral', 'angelegenheiten', 'dokumente', 'fröhlich', 'spezies', 'oktober', 'schachtel', 'opfers', 'noten', 'ellie', 'irgendwohin', 'nora', 'brunnen', 'toby', 'sandy', 'lampe', 'craig', 'jagt', 'eigentum', 'diebstahl', 'spenden', 'betrieb', 'gemeinsame', 'absurd', 'gegensatz', 'frühling', 'dünn', 'ausland', 'schultern', 'entwicklung', 'vergehen', 'ahnen', 'verbessern', 'herzog', 'diskussion', 'gehalt', 'lemon', 'freak', 'glocke'\n]);\n","/**\n * English Transition Words\n *\n * Transition words and phrases that signal logical flow between sentences.\n * Used by the content-low-transition-words rule to measure content coherence.\n *\n * Sources: Standard English linguistics references, independently compiled.\n * Thresholds inspired by Yoast SEO's readability analysis.\n */\n\nconst singleWords: readonly string[] = [\n 'accordingly', 'additionally', 'afterward', 'afterwards', 'albeit',\n 'also', 'although', 'altogether', 'basically', 'because', 'before',\n 'besides', 'but', 'certainly', 'chiefly', 'comparatively',\n 'concurrently', 'consequently', 'contrarily', 'conversely',\n 'correspondingly', 'despite', 'during', 'earlier', 'emphatically',\n 'equally', 'especially', 'eventually', 'evidently', 'explicitly',\n 'finally', 'firstly', 'following', 'formerly', 'furthermore',\n 'generally', 'hence', 'henceforth', 'however', 'identically',\n 'indeed', 'initially', 'instead', 'lastly', 'later', 'likewise',\n 'markedly', 'meanwhile', 'moreover', 'nevertheless', 'nonetheless',\n 'nor', 'notwithstanding', 'obviously', 'occasionally', 'otherwise',\n 'overall', 'particularly', 'presently', 'previously', 'rather',\n 'regardless', 'secondly', 'shortly', 'significantly', 'similarly',\n 'simultaneously', 'since', 'so', 'soon', 'specifically', 'still',\n 'subsequently', 'surely', 'surprisingly', 'than', 'then',\n 'thereafter', 'therefore', 'thereupon', 'thirdly', 'though',\n 'thus', 'undeniably', 'undoubtedly', 'unless', 'unlike',\n 'unquestionably', 'until', 'whereas', 'while', 'actually',\n 'anyway', 'anyhow', 'mostly', 'namely', 'including', 'suddenly',\n 'if', 'when', 'whenever', 'whether',\n] as const;\n\nconst multiWordPhrases: readonly string[] = [\n 'above all', 'after all', 'after that', 'all in all',\n 'all things considered', 'as a matter of fact', 'as a result',\n 'as an illustration', 'as can be seen', 'as has been noted',\n 'as long as', 'as much as', 'as opposed to', 'as shown above',\n 'as soon as', 'as well as', 'at any rate', 'at first', 'at last',\n 'at least', 'at length', 'at the same time', 'balanced against',\n 'being that', 'by all means', 'by and large', 'by comparison',\n 'by the same token', 'by the time', 'compared to',\n 'be that as it may', 'coupled with', 'different from', 'due to',\n 'equally important', 'even if', 'even more', 'even so',\n 'even though', 'for example', 'for instance', 'for one thing',\n 'for that reason', 'for the most part', 'for this reason',\n 'from time to time', 'given that', 'given these points',\n 'in a word', 'in addition', 'in any case', 'in any event',\n 'in brief', 'in case', 'in conclusion', 'in contrast',\n 'in detail', 'in effect', 'in either case', 'either way',\n 'in essence', 'in fact', 'in general', 'in light of',\n 'in like fashion', 'in like manner', 'in order to',\n 'in other words', 'in particular', 'in reality', 'in short',\n 'in similar fashion', 'in spite of', 'in sum', 'in summary',\n 'in that case', 'in the event that', 'in the first place',\n 'in the long run', 'in the meantime', 'in the same fashion',\n 'in the same way', 'in the second place', 'in the third place',\n 'in this case', 'in this situation', 'in time', 'in truth',\n 'in view of', 'most important', 'not only', 'not to mention',\n 'note that', 'now that', 'of course', 'on account of',\n 'on balance', 'on condition that', 'on one hand',\n 'on the condition that', 'on the contrary',\n 'on the other hand', 'on the whole', 'only if', 'owing to',\n 'prior to', 'provided that', 'seeing that', 'so as to',\n 'so far', 'so long as', 'so that', 'sooner or later',\n 'such as', 'summing up', 'that is', 'that is to say',\n 'then again', 'to begin with', 'to clarify', 'to conclude',\n 'to demonstrate', 'to emphasize', 'to explain', 'to illustrate',\n 'to put it another way', 'to put it differently', 'to repeat',\n 'to rephrase it', 'to say nothing of', 'to sum up',\n 'to summarize', 'to that end', 'together with',\n 'under those circumstances', 'until now', 'what is more',\n 'while it may be true', 'with this in mind', 'without a doubt',\n 'without delay', 'without doubt', 'according to', 'from now on',\n] as const;\n\n/** All English transition words and phrases (lowercased). */\nexport const TRANSITION_WORDS_EN: ReadonlySet<string> = new Set([\n ...singleWords,\n ...multiWordPhrases,\n]);\n\n/** Single-word transitions only (for fast set-membership checks). */\nexport const TRANSITION_SINGLE_WORDS_EN: ReadonlySet<string> = new Set(singleWords);\n\n/** Multi-word phrases only (checked via substring match). */\nexport const TRANSITION_PHRASES_EN: readonly string[] = multiWordPhrases;\n","/**\n * German Transition Words (Konjunktionen & Konnektoren)\n *\n * Transition words and phrases that signal logical flow between sentences.\n * Used by the content-low-transition-words rule to measure content coherence.\n *\n * Sources: Standard German linguistics references, independently compiled.\n */\n\nconst singleWords: readonly string[] = [\n 'aber', 'abschließend', 'allerdings', 'also', 'andererseits',\n 'anfänglich', 'anfangs', 'angenommen', 'anschließend', 'aufgrund',\n 'ausgenommen', 'außerdem', 'beispielsweise', 'bevor',\n 'beziehungsweise', 'bzw', 'da', 'dabei', 'dadurch', 'dafür',\n 'dagegen', 'daher', 'dahingegen', 'danach', 'dann', 'darauf',\n 'darum', 'dass', 'davor', 'dazu', 'dementsprechend', 'demgegenüber',\n 'demgemäß', 'demzufolge', 'denn', 'dennoch', 'derweil', 'desto',\n 'deshalb', 'deswegen', 'doch', 'drittens', 'ebenfalls', 'ebenso',\n 'ehe', 'einerseits', 'endlich', 'entsprechend', 'entweder', 'erst',\n 'erstens', 'falls', 'ferner', 'folgerichtig', 'folglich',\n 'genauso', 'gleichzeitig', 'hierdurch', 'hierzu', 'hingegen',\n 'immerhin', 'indem', 'indes', 'indessen', 'infolge',\n 'infolgedessen', 'insofern', 'insoweit', 'inzwischen',\n 'jedenfalls', 'jedoch', 'kurzum', 'mitnichten', 'mitunter',\n 'möglicherweise', 'nachdem', 'nebenher', 'nichtsdestotrotz',\n 'nichtsdestoweniger', 'ob', 'obenrein', 'obgleich', 'obschon',\n 'obwohl', 'obzwar', 'ohnehin', 'richtigerweise', 'schließlich',\n 'seit', 'seitdem', 'sobald', 'sodass', 'sofern', 'sogar',\n 'solange', 'somit', 'sondern', 'sooft', 'soviel', 'soweit',\n 'sowie', 'sowohl', 'statt', 'stattdessen', 'trotz', 'trotzdem',\n 'überdies', 'übrigens', 'ungeachtet', 'vielmehr', 'vorausgesetzt',\n 'vorher', 'während', 'währenddessen', 'weder', 'wegen', 'weil',\n 'weiter', 'weiterhin', 'wenn', 'wenngleich', 'wennschon',\n 'weshalb', 'widrigenfalls', 'wiewohl', 'wobei', 'wohingegen',\n 'zudem', 'zuerst', 'zufolge', 'zugleich', 'zuletzt', 'zumal',\n 'zunächst', 'zuvor', 'zwar', 'zweitens',\n] as const;\n\nconst multiWordPhrases: readonly string[] = [\n 'abgesehen von', 'abgesehen davon', 'als dass', 'als ob',\n 'als wenn', 'anders ausgedrückt', 'anders formuliert',\n 'anders gefasst', 'anders gefragt', 'anders gesagt',\n 'anders gesprochen', 'anstatt dass', 'auch wenn', 'auf grund',\n 'auf jeden fall', 'aus diesem grund', 'außer dass', 'außer wenn',\n 'besser ausgedrückt', 'besser formuliert', 'besser gesagt',\n 'besser gesprochen', 'bloß dass', 'darüber hinaus', 'das heißt',\n 'des weiteren', 'dessen ungeachtet', 'ebenso wie', 'genauso wie',\n 'geschweige denn', 'im fall', 'im falle', 'im folgenden',\n 'im gegensatz dazu', 'im gegenteil', 'im grunde genommen',\n 'in diesem sinne', 'je nachdem', 'kurz gesagt',\n 'mit anderen worten', 'ohne dass', 'so dass',\n 'umso mehr als', 'umso weniger als', 'unbeschadet dessen',\n 'und zwar', 'ungeachtet dessen', 'unter dem strich',\n 'zum beispiel', 'zunächst einmal',\n] as const;\n\n/** All German transition words and phrases (lowercased). */\nexport const TRANSITION_WORDS_DE: ReadonlySet<string> = new Set([\n ...singleWords,\n ...multiWordPhrases,\n]);\n\n/** Single-word transitions only (for fast set-membership checks). */\nexport const TRANSITION_SINGLE_WORDS_DE: ReadonlySet<string> = new Set(singleWords);\n\n/** Multi-word phrases only (checked via substring match). */\nexport const TRANSITION_PHRASES_DE: readonly string[] = multiWordPhrases;\n","/**\n * English First Word Exceptions\n *\n * Function words that should be skipped when checking for consecutive\n * sentence beginnings. When a sentence starts with one of these, the\n * analyzer uses the second word instead (e.g., \"The dog\" → \"dog\").\n */\nexport const FIRST_WORD_EXCEPTIONS_EN: ReadonlySet<string> = new Set([\n // Articles\n 'the', 'a', 'an',\n // Demonstratives\n 'this', 'that', 'these', 'those',\n // Cardinal numbers (1–10)\n 'one', 'two', 'three', 'four', 'five',\n 'six', 'seven', 'eight', 'nine', 'ten',\n]);\n","/**\n * German First Word Exceptions (Funktionswörter)\n *\n * Function words that should be skipped when checking for consecutive\n * sentence beginnings. When a sentence starts with one of these, the\n * analyzer uses the second word instead.\n */\nexport const FIRST_WORD_EXCEPTIONS_DE: ReadonlySet<string> = new Set([\n // Definite articles (all cases)\n 'der', 'die', 'das', 'dem', 'den', 'des',\n // Indefinite articles (all cases)\n 'ein', 'eine', 'einem', 'einen', 'einer', 'eines',\n // Demonstrative pronouns\n 'diese', 'dieser', 'dieses', 'diesem', 'diesen',\n 'jene', 'jener', 'jenes', 'jenem', 'jenen',\n 'welch', 'welcher', 'welches',\n // Cardinal numbers (1–10)\n 'eins', 'zwei', 'drei', 'vier', 'fünf',\n 'sechs', 'sieben', 'acht', 'neun', 'zehn',\n]);\n","/**\n * Language Data Registry\n * Provides locale-aware access to frequency lists, transition words,\n * and first-word exception lists.\n */\n\nimport { FREQUENCY_EN } from './frequency-en.js';\nimport { FREQUENCY_DE } from './frequency-de.js';\nimport { TRANSITION_SINGLE_WORDS_EN, TRANSITION_PHRASES_EN } from './transition-words-en.js';\nimport { TRANSITION_SINGLE_WORDS_DE, TRANSITION_PHRASES_DE } from './transition-words-de.js';\nimport { FIRST_WORD_EXCEPTIONS_EN } from './first-word-exceptions-en.js';\nimport { FIRST_WORD_EXCEPTIONS_DE } from './first-word-exceptions-de.js';\n\n// ---------------------------------------------------------------------------\n// Frequency Lists\n// ---------------------------------------------------------------------------\n\nconst FREQUENCY_LISTS: Record<string, ReadonlySet<string>> = {\n en: FREQUENCY_EN,\n de: FREQUENCY_DE,\n};\n\n/** Get the frequency word list for a locale. Returns undefined for unsupported locales. */\nexport function getFrequencyList(locale: string): ReadonlySet<string> | undefined {\n return FREQUENCY_LISTS[locale.toLowerCase()];\n}\n\n/** Check whether a frequency list exists for the given locale. */\nexport function hasFrequencyList(locale: string): boolean {\n return locale.toLowerCase() in FREQUENCY_LISTS;\n}\n\n/** All supported frequency list locales. */\nexport const SUPPORTED_FREQUENCY_LOCALES = Object.keys(FREQUENCY_LISTS);\n\n// ---------------------------------------------------------------------------\n// Transition Words\n// ---------------------------------------------------------------------------\n\ninterface TransitionWordData {\n singleWords: ReadonlySet<string>;\n phrases: readonly string[];\n}\n\nconst TRANSITION_WORD_DATA: Record<string, TransitionWordData> = {\n en: { singleWords: TRANSITION_SINGLE_WORDS_EN, phrases: TRANSITION_PHRASES_EN },\n de: { singleWords: TRANSITION_SINGLE_WORDS_DE, phrases: TRANSITION_PHRASES_DE },\n};\n\n/** Get transition word data for a locale. Returns undefined for unsupported locales. */\nexport function getTransitionWords(locale: string): TransitionWordData | undefined {\n return TRANSITION_WORD_DATA[locale.toLowerCase()];\n}\n\n// ---------------------------------------------------------------------------\n// First Word Exceptions (for consecutive sentence beginnings check)\n// ---------------------------------------------------------------------------\n\nconst FIRST_WORD_EXCEPTION_LISTS: Record<string, ReadonlySet<string>> = {\n en: FIRST_WORD_EXCEPTIONS_EN,\n de: FIRST_WORD_EXCEPTIONS_DE,\n};\n\n/** Get first-word exceptions for a locale. Returns empty set for unsupported locales. */\nexport function getFirstWordExceptions(locale: string): ReadonlySet<string> {\n return FIRST_WORD_EXCEPTION_LISTS[locale.toLowerCase()] ?? new Set();\n}\n","/**\n * Word Complexity Analyzer\n * Dynamic word complexity detection using a Yoast + Gunning Fog hybrid heuristic.\n *\n * A word is classified as complex when ALL conditions are met:\n * 1. Character length exceeds the locale threshold (EN: >7, DE: >10)\n * 2. Syllable count >= 3 (Gunning Fog signal)\n * 3. NOT in the locale's top-5K frequency list (Yoast signal)\n * 4. NOT a capitalized proper noun (skipped for German — all nouns are capitalized)\n */\n\nimport { stripMarkdown } from './word-counter.js';\nimport { estimateSyllables } from './readability.js';\nimport { getFrequencyList } from '../data/index.js';\n\n// ─── Locale Configuration ────────────────────────────────────────────────────\n\nexport interface LocaleComplexityConfig {\n /** Minimum character length to consider a word potentially complex */\n minLength: number;\n /** Minimum syllable count to flag as complex */\n minSyllables: number;\n /** Whether to skip capitalized words (proper nouns). False for German. */\n skipCapitalized: boolean;\n}\n\nconst LOCALE_CONFIGS: Record<string, LocaleComplexityConfig> = {\n en: { minLength: 7, minSyllables: 3, skipCapitalized: true },\n de: { minLength: 10, minSyllables: 3, skipCapitalized: false },\n};\n\nconst DEFAULT_CONFIG: LocaleComplexityConfig = {\n minLength: 7,\n minSyllables: 3,\n skipCapitalized: true,\n};\n\n/** Get the complexity config for a locale. Falls back to English-like defaults. */\nexport function getLocaleConfig(locale: string): LocaleComplexityConfig {\n return LOCALE_CONFIGS[locale.toLowerCase()] ?? DEFAULT_CONFIG;\n}\n\n// ─── Word Classification ─────────────────────────────────────────────────────\n\n/**\n * Determine whether a single word is complex.\n *\n * @param normalizedWord - Lowercased word for frequency/length checks\n * @param originalWord - Original-case word for capitalization checks\n * @param config - Locale-specific complexity thresholds\n * @param frequencyList - Top-frequency words that are never flagged\n */\nexport function isComplexWord(\n normalizedWord: string,\n originalWord: string,\n config: LocaleComplexityConfig,\n frequencyList: ReadonlySet<string> | undefined,\n locale: string = 'en',\n): boolean {\n // Short words are never complex\n if (normalizedWord.length <= config.minLength) return false;\n\n // Words with fewer than minSyllables are not complex\n if (estimateSyllables(normalizedWord, locale) < config.minSyllables) return false;\n\n // Common words (in frequency list) are not complex\n if (frequencyList?.has(normalizedWord)) return false;\n\n // In English, skip capitalized words (likely proper nouns)\n if (config.skipCapitalized && /^[A-Z]/.test(originalWord)) return false;\n\n return true;\n}\n\n// ─── Full-Text Analysis ──────────────────────────────────────────────────────\n\nexport interface ComplexityAnalysis {\n /** Number of words classified as complex */\n complexCount: number;\n /** Total words analyzed */\n totalWords: number;\n /** Ratio of complex words to total (0-1) */\n density: number;\n /** Top complex words sorted by frequency descending */\n topComplexWords: Array<{ word: string; count: number }>;\n}\n\n/**\n * Analyze word complexity across an entire body of text.\n *\n * @param body - Markdown/MDX content body\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'en'.\n */\nexport function analyzeWordComplexity(body: string, locale: string = 'en'): ComplexityAnalysis {\n const config = getLocaleConfig(locale);\n const frequencyList = getFrequencyList(locale);\n\n const plain = stripMarkdown(body);\n // Split into words, preserving original casing for proper-noun detection\n const rawWords = plain\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n const totalWords = rawWords.length;\n const complexCounts = new Map<string, number>();\n let complexCount = 0;\n\n for (const original of rawWords) {\n const normalized = original.toLowerCase();\n if (isComplexWord(normalized, original, config, frequencyList, locale)) {\n complexCount++;\n complexCounts.set(normalized, (complexCounts.get(normalized) ?? 0) + 1);\n }\n }\n\n const topComplexWords = [...complexCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([word, count]) => ({ word, count }));\n\n return {\n complexCount,\n totalWords,\n density: totalWords > 0 ? complexCount / totalWords : 0,\n topComplexWords,\n };\n}\n","/**\n * Content Quality Analyzer\n * Detects jargon stuffing, content repetition, extreme sentence length,\n * low substance (type-token ratio), and monotonous sentence length in content.\n */\n\nimport { stripMarkdown, countWords } from './word-counter.js';\nimport { analyzeWordComplexity } from './word-complexity.js';\nimport { extractSentences } from './geo-advanced-analyzer.js';\n\n// ─── Jargon / Word Complexity Detection ─────────────────────────────────────\n\nexport interface JargonAnalysis {\n jargonCount: number;\n totalWords: number;\n density: number;\n topJargonWords: Array<{ word: string; count: number }>;\n}\n\n/**\n * Analyze jargon density in content body using dynamic word complexity heuristics.\n * Delegates to analyzeWordComplexity which uses syllable count, word length,\n * and frequency lists instead of a hardcoded word list.\n *\n * @param body - Content body (Markdown/MDX)\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'en'.\n */\nexport function analyzeJargonDensity(body: string, locale: string = 'en'): JargonAnalysis {\n const result = analyzeWordComplexity(body, locale);\n\n return {\n jargonCount: result.complexCount,\n totalWords: result.totalWords,\n density: result.density,\n topJargonWords: result.topComplexWords,\n };\n}\n\n// ─── Content Repetition Detection ──────────────────────────────────────────\n\nexport interface RepetitionAnalysis {\n repeatedPhraseCount: number;\n maxPhraseOccurrences: number;\n topRepeatedPhrases: Array<{ phrase: string; count: number }>;\n avgParagraphSimilarity: number;\n}\n\n/** Extract n-grams from a word array. */\nfunction extractNgrams(words: string[], n: number): string[] {\n const ngrams: string[] = [];\n for (let i = 0; i <= words.length - n; i++) {\n ngrams.push(words.slice(i, i + n).join(' '));\n }\n return ngrams;\n}\n\n/** Calculate Jaccard similarity between two sets. */\nfunction jaccardSimilarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n let intersection = 0;\n for (const item of a) {\n if (b.has(item)) intersection++;\n }\n const union = a.size + b.size - intersection;\n return union > 0 ? intersection / union : 0;\n}\n\n/** Analyze content for repetitive phrases and paragraph similarity. */\nexport function analyzeRepetition(body: string): RepetitionAnalysis {\n const plain = stripMarkdown(body).toLowerCase();\n const words = plain\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n // Find repeated 5-grams across the entire text\n const fiveGrams = extractNgrams(words, 5);\n const phraseCounts = new Map<string, number>();\n\n for (const gram of fiveGrams) {\n phraseCounts.set(gram, (phraseCounts.get(gram) ?? 0) + 1);\n }\n\n // Filter to phrases that appear 3+ times\n const repeatedPhrases = [...phraseCounts.entries()]\n .filter(([, count]) => count >= 3)\n .sort((a, b) => b[1] - a[1]);\n\n const topRepeatedPhrases = repeatedPhrases\n .slice(0, 5)\n .map(([phrase, count]) => ({ phrase, count }));\n\n // Calculate pairwise paragraph similarity using 3-gram overlap\n const paragraphs = body\n .split(/\\n\\s*\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0 && !p.startsWith('#') && !p.startsWith('|'));\n\n let totalSimilarity = 0;\n let pairCount = 0;\n\n for (let i = 0; i < paragraphs.length; i++) {\n const wordsI = stripMarkdown(paragraphs[i]).toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n const ngramsI = new Set(extractNgrams(wordsI, 3));\n\n for (let j = i + 1; j < paragraphs.length; j++) {\n const wordsJ = stripMarkdown(paragraphs[j]).toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n const ngramsJ = new Set(extractNgrams(wordsJ, 3));\n\n totalSimilarity += jaccardSimilarity(ngramsI, ngramsJ);\n pairCount++;\n }\n }\n\n return {\n repeatedPhraseCount: repeatedPhrases.length,\n maxPhraseOccurrences: repeatedPhrases.length > 0 ? repeatedPhrases[0][1] : 0,\n topRepeatedPhrases,\n avgParagraphSimilarity: pairCount > 0 ? totalSimilarity / pairCount : 0,\n };\n}\n\n// ─── Sentence Length Analysis ──────────────────────────────────────────────\n\nexport interface SentenceLengthAnalysis {\n avgWordsPerSentence: number;\n maxWordsPerSentence: number;\n sentencesOver60Words: number;\n totalSentences: number;\n}\n\n/** Analyze sentence lengths in content. */\nexport function analyzeSentenceLength(body: string): SentenceLengthAnalysis {\n const plain = stripMarkdown(body);\n\n // Split into sentences on .!? followed by whitespace or end of string\n const sentences = plain\n .split(/(?<=[.!?])\\s+/)\n .map(s => s.trim())\n .filter(s => s.length > 0);\n\n if (sentences.length === 0) {\n return { avgWordsPerSentence: 0, maxWordsPerSentence: 0, sentencesOver60Words: 0, totalSentences: 0 };\n }\n\n let totalWordCount = 0;\n let maxWords = 0;\n let over60 = 0;\n\n for (const sentence of sentences) {\n const wordCount = sentence.split(/\\s+/).filter(w => w.length > 0).length;\n totalWordCount += wordCount;\n if (wordCount > maxWords) maxWords = wordCount;\n if (wordCount > 60) over60++;\n }\n\n return {\n avgWordsPerSentence: totalWordCount / sentences.length,\n maxWordsPerSentence: maxWords,\n sentencesOver60Words: over60,\n totalSentences: sentences.length,\n };\n}\n\n// ─── Substance Ratio (Type-Token Ratio) ────────────────────────────────────\n\n/** Common English stop words to exclude from substance analysis. */\nconst SUBSTANCE_STOPWORDS = new Set([\n 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',\n 'of', 'with', 'by', 'from', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'has', 'have', 'had', 'do', 'does', 'did', 'will', 'would',\n 'could', 'should', 'may', 'might', 'shall', 'can', 'this', 'that',\n 'these', 'those', 'it', 'its', 'not', 'no', 'as', 'if', 'so', 'than',\n 'also', 'very', 'just', 'about', 'up', 'out', 'all', 'each', 'every',\n 'both', 'few', 'more', 'most', 'other', 'some', 'such', 'only', 'own',\n 'same', 'into', 'over', 'after', 'before', 'between', 'through',\n 'during', 'above', 'below', 'which', 'who', 'whom', 'what', 'when',\n 'where', 'why', 'how', 'they', 'them', 'their', 'we', 'us', 'our',\n 'you', 'your', 'he', 'him', 'his', 'she', 'her',\n // German\n 'der', 'die', 'das', 'ein', 'eine', 'und', 'oder', 'aber', 'in',\n 'auf', 'an', 'mit', 'von', 'zu', 'für', 'ist', 'sind', 'den', 'dem',\n 'des', 'nicht', 'sich', 'auch', 'als', 'noch', 'wie', 'bei', 'aus',\n 'nach', 'über', 'vor', 'nur', 'noch', 'man', 'bis', 'zum', 'zur',\n]);\n\nexport interface SubstanceAnalysis {\n uniqueContentWords: number;\n totalContentWords: number;\n typeTokenRatio: number;\n}\n\n/** Analyze substance ratio: how many unique meaningful words vs total. */\nexport function analyzeSubstance(body: string): SubstanceAnalysis {\n const plain = stripMarkdown(body).toLowerCase();\n const words = plain\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 2 && !SUBSTANCE_STOPWORDS.has(w));\n\n const uniqueWords = new Set(words);\n\n return {\n uniqueContentWords: uniqueWords.size,\n totalContentWords: words.length,\n typeTokenRatio: words.length > 0 ? uniqueWords.size / words.length : 0,\n };\n}\n\n// ─── FAQ Quality Analysis ──────────────────────────────────────────────────\n\nexport interface FaqQualityAnalysis {\n hasSection: boolean;\n questionCount: number;\n avgAnswerWordCount: number;\n shortAnswers: number;\n}\n\n/** Analyze FAQ section quality: number of Q&As and answer lengths. */\nexport function analyzeFaqQuality(body: string): FaqQualityAnalysis {\n const faqPattern = /#{2,3}\\s*(FAQ|Häufige Fragen|Frequently Asked|Fragen und Antworten)/i;\n const faqMatch = body.match(faqPattern);\n\n if (!faqMatch) {\n return { hasSection: false, questionCount: 0, avgAnswerWordCount: 0, shortAnswers: 0 };\n }\n\n // Extract everything after the FAQ heading\n const faqStart = body.indexOf(faqMatch[0]);\n const faqContent = body.slice(faqStart + faqMatch[0].length);\n\n // Find Q&A pairs: sub-headings (###) followed by answer text\n const qaPairs = faqContent.split(/#{3}\\s+/).filter(s => s.trim().length > 0);\n\n let totalAnswerWords = 0;\n let shortAnswers = 0;\n\n for (const pair of qaPairs) {\n // First line is the question, rest is the answer\n const lines = pair.split('\\n').filter(l => l.trim().length > 0);\n const answerText = lines.slice(1).join(' ');\n const wordCount = countWords(answerText);\n totalAnswerWords += wordCount;\n\n if (wordCount < 20) {\n shortAnswers++;\n }\n }\n\n return {\n hasSection: true,\n questionCount: qaPairs.length,\n avgAnswerWordCount: qaPairs.length > 0 ? totalAnswerWords / qaPairs.length : 0,\n shortAnswers,\n };\n}\n\n// ─── Sentence Variety Analysis ─────────────────────────────────────────────\n\nexport interface SentenceVarietyAnalysis {\n /** Mean sentence length in words */\n avgLength: number;\n /** Standard deviation of sentence lengths */\n stdDev: number;\n /** Coefficient of variation (stdDev / avgLength) — normalized measure */\n coefficientOfVariation: number;\n /** Total sentences analyzed */\n totalSentences: number;\n}\n\n/**\n * Analyze sentence length variety using coefficient of variation.\n * Low CV = monotonous (all sentences are similar length).\n * High CV = varied (mix of short and long sentences).\n *\n * @example\n * analyzeSentenceVariety(\"Short one. Another short. Yet another short.\")\n * // { coefficientOfVariation: ~0.1, ... } — very monotonous\n */\nexport function analyzeSentenceVariety(body: string): SentenceVarietyAnalysis {\n const sentences = extractSentences(body);\n\n if (sentences.length < 2) {\n return { avgLength: 0, stdDev: 0, coefficientOfVariation: 0, totalSentences: sentences.length };\n }\n\n const lengths = sentences.map(s => s.wordCount);\n const mean = lengths.reduce((sum, l) => sum + l, 0) / lengths.length;\n\n if (mean === 0) {\n return { avgLength: 0, stdDev: 0, coefficientOfVariation: 0, totalSentences: sentences.length };\n }\n\n const variance = lengths.reduce((sum, l) => sum + (l - mean) ** 2, 0) / lengths.length;\n const stdDev = Math.sqrt(variance);\n const cv = stdDev / mean;\n\n return {\n avgLength: Math.round(mean * 10) / 10,\n stdDev: Math.round(stdDev * 10) / 10,\n coefficientOfVariation: Math.round(cv * 100) / 100,\n totalSentences: sentences.length,\n };\n}\n\n// ─── Citation Quality Analysis ─────────────────────────────────────────────\n\nexport interface CitationQualityAnalysis {\n totalStats: number;\n attributedStats: number;\n unattributedStats: number;\n}\n\n/** Check whether statistics have source attribution. */\nexport function analyzeCitationQuality(body: string): CitationQualityAnalysis {\n const lines = body.split('\\n');\n\n // Stat patterns: percentages, multipliers, currency, large numbers\n const statPatterns = [\n /\\d+\\s*%/g,\n /\\d+(?:\\.\\d+)?\\s*(?:x|mal|times)/gi,\n /(?:€|\\$|USD|EUR)\\s*\\d+/g,\n /\\d+(?:\\.\\d+)?\\s*(?:million|billion|mrd|mio)/gi,\n ];\n\n // Attribution patterns that should appear near statistics\n const attributionPatterns = [\n /according to\\b/i,\n /(?:a |the )?study (?:by|from)\\b/i,\n /research (?:by|from)\\b/i,\n /data from\\b/i,\n /report(?:ed)? by\\b/i,\n /source:\\s/i,\n /\\[[^\\]]+\\]\\(https?:\\/\\/[^)]+\\)/, // markdown link\n /\\[\\^[^\\]]+\\]/, // footnote\n ];\n\n let totalStats = 0;\n let attributedStats = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let hasStatOnLine = false;\n\n for (const pattern of statPatterns) {\n const matches = line.matchAll(pattern);\n for (const _ of matches) {\n if (!hasStatOnLine) {\n hasStatOnLine = true;\n totalStats++;\n\n // Check the surrounding context (3 lines before and after) for attribution\n const contextStart = Math.max(0, i - 3);\n const contextEnd = Math.min(lines.length - 1, i + 3);\n const context = lines.slice(contextStart, contextEnd + 1).join(' ');\n\n const hasAttribution = attributionPatterns.some(p => p.test(context));\n if (hasAttribution) {\n attributedStats++;\n }\n }\n }\n }\n }\n\n return {\n totalStats,\n attributedStats,\n unattributedStats: totalStats - attributedStats,\n };\n}\n","/**\n * GEO (Generative Engine Optimization) Rules\n * Validates content readiness for LLM-based search and AI visibility\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n countQuestionHeadings,\n analyzeLeadSentences,\n countStatistics,\n hasFAQSection,\n hasMarkdownTable,\n countEntityMentions,\n analyzeCitationBlocks,\n} from '../utils/geo-analyzer.js';\nimport {\n analyzeCitationQuality,\n analyzeFaqQuality,\n} from '../utils/content-quality-analyzer.js';\n\n/** Minimum word count before GEO rules apply */\nconst GEO_MIN_WORDS = 500;\n\n/** Minimum word count before FAQ section rule applies */\nconst FAQ_MIN_WORDS = 800;\n\n/** Minimum percentage of headings that should be question-formatted */\nconst QUESTION_HEADING_THRESHOLD = 0.2;\n\n/** Minimum percentage of sections with direct answer leads */\nconst DIRECT_ANSWER_THRESHOLD = 0.5;\n\n/** Expected data points per N words */\nconst CITATION_WORDS_PER_STAT = 500;\n\n/** Minimum word count before table rule applies */\nconst TABLE_MIN_WORDS = 1000;\n\n/** Minimum word count before entity density rule applies */\nconst ENTITY_MIN_WORDS = 800;\n\n/** Minimum word count before citation block rule applies */\nconst CITATION_BLOCK_MIN_WORDS = 800;\n\n/** Minimum words for a first paragraph to qualify as a citation block */\nconst CITATION_BLOCK_WORD_THRESHOLD = 40;\n\n/** Minimum ratio of sections that should have adequate citation blocks */\nconst CITATION_BLOCK_SECTION_THRESHOLD = 0.5;\n\n/**\n * Rule: Blog posts should use question-formatted headings for LLM discoverability\n * At least 20% of H2/H3 headings should be questions\n */\nexport const geoNoQuestionHeadings: Rule = {\n name: 'geo-no-question-headings',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Rephrase some headings as questions (e.g., \"How does X work?\")',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n\n if (subHeadings.length === 0) return [];\n\n const questionCount = countQuestionHeadings(item.body);\n const ratio = questionCount / subHeadings.length;\n\n if (ratio < QUESTION_HEADING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-no-question-headings',\n severity: 'warning',\n message: `Only ${questionCount}/${subHeadings.length} (${Math.round(ratio * 100)}%) H2/H3 headings are question-formatted — aim for at least ${Math.round(QUESTION_HEADING_THRESHOLD * 100)}%`,\n suggestion: 'Rephrase some headings as questions (e.g., \"How does X work?\" / \"Was ist X?\") to improve LLM snippet extraction.',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Sections should start with direct answers, not filler introductions\n * At least 50% of sections should lead with substantive first sentences\n */\nexport const geoWeakLeadSentences: Rule = {\n name: 'geo-weak-lead-sentences',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a concise factual sentence that directly answers the heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const { totalSections, sectionsWithDirectAnswers } = analyzeLeadSentences(item.body);\n\n if (totalSections === 0) return [];\n\n const ratio = sectionsWithDirectAnswers / totalSections;\n\n if (ratio < DIRECT_ANSWER_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-weak-lead-sentences',\n severity: 'warning',\n message: `Only ${sectionsWithDirectAnswers}/${totalSections} (${Math.round(ratio * 100)}%) sections start with direct answers — aim for at least ${Math.round(DIRECT_ANSWER_THRESHOLD * 100)}%`,\n suggestion: 'Start each section with a concise factual sentence that directly answers the heading. Avoid filler like \"In this section...\" or \"Let\\'s look at...\".',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Content should include statistical data points for citation potential\n * Expect at least 1 data point per 500 words\n */\nexport const geoLowCitationDensity: Rule = {\n name: 'geo-low-citation-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add statistics with source attribution (e.g., \"According to [Study], 73% of...\")',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const statCount = countStatistics(item.body);\n const expectedMin = Math.floor(wordCount / CITATION_WORDS_PER_STAT);\n\n if (statCount < expectedMin) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-citation-density',\n severity: 'warning',\n message: `Found ${statCount} data points but expected at least ${expectedMin} (1 per ${CITATION_WORDS_PER_STAT} words in ${wordCount}-word post)`,\n suggestion: 'Add statistics, percentages, or concrete numbers to increase citation potential in AI-generated answers.',\n }];\n }\n\n // Stats exist — check whether they have source attribution\n const citationQuality = analyzeCitationQuality(item.body);\n if (citationQuality.totalStats > 0 && citationQuality.unattributedStats > 0) {\n const ratio = citationQuality.attributedStats / citationQuality.totalStats;\n if (ratio < 0.5) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-citation-density',\n severity: 'warning',\n message: `${citationQuality.unattributedStats}/${citationQuality.totalStats} statistics lack source attribution`,\n suggestion: 'Add sources for your statistics (e.g., \"According to [Study Name]...\", link to source, or footnote). Unsourced stats reduce credibility for AI citation.',\n }];\n }\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Longer blog posts should include a FAQ section for LLM extraction\n * Applies to posts with 800+ words\n */\nexport const geoMissingFaqSection: Rule = {\n name: 'geo-missing-faq-section',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add an \"## FAQ\" or \"## Frequently Asked Questions\" section with 3+ Q&A pairs (min 20 words each)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FAQ_MIN_WORDS) return [];\n\n if (!hasFAQSection(item.body)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: 'No FAQ section detected in long-form content',\n suggestion: 'Add an \"## FAQ\" or \"## Häufige Fragen\" section with Q&A pairs. FAQ sections are frequently extracted by LLMs and featured in AI answers.',\n }];\n }\n\n // FAQ section exists — validate its quality\n const faqQuality = analyzeFaqQuality(item.body);\n\n const results: LintResult[] = [];\n\n if (faqQuality.questionCount < 3) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: `FAQ section has only ${faqQuality.questionCount} question(s) — aim for at least 3`,\n suggestion: 'Add more Q&A pairs to your FAQ section. LLMs prefer comprehensive FAQ sections with at least 3 questions.',\n });\n }\n\n if (faqQuality.shortAnswers > 0) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: `${faqQuality.shortAnswers} FAQ answer(s) are too short (under 20 words, avg: ${Math.round(faqQuality.avgAnswerWordCount)} words)`,\n suggestion: 'Expand FAQ answers to at least 20 words each. Short one-line answers provide little value to AI citation engines.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Long-form blog posts should contain at least one data table\n * Tables are highly extractable by AI systems and increase citation rates\n * Applies to posts with 1000+ words\n */\nexport const geoMissingTable: Rule = {\n name: 'geo-missing-table',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a comparison table, feature matrix, or data summary table',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < TABLE_MIN_WORDS) return [];\n\n if (!hasMarkdownTable(item.body)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-table',\n severity: 'warning',\n message: 'No data table found in long-form content (tables increase AI citation rates by 2.5x)',\n suggestion: 'Add a comparison table, feature matrix, or data summary table. Tables are highly extractable by AI systems and increase citation likelihood.',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: H2 sections should start with substantial \"citation blocks\"\n * AI systems extract the first paragraph after headings as citation snippets.\n * At least 50% of sections should have first paragraphs of 40+ words.\n * Applies to posts with 800+ words\n */\nexport const geoShortCitationBlocks: Rule = {\n name: 'geo-short-citation-blocks',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a 40-60 word paragraph that directly answers the heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < CITATION_BLOCK_MIN_WORDS) return [];\n\n const { totalSections, sectionsWithAdequateBlocks } = analyzeCitationBlocks(item.body);\n\n if (totalSections === 0) return [];\n\n const ratio = sectionsWithAdequateBlocks / totalSections;\n\n if (ratio < CITATION_BLOCK_SECTION_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-short-citation-blocks',\n severity: 'warning',\n message: `Only ${sectionsWithAdequateBlocks}/${totalSections} sections have substantial lead paragraphs (${CITATION_BLOCK_WORD_THRESHOLD}+ words) — AI systems extract these as citation blocks`,\n suggestion: `Start each section with a ${CITATION_BLOCK_WORD_THRESHOLD}-60 word paragraph that directly answers the heading question. These 'citation blocks' are what AI systems extract and cite.`,\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Factory: Create the entity density rule with project-specific brand/city\n * When brandName is empty, the brand check is skipped.\n * When brandCity is empty, the city check is skipped.\n */\nexport function createGeoEntityRule(brandName: string, brandCity: string): Rule {\n return {\n name: 'geo-low-entity-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Mention brand name and location naturally in the content body',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < ENTITY_MIN_WORDS) return [];\n\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n if (brandName && countEntityMentions(item.body, brandName) === 0) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-low-entity-density',\n severity: 'warning',\n message: `Brand name '${brandName}' not mentioned in content body — reduces entity recognition by AI systems`,\n suggestion: 'Mention the brand name naturally in the content to strengthen entity signals for AI systems.',\n });\n }\n\n if (brandCity && countEntityMentions(item.body, brandCity) === 0) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-low-entity-density',\n severity: 'warning',\n message: `Location '${brandCity}' not mentioned in content body — reduces local entity recognition`,\n suggestion: 'Include a location reference to strengthen local entity recognition for AI search.',\n });\n }\n\n return results;\n },\n };\n}\n\n/** Static GEO rules (no config dependency) */\nexport const geoStaticRules: Rule[] = [\n geoNoQuestionHeadings,\n geoWeakLeadSentences,\n geoLowCitationDensity,\n geoMissingFaqSection,\n geoMissingTable,\n geoShortCitationBlocks,\n];\n\n/**\n * Factory: Build the complete GEO rule set from config\n * Returns all 7 rules: 6 static + 1 entity density from factory\n */\nexport function createGeoRules(geo: { brandName: string; brandCity: string }): Rule[] {\n return [\n ...geoStaticRules,\n createGeoEntityRule(geo.brandName, geo.brandCity),\n ];\n}\n\n/**\n * Alias for backwards compatibility: static rules without entity density\n * Use when no GEO config is available\n */\nexport const geoRules: Rule[] = geoStaticRules;\n","/**\n * Category Validation Rules\n * Validates blog categories against a user-provided canonical list\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Find the closest canonical category for a misspelled value\n */\nfunction findSuggestion(value: string, canonicalCategories: Set<string>): string | undefined {\n const lower = value.toLowerCase();\n for (const canonical of canonicalCategories) {\n if (canonical.toLowerCase() === lower) {\n return canonical;\n }\n }\n return undefined;\n}\n\n/**\n * Factory: Create category validation rules from a list of valid categories\n * Returns an empty array when categories is empty (skip both rules).\n */\nexport function createCategoryRules(categories: string[]): Rule[] {\n if (categories.length === 0) {\n return [];\n }\n\n const canonicalCategories = new Set(categories);\n\n const categoryInvalid: Rule = {\n name: 'category-invalid',\n severity: 'error',\n category: 'content',\n fixStrategy: 'Use a valid category from the configured list',\n run: (item: ContentItem): LintResult[] => {\n if (!item.categories || item.categories.length === 0) return [];\n\n const results: LintResult[] = [];\n\n for (const cat of item.categories) {\n if (!canonicalCategories.has(cat)) {\n const suggested = findSuggestion(cat, canonicalCategories);\n results.push({\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'category-invalid',\n severity: 'error',\n message: `Invalid category \"${cat}\"`,\n suggestion: suggested\n ? `Did you mean \"${suggested}\"? Valid categories: ${[...canonicalCategories].join(', ')}`\n : `Valid categories: ${[...canonicalCategories].join(', ')}`,\n });\n }\n }\n\n return results;\n },\n };\n\n const missingCategories: Rule = {\n name: 'missing-categories',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add at least one category from the configured list',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') return [];\n\n if (!item.categories || item.categories.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'missing-categories',\n severity: 'warning',\n message: 'Blog post has no categories',\n suggestion: `Add at least one category: ${[...canonicalCategories].join(', ')}`,\n }];\n }\n return [];\n },\n };\n\n return [categoryInvalid, missingCategories];\n}\n","/**\n * Canonical URL Validation Rules\n * Validates canonical URL presence and format\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Factory: Create canonical URL validation rules for the given site URL\n */\nexport function createCanonicalRules(siteUrl: string): Rule[] {\n /**\n * Rule: Every indexed page should have a canonical URL (permalink)\n * Skips noindexed pages since they don't need canonical tags\n */\n const canonicalMissing: Rule = {\n name: 'canonical-missing',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Ensure the content has a valid slug so a permalink can be generated',\n run: (item: ContentItem): LintResult[] => {\n if (item.noindex) return [];\n\n if (!item.permalink || item.permalink.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'permalink',\n rule: 'canonical-missing',\n severity: 'warning',\n message: 'Missing canonical URL (permalink)',\n suggestion: 'Ensure the content has a valid slug so a permalink can be generated',\n }];\n }\n return [];\n },\n };\n\n /**\n * Rule: Canonical URL must be a valid relative path or absolute URL on the site domain\n * Catches misconfigured permalinks (wrong domain, http://, fragments, etc.)\n */\n const canonicalMalformed: Rule = {\n name: 'canonical-malformed',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Use a relative path (e.g., /blog/my-post) or absolute URL on the site domain',\n run: (item: ContentItem): LintResult[] => {\n if (!item.permalink || item.permalink.trim().length === 0) return [];\n\n const permalink = item.permalink.trim();\n\n // Valid: relative path starting with /\n if (permalink.startsWith('/')) return [];\n\n // Valid: absolute URL on site domain\n if (permalink.startsWith(siteUrl)) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'permalink',\n rule: 'canonical-malformed',\n severity: 'warning',\n message: `Canonical URL has unexpected format: \"${permalink}\"`,\n suggestion: `Canonical should be a relative path (e.g., /blog/my-post) or absolute URL starting with ${siteUrl}`,\n }];\n },\n };\n\n return [canonicalMissing, canonicalMalformed];\n}\n","/**\n * GEO E-E-A-T Rules\n * Validates Experience, Expertise, Authoritativeness, and Trustworthiness signals\n * plus answer formatting patterns for AI citation optimization\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n countSourceCitations,\n hasExpertQuote,\n extractH2Sections,\n hasFAQSection,\n} from '../utils/geo-analyzer.js';\nimport { analyzeFaqQuality } from '../utils/geo-advanced-analyzer.js';\nimport type { GeoConfig } from '../config/types.js';\n\nconst EEAT_MIN_WORDS = 500; // Minimum words before most E-E-A-T rules apply\nconst EEAT_LONG_MIN_WORDS = 800; // Minimum words for long-form content rules\nconst WORDS_PER_CITATION = 500; // Expected 1 source citation per N words\nconst FAQ_MIN_PAIRS = 3; // Minimum Q&A pairs in FAQ section\nconst FAQ_QUESTION_MARK_RATIO = 0.5;\nconst FAQ_ANSWER_RANGE_RATIO = 0.5;\nconst HEADING_MIN_WORDS = 3; // Minimum words for a descriptive heading\nconst TLDR_SCAN_WORDS = 150; // Words to scan for TL;DR at start of content\n\n// -- Rule 1: geo-missing-source-citations (static) --\nexport const geoMissingSourceCitations: Rule = {\n name: 'geo-missing-source-citations',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add source references using \"according to [Source]\" or linked citations',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const found = countSourceCitations(item.body);\n const expected = Math.floor(wordCount / WORDS_PER_CITATION);\n\n if (found < expected) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-source-citations',\n severity: 'warning',\n message: `Found ${found} source citation(s) but expected at least ${expected} (1 per ${WORDS_PER_CITATION} words in ${wordCount}-word post)`,\n suggestion: 'Add source references using \"according to [Source]\" or linked citations to strengthen authoritativeness.',\n }];\n }\n\n return [];\n },\n};\n// -- Rule 2: geo-missing-expert-quotes (static) --\nexport const geoMissingExpertQuotes: Rule = {\n name: 'geo-missing-expert-quotes',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add at least one blockquote with attribution (> \"Quote\" -- Expert Name)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n if (!hasExpertQuote(item.body)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-expert-quotes',\n severity: 'warning',\n message: 'No attributed expert quotation found in long-form content',\n suggestion: 'Add at least one blockquote with attribution (> \"Quote\" \\u2014 Expert Name) to boost E-E-A-T signals.',\n }];\n }\n\n return [];\n },\n};\n// -- Rule 6: geo-missing-author (factory) --\nexport function createGeoMissingAuthorRule(genericNames: string[]): Rule {\n return {\n name: 'geo-missing-author',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Set a real author name in frontmatter (not a generic placeholder)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const displayPath = getDisplayPath(item);\n\n // Check 1: missing or empty author (takes priority)\n if (!item.author || item.author.trim() === '') {\n return [{\n file: displayPath,\n field: 'author',\n rule: 'geo-missing-author',\n severity: 'warning',\n message: 'No author specified in frontmatter \\u2014 weakens E-E-A-T signals',\n suggestion: 'Add an \"author\" field with a real person or brand name to the frontmatter.',\n }];\n }\n\n // Check 2: generic author name\n const normalizedAuthor = item.author.toLowerCase().trim();\n const isGeneric = genericNames.some(\n g => normalizedAuthor === g.toLowerCase()\n );\n\n if (isGeneric) {\n return [{\n file: displayPath,\n field: 'author',\n rule: 'geo-missing-author',\n severity: 'warning',\n message: `Author \"${item.author}\" appears to be a generic placeholder`,\n suggestion: 'Replace the generic author name with a real person or brand name to strengthen authoritativeness.',\n }];\n }\n\n return [];\n },\n };\n}\n// -- Rule 7: geo-heading-too-vague (factory) --\nexport function createGeoHeadingTooVagueRule(vagueHeadings: string[]): Rule {\n const lowerVague = vagueHeadings.map(v => v.toLowerCase());\n\n return {\n name: 'geo-heading-too-vague',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace vague headings with specific, descriptive headings of 3+ words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const heading of subHeadings) {\n const words = heading.text.trim().split(/\\s+/);\n const isShort = words.length < HEADING_MIN_WORDS;\n const isSingleVague = words.length === 1\n && lowerVague.includes(words[0].toLowerCase());\n\n if (isShort || isSingleVague) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-heading-too-vague',\n severity: 'warning',\n message: `H${heading.level} \"${heading.text}\" is too vague (${words.length} word${words.length === 1 ? '' : 's'})`,\n suggestion: 'Use a specific, descriptive heading with 3+ words that tells the reader and AI systems what this section covers.',\n line: heading.line,\n });\n }\n }\n\n return results;\n },\n };\n}\n// -- Rule 10: geo-faq-quality (static) --\nexport const geoFaqQuality: Rule = {\n name: 'geo-faq-quality',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Improve FAQ section: add 3+ Q&A pairs, use question marks, keep answers 20-150 words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n if (!hasFAQSection(item.body)) return [];\n\n const { pairCount, questionsWithMark, answersInRange } = analyzeFaqQuality(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n if (pairCount < FAQ_MIN_PAIRS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `FAQ section has only ${pairCount} Q&A pair(s) \\u2014 aim for at least ${FAQ_MIN_PAIRS}`,\n suggestion: 'Add more question-answer pairs to the FAQ section. AI systems favour comprehensive FAQ blocks with 3+ entries.',\n });\n }\n\n if (pairCount > 0 && questionsWithMark / pairCount < FAQ_QUESTION_MARK_RATIO) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `Only ${questionsWithMark}/${pairCount} FAQ questions end with a question mark`,\n suggestion: 'End all FAQ questions with \"?\" so AI systems recognise them as interrogative queries.',\n });\n }\n\n if (pairCount > 0 && answersInRange / pairCount < FAQ_ANSWER_RANGE_RATIO) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `Only ${answersInRange}/${pairCount} FAQ answers are in the optimal 20\\u2013150 word range`,\n suggestion: 'Keep FAQ answers between 20 and 150 words \\u2014 concise enough for extraction but detailed enough to be useful.',\n });\n }\n\n return results;\n },\n};\n// -- Rule 11: geo-definition-pattern (static) --\nconst DEFINITION_HEADING_EN = /^what\\s+is\\s+/i;\nconst DEFINITION_HEADING_DE = /^was\\s+ist\\s+/i;\nconst DEFINITION_VERBS_EN = ['is', 'are', 'refers to', 'means'];\nconst DEFINITION_VERBS_DE = ['ist', 'sind', 'bezeichnet', 'bedeutet'];\n\n/** Extract subject from definition heading: \"What is GEO?\" -> \"GEO\" */\nfunction extractDefinitionSubject(heading: string): string {\n return heading\n .replace(DEFINITION_HEADING_EN, '')\n .replace(DEFINITION_HEADING_DE, '')\n .replace(/[?!.]$/, '')\n .trim();\n}\n\nexport const geoDefinitionPattern: Rule = {\n name: 'geo-definition-pattern',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start definition sections with \"[Subject] is/are...\" for AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isDefinition = DEFINITION_HEADING_EN.test(section.heading)\n || DEFINITION_HEADING_DE.test(section.heading);\n\n if (!isDefinition) continue;\n\n const subject = extractDefinitionSubject(section.heading);\n if (!subject) continue;\n\n // Get the first sentence of the section body\n const firstSentenceMatch = section.body.trim().match(/^([^.!?\\n]+[.!?]?)/);\n if (!firstSentenceMatch) continue;\n\n const firstSentence = firstSentenceMatch[1].trim().toLowerCase();\n const subjectLower = subject.toLowerCase();\n const allVerbs = [...DEFINITION_VERBS_EN, ...DEFINITION_VERBS_DE];\n\n const followsPattern = allVerbs.some(verb =>\n firstSentence.startsWith(`${subjectLower} ${verb}`)\n );\n\n if (!followsPattern) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-definition-pattern',\n severity: 'warning',\n message: `Section \"${section.heading}\" does not start with a \"${subject} is/are...\" definition pattern`,\n suggestion: `Start the first sentence with \"${subject} is ...\" or \"${subject} refers to ...\" so AI systems can extract a clean definition.`,\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n// -- Rule 12: geo-howto-steps (static) --\nconst HOWTO_HEADING = /^how\\s+to\\s+/i;\nconst HOWTO_HEADING_DE = /^wie\\s+(man\\s+)?/i;\nconst HOWTO_HEADING_DE_ALT = /^anleitung/i;\nconst MIN_HOWTO_STEPS = 3;\n\nexport const geoHowtoSteps: Rule = {\n name: 'geo-howto-steps',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a numbered list with 3+ steps to how-to sections',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isHowTo = HOWTO_HEADING.test(section.heading)\n || HOWTO_HEADING_DE.test(section.heading)\n || HOWTO_HEADING_DE_ALT.test(section.heading);\n\n if (!isHowTo) continue;\n\n const numberedItems = section.body.match(/^\\s*\\d+\\.\\s+/gm);\n const stepCount = numberedItems ? numberedItems.length : 0;\n\n if (stepCount < MIN_HOWTO_STEPS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-howto-steps',\n severity: 'warning',\n message: `How-to section \"${section.heading}\" has ${stepCount} numbered step(s) \\u2014 need at least ${MIN_HOWTO_STEPS}`,\n suggestion: 'Add a numbered list (1. 2. 3. ...) with at least 3 steps. AI systems parse numbered lists as HowTo structured data.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n// -- Rule 14: geo-missing-tldr (static) --\nconst TLDR_PATTERNS = [\n /tl;?dr/i,\n /key\\s+takeaway/i,\n /zusammenfassung/i,\n /das\\s+wichtigste/i,\n /in\\s+short/i,\n /quick\\s+answer/i,\n /^\\s*>\\s+\\*\\*/m,\n];\n\nexport const geoMissingTldr: Rule = {\n name: 'geo-missing-tldr',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a TL;DR, \"Key Takeaway\", or bold blockquote summary near the top of the article',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n // Scan the first ~150 words of the body\n const words = item.body.split(/\\s+/);\n const leadText = words.slice(0, TLDR_SCAN_WORDS).join(' ');\n\n const hasTldr = TLDR_PATTERNS.some(pattern => pattern.test(leadText));\n\n if (!hasTldr) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-tldr',\n severity: 'warning',\n message: 'No TL;DR or key-takeaway summary found near the top of the article',\n suggestion: 'Add a \"TL;DR\", \"Key Takeaway\", or bold blockquote summary in the first 150 words. AI systems often extract the opening summary for featured answers.',\n }];\n }\n\n return [];\n },\n};\n\n/** Patterns indicating organization-as-author (case-insensitive match) */\nconst ORG_AUTHOR_PATTERNS = [\n /\\bteam\\b/i,\n /\\bredaktion\\b/i,\n /\\beditorial\\b/i,\n /\\beditors?\\b/i,\n /\\bherausgeber\\b/i,\n /\\bverlag\\b/i,\n /\\bredaktionsteam\\b/i,\n];\n\n// -- Rule: geo-author-not-person (factory) --\nexport function createGeoAuthorNotPersonRule(brandName: string): Rule {\n return {\n name: 'geo-author-not-person',\n severity: 'warning',\n category: 'geo',\n fixStrategy:\n 'Replace organization name with individual author name. Use Person type in BlogPosting schema for stronger E-E-A-T signals.',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n // Skip if no author (handled by geo-missing-author)\n if (!item.author || item.author.trim() === '') return [];\n\n // Skip if brand not configured\n if (!brandName || brandName.trim() === '') return [];\n\n const normalizedAuthor = item.author.trim().toLowerCase();\n\n // Check 1: author exactly matches brand name\n if (normalizedAuthor === brandName.trim().toLowerCase()) {\n return [\n {\n file: getDisplayPath(item),\n field: 'author',\n rule: 'geo-author-not-person',\n severity: 'warning',\n message: `Author \"${item.author}\" is the organization name — use a person's name instead`,\n suggestion:\n 'AI models cite named experts over faceless organizations. Use the actual author\\'s name for stronger E-E-A-T signals.',\n },\n ];\n }\n\n // Check 2: author matches org patterns\n const matchesOrgPattern = ORG_AUTHOR_PATTERNS.some((pattern) =>\n pattern.test(item.author!)\n );\n\n if (matchesOrgPattern) {\n return [\n {\n file: getDisplayPath(item),\n field: 'author',\n rule: 'geo-author-not-person',\n severity: 'warning',\n message: `Author \"${item.author}\" appears to be an organization or team name`,\n suggestion:\n 'BlogPosting with author.@type: Person gets cited more than Organization. Use an individual person\\'s name.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/** Static E-E-A-T rules (no config dependency) */\nexport const geoEeatStaticRules: Rule[] = [\n geoMissingSourceCitations,\n geoMissingExpertQuotes,\n geoFaqQuality,\n geoDefinitionPattern,\n geoHowtoSteps,\n geoMissingTldr,\n];\n\n/** Build the complete E-E-A-T rule set from GEO config (6 static + 3 factory). */\nexport function createGeoEeatRules(geo: GeoConfig): Rule[] {\n return [\n ...geoEeatStaticRules,\n createGeoMissingAuthorRule(geo.genericAuthorNames ?? []),\n createGeoHeadingTooVagueRule(geo.vagueHeadings ?? []),\n createGeoAuthorNotPersonRule(geo.brandName),\n ];\n}\n","/**\n * GEO Structure Rules\n * Validates content structure and formatting patterns for AI extraction\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport {\n extractH2Sections,\n getParagraphs,\n hasMarkdownList,\n} from '../utils/geo-analyzer.js';\nimport {\n analyzeHeadingDensity,\n countStructuralElements,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before structure rules apply */\nconst STRUCTURE_MIN_WORDS = 500;\n\n/** Minimum word count for long-form structure rules */\nconst STRUCTURE_LONG_MIN_WORDS = 800;\n\n/** Maximum words per H2 section before it needs sub-headings */\nconst SECTION_MAX_WORDS = 300;\n\n/** Maximum words per paragraph */\nconst PARAGRAPH_MAX_WORDS = 100;\n\n/** Maximum paragraph violations reported (to reduce noise) */\nconst PARAGRAPH_MAX_VIOLATIONS = 5;\n\n/** Maximum words in the first paragraph of a citation block */\nconst CITATION_BLOCK_MAX_WORDS = 80;\n\n/** Ratio of sections with overly long citation blocks before flagging */\nconst CITATION_BLOCK_RATIO_THRESHOLD = 0.5;\n\n/** Maximum words in the introduction before first H2 */\nconst INTRO_MAX_WORDS = 150;\n\n/** Maximum word gap between headings for density rule */\nconst HEADING_GAP_MAX_WORDS = 300;\n\n/** Maximum heading density violations reported */\nconst HEADING_DENSITY_MAX_VIOLATIONS = 3;\n\n/** Expected structural elements per N words */\nconst WORDS_PER_STRUCTURAL_ELEMENT = 500;\n\n// ---------------------------------------------------------------------------\n// Rule 3: geo-section-too-long (static)\n// ---------------------------------------------------------------------------\n\nexport const geoSectionTooLong: Rule = {\n name: 'geo-section-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Break long sections into sub-sections with H3 headings every 200-300 words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const sectionWordCount = countWords(section.body);\n const hasSubHeadings = /^###\\s+/m.test(section.body);\n\n if (sectionWordCount > SECTION_MAX_WORDS && !hasSubHeadings) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-section-too-long',\n severity: 'warning',\n message: `Section \"${section.heading}\" is ${sectionWordCount} words with no sub-headings (H3) \\u2014 max recommended is ${SECTION_MAX_WORDS}`,\n suggestion: 'Break this section into sub-sections using H3 headings. AI systems parse shorter, well-structured sections more effectively.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 4: geo-paragraph-too-long (static)\n// ---------------------------------------------------------------------------\n\nexport const geoParagraphTooLong: Rule = {\n name: 'geo-paragraph-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Split paragraphs longer than 100 words into shorter focused paragraphs',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const paragraphs = getParagraphs(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const paragraph of paragraphs) {\n if (results.length >= PARAGRAPH_MAX_VIOLATIONS) break;\n\n if (paragraph.wordCount > PARAGRAPH_MAX_WORDS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-paragraph-too-long',\n severity: 'warning',\n message: `Paragraph at line ${paragraph.line} is ${paragraph.wordCount} words \\u2014 max recommended is ${PARAGRAPH_MAX_WORDS}`,\n suggestion: 'Split this paragraph into two or more shorter paragraphs. Shorter paragraphs are easier for AI systems to extract as citation blocks.',\n line: paragraph.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 5: geo-missing-lists (static)\n// ---------------------------------------------------------------------------\n\nexport const geoMissingLists: Rule = {\n name: 'geo-missing-lists',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add at least one bulleted or numbered list to improve scannability and AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n if (!hasMarkdownList(item.body)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-lists',\n severity: 'warning',\n message: 'No bulleted or numbered list found in content',\n suggestion: 'Add at least one bulleted or numbered list. Lists are highly extractable by AI systems and improve content scannability.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 13: geo-citation-block-upper-bound (static)\n// ---------------------------------------------------------------------------\n\nexport const geoCitationBlockUpperBound: Rule = {\n name: 'geo-citation-block-upper-bound',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Keep the first paragraph after each heading under 80 words for optimal AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_LONG_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n if (sections.length === 0) return [];\n\n let overLongCount = 0;\n\n for (const section of sections) {\n // First paragraph: text before first blank line after heading\n const firstParagraph = section.body.split(/\\n\\s*\\n/)[0] ?? '';\n const firstParaWords = countWords(firstParagraph.trim());\n\n if (firstParaWords > CITATION_BLOCK_MAX_WORDS) {\n overLongCount++;\n }\n }\n\n const ratio = overLongCount / sections.length;\n\n if (ratio > CITATION_BLOCK_RATIO_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-citation-block-upper-bound',\n severity: 'warning',\n message: `${overLongCount}/${sections.length} sections (${Math.round(ratio * 100)}%) have first paragraphs over ${CITATION_BLOCK_MAX_WORDS} words \\u2014 too long for AI citation extraction`,\n suggestion: `Keep the first paragraph after each H2 heading under ${CITATION_BLOCK_MAX_WORDS} words. Overly long opening paragraphs reduce AI extraction accuracy.`,\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 18: geo-orphaned-intro (static)\n// ---------------------------------------------------------------------------\n\nexport const geoOrphanedIntro: Rule = {\n name: 'geo-orphaned-intro',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Shorten the introduction to under 150 words or add a heading to break it up',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n // Content before the first H2 heading\n const introContent = item.body.split(/^##\\s+/m)[0] ?? '';\n const introWords = countWords(introContent);\n\n if (introWords > INTRO_MAX_WORDS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-orphaned-intro',\n severity: 'warning',\n message: `Introduction before first H2 heading is ${introWords} words \\u2014 max recommended is ${INTRO_MAX_WORDS}`,\n suggestion: 'Shorten the introduction or add an H2 heading to break up the opening. Long introductions delay AI systems from reaching structured content.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 22: geo-heading-density (static)\n// ---------------------------------------------------------------------------\n\nexport const geoHeadingDensity: Rule = {\n name: 'geo-heading-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add headings so that no text gap exceeds 300 words without a heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_LONG_MIN_WORDS) return [];\n\n const { gaps } = analyzeHeadingDensity(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const gap of gaps) {\n if (results.length >= HEADING_DENSITY_MAX_VIOLATIONS) break;\n if (gap.wordCount <= HEADING_GAP_MAX_WORDS) continue;\n\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-heading-density',\n severity: 'warning',\n message: `${gap.wordCount}-word gap without a heading after \"${gap.afterHeading}\" at line ${gap.line} \\u2014 max recommended is ${HEADING_GAP_MAX_WORDS}`,\n suggestion: 'Add a heading to break up this long text block. AI systems rely on headings to segment and extract content.',\n line: gap.line,\n });\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 28: geo-structural-element-ratio (static)\n// ---------------------------------------------------------------------------\n\nexport const geoStructuralElementRatio: Rule = {\n name: 'geo-structural-element-ratio',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add structural elements (lists, tables, blockquotes, code blocks) for better AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const structuralCount = countStructuralElements(item.body);\n const expected = Math.floor(wordCount / WORDS_PER_STRUCTURAL_ELEMENT);\n\n if (structuralCount < expected) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-structural-element-ratio',\n severity: 'warning',\n message: `Found ${structuralCount} structural element(s) but expected at least ${expected} (1 per ${WORDS_PER_STRUCTURAL_ELEMENT} words in ${wordCount}-word post)`,\n suggestion: 'Add structural elements such as lists, tables, blockquotes, or code blocks. These are highly extractable by AI systems and improve content scannability.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** All GEO structure rules (static, no config dependency) */\nexport const geoStructureRules: Rule[] = [\n geoSectionTooLong,\n geoParagraphTooLong,\n geoMissingLists,\n geoCitationBlockUpperBound,\n geoOrphanedIntro,\n geoHeadingDensity,\n geoStructuralElementRatio,\n];\n","/**\n * GEO Freshness & Quality Rules\n * Validates content freshness signals, readability, and technical quality\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractH2Sections, countInternalLinks, hasMarkdownTable } from '../utils/geo-analyzer.js';\nimport {\n findStaleYearReferences,\n analyzePassiveVoice,\n extractSentences,\n findInlineHtml,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before most freshness rules apply */\nconst FRESHNESS_MIN_WORDS = 500;\n\n/** Maximum stale-year violations to report (avoids noise) */\nconst MAX_STALE_YEAR_VIOLATIONS = 5;\n\n/** Content older than this many months triggers outdated warning */\nconst OUTDATED_MONTHS_THRESHOLD = 6;\n\n/** Passive voice ratio above this triggers a warning */\nconst PASSIVE_VOICE_THRESHOLD = 0.15;\n\n/** Sentences longer than this word count are flagged */\nconst MAX_SENTENCE_WORDS = 40;\n\n/** Maximum long-sentence violations to report */\nconst MAX_LONG_SENTENCE_VIOLATIONS = 3;\n\n/** Minimum internal links expected in a blog post */\nconst MIN_INTERNAL_LINKS = 2;\n\n/** Maximum inline-HTML violations to report */\nconst MAX_INLINE_HTML_VIOLATIONS = 5;\n\n/** Comparison heading patterns (English and German) */\nconst COMPARISON_PATTERNS: RegExp[] = [\n /\\bvs\\.?\\b/i,\n /\\bversus\\b/i,\n /\\bcomparison\\b/i,\n /\\bcompared?\\s+to\\b/i,\n /\\bdifference\\s+between\\b/i,\n /\\bvergleich\\b/i,\n /\\bunterschied\\b/i,\n];\n\n// ---------------------------------------------------------------------------\n// Rule 8: geo-stale-date-references\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag year references that are more than 18 months old.\n * Stale dates cause AI systems to deprioritize content in answers.\n */\nexport const geoStaleDateReferences: Rule = {\n name: 'geo-stale-date-references',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Update or remove year references older than 18 months; replace with current data',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const allRefs = findStaleYearReferences(item.body, new Date());\n const staleRefs = allRefs.filter(ref => ref.isStale);\n if (staleRefs.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return staleRefs.slice(0, MAX_STALE_YEAR_VIOLATIONS).map(ref => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-stale-date-references',\n severity: 'warning' as const,\n message: `Year reference \"${ref.year}\" is more than 18 months old — AI systems deprioritize stale content`,\n suggestion: `Update or remove the \"${ref.year}\" reference. Replace with current data or add a note that the information has been verified.`,\n line: ref.line,\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 9: geo-outdated-content\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Warn when content has not been updated in over 6 months.\n * Uses updatedAt or date frontmatter fields.\n */\nexport const geoOutdatedContent: Rule = {\n name: 'geo-outdated-content',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Review and update content, then set updatedAt to today',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const rawDate = item.updatedAt ?? item.date;\n if (!rawDate) return [];\n\n const parsedDate = new Date(rawDate);\n if (isNaN(parsedDate.getTime())) return [];\n\n const now = new Date();\n const cutoff = new Date(now);\n cutoff.setMonth(cutoff.getMonth() - OUTDATED_MONTHS_THRESHOLD);\n\n if (parsedDate < cutoff) {\n const field = item.updatedAt ? 'updatedAt' : 'date';\n const monthsAgo = Math.floor(\n (now.getTime() - parsedDate.getTime()) / (1000 * 60 * 60 * 24 * 30)\n );\n\n return [{\n file: getDisplayPath(item),\n field,\n rule: 'geo-outdated-content',\n severity: 'warning',\n message: `Content was last updated ${monthsAgo} months ago — AI systems favor recently updated content`,\n suggestion: 'Review the content for accuracy, update any stale information, and set the updatedAt field to today.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 15: geo-passive-voice-excess\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag content with excessive passive voice usage.\n * Passive voice reduces clarity and makes content harder for AI to extract.\n */\nexport const geoPassiveVoiceExcess: Rule = {\n name: 'geo-passive-voice-excess',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Rewrite passive sentences in active voice for clearer AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const { passiveSentences, totalSentences, passiveRatio } = analyzePassiveVoice(item.body, item.locale);\n\n if (passiveRatio > PASSIVE_VOICE_THRESHOLD) {\n const percentage = Math.round(passiveRatio * 100);\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-passive-voice-excess',\n severity: 'warning',\n message: `${percentage}% of sentences (${passiveSentences}/${totalSentences}) use passive voice — aim for under ${Math.round(PASSIVE_VOICE_THRESHOLD * 100)}%`,\n suggestion: 'Rewrite passive constructions in active voice. For example, \"The report was written by the team\" becomes \"The team wrote the report.\"',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 16: geo-sentence-too-long\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag sentences exceeding 40 words.\n * Long sentences reduce readability and hinder AI snippet extraction.\n */\nexport const geoSentenceTooLong: Rule = {\n name: 'geo-sentence-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Break long sentences into two or more shorter, focused sentences',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const sentences = extractSentences(item.body);\n const longSentences = sentences\n .filter(entry => entry.wordCount > MAX_SENTENCE_WORDS)\n .sort((a, b) => b.wordCount - a.wordCount);\n\n if (longSentences.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return longSentences.slice(0, MAX_LONG_SENTENCE_VIOLATIONS).map(entry => {\n const preview = entry.text.split(/\\s+/).slice(0, 10).join(' ');\n\n return {\n file: displayPath,\n field: 'body',\n rule: 'geo-sentence-too-long',\n severity: 'warning' as const,\n message: `Sentence is ${entry.wordCount} words (max ${MAX_SENTENCE_WORDS}): \"${preview}...\"`,\n suggestion: 'Break this sentence into two or more shorter sentences for better readability and AI extraction.',\n };\n });\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 17: geo-low-internal-links\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Blog posts should contain at least 2 internal links.\n * Internal links strengthen topical authority signals for AI systems.\n */\nexport const geoLowInternalLinks: Rule = {\n name: 'geo-low-internal-links',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add 2-3 internal links to related content on the same site',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const linkCount = countInternalLinks(item.body);\n\n if (linkCount < MIN_INTERNAL_LINKS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-internal-links',\n severity: 'warning',\n message: `Found ${linkCount} internal link${linkCount === 1 ? '' : 's'} — aim for at least ${MIN_INTERNAL_LINKS}`,\n suggestion: 'Add 2-3 internal links to related blog posts or pages. Internal links strengthen topical authority signals for AI search systems.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 20: geo-comparison-table\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Comparison headings (containing \"vs\", \"versus\", \"comparison\", etc.)\n * should include a markdown table in their section body.\n * Tables in comparison sections are highly extractable by AI systems.\n */\nexport const geoComparisonTable: Rule = {\n name: 'geo-comparison-table',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a comparison table under each heading that discusses comparisons',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isComparison = COMPARISON_PATTERNS.some(pattern =>\n pattern.test(section.heading)\n );\n\n if (isComparison && !hasMarkdownTable(section.body)) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-comparison-table',\n severity: 'warning',\n message: `Comparison heading \"${section.heading}\" has no data table — tables increase AI citation rates for comparisons`,\n suggestion: 'Add a markdown comparison table (e.g., feature matrix or pros/cons) under this heading.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 21: geo-inline-html (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the inline HTML detection rule with project-specific allowed tags.\n * Applies to ALL content types (not just blog).\n */\nexport function createGeoInlineHtmlRule(allowedTags: string[]): Rule {\n return {\n name: 'geo-inline-html',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace inline HTML with markdown equivalents or add the tag to allowedHtmlTags config',\n run: (item: ContentItem): LintResult[] => {\n const tags = findInlineHtml(item.body, allowedTags);\n if (tags.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return tags.slice(0, MAX_INLINE_HTML_VIOLATIONS).map(tag => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-inline-html',\n severity: 'warning' as const,\n message: `Inline HTML tag <${tag.tag}> found — raw HTML reduces content portability across AI systems`,\n suggestion: `Replace <${tag.tag}> with a markdown equivalent, or add \"${tag.tag}\" to the allowedHtmlTags config if this is a custom MDX component.`,\n line: tag.line,\n }));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** Static GEO freshness rules (no config dependency) */\nexport const geoFreshnessStaticRules: Rule[] = [\n geoStaleDateReferences,\n geoOutdatedContent,\n geoPassiveVoiceExcess,\n geoSentenceTooLong,\n geoLowInternalLinks,\n geoComparisonTable,\n];\n\n/**\n * Factory: Build the complete GEO freshness rule set from config.\n * Returns all 7 rules: 6 static + 1 inline-html from factory.\n */\nexport function createGeoFreshnessRules(geo: GeoConfig): Rule[] {\n return [\n ...geoFreshnessStaticRules,\n createGeoInlineHtmlRule(geo.allowedHtmlTags ?? []),\n ];\n}\n","/**\n * GEO RAG Optimization Rules\n * Validates content patterns that improve retrieval and citation in RAG systems\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractH2Sections } from '../utils/geo-analyzer.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n detectUnresolvedOpenings,\n findUnexpandedAcronyms,\n findContextlessStatistics,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before standard RAG rules apply */\nconst RAG_MIN_WORDS = 500;\n\n/** Minimum word count before extraction trigger rule applies */\nconst EXTRACTION_TRIGGER_MIN_WORDS = 1000;\n\n/** Minimum word count before summary section rule applies */\nconst SUMMARY_MIN_WORDS = 2000;\n\n/** Minimum extraction triggers expected */\nconst MIN_EXTRACTION_TRIGGERS = 2;\n\n/** Maximum section self-containment violations to report */\nconst MAX_SELF_CONTAINMENT_VIOLATIONS = 3;\n\n/** Maximum acronym violations to report */\nconst MAX_ACRONYM_VIOLATIONS = 5;\n\n/** Maximum contextless statistic violations to report */\nconst MAX_STATISTIC_VIOLATIONS = 5;\n\n/** Number of leading words to inspect for vague openings */\nconst VAGUE_OPENING_WORD_LIMIT = 150;\n\n/** Summary/takeaway heading patterns (English and German) */\nconst SUMMARY_HEADING_PATTERNS: RegExp[] = [\n /tl;?dr/i,\n /summary/i,\n /key\\s*takeaway/i,\n /conclusion/i,\n /zusammenfassung/i,\n /fazit/i,\n /kernpunkte/i,\n];\n\n// ---------------------------------------------------------------------------\n// Rule 19: geo-extraction-triggers (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the extraction triggers rule with project-specific trigger phrases.\n * Checks that long-form content contains phrases that help AI systems identify\n * key takeaways and extractable statements.\n */\nexport function createGeoExtractionTriggersRule(triggers: string[]): Rule {\n return {\n name: 'geo-extraction-triggers',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add summary phrases like \"In summary\", \"Key takeaway\", or \"The main benefit is\" to help AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EXTRACTION_TRIGGER_MIN_WORDS) return [];\n\n if (triggers.length === 0) return [];\n\n const bodyLower = item.body.toLowerCase();\n let foundCount = 0;\n\n for (const trigger of triggers) {\n if (bodyLower.includes(trigger.toLowerCase())) {\n foundCount++;\n }\n }\n\n if (foundCount < MIN_EXTRACTION_TRIGGERS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-extraction-triggers',\n severity: 'warning',\n message: `Found ${foundCount} extraction trigger${foundCount === 1 ? '' : 's'} — recommend at least ${MIN_EXTRACTION_TRIGGERS} for AI discoverability`,\n suggestion: `Add summary phrases such as \"${triggers.slice(0, 3).join('\", \"')}\" to help AI systems identify and extract key statements.`,\n }];\n }\n\n return [];\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 23: geo-section-self-containment\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: H2 sections should not open with unresolved pronouns.\n * RAG systems chunk content at section boundaries; each chunk must stand alone.\n */\nexport const geoSectionSelfContainment: Rule = {\n name: 'geo-section-self-containment',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a specific subject instead of a pronoun like \"This\" or \"It\"',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const unresolved = detectUnresolvedOpenings(sections);\n\n if (unresolved.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return unresolved.slice(0, MAX_SELF_CONTAINMENT_VIOLATIONS).map(opening => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-section-self-containment',\n severity: 'warning' as const,\n message: `Section \"${opening.heading}\" opens with an unresolved reference: \"${opening.firstWord}\"`,\n suggestion: 'Start the section with a specific subject instead of a pronoun. RAG systems chunk at headings, so each section must be self-contained.',\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 24: geo-vague-opening (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the vague opening detection rule with project-specific filler phrases.\n * Flags articles that start with generic filler rather than substantive content.\n */\nexport function createGeoVagueOpeningRule(fillerPhrases: string[]): Rule {\n return {\n name: 'geo-vague-opening',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace the generic opening with a specific, substantive first sentence',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n if (fillerPhrases.length === 0) return [];\n\n // Extract the first paragraph or first 150 words\n const lines = item.body.split('\\n');\n const contentLines: string[] = [];\n let totalWords = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines at the start\n if (contentLines.length === 0 && !trimmed) continue;\n\n // Skip headings, imports, and JSX\n if (/^#{1,6}\\s+/.test(trimmed)) continue;\n if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) continue;\n if (trimmed.startsWith('<') && !trimmed.startsWith('<a')) continue;\n\n // Stop at first blank line after content started, or word limit\n if (contentLines.length > 0 && !trimmed) break;\n\n contentLines.push(trimmed);\n totalWords += trimmed.split(/\\s+/).length;\n if (totalWords >= VAGUE_OPENING_WORD_LIMIT) break;\n }\n\n const openingText = contentLines.join(' ').toLowerCase();\n if (!openingText) return [];\n\n for (const phrase of fillerPhrases) {\n if (openingText.startsWith(phrase.toLowerCase())) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-vague-opening',\n severity: 'warning',\n message: `Article opens with filler phrase \"${phrase}\" — AI systems deprioritize generic introductions`,\n suggestion: 'Replace the opening with a specific, substantive first sentence that directly addresses the topic.',\n }];\n }\n }\n\n return [];\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 25: geo-acronym-expansion (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the acronym expansion rule with project-specific allowlist.\n * Flags acronyms that are never expanded on first use, reducing AI comprehension.\n */\nexport function createGeoAcronymExpansionRule(allowlist: string[]): Rule {\n return {\n name: 'geo-acronym-expansion',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Expand each acronym on first use, e.g. \"Search Engine Optimization (SEO)\"',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const unexpanded = findUnexpandedAcronyms(item.body, allowlist);\n if (unexpanded.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return unexpanded.slice(0, MAX_ACRONYM_VIOLATIONS).map(entry => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-acronym-expansion',\n severity: 'warning' as const,\n message: `Acronym \"${entry.acronym}\" is used but never expanded — AI systems may misinterpret unexpanded acronyms`,\n suggestion: `Expand \"${entry.acronym}\" on first use, e.g. \"Full Name (${entry.acronym})\".`,\n line: entry.line,\n }));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 26: geo-statistic-without-context\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Statistics (percentages) should include source attribution or timeframe.\n * Contextless numbers reduce trust signals for AI citation.\n */\nexport const geoStatisticWithoutContext: Rule = {\n name: 'geo-statistic-without-context',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add source attribution or timeframe context to each statistic',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const contextless = findContextlessStatistics(item.body);\n if (contextless.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return contextless.slice(0, MAX_STATISTIC_VIOLATIONS).map(stat => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-statistic-without-context',\n severity: 'warning' as const,\n message: `Statistic \"${stat.statistic}\" lacks source attribution — unattributed data reduces AI citation confidence`,\n suggestion: 'Add source or timeframe context to the statistic, e.g. \"according to [Source]\" or \"as of 2024\".',\n line: stat.line,\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 27: geo-missing-summary-section\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Long-form content (2000+ words) should include a summary or takeaway section.\n * Summary sections are frequently extracted by AI as answer snippets.\n */\nexport const geoMissingSummarySection: Rule = {\n name: 'geo-missing-summary-section',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a \"## TL;DR\", \"## Key Takeaways\", or \"## Conclusion\" section',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < SUMMARY_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n\n const hasSummaryHeading = headings.some(heading =>\n SUMMARY_HEADING_PATTERNS.some(pattern => pattern.test(heading.text))\n );\n\n if (!hasSummaryHeading) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-summary-section',\n severity: 'warning',\n message: `Long-form content (${wordCount} words) has no summary or takeaway section — AI systems frequently extract these for answers`,\n suggestion: 'Add a \"## TL;DR\", \"## Key Takeaways\", \"## Fazit\", or \"## Conclusion\" section summarizing the main points.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** Static GEO RAG rules (no config dependency) */\nexport const geoRagStaticRules: Rule[] = [\n geoSectionSelfContainment,\n geoStatisticWithoutContext,\n geoMissingSummarySection,\n];\n\n/**\n * Factory: Build the complete GEO RAG rule set from config.\n * Returns all 6 rules: 3 static + 3 from factories.\n */\nexport function createGeoRagRules(geo: GeoConfig): Rule[] {\n return [\n ...geoRagStaticRules,\n createGeoExtractionTriggersRule(geo.extractionTriggers ?? []),\n createGeoVagueOpeningRule(geo.fillerPhrases ?? []),\n createGeoAcronymExpansionRule(geo.acronymAllowlist ?? []),\n ];\n}\n","/**\n * Transition Word Analyzer\n *\n * Measures the ratio of sentences containing logical connectors.\n * Content with low transition word usage reads as a series of\n * disconnected statements — bad for both readers and LLM extraction.\n *\n * Inspired by Yoast SEO's transition words assessment.\n */\n\nimport { extractSentences } from './geo-advanced-analyzer.js';\nimport { getTransitionWords } from '../data/index.js';\n\nexport interface TransitionWordAnalysis {\n /** Total sentences analyzed */\n totalSentences: number;\n /** Sentences containing at least one transition word/phrase */\n sentencesWithTransition: number;\n /** Ratio of sentences with transitions (0–1) */\n ratio: number;\n}\n\n/**\n * Check if a sentence contains at least one transition word or phrase.\n * Multi-word phrases are checked via substring match on the lowercased sentence.\n * Single words are checked via set membership after splitting.\n */\nfunction sentenceHasTransition(\n sentenceText: string,\n singleWords: ReadonlySet<string>,\n phrases: readonly string[],\n): boolean {\n const lower = sentenceText.toLowerCase();\n\n // Check multi-word phrases first (substring match)\n for (const phrase of phrases) {\n if (lower.includes(phrase)) return true;\n }\n\n // Check single words via set membership\n const words = lower\n .replace(/[^a-zA-ZäöüÄÖÜßà-ÿ\\s-]/g, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n for (const word of words) {\n if (singleWords.has(word)) return true;\n }\n\n return false;\n}\n\n/**\n * Analyze transition word usage across all sentences in the body.\n *\n * @example\n * analyzeTransitionWords(\"Dogs are great. However, cats are also nice.\")\n * // { totalSentences: 2, sentencesWithTransition: 1, ratio: 0.5 }\n */\nexport function analyzeTransitionWords(\n body: string,\n locale?: string,\n): TransitionWordAnalysis {\n const sentences = extractSentences(body);\n const lang = (locale ?? 'en').toLowerCase();\n const wordData = getTransitionWords(lang);\n\n if (!wordData || sentences.length === 0) {\n return { totalSentences: sentences.length, sentencesWithTransition: 0, ratio: 0 };\n }\n\n let sentencesWithTransition = 0;\n\n for (const { text } of sentences) {\n if (sentenceHasTransition(text, wordData.singleWords, wordData.phrases)) {\n sentencesWithTransition++;\n }\n }\n\n return {\n totalSentences: sentences.length,\n sentencesWithTransition,\n ratio: sentences.length > 0 ? sentencesWithTransition / sentences.length : 0,\n };\n}\n","/**\n * Sentence Beginnings Analyzer\n *\n * Detects consecutive sentences starting with the same word.\n * Inspired by Yoast SEO's sentence beginnings assessment.\n * Function words (articles, demonstratives) are skipped — the second\n * word is used instead, so \"The dog\" and \"The cat\" don't count as same-start.\n */\n\nimport { extractSentences } from './geo-advanced-analyzer.js';\nimport { getFirstWordExceptions } from '../data/index.js';\n\nexport interface ConsecutiveStartGroup {\n /** The repeated starting word (lowercased) */\n word: string;\n /** Number of consecutive sentences with this start */\n count: number;\n /** 1-indexed line estimate of the first sentence in the group */\n startIndex: number;\n}\n\nexport interface SentenceBeginningsAnalysis {\n /** Groups of 3+ consecutive sentences starting with the same word */\n groups: ConsecutiveStartGroup[];\n}\n\n/**\n * Get the effective first word of a sentence, skipping function words.\n * If the first word is in the exceptions set, the second word is used.\n */\nfunction getEffectiveFirstWord(\n sentenceText: string,\n exceptions: ReadonlySet<string>,\n): string {\n const words = sentenceText\n .split(/\\s+/)\n .filter(w => w.length > 0)\n .map(w => w.replace(/[^a-zA-ZäöüÄÖÜß]/g, '').toLowerCase());\n\n if (words.length === 0) return '';\n\n const first = words[0];\n if (exceptions.has(first) && words.length > 1) {\n return words[1];\n }\n return first;\n}\n\n/**\n * Analyze sentence beginnings for monotonous repetition.\n *\n * @example\n * analyzeSentenceBeginnings(\"We went home. We ate dinner. We watched TV.\")\n * // { groups: [{ word: \"we\", count: 3, startIndex: 0 }] }\n */\nexport function analyzeSentenceBeginnings(\n body: string,\n locale?: string,\n): SentenceBeginningsAnalysis {\n const sentences = extractSentences(body);\n const exceptions = getFirstWordExceptions(locale ?? 'en');\n const groups: ConsecutiveStartGroup[] = [];\n\n if (sentences.length < 3) return { groups };\n\n const firstWords = sentences.map(s => getEffectiveFirstWord(s.text, exceptions));\n\n let currentWord = firstWords[0];\n let runStart = 0;\n let runLength = 1;\n\n for (let i = 1; i < firstWords.length; i++) {\n const word = firstWords[i];\n if (word && word === currentWord) {\n runLength++;\n } else {\n if (runLength >= 3 && currentWord) {\n groups.push({ word: currentWord, count: runLength, startIndex: runStart });\n }\n currentWord = word;\n runStart = i;\n runLength = 1;\n }\n }\n\n // Flush final run\n if (runLength >= 3 && currentWord) {\n groups.push({ word: currentWord, count: runLength, startIndex: runStart });\n }\n\n return { groups };\n}\n","/**\n * Content Quality Rules\n * Detects jargon stuffing, content repetition, extreme sentence lengths,\n * low substance, low transition word usage, monotonous sentence starts,\n * and lack of sentence length variety.\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport {\n analyzeJargonDensity,\n analyzeRepetition,\n analyzeSentenceLength,\n analyzeSubstance,\n analyzeSentenceVariety,\n} from '../utils/content-quality-analyzer.js';\nimport { analyzeTransitionWords } from '../utils/transition-word-analyzer.js';\nimport { analyzeSentenceBeginnings } from '../utils/sentence-beginnings-analyzer.js';\n\n/** Minimum word count before quality rules apply */\nconst QUALITY_MIN_WORDS = 300;\n\n/** Jargon density thresholds */\nconst JARGON_WARNING_THRESHOLD = 0.08;\nconst JARGON_ERROR_THRESHOLD = 0.15;\n\n/** Repetition thresholds */\nconst REPETITION_SIMILARITY_WARNING = 0.15;\nconst REPETITION_SIMILARITY_ERROR = 0.25;\nconst REPEATED_PHRASE_MIN_COUNT = 5;\n\n/** Sentence length thresholds */\nconst SENTENCE_AVG_WARNING = 35;\nconst SENTENCE_AVG_ERROR = 50;\n\n/** Substance (type-token ratio) thresholds — lower = less diverse vocabulary */\nconst SUBSTANCE_WARNING_THRESHOLD = 0.25;\nconst SUBSTANCE_ERROR_THRESHOLD = 0.15;\n\n/** Transition words thresholds (ratio of sentences containing transition words) */\nconst TRANSITION_WARNING_THRESHOLD = 0.20;\nconst TRANSITION_ERROR_THRESHOLD = 0.10;\nconst TRANSITION_MIN_WORDS = 200;\n\n/** Consecutive sentence beginnings */\nconst CONSECUTIVE_STARTS_WARNING = 3;\nconst CONSECUTIVE_STARTS_ERROR = 5;\nconst CONSECUTIVE_STARTS_MIN_WORDS = 100;\n\n/** Sentence variety thresholds (coefficient of variation) */\nconst VARIETY_WARNING_THRESHOLD = 0.30;\nconst VARIETY_MIN_WORDS = 300;\nconst VARIETY_MIN_SENTENCES = 10;\n\n// ─── Jargon Density Rule ───────────────────────────────────────────────────\n\nexport const jargonDensity: Rule = {\n name: 'content-jargon-density',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Replace complex or uncommon words with simpler alternatives',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeJargonDensity(item.body, locale);\n\n if (analysis.density >= JARGON_ERROR_THRESHOLD) {\n const topWords = analysis.topJargonWords\n .slice(0, 3)\n .map(w => `\"${w.word}\" (${w.count}x)`)\n .join(', ');\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-jargon-density',\n severity: 'error',\n message: `Extreme complex word density: ${Math.round(analysis.density * 100)}% of words are complex/uncommon (${analysis.jargonCount}/${analysis.totalWords})`,\n suggestion: `Replace complex words with simpler alternatives. Worst offenders: ${topWords}.`,\n }];\n }\n\n if (analysis.density >= JARGON_WARNING_THRESHOLD) {\n const topWords = analysis.topJargonWords\n .slice(0, 3)\n .map(w => `\"${w.word}\" (${w.count}x)`)\n .join(', ');\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-jargon-density',\n severity: 'warning',\n message: `High complex word density: ${Math.round(analysis.density * 100)}% of words are complex/uncommon (${analysis.jargonCount}/${analysis.totalWords})`,\n suggestion: `Reduce complex vocabulary for clearer communication. Top complex words: ${topWords}.`,\n }];\n }\n\n return [];\n },\n};\n\n// ─── Content Repetition Rule ───────────────────────────────────────────────\n\nexport const contentRepetition: Rule = {\n name: 'content-repetition',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Remove or rewrite paragraphs that repeat the same ideas',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeRepetition(item.body);\n const results: LintResult[] = [];\n\n // Check paragraph similarity\n if (analysis.avgParagraphSimilarity >= REPETITION_SIMILARITY_ERROR) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'error',\n message: `Extreme content repetition: ${Math.round(analysis.avgParagraphSimilarity * 100)}% average paragraph similarity`,\n suggestion: 'Paragraphs are rehashing the same ideas. Remove duplicate content and add unique information to each section.',\n });\n } else if (analysis.avgParagraphSimilarity >= REPETITION_SIMILARITY_WARNING) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'warning',\n message: `High content repetition: ${Math.round(analysis.avgParagraphSimilarity * 100)}% average paragraph similarity`,\n suggestion: 'Several paragraphs cover the same ground. Consolidate repeated ideas and add distinct value to each section.',\n });\n }\n\n // Check repeated phrases\n if (analysis.repeatedPhraseCount >= REPEATED_PHRASE_MIN_COUNT) {\n const topPhrase = analysis.topRepeatedPhrases[0];\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'warning',\n message: `${analysis.repeatedPhraseCount} phrases repeated 3+ times. Most repeated: \"${topPhrase.phrase}\" (${topPhrase.count}x)`,\n suggestion: 'Vary your language to avoid repetitive phrasing. Use synonyms or restructure sentences.',\n });\n }\n\n return results;\n },\n};\n\n// ─── Sentence Length Extreme Rule ──────────────────────────────────────────\n\nexport const sentenceLengthExtreme: Rule = {\n name: 'content-sentence-length-extreme',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Break long sentences into shorter ones (aim for 15-25 words per sentence)',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeSentenceLength(item.body);\n\n if (analysis.totalSentences === 0) return [];\n\n if (analysis.avgWordsPerSentence >= SENTENCE_AVG_ERROR) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-length-extreme',\n severity: 'error',\n message: `Extreme average sentence length: ${Math.round(analysis.avgWordsPerSentence)} words/sentence (longest: ${analysis.maxWordsPerSentence} words, ${analysis.sentencesOver60Words} sentences over 60 words)`,\n suggestion: 'Break sentences into digestible chunks. Aim for 15-25 words per sentence. Readers and AI models struggle with extremely long sentences.',\n }];\n }\n\n if (analysis.avgWordsPerSentence >= SENTENCE_AVG_WARNING) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-length-extreme',\n severity: 'warning',\n message: `High average sentence length: ${Math.round(analysis.avgWordsPerSentence)} words/sentence (longest: ${analysis.maxWordsPerSentence} words)`,\n suggestion: 'Consider splitting longer sentences. Good readability requires sentences of 15-25 words on average.',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Substance Ratio Rule ──────────────────────────────────────────────────\n\nexport const substanceRatio: Rule = {\n name: 'content-substance-ratio',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add specific, concrete information instead of repeating abstract concepts',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeSubstance(item.body);\n\n if (analysis.totalContentWords < 50) return [];\n\n if (analysis.typeTokenRatio <= SUBSTANCE_ERROR_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-substance-ratio',\n severity: 'error',\n message: `Extremely low vocabulary diversity: ${Math.round(analysis.typeTokenRatio * 100)}% unique words (${analysis.uniqueContentWords} unique out of ${analysis.totalContentWords} content words)`,\n suggestion: 'The same words are recycled extensively. Add concrete examples, specific data, and varied terminology.',\n }];\n }\n\n if (analysis.typeTokenRatio <= SUBSTANCE_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-substance-ratio',\n severity: 'warning',\n message: `Low vocabulary diversity: ${Math.round(analysis.typeTokenRatio * 100)}% unique words (${analysis.uniqueContentWords} unique out of ${analysis.totalContentWords} content words)`,\n suggestion: 'Increase vocabulary variety. Use specific terms, examples, and data points instead of repeating the same abstract concepts.',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Transition Words Rule ────────────────────────────────────────────────\n\nexport const lowTransitionWords: Rule = {\n name: 'content-low-transition-words',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add transition words (however, therefore, for example, in addition) to connect ideas between sentences',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < TRANSITION_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeTransitionWords(item.body, locale);\n\n if (analysis.totalSentences < 5) return [];\n\n if (analysis.ratio < TRANSITION_ERROR_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-low-transition-words',\n severity: 'error',\n message: `Very few transition words: ${Math.round(analysis.ratio * 100)}% of sentences (${analysis.sentencesWithTransition}/${analysis.totalSentences}) — aim for at least 20%`,\n suggestion: 'Add transition words to connect ideas: \"however\", \"therefore\", \"for example\", \"in addition\", \"as a result\". Content reads as disconnected statements without them.',\n }];\n }\n\n if (analysis.ratio < TRANSITION_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-low-transition-words',\n severity: 'warning',\n message: `Low transition word usage: ${Math.round(analysis.ratio * 100)}% of sentences (${analysis.sentencesWithTransition}/${analysis.totalSentences}) — aim for at least 20%`,\n suggestion: 'Improve content flow by adding transition words: \"however\", \"therefore\", \"for example\", \"in contrast\", \"as a result\".',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Consecutive Sentence Beginnings Rule ─────────────────────────────────\n\nexport const consecutiveStarts: Rule = {\n name: 'content-consecutive-starts',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Vary sentence openings — use transition words, prepositional phrases, or reversed structures',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < CONSECUTIVE_STARTS_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeSentenceBeginnings(item.body, locale);\n\n if (analysis.groups.length === 0) return [];\n\n // Report the worst group (highest count)\n const worst = analysis.groups.reduce((a, b) => a.count > b.count ? a : b);\n\n if (worst.count >= CONSECUTIVE_STARTS_ERROR) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-consecutive-starts',\n severity: 'error',\n message: `${worst.count} consecutive sentences start with \"${worst.word}\" — vary sentence openings`,\n suggestion: `Rephrase some sentences to begin with different words. Try starting with a transition word, a prepositional phrase, or by reversing the sentence structure.`,\n }];\n }\n\n if (worst.count >= CONSECUTIVE_STARTS_WARNING) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-consecutive-starts',\n severity: 'warning',\n message: `${worst.count} consecutive sentences start with \"${worst.word}\" — vary sentence openings`,\n suggestion: `Rephrase some sentences to begin with different words. Try starting with a transition word, a prepositional phrase, or by reversing the sentence structure.`,\n }];\n }\n\n return [];\n },\n};\n\n// ─── Sentence Variety Rule ────────────────────────────────────────────────\n\nexport const sentenceVariety: Rule = {\n name: 'content-sentence-variety',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Mix short punchy sentences with longer explanatory ones for better rhythm',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < VARIETY_MIN_WORDS) return [];\n\n const analysis = analyzeSentenceVariety(item.body);\n\n if (analysis.totalSentences < VARIETY_MIN_SENTENCES) return [];\n\n if (analysis.coefficientOfVariation < VARIETY_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-variety',\n severity: 'warning',\n message: `Monotonous sentence lengths: CV ${analysis.coefficientOfVariation} (avg ${analysis.avgLength} words, std dev ${analysis.stdDev}). Mix short and long sentences.`,\n suggestion: 'Vary sentence length: follow a long sentence with a short one. Use fragments for emphasis. Break up paragraphs with 5-10 word sentences between 25+ word ones.',\n }];\n }\n\n return [];\n },\n};\n\n/** All content quality rules */\nexport const contentQualityRules: Rule[] = [\n jargonDensity,\n contentRepetition,\n sentenceLengthExtreme,\n substanceRatio,\n lowTransitionWords,\n consecutiveStarts,\n sentenceVariety,\n];\n","/**\n * Technical Site-Level Rules\n * Validates site-wide technical requirements for AI citation optimization\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { TechnicalConfig } from '../config/types.js';\n\n/**\n * Rule: Site should have at least one RSS/Atom/JSON feed\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createNoFeedRule(\n feedUrls: string[] | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'technical-no-feed',\n severity: 'warning',\n category: 'technical',\n fixStrategy:\n 'Add an RSS or JSON feed endpoint exposing blog posts with full content.',\n run: (_item: ContentItem, _context: RuleContext): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // undefined = not configured, skip silently\n if (feedUrls === undefined) return [];\n\n // Empty array = user declared they have no feeds — flag it\n if (feedUrls.length === 0) {\n return [\n {\n file: '_site',\n field: 'feed',\n rule: 'technical-no-feed',\n severity: 'warning',\n message:\n 'No RSS/Atom/JSON feed detected — AI systems lose a structured ingestion path',\n suggestion:\n 'Feeds provide a structured ingestion path for AI systems beyond crawler discovery. Add an RSS or JSON feed endpoint.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/**\n * Rule: Site should have a /llms.txt endpoint\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createNoLlmsTxtRule(\n llmsTxtUrl: string | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'technical-no-llms-txt',\n severity: 'warning',\n category: 'technical',\n fixStrategy:\n 'Create a /llms.txt endpoint that maps your most important content for LLM consumption in Markdown format.',\n run: (_item: ContentItem, _context: RuleContext): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // undefined = not configured, skip silently\n if (llmsTxtUrl === undefined) return [];\n\n // Empty string = user declared they don't have llms.txt — flag it\n if (llmsTxtUrl.trim() === '') {\n return [\n {\n file: '_site',\n field: 'llms-txt',\n rule: 'technical-no-llms-txt',\n severity: 'warning',\n message:\n 'No /llms.txt endpoint detected — missing the emerging standard for LLM content declaration',\n suggestion:\n 'llms.txt is the robots.txt equivalent for AI — trivial to add, future-proofs your site for LLM crawlers.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/** Build the complete technical site-level rule set from config */\nexport function createTechnicalSiteRules(technical: TechnicalConfig): Rule[] {\n return [\n createNoFeedRule(technical.feedUrls),\n createNoLlmsTxtRule(technical.llmsTxtUrl),\n ];\n}\n","/**\n * Rule Registry\n * Builds the complete rule set from configuration and provides runner functions\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { GeoLintConfig } from '../config/types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\n\n// Static rule imports\nimport { titleRules } from './title-rules.js';\nimport { descriptionRules } from './description-rules.js';\nimport { duplicateRules } from './duplicate-rules.js';\nimport { headingRules } from './heading-rules.js';\nimport { imageRules } from './image-rules.js';\nimport { contentRules } from './content-rules.js';\nimport { ogRules } from './og-rules.js';\nimport { performanceRules } from './performance-rules.js';\nimport { robotsRules } from './robots-rules.js';\nimport { slugRules } from './slug-rules.js';\nimport { createI18nRules } from './i18n-rules.js';\nimport { dateRules } from './date-rules.js';\nimport { createSchemaRules } from './schema-rules.js';\nimport { keywordCoherenceRules } from './keyword-coherence-rules.js';\n\n// Factory rule imports\nimport { createLinkRules } from './link-rules.js';\nimport { createExternalLinkRules } from './external-link-rules.js';\nimport { createOrphanRules } from './orphan-rules.js';\nimport { createGeoRules } from './geo-rules.js';\nimport { createCategoryRules } from './category-rules.js';\nimport { createCanonicalRules } from './canonical-rules.js';\n\n// GEO advanced rule imports\nimport { createGeoEeatRules } from './geo-eeat-rules.js';\nimport { geoStructureRules } from './geo-structure-rules.js';\nimport { createGeoFreshnessRules } from './geo-freshness-rules.js';\nimport { createGeoRagRules } from './geo-rag-rules.js';\n\n// Content quality rules\nimport { contentQualityRules } from './content-quality-rules.js';\n\n// Technical site-level rules\nimport { createTechnicalSiteRules } from './technical-site-rules.js';\n\n/**\n * Build the complete rule set from config and link extractor\n */\nexport function buildRules(config: GeoLintConfig, linkExtractor: LinkExtractor): Rule[] {\n const rules: Rule[] = [\n ...titleRules,\n ...descriptionRules,\n ...duplicateRules,\n ...headingRules,\n ...createLinkRules(linkExtractor),\n ...createExternalLinkRules(linkExtractor),\n ...imageRules,\n ...contentRules,\n ...ogRules,\n ...performanceRules,\n ...createOrphanRules(linkExtractor),\n ...robotsRules,\n ...slugRules,\n ...createI18nRules(config.i18n),\n ...dateRules,\n ...(config.categories.length > 0 ? createCategoryRules(config.categories) : []),\n ...createSchemaRules(config.geo),\n ...createGeoRules(config.geo),\n ...createGeoEeatRules(config.geo),\n ...geoStructureRules,\n ...createGeoFreshnessRules(config.geo),\n ...createGeoRagRules(config.geo),\n ...keywordCoherenceRules,\n ...createCanonicalRules(config.siteUrl),\n ...contentQualityRules,\n ...createTechnicalSiteRules(config.technical),\n ];\n\n // Apply user rule overrides (severity changes + disabling)\n return rules.map(rule => applyRuleOverride(rule, config.rules));\n}\n\n/**\n * Apply a user-configured severity override to a rule.\n * 'off' disables the rule by replacing its run function with a no-op.\n */\nfunction applyRuleOverride(\n rule: Rule,\n overrides: Record<string, 'error' | 'warning' | 'off'>\n): Rule {\n const override = overrides[rule.name];\n if (!override) return rule;\n if (override === 'off') return { ...rule, run: () => [] };\n return { ...rule, severity: override };\n}\n\n/**\n * Run a single rule against a content item (with error isolation)\n */\nexport function runRule(rule: Rule, item: ContentItem, context: RuleContext): LintResult[] {\n try {\n return rule.run(item, context);\n } catch (error) {\n console.error(`Rule ${rule.name} failed on ${item.slug}:`, error);\n return [];\n }\n}\n\n/**\n * Run all provided rules against a single content item\n */\nexport function runRulesOnItem(\n item: ContentItem,\n context: RuleContext,\n rules: Rule[]\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const rule of rules) {\n const ruleResults = runRule(rule, item, context);\n results.push(...ruleResults);\n }\n\n return results;\n}\n\n/**\n * Run all provided rules against all content items\n */\nexport function runAllRules(\n items: ContentItem[],\n context: RuleContext,\n rules: Rule[]\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const item of items) {\n const itemResults = runRulesOnItem(item, context, rules);\n results.push(...itemResults);\n }\n\n return results;\n}\n\n// Re-export static rules for selective use\nexport { titleRules } from './title-rules.js';\nexport { descriptionRules } from './description-rules.js';\nexport { duplicateRules } from './duplicate-rules.js';\nexport { headingRules } from './heading-rules.js';\nexport { imageRules } from './image-rules.js';\nexport { contentRules } from './content-rules.js';\nexport { ogRules } from './og-rules.js';\nexport { performanceRules } from './performance-rules.js';\nexport { robotsRules } from './robots-rules.js';\nexport { slugRules } from './slug-rules.js';\nexport { i18nRules, createI18nRules } from './i18n-rules.js';\nexport { dateRules } from './date-rules.js';\nexport { schemaStaticRules, schemaRules, createSchemaRules, createSchemaSameAsRule } from './schema-rules.js';\nexport { keywordCoherenceRules } from './keyword-coherence-rules.js';\nexport { geoStaticRules, geoRules } from './geo-rules.js';\n\n// Re-export factory functions for selective use\nexport { createLinkRules } from './link-rules.js';\nexport { createExternalLinkRules } from './external-link-rules.js';\nexport { createOrphanRules } from './orphan-rules.js';\nexport { createGeoRules, createGeoEntityRule } from './geo-rules.js';\nexport { createCategoryRules } from './category-rules.js';\nexport { createCanonicalRules } from './canonical-rules.js';\n\n// GEO advanced rule re-exports\nexport { geoEeatStaticRules, createGeoEeatRules } from './geo-eeat-rules.js';\nexport { geoStructureRules } from './geo-structure-rules.js';\nexport { geoFreshnessStaticRules, createGeoFreshnessRules } from './geo-freshness-rules.js';\nexport { geoRagStaticRules, createGeoRagRules } from './geo-rag-rules.js';\n\n// Content quality rule re-exports\nexport { contentQualityRules } from './content-quality-rules.js';\n\n// Technical site-level rule re-exports\nexport { createNoFeedRule, createNoLlmsTxtRule, createTechnicalSiteRules } from './technical-site-rules.js';\n","/**\n * @ijonis/geo-lint Reporter\n * Formats and outputs lint results with color-coding\n */\n\nimport type { LintResult, Severity } from './types.js';\n\n/** ANSI color codes for terminal output */\nconst COLORS = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n} as const;\n\nexport interface ReportSummary {\n errors: number;\n warnings: number;\n passed: number;\n total: number;\n excluded: number;\n}\n\n/** Group results by file path */\nfunction groupByFile(results: LintResult[]): Map<string, LintResult[]> {\n const grouped = new Map<string, LintResult[]>();\n for (const result of results) {\n const existing = grouped.get(result.file) || [];\n existing.push(result);\n grouped.set(result.file, existing);\n }\n return grouped;\n}\n\n/** Format a single lint result line */\nfunction formatResult(result: LintResult): string {\n const { red, yellow, dim, reset } = COLORS;\n const icon = result.severity === 'error' ? `${red}\\u2717${reset}` : `${yellow}\\u26A0${reset}`;\n const ruleTag = `${dim}[${result.rule}]${reset}`;\n\n let line = ` ${icon} ${ruleTag} ${result.message}`;\n\n if (result.line) {\n line += ` ${dim}(line ${result.line})${reset}`;\n }\n\n if (result.suggestion) {\n line += `\\n ${dim}\\u2192 ${result.suggestion}${reset}`;\n }\n\n return line;\n}\n\n/** Print results grouped by severity */\nfunction printResultsBySection(\n results: LintResult[],\n severity: Severity,\n label: string,\n): void {\n const filtered = results.filter(r => r.severity === severity);\n if (filtered.length === 0) return;\n\n const { red, yellow, bold, reset } = COLORS;\n const color = severity === 'error' ? red : yellow;\n const grouped = groupByFile(filtered);\n\n console.log(`\\n${color}${bold}${label} (${filtered.length}):${reset}\\n`);\n\n for (const [file, fileResults] of grouped) {\n console.log(` ${bold}${file}${reset}`);\n for (const result of fileResults) {\n console.log(formatResult(result));\n }\n console.log('');\n }\n}\n\n/** Print summary statistics */\nfunction printSummary(summary: ReportSummary): void {\n const { red, yellow, green, bold, reset, dim } = COLORS;\n\n console.log(`${dim}${'─'.repeat(50)}${reset}`);\n console.log(`${bold}Summary:${reset}`);\n\n if (summary.errors > 0) {\n console.log(` ${red}\\u2717 ${summary.errors} error(s)${reset} ${dim}(build blocked)${reset}`);\n }\n if (summary.warnings > 0) {\n console.log(` ${yellow}\\u26A0 ${summary.warnings} warning(s)${reset}`);\n }\n if (summary.passed > 0) {\n console.log(` ${green}\\u2713 ${summary.passed} file(s) passed${reset}`);\n }\n if (summary.excluded > 0) {\n console.log(` ${dim}\\u2298 ${summary.excluded} file(s) excluded${reset}`);\n }\n\n console.log(`\\n ${dim}Total: ${summary.total} files checked${reset}\\n`);\n}\n\n/** Format and output all lint results. Returns summary for exit code. */\nexport function formatResults(\n results: LintResult[],\n totalFiles: number,\n excludedFiles: number = 0,\n): ReportSummary {\n const { bold, reset, cyan, green, dim } = COLORS;\n\n const errors = results.filter(r => r.severity === 'error').length;\n const warnings = results.filter(r => r.severity === 'warning').length;\n const filesWithIssues = new Set(results.map(r => r.file)).size;\n const passed = totalFiles - filesWithIssues;\n\n const summary: ReportSummary = { errors, warnings, passed, total: totalFiles, excluded: excludedFiles };\n\n console.log(`\\n${cyan}${bold}GEO Lint Results${reset}`);\n console.log(`${cyan}${'═'.repeat(50)}${reset}`);\n\n if (results.length === 0) {\n console.log(`\\n${green}${bold}\\u2713 GEO Lint: All checks passed!${reset}\\n`);\n console.log(` ${dim}${totalFiles} files checked${reset}\\n`);\n return summary;\n }\n\n printResultsBySection(results, 'error', 'ERRORS');\n printResultsBySection(results, 'warning', 'WARNINGS');\n printSummary(summary);\n\n return summary;\n}\n\n/** Format results as JSON for agent consumption */\nexport function formatResultsJson(results: LintResult[]): string {\n return JSON.stringify(results, null, 2);\n}\n\n/** Print a simple progress message */\nexport function printProgress(message: string): void {\n const { dim, reset } = COLORS;\n console.log(`${dim}${message}${reset}`);\n}\n"],"mappings":"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","names":["import_node_path","import_node_fs","import_node_fs","import_node_path","matter","isInCodeBlock","import_node_fs","import_node_path","isInCodeBlock","singleWords","multiWordPhrases","DEFAULT_CONFIG","analyzeFaqQuality","analyzeFaqQuality","singleWords","require"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/cli.ts","../src/index.ts","../src/config/loader.ts","../src/config/defaults.ts","../src/adapters/mdx.ts","../src/utils/link-extractor.ts","../src/utils/slug-resolver.ts","../src/utils/display-path.ts","../src/utils/resolve-thresholds.ts","../src/rules/title-rules.ts","../src/rules/description-rules.ts","../src/rules/duplicate-rules.ts","../src/utils/plaintext-structure.ts","../src/utils/heading-extractor.ts","../src/rules/heading-rules.ts","../src/utils/image-extractor.ts","../src/rules/image-rules.ts","../src/utils/word-counter.ts","../src/utils/readability.ts","../src/rules/content-rules.ts","../src/rules/og-rules.ts","../src/rules/performance-rules.ts","../src/rules/robots-rules.ts","../src/rules/slug-rules.ts","../src/rules/i18n-rules.ts","../src/rules/date-rules.ts","../src/utils/geo-analyzer.ts","../src/utils/geo-advanced-analyzer.ts","../src/rules/schema-rules.ts","../src/rules/keyword-coherence-rules.ts","../src/rules/link-rules.ts","../src/rules/external-link-rules.ts","../src/rules/orphan-rules.ts","../src/data/frequency-en.ts","../src/data/frequency-de.ts","../src/data/transition-words-en.ts","../src/data/transition-words-de.ts","../src/data/first-word-exceptions-en.ts","../src/data/first-word-exceptions-de.ts","../src/data/index.ts","../src/utils/word-complexity.ts","../src/utils/content-quality-analyzer.ts","../src/rules/geo-rules.ts","../src/rules/category-rules.ts","../src/rules/canonical-rules.ts","../src/rules/geo-eeat-rules.ts","../src/rules/geo-structure-rules.ts","../src/rules/geo-freshness-rules.ts","../src/rules/geo-rag-rules.ts","../src/utils/transition-word-analyzer.ts","../src/utils/sentence-beginnings-analyzer.ts","../src/rules/content-quality-rules.ts","../src/rules/technical-site-rules.ts","../src/rules/index.ts","../src/reporter.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","#!/usr/bin/env node\n\n/**\n * @ijonis/geo-lint CLI\n * Command-line interface for the SEO/GEO content linter\n */\n\nimport { createRequire } from 'node:module';\nimport { lint } from './index.js';\nimport { loadConfig } from './config/loader.js';\nimport { DEFAULT_CONFIG } from './config/defaults.js';\nimport { buildRules } from './rules/index.js';\nimport type { GeoLintConfig } from './config/types.js';\nimport { createLinkExtractor } from './utils/link-extractor.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json') as { version: string };\n\nconst args = process.argv.slice(2);\n\nfunction getFlag(name: string): string | undefined {\n const arg = args.find(a => a.startsWith(`--${name}=`));\n return arg?.split('=').slice(1).join('=');\n}\n\nfunction hasFlag(name: string): boolean {\n return args.includes(`--${name}`) || args.includes(`-${name.charAt(0)}`);\n}\n\nfunction printHelp(): void {\n console.log(`\n@ijonis/geo-lint — SEO & GEO linter for Markdown/MDX content\n\nUsage:\n geo-lint [options]\n\nOptions:\n --root=<path> Project root directory (default: cwd)\n --config=<path> Explicit config file path\n --format=pretty Human-readable colored output (default)\n --format=json Machine-readable JSON output (for AI agents)\n --rules List all registered rules with fix strategies\n -h, --help Show this help message\n -v, --version Show version\n\nExamples:\n geo-lint # Lint with default config\n geo-lint --format=json # JSON output for agent consumption\n geo-lint --rules # List all available rules\n geo-lint --root=./my-project # Lint a different project\n`);\n}\n\nfunction printVersion(): void {\n console.log(version);\n}\n\nasync function printRules(): Promise<void> {\n const projectRoot = getFlag('root') ?? process.cwd();\n\n let config: GeoLintConfig;\n try {\n config = await loadConfig(projectRoot);\n } catch {\n config = { siteUrl: 'https://example.com', ...DEFAULT_CONFIG } as GeoLintConfig;\n }\n\n const linkExtractor = createLinkExtractor(config.siteUrl);\n const rules = buildRules(config, linkExtractor);\n\n const ruleList = rules.map(r => ({\n name: r.name,\n severity: r.severity,\n category: r.category ?? 'uncategorized',\n fixStrategy: r.fixStrategy ?? null,\n }));\n\n console.log(JSON.stringify(ruleList, null, 2));\n}\n\nasync function main(): Promise<void> {\n if (hasFlag('help') || hasFlag('h')) {\n printHelp();\n process.exit(0);\n }\n\n if (hasFlag('version') || hasFlag('v')) {\n printVersion();\n process.exit(0);\n }\n\n if (hasFlag('rules')) {\n await printRules();\n process.exit(0);\n }\n\n const format = (getFlag('format') ?? 'pretty') as 'pretty' | 'json';\n const projectRoot = getFlag('root');\n\n const exitCode = await lint({ projectRoot, format });\n process.exit(exitCode);\n}\n\nmain().catch(error => {\n console.error('geo-lint failed:', error.message);\n process.exit(1);\n});\n","/**\n * @ijonis/geo-lint\n * SEO and GEO (Generative Engine Optimization) linter for Markdown/MDX content\n *\n * The first open-source linter that checks your content for AI search visibility.\n */\n\nimport { resolve } from 'node:path';\nimport { loadConfig, mergeWithDefaults, defineConfig } from './config/loader.js';\nimport type { GeoLintConfig, GeoLintUserConfig } from './config/types.js';\nimport { loadContentItems } from './adapters/mdx.js';\nimport type { ContentAdapter } from './adapters/types.js';\nimport { createLinkExtractor } from './utils/link-extractor.js';\nimport { buildSlugRegistry, buildImageRegistry } from './utils/slug-resolver.js';\nimport { buildRules, runAllRules } from './rules/index.js';\nimport { formatResults, formatResultsJson, printProgress } from './reporter.js';\nimport type { LintResult, Rule, ContentItem, RuleContext, GlobalRule } from './types.js';\n\n/** Options for the lint() function */\nexport interface LintOptions {\n /** Project root directory (defaults to cwd) */\n projectRoot?: string;\n /** Explicit config (skips file loading) */\n config?: GeoLintUserConfig;\n /** Custom content adapter (skips default MDX scanning) */\n adapter?: ContentAdapter;\n /** Global rules to run after per-item rules */\n globalRules?: GlobalRule[];\n /** Output format: 'pretty' for terminal, 'json' for machine consumption */\n format?: 'pretty' | 'json';\n}\n\n/**\n * Run the complete GEO lint process.\n * Returns exit code: 0 for success (no errors), 1 for errors found.\n */\nexport async function lint(options: LintOptions = {}): Promise<number> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n\n // Load config\n const config: GeoLintConfig = options.config\n ? mergeWithDefaults(options.config)\n : await loadConfig(projectRoot);\n\n const isPretty = (options.format ?? 'pretty') === 'pretty';\n\n if (isPretty) printProgress('Loading content...');\n\n // Load content items\n const contentItems = options.adapter\n ? await options.adapter.loadItems(projectRoot)\n : loadContentItems(config.contentPaths, projectRoot);\n\n // Separate excluded items (still included in context for link validation)\n const excludeSlugs = new Set(config.excludeSlugs);\n const excludeCategories = new Set(config.excludeCategories);\n\n const isExcluded = (item: ContentItem): boolean => {\n if (item.category && excludeCategories.has(item.category)) return true;\n return excludeSlugs.has(item.slug);\n };\n\n const excludedItems = contentItems.filter(isExcluded);\n const lintableItems = contentItems.filter(item => !isExcluded(item));\n\n if (isPretty) {\n printProgress(`Loaded ${contentItems.length} content files (${excludedItems.length} excluded)`);\n printProgress('Building validation context...');\n }\n\n // Build validation context with ALL items (excluded are still valid link targets)\n const linkExtractor = createLinkExtractor(config.siteUrl);\n const context: RuleContext = {\n allContent: contentItems,\n validSlugs: buildSlugRegistry(contentItems, config.staticRoutes, config.contentPaths),\n validImages: buildImageRegistry(config.imageDirectories),\n thresholds: config.thresholds,\n geoEnabledContentTypes: config.geo.enabledContentTypes ?? ['blog'],\n defaultLocale: config.i18n.defaultLocale,\n };\n\n if (isPretty) {\n printProgress(`Found ${context.validSlugs.size} valid URLs, ${context.validImages.size} images`);\n printProgress('Running validation rules...');\n }\n\n // Build and run rules\n const rules = buildRules(config, linkExtractor);\n const results: LintResult[] = runAllRules(lintableItems, context, rules);\n\n // Run global rules (user-provided, e.g., service registry checks)\n if (options.globalRules) {\n for (const globalRule of options.globalRules) {\n try {\n results.push(...globalRule.run());\n } catch (error) {\n if (isPretty) console.error(`Global rule ${globalRule.name} failed:`, error);\n }\n }\n }\n\n // Output results\n if (options.format === 'json') {\n console.log(formatResultsJson(results));\n } else {\n formatResults(results, lintableItems.length, excludedItems.length);\n }\n\n return 0;\n}\n\n/**\n * Run the linter and return raw results (no console output).\n * Useful for programmatic integration.\n */\nexport async function lintQuiet(options: LintOptions = {}): Promise<LintResult[]> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n\n const config: GeoLintConfig = options.config\n ? mergeWithDefaults(options.config)\n : await loadConfig(projectRoot);\n\n const contentItems = options.adapter\n ? await options.adapter.loadItems(projectRoot)\n : loadContentItems(config.contentPaths, projectRoot);\n\n const excludeSlugs = new Set(config.excludeSlugs);\n const excludeCategories = new Set(config.excludeCategories);\n\n const isExcluded = (item: ContentItem): boolean => {\n if (item.category && excludeCategories.has(item.category)) return true;\n return excludeSlugs.has(item.slug);\n };\n\n const lintableItems = contentItems.filter(item => !isExcluded(item));\n const linkExtractor = createLinkExtractor(config.siteUrl);\n\n const context: RuleContext = {\n allContent: contentItems,\n validSlugs: buildSlugRegistry(contentItems, config.staticRoutes, config.contentPaths),\n validImages: buildImageRegistry(config.imageDirectories),\n thresholds: config.thresholds,\n geoEnabledContentTypes: config.geo.enabledContentTypes ?? ['blog'],\n defaultLocale: config.i18n.defaultLocale,\n };\n\n const rules = buildRules(config, linkExtractor);\n return runAllRules(lintableItems, context, rules);\n}\n\n// Re-export public API\nexport { defineConfig } from './config/loader.js';\nexport type {\n GeoLintUserConfig,\n GeoLintConfig,\n GeoConfig,\n ContentPathConfig,\n ThresholdConfig,\n TechnicalConfig,\n I18nConfig,\n} from './config/types.js';\nexport type {\n LintResult,\n Rule,\n GlobalRule,\n ContentItem,\n RuleContext,\n ContentType,\n Severity,\n Heading,\n ExtractedLink,\n ExtractedImage,\n} from './types.js';\nexport type { ContentAdapter } from './adapters/types.js';\nexport { createAdapter } from './adapters/types.js';\nexport { loadContentItems } from './adapters/mdx.js';\n","/**\n * @ijonis/geo-lint Configuration Loader\n */\n\nimport { existsSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { GeoLintUserConfig, GeoLintConfig } from './types.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\n\nconst CONFIG_FILENAMES = [\n 'geo-lint.config.ts',\n 'geo-lint.config.mts',\n 'geo-lint.config.mjs',\n 'geo-lint.config.js',\n];\n\n/**\n * Helper for TypeScript-aware config files. Provides autocomplete in user configs.\n */\nexport function defineConfig(config: GeoLintUserConfig): GeoLintUserConfig {\n return config;\n}\n\n/**\n * Try to load a config file from the project root using jiti for TS support\n */\nasync function tryLoadConfigFile(projectRoot: string): Promise<GeoLintUserConfig | null> {\n for (const filename of CONFIG_FILENAMES) {\n const configPath = join(projectRoot, filename);\n if (!existsSync(configPath)) continue;\n\n try {\n // Use jiti for TypeScript config loading (works without tsx/ts-node)\n const { createJiti } = await import('jiti');\n const jiti = createJiti(import.meta.url);\n const mod = await jiti.import(configPath) as Record<string, unknown>;\n const config = (mod.default ?? mod) as GeoLintUserConfig;\n\n if (config && typeof config === 'object' && 'siteUrl' in config) {\n return config;\n }\n } catch {\n // Try next file\n }\n }\n return null;\n}\n\n/**\n * Try to load config from package.json geoLint key\n */\nfunction tryLoadPackageJsonConfig(projectRoot: string): GeoLintUserConfig | null {\n try {\n const pkgPath = join(projectRoot, 'package.json');\n if (!existsSync(pkgPath)) return null;\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const config = pkg.geoLint;\n if (config && typeof config === 'object' && 'siteUrl' in config) {\n return config as GeoLintUserConfig;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Merge user config with defaults\n */\nexport function mergeWithDefaults(user: GeoLintUserConfig): GeoLintConfig {\n return {\n siteUrl: user.siteUrl,\n contentPaths: user.contentPaths ?? DEFAULT_CONFIG.contentPaths,\n staticRoutes: user.staticRoutes ?? DEFAULT_CONFIG.staticRoutes,\n imageDirectories: user.imageDirectories ?? DEFAULT_CONFIG.imageDirectories,\n categories: user.categories ?? DEFAULT_CONFIG.categories,\n excludeSlugs: user.excludeSlugs ?? DEFAULT_CONFIG.excludeSlugs,\n excludeCategories: user.excludeCategories ?? DEFAULT_CONFIG.excludeCategories,\n geo: {\n brandName: user.geo?.brandName ?? DEFAULT_CONFIG.geo.brandName,\n brandCity: user.geo?.brandCity ?? DEFAULT_CONFIG.geo.brandCity,\n keywordsPath: user.geo?.keywordsPath ?? DEFAULT_CONFIG.geo.keywordsPath,\n enabledContentTypes: user.geo?.enabledContentTypes ?? DEFAULT_CONFIG.geo.enabledContentTypes,\n fillerPhrases: user.geo?.fillerPhrases ?? DEFAULT_CONFIG.geo.fillerPhrases,\n extractionTriggers: user.geo?.extractionTriggers ?? DEFAULT_CONFIG.geo.extractionTriggers,\n acronymAllowlist: user.geo?.acronymAllowlist ?? DEFAULT_CONFIG.geo.acronymAllowlist,\n vagueHeadings: user.geo?.vagueHeadings ?? DEFAULT_CONFIG.geo.vagueHeadings,\n genericAuthorNames: user.geo?.genericAuthorNames ?? DEFAULT_CONFIG.geo.genericAuthorNames,\n allowedHtmlTags: user.geo?.allowedHtmlTags ?? DEFAULT_CONFIG.geo.allowedHtmlTags,\n organizationSameAs: user.geo?.organizationSameAs ?? DEFAULT_CONFIG.geo.organizationSameAs,\n servicePagePatterns: user.geo?.servicePagePatterns ?? DEFAULT_CONFIG.geo.servicePagePatterns,\n },\n i18n: {\n locales: user.i18n?.locales ?? DEFAULT_CONFIG.i18n.locales,\n defaultLocale: user.i18n?.defaultLocale ?? DEFAULT_CONFIG.i18n.defaultLocale,\n },\n technical: {\n feedUrls: user.technical?.feedUrls ?? DEFAULT_CONFIG.technical.feedUrls,\n llmsTxtUrl: user.technical?.llmsTxtUrl ?? DEFAULT_CONFIG.technical.llmsTxtUrl,\n },\n rules: { ...DEFAULT_CONFIG.rules, ...(user.rules ?? {}) },\n thresholds: {\n title: { ...DEFAULT_CONFIG.thresholds.title, ...(user.thresholds?.title ?? {}) },\n description: { ...DEFAULT_CONFIG.thresholds.description, ...(user.thresholds?.description ?? {}) },\n slug: { ...DEFAULT_CONFIG.thresholds.slug, ...(user.thresholds?.slug ?? {}) },\n content: { ...DEFAULT_CONFIG.thresholds.content, ...(user.thresholds?.content ?? {}) },\n byContentType: user.thresholds?.byContentType,\n },\n };\n}\n\n/**\n * Load configuration from the project root.\n * Searches for geo-lint.config.{ts,mjs,js} or package.json#geoLint\n */\nexport async function loadConfig(projectRoot?: string): Promise<GeoLintConfig> {\n const root = resolve(projectRoot ?? process.cwd());\n\n const userConfig = await tryLoadConfigFile(root) ?? tryLoadPackageJsonConfig(root);\n\n if (!userConfig) {\n throw new Error(\n 'geo-lint: No configuration found.\\n' +\n 'Create a geo-lint.config.ts in your project root with at least:\\n\\n' +\n ' import { defineConfig } from \"@ijonis/geo-lint\";\\n' +\n ' export default defineConfig({ siteUrl: \"https://example.com\" });\\n\\n' +\n 'See https://github.com/ijonis/geo-lint#configuration'\n );\n }\n\n return mergeWithDefaults(userConfig);\n}\n","/**\n * @ijonis/geo-lint Default Configuration\n */\n\nimport type { GeoLintConfig } from './types.js';\n\n/** Default configuration values (no project-specific data) */\nexport const DEFAULT_CONFIG: Omit<GeoLintConfig, 'siteUrl'> = {\n contentPaths: [\n { dir: 'content/blog', type: 'blog', urlPrefix: '/blog/' },\n { dir: 'content/pages', type: 'page', urlPrefix: '/' },\n { dir: 'content/projects', type: 'project', urlPrefix: '/projects/' },\n ],\n staticRoutes: [],\n imageDirectories: ['public/images'],\n categories: [],\n excludeSlugs: [],\n excludeCategories: ['legal'],\n geo: {\n brandName: '',\n brandCity: '',\n keywordsPath: '',\n fillerPhrases: [\n 'in this article', 'in this post', 'in this guide',\n 'in diesem artikel', 'in diesem beitrag',\n 'welcome to', 'willkommen zu',\n 'today we will', 'heute werden wir',\n \"let me tell you\", 'lass mich dir erzählen',\n \"in today's world\", 'in der heutigen welt',\n \"it's no secret\", 'es ist kein geheimnis',\n 'in the ever-changing', 'in der sich ständig verändernden',\n ],\n extractionTriggers: [\n 'key takeaway', 'in summary', 'the bottom line',\n 'tl;dr', 'to summarize', 'in short', 'put simply',\n 'the short answer', \"here's what you need to know\",\n 'zusammenfassend', 'fazit', 'das wichtigste',\n 'kurz gesagt', 'anders gesagt',\n ],\n acronymAllowlist: [\n 'HTML', 'CSS', 'API', 'URL', 'SDK', 'CLI', 'UI', 'UX',\n 'JSON', 'XML', 'HTTP', 'HTTPS', 'SQL', 'SEO', 'GEO', 'AEO',\n 'AI', 'ML', 'LLM', 'FAQ', 'CMS', 'CRM', 'SaaS', 'B2B', 'B2C',\n 'ROI', 'KPI', 'PDF', 'CEO', 'CTO', 'VP', 'HR', 'PR', 'IT',\n 'US', 'EU', 'UK', 'DE', 'MDX', 'JSX', 'TSX', 'RSS', 'DNS',\n ],\n vagueHeadings: [\n 'introduction', 'overview', 'background', 'details',\n 'summary', 'conclusion', 'more', 'other', 'misc',\n 'einleitung', 'überblick', 'hintergrund', 'details',\n 'zusammenfassung', 'fazit', 'weiteres', 'sonstiges',\n ],\n genericAuthorNames: [\n 'admin', 'administrator', 'team', 'editor', 'author',\n 'webmaster', 'staff', 'contributor',\n 'redaktion', 'redakteur', 'herausgeber',\n ],\n allowedHtmlTags: [\n 'Callout', 'CalloutBox', 'Note', 'Warning', 'Tip',\n 'CodeBlock', 'Image', 'Video', 'Embed', 'Tabs', 'Tab',\n ],\n enabledContentTypes: ['blog'],\n organizationSameAs: [],\n servicePagePatterns: [],\n },\n technical: {\n feedUrls: [],\n llmsTxtUrl: '',\n },\n i18n: {\n locales: ['de', 'en'],\n defaultLocale: 'de',\n },\n rules: {},\n thresholds: {\n title: { minLength: 30, maxLength: 60, warnLength: 55 },\n description: { minLength: 70, maxLength: 160, warnLength: 150 },\n slug: { maxLength: 75 },\n content: { minWordCount: 300, minReadabilityScore: 30 },\n },\n};\n","/**\n * @ijonis/geo-lint MDX Content Adapter\n * Scans directories for MDX/Markdown files and parses them with gray-matter\n */\n\nimport { readdirSync, statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport matter from 'gray-matter';\nimport type { ContentItem, ContentType } from '../types.js';\nimport type { ContentPathConfig } from '../config/types.js';\n\n/**\n * Derive permalink from slug, locale, and URL prefix config\n */\nfunction derivePermalink(\n slug: string,\n locale: string | undefined,\n pathConfig: ContentPathConfig,\n): string {\n const prefix = pathConfig.urlPrefix ?? '/';\n\n // Pages use root-level URLs\n if (pathConfig.type === 'page') {\n return `/${slug}`.replace(/\\/\\/+/g, '/');\n }\n\n // Non-default locale gets locale prefix\n const defaultLocale = pathConfig.defaultLocale ?? 'de';\n if (locale && locale !== defaultLocale) {\n return `/${locale}${prefix}${slug}`.replace(/\\/\\/+/g, '/');\n }\n\n return `${prefix}${slug}`.replace(/\\/\\/+/g, '/');\n}\n\n/**\n * Recursively find all MDX/Markdown files in a directory\n */\nfunction findContentFiles(dir: string): string[] {\n const files: string[] = [];\n if (!existsSync(dir)) return files;\n\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n try {\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n files.push(...findContentFiles(fullPath));\n } else if (entry.endsWith('.mdx') || entry.endsWith('.md')) {\n files.push(fullPath);\n }\n } catch {\n // Skip files that can't be read\n }\n }\n return files;\n}\n\n/**\n * Parse a single content file into a ContentItem\n */\nfunction parseContentFile(\n filePath: string,\n pathConfig: ContentPathConfig,\n): ContentItem | null {\n try {\n const { data: fm, content: body, orig } = matter.read(filePath);\n\n const slug = fm.slug as string | undefined;\n if (!slug) return null;\n\n // Skip drafts\n if (fm.draft === true) return null;\n\n const locale = fm.locale as string | undefined;\n const permalink =\n (fm.permalink as string | undefined) ??\n derivePermalink(slug, locale, pathConfig);\n\n return {\n title: (fm.title as string) ?? '',\n slug,\n description: (fm.description as string) ?? '',\n permalink,\n image: (fm.image as string | undefined) ?? (fm.thumbnail as string | undefined),\n imageAlt: fm.imageAlt as string | undefined,\n categories: fm.categories as string[] | undefined,\n date: fm.date ? String(fm.date) : undefined,\n category: fm.category as string | undefined,\n locale,\n translationKey: fm.translationKey as string | undefined,\n updatedAt: fm.updatedAt ? String(fm.updatedAt) : undefined,\n noindex: fm.noindex as boolean | undefined,\n draft: fm.draft as boolean | undefined,\n author: fm.author as string | undefined,\n contentType: pathConfig.type as ContentType,\n filePath,\n rawContent: orig?.toString() ?? '',\n body,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Load all content items from configured content paths.\n * Uses gray-matter for robust YAML frontmatter parsing.\n */\nexport function loadContentItems(\n contentPaths: ContentPathConfig[],\n projectRoot: string,\n): ContentItem[] {\n const items: ContentItem[] = [];\n\n for (const pathConfig of contentPaths) {\n const fullDir = join(projectRoot, pathConfig.dir);\n const files = findContentFiles(fullDir);\n\n for (const filePath of files) {\n const item = parseContentFile(filePath, pathConfig);\n if (item) items.push(item);\n }\n }\n\n return items;\n}\n","/**\n * Link Extractor Utility\n * Extracts and classifies links from MDX content\n */\n\nimport type { ExtractedLink } from '../types.js';\n\n/** Link extraction utilities bound to a specific site URL */\nexport interface LinkExtractor {\n isInternalUrl: (url: string) => boolean;\n normalizeInternalUrl: (url: string) => string;\n isAbsoluteInternalLink: (url: string) => boolean;\n extractLinks: (mdxBody: string) => ExtractedLink[];\n getInternalLinks: (links: ExtractedLink[]) => ExtractedLink[];\n}\n\n/**\n * Create a link extractor bound to a specific site URL.\n * All internal URL detection derives from the provided siteUrl.\n */\nexport function createLinkExtractor(siteUrl: string): LinkExtractor {\n const { hostname } = new URL(siteUrl);\n const escapedDomain = hostname.replace(/\\./g, '\\\\.');\n\n const internalPatterns = [\n new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}(\\\\/|$)`, 'i'),\n new RegExp(`^\\\\/\\\\/${escapedDomain}(\\\\/|$)`, 'i'),\n /^\\/(?!\\/)/, // Relative paths starting with single /\n ];\n\n function isInternalUrl(url: string): boolean {\n return internalPatterns.some(pattern => pattern.test(url));\n }\n\n function normalizeInternalUrl(url: string): string {\n let normalized = url;\n normalized = normalized.replace(new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}`, 'i'), '');\n normalized = normalized.replace(new RegExp(`^\\\\/\\\\/${escapedDomain}`, 'i'), '');\n if (!normalized.startsWith('/')) {\n normalized = '/' + normalized;\n }\n normalized = normalized.split('?')[0].split('#')[0];\n if (normalized.length > 1 && normalized.endsWith('/')) {\n normalized = normalized.slice(0, -1);\n }\n return normalized;\n }\n\n function isAbsoluteInternalLink(url: string): boolean {\n return new RegExp(`^https?:\\\\/\\\\/(www\\\\.)?${escapedDomain}`, 'i').test(url);\n }\n\n function isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n return inCodeBlock;\n }\n\n function extractLinks(mdxBody: string): ExtractedLink[] {\n const links: ExtractedLink[] = [];\n const lines = mdxBody.split('\\n');\n const markdownLinkRegex = /(?<!!)\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n const hrefRegex = /href=[\"']([^\"']+)[\"']/g;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (isInCodeBlock(lines, i)) continue;\n\n let match;\n while ((match = markdownLinkRegex.exec(line)) !== null) {\n const [, text, url] = match;\n if (url.startsWith('mailto:') || url.startsWith('tel:') || url === '#') continue;\n const internal = isInternalUrl(url);\n links.push({\n text: text.trim(),\n url: internal ? normalizeInternalUrl(url) : url,\n originalUrl: url,\n line: i + 1,\n isInternal: internal,\n });\n }\n markdownLinkRegex.lastIndex = 0;\n\n while ((match = hrefRegex.exec(line)) !== null) {\n const [, url] = match;\n if (url.startsWith('mailto:') || url.startsWith('tel:') || url === '#') continue;\n const normalized = isInternalUrl(url) ? normalizeInternalUrl(url) : url;\n const alreadyCaptured = links.some(\n l => l.line === i + 1 && (l.url === normalized || l.originalUrl === url)\n );\n if (!alreadyCaptured) {\n const internal = isInternalUrl(url);\n links.push({\n text: '',\n url: internal ? normalizeInternalUrl(url) : url,\n originalUrl: url,\n line: i + 1,\n isInternal: internal,\n });\n }\n }\n hrefRegex.lastIndex = 0;\n }\n return links;\n }\n\n function getInternalLinks(links: ExtractedLink[]): ExtractedLink[] {\n return links.filter(l => l.isInternal);\n }\n\n return { isInternalUrl, normalizeInternalUrl, isAbsoluteInternalLink, extractLinks, getInternalLinks };\n}\n","/**\n * Slug Resolver Utility\n * Builds a registry of valid internal URLs for link validation\n */\n\nimport { readdirSync, readFileSync, statSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { ContentItem } from '../types.js';\nimport type { ContentPathConfig } from '../config/types.js';\n\n/**\n * Extract frontmatter slug and locale from a raw MDX file\n * Returns null if the file has no valid frontmatter\n */\nfunction extractSlugFromFile(\n filePath: string,\n defaultLocale: string = 'de',\n): { slug: string; locale: string } | null {\n try {\n const content = readFileSync(filePath, 'utf-8');\n if (!content.startsWith('---')) return null;\n\n const endIndex = content.indexOf('---', 3);\n if (endIndex === -1) return null;\n\n const frontmatter = content.slice(3, endIndex);\n\n const slugMatch = frontmatter.match(/^slug:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n if (!slugMatch) return null;\n\n const localeMatch = frontmatter.match(/^locale:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m);\n const draftMatch = frontmatter.match(/^draft:\\s*true\\s*$/m);\n\n if (draftMatch) return null;\n\n return {\n slug: slugMatch[1].trim(),\n locale: localeMatch ? localeMatch[1].trim() : defaultLocale,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Find all files with a given extension in a directory (recursive)\n */\nfunction findFilesInDir(dir: string, ext: string): string[] {\n const results: string[] = [];\n try {\n for (const entry of readdirSync(dir)) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n if (stat.isDirectory()) {\n results.push(...findFilesInDir(fullPath, ext));\n } else if (entry.endsWith(ext)) {\n results.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n return results;\n}\n\n/**\n * Scan raw MDX files to find permalinks not covered by content adapter output.\n * Handles cases where the content adapter fails to process certain files.\n *\n * @param knownSlugs - Set of already-known permalink slugs\n * @param contentPaths - Content directory configurations to scan\n */\nexport function scanRawContentPermalinks(\n knownSlugs: Set<string>,\n contentPaths: ContentPathConfig[],\n): string[] {\n const projectRoot = process.cwd();\n const additionalPermalinks: string[] = [];\n\n for (const pathConfig of contentPaths) {\n const contentDir = join(projectRoot, pathConfig.dir);\n if (!existsSync(contentDir)) continue;\n\n const urlPrefix = pathConfig.urlPrefix ?? '/';\n\n const defaultLocale = pathConfig.defaultLocale ?? 'de';\n\n for (const file of findFilesInDir(contentDir, '.mdx')) {\n const meta = extractSlugFromFile(file, defaultLocale);\n if (!meta) continue;\n\n // Build permalink based on locale and URL prefix\n let permalink: string;\n\n if (meta.locale !== defaultLocale) {\n // Non-default locale: prefix with locale\n permalink = `/${meta.locale}${urlPrefix}${meta.slug}`.replace(/\\/+/g, '/');\n } else {\n permalink = `${urlPrefix}${meta.slug}`.replace(/\\/+/g, '/');\n }\n\n // Ensure leading slash\n if (!permalink.startsWith('/')) {\n permalink = '/' + permalink;\n }\n\n // Remove trailing slash (except root)\n if (permalink.length > 1 && permalink.endsWith('/')) {\n permalink = permalink.slice(0, -1);\n }\n\n if (!knownSlugs.has(permalink)) {\n additionalPermalinks.push(permalink);\n }\n }\n }\n\n return additionalPermalinks;\n}\n\n/**\n * Build a set of all valid internal URL paths.\n * Combines content permalinks, static routes, and raw MDX file scan.\n *\n * @param allContent - Content items from the content adapter\n * @param staticRoutes - Array of static route paths (e.g. ['/about', '/contact'])\n * @param contentPaths - Content directory configurations for raw MDX fallback scan\n */\nexport function buildSlugRegistry(\n allContent: ContentItem[],\n staticRoutes: string[],\n contentPaths: ContentPathConfig[],\n): Set<string> {\n const slugs = new Set<string>();\n\n // Add static routes\n for (const route of staticRoutes) {\n slugs.add(route);\n }\n\n // Add content permalinks from adapter output\n for (const item of allContent) {\n slugs.add(item.permalink);\n\n // Also add without trailing slash if present\n if (item.permalink.endsWith('/') && item.permalink.length > 1) {\n slugs.add(item.permalink.slice(0, -1));\n }\n }\n\n // Scan raw MDX files for any permalinks the adapter missed\n const additional = scanRawContentPermalinks(slugs, contentPaths);\n for (const permalink of additional) {\n slugs.add(permalink);\n }\n\n return slugs;\n}\n\n/**\n * Check if a normalized internal URL is valid\n */\nexport function isValidInternalLink(url: string, validSlugs: Set<string>): boolean {\n // Direct match\n if (validSlugs.has(url)) {\n return true;\n }\n\n // Try with trailing slash\n if (validSlugs.has(url + '/')) {\n return true;\n }\n\n // Try without trailing slash\n if (url.endsWith('/') && validSlugs.has(url.slice(0, -1))) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Recursively scan directory for files\n */\nfunction scanDirectory(dir: string): string[] {\n const files: string[] = [];\n\n try {\n const entries = readdirSync(dir);\n\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n\n if (stat.isDirectory()) {\n files.push(...scanDirectory(fullPath));\n } else {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or can't be read\n }\n\n return files;\n}\n\n/**\n * Build a set of all valid image paths.\n * Scans the provided image directories.\n *\n * @param imageDirectories - Array of image directory paths relative to project root\n * (e.g. ['public/images'])\n */\nexport function buildImageRegistry(imageDirectories: string[]): Set<string> {\n const images = new Set<string>();\n const projectRoot = process.cwd();\n\n for (const imageDir of imageDirectories) {\n const fullDir = join(projectRoot, imageDir);\n\n if (!existsSync(fullDir)) {\n continue;\n }\n\n const files = scanDirectory(fullDir);\n\n for (const file of files) {\n // Get path relative to public directory\n const relativePath = file.replace(join(projectRoot, 'public'), '');\n // Normalize to forward slashes and ensure leading slash\n const normalizedPath = relativePath.replace(/\\\\/g, '/');\n images.add(normalizedPath.startsWith('/') ? normalizedPath : '/' + normalizedPath);\n }\n }\n\n return images;\n}\n\n/**\n * Check if an image path exists\n */\nexport function isValidImagePath(imagePath: string, validImages: Set<string>): boolean {\n // Normalize the path\n let normalized = imagePath;\n\n // Handle paths without leading slash\n if (!normalized.startsWith('/')) {\n normalized = '/' + normalized;\n }\n\n // Direct match\n if (validImages.has(normalized)) {\n return true;\n }\n\n // Try URL-decoded version\n try {\n const decoded = decodeURIComponent(normalized);\n if (validImages.has(decoded)) {\n return true;\n }\n } catch {\n // Invalid URL encoding, ignore\n }\n\n return false;\n}\n","import type { ContentItem } from '../types.js';\n\n/** Get the relative file path for display in lint results */\nexport function getDisplayPath(item: ContentItem): string {\n return `${item.contentType}/${item.slug}`;\n}\n","/**\n * Per-content-type threshold resolution\n * Merges base thresholds with optional per-type overrides\n */\n\nimport type { ThresholdConfig } from '../config/types.js';\nimport type { ContentType } from '../types.js';\n\n/** Resolved thresholds for a specific content type (no byContentType nesting) */\nexport interface ResolvedThresholds {\n title: { minLength: number; maxLength: number; warnLength: number };\n description: { minLength: number; maxLength: number; warnLength: number };\n slug: { maxLength: number };\n content: { minWordCount: number; minReadabilityScore: number };\n}\n\n/**\n * Resolve thresholds for a specific content type.\n * Merges per-type overrides on top of base values.\n *\n * @example\n * resolveThresholds(config.thresholds, 'page')\n * // Returns base thresholds with any page-specific overrides applied\n */\nexport function resolveThresholds(\n thresholds: ThresholdConfig,\n contentType: ContentType,\n): ResolvedThresholds {\n const override = thresholds.byContentType?.[contentType];\n if (!override) {\n return {\n title: thresholds.title,\n description: thresholds.description,\n slug: thresholds.slug,\n content: thresholds.content,\n };\n }\n\n return {\n title: { ...thresholds.title, ...override.title },\n description: { ...thresholds.description, ...override.description },\n slug: { ...thresholds.slug, ...override.slug },\n content: { ...thresholds.content, ...override.content },\n };\n}\n","/**\n * Title Validation Rules\n * Validates title presence and length\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default title length thresholds (used when context has no thresholds) */\nconst TITLE_DEFAULTS = { minLength: 30, maxLength: 60, warnLength: 55 };\n\n/**\n * Rule: Title must be present\n */\nexport const titleMissing: Rule = {\n name: 'title-missing',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add a title field to the frontmatter',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || item.title.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-missing',\n severity: 'error',\n message: 'Missing title',\n suggestion: 'Add a title field to the frontmatter',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title should not be too short\n */\nexport const titleTooShort: Rule = {\n name: 'title-too-short',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Expand the title to meet minimum length',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > 0 && length < t.minLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-too-short',\n severity: 'warning',\n message: `Title is too short (${length}/${t.minLength} chars minimum)`,\n suggestion: `Expand the title to at least ${t.minLength} characters for better SEO`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title must not exceed maximum length\n */\nexport const titleTooLong: Rule = {\n name: 'title-too-long',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Shorten the title to avoid truncation in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > t.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-too-long',\n severity: 'error',\n message: `Title is too long (${length}/${t.maxLength} chars)`,\n suggestion: `Shorten the title to ${t.maxLength} characters or less to avoid truncation in search results`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Warn when title is approaching maximum length\n */\nexport const titleApproachingLimit: Rule = {\n name: 'title-approaching-limit',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Consider shortening to leave room for site name suffix',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.title) return [];\n\n const t = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).title\n : TITLE_DEFAULTS;\n const length = item.title.length;\n if (length > t.warnLength && length <= t.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'title-approaching-limit',\n severity: 'warning',\n message: `Title is approaching maximum length (${length}/${t.maxLength} chars)`,\n suggestion: 'Consider shortening to leave room for site name suffix in search results',\n }];\n }\n return [];\n },\n};\n\n/**\n * All title rules\n */\nexport const titleRules: Rule[] = [\n titleMissing,\n titleTooShort,\n titleTooLong,\n titleApproachingLimit,\n];\n","/**\n * Description Validation Rules\n * Validates meta description presence and length\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default description length thresholds (used when context has no thresholds) */\nconst DESC_DEFAULTS = { minLength: 70, maxLength: 160, warnLength: 150 };\n\n/**\n * Rule: Description must be present\n */\nexport const descriptionMissing: Rule = {\n name: 'description-missing',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add a description field to the frontmatter (max 160 chars)',\n run: (item: ContentItem): LintResult[] => {\n if (!item.description || item.description.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-missing',\n severity: 'error',\n message: 'Missing description',\n suggestion: 'Add a description field to the frontmatter (max 160 chars)',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Description must not exceed maximum length\n */\nexport const descriptionTooLong: Rule = {\n name: 'description-too-long',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Shorten the description to avoid truncation in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length > d.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-too-long',\n severity: 'error',\n message: `Description is too long (${length}/${d.maxLength} chars)`,\n suggestion: `Shorten to ${d.maxLength} characters to avoid truncation in search results`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Warn when description is approaching maximum length\n */\nexport const descriptionApproachingLimit: Rule = {\n name: 'description-approaching-limit',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Consider shortening to ensure full display in search results',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length > d.warnLength && length <= d.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-approaching-limit',\n severity: 'warning',\n message: `Description is approaching maximum length (${length}/${d.maxLength} chars)`,\n suggestion: 'Consider shortening to ensure full display in search results',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Description should meet minimum length for effective SEO\n */\nexport const descriptionTooShort: Rule = {\n name: 'description-too-short',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Expand the description for better search result snippets',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.description || item.description.trim().length === 0) return [];\n\n const d = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).description\n : DESC_DEFAULTS;\n const length = item.description.length;\n if (length < d.minLength) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'description-too-short',\n severity: 'warning',\n message: `Description is too short (${length}/${d.minLength} chars minimum)`,\n suggestion: `Expand the description to at least ${d.minLength} characters for better search result snippets`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All description rules\n */\nexport const descriptionRules: Rule[] = [\n descriptionMissing,\n descriptionTooLong,\n descriptionApproachingLimit,\n descriptionTooShort,\n];\n","/**\n * Duplicate Detection Rules\n * Validates that titles and descriptions are unique across all content\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Build a map of value -> list of files using that value\n */\nfunction buildDuplicateMap(\n items: ContentItem[],\n getValue: (item: ContentItem) => string | undefined\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n\n for (const item of items) {\n const value = getValue(item);\n if (!value || value.trim().length === 0) continue;\n\n // Normalize for comparison (lowercase, trim)\n const normalized = value.toLowerCase().trim();\n const files = map.get(normalized) || [];\n files.push(getDisplayPath(item));\n map.set(normalized, files);\n }\n\n return map;\n}\n\n/**\n * Rule: Titles must be unique across all content\n */\nexport const duplicateTitle: Rule = {\n name: 'duplicate-title',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Use a unique title that differentiates this content from others',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const titleMap = buildDuplicateMap(context.allContent, c => c.title);\n const normalizedTitle = item.title?.toLowerCase().trim();\n\n if (!normalizedTitle) return [];\n\n const filesWithSameTitle = titleMap.get(normalizedTitle);\n if (!filesWithSameTitle || filesWithSameTitle.length <= 1) return [];\n\n // Filter out the current file\n const otherFiles = filesWithSameTitle.filter(f => f !== getDisplayPath(item));\n if (otherFiles.length === 0) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'title',\n rule: 'duplicate-title',\n severity: 'error',\n message: `Duplicate title found`,\n suggestion: `Also used by: ${otherFiles.join(', ')}`,\n }];\n },\n};\n\n/**\n * Rule: Descriptions must be unique across all content\n */\nexport const duplicateDescription: Rule = {\n name: 'duplicate-description',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Write a unique description that differentiates this content',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const descMap = buildDuplicateMap(context.allContent, c => c.description);\n const normalizedDesc = item.description?.toLowerCase().trim();\n\n if (!normalizedDesc) return [];\n\n const filesWithSameDesc = descMap.get(normalizedDesc);\n if (!filesWithSameDesc || filesWithSameDesc.length <= 1) return [];\n\n // Filter out the current file\n const otherFiles = filesWithSameDesc.filter(f => f !== getDisplayPath(item));\n if (otherFiles.length === 0) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'duplicate-description',\n severity: 'error',\n message: `Duplicate description found`,\n suggestion: `Also used by: ${otherFiles.join(', ')}`,\n }];\n },\n};\n\n/**\n * All duplicate rules\n */\nexport const duplicateRules: Rule[] = [\n duplicateTitle,\n duplicateDescription,\n];\n","/**\n * Plain-Text Structure Detection\n * Heuristic detection of headings, tables, lists, and FAQ sections\n * in content extracted from URLs (no markdown formatting).\n */\n\nimport type { Heading } from '../types.js';\n\n/** Max line length for a heading candidate */\nconst MAX_HEADING_LENGTH = 80;\n\n/** Min consecutive structured rows to detect a table */\nconst MIN_TABLE_ROWS = 2;\n\n/**\n * Detect headings in plain text using heuristics:\n * - Short line (<80 chars) followed by blank line\n * - Not ending with sentence punctuation (. , ;) unless it's ?\n * - Title Case, ALL CAPS, or starts with question word\n *\n * @example\n * ```ts\n * const headings = detectPlaintextHeadings('Introduction\\n\\nSome text.');\n * // [{ level: 2, text: 'Introduction', line: 1 }]\n * ```\n */\nexport function detectPlaintextHeadings(text: string): Heading[] {\n const lines = text.split('\\n');\n const headings: Heading[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line || line.length > MAX_HEADING_LENGTH) continue;\n\n // Must be followed by blank line or be at end of text\n const nextLine = lines[i + 1]?.trim() ?? '';\n const isFollowedByBlank = i + 1 >= lines.length || nextLine === '';\n if (!isFollowedByBlank) continue;\n\n // Reject lines ending with sentence-ending punctuation (except ?)\n if (/[.,;:]$/.test(line)) continue;\n\n // Must look like a heading: Title Case, ALL CAPS, or question\n const isTitleCase =\n /^[A-ZÄÖÜ]/.test(line) && line.split(/\\s+/).length <= 12;\n const isAllCaps =\n line === line.toUpperCase() &&\n /[A-ZÄÖÜ]/.test(line) &&\n line.length > 2;\n const isQuestion = line.endsWith('?');\n\n if (isTitleCase || isAllCaps || isQuestion) {\n // Estimate heading level: ALL CAPS or very short = level 2, others = level 3\n const level =\n isAllCaps || line.split(/\\s+/).length <= 4 ? 2 : 3;\n headings.push({ level, text: line, line: i + 1 });\n }\n }\n\n return headings;\n}\n\n/**\n * Detect tabular data in plain text:\n * - Tab-separated rows with consistent column count\n * - Space-aligned columns (3+ spaces between values)\n *\n * @example\n * ```ts\n * detectPlaintextTable('Name\\tPrice\\nA\\t$10'); // true\n * ```\n */\nexport function detectPlaintextTable(text: string): boolean {\n const lines = text.split('\\n').filter((l) => l.trim().length > 0);\n\n // Check for tab-separated data\n const tabLines = lines.filter((l) => l.includes('\\t'));\n if (tabLines.length >= MIN_TABLE_ROWS) {\n const colCounts = tabLines.map((l) => l.split('\\t').length);\n const consistent = colCounts.every(\n (c) => c === colCounts[0] && c >= 2,\n );\n if (consistent) return true;\n }\n\n // Check for space-aligned columns (3+ spaces between values)\n const spaceSeparated = lines.filter((l) => /\\S {3,}\\S/.test(l));\n if (spaceSeparated.length >= MIN_TABLE_ROWS + 1) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Detect list items in plain text:\n * - Unicode bullets: bullet, middle dot, en-dash, em-dash\n * - Parenthetical numbers: 1), 2), a), b)\n *\n * @example\n * ```ts\n * detectPlaintextList('• First\\n• Second'); // true\n * ```\n */\nexport function detectPlaintextList(text: string): boolean {\n const listPattern =\n /^[\\s]*[•·–—]\\s+|^[\\s]*\\w\\)\\s+|^[\\s]*\\d+\\)\\s+/m;\n const lines = text.split('\\n').filter((l) => listPattern.test(l));\n return lines.length >= 2;\n}\n\n/**\n * Detect FAQ-like question-answer patterns:\n * - Lines ending with ? followed by paragraph text\n * - At least 2 Q&A pairs to qualify\n *\n * @example\n * ```ts\n * detectPlaintextFaq('What is X?\\nX is...\\n\\nWhy Y?\\nBecause...');\n * // { hasFaq: true, questionCount: 2 }\n * ```\n */\nexport function detectPlaintextFaq(text: string): {\n hasFaq: boolean;\n questionCount: number;\n} {\n const lines = text.split('\\n');\n let questionCount = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line.endsWith('?')) continue;\n if (line.length > MAX_HEADING_LENGTH) continue;\n\n // Next non-empty line should be an answer (longer text)\n const nextContent = lines\n .slice(i + 1)\n .find((l) => l.trim().length > 0);\n if (nextContent && nextContent.trim().length > line.length) {\n questionCount++;\n }\n }\n\n return {\n hasFaq: questionCount >= 2,\n questionCount,\n };\n}\n","/**\n * Heading Extractor Utility\n * Extracts and analyzes heading structure from MDX content\n */\n\nimport type { Heading } from '../types.js';\nimport { detectPlaintextHeadings } from './plaintext-structure.js';\n\n/**\n * Check if a line is inside a code block\n * Tracks ``` and ~~~ fenced code blocks\n */\nfunction isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n\n return inCodeBlock;\n}\n\n/**\n * Extract all headings from MDX body content\n * Handles markdown-style headings (# H1, ## H2, etc.)\n */\nexport function extractHeadings(mdxBody: string, contentSource?: 'file' | 'url'): Heading[] {\n const headings: Heading[] = [];\n const lines = mdxBody.split('\\n');\n\n // Regex for markdown headings: # to ######\n const headingRegex = /^(#{1,6})\\s+(.+)$/;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(headingRegex);\n\n if (match && !isInCodeBlock(lines, i)) {\n const [, hashes, text] = match;\n headings.push({\n level: hashes.length,\n text: text.trim(),\n line: i + 1, // 1-indexed for display\n });\n }\n }\n\n // If no markdown headings found and content is from URL, try plain-text detection\n if (headings.length === 0 && contentSource === 'url') {\n return detectPlaintextHeadings(mdxBody);\n }\n\n return headings;\n}\n\n/**\n * Count H1 headings in the content\n */\nexport function countH1s(headings: Heading[]): number {\n return headings.filter(h => h.level === 1).length;\n}\n\n/**\n * Find H1 headings (for error reporting)\n */\nexport function findH1s(headings: Heading[]): Heading[] {\n return headings.filter(h => h.level === 1);\n}\n\n/**\n * Check for heading hierarchy violations\n * A violation occurs when a heading level is skipped (e.g., H1 -> H3 without H2)\n */\nexport function findHierarchyViolations(headings: Heading[]): Array<{\n heading: Heading;\n previousLevel: number;\n expectedMaxLevel: number;\n}> {\n const violations: Array<{\n heading: Heading;\n previousLevel: number;\n expectedMaxLevel: number;\n }> = [];\n\n let previousLevel = 0;\n\n for (const heading of headings) {\n // A heading should be at most 1 level deeper than previous\n // e.g., H1 can be followed by H1 or H2, not H3+\n if (heading.level > previousLevel + 1 && previousLevel > 0) {\n violations.push({\n heading,\n previousLevel,\n expectedMaxLevel: previousLevel + 1,\n });\n }\n\n previousLevel = heading.level;\n }\n\n return violations;\n}\n\n/**\n * Get a summary of heading structure for debugging\n */\nexport function getHeadingSummary(headings: Heading[]): string {\n if (headings.length === 0) {\n return 'No headings found';\n }\n\n const counts: Record<number, number> = {};\n for (const h of headings) {\n counts[h.level] = (counts[h.level] || 0) + 1;\n }\n\n return Object.entries(counts)\n .sort(([a], [b]) => Number(a) - Number(b))\n .map(([level, count]) => `H${level}: ${count}`)\n .join(', ');\n}\n","/**\n * Heading Structure Rules\n * Validates H1 presence, count, and heading hierarchy\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport {\n extractHeadings,\n countH1s,\n findH1s,\n findHierarchyViolations,\n} from '../utils/heading-extractor.js';\n\n/**\n * Rule: Content must have exactly one H1 heading\n * Exceptions:\n * - Pages with category 'legal' or 'service' use ServicePageHeader (H1 via title prop)\n * - Blog posts use BlogHeader component which renders the H1 from frontmatter title\n */\nexport const missingH1: Rule = {\n name: 'missing-h1',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an H1 heading (# Heading) at the start of the content',\n run: (item: ContentItem): LintResult[] => {\n // Skip H1 check for URL-scanned content — Readability strips <h1>,\n // the title is in item.title metadata instead\n if (item.contentSource === 'url') {\n return [];\n }\n\n // Skip H1 check for blog posts — BlogHeader renders the H1 from frontmatter title\n if (item.contentType === 'blog') {\n return [];\n }\n\n // Skip H1 check for pages that use ServicePageHeader component\n // These pages get their H1 from the title prop in the header\n if (item.category === 'legal' || item.category === 'service') {\n return [];\n }\n\n const headings = extractHeadings(item.body);\n const h1Count = countH1s(headings);\n\n if (h1Count === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'missing-h1',\n severity: 'warning',\n message: 'No H1 heading found in content',\n suggestion: 'Add an H1 heading (# Heading) at the start of your content',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Content must not have multiple H1 headings\n * Blog posts are exempt — BlogHeader provides the page H1,\n * and MDX # headings are rendered as <h2> via mdx-components.tsx.\n */\nexport const multipleH1: Rule = {\n name: 'multiple-h1',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Convert extra H1s to H2s',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'blog') {\n return [];\n }\n\n const headings = extractHeadings(item.body);\n const h1s = findH1s(headings);\n\n if (h1s.length > 1) {\n const locations = h1s.map(h => `line ${h.line}`).join(', ');\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'multiple-h1',\n severity: 'error',\n message: `Found ${h1s.length} H1 headings (expected 1)`,\n suggestion: `H1 headings at: ${locations}. Convert extra H1s to H2s.`,\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Heading hierarchy should not skip levels\n * e.g., H1 -> H3 without H2 is a violation\n */\nexport const headingHierarchySkip: Rule = {\n name: 'heading-hierarchy-skip',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Adjust heading levels to avoid skipping (e.g., H2 before H3)',\n run: (item: ContentItem): LintResult[] => {\n const headings = extractHeadings(item.body);\n const violations = findHierarchyViolations(headings);\n\n return violations.map(v => ({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'heading-hierarchy-skip',\n severity: 'warning' as const,\n message: `Heading level skipped: H${v.previousLevel} → H${v.heading.level}`,\n suggestion: `At line ${v.heading.line}: \"${v.heading.text}\". Expected H${v.expectedMaxLevel} or lower.`,\n line: v.heading.line,\n }));\n },\n};\n\n/**\n * Rule: Heading text should not be duplicated within the same page\n * Duplicate headings confuse readers and dilute SEO signal\n */\nexport const duplicateHeadingText: Rule = {\n name: 'duplicate-heading-text',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Use unique heading text for each section',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const headings = extractHeadings(item.body);\n\n const seen = new Map<string, number>();\n\n for (const heading of headings) {\n const normalized = heading.text.toLowerCase();\n const previousLine = seen.get(normalized);\n\n if (previousLine !== undefined) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'duplicate-heading-text',\n severity: 'warning',\n message: `Duplicate heading text: \"${heading.text}\"`,\n suggestion: `Same heading appears at line ${previousLine} and line ${heading.line}. Use unique headings for better structure.`,\n line: heading.line,\n });\n } else {\n seen.set(normalized, heading.line);\n }\n }\n\n return results;\n },\n};\n\n/**\n * All heading rules\n */\nexport const headingRules: Rule[] = [\n missingH1,\n multipleH1,\n headingHierarchySkip,\n duplicateHeadingText,\n];\n","/**\n * Image Extractor Utility\n * Extracts images and their alt text from MDX content\n */\n\nimport type { ExtractedImage } from '../types.js';\n\n/**\n * Check if a line is inside a code block\n */\nfunction isInCodeBlock(lines: string[], lineIndex: number): boolean {\n let inCodeBlock = false;\n\n for (let i = 0; i < lineIndex; i++) {\n const line = lines[i].trim();\n if (line.startsWith('```') || line.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n }\n }\n\n return inCodeBlock;\n}\n\n/**\n * Extract all images from MDX body content\n * Handles markdown images  and JSX/HTML img tags\n */\nexport function extractImages(mdxBody: string): ExtractedImage[] {\n const images: ExtractedImage[] = [];\n const lines = mdxBody.split('\\n');\n\n // Regex patterns\n // Markdown:  or \n const markdownImageRegex = /!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"[^\"]*\")?\\)/g;\n\n // JSX/HTML: <img src=\"...\" alt=\"...\" /> or <Image src=\"...\" alt=\"...\" />\n const jsxImageRegex = /<(?:img|Image)\\s+[^>]*src=[\"']([^\"']+)[\"'][^>]*>/gi;\n const altAttrRegex = /alt=[\"']([^\"']*)[\"']/i;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Skip lines inside code blocks\n if (isInCodeBlock(lines, i)) {\n continue;\n }\n\n // Find markdown images: \n let match;\n while ((match = markdownImageRegex.exec(line)) !== null) {\n const [, alt, src] = match;\n\n images.push({\n src,\n alt: alt.trim(),\n line: i + 1,\n hasAlt: alt.trim().length > 0,\n source: 'inline',\n });\n }\n\n // Reset regex lastIndex for reuse\n markdownImageRegex.lastIndex = 0;\n\n // Find JSX/HTML images: <img src=\"...\" /> or <Image src=\"...\" />\n while ((match = jsxImageRegex.exec(line)) !== null) {\n const [fullMatch, src] = match;\n\n // Extract alt attribute if present\n const altMatch = fullMatch.match(altAttrRegex);\n const alt = altMatch ? altMatch[1] : '';\n\n // Skip if this src was already captured by markdown regex\n const alreadyCaptured = images.some(\n img => img.line === i + 1 && img.src === src\n );\n\n if (!alreadyCaptured) {\n images.push({\n src,\n alt: alt.trim(),\n line: i + 1,\n hasAlt: alt.trim().length > 0,\n source: 'inline',\n });\n }\n }\n\n // Reset regex lastIndex for reuse\n jsxImageRegex.lastIndex = 0;\n }\n\n return images;\n}\n\n/**\n * Get images missing alt text\n */\nexport function getImagesMissingAlt(images: ExtractedImage[]): ExtractedImage[] {\n return images.filter(img => !img.hasAlt);\n}\n\n/**\n * Create an ExtractedImage from frontmatter data\n */\nexport function createFrontmatterImage(\n imagePath: string | undefined,\n imageAlt: string | undefined\n): ExtractedImage | null {\n if (!imagePath) {\n return null;\n }\n\n return {\n src: imagePath,\n alt: imageAlt || '',\n line: 0, // Frontmatter doesn't have a specific line\n hasAlt: !!imageAlt && imageAlt.trim().length > 0,\n source: 'frontmatter',\n };\n}\n\n/**\n * Normalize image path for comparison\n */\nexport function normalizeImagePath(src: string): string {\n let normalized = src;\n\n // Handle relative paths\n if (!normalized.startsWith('/') && !normalized.startsWith('http')) {\n normalized = '/' + normalized;\n }\n\n // Remove query strings\n normalized = normalized.split('?')[0];\n\n return normalized;\n}\n","/**\n * Image Validation Rules\n * Validates image alt text presence and image file existence\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport {\n extractImages,\n createFrontmatterImage,\n normalizeImagePath,\n} from '../utils/image-extractor.js';\nimport { isValidImagePath } from '../utils/slug-resolver.js';\n\n/**\n * Rule: Inline images must have alt text\n */\nexport const inlineImageMissingAlt: Rule = {\n name: 'inline-image-missing-alt',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Add descriptive alt text for accessibility and SEO',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const images = extractImages(item.body);\n\n for (const img of images) {\n if (!img.hasAlt) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'inline-image-missing-alt',\n severity: 'error',\n message: `Image missing alt text: ${img.src}`,\n suggestion: 'Add descriptive alt text for accessibility and SEO',\n line: img.line,\n });\n }\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Featured image in frontmatter should have alt text\n */\nexport const frontmatterImageMissingAlt: Rule = {\n name: 'frontmatter-image-missing-alt',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an imageAlt field to the frontmatter for the featured image',\n run: (item: ContentItem): LintResult[] => {\n // Only check if there's an image but no imageAlt\n if (item.image && (!item.imageAlt || item.imageAlt.trim().length === 0)) {\n return [{\n file: getDisplayPath(item),\n field: 'imageAlt',\n rule: 'frontmatter-image-missing-alt',\n severity: 'warning',\n message: 'Featured image missing alt text',\n suggestion: 'Add an imageAlt field to the frontmatter for the featured image',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Referenced images should exist in public directory\n */\nexport const imageNotFound: Rule = {\n name: 'image-not-found',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Check that the image path is correct and the file exists in public/',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const results: LintResult[] = [];\n\n // Check frontmatter image\n if (item.image) {\n const normalizedPath = normalizeImagePath(item.image);\n // Only check local images, not external URLs\n if (!item.image.startsWith('http') && !isValidImagePath(normalizedPath, context.validImages)) {\n results.push({\n file: getDisplayPath(item),\n field: 'image',\n rule: 'image-not-found',\n severity: 'warning',\n message: `Featured image not found: ${item.image}`,\n suggestion: 'Check that the image path is correct and the file exists in public/',\n });\n }\n }\n\n // Check inline images\n const images = extractImages(item.body);\n for (const img of images) {\n // Only check local images\n if (!img.src.startsWith('http')) {\n const normalizedPath = normalizeImagePath(img.src);\n if (!isValidImagePath(normalizedPath, context.validImages)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'image-not-found',\n severity: 'warning',\n message: `Inline image not found: ${img.src}`,\n suggestion: 'Check that the image path is correct and the file exists in public/',\n line: img.line,\n });\n }\n }\n }\n\n return results;\n },\n};\n\n/**\n * All image rules\n */\nexport const imageRules: Rule[] = [\n inlineImageMissingAlt,\n frontmatterImageMissingAlt,\n imageNotFound,\n];\n","/**\n * Word Counter Utility\n * Counts words in MDX content, stripping markdown syntax\n */\n\n/**\n * Strip markdown syntax to get plain text\n */\nexport function stripMarkdown(text: string): string {\n let result = text;\n\n // Remove code blocks (``` ... ```)\n result = result.replace(/```[\\s\\S]*?```/g, '');\n\n // Remove inline code (`code`)\n result = result.replace(/`[^`]+`/g, '');\n\n // Remove images \n result = result.replace(/!\\[[^\\]]*\\]\\([^)]+\\)/g, '');\n\n // Remove links but keep text [text](url) -> text\n result = result.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n\n // Remove HTML/JSX tags\n result = result.replace(/<[^>]+>/g, '');\n\n // Remove headings markers (#)\n result = result.replace(/^#{1,6}\\s+/gm, '');\n\n // Remove bold/italic markers\n result = result.replace(/\\*\\*([^*]+)\\*\\*/g, '$1');\n result = result.replace(/\\*([^*]+)\\*/g, '$1');\n result = result.replace(/__([^_]+)__/g, '$1');\n result = result.replace(/_([^_]+)_/g, '$1');\n\n // Remove blockquotes\n result = result.replace(/^>\\s+/gm, '');\n\n // Remove horizontal rules\n result = result.replace(/^[-*_]{3,}$/gm, '');\n\n // Remove list markers\n result = result.replace(/^[\\s]*[-*+]\\s+/gm, '');\n result = result.replace(/^[\\s]*\\d+\\.\\s+/gm, '');\n\n // Remove frontmatter-style content (import statements, etc.)\n result = result.replace(/^import\\s+.*$/gm, '');\n result = result.replace(/^export\\s+.*$/gm, '');\n\n // Remove JSX component tags (like <CalloutBox>...</CalloutBox>)\n result = result.replace(/<\\w+[^>]*>[\\s\\S]*?<\\/\\w+>/g, (match) => {\n // Try to extract text content from JSX\n return match.replace(/<[^>]+>/g, ' ');\n });\n\n return result;\n}\n\n/**\n * Count words in text\n * Splits on whitespace and counts non-empty tokens\n */\nexport function countWords(text: string): number {\n const stripped = stripMarkdown(text);\n\n // Split on whitespace and filter empty strings\n const words = stripped\n .split(/\\s+/)\n .filter(word => word.length > 0)\n // Filter out remaining non-word characters\n .filter(word => /\\w/.test(word));\n\n return words.length;\n}\n\n/**\n * Count sentences in text\n * Looks for sentence-ending punctuation\n */\nexport function countSentences(text: string): number {\n const stripped = stripMarkdown(text);\n\n // Match sentence-ending punctuation followed by:\n // - whitespace or end of string (original)\n // - a capital letter (handles no-space after period)\n // - a newline (handles line-break-separated sentences)\n const sentenceEndings = stripped.match(/[.!?]+(?:\\s|$|(?=[A-ZÄÖÜ]))/g);\n\n if (sentenceEndings && sentenceEndings.length > 0) {\n return sentenceEndings.length;\n }\n\n // Fallback: estimate from paragraph/line breaks\n const lines = stripped.split(/\\n+/).filter(l => l.trim().length > 20);\n if (lines.length > 1) {\n return lines.length;\n }\n\n // Last resort: if there are words, assume at least 1 sentence\n const hasWords = /\\w{2,}/.test(stripped);\n return hasWords ? 1 : 0;\n}\n\n/**\n * Get word count statistics for content\n */\nexport function getWordStats(mdxBody: string): {\n wordCount: number;\n sentenceCount: number;\n avgWordsPerSentence: number;\n} {\n const wordCount = countWords(mdxBody);\n const sentenceCount = countSentences(mdxBody);\n\n return {\n wordCount,\n sentenceCount,\n avgWordsPerSentence: sentenceCount > 0 ? wordCount / sentenceCount : 0,\n };\n}\n","/**\n * Readability Utility\n * Calculates locale-aware Flesch Reading Ease scores for content.\n *\n * Supports English and German with their respective formulas:\n * - English: 206.835 - 1.015*ASL - 84.6*ASW\n * - German: 180 - ASL - 58.5*ASW\n */\n\nimport { stripMarkdown, countWords, countSentences } from './word-counter.js';\n\n/**\n * Estimate syllable count for a word using locale-specific heuristics.\n * English: applies silent-e discount. German: applies compound word adjustment.\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'de'.\n */\nexport function estimateSyllables(word: string, locale: string = 'de'): number {\n const lower = word.toLowerCase();\n\n // Count vowel groups (including umlauts)\n const vowelPattern = /[aeiouyäöü]+/gi;\n const matches = lower.match(vowelPattern);\n\n if (!matches) {\n return 1; // Assume at least 1 syllable\n }\n\n let count = matches.length;\n const lang = locale.toLowerCase().slice(0, 2);\n\n if (lang === 'en') {\n // English: silent-e discount\n if (lower.endsWith('e') && count > 1) {\n count -= 0.5;\n }\n } else {\n // German (and fallback): compound word adjustment for long words\n if (word.length > 12) {\n count = Math.max(count, Math.ceil(word.length / 4));\n }\n }\n\n return Math.max(1, Math.round(count));\n}\n\n/**\n * Count total syllables in text\n */\nfunction countSyllables(text: string, locale: string): number {\n const words = text\n .split(/\\s+/)\n .filter(word => word.length > 0)\n .filter(word => /\\w/.test(word));\n\n return words.reduce((total, word) => total + estimateSyllables(word, locale), 0);\n}\n\n/**\n * Calculate average word length in characters\n */\nfunction averageWordLength(text: string): number {\n const words = text\n .split(/\\s+/)\n .filter(word => word.length > 0)\n .filter(word => /\\w/.test(word));\n\n if (words.length === 0) return 0;\n\n const totalLength = words.reduce((sum, word) => sum + word.length, 0);\n return totalLength / words.length;\n}\n\n/**\n * Calculate locale-aware Flesch Reading Ease score.\n * Score range: 0-100 (higher = easier to read).\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'de'.\n */\n/** Flesch Reading Ease coefficients per locale */\nconst FLESCH_COEFFICIENTS = {\n en: { intercept: 206.835, aslWeight: 1.015, aswWeight: 84.6 },\n de: { intercept: 180, aslWeight: 1.0, aswWeight: 58.5 },\n} as const;\n\ntype FleschLocale = keyof typeof FLESCH_COEFFICIENTS;\n\n/** Interpretation bands per locale (score thresholds differ between formulas) */\nconst INTERPRETATION_BANDS: Record<FleschLocale, ReadonlyArray<{ min: number; label: string }>> = {\n en: [\n { min: 90, label: 'Very easy to read' },\n { min: 80, label: 'Easy to read' },\n { min: 70, label: 'Fairly easy to read' },\n { min: 60, label: 'Standard' },\n { min: 50, label: 'Fairly difficult' },\n { min: 30, label: 'Difficult' },\n { min: 0, label: 'Very difficult' },\n ],\n de: [\n { min: 70, label: 'Very easy to read' },\n { min: 60, label: 'Easy to read' },\n { min: 50, label: 'Fairly easy to read' },\n { min: 40, label: 'Standard' },\n { min: 30, label: 'Fairly difficult' },\n { min: 20, label: 'Difficult' },\n { min: 0, label: 'Very difficult' },\n ],\n};\n\nexport function calculateReadability(mdxBody: string, locale: string = 'de'): {\n score: number;\n avgSentenceLength: number;\n avgSyllablesPerWord: number;\n avgWordLength: number;\n interpretation: string;\n} {\n const plainText = stripMarkdown(mdxBody);\n\n const wordCount = countWords(mdxBody);\n const sentenceCount = countSentences(mdxBody);\n const syllableCount = countSyllables(plainText, locale);\n\n // Avoid division by zero\n if (wordCount === 0 || sentenceCount === 0) {\n return {\n score: 0,\n avgSentenceLength: 0,\n avgSyllablesPerWord: 0,\n avgWordLength: 0,\n interpretation: 'No content to analyze',\n };\n }\n\n const avgSentenceLength = wordCount / sentenceCount;\n const avgSyllablesPerWord = syllableCount / wordCount;\n const avgWordLen = averageWordLength(plainText);\n\n const lang = locale.toLowerCase().slice(0, 2) as FleschLocale;\n const coefficients = FLESCH_COEFFICIENTS[lang] ?? FLESCH_COEFFICIENTS.de;\n const score = Math.round(\n coefficients.intercept\n - coefficients.aslWeight * avgSentenceLength\n - coefficients.aswWeight * avgSyllablesPerWord,\n );\n\n const clampedScore = Math.max(0, Math.min(100, score));\n\n return {\n score: clampedScore,\n avgSentenceLength: Math.round(avgSentenceLength * 10) / 10,\n avgSyllablesPerWord: Math.round(avgSyllablesPerWord * 100) / 100,\n avgWordLength: Math.round(avgWordLen * 10) / 10,\n interpretation: getInterpretation(clampedScore, locale),\n };\n}\n\n/**\n * Get human-readable interpretation of readability score\n */\nfunction getInterpretation(score: number, locale: string = 'de'): string {\n const lang = locale.toLowerCase().slice(0, 2) as FleschLocale;\n const bands = INTERPRETATION_BANDS[lang] ?? INTERPRETATION_BANDS.de;\n\n for (const band of bands) {\n if (score >= band.min) return band.label;\n }\n return 'Very difficult';\n}\n\n/**\n * Check if readability score meets minimum threshold\n */\nexport function isReadable(score: number, threshold: number): boolean {\n return score >= threshold;\n}\n","/**\n * Content Quality Rules\n * Validates word count and readability\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { calculateReadability, isReadable } from '../utils/readability.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default content thresholds (used when context has no thresholds) */\nconst CONTENT_DEFAULTS = { minWordCount: 300, minReadabilityScore: 30 };\n\n/**\n * Rule: Content should have minimum word count\n */\nexport const contentTooShort: Rule = {\n name: 'content-too-short',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Expand the content for better SEO performance',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const c = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).content\n : CONTENT_DEFAULTS;\n const wordCount = countWords(item.body);\n\n if (wordCount < c.minWordCount) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-too-short',\n severity: 'warning',\n message: `Content is too short (${wordCount} words, minimum ${c.minWordCount})`,\n suggestion: 'Consider expanding the content for better SEO performance',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Content should meet minimum readability threshold\n */\nexport const lowReadability: Rule = {\n name: 'low-readability',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Use shorter sentences for easier reading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n\n if (wordCount < 100) {\n return [];\n }\n\n const c = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).content\n : CONTENT_DEFAULTS;\n const locale = item.locale ?? context.defaultLocale ?? 'de';\n const readability = calculateReadability(item.body, locale);\n\n if (!isReadable(readability.score, c.minReadabilityScore)) {\n /** Escalate to error for extremely unreadable content (score < 20) */\n const isExtreme = readability.score < 20;\n const severity = isExtreme ? 'error' : 'warning';\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'low-readability',\n severity,\n message: `${isExtreme ? 'Extremely low' : 'Low'} readability score (${readability.score}/100 - ${readability.interpretation})`,\n suggestion: `Avg sentence length: ${readability.avgSentenceLength} words. ${isExtreme ? 'Content is nearly unreadable. Drastically simplify sentence structure and vocabulary.' : 'Consider shorter sentences for easier reading.'}`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All content rules\n */\nexport const contentRules: Rule[] = [\n contentTooShort,\n lowReadability,\n];\n","/**\n * Open Graph Rules\n * Validates Open Graph / social sharing metadata\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Blog posts should have a featured image for social sharing\n */\nexport const blogMissingOgImage: Rule = {\n name: 'blog-missing-og-image',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an image field to the frontmatter for social sharing previews',\n run: (item: ContentItem): LintResult[] => {\n // Only apply to blog posts\n if (item.contentType !== 'blog') {\n return [];\n }\n\n if (!item.image || item.image.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'image',\n rule: 'blog-missing-og-image',\n severity: 'warning',\n message: 'Blog post missing featured image',\n suggestion: 'Add an image field for better social media sharing previews.',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Project pages should have a thumbnail/featured image for social sharing\n */\nexport const projectMissingOgImage: Rule = {\n name: 'project-missing-og-image',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a thumbnail image for social media sharing previews',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'project') {\n return [];\n }\n\n if (!item.image || item.image.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'image',\n rule: 'project-missing-og-image',\n severity: 'warning',\n message: 'Project missing thumbnail/featured image',\n suggestion: 'Add a thumbnail image for better social media sharing previews.',\n }];\n }\n return [];\n },\n};\n\n/**\n * All Open Graph rules\n */\nexport const ogRules: Rule[] = [\n blogMissingOgImage,\n projectMissingOgImage,\n];\n","/**\n * Performance Validation Rules\n * Checks image file sizes and other performance-related concerns\n */\n\nimport { statSync } from 'fs';\nimport { join } from 'path';\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { extractImages } from '../utils/image-extractor.js';\n\n/** Default max image size in KB */\nconst MAX_IMAGE_SIZE_KB = 500;\n\n/**\n * Rule: Image files should not exceed the configured size limit\n * Large images degrade page load performance and Core Web Vitals\n */\nexport const imageFileTooLarge: Rule = {\n name: 'image-file-too-large',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Compress the image or convert to WebP/AVIF format',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const maxBytes = MAX_IMAGE_SIZE_KB * 1024;\n const imagesToCheck: Array<{ src: string; line?: number; source: string }> = [];\n\n // Check featured image from frontmatter\n if (item.image && !item.image.startsWith('http')) {\n imagesToCheck.push({ src: item.image, source: 'frontmatter' });\n }\n\n // Check inline images from body\n const inlineImages = extractImages(item.body);\n for (const img of inlineImages) {\n if (!img.src.startsWith('http')) {\n imagesToCheck.push({ src: img.src, line: img.line, source: 'inline' });\n }\n }\n\n for (const image of imagesToCheck) {\n try {\n const imagePath = join(process.cwd(), 'public', image.src);\n const stats = statSync(imagePath);\n const sizeKB = Math.round(stats.size / 1024);\n\n if (stats.size > maxBytes) {\n results.push({\n file: getDisplayPath(item),\n field: image.source === 'frontmatter' ? 'image' : 'body',\n rule: 'image-file-too-large',\n severity: 'warning',\n message: `Image file too large: ${image.src} (${sizeKB}KB > ${MAX_IMAGE_SIZE_KB}KB)`,\n suggestion: 'Compress the image or convert to WebP/AVIF format to improve page load speed',\n line: image.line,\n });\n }\n } catch {\n // File not found is handled by image-not-found rule\n }\n }\n\n return results;\n },\n};\n\n/**\n * All performance rules\n */\nexport const performanceRules: Rule[] = [\n imageFileTooLarge,\n];\n","/**\n * Robots / Indexing Validation Rules\n * Validates noindex and robots-related settings\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Published (non-draft) content with noindex may be unintentional\n * Warns when content is publicly available but hidden from search engines\n */\nexport const publishedNoindex: Rule = {\n name: 'published-noindex',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Remove noindex if content should be discoverable, or set draft: true to hide it',\n run: (item: ContentItem): LintResult[] => {\n if (!item.draft && item.noindex === true) {\n return [{\n file: getDisplayPath(item),\n field: 'noindex',\n rule: 'published-noindex',\n severity: 'warning',\n message: 'Published content has noindex set — it will not appear in search results',\n suggestion: 'Remove noindex if this content should be discoverable, or set draft: true if it should be hidden entirely',\n }];\n }\n return [];\n },\n};\n\n/**\n * All robots/indexing rules\n */\nexport const robotsRules: Rule[] = [\n publishedNoindex,\n];\n","/**\n * Slug Validation Rules\n * Validates slug format and length for SEO-friendly URLs\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { resolveThresholds } from '../utils/resolve-thresholds.js';\n\n/** Default slug threshold (used when context has no thresholds) */\nconst SLUG_DEFAULTS = { maxLength: 75 };\nconst SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nconst URL_PATH_PATTERN = /^[a-z0-9]+(?:[-/][a-z0-9]+)*$/;\n\n/**\n * Rule: Slug must contain only valid characters (lowercase alphanumeric + hyphens)\n */\nexport const slugInvalidCharacters: Rule = {\n name: 'slug-invalid-characters',\n severity: 'error',\n category: 'seo',\n fixStrategy: 'Use lowercase alphanumeric characters with hyphens only (e.g., \"my-blog-post\")',\n run: (item: ContentItem): LintResult[] => {\n if (!item.slug) return [];\n\n const isUrl = item.contentSource === 'url';\n const pattern = isUrl ? URL_PATH_PATTERN : SLUG_PATTERN;\n\n const hasUppercase = /[A-Z]/.test(item.slug);\n const matchesPattern = pattern.test(item.slug);\n\n if (hasUppercase || !matchesPattern) {\n return [{\n file: getDisplayPath(item),\n field: 'slug',\n rule: 'slug-invalid-characters',\n severity: 'error',\n message: `Slug \"${item.slug}\" contains invalid characters`,\n suggestion: isUrl\n ? 'URL paths must be lowercase alphanumeric with hyphens and slashes only'\n : 'Slugs must be lowercase alphanumeric with hyphens only (e.g., \"my-blog-post\")',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Slug should not exceed maximum length\n */\nexport const slugTooLong: Rule = {\n name: 'slug-too-long',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Shorten the slug for better URL readability',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.slug) return [];\n\n const s = context.thresholds\n ? resolveThresholds(context.thresholds, item.contentType).slug\n : SLUG_DEFAULTS;\n const length = item.slug.length;\n if (length > s.maxLength) {\n return [{\n file: getDisplayPath(item),\n field: 'slug',\n rule: 'slug-too-long',\n severity: 'warning',\n message: `Slug is too long (${length}/${s.maxLength} chars)`,\n suggestion: `Shorten the slug to ${s.maxLength} characters or less for better URL readability`,\n }];\n }\n return [];\n },\n};\n\n/**\n * All slug rules\n */\nexport const slugRules: Rule[] = [\n slugInvalidCharacters,\n slugTooLong,\n];\n","/**\n * Internationalization Validation Rules\n * Validates translation completeness, locale metadata, and hreflang x-default readiness\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { I18nConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Create a translation-pair-missing rule for the configured locales.\n * Checks that every translation group has versions for all configured locales.\n */\nfunction createTranslationPairMissingRule(i18n: I18nConfig): Rule {\n return {\n name: 'translation-pair-missing',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: 'Create the missing translation version with the same translationKey',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.translationKey) return [];\n if (!item.locale) return [];\n\n const siblings = context.allContent.filter(\n c => c.translationKey === item.translationKey && c.slug !== item.slug,\n );\n const presentLocales = new Set([item.locale, ...siblings.map(s => s.locale)]);\n const results: LintResult[] = [];\n\n for (const locale of i18n.locales) {\n if (!presentLocales.has(locale)) {\n results.push({\n file: getDisplayPath(item),\n field: 'translationKey',\n rule: 'translation-pair-missing',\n severity: 'warning',\n message: `Missing \"${locale}\" translation for translationKey \"${item.translationKey}\"`,\n suggestion: `Create a ${locale} version with the same translationKey value.`,\n });\n }\n }\n\n return results;\n },\n };\n}\n\n/**\n * Create a missing-locale rule that lists all configured locales in the suggestion.\n */\nfunction createMissingLocaleRule(i18n: I18nConfig): Rule {\n const localeList = i18n.locales.join(' / ');\n\n return {\n name: 'missing-locale',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: `Add a locale field (${localeList}) to the frontmatter`,\n run: (item: ContentItem): LintResult[] => {\n if (!item.locale) {\n return [{\n file: getDisplayPath(item),\n field: 'locale',\n rule: 'missing-locale',\n severity: 'warning',\n message: 'Missing locale field',\n suggestion: `Add a locale field (${localeList}) to the frontmatter for proper i18n support.`,\n }];\n }\n return [];\n },\n };\n}\n\n/**\n * Create an x-default-missing rule.\n * Checks that each translation group has a version in the default locale.\n * Fires once per group (on the first non-default item, sorted by slug).\n */\nfunction createXDefaultMissingRule(i18n: I18nConfig): Rule {\n return {\n name: 'x-default-missing',\n severity: 'warning',\n category: 'i18n',\n fixStrategy: `Create a ${i18n.defaultLocale} version so hreflang x-default resolves correctly`,\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n if (!item.translationKey) return [];\n if (item.locale === i18n.defaultLocale) return [];\n\n const groupItems = context.allContent.filter(\n c => c.translationKey === item.translationKey,\n );\n\n const hasDefaultLocale = groupItems.some(c => c.locale === i18n.defaultLocale);\n if (hasDefaultLocale) return [];\n\n // Fire only on the first non-default item (sorted by slug for determinism)\n const sortedNonDefault = groupItems\n .filter(c => c.locale !== i18n.defaultLocale)\n .sort((a, b) => a.slug.localeCompare(b.slug));\n\n if (sortedNonDefault.length === 0 || sortedNonDefault[0].slug !== item.slug) {\n return [];\n }\n\n return [{\n file: getDisplayPath(item),\n field: 'translationKey',\n rule: 'x-default-missing',\n severity: 'warning',\n message: `Translation group \"${item.translationKey}\" has no ${i18n.defaultLocale} version — hreflang x-default will not resolve`,\n suggestion: `Create a ${i18n.defaultLocale} version with translationKey \"${item.translationKey}\".`,\n }];\n },\n };\n}\n\n/**\n * Create all i18n rules from configuration.\n * Supports configurable locales and default locale.\n */\nexport function createI18nRules(i18n: I18nConfig): Rule[] {\n return [\n createTranslationPairMissingRule(i18n),\n createMissingLocaleRule(i18n),\n createXDefaultMissingRule(i18n),\n ];\n}\n\n/** Static export for backward compatibility (DE/EN defaults) */\nexport const i18nRules: Rule[] = createI18nRules({\n locales: ['de', 'en'],\n defaultLocale: 'de',\n});\n","/**\n * Date Validation Rules\n * Validates date presence and correctness for blog and project content\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Rule: Blog and project content must have a date field\n */\nexport const missingDate: Rule = {\n name: 'missing-date',\n severity: 'error',\n category: 'content',\n fixStrategy: 'Add a date field (e.g., \"2025-01-15\") to the frontmatter',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'page') return [];\n\n if (!item.date) {\n return [{\n file: getDisplayPath(item),\n field: 'date',\n rule: 'missing-date',\n severity: 'error',\n message: 'Missing date field',\n suggestion: 'Add a date field (e.g., \"2025-01-15\") to the frontmatter',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Date should not be in the future\n */\nexport const futureDate: Rule = {\n name: 'future-date',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Verify the publish date is correct or set it to today',\n run: (item: ContentItem): LintResult[] => {\n if (!item.date) return [];\n\n const dateValue = new Date(item.date);\n const now = new Date();\n\n if (dateValue > now) {\n return [{\n file: getDisplayPath(item),\n field: 'date',\n rule: 'future-date',\n severity: 'warning',\n message: `Date \"${item.date}\" is in the future`,\n suggestion: 'Verify the publish date is correct or set it to today',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Blog and project content should have an updatedAt field\n */\nexport const missingUpdatedAt: Rule = {\n name: 'missing-updated-at',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add an updatedAt field to help search engines identify fresh content',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'page') return [];\n\n if (!item.updatedAt) {\n return [{\n file: getDisplayPath(item),\n field: 'updatedAt',\n rule: 'missing-updated-at',\n severity: 'warning',\n message: 'Missing updatedAt field',\n suggestion: 'Add an updatedAt field to help search engines identify fresh content',\n }];\n }\n return [];\n },\n};\n\n/**\n * All date rules\n */\nexport const dateRules: Rule[] = [\n missingDate,\n futureDate,\n missingUpdatedAt,\n];\n","/**\n * GEO (Generative Engine Optimization) Analyzer\n * Utilities for analyzing content readiness for LLM visibility\n */\n\nimport { extractHeadings } from './heading-extractor.js';\nimport { countWords } from './word-counter.js';\nimport { detectPlaintextFaq, detectPlaintextTable, detectPlaintextList } from './plaintext-structure.js';\n\n/**\n * Question words in English and German (case-insensitive matching)\n */\nconst QUESTION_WORDS = [\n 'was', 'wie', 'warum', 'wann', 'wo', 'wer', 'welche',\n 'how', 'what', 'why', 'when', 'where', 'who', 'which',\n 'can', 'do', 'does', 'is', 'are', 'should',\n];\n\n/**\n * Weak lead sentence patterns (case-insensitive)\n * These indicate introductory filler rather than direct answers\n */\nconst WEAK_LEAD_STARTS = [\n // English — generic filler openings\n 'in this', 'the following', 'this section', 'this article',\n 'this post', 'this guide', 'this chapter',\n 'as we discussed', 'as mentioned', 'as noted', 'as stated',\n 'it is important to', 'it should be noted', 'it is worth noting',\n 'it is well known', 'it goes without saying',\n 'in the following', 'in this section', 'in this article',\n 'there are many', 'there are several', 'there are a number of',\n 'we will discuss', 'we will explore', 'we will examine',\n \"let's\", \"let's take a look\",\n // German — generische Fülleröffnungen\n 'dieser abschnitt', 'dieser artikel', 'dieser beitrag',\n 'diesem', 'lass uns', 'im folgenden',\n 'wie bereits erwähnt', 'wie oben erwähnt',\n 'es ist wichtig', 'es sei darauf hingewiesen',\n 'es gibt viele', 'es gibt zahlreiche',\n 'wir werden', 'schauen wir uns',\n];\n\n/**\n * Markdown table separator pattern\n * Matches `|---`, `| ---`, `|:---`, `| :---:` and similar variants\n */\nconst TABLE_SEPARATOR_PATTERN = /\\|\\s*:?-{2,}/;\n\n/**\n * Count headings that are formatted as questions\n * A question heading either ends with '?' or starts with a question word\n */\nexport function countQuestionHeadings(body: string, contentSource?: 'file' | 'url'): number {\n const headings = extractHeadings(body, contentSource);\n let count = 0;\n\n for (const heading of headings) {\n const text = heading.text.trim();\n\n // Check if heading ends with question mark\n if (text.endsWith('?')) {\n count++;\n continue;\n }\n\n // Check if heading starts with a question word\n const firstWord = text.split(/\\s+/)[0]?.toLowerCase() ?? '';\n if (QUESTION_WORDS.includes(firstWord)) {\n count++;\n }\n }\n\n return count;\n}\n\n/**\n * Analyze lead sentences across content sections\n * Splits on H2/H3 headings and checks if the first sentence in each\n * section is a direct answer (not a weak intro)\n */\nexport function analyzeLeadSentences(body: string): {\n totalSections: number;\n sectionsWithDirectAnswers: number;\n} {\n // Split body on H2/H3 heading patterns\n const sectionPattern = /^#{2,3}\\s+.+$/m;\n const sections = body.split(sectionPattern);\n\n // First element is content before the first heading (skip it)\n const contentSections = sections.slice(1);\n\n let totalSections = 0;\n let sectionsWithDirectAnswers = 0;\n\n for (const section of contentSections) {\n const trimmed = section.trim();\n if (!trimmed) continue;\n\n totalSections++;\n\n // Extract first sentence (ends with . ! or ?)\n const sentenceMatch = trimmed.match(/^([^.!?]+[.!?])/);\n if (!sentenceMatch) continue;\n\n const firstSentence = sentenceMatch[1].trim();\n\n // Skip if too short to be meaningful\n if (firstSentence.length <= 20) continue;\n\n // Skip if ends with question mark (not a direct answer)\n if (firstSentence.endsWith('?')) continue;\n\n // Check for weak lead patterns\n const lowerSentence = firstSentence.toLowerCase();\n const isWeakLead = WEAK_LEAD_STARTS.some(\n pattern => lowerSentence.startsWith(pattern)\n );\n\n if (!isWeakLead) {\n sectionsWithDirectAnswers++;\n }\n }\n\n return { totalSections, sectionsWithDirectAnswers };\n}\n\n/**\n * Count statistical data points in the content body\n * Looks for percentages, multipliers, currency values, large numbers, and scales\n */\nexport function countStatistics(body: string): number {\n const patterns: RegExp[] = [\n /\\d+\\s*%/g, // Percentages: 50%, 23 %\n /\\d+(?:\\.\\d+)?\\s*(?:x|mal|times)/gi, // Multipliers: 3x, 2.5 mal, 10 times\n /(?:€|\\$|USD|EUR)\\s*\\d+/g, // Currency: €500, $1000, USD 50\n /\\d{4,}/g, // Large numbers: 10000, 2024 (4+ digits)\n /\\d+(?:\\.\\d+)?\\s*(?:million|billion|mrd|mio)/gi, // Scales: 5 million, 2.3 Mrd\n ];\n\n const matches = new Set<string>();\n\n for (const pattern of patterns) {\n const found = body.matchAll(pattern);\n for (const match of found) {\n // Use position as key to avoid double-counting overlapping matches\n matches.add(`${match.index}:${match[0]}`);\n }\n }\n\n return matches.size;\n}\n\n/**\n * Check if the content body contains a FAQ section\n * Matches common FAQ heading patterns in English and German\n */\nexport function hasFAQSection(body: string, contentSource?: 'file' | 'url'): boolean {\n const faqPattern = /#{2,3}\\s*(FAQ|Häufige Fragen|Frequently Asked|Fragen und Antworten)/i;\n if (faqPattern.test(body)) return true;\n if (contentSource === 'url') {\n return detectPlaintextFaq(body).hasFaq;\n }\n return false;\n}\n\n/**\n * Check if the content body contains at least one Markdown table\n * Detects the table separator row pattern (e.g., `|---|---`)\n */\nexport function hasMarkdownTable(body: string, contentSource?: 'file' | 'url'): boolean {\n if (TABLE_SEPARATOR_PATTERN.test(body)) return true;\n if (contentSource === 'url') {\n return detectPlaintextTable(body);\n }\n return false;\n}\n\n/**\n * Count case-insensitive occurrences of an entity string in the body\n *\n * @example\n * countEntityMentions(\"ACME builds software in Berlin\", \"acme\") // 1\n * countEntityMentions(\"Visit Berlin, the best city. Berlin rocks.\", \"berlin\") // 2\n */\nexport function countEntityMentions(body: string, entity: string): number {\n const escapedEntity = entity.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(escapedEntity, 'gi');\n const matches = body.match(pattern);\n return matches ? matches.length : 0;\n}\n\n/**\n * Analyze citation blocks after H2 headings\n * For each H2 section, checks whether the first paragraph is substantial\n * (40+ words), which improves AI system extraction and citation likelihood\n *\n * @example\n * analyzeCitationBlocks(\"## Heading\\n\\nA long first paragraph...\") // { totalSections: 1, sectionsWithAdequateBlocks: 1 }\n */\nexport function analyzeCitationBlocks(body: string): {\n totalSections: number;\n sectionsWithAdequateBlocks: number;\n} {\n // Split on H2 headings specifically (not H3+)\n const h2Pattern = /^##\\s+.+$/gm;\n const h2Matches = [...body.matchAll(h2Pattern)];\n\n if (h2Matches.length === 0) {\n return { totalSections: 0, sectionsWithAdequateBlocks: 0 };\n }\n\n let totalSections = 0;\n let sectionsWithAdequateBlocks = 0;\n\n for (let i = 0; i < h2Matches.length; i++) {\n const matchStart = h2Matches[i].index! + h2Matches[i][0].length;\n const nextHeadingStart = i + 1 < h2Matches.length\n ? h2Matches[i + 1].index!\n : body.length;\n\n const sectionContent = body.slice(matchStart, nextHeadingStart).trim();\n if (!sectionContent) continue;\n\n totalSections++;\n\n // Extract the first paragraph: text before the first blank line\n // followed by a heading, or before a sub-heading (### ...)\n const firstParagraph = extractFirstParagraph(sectionContent);\n if (!firstParagraph) continue;\n\n const wordCount = countWords(firstParagraph);\n if (wordCount >= 40) {\n sectionsWithAdequateBlocks++;\n }\n }\n\n return { totalSections, sectionsWithAdequateBlocks };\n}\n\n/**\n * Extract the first paragraph from a section content block\n * A paragraph ends at a blank line or at the next heading\n */\nfunction extractFirstParagraph(sectionContent: string): string {\n const lines = sectionContent.split('\\n');\n const paragraphLines: string[] = [];\n let foundContent = false;\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n\n // Skip leading empty lines\n if (!foundContent && !trimmedLine) continue;\n\n // Stop at a heading line\n if (trimmedLine.startsWith('#')) break;\n\n // Stop at a blank line after content has started\n if (foundContent && !trimmedLine) break;\n\n // Skip import/export statements and JSX component lines\n if (trimmedLine.startsWith('import ') || trimmedLine.startsWith('export ')) continue;\n if (trimmedLine.startsWith('<') && !trimmedLine.startsWith('<a')) continue;\n\n foundContent = true;\n paragraphLines.push(trimmedLine);\n }\n\n return paragraphLines.join(' ');\n}\n\n/**\n * Citation attribution patterns (case-insensitive)\n */\nconst CITATION_PHRASES = [\n /according to\\b/gi,\n /a study by\\b/gi,\n /research by\\b/gi,\n /data from\\b/gi,\n];\n\n/**\n * Count source citations in content body.\n * Matches: \"according to [Source]\", markdown links [text](url),\n * blockquote attributions (> ... -- Name), footnote markers [^1]\n *\n * @example\n * countSourceCitations(\"According to [ACME](https://acme.com), results improved by 30%.\") // 2\n */\nexport function countSourceCitations(body: string): number {\n let count = 0;\n\n // Count attribution phrases\n for (const pattern of CITATION_PHRASES) {\n const matches = body.match(pattern);\n if (matches) count += matches.length;\n }\n\n // Count markdown links with HTTP URLs\n const linkPattern = /\\[[^\\]]+\\]\\(https?:\\/\\/[^)]+\\)/g;\n const linkMatches = body.match(linkPattern);\n if (linkMatches) count += linkMatches.length;\n\n // Count blockquote attributions: lines starting with > containing em-dash or double-dash attribution\n const attributionPattern = /^>\\s*.*(?:\\u2014|--)\\s*\\S+/gm;\n const attrMatches = body.match(attributionPattern);\n if (attrMatches) count += attrMatches.length;\n\n // Count footnote markers [^1], [^note], etc.\n const footnotePattern = /\\[\\^[^\\]]+\\]/g;\n const footnoteMatches = body.match(footnotePattern);\n if (footnoteMatches) count += footnoteMatches.length;\n\n return count;\n}\n\n/**\n * Check if content has at least one attributed expert quote.\n * Attributed: blockquote (>) followed by em-dash + name, or \"said [Name]\"\n *\n * @example\n * hasExpertQuote('> AI will transform everything.\\n> \\u2014 Dr. Smith') // true\n */\nexport function hasExpertQuote(body: string): boolean {\n const lines = body.split('\\n');\n let inBlockquote = false;\n let blockquoteText = '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('>')) {\n inBlockquote = true;\n blockquoteText += ' ' + trimmed.slice(1).trim();\n } else {\n if (inBlockquote && blockquoteText) {\n // Check for em-dash or double-dash attribution within the blockquote\n if (/(?:\\u2014|--)\\s*[A-Z]/.test(blockquoteText)) {\n return true;\n }\n }\n inBlockquote = false;\n blockquoteText = '';\n }\n }\n\n // Check final blockquote if body ends with one\n if (inBlockquote && /(?:\\u2014|--)\\s*[A-Z]/.test(blockquoteText)) {\n return true;\n }\n\n // Check for \"said [Name]\" pattern anywhere\n if (/(?:said|says)\\s+[A-Z][a-z]+/.test(body)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Extract H2 sections from body, returning heading text, section body, and line number.\n *\n * @example\n * extractH2Sections(\"## Intro\\n\\nHello world\\n\\n## Next\\n\\nMore text\")\n * // [{ heading: \"Intro\", body: \"Hello world\", line: 1 }, { heading: \"Next\", body: \"More text\", line: 5 }]\n */\nexport function extractH2Sections(body: string): Array<{ heading: string; body: string; line: number }> {\n const h2Pattern = /^##\\s+(.+)$/gm;\n const matches = [...body.matchAll(h2Pattern)];\n const sections: Array<{ heading: string; body: string; line: number }> = [];\n\n for (let i = 0; i < matches.length; i++) {\n const match = matches[i];\n const headingText = match[1].trim();\n const lineNumber = body.slice(0, match.index!).split('\\n').length;\n\n const contentStart = match.index! + match[0].length;\n const contentEnd = i + 1 < matches.length ? matches[i + 1].index! : body.length;\n const sectionBody = body.slice(contentStart, contentEnd).trim();\n\n sections.push({ heading: headingText, body: sectionBody, line: lineNumber });\n }\n\n return sections;\n}\n\n/**\n * Split body into paragraphs (text between blank lines), with word counts.\n * Skips code blocks, import/export lines, JSX components, and heading lines.\n *\n * @example\n * getParagraphs(\"Hello world.\\n\\nAnother paragraph.\") // [{ text: \"Hello world.\", line: 1, wordCount: 2 }, ...]\n */\nexport function getParagraphs(body: string): Array<{ text: string; line: number; wordCount: number }> {\n const lines = body.split('\\n');\n const paragraphs: Array<{ text: string; line: number; wordCount: number }> = [];\n let inCodeBlock = false;\n let currentLines: string[] = [];\n let paragraphStartLine = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // Track code block state\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n // Flush current paragraph before code block\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n currentLines = [];\n }\n continue;\n }\n\n if (inCodeBlock) continue;\n\n // Skip import/export lines, JSX components, and heading lines\n if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) continue;\n if (trimmed.startsWith('<') && !trimmed.startsWith('<a')) continue;\n if (/^#{1,6}\\s+/.test(trimmed)) continue;\n\n // Blank line: flush current paragraph\n if (!trimmed) {\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n currentLines = [];\n }\n continue;\n }\n\n // Start new paragraph if needed\n if (currentLines.length === 0) {\n paragraphStartLine = i;\n }\n currentLines.push(trimmed);\n }\n\n // Flush final paragraph\n if (currentLines.length > 0) {\n const text = currentLines.join(' ');\n const wc = countWords(text);\n if (wc > 0) {\n paragraphs.push({ text, line: paragraphStartLine + 1, wordCount: wc });\n }\n }\n\n return paragraphs;\n}\n\n/**\n * Check if body contains at least one bulleted or numbered markdown list.\n * Matches: \"- \", \"* \", \"1. \" at start of line (outside code blocks).\n *\n * @example\n * hasMarkdownList(\"Some text\\n- item one\\n- item two\") // true\n */\nexport function hasMarkdownList(body: string, contentSource?: 'file' | 'url'): boolean {\n const lines = body.split('\\n');\n let inCodeBlock = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n\n if (inCodeBlock) continue;\n\n // Check for unordered list items\n if (/^[-*]\\s+/.test(trimmed)) return true;\n\n // Check for ordered list items\n if (/^\\d+\\.\\s+/.test(trimmed)) return true;\n }\n\n if (contentSource === 'url') {\n return detectPlaintextList(body);\n }\n\n return false;\n}\n\n/**\n * Count internal markdown links (relative paths starting with /).\n * Only counts markdown link syntax [text](/path), not bare URLs.\n *\n * @example\n * countInternalLinks(\"See [our blog](/blog) and [about](/about) pages.\") // 2\n */\nexport function countInternalLinks(body: string): number {\n const pattern = /\\[([^\\]]+)\\]\\(\\/[^)]+\\)/g;\n const matches = body.match(pattern);\n return matches ? matches.length : 0;\n}\n","/**\n * GEO Advanced Analyzer\n * Complex analysis utilities for LLM citation optimization rules\n */\n\nimport { countWords, stripMarkdown } from './word-counter.js';\nimport { extractHeadings } from './heading-extractor.js';\n\n/** FAQ quality analysis result */\nexport interface FaqQualityResult {\n pairCount: number;\n questionsWithMark: number;\n answersInRange: number;\n answerWordCounts: number[];\n}\n\n/** Passive voice analysis result */\nexport interface PassiveVoiceResult {\n totalSentences: number;\n passiveSentences: number;\n passiveRatio: number;\n}\n\n/**\n * Common irregular past participles for passive voice detection\n */\nconst IRREGULAR_PAST_PARTICIPLES = new Set([\n 'written', 'known', 'made', 'done', 'seen', 'taken', 'given',\n 'found', 'built', 'shown', 'broken', 'chosen', 'driven', 'spoken',\n 'stolen', 'worn', 'torn', 'frozen', 'hidden', 'forgotten', 'risen',\n 'fallen', 'begun', 'run', 'come', 'become', 'grown', 'drawn',\n 'thrown', 'blown', 'flown', 'sworn', 'shaken', 'mistaken', 'proven', 'woven',\n]);\n\n/**\n * Forms of \"to be\" used in passive voice constructions\n */\nconst BE_FORMS = new Set(['is', 'are', 'was', 'were', 'been', 'being', 'be']);\n\n/**\n * Attribution markers that provide context for statistics\n */\nconst ATTRIBUTION_MARKERS = [\n 'according to', 'study', 'survey', 'report', 'research',\n 'source', 'data from', 'published',\n];\n\n/**\n * Pronouns/references that indicate unresolved section openings\n */\nconst UNRESOLVED_WORDS = new Set([\n 'this', 'it', 'that', 'these', 'those', 'they', 'such', 'here', 'there',\n]);\n\nconst UNRESOLVED_PHRASES = [\n 'as mentioned', 'as noted', 'as discussed', 'previously',\n];\n\n/**\n * Standard HTML tags that should be flagged when found in markdown.\n */\nconst STANDARD_HTML_TAGS = new Set([\n 'div', 'span', 'p', 'br', 'b', 'i', 'em', 'strong', 'a', 'ul', 'ol', 'li',\n 'table', 'tr', 'td', 'th', 'thead', 'tbody', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',\n 'img', 'hr', 'blockquote', 'pre', 'code', 'section', 'article', 'nav', 'header',\n 'footer', 'main', 'aside', 'figure', 'figcaption', 'details', 'summary',\n]);\n\n/**\n * Analyze FAQ section quality: count Q&A pairs, answer lengths, question formatting.\n *\n * @example\n * analyzeFaqQuality(\"## FAQ\\n\\n### What is SEO?\\n\\nSEO stands for...\") // { pairCount: 1, ... }\n */\nexport function analyzeFaqQuality(body: string): FaqQualityResult {\n const result: FaqQualityResult = {\n pairCount: 0,\n questionsWithMark: 0,\n answersInRange: 0,\n answerWordCounts: [],\n };\n\n // Find FAQ section start\n const faqPattern = /^#{2,3}\\s*(FAQ|H\\u00e4ufige Fragen|Frequently Asked|Fragen und Antworten)/im;\n const faqMatch = body.match(faqPattern);\n if (!faqMatch || faqMatch.index === undefined) return result;\n\n // Get content after FAQ heading until next H2 or end\n const afterFaq = body.slice(faqMatch.index + faqMatch[0].length);\n const nextH2Match = afterFaq.match(/^##\\s+(?!#)/m);\n const faqContent = nextH2Match && nextH2Match.index !== undefined\n ? afterFaq.slice(0, nextH2Match.index)\n : afterFaq;\n\n // Extract H3 headings as questions within the FAQ section\n const h3Pattern = /^###\\s+(.+)$/gm;\n const h3Matches = [...faqContent.matchAll(h3Pattern)];\n\n for (let i = 0; i < h3Matches.length; i++) {\n const questionText = h3Matches[i][1].trim();\n result.pairCount++;\n\n if (questionText.endsWith('?')) {\n result.questionsWithMark++;\n }\n\n // Extract answer: content between this H3 and the next H3 (or end of FAQ)\n const answerStart = h3Matches[i].index! + h3Matches[i][0].length;\n const answerEnd = i + 1 < h3Matches.length ? h3Matches[i + 1].index! : faqContent.length;\n const answerText = faqContent.slice(answerStart, answerEnd).trim();\n const answerWords = countWords(answerText);\n result.answerWordCounts.push(answerWords);\n\n if (answerWords >= 30 && answerWords <= 75) {\n result.answersInRange++;\n }\n }\n\n return result;\n}\n\n/**\n * German passive voice auxiliary verbs (all conjugations of \"werden\")\n */\nconst GERMAN_PASSIVE_AUXILIARIES = new Set([\n 'werde', 'wirst', 'wird', 'werden', 'werdet',\n 'wurde', 'wurdest', 'wurden', 'wurdet',\n 'worden', 'würde', 'würdest', 'würden', 'würdet',\n]);\n\n/**\n * German past participle regex patterns.\n * German participles typically follow: ge-...-t, ge-...-en, or -iert.\n * Separable prefixes (ab-, an-, auf-, etc.) insert \"ge\" after the prefix.\n * Inseparable prefixes (be-, ent-, er-, ver-, zer-, über-) have no \"ge-\".\n */\nconst GERMAN_PARTICIPLE_PATTERNS: RegExp[] = [\n /^ge\\S+t$/i, // gemacht, gesagt\n /^ge\\S+en$/i, // geschrieben, gefunden\n /^\\S+iert$/i, // organisiert, implementiert\n /^(ab|an|auf|aus|vor|wieder|zurück)ge\\S+(t|en)$/i, // aufgemacht, angenommen\n /^(be|ent|er|her|ver|zer|über)\\S+([^s]t|en)$/i, // bearbeitet, verstanden\n];\n\n/**\n * Detect passive voice sentences with locale support.\n * English: \"be\" form + past participle within 3 words.\n * German: \"werden\" conjugation + past participle within 5 words.\n *\n * @example\n * analyzePassiveVoice(\"The report was written by the team.\") // passiveRatio: 1.0\n * analyzePassiveVoice(\"Der Bericht wurde geschrieben.\", \"de\") // passiveRatio: 1.0\n */\nexport function analyzePassiveVoice(body: string, locale?: string): PassiveVoiceResult {\n const sentences = extractSentences(body);\n const lang = (locale ?? 'en').toLowerCase();\n let passiveCount = 0;\n\n for (const { text } of sentences) {\n if (lang === 'de' ? isGermanPassiveSentence(text) : isEnglishPassiveSentence(text)) {\n passiveCount++;\n }\n }\n\n const total = sentences.length;\n return {\n totalSentences: total,\n passiveSentences: passiveCount,\n passiveRatio: total > 0 ? passiveCount / total : 0,\n };\n}\n\n/**\n * Check if a single English sentence contains passive voice construction.\n * Heuristic: a form of \"be\" followed within 3 words by a past participle.\n */\nfunction isEnglishPassiveSentence(sentence: string): boolean {\n const words = sentence.toLowerCase().split(/\\s+/).filter(w => w.length > 0);\n\n for (let i = 0; i < words.length; i++) {\n const cleaned = words[i].replace(/[^a-z]/g, '');\n if (!BE_FORMS.has(cleaned)) continue;\n\n // Check next 3 words for a past participle\n const searchEnd = Math.min(i + 4, words.length);\n for (let j = i + 1; j < searchEnd; j++) {\n const candidate = words[j].replace(/[^a-z]/g, '');\n if (candidate.endsWith('ed') || IRREGULAR_PAST_PARTICIPLES.has(candidate)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Check if a single German sentence contains passive voice construction.\n * Heuristic: a \"werden\" conjugation followed within 5 words by a past participle.\n * German word order is more flexible than English, so the window is wider.\n */\nfunction isGermanPassiveSentence(sentence: string): boolean {\n const words = sentence.toLowerCase().split(/\\s+/).filter(w => w.length > 0);\n\n for (let i = 0; i < words.length; i++) {\n const cleaned = words[i].replace(/[^a-zäöüß]/g, '');\n if (!GERMAN_PASSIVE_AUXILIARIES.has(cleaned)) continue;\n\n // Check next 5 words for a German past participle\n const searchEnd = Math.min(i + 6, words.length);\n for (let j = i + 1; j < searchEnd; j++) {\n const candidate = words[j].replace(/[^a-zäöüß]/g, '');\n if (candidate.length < 3) continue;\n if (GERMAN_PARTICIPLE_PATTERNS.some(p => p.test(candidate))) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Extract sentences with word counts from stripped markdown.\n *\n * @example\n * extractSentences(\"Hello world. How are you?\")\n * // [{ text: \"Hello world\", wordCount: 2 }, { text: \"How are you\", wordCount: 3 }]\n */\nexport function extractSentences(body: string): Array<{ text: string; wordCount: number }> {\n const stripped = stripMarkdown(body);\n const rawSentences = stripped.split(/(?<=[.!?])\\s+/);\n const sentences: Array<{ text: string; wordCount: number }> = [];\n\n for (const raw of rawSentences) {\n const text = raw.trim().replace(/[.!?]+$/, '').trim();\n if (!text) continue;\n const wordCount = text.split(/\\s+/).filter(w => w.length > 0 && /\\w/.test(w)).length;\n if (wordCount > 0) {\n sentences.push({ text, wordCount });\n }\n }\n\n return sentences;\n}\n\n/**\n * Find year references in body that are stale (>18 months from currentDate).\n *\n * @example\n * findStaleYearReferences(\"In 2020, things changed.\", new Date('2025-06-01'))\n * // [{ year: 2020, line: 1, isStale: true }]\n */\nexport function findStaleYearReferences(\n body: string,\n currentDate: Date,\n): Array<{ year: number; line: number; isStale: boolean }> {\n const lines = body.split('\\n');\n const yearPattern = /\\b((?:19|20)\\d{2})\\b/g;\n const results: Array<{ year: number; line: number; isStale: boolean }> = [];\n\n const cutoffDate = new Date(currentDate);\n cutoffDate.setMonth(cutoffDate.getMonth() - 18);\n\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n yearPattern.lastIndex = 0;\n\n while ((match = yearPattern.exec(line)) !== null) {\n const year = parseInt(match[1], 10);\n const yearEnd = new Date(year, 11, 31);\n const isStale = yearEnd < cutoffDate;\n results.push({ year, line: i + 1, isStale });\n }\n }\n\n return results;\n}\n\n/**\n * Detect sections opening with unresolved pronouns or back-references.\n * Flags sections whose first word is a pronoun like \"this\", \"it\", \"that\", etc.\n *\n * @example\n * detectUnresolvedOpenings([{ heading: \"Benefits\", body: \"This is important...\" }])\n * // [{ heading: \"Benefits\", firstWord: \"this\" }]\n */\nexport function detectUnresolvedOpenings(\n sections: Array<{ heading: string; body: string }>,\n): Array<{ heading: string; firstWord: string }> {\n const flagged: Array<{ heading: string; firstWord: string }> = [];\n\n for (const section of sections) {\n const bodyTrimmed = section.body.trim();\n if (!bodyTrimmed) continue;\n\n const firstLine = bodyTrimmed.split('\\n').find(l => l.trim().length > 0);\n if (!firstLine) continue;\n\n const lineText = firstLine.trim().toLowerCase();\n\n // Check phrase matches first\n const matchedPhrase = UNRESOLVED_PHRASES.find(p => lineText.startsWith(p));\n if (matchedPhrase) {\n flagged.push({ heading: section.heading, firstWord: matchedPhrase });\n continue;\n }\n\n // Check single-word pronouns\n const firstWord = lineText.split(/\\s+/)[0]?.replace(/[^a-z]/g, '') ?? '';\n if (UNRESOLVED_WORDS.has(firstWord)) {\n flagged.push({ heading: section.heading, firstWord });\n }\n }\n\n return flagged;\n}\n\n/**\n * Find acronyms not expanded on first use (not in allowlist).\n * Searches for uppercase sequences (2+ chars) and checks if the body\n * contains a parenthetical expansion pattern like \"Full Name (ACRONYM)\".\n *\n * @example\n * findUnexpandedAcronyms(\"Use GEO to improve visibility.\", [\"URL\", \"HTML\"])\n * // [{ acronym: \"GEO\", line: 1 }]\n */\nexport function findUnexpandedAcronyms(\n body: string,\n allowlist: string[],\n): Array<{ acronym: string; line: number }> {\n const allowSet = new Set(allowlist);\n const lines = body.split('\\n');\n const acronymPattern = /\\b([A-Z]{2,})\\b/g;\n const found = new Map<string, number>();\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n acronymPattern.lastIndex = 0;\n\n while ((match = acronymPattern.exec(line)) !== null) {\n const acronym = match[1];\n if (allowSet.has(acronym)) continue;\n if (!found.has(acronym)) {\n found.set(acronym, i + 1);\n }\n }\n }\n\n const results: Array<{ acronym: string; line: number }> = [];\n\n for (const [acronym, line] of found) {\n const expansionPattern = new RegExp(`\\\\(${acronym}\\\\)`, 'i');\n if (!expansionPattern.test(body)) {\n results.push({ acronym, line });\n }\n }\n\n return results;\n}\n\n/**\n * Find statistics/numbers without source context.\n * Checks for percentages and multipliers that lack nearby attribution.\n *\n * @example\n * findContextlessStatistics(\"Revenue grew 45% last year.\")\n * // [{ statistic: \"45%\", line: 1 }]\n */\nexport function findContextlessStatistics(\n body: string,\n): Array<{ statistic: string; line: number }> {\n const lines = body.split('\\n');\n const results: Array<{ statistic: string; line: number }> = [];\n const statPatterns = [/\\d+%/g, /\\d+x\\b/gi];\n const yearPattern = /\\b(?:19|20)\\d{2}\\b/;\n const linkPattern = /\\[[^\\]]+\\]\\([^)]+\\)/;\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n for (const pattern of statPatterns) {\n pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = pattern.exec(line)) !== null) {\n const position = match.index;\n const contextStart = Math.max(0, position - 100);\n const contextEnd = Math.min(line.length, position + match[0].length + 100);\n const surrounding = line.slice(contextStart, contextEnd).toLowerCase();\n\n const hasAttribution = ATTRIBUTION_MARKERS.some(m => surrounding.includes(m));\n const hasYear = yearPattern.test(surrounding);\n const hasLink = linkPattern.test(line.slice(contextStart, contextEnd));\n\n if (!hasAttribution && !hasYear && !hasLink) {\n results.push({ statistic: match[0], line: i + 1 });\n }\n }\n }\n }\n\n return results;\n}\n\n/**\n * Count structural elements in markdown: tables, lists, blockquotes, code blocks.\n * Returns total count of distinct structural element types found.\n *\n * @example\n * countStructuralElements(\"- item\\n\\n| col |\\n|---|\\n\\n> quote\") // 3\n */\nexport function countStructuralElements(body: string): number {\n const lines = body.split('\\n');\n let hasTable = false;\n let hasUnorderedList = false;\n let hasOrderedList = false;\n let hasBlockquote = false;\n let hasCodeBlock = false;\n let inCodeBlock = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n hasCodeBlock = true;\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n if (/\\|\\s*:?-{2,}/.test(trimmed)) hasTable = true;\n if (/^[-*]\\s+/.test(trimmed)) hasUnorderedList = true;\n if (/^\\d+\\.\\s+/.test(trimmed)) hasOrderedList = true;\n if (trimmed.startsWith('>')) hasBlockquote = true;\n }\n\n let count = 0;\n if (hasTable) count++;\n if (hasUnorderedList) count++;\n if (hasOrderedList) count++;\n if (hasBlockquote) count++;\n if (hasCodeBlock) count++;\n\n return count;\n}\n\n/**\n * Find raw HTML tags in markdown (excluding allowed MDX component tags).\n * MDX components are PascalCase; standard HTML tags (div, span, etc.) are flagged.\n *\n * @example\n * findInlineHtml(\"<div>text</div>\", [\"CustomComponent\"])\n * // [{ tag: \"div\", line: 1 }]\n */\nexport function findInlineHtml(\n body: string,\n allowedTags: string[],\n): Array<{ tag: string; line: number }> {\n const allowedSet = new Set(allowedTags);\n const lines = body.split('\\n');\n const results: Array<{ tag: string; line: number }> = [];\n const tagPattern = /<\\/?([a-zA-Z][a-zA-Z0-9]*)[^>]*>/g;\n let inCodeBlock = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {\n inCodeBlock = !inCodeBlock;\n continue;\n }\n if (inCodeBlock) continue;\n\n let match: RegExpExecArray | null;\n tagPattern.lastIndex = 0;\n\n while ((match = tagPattern.exec(line)) !== null) {\n const tagName = match[1];\n\n // Skip allowed tags (case-sensitive for MDX components)\n if (allowedSet.has(tagName)) continue;\n\n // Flag standard HTML tags (lowercase)\n if (STANDARD_HTML_TAGS.has(tagName.toLowerCase()) && tagName === tagName.toLowerCase()) {\n results.push({ tag: tagName, line: i + 1 });\n }\n }\n }\n\n return results;\n}\n\n/**\n * Analyze heading density -- find gaps > 300 words without a heading.\n * Returns gaps where the word count between consecutive headings exceeds 300.\n *\n * @example\n * analyzeHeadingDensity(\"## Intro\\n\\n\" + \"word \".repeat(350) + \"\\n\\n## Next\")\n * // { gaps: [{ afterHeading: \"Intro\", wordCount: 350, line: 1 }] }\n */\nexport function analyzeHeadingDensity(\n body: string,\n): { gaps: Array<{ afterHeading: string; wordCount: number; line: number }> } {\n const headings = extractHeadings(body);\n const lines = body.split('\\n');\n const gaps: Array<{ afterHeading: string; wordCount: number; line: number }> = [];\n\n if (headings.length === 0) {\n const totalWords = countWords(body);\n if (totalWords > 300) {\n gaps.push({ afterHeading: '(start)', wordCount: totalWords, line: 1 });\n }\n return { gaps };\n }\n\n // Check content before first heading\n const beforeFirst = lines.slice(0, headings[0].line - 1).join('\\n');\n const beforeWords = countWords(beforeFirst);\n if (beforeWords > 300) {\n gaps.push({ afterHeading: '(start)', wordCount: beforeWords, line: 1 });\n }\n\n // Check content between each heading pair\n for (let i = 0; i < headings.length; i++) {\n const currentLine = headings[i].line; // 1-indexed\n const nextLine = i + 1 < headings.length ? headings[i + 1].line : lines.length + 1;\n\n const sectionLines = lines.slice(currentLine, nextLine - 1);\n const sectionText = sectionLines.join('\\n');\n const wordCount = countWords(sectionText);\n\n if (wordCount > 300) {\n gaps.push({\n afterHeading: headings[i].text,\n wordCount,\n line: headings[i].line,\n });\n }\n }\n\n return { gaps };\n}\n","/**\n * Schema Rules\n * Validates structured data (schema.org) readiness for content frontmatter\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { hasFAQSection, hasMarkdownTable } from '../utils/geo-analyzer.js';\nimport { analyzeFaqQuality } from '../utils/geo-advanced-analyzer.js';\n\nconst MIN_FAQ_PAIRS_FOR_SCHEMA = 3;\nconst MIN_DATASET_DESCRIPTION_LENGTH = 100;\n\n/**\n * Rule: Blog posts should have fields required for rich BlogPosting schema\n * Checks for date, author, updatedAt, and image\n */\nexport const blogMissingSchemaFields: Rule = {\n name: 'blog-missing-schema-fields',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add date, author, updatedAt, and image fields to frontmatter for complete schema.org data',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') return [];\n\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'blog-missing-schema-fields';\n\n if (!item.date) {\n results.push({\n file, field: 'date', rule, severity: 'warning',\n message: 'Missing date — BlogPosting schema datePublished will be empty',\n suggestion: 'Add a date field (ISO format) for schema.org datePublished.',\n });\n }\n\n if (!item.author) {\n results.push({\n file, field: 'author', rule, severity: 'warning',\n message: 'Missing author — BlogPosting schema author will be empty',\n suggestion: 'Add an author field for complete Article/BlogPosting structured data.',\n });\n }\n\n if (!item.updatedAt) {\n results.push({\n file, field: 'updatedAt', rule, severity: 'warning',\n message: 'Missing updatedAt — BlogPosting schema dateModified will fall back to datePublished',\n suggestion: 'Add updatedAt field to frontmatter for accurate schema.org dateModified.',\n });\n }\n\n if (!item.image || item.image.trim().length === 0) {\n results.push({\n file, field: 'image', rule, severity: 'warning',\n message: 'Missing featured image — BlogPosting schema image will be empty',\n suggestion: 'Add an image field for complete BlogPosting structured data.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Content with FAQ sections should meet FAQPage schema requirements\n * Validates structure is sufficient for schema.org FAQPage emission\n */\nexport const faqpageSchemaReadiness: Rule = {\n name: 'faqpage-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add at least 3 Q&A pairs with question marks to the FAQ section',\n run: (item: ContentItem): LintResult[] => {\n if (!hasFAQSection(item.body)) return [];\n\n const faq = analyzeFaqQuality(item.body);\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'faqpage-schema-readiness';\n\n if (faq.pairCount < MIN_FAQ_PAIRS_FOR_SCHEMA) {\n results.push({\n file, field: 'body', rule, severity: 'warning',\n message: `FAQ section has ${faq.pairCount} Q&A pairs — FAQPage schema needs at least ${MIN_FAQ_PAIRS_FOR_SCHEMA}`,\n suggestion: `Add more Q&A pairs (H3 headings with answers) to enable FAQPage structured data.`,\n });\n }\n\n if (faq.pairCount > 0 && faq.questionsWithMark < faq.pairCount) {\n results.push({\n file, field: 'body', rule, severity: 'warning',\n message: `${faq.pairCount - faq.questionsWithMark}/${faq.pairCount} FAQ headings lack question marks — FAQPage schema expects questions`,\n suggestion: 'End all FAQ headings with a question mark for valid FAQPage structured data.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Content should have category data for BreadcrumbList schema\n * Checks that categories or category is populated for breadcrumb generation\n */\nexport const breadcrumblistSchemaReadiness: Rule = {\n name: 'breadcrumblist-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a categories array or category field to frontmatter for breadcrumb navigation',\n run: (item: ContentItem): LintResult[] => {\n const hasCategories = item.categories && item.categories.length > 0;\n const hasCategory = !!item.category;\n\n if (!hasCategories && !hasCategory) {\n return [{\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'breadcrumblist-schema-readiness',\n severity: 'warning',\n message: 'No category data — BreadcrumbList schema will lack breadcrumb path',\n suggestion: 'Add a categories array or category field for BreadcrumbList structured data.',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Data-heavy content with tables should have fields for Dataset schema\n * Only fires on project/page content that contains markdown tables\n */\nexport const datasetSchemaReadiness: Rule = {\n name: 'dataset-schema-readiness',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add a detailed description (100+ chars) and date field for Dataset schema readiness',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType === 'blog') return [];\n if (!hasMarkdownTable(item.body)) return [];\n\n const results: LintResult[] = [];\n const file = getDisplayPath(item);\n const rule = 'dataset-schema-readiness';\n\n if (item.description.length < MIN_DATASET_DESCRIPTION_LENGTH) {\n results.push({\n file, field: 'description', rule, severity: 'warning',\n message: `Description is too short for Dataset schema (${item.description.length}/${MIN_DATASET_DESCRIPTION_LENGTH} chars)`,\n suggestion: `Expand description to at least ${MIN_DATASET_DESCRIPTION_LENGTH} characters for rich Dataset structured data.`,\n });\n }\n\n if (!item.date) {\n results.push({\n file, field: 'date', rule, severity: 'warning',\n message: 'Missing date — Dataset schema dateModified will be empty',\n suggestion: 'Add a date field for Dataset schema temporal metadata.',\n });\n }\n\n return results;\n },\n};\n\nconst MIN_SAMEAS_ENTRIES = 2;\n\n/**\n * Rule: Organization schema sameAs array should have 2+ entries\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createSchemaSameAsRule(\n organizationSameAs: string[] | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'seo-schema-sameas-incomplete',\n severity: 'warning',\n category: 'seo',\n fixStrategy:\n 'Add social profiles (LinkedIn, GitHub, Twitter), Wikidata QID, and Crunchbase URL to Organization schema sameAs array',\n run: (_item: ContentItem): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // Not configured = skip (user hasn't declared sameAs)\n if (!organizationSameAs || organizationSameAs.length === 0) return [];\n\n if (organizationSameAs.length < MIN_SAMEAS_ENTRIES) {\n return [\n {\n file: '_site',\n field: 'schema',\n rule: 'seo-schema-sameas-incomplete',\n severity: 'warning',\n message: `Organization sameAs has ${organizationSameAs.length} entry — include at least ${MIN_SAMEAS_ENTRIES} for entity verification`,\n suggestion:\n 'AI models use sameAs to verify entity identity. Include at least LinkedIn + one other profile (GitHub, Wikidata QID, Crunchbase).',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/**\n * Rule: Service pages should have Service structured data\n * Checks if page URL matches a service page pattern and flags it for schema markup\n */\nexport function createServicePageSchemaRule(\n servicePagePatterns: string[] | undefined\n): Rule {\n return {\n name: 'seo-service-page-no-schema',\n severity: 'warning',\n category: 'seo',\n fixStrategy:\n 'Add Service structured data (JSON-LD) to service pages with name, description, provider, and areaServed.',\n run: (item: ContentItem): LintResult[] => {\n if (!servicePagePatterns || servicePagePatterns.length === 0) return [];\n\n const matchesPattern = servicePagePatterns.some((pattern) =>\n item.permalink.includes(pattern)\n );\n\n if (!matchesPattern) return [];\n\n return [\n {\n file: getDisplayPath(item),\n field: 'schema',\n rule: 'seo-service-page-no-schema',\n severity: 'warning',\n message: `Service page \"${item.permalink}\" should have Service structured data`,\n suggestion:\n 'Service pages need schema markup to appear in AI answers for \"[service] provider in [city]\" queries. Add Service JSON-LD with name, description, provider, and areaServed.',\n },\n ];\n },\n };\n}\n\n/** Static schema rules (no config dependency) */\nexport const schemaStaticRules: Rule[] = [\n blogMissingSchemaFields,\n faqpageSchemaReadiness,\n breadcrumblistSchemaReadiness,\n datasetSchemaReadiness,\n];\n\n/** Build the complete schema rule set from config */\nexport function createSchemaRules(geo: GeoConfig): Rule[] {\n return [\n ...schemaStaticRules,\n createSchemaSameAsRule(geo.organizationSameAs),\n createServicePageSchemaRule(geo.servicePagePatterns),\n ];\n}\n\n// Keep backward-compatible export\nexport const schemaRules = schemaStaticRules;\n","/**\n * Keyword Coherence Rules\n * Validates that title keywords appear in description and headings\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport { countWords } from '../utils/word-counter.js';\n\n/** Keyword coherence thresholds */\nconst MIN_SIGNIFICANT_WORDS = 2;\nconst MIN_WORD_LENGTH = 3;\nconst MIN_CONTENT_WORDS = 300;\n\n/**\n * Combined DE + EN stopwords (articles, prepositions, conjunctions, pronouns)\n * These are filtered out when extracting significant keywords from titles\n */\nconst STOPWORDS = new Set([\n // German\n 'der', 'die', 'das', 'ein', 'eine', 'einer', 'eines', 'einem', 'einen',\n 'und', 'oder', 'aber', 'als', 'auch', 'auf', 'aus', 'bei', 'bis',\n 'für', 'mit', 'nach', 'über', 'von', 'vor', 'wie', 'zum', 'zur',\n 'den', 'dem', 'des', 'ist', 'sind', 'war', 'hat', 'ihr', 'wir',\n 'sie', 'ich', 'nicht', 'sich', 'man', 'nur', 'noch', 'mehr',\n // English\n 'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can',\n 'her', 'was', 'one', 'our', 'out', 'has', 'had', 'its', 'his',\n 'how', 'who', 'what', 'why', 'when', 'where', 'which', 'with',\n 'this', 'that', 'from', 'they', 'been', 'have', 'will', 'your',\n 'into', 'than', 'them', 'then', 'some', 'each', 'make',\n]);\n\n/**\n * Extract significant words from text\n * Filters out stopwords and short words, normalizes to lowercase\n */\nfunction extractSignificantWords(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(word =>\n word.length >= MIN_WORD_LENGTH && !STOPWORDS.has(word)\n );\n}\n\n/**\n * Check if any keyword appears in a target text (case-insensitive)\n */\nfunction findMatchingKeywords(keywords: string[], targetText: string): string[] {\n const normalizedTarget = targetText.toLowerCase();\n return keywords.filter(keyword => normalizedTarget.includes(keyword));\n}\n\n/**\n * Rule: At least one title keyword should appear in the meta description\n * Improves click-through rate by ensuring title/description alignment\n */\nexport const keywordNotInDescription: Rule = {\n name: 'keyword-not-in-description',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Include at least one title keyword in the meta description',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || !item.description) return [];\n\n const keywords = extractSignificantWords(item.title);\n if (keywords.length < MIN_SIGNIFICANT_WORDS) return [];\n\n const matches = findMatchingKeywords(keywords, item.description);\n if (matches.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'keyword-not-in-description',\n severity: 'warning',\n message: `Description contains none of the title keywords: ${keywords.join(', ')}`,\n suggestion: 'Include at least one keyword from the title in the meta description for better SEO coherence',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: At least one title keyword should appear in H2/H3 headings\n * Only applies to blog/project content with sufficient length\n */\nexport const keywordNotInHeadings: Rule = {\n name: 'keyword-not-in-headings',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Include at least one title keyword in subheadings',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog' && item.contentType !== 'project') return [];\n if (!item.title || !item.body) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < MIN_CONTENT_WORDS) return [];\n\n const keywords = extractSignificantWords(item.title);\n if (keywords.length < MIN_SIGNIFICANT_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n if (subHeadings.length === 0) return [];\n\n const allHeadingText = subHeadings.map(h => h.text).join(' ');\n const matches = findMatchingKeywords(keywords, allHeadingText);\n\n if (matches.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'keyword-not-in-headings',\n severity: 'warning',\n message: `No title keywords found in H2/H3 headings: ${keywords.join(', ')}`,\n suggestion: 'Include at least one title keyword in your subheadings to reinforce topical relevance',\n }];\n }\n return [];\n },\n};\n\n/**\n * Rule: Title and description must share at least one significant word\n * Catches completely disconnected metadata that confuses search engines\n */\nexport const titleDescriptionNoOverlap: Rule = {\n name: 'title-description-no-overlap',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Ensure title and description share at least one keyword',\n run: (item: ContentItem): LintResult[] => {\n if (!item.title || !item.description) return [];\n\n const titleWords = extractSignificantWords(item.title);\n const descWords = new Set(extractSignificantWords(item.description));\n\n if (titleWords.length < MIN_SIGNIFICANT_WORDS) return [];\n if (descWords.size < MIN_SIGNIFICANT_WORDS) return [];\n\n const overlap = titleWords.filter(word => descWords.has(word));\n if (overlap.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'description',\n rule: 'title-description-no-overlap',\n severity: 'warning',\n message: 'Title and description share no significant words',\n suggestion: 'Title and description should be thematically connected. Ensure they share at least one keyword.',\n }];\n }\n return [];\n },\n};\n\n/**\n * All keyword coherence rules\n */\nexport const keywordCoherenceRules: Rule[] = [\n keywordNotInDescription,\n keywordNotInHeadings,\n titleDescriptionNoOverlap,\n];\n","/**\n * Link Validation Rules\n * Validates internal links resolve to existing pages\n *\n * These rules require a LinkExtractor instance (created per-project\n * with the site's internal URL patterns). Use the createLinkRules()\n * factory to build the rule set.\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { isValidInternalLink } from '../utils/slug-resolver.js';\n\n/**\n * Factory: Create link validation rules that use the provided LinkExtractor\n */\nexport function createLinkRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks, getInternalLinks, isAbsoluteInternalLink } = linkExtractor;\n\n /**\n * Rule: Internal links must resolve to existing pages\n */\n const brokenInternalLink: Rule = {\n name: 'broken-internal-link',\n severity: 'error',\n category: 'technical',\n fixStrategy: 'Fix the link target to point to an existing page',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n if (!isValidInternalLink(link.url, context.validSlugs)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'broken-internal-link',\n severity: 'error',\n message: `Broken internal link: ${link.url}`,\n suggestion: `Link \"${link.originalUrl}\" does not resolve to any known page`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links should use relative paths instead of absolute URLs\n */\n const absoluteInternalLink: Rule = {\n name: 'absolute-internal-link',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Use a relative path instead of an absolute URL',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal && isAbsoluteInternalLink(link.originalUrl)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'absolute-internal-link',\n severity: 'warning',\n message: `Absolute internal URL: ${link.originalUrl}`,\n suggestion: `Use relative path \"${link.url}\" instead for better portability`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links must not point to draft or noindex pages\n * Prevents publishing content that links to hidden pages\n */\n const draftLinkLeak: Rule = {\n name: 'draft-link-leak',\n severity: 'error',\n category: 'technical',\n fixStrategy: 'Remove or update link — the target page is not publicly visible',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n // Skip draft/noindex items — they aren't publicly visible\n if (item.draft || item.noindex) {\n return [];\n }\n\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n // Build set of permalinks for draft/noindex content\n const draftPermalinks = new Set<string>(\n context.allContent\n .filter(c => c.draft === true || c.noindex === true)\n .map(c => c.permalink)\n );\n\n for (const link of internalLinks) {\n if (draftPermalinks.has(link.url)) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'draft-link-leak',\n severity: 'error',\n message: `Internal link points to draft/noindex page: ${link.url}`,\n suggestion: `Remove or update link \"${link.originalUrl}\" — the target page is not publicly visible`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Internal links should not have trailing slashes\n * Ensures consistent URL formatting across the site\n */\n const trailingSlashInconsistency: Rule = {\n name: 'trailing-slash-inconsistency',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Remove the trailing slash from the internal link',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n // Check original URL (before normalization) for trailing slash\n // Skip root \"/\" which is fine\n const originalPath = link.originalUrl.split('?')[0].split('#')[0];\n if (originalPath !== '/' && originalPath.endsWith('/')) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'trailing-slash-inconsistency',\n severity: 'warning',\n message: `Internal link has trailing slash: ${link.originalUrl}`,\n suggestion: `Remove trailing slash: \"${originalPath.slice(0, -1)}\"`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n return [\n brokenInternalLink,\n absoluteInternalLink,\n draftLinkLeak,\n trailingSlashInconsistency,\n ];\n}\n","/**\n * External Link Validation Rules\n * Validates external URLs for correctness, security, and density\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\n\n/**\n * Outbound link density thresholds.\n * Minimum external links required scales with word count.\n */\nconst OUTBOUND_MIN_BASE = 3;\nconst OUTBOUND_WORDS_PER_EXTRA_LINK = 500;\nconst OUTBOUND_MIN_WORDS_TO_APPLY = 300;\n\n/**\n * Factory: Create external link validation rules that use the provided LinkExtractor\n */\nexport function createExternalLinkRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks } = linkExtractor;\n\n /**\n * Rule: External links must be well-formed URLs\n * Catches typos and malformed URLs before they reach production\n */\n const externalLinkMalformed: Rule = {\n name: 'external-link-malformed',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Check the URL for typos or missing protocol (https://)',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal) {\n continue;\n }\n\n try {\n new URL(link.url);\n } catch {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-malformed',\n severity: 'warning',\n message: `Malformed external URL: ${link.url}`,\n suggestion: 'Check the URL for typos or missing protocol (https://)',\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: External links should use HTTPS instead of HTTP\n * HTTP links are insecure and may trigger browser warnings\n */\n const externalLinkHttp: Rule = {\n name: 'external-link-http',\n severity: 'warning',\n category: 'technical',\n fixStrategy: 'Replace http:// with https://',\n run: (item: ContentItem): LintResult[] => {\n const results: LintResult[] = [];\n const links = extractLinks(item.body);\n\n for (const link of links) {\n if (link.isInternal) {\n continue;\n }\n\n // Check for http:// but exclude localhost for development links\n if (link.url.startsWith('http://') && !link.url.startsWith('http://localhost')) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-http',\n severity: 'warning',\n message: `Insecure HTTP link: ${link.url}`,\n suggestion: `Use HTTPS instead: \"${link.url.replace('http://', 'https://')}\"`,\n line: link.line,\n });\n }\n }\n\n return results;\n },\n };\n\n /**\n * Rule: Content should include enough outbound links to cite sources.\n * Minimum scales with article length: 3 for short articles,\n * +1 for every additional 500 words.\n */\n const externalLinkMinDensity: Rule = {\n name: 'external-link-low-density',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add outbound links to cite sources, reference tools, or link to studies',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') {\n return [];\n }\n\n const wordCount = countWords(item.body);\n if (wordCount < OUTBOUND_MIN_WORDS_TO_APPLY) {\n return [];\n }\n\n const links = extractLinks(item.body);\n const externalLinks = links.filter(link => !link.isInternal);\n const externalCount = externalLinks.length;\n\n const extraLinks = Math.max(\n 0,\n Math.floor((wordCount - OUTBOUND_MIN_WORDS_TO_APPLY) / OUTBOUND_WORDS_PER_EXTRA_LINK)\n );\n const requiredMin = OUTBOUND_MIN_BASE + extraLinks;\n\n if (externalCount < requiredMin) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'external-link-low-density',\n severity: 'warning',\n message: `Only ${externalCount} outbound link(s) for ${wordCount} words (minimum: ${requiredMin})`,\n suggestion: `Add ${requiredMin - externalCount} more outbound link(s) to cite sources, reference tools, or link to studies that support your claims.`,\n }];\n }\n\n return [];\n },\n };\n\n return [\n externalLinkMalformed,\n externalLinkHttp,\n externalLinkMinDensity,\n ];\n}\n","/**\n * Orphan Content Detection Rules\n * Identifies content that is not linked from any other page\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Normalize a permalink for comparison by removing trailing slashes\n */\nfunction normalizePermalink(permalink: string): string {\n if (permalink.length > 1 && permalink.endsWith('/')) {\n return permalink.slice(0, -1);\n }\n return permalink;\n}\n\n/**\n * Factory: Create orphan content detection rules that use the provided LinkExtractor\n */\nexport function createOrphanRules(linkExtractor: LinkExtractor): Rule[] {\n const { extractLinks, getInternalLinks } = linkExtractor;\n\n /**\n * Rule: Blog and project content should be linked from at least one other page\n * Orphan pages are hard to discover and receive less search engine traffic\n */\n const orphanContent: Rule = {\n name: 'orphan-content',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Add an internal link to this page from a related page',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n // Only check blog posts and projects\n if (item.contentType !== 'blog' && item.contentType !== 'project') {\n return [];\n }\n\n // Skip drafts and noindex content\n if (item.draft || item.noindex) {\n return [];\n }\n\n const itemPermalink = normalizePermalink(item.permalink);\n\n // Check if any other content item links to this item\n for (const other of context.allContent) {\n // Skip self\n if (other.slug === item.slug && other.contentType === item.contentType) {\n continue;\n }\n\n const links = extractLinks(other.body);\n const internalLinks = getInternalLinks(links);\n\n for (const link of internalLinks) {\n const normalizedLink = normalizePermalink(link.url);\n if (normalizedLink === itemPermalink) {\n // Found a link to this item — not orphaned\n return [];\n }\n }\n }\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'orphan-content',\n severity: 'warning',\n message: `No other content links to this ${item.contentType} post`,\n suggestion: `Add an internal link to \"${item.permalink}\" from a related page to improve discoverability`,\n }];\n },\n };\n\n return [orphanContent];\n}\n","/**\n * Top 5,000 most common English words\n * Source: google-10000-english (first20hours/google-10000-english)\n * Used for word complexity analysis — common words are not flagged as jargon.\n */\nexport const FREQUENCY_EN: ReadonlySet<string> = new Set([\n 'the', 'of', 'and', 'to', 'a', 'in', 'for', 'is', 'on', 'that', 'by', 'this', 'with', 'i', 'you', 'it', 'not', 'or', 'be', 'are', 'from', 'at', 'as', 'your', 'all', 'have', 'new', 'more', 'an', 'was', 'we', 'will', 'home', 'can', 'us', 'about', 'if', 'page', 'my', 'has',\n 'search', 'free', 'but', 'our', 'one', 'other', 'do', 'no', 'information', 'time', 'they', 'site', 'he', 'up', 'may', 'what', 'which', 'their', 'news', 'out', 'use', 'any', 'there', 'see', 'only', 'so', 'his', 'when', 'contact', 'here', 'business', 'who', 'web', 'also', 'now', 'help', 'get', 'pm', 'view', 'online',\n 'c', 'e', 'first', 'am', 'been', 'would', 'how', 'were', 'me', 's', 'services', 'some', 'these', 'click', 'its', 'like', 'service', 'x', 'than', 'find', 'price', 'date', 'back', 'top', 'people', 'had', 'list', 'name', 'just', 'over', 'state', 'year', 'day', 'into', 'email', 'two', 'health', 'n', 'world', 're',\n 'next', 'used', 'go', 'b', 'work', 'last', 'most', 'products', 'music', 'buy', 'data', 'make', 'them', 'should', 'product', 'system', 'post', 'her', 'city', 't', 'add', 'policy', 'number', 'such', 'please', 'available', 'copyright', 'support', 'message', 'after', 'best', 'software', 'then', 'jan', 'good', 'video', 'well', 'd', 'where', 'info',\n 'rights', 'public', 'books', 'high', 'school', 'through', 'm', 'each', 'links', 'she', 'review', 'years', 'order', 'very', 'privacy', 'book', 'items', 'company', 'r', 'read', 'group', 'need', 'many', 'user', 'said', 'de', 'does', 'set', 'under', 'general', 'research', 'university', 'january', 'mail', 'full', 'map', 'reviews', 'program', 'life', 'know',\n 'games', 'way', 'days', 'management', 'p', 'part', 'could', 'great', 'united', 'hotel', 'real', 'f', 'item', 'international', 'center', 'ebay', 'must', 'store', 'travel', 'comments', 'made', 'development', 'report', 'off', 'member', 'details', 'line', 'terms', 'before', 'hotels', 'did', 'send', 'right', 'type', 'because', 'local', 'those', 'using', 'results', 'office',\n 'education', 'national', 'car', 'design', 'take', 'posted', 'internet', 'address', 'community', 'within', 'states', 'area', 'want', 'phone', 'dvd', 'shipping', 'reserved', 'subject', 'between', 'forum', 'family', 'l', 'long', 'based', 'w', 'code', 'show', 'o', 'even', 'black', 'check', 'special', 'prices', 'website', 'index', 'being', 'women', 'much', 'sign', 'file',\n 'link', 'open', 'today', 'technology', 'south', 'case', 'project', 'same', 'pages', 'uk', 'version', 'section', 'own', 'found', 'sports', 'house', 'related', 'security', 'both', 'g', 'county', 'american', 'photo', 'game', 'members', 'power', 'while', 'care', 'network', 'down', 'computer', 'systems', 'three', 'total', 'place', 'end', 'following', 'download', 'h', 'him',\n 'without', 'per', 'access', 'think', 'north', 'resources', 'current', 'posts', 'big', 'media', 'law', 'control', 'water', 'history', 'pictures', 'size', 'art', 'personal', 'since', 'including', 'guide', 'shop', 'directory', 'board', 'location', 'change', 'white', 'text', 'small', 'rating', 'rate', 'government', 'children', 'during', 'usa', 'return', 'students', 'v', 'shopping', 'account',\n 'times', 'sites', 'level', 'digital', 'profile', 'previous', 'form', 'events', 'love', 'old', 'john', 'main', 'call', 'hours', 'image', 'department', 'title', 'description', 'non', 'k', 'y', 'insurance', 'another', 'why', 'shall', 'property', 'class', 'cd', 'still', 'money', 'quality', 'every', 'listing', 'content', 'country', 'private', 'little', 'visit', 'save', 'tools',\n 'low', 'reply', 'customer', 'december', 'compare', 'movies', 'include', 'college', 'value', 'article', 'york', 'man', 'card', 'jobs', 'provide', 'j', 'food', 'source', 'author', 'different', 'press', 'u', 'learn', 'sale', 'around', 'print', 'course', 'job', 'canada', 'process', 'teen', 'room', 'stock', 'training', 'too', 'credit', 'point', 'join', 'science', 'men',\n 'categories', 'advanced', 'west', 'sales', 'look', 'english', 'left', 'team', 'estate', 'box', 'conditions', 'select', 'windows', 'photos', 'gay', 'thread', 'week', 'category', 'note', 'live', 'large', 'gallery', 'table', 'register', 'however', 'june', 'october', 'november', 'market', 'library', 'really', 'action', 'start', 'series', 'model', 'features', 'air', 'industry', 'plan', 'human',\n 'provided', 'tv', 'yes', 'required', 'second', 'hot', 'accessories', 'cost', 'movie', 'forums', 'march', 'la', 'september', 'better', 'say', 'questions', 'july', 'yahoo', 'going', 'medical', 'test', 'friend', 'come', 'dec', 'server', 'pc', 'study', 'application', 'cart', 'staff', 'articles', 'san', 'feedback', 'again', 'play', 'looking', 'issues', 'april', 'never', 'users',\n 'complete', 'street', 'topic', 'comment', 'financial', 'things', 'working', 'against', 'standard', 'tax', 'person', 'below', 'mobile', 'less', 'got', 'blog', 'party', 'payment', 'equipment', 'login', 'student', 'let', 'programs', 'offers', 'legal', 'above', 'recent', 'park', 'stores', 'side', 'act', 'problem', 'red', 'give', 'memory', 'performance', 'social', 'q', 'august', 'quote',\n 'language', 'story', 'sell', 'options', 'experience', 'rates', 'create', 'key', 'body', 'young', 'america', 'important', 'field', 'few', 'east', 'paper', 'single', 'ii', 'age', 'activities', 'club', 'example', 'girls', 'additional', 'password', 'z', 'latest', 'something', 'road', 'gift', 'question', 'changes', 'night', 'ca', 'hard', 'texas', 'oct', 'pay', 'four', 'poker',\n 'status', 'browse', 'issue', 'range', 'building', 'seller', 'court', 'february', 'always', 'result', 'audio', 'light', 'write', 'war', 'nov', 'offer', 'blue', 'groups', 'al', 'easy', 'given', 'files', 'event', 'release', 'analysis', 'request', 'fax', 'china', 'making', 'picture', 'needs', 'possible', 'might', 'professional', 'yet', 'month', 'major', 'star', 'areas', 'future',\n 'space', 'committee', 'hand', 'sun', 'cards', 'problems', 'london', 'washington', 'meeting', 'rss', 'become', 'interest', 'id', 'child', 'keep', 'enter', 'california', 'share', 'similar', 'garden', 'schools', 'million', 'added', 'reference', 'companies', 'listed', 'baby', 'learning', 'energy', 'run', 'delivery', 'net', 'popular', 'term', 'film', 'stories', 'put', 'computers', 'journal', 'reports',\n 'co', 'try', 'welcome', 'central', 'images', 'president', 'notice', 'original', 'head', 'radio', 'until', 'cell', 'color', 'self', 'council', 'away', 'includes', 'track', 'australia', 'discussion', 'archive', 'once', 'others', 'entertainment', 'agreement', 'format', 'least', 'society', 'months', 'log', 'safety', 'friends', 'sure', 'faq', 'trade', 'edition', 'cars', 'messages', 'marketing', 'tell',\n 'further', 'updated', 'association', 'able', 'having', 'provides', 'david', 'fun', 'already', 'green', 'studies', 'close', 'common', 'drive', 'specific', 'several', 'gold', 'feb', 'living', 'sep', 'collection', 'called', 'short', 'arts', 'lot', 'ask', 'display', 'limited', 'powered', 'solutions', 'means', 'director', 'daily', 'beach', 'past', 'natural', 'whether', 'due', 'et', 'electronics',\n 'five', 'upon', 'period', 'planning', 'database', 'says', 'official', 'weather', 'mar', 'land', 'average', 'done', 'technical', 'window', 'france', 'pro', 'region', 'island', 'record', 'direct', 'microsoft', 'conference', 'environment', 'records', 'st', 'district', 'calendar', 'costs', 'style', 'url', 'front', 'statement', 'update', 'parts', 'aug', 'ever', 'downloads', 'early', 'miles', 'sound',\n 'resource', 'present', 'applications', 'either', 'ago', 'document', 'word', 'works', 'material', 'bill', 'apr', 'written', 'talk', 'federal', 'hosting', 'rules', 'final', 'adult', 'tickets', 'thing', 'centre', 'requirements', 'via', 'cheap', 'kids', 'finance', 'true', 'minutes', 'else', 'mark', 'third', 'rock', 'gifts', 'europe', 'reading', 'topics', 'bad', 'individual', 'tips', 'plus',\n 'auto', 'cover', 'usually', 'edit', 'together', 'videos', 'percent', 'fast', 'function', 'fact', 'unit', 'getting', 'global', 'tech', 'meet', 'far', 'economic', 'en', 'player', 'projects', 'lyrics', 'often', 'subscribe', 'submit', 'germany', 'amount', 'watch', 'included', 'feel', 'though', 'bank', 'risk', 'thanks', 'everything', 'deals', 'various', 'words', 'linux', 'jul', 'production',\n 'commercial', 'james', 'weight', 'town', 'heart', 'advertising', 'received', 'choose', 'treatment', 'newsletter', 'archives', 'points', 'knowledge', 'magazine', 'error', 'camera', 'jun', 'girl', 'currently', 'construction', 'toys', 'registered', 'clear', 'golf', 'receive', 'domain', 'methods', 'chapter', 'makes', 'protection', 'policies', 'loan', 'wide', 'beauty', 'manager', 'india', 'position', 'taken', 'sort', 'listings',\n 'models', 'michael', 'known', 'half', 'cases', 'step', 'engineering', 'florida', 'simple', 'quick', 'none', 'wireless', 'license', 'paul', 'friday', 'lake', 'whole', 'annual', 'published', 'later', 'basic', 'sony', 'shows', 'corporate', 'google', 'church', 'method', 'purchase', 'customers', 'active', 'response', 'practice', 'hardware', 'figure', 'materials', 'fire', 'holiday', 'chat', 'enough', 'designed',\n 'along', 'among', 'death', 'writing', 'speed', 'html', 'countries', 'loss', 'face', 'brand', 'discount', 'higher', 'effects', 'created', 'remember', 'standards', 'oil', 'bit', 'yellow', 'political', 'increase', 'advertise', 'kingdom', 'base', 'near', 'environmental', 'thought', 'stuff', 'french', 'storage', 'oh', 'japan', 'doing', 'loans', 'shoes', 'entry', 'stay', 'nature', 'orders', 'availability',\n 'africa', 'summary', 'turn', 'mean', 'growth', 'notes', 'agency', 'king', 'monday', 'european', 'activity', 'copy', 'although', 'drug', 'pics', 'western', 'income', 'force', 'cash', 'employment', 'overall', 'bay', 'river', 'commission', 'ad', 'package', 'contents', 'seen', 'players', 'engine', 'port', 'album', 'regional', 'stop', 'supplies', 'started', 'administration', 'bar', 'institute', 'views',\n 'plans', 'double', 'dog', 'build', 'screen', 'exchange', 'types', 'soon', 'sponsored', 'lines', 'electronic', 'continue', 'across', 'benefits', 'needed', 'season', 'apply', 'someone', 'held', 'ny', 'anything', 'printer', 'condition', 'effective', 'believe', 'organization', 'effect', 'asked', 'eur', 'mind', 'sunday', 'selection', 'casino', 'pdf', 'lost', 'tour', 'menu', 'volume', 'cross', 'anyone',\n 'mortgage', 'hope', 'silver', 'corporation', 'wish', 'inside', 'solution', 'mature', 'role', 'rather', 'weeks', 'addition', 'came', 'supply', 'nothing', 'certain', 'usr', 'executive', 'running', 'lower', 'necessary', 'union', 'jewelry', 'according', 'dc', 'clothing', 'mon', 'com', 'particular', 'fine', 'names', 'robert', 'homepage', 'hour', 'gas', 'skills', 'six', 'bush', 'islands', 'advice',\n 'career', 'military', 'rental', 'decision', 'leave', 'british', 'teens', 'pre', 'huge', 'sat', 'woman', 'facilities', 'zip', 'bid', 'kind', 'sellers', 'middle', 'move', 'cable', 'opportunities', 'taking', 'values', 'division', 'coming', 'tuesday', 'object', 'lesbian', 'appropriate', 'machine', 'logo', 'length', 'actually', 'nice', 'score', 'statistics', 'client', 'ok', 'returns', 'capital', 'follow',\n 'sample', 'investment', 'sent', 'shown', 'saturday', 'christmas', 'england', 'culture', 'band', 'flash', 'ms', 'lead', 'george', 'choice', 'went', 'starting', 'registration', 'fri', 'thursday', 'courses', 'consumer', 'hi', 'airport', 'foreign', 'artist', 'outside', 'furniture', 'levels', 'channel', 'letter', 'mode', 'phones', 'ideas', 'wednesday', 'structure', 'fund', 'summer', 'allow', 'degree', 'contract',\n 'button', 'releases', 'wed', 'homes', 'super', 'male', 'matter', 'custom', 'virginia', 'almost', 'took', 'located', 'multiple', 'asian', 'distribution', 'editor', 'inn', 'industrial', 'cause', 'potential', 'song', 'cnet', 'ltd', 'los', 'hp', 'focus', 'late', 'fall', 'featured', 'idea', 'rooms', 'female', 'responsible', 'inc', 'communications', 'win', 'associated', 'thomas', 'primary', 'cancer',\n 'numbers', 'reason', 'tool', 'browser', 'spring', 'foundation', 'answer', 'voice', 'eg', 'friendly', 'schedule', 'documents', 'communication', 'purpose', 'feature', 'bed', 'comes', 'police', 'everyone', 'independent', 'ip', 'approach', 'cameras', 'brown', 'physical', 'operating', 'hill', 'maps', 'medicine', 'deal', 'hold', 'ratings', 'chicago', 'forms', 'glass', 'happy', 'tue', 'smith', 'wanted', 'developed',\n 'thank', 'safe', 'unique', 'survey', 'prior', 'telephone', 'sport', 'ready', 'feed', 'animal', 'sources', 'mexico', 'population', 'pa', 'regular', 'secure', 'navigation', 'operations', 'therefore', 'simply', 'evidence', 'station', 'christian', 'round', 'paypal', 'favorite', 'understand', 'option', 'master', 'valley', 'recently', 'probably', 'thu', 'rentals', 'sea', 'built', 'publications', 'blood', 'cut', 'worldwide',\n 'improve', 'connection', 'publisher', 'hall', 'larger', 'anti', 'networks', 'earth', 'parents', 'nokia', 'impact', 'transfer', 'introduction', 'kitchen', 'strong', 'tel', 'carolina', 'wedding', 'properties', 'hospital', 'ground', 'overview', 'ship', 'accommodation', 'owners', 'disease', 'tx', 'excellent', 'paid', 'italy', 'perfect', 'hair', 'opportunity', 'kit', 'classic', 'basis', 'command', 'cities', 'william', 'express',\n 'award', 'distance', 'tree', 'peter', 'assessment', 'ensure', 'thus', 'wall', 'ie', 'involved', 'el', 'extra', 'especially', 'interface', 'partners', 'budget', 'rated', 'guides', 'success', 'maximum', 'ma', 'operation', 'existing', 'quite', 'selected', 'boy', 'amazon', 'patients', 'restaurants', 'beautiful', 'warning', 'wine', 'locations', 'horse', 'vote', 'forward', 'flowers', 'stars', 'significant', 'lists',\n 'technologies', 'owner', 'retail', 'animals', 'useful', 'directly', 'manufacturer', 'ways', 'est', 'son', 'providing', 'rule', 'mac', 'housing', 'takes', 'iii', 'gmt', 'bring', 'catalog', 'searches', 'max', 'trying', 'mother', 'authority', 'considered', 'told', 'xml', 'traffic', 'programme', 'joined', 'input', 'strategy', 'feet', 'agent', 'valid', 'bin', 'modern', 'senior', 'ireland', 'teaching',\n 'door', 'grand', 'testing', 'trial', 'charge', 'units', 'instead', 'canadian', 'cool', 'normal', 'wrote', 'enterprise', 'ships', 'entire', 'educational', 'md', 'leading', 'metal', 'positive', 'fl', 'fitness', 'chinese', 'opinion', 'mb', 'asia', 'football', 'abstract', 'uses', 'output', 'funds', 'mr', 'greater', 'likely', 'develop', 'employees', 'artists', 'alternative', 'processing', 'responsibility', 'resolution',\n 'java', 'guest', 'seems', 'publication', 'pass', 'relations', 'trust', 'van', 'contains', 'session', 'multi', 'photography', 'republic', 'fees', 'components', 'vacation', 'century', 'academic', 'assistance', 'completed', 'skin', 'graphics', 'indian', 'prev', 'ads', 'mary', 'il', 'expected', 'ring', 'grade', 'dating', 'pacific', 'mountain', 'organizations', 'pop', 'filter', 'mailing', 'vehicle', 'longer', 'consider',\n 'int', 'northern', 'behind', 'panel', 'floor', 'german', 'buying', 'match', 'proposed', 'default', 'require', 'iraq', 'boys', 'outdoor', 'deep', 'morning', 'otherwise', 'allows', 'rest', 'protein', 'plant', 'reported', 'hit', 'transportation', 'mm', 'pool', 'mini', 'politics', 'partner', 'disclaimer', 'authors', 'boards', 'faculty', 'parties', 'fish', 'membership', 'mission', 'eye', 'string', 'sense',\n 'modified', 'pack', 'released', 'stage', 'internal', 'goods', 'recommended', 'born', 'unless', 'richard', 'detailed', 'japanese', 'race', 'approved', 'background', 'target', 'except', 'character', 'usb', 'maintenance', 'ability', 'maybe', 'functions', 'ed', 'moving', 'brands', 'places', 'php', 'pretty', 'trademarks', 'phentermine', 'spain', 'southern', 'yourself', 'etc', 'winter', 'battery', 'youth', 'pressure', 'submitted',\n 'boston', 'debt', 'keywords', 'medium', 'television', 'interested', 'core', 'break', 'purposes', 'throughout', 'sets', 'dance', 'wood', 'msn', 'itself', 'defined', 'papers', 'playing', 'awards', 'fee', 'studio', 'reader', 'virtual', 'device', 'established', 'answers', 'rent', 'las', 'remote', 'dark', 'programming', 'external', 'apple', 'le', 'regarding', 'instructions', 'min', 'offered', 'theory', 'enjoy',\n 'remove', 'aid', 'surface', 'minimum', 'visual', 'host', 'variety', 'teachers', 'isbn', 'martin', 'manual', 'block', 'subjects', 'agents', 'increased', 'repair', 'fair', 'civil', 'steel', 'understanding', 'songs', 'fixed', 'wrong', 'beginning', 'hands', 'associates', 'finally', 'az', 'updates', 'desktop', 'classes', 'paris', 'ohio', 'gets', 'sector', 'capacity', 'requires', 'jersey', 'un', 'fat',\n 'fully', 'father', 'electric', 'saw', 'instruments', 'quotes', 'officer', 'driver', 'businesses', 'dead', 'respect', 'unknown', 'specified', 'restaurant', 'mike', 'trip', 'pst', 'worth', 'mi', 'procedures', 'poor', 'teacher', 'eyes', 'relationship', 'workers', 'farm', 'georgia', 'peace', 'traditional', 'campus', 'tom', 'showing', 'creative', 'coast', 'benefit', 'progress', 'funding', 'devices', 'lord', 'grant',\n 'sub', 'agree', 'fiction', 'hear', 'sometimes', 'watches', 'careers', 'beyond', 'goes', 'families', 'led', 'museum', 'themselves', 'fan', 'transport', 'interesting', 'blogs', 'wife', 'evaluation', 'accepted', 'former', 'implementation', 'ten', 'hits', 'zone', 'complex', 'th', 'cat', 'galleries', 'references', 'die', 'presented', 'jack', 'flat', 'flow', 'agencies', 'literature', 'respective', 'parent', 'spanish',\n 'michigan', 'columbia', 'setting', 'dr', 'scale', 'stand', 'economy', 'highest', 'helpful', 'monthly', 'critical', 'frame', 'musical', 'definition', 'secretary', 'angeles', 'networking', 'path', 'australian', 'employee', 'chief', 'gives', 'kb', 'bottom', 'magazines', 'packages', 'detail', 'francisco', 'laws', 'changed', 'pet', 'heard', 'begin', 'individuals', 'colorado', 'royal', 'clean', 'switch', 'russian', 'largest',\n 'african', 'guy', 'titles', 'relevant', 'guidelines', 'justice', 'connect', 'bible', 'dev', 'cup', 'basket', 'applied', 'weekly', 'vol', 'installation', 'described', 'demand', 'pp', 'suite', 'vegas', 'na', 'square', 'chris', 'attention', 'advance', 'skip', 'diet', 'army', 'auction', 'gear', 'lee', 'os', 'difference', 'allowed', 'correct', 'charles', 'nation', 'selling', 'lots', 'piece',\n 'sheet', 'firm', 'seven', 'older', 'illinois', 'regulations', 'elements', 'species', 'jump', 'cells', 'module', 'resort', 'facility', 'random', 'pricing', 'dvds', 'certificate', 'minister', 'motion', 'looks', 'fashion', 'directions', 'visitors', 'documentation', 'monitor', 'trading', 'forest', 'calls', 'whose', 'coverage', 'couple', 'giving', 'chance', 'vision', 'ball', 'ending', 'clients', 'actions', 'listen', 'discuss',\n 'accept', 'automotive', 'naked', 'goal', 'successful', 'sold', 'wind', 'communities', 'clinical', 'situation', 'sciences', 'markets', 'lowest', 'highly', 'publishing', 'appear', 'emergency', 'developing', 'lives', 'currency', 'leather', 'determine', 'temperature', 'palm', 'announcements', 'patient', 'actual', 'historical', 'stone', 'bob', 'commerce', 'ringtones', 'perhaps', 'persons', 'difficult', 'scientific', 'satellite', 'fit', 'tests', 'village',\n 'accounts', 'amateur', 'ex', 'met', 'pain', 'xbox', 'particularly', 'factors', 'coffee', 'www', 'settings', 'buyer', 'cultural', 'steve', 'easily', 'oral', 'ford', 'poster', 'edge', 'functional', 'root', 'au', 'fi', 'closed', 'holidays', 'ice', 'pink', 'zealand', 'balance', 'monitoring', 'graduate', 'replies', 'shot', 'nc', 'architecture', 'initial', 'label', 'thinking', 'scott', 'llc',\n 'sec', 'recommend', 'canon', 'league', 'waste', 'minute', 'bus', 'provider', 'optional', 'dictionary', 'cold', 'accounting', 'manufacturing', 'sections', 'chair', 'fishing', 'effort', 'phase', 'fields', 'bag', 'fantasy', 'po', 'letters', 'motor', 'va', 'professor', 'context', 'install', 'shirt', 'apparel', 'generally', 'continued', 'foot', 'mass', 'crime', 'count', 'breast', 'techniques', 'ibm', 'rd',\n 'johnson', 'sc', 'quickly', 'dollars', 'websites', 'religion', 'claim', 'driving', 'permission', 'surgery', 'patch', 'heat', 'wild', 'measures', 'generation', 'kansas', 'miss', 'chemical', 'doctor', 'task', 'reduce', 'brought', 'himself', 'nor', 'component', 'enable', 'exercise', 'bug', 'santa', 'mid', 'guarantee', 'leader', 'diamond', 'israel', 'se', 'processes', 'soft', 'servers', 'alone', 'meetings',\n 'seconds', 'jones', 'arizona', 'keyword', 'interests', 'flight', 'congress', 'fuel', 'username', 'walk', 'produced', 'italian', 'paperback', 'classifieds', 'wait', 'supported', 'pocket', 'saint', 'rose', 'freedom', 'argument', 'competition', 'creating', 'jim', 'drugs', 'joint', 'premium', 'providers', 'fresh', 'characters', 'attorney', 'upgrade', 'di', 'factor', 'growing', 'thousands', 'km', 'stream', 'apartments', 'pick',\n 'hearing', 'eastern', 'auctions', 'therapy', 'entries', 'dates', 'generated', 'signed', 'upper', 'administrative', 'serious', 'prime', 'samsung', 'limit', 'began', 'louis', 'steps', 'errors', 'shops', 'del', 'efforts', 'informed', 'ga', 'ac', 'thoughts', 'creek', 'ft', 'worked', 'quantity', 'urban', 'practices', 'sorted', 'reporting', 'essential', 'myself', 'tours', 'platform', 'load', 'affiliate', 'labor',\n 'immediately', 'admin', 'nursing', 'defense', 'machines', 'designated', 'tags', 'heavy', 'covered', 'recovery', 'joe', 'guys', 'integrated', 'configuration', 'merchant', 'comprehensive', 'expert', 'universal', 'protect', 'drop', 'solid', 'cds', 'presentation', 'languages', 'became', 'orange', 'compliance', 'vehicles', 'prevent', 'theme', 'rich', 'im', 'campaign', 'marine', 'improvement', 'vs', 'guitar', 'finding', 'pennsylvania', 'examples',\n 'ipod', 'saying', 'spirit', 'ar', 'claims', 'challenge', 'motorola', 'acceptance', 'strategies', 'mo', 'seem', 'affairs', 'touch', 'intended', 'towards', 'sa', 'goals', 'hire', 'election', 'suggest', 'branch', 'charges', 'serve', 'affiliates', 'reasons', 'magic', 'mount', 'smart', 'talking', 'gave', 'ones', 'latin', 'multimedia', 'xp', 'avoid', 'certified', 'manage', 'corner', 'rank', 'computing',\n 'oregon', 'element', 'birth', 'virus', 'abuse', 'interactive', 'requests', 'separate', 'quarter', 'procedure', 'leadership', 'tables', 'define', 'racing', 'religious', 'facts', 'breakfast', 'kong', 'column', 'plants', 'faith', 'chain', 'developer', 'identify', 'avenue', 'missing', 'died', 'approximately', 'domestic', 'sitemap', 'recommendations', 'moved', 'houston', 'reach', 'comparison', 'mental', 'viewed', 'moment', 'extended', 'sequence',\n 'inch', 'attack', 'sorry', 'centers', 'opening', 'damage', 'lab', 'reserve', 'recipes', 'cvs', 'gamma', 'plastic', 'produce', 'snow', 'placed', 'truth', 'counter', 'failure', 'follows', 'eu', 'weekend', 'dollar', 'camp', 'ontario', 'automatically', 'des', 'minnesota', 'films', 'bridge', 'native', 'fill', 'williams', 'movement', 'printing', 'baseball', 'owned', 'approval', 'draft', 'chart', 'played',\n 'contacts', 'cc', 'jesus', 'readers', 'clubs', 'lcd', 'wa', 'jackson', 'equal', 'adventure', 'matching', 'offering', 'shirts', 'profit', 'leaders', 'posters', 'institutions', 'assistant', 'variable', 'ave', 'dj', 'advertisement', 'expect', 'parking', 'headlines', 'yesterday', 'compared', 'determined', 'wholesale', 'workshop', 'russia', 'gone', 'codes', 'kinds', 'extension', 'seattle', 'statements', 'golden', 'completely', 'teams',\n 'fort', 'cm', 'wi', 'lighting', 'senate', 'forces', 'funny', 'brother', 'gene', 'turned', 'portable', 'tried', 'electrical', 'applicable', 'disc', 'returned', 'pattern', 'ct', 'boat', 'named', 'theatre', 'laser', 'earlier', 'manufacturers', 'sponsor', 'classical', 'icon', 'warranty', 'dedicated', 'indiana', 'direction', 'harry', 'basketball', 'objects', 'ends', 'delete', 'evening', 'assembly', 'nuclear', 'taxes',\n 'mouse', 'signal', 'criminal', 'issued', 'brain', 'sexual', 'wisconsin', 'powerful', 'dream', 'obtained', 'false', 'da', 'cast', 'flower', 'felt', 'personnel', 'passed', 'supplied', 'identified', 'falls', 'pic', 'soul', 'aids', 'opinions', 'promote', 'stated', 'stats', 'hawaii', 'professionals', 'appears', 'carry', 'flag', 'decided', 'nj', 'covers', 'hr', 'em', 'advantage', 'hello', 'designs',\n 'maintain', 'tourism', 'priority', 'newsletters', 'adults', 'clips', 'savings', 'iv', 'graphic', 'atom', 'payments', 'rw', 'estimated', 'binding', 'brief', 'ended', 'winning', 'eight', 'anonymous', 'iron', 'straight', 'script', 'served', 'wants', 'miscellaneous', 'prepared', 'void', 'dining', 'alert', 'integration', 'atlanta', 'dakota', 'tag', 'interview', 'mix', 'framework', 'disk', 'installed', 'queen', 'vhs',\n 'credits', 'clearly', 'fix', 'handle', 'sweet', 'desk', 'criteria', 'pubmed', 'dave', 'massachusetts', 'diego', 'hong', 'vice', 'associate', 'ne', 'truck', 'behavior', 'enlarge', 'ray', 'frequently', 'revenue', 'measure', 'changing', 'votes', 'du', 'duty', 'looked', 'discussions', 'bear', 'gain', 'festival', 'laboratory', 'ocean', 'flights', 'experts', 'signs', 'lack', 'depth', 'iowa', 'whatever',\n 'logged', 'laptop', 'vintage', 'train', 'exactly', 'dry', 'explore', 'maryland', 'spa', 'concept', 'nearly', 'eligible', 'checkout', 'reality', 'forgot', 'handling', 'origin', 'knew', 'gaming', 'feeds', 'billion', 'destination', 'scotland', 'faster', 'intelligence', 'dallas', 'bought', 'con', 'ups', 'nations', 'route', 'followed', 'specifications', 'broken', 'tripadvisor', 'frank', 'alaska', 'zoom', 'blow', 'battle',\n 'residential', 'anime', 'speak', 'decisions', 'industries', 'protocol', 'query', 'clip', 'partnership', 'editorial', 'nt', 'expression', 'es', 'equity', 'provisions', 'speech', 'wire', 'principles', 'suggestions', 'rural', 'shared', 'sounds', 'replacement', 'tape', 'strategic', 'judge', 'spam', 'economics', 'acid', 'bytes', 'cent', 'forced', 'compatible', 'fight', 'apartment', 'height', 'null', 'zero', 'speaker', 'filed',\n 'gb', 'netherlands', 'obtain', 'bc', 'consulting', 'recreation', 'offices', 'designer', 'remain', 'managed', 'pr', 'failed', 'marriage', 'roll', 'korea', 'banks', 'fr', 'participants', 'secret', 'bath', 'aa', 'kelly', 'leads', 'negative', 'austin', 'favorites', 'toronto', 'theater', 'springs', 'missouri', 'andrew', 'var', 'perform', 'healthy', 'translation', 'estimates', 'font', 'assets', 'injury', 'mt',\n 'joseph', 'ministry', 'drivers', 'lawyer', 'figures', 'married', 'protected', 'proposal', 'sharing', 'philadelphia', 'portal', 'waiting', 'birthday', 'beta', 'fail', 'gratis', 'banking', 'officials', 'brian', 'toward', 'won', 'slightly', 'assist', 'conduct', 'contained', 'lingerie', 'legislation', 'calling', 'parameters', 'jazz', 'serving', 'bags', 'profiles', 'miami', 'comics', 'matters', 'houses', 'doc', 'postal', 'relationships',\n 'tennessee', 'wear', 'controls', 'breaking', 'combined', 'ultimate', 'wales', 'representative', 'frequency', 'introduced', 'minor', 'finish', 'departments', 'residents', 'noted', 'displayed', 'mom', 'reduced', 'physics', 'rare', 'spent', 'performed', 'extreme', 'samples', 'davis', 'daniel', 'bars', 'reviewed', 'row', 'oz', 'forecast', 'removed', 'helps', 'singles', 'administrator', 'cycle', 'amounts', 'contain', 'accuracy', 'dual',\n 'rise', 'usd', 'sleep', 'mg', 'bird', 'pharmacy', 'brazil', 'creation', 'static', 'scene', 'hunter', 'addresses', 'lady', 'crystal', 'famous', 'writer', 'chairman', 'violence', 'fans', 'oklahoma', 'speakers', 'drink', 'academy', 'dynamic', 'gender', 'eat', 'permanent', 'agriculture', 'dell', 'cleaning', 'constitutes', 'portfolio', 'practical', 'delivered', 'collectibles', 'infrastructure', 'exclusive', 'seat', 'concerns', 'colour',\n 'vendor', 'originally', 'intel', 'utilities', 'philosophy', 'regulation', 'officers', 'reduction', 'aim', 'bids', 'referred', 'supports', 'nutrition', 'recording', 'regions', 'junior', 'toll', 'les', 'cape', 'ann', 'rings', 'meaning', 'tip', 'secondary', 'wonderful', 'mine', 'ladies', 'henry', 'ticket', 'announced', 'guess', 'agreed', 'prevention', 'whom', 'ski', 'soccer', 'math', 'import', 'posting', 'presence',\n 'instant', 'mentioned', 'automatic', 'healthcare', 'viewing', 'maintained', 'ch', 'increasing', 'majority', 'connected', 'christ', 'dan', 'dogs', 'sd', 'directors', 'aspects', 'austria', 'ahead', 'moon', 'participation', 'scheme', 'utility', 'preview', 'fly', 'manner', 'matrix', 'containing', 'combination', 'devel', 'amendment', 'despite', 'strength', 'guaranteed', 'turkey', 'libraries', 'proper', 'distributed', 'degrees', 'singapore', 'enterprises',\n 'delta', 'fear', 'seeking', 'inches', 'phoenix', 'rs', 'convention', 'shares', 'principal', 'daughter', 'standing', 'comfort', 'colors', 'wars', 'cisco', 'ordering', 'kept', 'alpha', 'appeal', 'cruise', 'bonus', 'certification', 'previously', 'hey', 'bookmark', 'buildings', 'specials', 'beat', 'disney', 'household', 'batteries', 'adobe', 'smoking', 'bbc', 'becomes', 'drives', 'arms', 'alabama', 'tea', 'improved',\n 'trees', 'avg', 'achieve', 'positions', 'dress', 'subscription', 'dealer', 'contemporary', 'sky', 'utah', 'nearby', 'rom', 'carried', 'happen', 'exposure', 'panasonic', 'hide', 'permalink', 'signature', 'gambling', 'refer', 'miller', 'provision', 'outdoors', 'clothes', 'caused', 'luxury', 'babes', 'frames', 'certainly', 'indeed', 'newspaper', 'toy', 'circuit', 'layer', 'printed', 'slow', 'removal', 'easier', 'src',\n 'liability', 'trademark', 'hip', 'printers', 'faqs', 'nine', 'adding', 'kentucky', 'mostly', 'eric', 'spot', 'taylor', 'trackback', 'prints', 'spend', 'factory', 'interior', 'revised', 'grow', 'americans', 'optical', 'promotion', 'relative', 'amazing', 'clock', 'dot', 'hiv', 'identity', 'suites', 'conversion', 'feeling', 'hidden', 'reasonable', 'victoria', 'serial', 'relief', 'revision', 'broadband', 'influence', 'ratio',\n 'pda', 'importance', 'rain', 'onto', 'dsl', 'planet', 'webmaster', 'copies', 'recipe', 'zum', 'permit', 'seeing', 'proof', 'dna', 'diff', 'tennis', 'bass', 'prescription', 'bedroom', 'empty', 'instance', 'hole', 'pets', 'ride', 'licensed', 'orlando', 'specifically', 'tim', 'bureau', 'maine', 'sql', 'represent', 'conservation', 'pair', 'ideal', 'specs', 'recorded', 'don', 'pieces', 'finished',\n 'parks', 'dinner', 'lawyers', 'sydney', 'stress', 'cream', 'ss', 'runs', 'trends', 'yeah', 'discover', 'ap', 'patterns', 'boxes', 'louisiana', 'hills', 'javascript', 'fourth', 'nm', 'advisor', 'mn', 'marketplace', 'nd', 'evil', 'aware', 'wilson', 'shape', 'evolution', 'irish', 'certificates', 'objectives', 'stations', 'suggested', 'gps', 'op', 'remains', 'acc', 'greatest', 'firms', 'concerned',\n 'euro', 'operator', 'structures', 'generic', 'encyclopedia', 'usage', 'cap', 'ink', 'charts', 'continuing', 'mixed', 'census', 'interracial', 'peak', 'tn', 'competitive', 'exist', 'wheel', 'transit', 'suppliers', 'salt', 'compact', 'poetry', 'lights', 'tracking', 'angel', 'bell', 'keeping', 'preparation', 'attempt', 'receiving', 'matches', 'accordance', 'width', 'noise', 'engines', 'forget', 'array', 'discussed', 'accurate',\n 'stephen', 'elizabeth', 'climate', 'reservations', 'pin', 'playstation', 'alcohol', 'greek', 'instruction', 'managing', 'annotation', 'sister', 'raw', 'differences', 'walking', 'explain', 'smaller', 'newest', 'establish', 'gnu', 'happened', 'expressed', 'jeff', 'extent', 'sharp', 'lesbians', 'ben', 'lane', 'paragraph', 'kill', 'mathematics', 'aol', 'compensation', 'ce', 'export', 'managers', 'aircraft', 'modules', 'sweden', 'conflict',\n 'conducted', 'versions', 'employer', 'occur', 'percentage', 'knows', 'mississippi', 'describe', 'concern', 'backup', 'requested', 'citizens', 'connecticut', 'heritage', 'personals', 'immediate', 'holding', 'trouble', 'spread', 'coach', 'kevin', 'agricultural', 'expand', 'supporting', 'audience', 'assigned', 'jordan', 'collections', 'ages', 'participate', 'plug', 'specialist', 'cook', 'affect', 'virgin', 'experienced', 'investigation', 'raised', 'hat', 'institution',\n 'directed', 'dealers', 'searching', 'sporting', 'helping', 'perl', 'affected', 'lib', 'bike', 'totally', 'plate', 'expenses', 'indicate', 'blonde', 'ab', 'proceedings', 'favourite', 'transmission', 'anderson', 'utc', 'characteristics', 'der', 'lose', 'organic', 'seek', 'experiences', 'albums', 'cheats', 'extremely', 'verzeichnis', 'contracts', 'guests', 'hosted', 'diseases', 'concerning', 'developers', 'equivalent', 'chemistry', 'tony', 'neighborhood',\n 'nevada', 'kits', 'thailand', 'variables', 'agenda', 'anyway', 'continues', 'tracks', 'advisory', 'cam', 'curriculum', 'logic', 'template', 'prince', 'circle', 'soil', 'grants', 'anywhere', 'psychology', 'responses', 'atlantic', 'wet', 'circumstances', 'edward', 'investor', 'identification', 'ram', 'leaving', 'wildlife', 'appliances', 'matt', 'elementary', 'cooking', 'speaking', 'sponsors', 'fox', 'unlimited', 'respond', 'sizes', 'plain',\n 'exit', 'entered', 'iran', 'arm', 'keys', 'launch', 'wave', 'checking', 'costa', 'belgium', 'printable', 'holy', 'acts', 'guidance', 'mesh', 'trail', 'enforcement', 'symbol', 'crafts', 'highway', 'buddy', 'hardcover', 'observed', 'dean', 'setup', 'poll', 'booking', 'glossary', 'fiscal', 'celebrity', 'styles', 'denver', 'unix', 'filled', 'bond', 'channels', 'ericsson', 'appendix', 'notify', 'blues',\n 'chocolate', 'pub', 'portion', 'scope', 'hampshire', 'supplier', 'cables', 'cotton', 'bluetooth', 'controlled', 'requirement', 'authorities', 'biology', 'dental', 'killed', 'border', 'ancient', 'debate', 'representatives', 'starts', 'pregnancy', 'causes', 'arkansas', 'biography', 'leisure', 'attractions', 'learned', 'transactions', 'notebook', 'explorer', 'historic', 'attached', 'opened', 'tm', 'husband', 'disabled', 'authorized', 'crazy', 'upcoming', 'britain',\n 'concert', 'retirement', 'scores', 'financing', 'efficiency', 'sp', 'comedy', 'adopted', 'efficient', 'weblog', 'linear', 'commitment', 'specialty', 'bears', 'jean', 'hop', 'carrier', 'edited', 'constant', 'visa', 'mouth', 'jewish', 'meter', 'linked', 'portland', 'interviews', 'concepts', 'nh', 'gun', 'reflect', 'pure', 'deliver', 'wonder', 'lessons', 'fruit', 'begins', 'qualified', 'reform', 'lens', 'alerts',\n 'treated', 'discovery', 'draw', 'mysql', 'classified', 'relating', 'assume', 'confidence', 'alliance', 'fm', 'confirm', 'warm', 'neither', 'lewis', 'howard', 'offline', 'leaves', 'engineer', 'lifestyle', 'consistent', 'replace', 'clearance', 'connections', 'inventory', 'converter', 'organisation', 'babe', 'checks', 'reached', 'becoming', 'safari', 'objective', 'indicated', 'sugar', 'crew', 'legs', 'sam', 'stick', 'securities', 'allen',\n 'pdt', 'relation', 'enabled', 'genre', 'slide', 'montana', 'volunteer', 'tested', 'rear', 'democratic', 'enhance', 'switzerland', 'exact', 'bound', 'parameter', 'adapter', 'processor', 'node', 'formal', 'dimensions', 'contribute', 'lock', 'hockey', 'storm', 'micro', 'colleges', 'laptops', 'mile', 'showed', 'challenges', 'editors', 'mens', 'threads', 'bowl', 'supreme', 'brothers', 'recognition', 'presents', 'ref', 'tank',\n 'submission', 'dolls', 'estimate', 'encourage', 'navy', 'kid', 'regulatory', 'inspection', 'consumers', 'cancel', 'limits', 'territory', 'transaction', 'manchester', 'weapons', 'paint', 'delay', 'pilot', 'outlet', 'contributions', 'continuous', 'db', 'czech', 'resulting', 'cambridge', 'initiative', 'novel', 'pan', 'execution', 'disability', 'increases', 'ultra', 'winner', 'idaho', 'contractor', 'ph', 'episode', 'examination', 'potter', 'dish',\n 'plays', 'bulletin', 'ia', 'pt', 'indicates', 'modify', 'oxford', 'adam', 'truly', 'epinions', 'painting', 'committed', 'extensive', 'affordable', 'universe', 'candidate', 'databases', 'patent', 'slot', 'psp', 'outstanding', 'ha', 'eating', 'perspective', 'planned', 'watching', 'lodge', 'messenger', 'mirror', 'tournament', 'consideration', 'ds', 'discounts', 'sterling', 'sessions', 'kernel', 'stocks', 'buyers', 'journals', 'gray',\n 'catalogue', 'ea', 'jennifer', 'antonio', 'charged', 'broad', 'taiwan', 'und', 'chosen', 'demo', 'greece', 'lg', 'swiss', 'sarah', 'clark', 'labour', 'hate', 'terminal', 'publishers', 'nights', 'behalf', 'caribbean', 'liquid', 'rice', 'nebraska', 'loop', 'salary', 'reservation', 'foods', 'gourmet', 'guard', 'properly', 'orleans', 'saving', 'nfl', 'remaining', 'empire', 'resume', 'twenty', 'newly',\n 'raise', 'prepare', 'avatar', 'gary', 'depending', 'illegal', 'expansion', 'vary', 'hundreds', 'rome', 'arab', 'lincoln', 'helped', 'premier', 'tomorrow', 'purchased', 'milk', 'decide', 'consent', 'drama', 'visiting', 'performing', 'downtown', 'keyboard', 'contest', 'collected', 'nw', 'bands', 'boot', 'suitable', 'ff', 'absolutely', 'millions', 'lunch', 'audit', 'push', 'chamber', 'guinea', 'findings', 'muscle',\n 'featuring', 'iso', 'implement', 'clicking', 'scheduled', 'polls', 'typical', 'tower', 'yours', 'sum', 'misc', 'calculator', 'significantly', 'chicken', 'temporary', 'attend', 'shower', 'alan', 'sending', 'jason', 'tonight', 'dear', 'sufficient', 'holdem', 'shell', 'province', 'catholic', 'oak', 'vat', 'awareness', 'vancouver', 'governor', 'beer', 'seemed', 'contribution', 'measurement', 'swimming', 'spyware', 'formula', 'constitution',\n 'packaging', 'solar', 'jose', 'catch', 'jane', 'pakistan', 'ps', 'reliable', 'consultation', 'northwest', 'sir', 'doubt', 'earn', 'finder', 'unable', 'periods', 'classroom', 'tasks', 'democracy', 'attacks', 'kim', 'wallpaper', 'merchandise', 'const', 'resistance', 'doors', 'symptoms', 'resorts', 'biggest', 'memorial', 'visitor', 'twin', 'forth', 'insert', 'baltimore', 'gateway', 'ky', 'dont', 'alumni', 'drawing',\n 'candidates', 'charlotte', 'ordered', 'biological', 'fighting', 'transition', 'happens', 'preferences', 'spy', 'romance', 'instrument', 'bruce', 'split', 'themes', 'powers', 'heaven', 'br', 'bits', 'pregnant', 'twice', 'classification', 'focused', 'egypt', 'physician', 'hollywood', 'bargain', 'wikipedia', 'cellular', 'norway', 'vermont', 'asking', 'blocks', 'normally', 'lo', 'spiritual', 'hunting', 'diabetes', 'suit', 'ml', 'shift',\n 'chip', 'res', 'sit', 'bodies', 'photographs', 'cutting', 'wow', 'simon', 'writers', 'marks', 'flexible', 'loved', 'favourites', 'mapping', 'numerous', 'relatively', 'birds', 'satisfaction', 'represents', 'char', 'indexed', 'pittsburgh', 'superior', 'preferred', 'saved', 'paying', 'cartoon', 'shots', 'intellectual', 'moore', 'granted', 'choices', 'carbon', 'spending', 'comfortable', 'magnetic', 'interaction', 'listening', 'effectively', 'registry',\n 'crisis', 'outlook', 'massive', 'denmark', 'employed', 'bright', 'treat', 'header', 'cs', 'poverty', 'formed', 'piano', 'echo', 'que', 'grid', 'sheets', 'patrick', 'experimental', 'puerto', 'revolution', 'consolidation', 'displays', 'plasma', 'allowing', 'earnings', 'voip', 'mystery', 'landscape', 'dependent', 'mechanical', 'journey', 'delaware', 'bidding', 'consultants', 'risks', 'banner', 'applicant', 'charter', 'fig', 'barbara',\n 'cooperation', 'counties', 'acquisition', 'ports', 'implemented', 'sf', 'directories', 'recognized', 'dreams', 'blogger', 'notification', 'kg', 'licensing', 'stands', 'teach', 'occurred', 'textbooks', 'rapid', 'pull', 'hairy', 'diversity', 'cleveland', 'ut', 'reverse', 'deposit', 'seminar', 'investments', 'latina', 'nasa', 'wheels', 'specify', 'accessibility', 'dutch', 'sensitive', 'templates', 'formats', 'tab', 'depends', 'boots', 'holds',\n 'router', 'concrete', 'si', 'editing', 'poland', 'folder', 'womens', 'css', 'completion', 'upload', 'pulse', 'universities', 'technique', 'contractors', 'voting', 'courts', 'notices', 'subscriptions', 'calculate', 'mc', 'detroit', 'alexander', 'broadcast', 'converted', 'metro', 'toshiba', 'anniversary', 'improvements', 'strip', 'specification', 'pearl', 'accident', 'nick', 'accessible', 'accessory', 'resident', 'plot', 'qty', 'possibly', 'airline',\n 'typically', 'representation', 'regard', 'pump', 'exists', 'arrangements', 'smooth', 'conferences', 'uniprotkb', 'strike', 'consumption', 'birmingham', 'flashing', 'lp', 'narrow', 'afternoon', 'threat', 'surveys', 'sitting', 'putting', 'consultant', 'controller', 'ownership', 'committees', 'legislative', 'researchers', 'vietnam', 'trailer', 'anne', 'castle', 'gardens', 'missed', 'malaysia', 'unsubscribe', 'antique', 'labels', 'willing', 'bio', 'molecular', 'acting',\n 'heads', 'stored', 'exam', 'logos', 'residence', 'attorneys', 'antiques', 'density', 'hundred', 'ryan', 'operators', 'strange', 'sustainable', 'philippines', 'statistical', 'beds', 'mention', 'innovation', 'pcs', 'employers', 'grey', 'parallel', 'honda', 'amended', 'operate', 'bills', 'bold', 'bathroom', 'stable', 'opera', 'definitions', 'von', 'doctors', 'lesson', 'cinema', 'asset', 'ag', 'scan', 'elections', 'drinking',\n 'reaction', 'blank', 'enhanced', 'entitled', 'severe', 'generate', 'stainless', 'newspapers', 'hospitals', 'vi', 'deluxe', 'humor', 'aged', 'monitors', 'exception', 'lived', 'duration', 'bulk', 'successfully', 'indonesia', 'pursuant', 'sci', 'fabric', 'edt', 'visits', 'primarily', 'tight', 'domains', 'capabilities', 'pmid', 'contrast', 'recommendation', 'flying', 'recruitment', 'sin', 'berlin', 'cute', 'organized', 'ba', 'para',\n 'siemens', 'adoption', 'improving', 'cr', 'expensive', 'meant', 'capture', 'pounds', 'buffalo', 'organisations', 'plane', 'pg', 'explained', 'seed', 'programmes', 'desire', 'expertise', 'mechanism', 'camping', 'ee', 'jewellery', 'meets', 'welfare', 'peer', 'caught', 'eventually', 'marked', 'driven', 'measured', 'medline', 'bottle', 'agreements', 'considering', 'innovative', 'marshall', 'massage', 'rubber', 'conclusion', 'closing', 'tampa',\n 'thousand', 'meat', 'legend', 'grace', 'susan', 'ing', 'ks', 'adams', 'python', 'monster', 'alex', 'bang', 'villa', 'bone', 'columns', 'disorders', 'bugs', 'collaboration', 'hamilton', 'detection', 'ftp', 'cookies', 'inner', 'formation', 'tutorial', 'med', 'engineers', 'entity', 'cruises', 'gate', 'holder', 'proposals', 'moderator', 'sw', 'tutorials', 'settlement', 'portugal', 'lawrence', 'roman', 'duties',\n 'valuable', 'tone', 'collectables', 'ethics', 'forever', 'dragon', 'busy', 'captain', 'fantastic', 'imagine', 'brings', 'heating', 'leg', 'neck', 'hd', 'wing', 'governments', 'purchasing', 'scripts', 'abc', 'stereo', 'appointed', 'taste', 'dealing', 'commit', 'tiny', 'operational', 'rail', 'airlines', 'liberal', 'livecam', 'jay', 'trips', 'gap', 'sides', 'tube', 'turns', 'corresponding', 'descriptions', 'cache',\n 'belt', 'jacket', 'determination', 'animation', 'oracle', 'er', 'matthew', 'lease', 'productions', 'aviation', 'hobbies', 'proud', 'excess', 'disaster', 'console', 'commands', 'jr', 'telecommunications', 'instructor', 'giant', 'achieved', 'injuries', 'shipped', 'seats', 'approaches', 'biz', 'alarm', 'voltage', 'anthony', 'nintendo', 'usual', 'loading', 'stamps', 'appeared', 'franklin', 'angle', 'rob', 'vinyl', 'highlights', 'mining',\n 'designers', 'melbourne', 'ongoing', 'worst', 'imaging', 'betting', 'scientists', 'liberty', 'wyoming', 'blackjack', 'argentina', 'era', 'convert', 'possibility', 'analyst', 'commissioner', 'dangerous', 'garage', 'exciting', 'reliability', 'thongs', 'gcc', 'unfortunately', 'respectively', 'volunteers', 'attachment', 'ringtone', 'finland', 'morgan', 'derived', 'pleasure', 'honor', 'asp', 'oriented', 'eagle', 'desktops', 'pants', 'columbus', 'nurse', 'prayer',\n 'appointment', 'workshops', 'hurricane', 'quiet', 'luck', 'postage', 'producer', 'represented', 'mortgages', 'dial', 'responsibilities', 'cheese', 'comic', 'carefully', 'jet', 'productivity', 'investors', 'crown', 'par', 'underground', 'diagnosis', 'maker', 'crack', 'principle', 'picks', 'vacations', 'gang', 'semester', 'calculated', 'fetish', 'applies', 'casinos', 'appearance', 'smoke', 'apache', 'filters', 'incorporated', 'nv', 'craft', 'cake',\n 'notebooks', 'apart', 'fellow', 'blind', 'lounge', 'mad', 'algorithm', 'semi', 'coins', 'andy', 'gross', 'strongly', 'cafe', 'valentine', 'hilton', 'ken', 'proteins', 'horror', 'su', 'exp', 'familiar', 'capable', 'douglas', 'debian', 'till', 'involving', 'pen', 'investing', 'christopher', 'admission', 'epson', 'shoe', 'elected', 'carrying', 'victory', 'sand', 'madison', 'terrorism', 'joy', 'editions',\n 'cpu', 'mainly', 'ethnic', 'ran', 'parliament', 'actor', 'finds', 'seal', 'situations', 'fifth', 'allocated', 'citizen', 'vertical', 'corrections', 'structural', 'municipal', 'describes', 'prize', 'sr', 'occurs', 'jon', 'absolute', 'disabilities', 'consists', 'anytime', 'substance', 'prohibited', 'addressed', 'lies', 'pipe', 'soldiers', 'nr', 'guardian', 'lecture', 'simulation', 'layout', 'initiatives', 'ill', 'concentration', 'classics',\n 'lbs', 'lay', 'interpretation', 'horses', 'lol', 'dirty', 'deck', 'wayne', 'donate', 'taught', 'bankruptcy', 'mp', 'worker', 'optimization', 'alive', 'temple', 'substances', 'prove', 'discovered', 'wings', 'breaks', 'genetic', 'restrictions', 'participating', 'waters', 'promise', 'thin', 'exhibition', 'prefer', 'ridge', 'cabinet', 'modem', 'harris', 'mph', 'bringing', 'sick', 'dose', 'evaluate', 'tiffany', 'tropical',\n 'collect', 'bet', 'composition', 'toyota', 'streets', 'nationwide', 'vector', 'definitely', 'shaved', 'turning', 'buffer', 'purple', 'existence', 'commentary', 'larry', 'limousines', 'developments', 'def', 'immigration', 'destinations', 'lets', 'mutual', 'pipeline', 'necessarily', 'syntax', 'li', 'attribute', 'prison', 'skill', 'chairs', 'nl', 'everyday', 'apparently', 'surrounding', 'mountains', 'moves', 'popularity', 'inquiry', 'ethernet', 'checked',\n 'exhibit', 'throw', 'trend', 'sierra', 'visible', 'cats', 'desert', 'postposted', 'ya', 'oldest', 'rhode', 'nba', 'coordinator', 'obviously', 'mercury', 'steven', 'handbook', 'greg', 'navigate', 'worse', 'summit', 'victims', 'epa', 'spaces', 'fundamental', 'burning', 'escape', 'coupons', 'somewhat', 'receiver', 'substantial', 'tr', 'progressive', 'cialis', 'bb', 'boats', 'glance', 'scottish', 'championship', 'arcade',\n 'richmond', 'sacramento', 'impossible', 'ron', 'russell', 'tells', 'obvious', 'fiber', 'depression', 'graph', 'covering', 'platinum', 'judgment', 'bedrooms', 'talks', 'filing', 'foster', 'modeling', 'passing', 'awarded', 'testimonials', 'trials', 'tissue', 'nz', 'memorabilia', 'clinton', 'masters', 'bonds', 'cartridge', 'alberta', 'explanation', 'folk', 'org', 'commons', 'cincinnati', 'subsection', 'fraud', 'electricity', 'permitted', 'spectrum',\n 'arrival', 'okay', 'pottery', 'emphasis', 'roger', 'aspect', 'workplace', 'awesome', 'mexican', 'confirmed', 'counts', 'priced', 'wallpapers', 'hist', 'crash', 'lift', 'desired', 'inter', 'closer', 'assumes', 'heights', 'shadow', 'riding', 'infection', 'firefox', 'lisa', 'expense', 'grove', 'eligibility', 'venture', 'clinic', 'korean', 'healing', 'princess', 'mall', 'entering', 'packet', 'spray', 'studios', 'involvement',\n 'dad', 'buttons', 'placement', 'observations', 'vbulletin', 'funded', 'thompson', 'winners', 'extend', 'roads', 'subsequent', 'pat', 'dublin', 'rolling', 'fell', 'motorcycle', 'yard', 'disclosure', 'establishment', 'memories', 'nelson', 'te', 'arrived', 'creates', 'faces', 'tourist', 'av', 'mayor', 'murder', 'sean', 'adequate', 'senator', 'yield', 'presentations', 'grades', 'cartoons', 'pour', 'digest', 'reg', 'lodging',\n 'tion', 'dust', 'hence', 'wiki', 'entirely', 'replaced', 'radar', 'rescue', 'undergraduate', 'losses', 'combat', 'reducing', 'stopped', 'occupation', 'lakes', 'donations', 'associations', 'citysearch', 'closely', 'radiation', 'diary', 'seriously', 'kings', 'shooting', 'kent', 'adds', 'nsw', 'ear', 'flags', 'pci', 'baker', 'launched', 'elsewhere', 'pollution', 'conservative', 'guestbook', 'shock', 'effectiveness', 'walls', 'abroad',\n 'ebony', 'tie', 'ward', 'drawn', 'arthur', 'ian', 'visited', 'roof', 'walker', 'demonstrate', 'atmosphere', 'suggests', 'kiss', 'beast', 'ra', 'operated', 'experiment', 'targets', 'overseas', 'purchases', 'dodge', 'counsel', 'federation', 'pizza', 'invited', 'yards', 'assignment', 'chemicals', 'gordon', 'mod', 'farmers', 'rc', 'queries', 'bmw', 'rush', 'ukraine', 'absence', 'nearest', 'cluster', 'vendors',\n 'mpeg', 'whereas', 'yoga', 'serves', 'woods', 'surprise', 'lamp', 'rico', 'partial', 'shoppers', 'phil', 'everybody', 'couples', 'nashville', 'ranking', 'jokes', 'cst', 'http', 'ceo', 'simpson', 'twiki', 'sublime', 'counseling', 'palace', 'acceptable', 'satisfied', 'glad', 'wins', 'measurements', 'verify', 'globe', 'trusted', 'copper', 'milwaukee', 'rack', 'medication', 'warehouse', 'shareware', 'ec', 'rep',\n 'dicke', 'kerry', 'receipt', 'supposed', 'ordinary', 'nobody', 'ghost', 'violation', 'configure', 'stability', 'mit', 'applying', 'southwest', 'boss', 'pride', 'institutional', 'expectations', 'independence', 'knowing', 'reporter', 'metabolism', 'keith', 'champion', 'cloudy', 'linda', 'ross', 'personally', 'chile', 'anna', 'plenty', 'solo', 'sentence', 'throat', 'ignore', 'maria', 'uniform', 'excellence', 'wealth', 'tall', 'rm',\n 'somewhere', 'vacuum', 'dancing', 'attributes', 'recognize', 'brass', 'writes', 'plaza', 'pdas', 'outcomes', 'survival', 'quest', 'publish', 'sri', 'screening', 'toe', 'thumbnail', 'trans', 'jonathan', 'whenever', 'nova', 'lifetime', 'api', 'pioneer', 'booty', 'forgotten', 'acrobat', 'plates', 'acres', 'venue', 'athletic', 'thermal', 'essays', 'behaviour', 'vital', 'telling', 'fairly', 'coastal', 'config', 'cf',\n 'charity', 'intelligent', 'edinburgh', 'vt', 'excel', 'modes', 'obligation', 'campbell', 'wake', 'stupid', 'harbor', 'hungary', 'traveler', 'urw', 'segment', 'realize', 'regardless', 'lan', 'enemy', 'puzzle', 'rising', 'aluminum', 'wells', 'wishlist', 'opens', 'insight', 'sms', 'restricted', 'republican', 'secrets', 'lucky', 'latter', 'merchants', 'thick', 'trailers', 'repeat', 'syndrome', 'philips', 'attendance', 'penalty',\n 'drum', 'glasses', 'enables', 'nec', 'iraqi', 'builder', 'vista', 'jessica', 'chips', 'terry', 'flood', 'foto', 'ease', 'arguments', 'amsterdam', 'arena', 'adventures', 'pupils', 'stewart', 'announcement', 'tabs', 'outcome', 'appreciate', 'expanded', 'casual', 'grown', 'polish', 'lovely', 'extras', 'gm', 'centres', 'jerry', 'clause', 'smile', 'lands', 'ri', 'troops', 'indoor', 'bulgaria', 'armed',\n 'broker', 'charger', 'regularly', 'believed', 'pine', 'cooling', 'tend', 'gulf', 'rt', 'rick', 'trucks', 'cp', 'mechanisms', 'divorce', 'laura', 'shopper', 'tokyo', 'partly', 'nikon', 'customize', 'tradition', 'candy', 'pills', 'tiger', 'donald', 'folks', 'sensor', 'exposed', 'telecom', 'hunt', 'angels', 'deputy', 'indicators', 'sealed', 'thai', 'emissions', 'physicians', 'loaded', 'fred', 'complaint',\n 'scenes', 'experiments', 'afghanistan', 'dd', 'boost', 'spanking', 'scholarship', 'governance', 'mill', 'founded', 'supplements', 'chronic', 'icons', 'moral', 'den', 'catering', 'aud', 'finger', 'keeps', 'pound', 'locate', 'camcorder', 'pl', 'trained', 'burn', 'implementing', 'roses', 'labs', 'ourselves', 'bread', 'tobacco', 'wooden', 'motors', 'tough', 'roberts', 'incident', 'gonna', 'dynamics', 'lie', 'crm',\n 'rf', 'conversation', 'decrease', 'chest', 'pension', 'billy', 'revenues', 'emerging', 'worship', 'capability', 'ak', 'fe', 'craig', 'herself', 'producing', 'churches', 'precision', 'damages', 'reserves', 'contributed', 'solve', 'shorts', 'reproduction', 'minority', 'td', 'diverse', 'amp', 'ingredients', 'sb', 'ah', 'johnny', 'sole', 'franchise', 'recorder', 'complaints', 'facing', 'sm', 'nancy', 'promotions', 'tones',\n 'passion', 'rehabilitation', 'maintaining', 'sight', 'laid', 'clay', 'defence', 'patches', 'weak', 'refund', 'usc', 'towns', 'environments', 'trembl', 'divided', 'blvd', 'reception', 'amd', 'wise', 'emails', 'cyprus', 'wv', 'odds', 'correctly', 'insider', 'seminars', 'consequences', 'makers', 'hearts', 'geography', 'appearing', 'integrity', 'worry', 'ns', 'discrimination', 'eve', 'carter', 'legacy', 'marc', 'pleased',\n 'danger', 'vitamin', 'widely', 'processed', 'phrase', 'genuine', 'raising', 'implications', 'functionality', 'paradise', 'hybrid', 'reads', 'roles', 'intermediate', 'emotional', 'sons', 'leaf', 'pad', 'glory', 'platforms', 'ja', 'bigger', 'billing', 'diesel', 'versus', 'combine', 'overnight', 'geographic', 'exceed', 'bs', 'rod', 'saudi', 'fault', 'cuba', 'hrs', 'preliminary', 'districts', 'introduce', 'silk', 'promotional',\n]);\n","/**\n * Top 5,000 most common German words\n * Source: FrequencyWords (hermitdave/FrequencyWords, Leipzig Corpora)\n * Used for word complexity analysis — common words are not flagged as jargon.\n */\nexport const FREQUENCY_DE: ReadonlySet<string> = new Set([\n 'ich', 'sie', 'das', 'ist', 'du', 'nicht', 'die', 'es', 'und', 'der', 'wir', 'was', 'zu', 'er', 'ein', 'in', 'ja', 'mir', 'mit', 'wie', 'den', 'mich', 'auf', 'dass', 'aber', 'eine', 'so', 'hat', 'hier', 'haben', 'für', 'sind', 'war', 'von', 'wenn', 'dich', 'ihr', 'nein', 'habe', 'an',\n 'bin', 'noch', 'nur', 'da', 'dir', 'sich', 'einen', 'uns', 'hast', 'dem', 'kann', 'gut', 'auch', 'schon', 'als', 'sein', 'mal', 'jetzt', 'ihn', 'dann', 'aus', 'meine', 'um', 'im', 'wird', 'mein', 'bist', 'doch', 'alles', 'weiß', 'keine', 'oder', 'nach', 's', 'nichts', 'man', 'muss', 'werden', 'will', 'ihnen',\n 'geht', 'wo', 'etwas', 'oh', 'mehr', 'bei', 'also', 'bitte', 'immer', 'hab', 'warum', 'vor', 'los', 'können', 'wieder', 'sagen', 'machen', 'danke', 'sehr', 'alle', 'denn', 'mann', 'tun', 'ihm', 'zum', 'gehen', 'sehen', 'vielleicht', 'einem', 'wer', 'ihre', 'diese', 'euch', 'einer', 'komm', 'über', 'gibt', 'okay', 'wissen', 'deine',\n 'müssen', 'soll', 'werde', 'nie', 'wirklich', 'hey', 'kein', 'viel', 'weg', 'würde', 'tut', 'am', 'des', 'einfach', 'leben', 'hatte', 'zeit', 'weil', 'willst', 'kommen', 'dein', 'heute', 'kommt', 'wollen', 'damit', 'ganz', 'wäre', 'wollte', 'weißt', 'ok', 'sicher', 'gesagt', 'frau', 'nun', 'bis', 'wurde', 'leid', 'na', 'kannst', 'macht',\n 'dieser', 'zurück', 'lassen', 'hallo', 'meinen', 'gott', 'seine', 'hätte', 'zwei', 'könnte', 'genau', 'waren', 'zur', 'lass', 'klar', 'morgen', 'leute', 'vater', 'schön', 'glaube', 'mr.', 'ab', 'gerade', 'tag', 'gesehen', 'reden', 'wohl', 'liebe', 'sollte', 'sagte', 'unsere', 'jemand', 'geld', 'durch', 'ob', 'keinen', 'mutter', 'raus', 'gemacht', 'paar',\n 'mach', 'passiert', 'dachte', 'besser', 'musst', 'wieso', 'sir', 'dieses', 'selbst', 'gehört', 'möchte', 'ohne', 'hör', 'her', 'sag', 'meiner', 'anderen', 'helfen', 'nacht', 'finden', 'diesen', 'gute', 'wirst', 'lange', 'natürlich', 'ach', 'meinem', 'gar', 'ins', 'sei', 'dort', 'weiter', 'geben', 'seit', 'gleich', 'sagt', 'recht', 'ihren', 'richtig', 'ordnung',\n 'vom', 'hören', 'sieht', 'davon', 'dafür', 'geh', 'diesem', 'wegen', 'hause', 'sollten', 'mädchen', 'hin', 'sollen', 'abend', 'haus', 'denke', 'viele', 'drei', 'deinen', 'freund', 'guten', 'unser', 'warte', 'machst', 'menschen', 'essen', 'angst', 'bleiben', 'zusammen', 'welt', 'unter', 'habt', 'schnell', 'andere', 'tot', 'getan', 'darf', 'erst', 'rein', 'stimmt',\n 'nehmen', 'kinder', 'eines', 'glauben', 'bringen', 'ganze', 'genug', 'scheiße', 'brauchen', 'gegen', 'moment', 'junge', 'steht', 'sonst', 'musik', 'arbeit', 'seid', 'ihrer', 'fragen', 'herr', 'dabei', 'heißt', 'familie', 'warten', 'niemand', 'sofort', 'bevor', 'jahre', 'einmal', 'problem', 'sohn', 'wann', 'brauche', 'fertig', 'halt', 'allein', 'beim', 'sprechen', 'beide', 'gefunden',\n 'hatten', 'sache', 'hilfe', 'verdammt', 'ne', 'jeder', 'warst', 'gern', 'konnte', 'darüber', 'halten', 'siehst', 'verstehe', 'jahren', 'kam', 'kind', 'wusste', 'wahr', 'seinen', 'dazu', 'bruder', 'daran', 'ihrem', 'denken', 'könnten', 'dank', 'würden', 'lieber', 'fall', 'deiner', 'sehe', 'egal', 'kennen', 'deinem', 'vergessen', 'frage', 'mache', 'komme', 'sage', 'mag',\n 'sieh', 'echt', 'gib', 'eigentlich', 'jeden', 'dad', 'gab', 'uhr', 'stadt', 'männer', 'baby', 'fahren', 'namen', 'bekommen', 'kopf', 'hi', 'gehe', 'kleine', 'später', 'glück', 'letzte', 'freunde', 'n', 'all', 'darauf', 'ende', 'dr.', 'bald', 'töten', 'dinge', 'meinst', 'toll', 'eins', 'minuten', 'vielen', 'bereit', 'weit', 'ahnung', 'seiner', 'bisschen',\n 'tür', 'auto', 'jungs', 'eure', 'augen', 'polizei', 'stehen', 'sterben', 'hätten', 'draußen', 'kenne', 'fast', 'runter', 'vorbei', 'treffen', 'gerne', 'dran', 'wurden', 'arbeiten', 'mom', 'verrückt', 'neue', 'ging', 'hinter', 'sorgen', 'einzige', 'jemanden', 'darum', 'tochter', 'braucht', 'idee', 'schwester', 'drin', 'ruhig', 'sah', 'ganzen', 'spät', 'ziemlich', 'solltest', 'name',\n 'sogar', 'kurz', 'kerl', 'frauen', 'liegt', 'suchen', 'finde', 'je', 'woher', 'lang', 'job', 'keiner', 'seinem', 'hört', 'verstehen', 'spielen', 's.', 'überhaupt', 'teufel', 'verstanden', 'verloren', 'große', 'hand', 'grund', 'jahr', 'kommst', 'mama', 'ruhe', 'gewesen', 'tod', 'stunden', 'hoffe', 'denkst', 'oben', 'gestern', 'versuchen', 'art', 'letzten', 'schatz', 'endlich',\n 'he', 'nimm', 'etwa', 'erzählt', 'läuft', 'schwer', 'anders', 'miss', 'musste', 'fünf', 'wasser', 'lässt', 'erste', 'versucht', 'gekommen', 'geschichte', 'wenig', 'holen', 'bedeutet', 'nett', 'wahrheit', 'woche', 'bringt', 'deshalb', 'welche', 'bestimmt', 'hoch', 'alter', 'sagst', 'schau', 'ah', 'land', 'zimmer', 'wagen', 'vier', 'gefallen', 'spaß', 'niemals', 'schuld', 'getötet',\n 'wollten', 'verlassen', 'zeigen', 'beste', 'ernst', 'unserer', 'denen', 'ort', 'bleibt', 'würdest', 'manchmal', 'glaubst', 'seite', 'lasst', 'zwischen', 'eben', 'während', 'spiel', 'nehme', 'ersten', 'guter', 'chance', 'freundin', 'krieg', 'gefällt', 'kleinen', 'erzählen', 'anderes', 'tage', 'entschuldigen', 'wichtig', 'gehst', 'allen', 'bett', 'mrs.', 'sachen', 'the', 'schlecht', 'schule', 'entschuldigung',\n 'wort', 'john', 'hättest', 'wären', 'typ', 'schlafen', 'äh', 'tu', 'euer', 'captain', 'gesicht', 'falls', 'neuen', 'bloß', 'unten', 'teil', 'beiden', 'mensch', 'kleiner', 'stellen', 'oft', 'sorge', 'gedacht', 'tust', 'trinken', 'einige', 'dies', 'ding', 'unseren', 'kriegen', 'blut', 'ehrlich', 'eltern', 'scheint', 'herz', 'jack', 'glücklich', 'alte', 'alt', 'bleib',\n 'wiedersehen', 'frei', 'wen', 'drauf', 'möglich', 'irgendwie', 'reicht', 'fest', 'besten', 'waffe', 'kaum', 'irgendwas', 'klingt', 'platz', 'brauchst', 'rede', 'papa', 'falsch', 'sondern', 'alten', 'nummer', 'früher', 'jungen', 'wohin', 'außer', 'früh', 'setzen', 'zuerst', 'wahrscheinlich', 'dürfen', 'jede', 'arsch', 'telefon', 'tue', 'kennst', 'willkommen', 'plan', 'großen', 'retten', 'hierher',\n 'wär', 'bring', 'fehler', 'wollt', 'dollar', 'zehn', 'allem', 'pass', 'nächste', 'stunde', 'hände', 'gegeben', 'menge', 'langsam', 'bereits', 'wartet', 'sechs', 'lieben', 'meines', 'büro', 'nächsten', 'gebe', 'wochen', 'ruf', 'schaffen', 'leider', 'scheiß', 'hölle', 'trotzdem', 'doktor', 'tja', 'new', 'voll', 'film', 'überall', 'hund', 'geworden', 'direkt', 'wolltest', 'tat',\n 'denkt', 'schiff', 'neues', 'wem', 'könig', 'danach', 'funktioniert', 'hattest', 'lernen', 'deswegen', 'wow', 'nennen', 'hm', 'feuer', 'laufen', 'alleine', 'erinnern', 'völlig', 'kleines', 'könnt', 'stelle', 'kumpel', 'verlieren', 'probleme', 'spricht', 'kaffee', 'luft', 'fand', 'i', 'entschuldige', 'ziehen', 'verschwinden', 'könntest', 'seht', 'aufhören', 'eigenen', 'richtige', 'unserem', 'suche', 'zwar',\n 'groß', 'hol', 'buch', 'krank', 'fühle', 'jedes', 'verstehst', 'wert', 'arzt', 'froh', 'versuche', 'straße', 'rufen', 'heiraten', 'super', 'sam', 'lebt', 'gutes', 'lasse', 'onkel', 'total', 'gebracht', 'party', 'erklären', 'spielt', 'wahl', 'vertrauen', 'damals', 'tagen', 'leicht', 'nachdem', 'gegangen', 'gefühl', 'kaufen', 'geschafft', 'typen', 'interessiert', 'möchten', 'halte', 'hält',\n 'glaub', 'irgendwo', 'stück', 'genauso', 'kennt', 'genommen', 'zukunft', 'weniger', 'cool', 'licht', 'getroffen', 'himmel', 'nachricht', 'drüben', 'passt', 'sagten', 'kümmern', 'laut', 'vergiss', 'angerufen', 'sitzen', 'daß', 'erde', 'großer', 'schlüssel', 'rest', 'passieren', 'eher', 'gefragt', 'gefängnis', 'opfer', 'körper', 'solche', 'mist', 'mr', 'findet', 'schreiben', 'böse', 'gesprochen', 'versuch',\n 'vorstellen', 'wovon', 'sobald', 'nochmal', 'herren', 'sex', 'waffen', 'wohnung', 'weh', 'heißen', 'krankenhaus', 'bringe', 'höre', 'millionen', 'klasse', 'hart', 'worden', 'sinn', 'außerdem', 'verletzt', 'ändern', 'erfahren', 'tragen', 'wenigstens', 'vorsichtig', 'daddy', 'stolz', 'stark', 'fällt', 'möchtest', 'leuten', 'besonders', 'schöne', 'schicken', 'person', 'schätze', 'solange', 'länger', 'großartig', 'lacht',\n 'anrufen', 'stand', 'redest', 'fühlen', 'erwartet', 'boden', 'boss', 'stimme', 'glaubt', 'still', 'sicherheit', 'setz', 'ma', 'mund', 'kämpfen', 'wisst', 'lachen', 'hörst', 'zeug', 'lustig', 'umbringen', 'sollst', 'hasse', 'schlimm', 'o', 'unglaublich', 'wärst', 'laden', 'führen', 'gestorben', 'schauen', 'meinung', 'lesen', 'mörder', 'frank', 'ähm', 'geschehen', 'geschäft', 'idiot', 'verzeihung',\n 'fliegen', 'zeig', 'team', 'general', 'mike', 'aufs', 'york', 'vorher', 'schluss', 'schneller', 'liebt', 'verdient', 'mögen', 'meisten', 'denk', 'umgebracht', 'perfekt', 'versprochen', 'handy', 'hinten', 'monate', 'erinnere', 'acht', 'arbeitet', 'fallen', 'rufe', 'nötig', 'a', 'mord', 'heraus', 'tages', 'unmöglich', 'liebling', 'charlie', 'tatsächlich', 'folgen', 'bitten', 'behalten', 'nähe', 'arbeite',\n 'joe', 'verdammte', 'plötzlich', 'lebens', 'hole', 'tisch', 'michael', 'hörte', 'jemals', 'liegen', 'verkaufen', 'gefährlich', 'anfangen', 'bekommt', 'machte', 'ha', 'hotel', 'hilft', 'werdet', 'meister', 'kampf', 'antwort', 'konnten', 'geschickt', 'jedem', 'obwohl', 'sieben', 'komisch', 'gewinnen', 'ihres', 'bezahlt', 'you', 'voller', 'unterwegs', 'dumm', 'ärger', 'bild', 'george', 'neu', 'bezahlen',\n 'dagegen', 'seien', 'starb', 'tom', 'monaten', 'leiche', 'niemanden', 'auge', 'arschloch', 'verheiratet', 'peter', 'zieh', 'nimmt', 'gerettet', 'agent', 'traum', 'entscheidung', 'schlimmer', 'regeln', 'fenster', 'fangen', 'fort', 'ständig', 'findest', 'gefahr', 'absolut', 'mary', 'augenblick', 'bescheid', 'rum', 'gedanken', 'werd', 'ziel', 'benutzt', 'bewegung', 'jemandem', 'wünschte', 'worte', 'kamen', 'welcher',\n 'zahlen', 'anfang', 'legen', 'erinnerst', 'anwalt', 'fahr', 'sitzt', 'hilf', 'offen', 'schönen', 'monsieur', 'müsste', 'arme', 'bier', 'fürs', 'partner', 'klein', 'david', 'klappe', 'süß', 'herum', 'finger', 'ehe', 'rolle', 'ließ', 'gleiche', 'monat', 'hochzeit', 'max', 'führt', 'paris', 'wach', 'wozu', 'arm', 'geschrieben', 'chef', 'benutzen', 'informationen', 'erledigt', 'hoffentlich',\n 'müsst', 'fühlt', 'tanzen', 'ansehen', 'darfst', 'zuhause', 'wunderbar', 'hältst', 'reise', 'gewonnen', 'dame', 'irgendwann', 'chffffff', 'alex', 'steckt', 'jedenfalls', 'schreit', 'tolle', 'rüber', 'tschüss', 'nennt', 'raum', 'heiß', 'foto', 'kalt', 'paul', 'irgendetwas', 'weile', 'bisher', 'minute', 'unbedingt', 'zug', 'sekunden', 'wofür', 'erzähl', 'nen', 'beweise', 'nahm', 'aller', 'freut',\n 'seele', 'schießen', 'müde', 'dauert', 'magst', 'harry', 'brief', 'gelernt', 'sucht', 'bekannt', 'weitere', 'unfall', 'dahin', 'kontrolle', 'beispiel', 'lady', 'dasselbe', 'herzen', 'schlagen', 'wütend', 'weise', 'damen', 'darin', 'gottes', 'holt', 'fehlt', 'vorsicht', 'heiße', 'beweisen', 'gehabt', 'zumindest', 'vermisst', 'hübsch', 'kriegt', 'verbindung', 'tief', 'richtung', 'lage', 'sowieso', 'kraft',\n 'normal', 'lauf', 'ehre', 'stell', 'geschenk', 'bar', 'tasche', 'gelesen', 'gekauft', 'wussten', 'gestohlen', 'hunger', 'leg', 'lügen', 'beziehung', 'ben', 'verschwunden', 'steh', 'nächstes', 'gearbeitet', 'preis', 'witz', 'meinte', 'liste', 'geist', 'neben', 'gesucht', 'firma', 'süße', 'rücken', 'schrecklich', 'letzter', 'verliebt', 'öffnen', 'redet', 'boot', 'seltsam', 'versteckt', 'fürchte', 'verschwinde',\n 'erwischt', 'verkauft', 'tante', 'erwarten', 'pferd', 'wunder', 'sauer', 'vermutlich', 'näher', 'major', 'jung', 'majestät', 'aussehen', 'ans', 'de', 'and', 'links', 'großes', 'welches', 'beschützen', 'geboren', 'erreichen', 'punkt', 'kindern', 'kirche', 'verraten', 'selber', 'befehl', 'colonel', 'fährt', 'zieht', 'geburtstag', 'haut', 'wette', 'reich', 'sekunde', 'fahre', 'schwöre', 'geredet', 'james',\n 'madame', 'eigene', 'zeiten', 'traurig', 'anruf', 'nachrichten', 'frieden', 'karte', 'güte', 'euren', 'diesmal', 'schade', 'persönlich', 'kriege', 'stirbt', 'bleibe', 'verändert', 'sonne', 'lieb', 'nämlich', 'letztes', 'bekam', 'ruft', 'professor', 'gericht', 'nase', 'ewig', 'singen', 'bank', 'beschäftigt', 'computer', 'yeah', 'toten', 'weihnachten', 'offensichtlich', 'naja', 'henry', 'gefühle', 'fuß', 'show',\n 'überraschung', 'geheimnis', 'fbi', 'kontakt', 'gold', 'drogen', 'regierung', 'wein', 'kriegst', 'ermordet', 'fotos', 'entfernt', 'geschlafen', 'manche', 'erledigen', 'ran', 'gegenüber', 'schlaf', 'lust', 'wunderschön', 'witzig', 'nick', 'zerstört', 'übrigens', 'willen', 'heim', 'richtigen', 'deines', 'namens', 'zeigt', 'geliebt', 'gehören', 'brachte', 'herrn', 'blick', 'besuch', 'schlechte', 'bewegen', 'haare', 'antworten',\n 'präsident', 'sagtest', 'hoffnung', 'stecken', 'lebe', 'rechts', 'interessant', 'entscheiden', 'miteinander', 'meint', 'liebst', 'indem', 'bleibst', 'kümmere', 'wohnen', 'weder', 'möglichkeit', 'kaputt', 'bekomme', 'flugzeug', 'vergangenheit', 'anderer', 'zweite', 'armee', 'jim', 'tee', 'entweder', 'weiss', 'don', 'detective', 'aufhalten', 'stellt', 'verspreche', 'überrascht', 'sauber', 'hau', 'mark', 'schlag', 'sheriff', 'untertitel',\n 'setzt', 'frag', 'vaters', 'nervös', 'gesellschaft', 'verstecken', 'schuldig', 'hals', 'schützen', 'besuchen', 'of', 'passen', 'überleben', 'erhalten', 'teilen', 'gebäude', 'schicksal', 'zeichen', 'richter', 'besorgt', 'küche', 'lief', 'vergnügen', 'wüsste', 'volk', 'lhr', 'herausfinden', 'königin', 'soldaten', 'feiern', 'situation', 'lag', 'gelassen', 'allerdings', 'soweit', 'gefahren', 'verstand', 'bord', 'schönes', 'jimmy',\n 'billy', 'angefangen', 'lee', 'fühlst', 'bob', 'mussten', 'rat', 'worauf', 'gebeten', 'tony', 'kamera', 'achtung', 'lieutenant', 'ganzes', 'schuhe', 'sarah', 'glückwunsch', 'niemandem', 'gibst', 'statt', 'übernehmen', 'gegend', 'wald', 'al', 'la', 'nimmst', 'danny', 'erkennen', 'glas', 'falsche', 'verantwortlich', 'jesus', 'stöhnt', 'herein', 'kleid', 'zerstören', 'jawohl', 'london', 'gegessen', 'abendessen',\n 'gesetz', 'gemeinsam', 'geholfen', 'erster', 'wohnt', 'schritt', 'guck', 'nahe', 'aussieht', 'beginnen', 'dachten', 'band', 'ungefähr', 'aufgabe', 'neun', 'furchtbar', 'drinnen', 'zuvor', 'charles', 'freue', 'amerika', 'übrig', 'spur', 'falschen', 'sergeant', 'melden', 'helfe', 'werfen', 'bill', 'haltet', 'erinnert', 'hängt', 'freude', 'ehemann', 'erschossen', 'verzeihen', 'schwein', 'uh', 'monster', 'entschieden',\n 'mission', 'verdammten', 'brauch', 'gewusst', 'vorne', 'stopp', 'übel', 'schlampe', 'schöner', 'adresse', 'unsinn', 'messer', 'gesund', 'respekt', 'pro', 'leisten', 'davor', 'richard', 'bedeuten', 'ball', 'mitnehmen', 'gespielt', 'to', 'schwierigkeiten', 'hälfte', 'kannte', 'stehe', 'maria', 'planeten', 'schwanger', 'gruppe', 'anna', 'verhaftet', 'deal', 'seines', 'irgendwelche', 'händen', 'versteht', 'drehen', 'eis',\n 'danken', 'erfolg', 'zufrieden', 'schließen', 'besorgen', 'wochenende', 'worüber', 'stimmen', 'nehmt', 'martin', 'm', 'witze', 'beine', 'verbrechen', 'bericht', 'nachts', 'eurer', 'prinzessin', 'schmerz', 'klingelt', 'position', 'echte', 'gleichen', 'fernsehen', 'wünsche', 'schließlich', 'gefangen', 'schätzchen', 'seh', 'schwierig', 'angebot', 'nah', 'jane', 'gewartet', 'kümmert', 'ring', 'rennen', 'lied', 'eier', 'welchen',\n 'sorry', 'fantastisch', 'schaut', 'hielt', 'falle', 'drink', 'insel', 'dauern', 'daher', 'zufällig', 'dorf', 'clark', 'bewegt', 'mitten', 'bullen', 'feind', 'einverstanden', 'neuer', 'bauen', 'trägt', 'hängen', 'freunden', 'deren', 'halb', 'verpasst', 'sprach', 'leise', 'armen', 'wusstest', 'fanden', 'unternehmen', 'träume', 'schläft', 'kostet', 'spiele', 'unseres', 'entlang', 'johnny', 'versprechen', 'tiere',\n 'freiheit', 'verdienen', 'aha', 'unterhalten', 'eingeladen', 'schaden', 'genannt', 'beenden', 'ray', 'geändert', 'thomas', 'lächerlich', 'geschlagen', 'park', 'schätzen', 'männern', 't', 'beginnt', 'ehren', 'größte', 'energie', 'fleisch', 'besonderes', 'besteht', 'reichen', 'robert', 'zeitung', 'worum', 'nachgedacht', 'betrunken', 'sowas', 'patienten', 'gespräch', 'leiden', 'taxi', 'tötet', 'see', 'unterschied', 'wind', 'singt',\n 'schreien', 'daniel', 'sahen', 'wand', 'bus', 'lhre', 'angriff', 'verhalten', 'loch', 'interesse', 'treten', 'quatsch', 'trifft', 'polizist', 'blumen', 'neuigkeiten', 'bringst', 'flasche', 'rief', 'schuss', 'fassen', 'meer', 'konntest', 'schafft', 'maschine', 'spreche', 'bein', 'eddie', 'bekommst', 'verbringen', 'bücher', 'blöd', 'frühstück', 'tommy', 'meter', 'bilder', 'aufpassen', 'claire', 'dessen', 'muß',\n 'freuen', 'engel', 'offenbar', 'gelegenheit', 'fang', 'lüge', 'ohren', 'au', 'angetan', 'beeil', 'brechen', 'brüder', 'zeitpunkt', 'keinem', 'ecke', 'brücke', 'druck', 'mitgebracht', 'seufzt', 'date', 'haufen', 'oma', 'auftrag', 'leer', 'entkommen', 'bobby', 'weißen', 'lösung', 'wart', 'pause', 'irre', 'gestellt', 'keller', 'gebrochen', 'weinen', 'nutzen', 'wünschen', 'fragt', 'maul', 'verantwortung',\n 'schloss', 'hut', 'lächeln', 'ryan', 'red', 'grad', 'zweiten', 'hinaus', 'mitkommen', 'vorhin', 'fahrt', 'gemeint', 'ernsthaft', 'gebaut', 'bombe', 'hasst', 'versteh', 'kosten', 'zeige', 'traf', 'eigenes', 'haar', 'fragte', 'jason', 'operation', 'befehle', 'schmerzen', 'erklärt', 'steve', 'dach', 'folge', 'gelaufen', 'schwarze', 'dankbar', 'gehirn', 'töte', 'mädels', 'mut', 'heilige', 'laura',\n 'tier', 'system', 'mannes', 'wahnsinn', 'nee', 'rose', 'club', 'geschlossen', 'hintern', 'is', 'thema', 'fiel', 'gehalten', 'dorthin', 'urlaub', 'steig', 'vorwärts', 'überprüfen', 'besseres', 'beweis', 'baum', 'gebt', 'funktionieren', 'anscheinend', 'lehrer', 'hoffen', 'bessere', 'isst', 'nachmittag', 'nem', 'risiko', 'chuck', 'knast', 'entschuldigt', 'gilt', 'held', 'daraus', 'erstes', 'fräulein', 'rachel',\n 'prima', 'brauchte', 'gewalt', 'dean', 'liebes', 'schaffst', 'nachdenken', 'tor', 'erfahrung', 'pläne', 'jagen', 'katze', 'runde', 'deutsche', 'schwanz', 'taten', 'lord', 'dringend', 'commander', 'großvater', 'sommer', 'gezeigt', 'hinterlassen', 'gewissen', 'getrunken', 'wahre', 'luke', 'kunden', 'kate', 'zeugen', 'geplant', 'amanda', 'erreicht', 'stören', 'stein', 'atmen', 'hose', 'weiße', 'sprichst', 'größer',\n 'schickt', 'city', 'prinz', 'behandelt', 'tote', 'überlegen', 'karten', 'it', 'd', 'restaurant', 'welchem', 'roger', 'natur', 'carter', 'emily', 'mami', 'verschwindet', 'lautet', 'streit', 'küssen', 'sprich', 'längst', 'fängt', 'drüber', 'gingen', 'erlaubt', 'einzigen', 'bad', 'schmeckt', 'kugel', 'normalerweise', 'schwarzen', 'rauf', 'flug', 'beruhigen', 'walter', 'halbe', 'dan', 'geschieht', 'einiges',\n 'entdeckt', 'morgens', 'schlechter', 'vollkommen', 'gelogen', 'verfolgt', 'college', 'weiteren', 'chris', 'louis', 'eh', 'schwert', 'hunde', 'steigen', 'verdammter', 'dürfte', 'riecht', 'labor', 'bat', 'tim', 'arthur', 'mindestens', 'fisch', 'eurem', 'füße', 'stehst', 'erschießen', 'kuchen', 'versuchte', 'zustand', 'wunsch', 'gäste', 'erwähnt', 'farbe', 'van', 'einigen', 'zufall', 'garten', 'junger', 'autos',\n 'abgesehen', 'fair', 'vertraut', 'koffer', 'hieß', 'kurs', 'wirkt', 'idioten', 'netter', 'seitdem', 'angegriffen', 'geschichten', 'wahnsinnig', 'ähnlich', 'lily', 'aufgeben', 'england', 'entführt', 'ms.', 'mistkerl', 'solchen', 'ner', 'geschossen', 'lager', 'besprechen', 'reihe', 'polizisten', 'vogel', 'legt', 'strand', 'amerikaner', 'schwarz', 'fern', 'fick', 'scherz', 'san', 'erzählte', 'wichser', 'jake', 'langweilig',\n 'womit', 'geschäfte', 'my', 'kapiert', 'nachher', 'verlangt', 'schlägt', 'überzeugt', 'irgendjemand', 'rot', 'soldat', 'vorbereitet', 'geschah', 'reisen', 'termin', 'gang', 'stehlen', 'rechte', 'rache', 'bemerkt', 'frankreich', 'stört', 'radio', 'beruhige', 'pferde', 'vertrag', 'arbeitest', 'dienst', 'zählt', 'fragst', 'wesen', 'bürgermeister', 'emma', 'fluss', 'woran', 'geblieben', 'durcheinander', 'me', 'ted', 'nette',\n 'test', 'mister', 'dadurch', 'direktor', 'wichtiger', 'kevin', 'scott', 'karriere', 'akte', 'erinnerung', 'großmutter', 'erzähle', 'lösen', 'bravo', 'griff', 'verfolgen', 'zweifel', 'such', 'sprache', 'nerven', 'officer', 'andy', 'langer', 'ziehe', 'entlassen', 'zweimal', 'abholen', 'washington', 'kollegen', 'doc', 'fass', 'szene', 'robin', 'scheinen', 'bösen', 'schaffe', 'pflicht', 'wache', 'neulich', 'beeilen',\n 'knie', 'alice', 'lauter', 'spannende', 'unschuldig', 'folgt', 'schutz', 'weshalb', 'geheiratet', 'woanders', 'wurdest', 'kuss', 'verhindern', 'erklärung', 'video', 'rom', 'klug', 'kräfte', 'verlangen', 'außerhalb', 'opa', 'selbstverständlich', 'aufstehen', 'hassen', 'pete', 'gebrauchen', 'geglaubt', 'milch', 'trink', 'gefeuert', 'erinnerungen', 'müssten', 'suchst', 'fährst', 'kochen', 'schwach', 'schreibt', 'schulden', 'hinein', 'simon',\n 'grenze', 'braut', 'gebraucht', 'peinlich', 'klappt', 'geheimnisse', 'joey', 'aufmerksamkeit', 'form', 'umsonst', 'kennenzulernen', 'überlebt', 'nirgendwo', 'meilen', 'einfacher', 'blöde', 'mond', 'ergibt', 'daten', 'merken', 'schande', 'fuck', 'fühlte', 'jenny', 'sieg', 'satt', 'blödsinn', 'adam', 'lisa', 'pfund', 'handeln', 'lois', 'enden', 'warm', 'raten', 'übersetzung', 'kunst', 'kapitän', 'desto', 'einsatz',\n 'schweigen', 'krankheit', 'toller', 'schatten', 'wachen', 'tatsache', 'eric', 'stock', 'chief', 'hingehen', 'verboten', 'gäbe', 'anzug', 'leichen', 'high', 'beendet', 'freitag', 'million', 'verflucht', 'dunkel', 'geb', 'enttäuscht', 'klopfen', 'spuren', 'dreck', 'seiten', 'mühe', 'gezogen', 'brian', 'kontrollieren', 'knochen', 'schick', 'getrennt', 'programm', 'grab', 'ebenso', 'trage', 'nachbarn', 'bieten', 'bestes',\n 'elizabeth', 'fuhr', 'verlässt', 'freundlich', 'dennoch', 'rauchen', 'dick', 'stuhl', 'dreh', 'bester', 'schicke', 'vergeben', 'ausgehen', 'behandeln', 'trotz', 'gast', 'ändert', 'passierte', 'toilette', 'annehmen', 'herzlichen', 'hexe', 'erwachsen', 'jerry', 'pistole', 'saß', 'dreht', 'aussage', 'liebte', 'street', 'genießen', 'eifersüchtig', 'derjenige', 'teuer', 'leo', 'zähne', 'beobachtet', 'gentlemen', 'wählen', 'helft',\n 'fliegt', 'theater', 'regen', 'feinde', 'william', 'erlauben', 'zulassen', 'schnappen', 'komplett', 'panik', 'flughafen', 'bewusst', 'deutschen', 'voraus', 'sterbe', 'solltet', 'begleiten', 'einander', 'fred', 'erlebt', 'weiterhin', 'stärker', 'fahrer', 'konzentrieren', 'streiten', 'angeht', 'selben', 'star', 'überzeugen', 'alkohol', 'übersetzt', 'verrückte', 'lch', 'king', 'begann', 'angenommen', 'weitermachen', 'echter', 'jackson', 'post',\n 'mitgenommen', 'botschaft', 'ideen', 'fehlen', 'aufgeregt', 'selbstmord', 'dumme', 'zurückkommen', 'irgendein', 'magie', 'phil', 'schlage', 'handelt', 'treffe', 'untersuchen', 'flucht', 'verliert', 'irgendeine', 'gegenteil', 'betrifft', 'scharf', 'gehofft', 'kennengelernt', 'schlimmste', 'projekt', 'trottel', 'immerhin', 'mehrere', 'erwarte', 'mochte', 'schwimmen', 'zählen', 'innerhalb', 'matt', 'blind', 'schwestern', 'code', 'alan', 'schlau', 'absicht',\n 'barry', 'spielst', 'zuletzt', 'oliver', 'art.', 'englisch', 'ohr', 'verletzen', 'song', 'schüler', 'schien', 'gewinnt', 'älter', 'merkwürdig', 'judy', 'vermisse', 'größe', 'tritt', 'trauen', 'präsidenten', 'trick', 'harvey', 'doug', 'roten', 'überlegt', 'größten', 'sonntag', 'zwölf', 'vorstellung', 'schrieb', 'reinkommen', 'killer', 'unterstützung', 'antun', 'rechnung', 'dieselbe', 'verändern', 'möglicherweise', 'definitiv', 'locker',\n 'ed', 'vincent', 'ums', 'abends', 'frisch', 'kohle', 'fing', 'hure', 'cousin', 'familien', 'einsam', 'lebendig', 'heiligen', 'knapp', 'ebenfalls', 'überprüft', 'artikel', 'gesetzt', 'jederzeit', 'kompliziert', 'spüren', 'signal', 'amy', 'stich', 'kino', 'probieren', 'tode', 'wundervoll', 'tanz', 'geöffnet', 'kerle', 'begraben', 'prozent', 'stoppen', 'hoheit', 'riesen', 'rote', 'zugang', 'liest', 'vorn',\n 'wichtige', 'aufmachen', 'kelly', 'sexy', 'erlaubnis', 'grace', 'big', 'story', 'madam', 'leichter', 'halben', 'filme', 'priester', 'herauszufinden', 'packen', 'dritte', 'inzwischen', 'larry', 'presse', 'sitze', 'machten', 'geklaut', 'helden', 'susan', 'geduld', 'bühne', 'reparieren', 'hä', 'usa', 'gerechtigkeit', 'fälle', 'selten', 'anrufe', 'unterschreiben', 'julia', 'drücken', 'mrs', 'lügner', 'endet', 'dave',\n 'medizin', 'schreibe', 'verhaften', 'prozess', 'samstag', 'amen', 'motor', 'marie', 'abhauen', 'chaos', 'schönheit', 'beinahe', 'lebst', 'tolles', 'anhalten', 'fremden', 'hof', 'akzeptieren', 'norden', 'ärzte', 'anziehen', 'dingen', 'umgehen', 'bauch', 'gesamte', 'hübsche', 'ertragen', 'kiste', 'brennt', 'teile', 'deckung', 'landen', 'berg', 'straßen', 'aufgenommen', 'gerufen', 'untersuchung', 'alarm', 'blieb', 'vertraue',\n 'extra', 'entspann', 'beobachten', 'eindruck', 'tschüs', 'babys', 'wehtun', 'zog', 'iss', 'herrgott', 'echten', 'springen', 'nackt', 'existiert', 'befreien', 'gerät', 'montag', 'gezwungen', 'perfekte', 'erzählst', 'bastard', 'interessieren', 'schlechten', 'hank', 'steigt', 'st.', 'on', 'carl', 'gekriegt', 'fliehen', 'trug', 'freundschaft', 'rate', 'papiere', 'abgeschlossen', 'schnauze', 'beruf', 'gebiet', 'jeff', 'jedoch',\n 'beten', 'verbunden', 'sprachen', 'verräter', 'wichtigste', 'prost', 'brust', 'aufgehört', 'kleider', 'jacke', 'bestellt', 'herkommen', 'wild', 'nenne', 'angesehen', 'zuhören', 'trennen', 'schlafzimmer', 'vorschlag', 'meins', 'gift', 'ton', 'vermissen', 'angekommen', 'beantworten', 'deutlich', 'träumen', 'verwirrt', 'akten', 'riskieren', 'b', 'victor', 'find', 'erkannt', 'beerdigung', 'müll', 'weisst', 'möge', 'stellte', 'mitte',\n 'erleben', 'geburt', 'decke', 'ch00ffff', 'wege', 'schritte', 'gibts', 'gemeldet', 'hilfst', 'mittagessen', 'weint', 'vernichten', 'rock', 'chicago', 'ellen', 'crew', 'roy', 'türen', 'gewehr', 'elena', 'arbeitete', 'spiegel', 'hauen', 'geraten', 'dritten', 'ross', 'julie', 'wetter', 'schwul', 'regel', 'befindet', 'einheit', 'german', 'armer', 'gucken', 'anstatt', 'champagner', 'gründe', 'strafe', 'smith',\n 'öfter', 'anne', 'zelle', 'langen', 'altes', 'ruiniert', 'jonathan', 'kleidung', 'gras', 'kenn', 'agenten', 'herausgefunden', 'annie', 'rechten', 'brot', 'berlin', 'erfreut', 'lügt', 'nehm', 'harte', 'staaten', 'station', 'gaben', 'hinterher', 'verpassen', 'geholt', 'jesse', 'hemd', 'trinke', 'klären', 'praktisch', 'theorie', 'zunge', 'notfall', 'besseren', 'winter', 'c', 'versuchst', 'dahinter', 'schwere',\n 'feuern', 'lucy', 'schießt', 'anführer', 'schief', 'blau', 'bestens', 'wartest', 'gehts', 'morgan', 'unrecht', 'leck', 'wonach', 'entwickelt', 'bedeutung', 'strom', 'krebs', 'gemein', 'wessen', 'minister', 'lhnen', 'quelle', 'zahl', 'schiffe', 'schüsse', 'bricht', 'talent', 'spitze', 'fernseher', 'treiben', 'ausgezeichnet', 'tatort', 'möglichkeiten', 'trinkt', 'esse', 'cop', 'details', 'täter', 'wahren', 'dieb',\n 'offiziell', 'dienen', 'westen', 'entscheidungen', 'dauernd', 'geschmack', 'gegenseitig', 'gewählt', 'charlotte', 'pech', 'verteidigen', 'schauspieler', 'personen', 'überlassen', 'publikum', 'trägst', 'wechseln', 'begegnet', 'betrogen', 'besucht', 'vertrau', 'europa', 'carrie', 'patrick', 'deutschland', 'süßer', 'loswerden', 'melde', 'maggie', 'bestätigt', 'gas', 'sturm', 'setze', 'briefe', 'null', 'penny', 'schlafe', 'wirken', 'geführt', 'starten',\n 'götter', 'festhalten', 'geheim', 'übergeben', 'cia', 'abteilung', 'papier', 'wetten', 'gefolgt', 'verschiedene', 'gleichzeitig', 'genie', 'hungrig', 'inspektor', 'zwingen', 'atmet', 'kuh', 'unterstützen', 'geworfen', 'verlor', 'süden', 'pater', 'menschheit', 'versteck', 'tötete', 'fähigkeiten', 'beruhigt', 'rechtzeitig', 'streng', 'sendung', 'gelebt', 'treppe', 'kim', 'richtiger', 'aufnehmen', 'wolf', 'pa', 'öffnet', 'dämon', 'wut',\n 'schlange', 'medikamente', 'geschenkt', 'nenn', 'gelegt', 'anfassen', 'pizza', 'schlechtes', 'hütte', 'mantel', 'behauptet', 'kilometer', 'beeilung', 'angeblich', 'reiten', 'helen', 'mittag', 'gewarnt', 'wohne', 'las', 'dunkelheit', 'spazieren', 'angel', 'hiermit', 'schließt', 'phoebe', 'vieles', 'erfüllt', 'tausend', 'sack', 'eindeutig', 'unterhaltung', 'gründen', 'km', 'zugeben', 'mittel', 'explosion', 'gefangenen', 'taylor', 'frische',\n 'verdächtigen', 'neugierig', 'leitung', 'kennenlernen', 'fliege', 'lebte', 'menschliche', 'anderem', 'auseinander', 'fressen', 'beides', 'ficken', 'stoff', 'spüre', 'eilig', 'stammt', 'vorgestellt', 'linda', 'welch', 'wichtiges', 'no', 'gehörte', 'mhm', 'glaubte', 'oberst', 'schrank', 'fremde', 'gnade', 'chloe', 'yo', 'entspannen', 'virus', 'schläfst', 'einladung', 'krieger', 'vernünftig', 'fein', 'greifen', 'whoa', 'kyle',\n 'schickte', 'per', 'mitglied', 'einziger', 'umzubringen', 'zurückkehren', 'feld', 'mexiko', 'erschaffen', 'information', 'hergekommen', 'beweg', 'stärke', 'vermögen', 'verbracht', 'gewisse', 'waschen', 'howard', 'staat', 'geister', 'behaupten', 'schrei', 'würdet', 'vögel', 'warnen', 'albert', 'chancen', 'treibt', 'nannte', 'vermute', 'mitternacht', 'jones', 'freundinnen', 'lecker', 'klinik', 'dicht', 'befinden', 'ließen', 'bürger', 'verursacht',\n 'hammer', 'klang', 'internet', 'aufregend', 'grenzen', 'politik', 'superman', 'zurecht', 'besitz', 'cops', 'eingesperrt', 'irren', 'kommando', 'schlug', 'krankenwagen', 'love', 'öffne', 'karen', 'richten', 'mademoiselle', 'erfunden', 'schnee', 'fühl', 'behalte', 'beschützt', 'punkte', 'entfernen', 'abgehauen', 'geträumt', 'stefan', 'dämonen', 'tränen', 'erfolgreich', 'volle', 'wilson', 'caroline', 'höher', 'happy', 'brille', 'musstest',\n 'heimat', 'terry', 'liebsten', 'bye', 'leiter', 'sean', 'kauf', 'spinnst', 'werk', 'cent', 'schlacht', 'beziehungen', 'abgemacht', 'schreie', 'hmm', 'bestätigen', 'erschreckt', 'offizier', 'that', 'sara', 'affäre', 'empfangen', 'zweck', 'kämpfe', 'ergeben', 'china', 'fange', 'häuser', 'verliere', 'gedanke', 'tausende', 'heutzutage', 'gefühlt', 'schnitt', 'carlos', 'harold', 'lebend', 'real', 'holz', 'kaiser',\n 'spielte', 'begonnen', 'ziehst', 'gelandet', 'scheidung', 'bart', 'beschlossen', 'klo', 'riechen', 'vergisst', 'begeistert', 'ei', 'durchs', 'geil', 'nieder', 'erkläre', 'schreckliche', 'beeindruckt', 'vince', 'aufgegeben', 'aufgrund', 'momentan', 'solch', 'meistens', 'stress', 'sterne', 'heilen', 'soviel', 'kannten', 'stattdessen', 'aye', 'dinger', 'stimmung', 'bulle', 'aufgefallen', 'kämpft', 'geräusch', 'künstler', 'wachsen', 'verurteilt',\n 'himmels', 'tyler', 'urteil', 'schweine', 'nettes', 'house', 'verlust', 'verließ', 'wirf', 'wenige', 'willie', 'schulter', 'kalifornien', 'lernt', 'beigebracht', 'normale', 'anbieten', 'verwenden', 'gratuliere', 'fluch', 'rick', 'übers', 'grün', 'unterricht', 'dachtest', 'verarschen', 'gewöhnt', 'anklage', 'tollen', 'lippen', 'fett', 'lege', 'feigling', 'achten', 'gary', 'erfährt', 'gewohnt', 'jessica', 'äußerst', 'einladen',\n 'käse', 'aufwachen', 'verfügung', 'uniform', 'zusehen', 'board.tv4user.de', 'gesundheit', 'abenteuer', 'hosen', 'kurze', 'scheck', 'täglich', 'fresse', 'übernehme', 'wiederholen', 'bestellen', 'freiwillig', 'cole', 'universum', 'zeuge', 'west', 'marshall', 'fähig', 'revier', 'reifen', 'mum', 'führe', 'durchgemacht', 'tests', 'führte', 'schenken', 'schädel', 'realität', 'april', 'albern', 'brav', 'schwerer', 'jagd', 'versagt', 'truck',\n 'steckst', 'geschenke', 'sicherlich', 'öffentlichkeit', 'merkt', 'verbrecher', 'maske', 'verstärkung', 'liefern', 'jo', 'starke', 'grunde', 'gordon', 'würd', 'verschwand', 'schulde', 'russen', 'führer', 'gemerkt', 'ciao', 'loslassen', 'berichten', 'verabschieden', 'antrag', 'schieß', 'abby', 'benehmen', 'verdacht', 'hübsches', 'schreibtisch', 'e', 'vampir', 'rory', 'probe', 'schaff', 'verzeih', 'patient', 'geküsst', 'ertönt', 'nahmen',\n 'zahlt', 'vorbereiten', 'verbrannt', 'verdammtes', 'frankie', 'informiert', 'einziges', 'zucker', 'stinkt', 'schnappt', 'schreib', 'standen', 'klamotten', 'heil', 'besitzer', 'marcus', 'tess', 'drum', 'tasse', 'hinweis', 'verteidigung', 'lügst', 'lies', 'magen', 'enterprise', 'michelle', 'beeilt', 'tunnel', 'einst', 'behandlung', 'serie', 'applaus', 'markt', 'korrekt', 'besessen', 'bewahren', 'nr.', 'pack', 'gekämpft', 'black',\n 'angreifen', 'tiefer', 'huh', 'truppen', 'kommandant', 'osten', 'elf', 'beeindruckend', 'besitzt', 'ho', 'heut', 'clever', 'verrückten', 'freien', 'hass', 'antworte', 'posten', 'schneiden', 'sammeln', 'gesteckt', 'wissenschaft', 'ursache', 'gewiss', 'bereich', 'catherine', 'meinetwegen', 'l.a.', 'senator', 'ausziehen', 'verzweifelt', 'jess', 'anteil', 'stets', 'ritter', 'viertel', 'roman', 'pünktlich', 'erfüllen', 'kauft', 'molly',\n 'basis', 'eva', 'schock', 'empfang', 'wiederhole', 'wünscht', 'besondere', 'titel', 'stil', 'fingerabdrücke', 'einfluss', 'anweisungen', 'zahle', 'shield', 'opfern', 'blaue', 'sparen', 'weiteres', 'gehörst', 'farm', 'erstaunlich', 'schwachsinn', 'miete', 'verwandelt', 'daneben', 'klaus', 'bereiten', 'wüste', 'prüfen', 'gabe', 'hundert', 'erscheinen', 'laß', 'besiegen', 'verpiss', 'umständen', 'angelegenheit', 'landes', 'dienstag', 'folgendes',\n 'fürchten', 'mordes', 'nennst', 'angestellt', 'training', 'aufgetaucht', 'rausfinden', 'ächzt', 'rauskommen', 'planet', 'suppe', 'erwischen', 'sitz', 'johnson', 'vorteil', 'for', 'rosa', 'tour', 'amerikanische', 'schönste', 'rufst', 'berührt', 'französisch', 'gouverneur', 'angeles', 'kaufe', 'stern', 'gedächtnis', 'wirklichkeit', 'bestraft', 'kreis', 'reine', 'edward', 'schlimmes', 'bestehen', 'jeannie', 'erscheint', 'staatsanwalt', 'ewigkeit', 'störung',\n 'hässlich', 'lauft', 'angezogen', 'señor', 'half', 'sollt', 'martha', 'tiger', 'zigarette', 'mutig', 'ausruhen', 'andrew', 'linken', 'hauptmann', 'umstände', 'not', 'unglück', 'eng', 'white', 'lucas', 'üben', 'wissenschaftler', 'gelöst', 'reaktion', 'morde', 'dusche', 'mitarbeiter', 'your', 'bedroht', 'gehöre', 'befreit', 'stöhnen', 'reagiert', 'identität', 'rund', 'texas', 'fieber', 'hirn', 'leiten', 'donnerstag',\n 'leonard', 'unheimlich', 'mulder', 'jahrhundert', 'irgend', 'diener', 'bruce', 'extrem', 'ausweis', 'sicht', 'sport', 'juden', 'studiert', 'angelogen', 'schaue', 'little', 'sally', 'text', 'earl', 'nebenan', 'todd', 'lektion', 'mäuse', 'staub', 'sophie', 'kugeln', 'dutzend', 'ratte', 'mitleid', 'testen', 'auftritt', 'gegner', 'joseph', 'verdienst', 'langsamer', 'wunde', 'linie', 'bedrohung', 'bauer', 'kurzem',\n 'fische', 'einkaufen', 'kreuz', 'afrika', 'begangen', 'el', 'nachsehen', 'junior', 'bäume', 'leidenschaft', 'geliebte', 'bereuen', 'spieler', 'berge', 'verwendet', 'steuern', 'gekümmert', 'voran', 'wieviel', 'barney', 'graf', 'verabredung', 'verlasse', 'überfallen', 'donna', 'umdrehen', 'damon', 'kilo', 'diego', 'negativ', 'schild', 'tanzt', 'verbrennen', 'gefreut', 'penner', 'blauen', 'jay', 'stücke', 'angela', 'kühlschrank',\n 'identifizieren', 'lehrerin', 'francisco', 'kameras', 'zentrale', 'jäger', 'josh', 'wayne', 'wenden', 'we', 'holst', 'suchte', 'start', 'füßen', 'unglücklich', 'frohe', 'sand', 'pfarrer', 'plus', 'nancy', 'brachten', 'zauber', 'berühren', 'rückkehr', 'hafen', 'indianer', 'miller', 'verschwenden', 'untersucht', 'königs', 'jean', 'lese', 'stahl', 'hättet', 'affen', 'worten', 'kindheit', 'gewollt', 'op', 'vermeiden',\n 'fabrik', 'aussagen', 'wunderbare', 'grandpa', 'miststück', 'verrückter', 'lane', 'jungfrau', 'einfache', 'nate', 'laufe', 'reingelegt', 'seltsame', 'heiratet', 'angenehm', 'daheim', 'planen', 'klauen', 'geruch', 'marty', 'klingen', 'tina', 'nächster', 'hörten', 'jackie', 'trafen', 'ungern', 'abgelehnt', 'erstens', 'abmachung', 'appetit', 'miami', 'zeigte', 'fan', 'hohen', 'alf', 'ladys', 'sms', 'verkauf', 'jamie',\n 'verbergen', 'sorgt', 'karl', 'sohnes', 'berühmt', 'aussteigen', 'bonnie', 'ginge', 'reingehen', 'durfte', 'korrektur', 'wirft', 'titten', 'betreten', 'todes', 'one', 'doctor', 'blöden', 'miles', 'rausholen', 'hohe', 'aufnahme', 'by', 'holmes', 'hübscher', 'vegas', 'manager', 'stellung', 'höhle', 'schokolade', 'angeboten', 'befreundet', 'weib', 'ausgerechnet', 'walker', 'beibringen', 'nelson', 'ex', 'belohnung', 'seelen',\n 'steine', 'garage', 'scheißkerl', 'gestört', 'cooper', 'ruhen', 'pillen', 'gepäck', 'carol', 'norman', 'zoe', 'amerikanischen', 'telefonieren', 'heirate', 'erkenne', 'funk', 'grüß', 'hurensohn', 'mögliche', 'spring', 'uni', 'scheinbar', 'fakten', 'informieren', 'jugend', 'feier', 'wenigen', 'söhne', 'benzin', 'nix', 'vampire', 'erkennt', 'sicherer', 'zigaretten', 'dummes', 'mauer', 'erneut', 'flügel', 'schluck', 'hierbleiben',\n 'abschluss', 'christus', 'bezahle', 'böses', 'dummkopf', 'gerüchte', 'eingestellt', 'm.', 'weitergehen', 'technik', 'ali', 'bezweifle', 'piper', 'over', 'gekostet', 'anzeige', 'wohnst', 'hans', 'ergebnis', 'bedingungen', 'brad', 'aufzuhalten', 'versprich', 'verdiene', 'geschnappt', 'francis', 'eile', 'innen', 'italien', 'einig', 'verhandeln', 'weswegen', 'nützlich', 'inneren', 'gentleman', 'felix', 'vergesse', 'dunkle', 'warnung', 'gemeinde',\n 'diamanten', 'wächst', 'gewöhnlich', 'seil', 'bär', 'euro', 'großartige', 'beth', 'ware', 'traurige', 'persönliche', 'figur', 'time', 'roboter', 'anschauen', 'kürzlich', 'material', 'paula', 'käme', 'stellst', 'bereitet', 'einfallen', 'käfig', 'fantasie', 'brach', 'satz', 'kommissar', 'exzellenz', 'schuldest', 'nass', 'rächen', 'womöglich', 'begrüßen', 'lou', 'davis', 'überraschen', 'menschlichen', 'repariert', 'führung', 'gestanden',\n 'jacob', 'schütze', 'störe', 'nina', 'filmen', 'jobs', 'maschinen', 'unterlagen', 'palast', 'graben', 'kette', 'auftauchen', 'interessante', 'wovor', 'springt', 'terroristen', 'stan', 'bekämpfen', 'lärm', 'flehe', 'aufgewachsen', 'arbeiter', 'größere', 'humor', 'betrachten', 'be', 'organisation', 'widerstand', 'bergen', 'studio', 'hausaufgaben', 'vögeln', 'bescheuert', 'weggehen', 'teller', 'original', 'revolution', 'hitler', 'mädel', 'verbinden',\n 'nathan', 'ermittlungen', 'steck', 'wäsche', 'rätsel', 'besonderen', 'hunderte', 'versetzt', 'bibel', 'heiliger', 'reiß', 'kopie', 'besitzen', 'zeitungen', 'zurückgekommen', 'süßes', 'barbara', 'ungewöhnlich', 'höhe', 'geschaffen', 'beschreiben', 'ausgesucht', 'notwendig', 'dunklen', 'ignorieren', 'toter', 'deck', 'narr', 'scheißegal', 'höchstens', 'übersehen', 'geirrt', 'darunter', 'außen', 'einzig', 'stirbst', 'lhren', 'spielchen', 'girl', 'fahrrad',\n 'nutte', 'wilde', 'jordan', 'bequem', 'rauch', 'verschiedenen', 'kamst', 'l', 'betty', 'pool', 'hubschrauber', 'wüssten', 'erstmal', 'kollege', 'vernichtet', 'gesichter', 'derselbe', 'hattet', 'konto', 'freie', 'casey', 'haken', 'munition', 'sünde', 'militär', 'gefasst', 'anzeichen', 'geklappt', 'hintergrund', 'erwähnen', 'tipp', 'reißen', 'keins', 'genial', 'berichte', 'kram', 'schnapp', 'solle', 'randy', 'umziehen',\n 'zunächst', 'keinerlei', 'typisch', 'bietet', 'leb', 'technologie', 'john-boy', 'ruinieren', 'jünger', 'poirot', 'umso', 'starben', 'rette', 'triffst', 'unhöflich', 'safe', 'anzurufen', 'universität', 'mai', 'heben', 'koch', 'derselben', 'katastrophe', 'male', 'olivia', 'prüfung', 'brown', 'gesetze', 'meeting', 'versicherung', 'getragen', 'ehefrau', 'mitmachen', 'tauschen', 'ergebnisse', 'boston', 'reg', 'einstellen', 'reagieren', 'gefehlt',\n 'verwandeln', 'gedauert', 'senden', 'blair', 'reporter', 'abgeben', 'mm', 'parker', 'anhören', 'bibliothek', 'japan', 'hinsetzen', 'hannah', 'serena', 'motiv', 'paige', 'schalten', 'derek', 'gewöhnen', 'lernte', 'vereinigten', 'gewicht', 'zweiter', 'badezimmer', 'schieben', 'dreimal', 'weich', 'echtes', 'zweitens', 'drachen', 'bahnhof', 'erschöpft', 'genauer', 'verlange', 'spanisch', 'verrat', 'hexen', 'live', 'legende', 'taub',\n 'freu', 'konzert', 'hopp', 'wiederzusehen', 'doppelt', 'last', 'vergleich', 'böser', 'herzlich', 'monica', 'taschen', 'genügt', 'besucher', 'spanien', 'großzügig', 'teddy', 'hauses', 'leihen', 'scheiden', 'einstellung', 'köstlich', 'watson', 'einheiten', 'wichtigen', 'go', 'warne', 'russland', 'angeschossen', 'sammy', 'pierre', 'sklaven', 'laune', 'gesamten', 'stille', 'asche', 'geflogen', 'spion', 'what', 'aaron', 'weihnachtsmann',\n 'hervorragend', 'can', 'verärgert', 'puppe', 'überfall', 'unwichtig', 'santa', 'linke', 'übung', 'buffy', 'franzosen', 'wehgetan', 'schwäche', 'couch', 'cousine', 'grant', 'atme', 'irgendeinem', 'unterstützt', 'oscar', 'ausdruck', 'pleite', 'beleidigt', 'knopf', 'stop', 'schlimme', 'beweist', 'katie', 'dramatische', 'heutigen', 'leere', 'island', 'shane', 'daisy', 'trinkst', 'heimlich', 'eingehen', 'rad', 'greift', 'mächtig',\n 'williams', 'sinnlos', 'versaut', 'netz', 'atem', 'anstellen', 'milliarden', 'flotte', 'umgebung', 'mitbringen', 'beteiligt', 'dunkeln', 'entwickeln', 'schämen', 'erwachsene', 'zack', 'durchsuchen', 'hollywood', 'rollen', 'vergesst', 'tricks', 'plätze', 'gefangene', 'sünden', 'sender', 'verlass', 'räumen', 'lerne', 'rettet', 'hinweise', 'ausreden', 'alexander', 'mommy', 'diejenige', 'nächte', 'herrscht', 'bud', 'jahres', 'dna', 'romantisch',\n 'flüstert', 'drück', 'jeremy', 'bedanken', 'verabredet', 'pilot', 'colt', 'nigger', 'reizend', 'grade', 'stanley', 'leib', 'stecke', 'scheisse', 'ärztin', 'vergewaltigt', 'mußt', 'lieferung', 'botschafter', 'studieren', 'köpfe', 'duschen', 'kopfschmerzen', 'öl', 'knarre', 'sekretärin', 'phase', 'handschellen', 'lewis', 'versehen', 'bande', 'treu', 'positiv', 'meiste', 'museum', 'albtraum', 'margaret', 'verlobt', 'besiegt', 'existieren',\n 'könne', 'proben', 'beschissen', 'gewinne', 'personal', 'christian', 'bewaffnet', 'fällen', 'wecken', 'wirkung', 'kurt', 'connor', 'rebecca', 'therapie', 'travis', 'amüsieren', 'ordentlich', 'weglaufen', 'aufgewacht', 'nähern', 'decken', 'sinne', 'leutnant', 'zauberer', 'hogan', 'bittet', 'ankunft', 'klopft', 'abstand', 'bewusstsein', 'nation', 'kontrolliert', 'treffer', 'abnehmen', 'ratten', 'anwälte', 'tempel', 'vergiftet', 'kunde', 'august',\n 'wunden', 'unangenehm', 'ausrüstung', 'segen', 'präsentiert', 'schließ', 'kehle', 'krone', 'garantiert', 'durchsucht', 'president', 'tracy', 'verfluchte', 'bestimmten', 'clay', 'ladies', 'b.', 'ladung', 'beinen', 'hell', 'kent', 'kapitel', 'chase', 'benutze', 'alibi', 'ziele', 'bestie', 'gus', 'nirgends', 'wohnzimmer', 'beute', 'bau', 'brennen', 'lex', 'durst', 'logan', 'schwarzer', 'schmutzig', 'liebhaber', 'ersetzen',\n 'juli', 'verfahren', 'kirk', 'stiefel', 'inspector', 'allzu', 'camp', 'dürft', 'orten', 'hitze', 'spielzeug', 'tv', 'gloria', 'wolle', 'knurrt', 'meldet', 'rita', 'zone', 'trocken', 'lincoln', 'schreibst', 'audrey', 'quinn', 'probier', 'le', 'kids', 'unterschrieben', 'do', 'heulen', 'entschlossen', 'paket', 'gefiel', 'bekamen', 'netten', 'geheime', 'jennifer', 'aktiviert', 'ausweg', 'hinweg', 'schmuck',\n 'ausgang', 'wunderschöne', 'zurückkommt', 'ann', 'illegal', 'ferien', 'persönlichen', 'geiseln', 'segne', 'normaler', 'steuer', 'aufgepasst', 'murphy', 'raumschiff', 'dummen', 'weißer', 'ausbildung', 'klavier', 'hauptsache', 'admiral', 'entgegen', 'fasse', 'strecke', 'julian', 'version', 'hilfreich', 'schweren', 'h', 'jahrelang', 'leeren', 'küste', 'baron', 'behörden', 'grüße', 'geklärt', 'bruders', 'kaufte', 'stone', 'puls', 'blue',\n 'flur', 'denselben', 'rettung', 'widerlich', 'parkplatz', 'katzen', 'laster', 'sozusagen', 'mittwoch', 'unschuldige', 'abwarten', 'grandma', 'florida', 're', 'grünen', 'könntet', 'aufnahmen', 'vision', 'schauspielerin', 'passe', 'sing', 'glückliche', 'highschool', 'friedhof', 'irrtum', 'klienten', 'nervt', 'leidet', 'reverend', 'trainieren', 'gegenwart', 'zurückbringen', 'herman', 'protokoll', 'studenten', 'durchaus', 'grausam', 'höchste', 'verwickelt', 'schmecken',\n 'klappen', 'apropos', 'liz', 'alfred', 'ansonsten', 'wade', 'missverständnis', 'mitglieder', 'motorrad', 'mickey', 'blicken', 'glücklicher', 'hübschen', 'dicke', 'gewünscht', 'gejagt', 'diejenigen', 'diskutieren', 'pinkeln', 'huhn', 'erheben', 'paradies', 'tagebuch', 'möglichen', 'jenseits', 'arschlöcher', 'apartment', 'mason', 'pfeift', 'dieselben', 'wilden', 'vergaß', 'enttäuschen', 'greg', 'konsequenzen', 'fleck', 'macgyver', 'führerschein', 'online', 'bete',\n 'verdächtige', 'enkel', 'normalen', 'stift', 'interview', 'süßen', 'riesige', 'aussicht', 'ned', 'wiederkommen', 'werbung', 'warf', 'telefoniert', 'anblick', 'einzelnen', 'teppich', 'hielten', 'handel', 'gekannt', 'getrieben', 'trainer', 'scully', 'schuh', 'bomben', 'kämpfer', 'victoria', 'bedenken', 'sitzung', 'ken', 'sicheren', 'verkaufe', 'ron', 'tapfer', 'experiment', 'besorge', 'tiefe', 'narren', 'abgeholt', 'abhalten', 'bestimmte',\n 'laufenden', 'auftaucht', 'school', 'löschen', 'tara', 'sebastian', 'mies', 'sarg', 'r', 'vertragen', 'gebissen', 'geheimen', 'drinks', 'schlief', 'tradition', 'soeben', 'komische', 'schultz', 'aufgehalten', 'fähigkeit', 'attraktiv', 'begriff', 'versichere', 'schilde', 'legte', 'mitteilen', 'sdh', 'gemütlich', 'muster', 'versprach', 'überwachen', 'eingeschlafen', 'schlimmsten', 'verlierst', 'einzelne', 'vergib', 'vorbeikommen', 'aua', 'brüste', 'sandwich',\n 'gewinner', 'verständnis', 'g', 'raymond', 'papst', 'toast', 'matthew', 'einsteigen', 'löwen', 'einsetzen', 'gewinn', 'schüchtern', 'scheinst', 'pflanzen', 'green', 'sheldon', 'christopher', 'hätt', 'coach', 'werte', 'modell', 'übernimmt', 'walton', 'heftig', 'vorfall', 'motel', 'teams', 'irgendeinen', 'müsstest', 'freier', 'zirkus', 'ruhm', 'zurzeit', 'ausmachen', 'rezept', 'töchter', 'laute', 'akzeptiert', 'geschwindigkeit', 'beliebt',\n 'verpflichtet', 'betrüger', 'lohnt', 'märchen', 'blöder', 'becky', 'wille', 'hügel', 'königreich', 'dennis', 'kehren', 'baut', 'chinesen', 'gesichert', 'michel', 'ruth', 'block', 'belogen', 'malen', 'kofferraum', 'road', 'bursche', 'erin', 'geständnis', 'ausgegangen', 'begreifen', 'dana', 'blitz', 'löst', 'furcht', 'jersey', 'ernstes', 'verteilt', 'bezüglich', 'faszinierend', 'aufmerksam', 'aufregung', 'wendy', 'ethan', 'orte',\n 'entführung', 'keucht', 'erhielt', 'treue', 'felsen', 'malcolm', 'kurzen', 'zorn', 'taucht', 'bestimmen', 'ausgesetzt', 'zurückgeben', 'verkehr', 'bewiesen', 'generation', 'liebste', 'ausrichten', 'ausnahme', 'ebene', 'herrlich', 'stürzen', 'herausforderung', 'gefälligst', 'farben', 'geliebten', 'ankommen', 'tempo', 'unterbrechen', 'kindes', 'babe', 'erden', 'schrecklichen', 'falsches', 'täuschen', 'tal', 'irgendwer', 'deins', 'witwe', 'sichern', 'gerede',\n 'betrug', 'trauer', 'anwesenheit', 'bilden', 'gewachsen', 'ausflug', 'jill', 'verlaufen', 'rand', 'kenny', 'rechnen', 'aufzug', 'befragen', 'wegnehmen', 'abschied', 'benötigen', 'pst', 'amt', 'reiche', 'otto', 'beginn', 'daumen', 'bestrafen', 'clarence', 'weine', 'fremder', 'sachte', 'identifiziert', 'gestehen', 'mac', 'owen', 'morris', 'riesig', 'entscheide', 'koma', 'prinzen', 'bewusstlos', 'county', 'marke', 'harter',\n 'hill', 'höflich', 'jude', 'setzte', 'besorg', 'absichtlich', 'vermasselt', 'verschlossen', 'sowie', 'gesang', 'gedreht', 'ford', 'religion', 'ey', 'unterschrift', 'rosen', 'persönliches', 'queen', 'fortschritte', 'eingang', 'zugehört', 'biete', 'clara', 'vorhaben', 'kultur', 'patientin', 'stephen', 'explodiert', 'nichte', 'verzichten', 'steven', 'harris', 'existenz', 'drehbuch', 'football', 'anzusehen', 'ohnmächtig', 'zaun', 'anthony', 'geladen',\n 'guckt', 'privat', 'peg', 'brauchten', 'liam', 'heb', 'virginia', 'wächter', 'eimer', 'blasen', 'rakete', 'salz', 'unfair', 'verzeiht', 'esel', 'krankenschwester', 'symbol', 'entscheidet', 'fahrzeug', 'unterwäsche', 'betrachtet', 'bauern', 'engländer', 'wartete', 'schaust', 'genossen', 'tropfen', 'probiert', 'spock', 'café', 'verhungern', 'versuchten', 'mütter', 'september', 'aktion', 'bestanden', 'haaren', 'louise', 'schluchzt', 'übertrieben',\n 'heilmittel', 'apparat', 'vorm', 'friedlich', 'richtiges', 'zuschauer', 'teenager', 'geliefert', 'may', 'gestritten', 'maus', 'lediglich', 'charakter', 'riley', 'krass', 'weiterer', 'group', 'ricky', 'diana', 'geräusche', 'lichter', 'starken', 'dexter', 'staffel', 'flaschen', 'putzen', 'einbruch', 'geheilt', 'beißen', 'nicole', 'stammen', 'wände', 'befürchte', 'kostüm', 'warren', 'grüßen', 'versagen', 'übernommen', 'hoffte', 'verschieben',\n 'verspätung', 'whiskey', 'mars', 'media', 'entdecken', 'traue', 'thron', 'riesigen', 'zelt', 'akzent', 'truppe', 'übertragen', 'kompliment', 'flammen', 'erkennst', 'erschrecken', 'gemälde', 'ari', 'walt', 'chip', 'mannschaft', 'cindy', 'loyalität', 'benjamin', 'dankeschön', 'vertreten', 'verhandlung', 'lernst', 'brüllt', 'füllen', 'letztendlich', 'krise', 'verlierer', 'spencer', 'with', 'kekse', 'ausschalten', 'penis', 'profi', 'whisky',\n 'erledige', 'gelächter', 'fängst', 'erklär', 'einspruch', 'angeln', 'rausgehen', 'monk', 'kaution', 'eures', 'gesessen', 'verrate', 'kehrt', 'boy', 'summe', 'lade', 'billig', 'curtis', 'bernard', 'juni', 'gerissen', 'festgenommen', 'ralph', 'befohlen', 'überlege', 'koordinaten', 'flog', 'herzinfarkt', 'hinlegen', 'nahrung', 'liege', 'geflohen', 'knall', 'nebenbei', 'mylord', 'nachbar', 'küss', 'lhrem', 'geleistet', 'nutzt',\n 'fröhliche', 'nebel', 'front', 'veränderung', 'affe', 'kontaktieren', 'brand', 'fuhren', 'zwischenzeit', 'eingesetzt', 'anton', 'philip', 'megan', 'schlimmeres', 'rennt', 'anlegen', 'nachzudenken', 'schwör', 'übliche', 'kreatur', 'verderben', 'medizinische', 'besetzt', 'zugriff', 'kanal', 'blutdruck', 'grüne', 'ausgeben', 'papi', 'clown', 'lhrer', 'sonny', 'schwören', 'hühnchen', 'arten', 'aufgebaut', 'sydney', 'betrügen', 'steele', 'trank',\n 'glatt', 'trainiert', 'indien', 'autor', 'geweint', 'blume', 'verletzungen', 'special', 'zwillinge', 'mia', 'reißt', 'zeigst', 'stirb', 'justin', 'diane', 'gefickt', 'schlägst', 'moskau', 'erwartest', 'gestoßen', 'durchgehen', 'praxis', 'gründlich', 'benny', 'eingeschlossen', 'tragödie', 'vollständig', 'psychiater', 'rasse', 'lance', 'vertraust', 'kummer', 'eigener', 'christine', 'partei', 'zentrum', 'testament', 'entfernung', 'private', 'welten',\n 'verlegen', 'heroin', 'erfuhr', 'gelände', 'kutsche', 'dummer', 'homer', 'stabil', 'ausgeschlossen', 'out', 'draus', 'aufgehoben', 'single', 'regisseur', 'vielmals', 'dylan', 'bestand', 'k', 'erbe', 'weggelaufen', 'jim-bob', 'noah', 'leichte', 'zuständig', 'losgehen', 'long', 'hustet', 'brutal', 'besprochen', 'halbes', 'bargeld', 'peggy', 'action', 'zusammenarbeiten', 'beunruhigt', 'achte', 'innere', 'kanone', 'eklig', 'x',\n 'armes', 'avenue', 'öffentlich', 'nützt', 'marine', 'brillant', 'köder', 'gespräche', 'nähert', 'vorgehen', 'kleinigkeit', 'kissen', 'manny', 'geisel', 'gerecht', 'trost', 'gehasst', 'a.', 'gesorgt', 'archer', 'spinner', 'vergebung', 'vieh', 'schnelle', 'normales', 'gefesselt', 'lautes', 'kalte', 'leitet', 'angehen', 'ekelhaft', 'salat', 'schicht', 'intelligent', 'meg', 'verhältnis', 'socken', 'brieftasche', 'holly', 'packt',\n 'eventuell', 'nirgendwohin', 'methode', 'gelangen', 'gespannt', 'vernunft', 'zurückgehen', 'regnet', 'drama', 'entspannt', 'wörter', 'klingeln', 'ruhige', 'sprung', 'anständig', 'gangster', 'harten', 'aufzeichnungen', 'ofen', 'cowboy', 'endgültig', 'aufgaben', 'ruh', 'deutsch', 'neil', 'wodka', 'know', 'air', 'respektieren', 'riskant', 'lohn', 'zuviel', 'zustimmen', 'schnaps', 'troy', 'stufe', 'erleichtert', 'scheune', 'vanessa', 'klink',\n 'spaziergang', 'katherine', 'zettel', 'kotzen', 'blödmann', 'hurra', 'lana', 'symptome', 'vorfahren', 'nutzlos', 'shaw', 'telefonnummer', 'nochmals', 'grey', 'medien', 'faul', 'dient', 'russell', 'ereignisse', 'aussuchen', 'verprügelt', 'zweites', 'sherlock', 'fabelhaft', 'klinge', 'leistung', 'beileid', 'castle', 'durchführen', 'mitchell', 'eröffnen', 'unschuld', 'seist', 'stoßen', 'palmer', 'like', 'genügend', 'sofa', 'gestatten', 'gekocht',\n 'biest', 'lydia', 'bräuchte', 'ausgelöst', 'väter', 'verarscht', 'butter', 'nachbarschaft', 'villa', 'data', 'goldene', 'schließe', 'saft', 'begehen', 'hauptquartier', 'geschworen', 'abgenommen', 'werkstatt', 'überreden', 'nannten', 'gemüse', 'schläger', 'frisst', 'bewundere', 'geschieden', 'assistentin', 'wettbewerb', 'lebten', 'sieger', 'verfassung', 'küsst', 'fußball', 'geschnitten', 'master', 'quietschen', 'füttern', 'gürtel', 'unschuldigen', 'menschlich', 'eigenartig',\n 'oje', 'hanna', 'kabel', 'duke', 'franz', 'zahn', 'landet', 'kisten', 'liegst', 'mona', 'krankenstation', 'leine', 'beschreibung', 'ausmacht', 'beschädigt', 'grundstück', 'steckte', 'bahn', 'turm', 'mine', 'sauerstoff', 'nö', 'angesichts', 'll', 'versager', 'deinetwegen', 'vic', 'angeklagt', 'aufhört', 'baden', 'knacken', 'verbindungen', 'panzer', 'marcel', 'bach', 'leiser', 'stimmengewirr', 'zerstörung', 'stirn', 'finn',\n 'sanft', 'kloster', 'charmant', 'aufbauen', 'thanksgiving', 'anlass', 'zähle', 'verlieben', 'atmosphäre', 'ronnie', 'samantha', 'leber', 'jener', 'begegnen', 'dämlich', 'krawatte', 'juan', 'tarnung', 'kanada', 'alpha', 'baker', 'tabletten', 'faust', 'auftreten', 'monroe', 'blatt', 'gelöscht', 'dschungel', 'alison', 'niedlich', 'c.', 'klage', 'wolltet', 'jonas', 'akt', 'schießerei', 'anwältin', 'überleg', 'frisur', 'spruch',\n 'jene', 'moral', 'angelegenheiten', 'dokumente', 'fröhlich', 'spezies', 'oktober', 'schachtel', 'opfers', 'noten', 'ellie', 'irgendwohin', 'nora', 'brunnen', 'toby', 'sandy', 'lampe', 'craig', 'jagt', 'eigentum', 'diebstahl', 'spenden', 'betrieb', 'gemeinsame', 'absurd', 'gegensatz', 'frühling', 'dünn', 'ausland', 'schultern', 'entwicklung', 'vergehen', 'ahnen', 'verbessern', 'herzog', 'diskussion', 'gehalt', 'lemon', 'freak', 'glocke'\n]);\n","/**\n * English Transition Words\n *\n * Transition words and phrases that signal logical flow between sentences.\n * Used by the content-low-transition-words rule to measure content coherence.\n *\n * Sources: Standard English linguistics references, independently compiled.\n * Thresholds inspired by Yoast SEO's readability analysis.\n */\n\nconst singleWords: readonly string[] = [\n 'accordingly', 'additionally', 'afterward', 'afterwards', 'albeit',\n 'also', 'although', 'altogether', 'basically', 'because', 'before',\n 'besides', 'but', 'certainly', 'chiefly', 'comparatively',\n 'concurrently', 'consequently', 'contrarily', 'conversely',\n 'correspondingly', 'despite', 'during', 'earlier', 'emphatically',\n 'equally', 'especially', 'eventually', 'evidently', 'explicitly',\n 'finally', 'firstly', 'following', 'formerly', 'furthermore',\n 'generally', 'hence', 'henceforth', 'however', 'identically',\n 'indeed', 'initially', 'instead', 'lastly', 'later', 'likewise',\n 'markedly', 'meanwhile', 'moreover', 'nevertheless', 'nonetheless',\n 'nor', 'notwithstanding', 'obviously', 'occasionally', 'otherwise',\n 'overall', 'particularly', 'presently', 'previously', 'rather',\n 'regardless', 'secondly', 'shortly', 'significantly', 'similarly',\n 'simultaneously', 'since', 'so', 'soon', 'specifically', 'still',\n 'subsequently', 'surely', 'surprisingly', 'than', 'then',\n 'thereafter', 'therefore', 'thereupon', 'thirdly', 'though',\n 'thus', 'undeniably', 'undoubtedly', 'unless', 'unlike',\n 'unquestionably', 'until', 'whereas', 'while', 'actually',\n 'anyway', 'anyhow', 'mostly', 'namely', 'including', 'suddenly',\n 'if', 'when', 'whenever', 'whether',\n] as const;\n\nconst multiWordPhrases: readonly string[] = [\n 'above all', 'after all', 'after that', 'all in all',\n 'all things considered', 'as a matter of fact', 'as a result',\n 'as an illustration', 'as can be seen', 'as has been noted',\n 'as long as', 'as much as', 'as opposed to', 'as shown above',\n 'as soon as', 'as well as', 'at any rate', 'at first', 'at last',\n 'at least', 'at length', 'at the same time', 'balanced against',\n 'being that', 'by all means', 'by and large', 'by comparison',\n 'by the same token', 'by the time', 'compared to',\n 'be that as it may', 'coupled with', 'different from', 'due to',\n 'equally important', 'even if', 'even more', 'even so',\n 'even though', 'for example', 'for instance', 'for one thing',\n 'for that reason', 'for the most part', 'for this reason',\n 'from time to time', 'given that', 'given these points',\n 'in a word', 'in addition', 'in any case', 'in any event',\n 'in brief', 'in case', 'in conclusion', 'in contrast',\n 'in detail', 'in effect', 'in either case', 'either way',\n 'in essence', 'in fact', 'in general', 'in light of',\n 'in like fashion', 'in like manner', 'in order to',\n 'in other words', 'in particular', 'in reality', 'in short',\n 'in similar fashion', 'in spite of', 'in sum', 'in summary',\n 'in that case', 'in the event that', 'in the first place',\n 'in the long run', 'in the meantime', 'in the same fashion',\n 'in the same way', 'in the second place', 'in the third place',\n 'in this case', 'in this situation', 'in time', 'in truth',\n 'in view of', 'most important', 'not only', 'not to mention',\n 'note that', 'now that', 'of course', 'on account of',\n 'on balance', 'on condition that', 'on one hand',\n 'on the condition that', 'on the contrary',\n 'on the other hand', 'on the whole', 'only if', 'owing to',\n 'prior to', 'provided that', 'seeing that', 'so as to',\n 'so far', 'so long as', 'so that', 'sooner or later',\n 'such as', 'summing up', 'that is', 'that is to say',\n 'then again', 'to begin with', 'to clarify', 'to conclude',\n 'to demonstrate', 'to emphasize', 'to explain', 'to illustrate',\n 'to put it another way', 'to put it differently', 'to repeat',\n 'to rephrase it', 'to say nothing of', 'to sum up',\n 'to summarize', 'to that end', 'together with',\n 'under those circumstances', 'until now', 'what is more',\n 'while it may be true', 'with this in mind', 'without a doubt',\n 'without delay', 'without doubt', 'according to', 'from now on',\n] as const;\n\n/** All English transition words and phrases (lowercased). */\nexport const TRANSITION_WORDS_EN: ReadonlySet<string> = new Set([\n ...singleWords,\n ...multiWordPhrases,\n]);\n\n/** Single-word transitions only (for fast set-membership checks). */\nexport const TRANSITION_SINGLE_WORDS_EN: ReadonlySet<string> = new Set(singleWords);\n\n/** Multi-word phrases only (checked via substring match). */\nexport const TRANSITION_PHRASES_EN: readonly string[] = multiWordPhrases;\n","/**\n * German Transition Words (Konjunktionen & Konnektoren)\n *\n * Transition words and phrases that signal logical flow between sentences.\n * Used by the content-low-transition-words rule to measure content coherence.\n *\n * Sources: Standard German linguistics references, independently compiled.\n */\n\nconst singleWords: readonly string[] = [\n 'aber', 'abschließend', 'allerdings', 'also', 'andererseits',\n 'anfänglich', 'anfangs', 'angenommen', 'anschließend', 'aufgrund',\n 'ausgenommen', 'außerdem', 'beispielsweise', 'bevor',\n 'beziehungsweise', 'bzw', 'da', 'dabei', 'dadurch', 'dafür',\n 'dagegen', 'daher', 'dahingegen', 'danach', 'dann', 'darauf',\n 'darum', 'dass', 'davor', 'dazu', 'dementsprechend', 'demgegenüber',\n 'demgemäß', 'demzufolge', 'denn', 'dennoch', 'derweil', 'desto',\n 'deshalb', 'deswegen', 'doch', 'drittens', 'ebenfalls', 'ebenso',\n 'ehe', 'einerseits', 'endlich', 'entsprechend', 'entweder', 'erst',\n 'erstens', 'falls', 'ferner', 'folgerichtig', 'folglich',\n 'genauso', 'gleichzeitig', 'hierdurch', 'hierzu', 'hingegen',\n 'immerhin', 'indem', 'indes', 'indessen', 'infolge',\n 'infolgedessen', 'insofern', 'insoweit', 'inzwischen',\n 'jedenfalls', 'jedoch', 'kurzum', 'mitnichten', 'mitunter',\n 'möglicherweise', 'nachdem', 'nebenher', 'nichtsdestotrotz',\n 'nichtsdestoweniger', 'ob', 'obenrein', 'obgleich', 'obschon',\n 'obwohl', 'obzwar', 'ohnehin', 'richtigerweise', 'schließlich',\n 'seit', 'seitdem', 'sobald', 'sodass', 'sofern', 'sogar',\n 'solange', 'somit', 'sondern', 'sooft', 'soviel', 'soweit',\n 'sowie', 'sowohl', 'statt', 'stattdessen', 'trotz', 'trotzdem',\n 'überdies', 'übrigens', 'ungeachtet', 'vielmehr', 'vorausgesetzt',\n 'vorher', 'während', 'währenddessen', 'weder', 'wegen', 'weil',\n 'weiter', 'weiterhin', 'wenn', 'wenngleich', 'wennschon',\n 'weshalb', 'widrigenfalls', 'wiewohl', 'wobei', 'wohingegen',\n 'zudem', 'zuerst', 'zufolge', 'zugleich', 'zuletzt', 'zumal',\n 'zunächst', 'zuvor', 'zwar', 'zweitens',\n] as const;\n\nconst multiWordPhrases: readonly string[] = [\n 'abgesehen von', 'abgesehen davon', 'als dass', 'als ob',\n 'als wenn', 'anders ausgedrückt', 'anders formuliert',\n 'anders gefasst', 'anders gefragt', 'anders gesagt',\n 'anders gesprochen', 'anstatt dass', 'auch wenn', 'auf grund',\n 'auf jeden fall', 'aus diesem grund', 'außer dass', 'außer wenn',\n 'besser ausgedrückt', 'besser formuliert', 'besser gesagt',\n 'besser gesprochen', 'bloß dass', 'darüber hinaus', 'das heißt',\n 'des weiteren', 'dessen ungeachtet', 'ebenso wie', 'genauso wie',\n 'geschweige denn', 'im fall', 'im falle', 'im folgenden',\n 'im gegensatz dazu', 'im gegenteil', 'im grunde genommen',\n 'in diesem sinne', 'je nachdem', 'kurz gesagt',\n 'mit anderen worten', 'ohne dass', 'so dass',\n 'umso mehr als', 'umso weniger als', 'unbeschadet dessen',\n 'und zwar', 'ungeachtet dessen', 'unter dem strich',\n 'zum beispiel', 'zunächst einmal',\n] as const;\n\n/** All German transition words and phrases (lowercased). */\nexport const TRANSITION_WORDS_DE: ReadonlySet<string> = new Set([\n ...singleWords,\n ...multiWordPhrases,\n]);\n\n/** Single-word transitions only (for fast set-membership checks). */\nexport const TRANSITION_SINGLE_WORDS_DE: ReadonlySet<string> = new Set(singleWords);\n\n/** Multi-word phrases only (checked via substring match). */\nexport const TRANSITION_PHRASES_DE: readonly string[] = multiWordPhrases;\n","/**\n * English First Word Exceptions\n *\n * Function words that should be skipped when checking for consecutive\n * sentence beginnings. When a sentence starts with one of these, the\n * analyzer uses the second word instead (e.g., \"The dog\" → \"dog\").\n */\nexport const FIRST_WORD_EXCEPTIONS_EN: ReadonlySet<string> = new Set([\n // Articles\n 'the', 'a', 'an',\n // Demonstratives\n 'this', 'that', 'these', 'those',\n // Cardinal numbers (1–10)\n 'one', 'two', 'three', 'four', 'five',\n 'six', 'seven', 'eight', 'nine', 'ten',\n]);\n","/**\n * German First Word Exceptions (Funktionswörter)\n *\n * Function words that should be skipped when checking for consecutive\n * sentence beginnings. When a sentence starts with one of these, the\n * analyzer uses the second word instead.\n */\nexport const FIRST_WORD_EXCEPTIONS_DE: ReadonlySet<string> = new Set([\n // Definite articles (all cases)\n 'der', 'die', 'das', 'dem', 'den', 'des',\n // Indefinite articles (all cases)\n 'ein', 'eine', 'einem', 'einen', 'einer', 'eines',\n // Demonstrative pronouns\n 'diese', 'dieser', 'dieses', 'diesem', 'diesen',\n 'jene', 'jener', 'jenes', 'jenem', 'jenen',\n 'welch', 'welcher', 'welches',\n // Cardinal numbers (1–10)\n 'eins', 'zwei', 'drei', 'vier', 'fünf',\n 'sechs', 'sieben', 'acht', 'neun', 'zehn',\n]);\n","/**\n * Language Data Registry\n * Provides locale-aware access to frequency lists, transition words,\n * and first-word exception lists.\n */\n\nimport { FREQUENCY_EN } from './frequency-en.js';\nimport { FREQUENCY_DE } from './frequency-de.js';\nimport { TRANSITION_SINGLE_WORDS_EN, TRANSITION_PHRASES_EN } from './transition-words-en.js';\nimport { TRANSITION_SINGLE_WORDS_DE, TRANSITION_PHRASES_DE } from './transition-words-de.js';\nimport { FIRST_WORD_EXCEPTIONS_EN } from './first-word-exceptions-en.js';\nimport { FIRST_WORD_EXCEPTIONS_DE } from './first-word-exceptions-de.js';\n\n// ---------------------------------------------------------------------------\n// Frequency Lists\n// ---------------------------------------------------------------------------\n\nconst FREQUENCY_LISTS: Record<string, ReadonlySet<string>> = {\n en: FREQUENCY_EN,\n de: FREQUENCY_DE,\n};\n\n/** Get the frequency word list for a locale. Returns undefined for unsupported locales. */\nexport function getFrequencyList(locale: string): ReadonlySet<string> | undefined {\n return FREQUENCY_LISTS[locale.toLowerCase()];\n}\n\n/** Check whether a frequency list exists for the given locale. */\nexport function hasFrequencyList(locale: string): boolean {\n return locale.toLowerCase() in FREQUENCY_LISTS;\n}\n\n/** All supported frequency list locales. */\nexport const SUPPORTED_FREQUENCY_LOCALES = Object.keys(FREQUENCY_LISTS);\n\n// ---------------------------------------------------------------------------\n// Transition Words\n// ---------------------------------------------------------------------------\n\ninterface TransitionWordData {\n singleWords: ReadonlySet<string>;\n phrases: readonly string[];\n}\n\nconst TRANSITION_WORD_DATA: Record<string, TransitionWordData> = {\n en: { singleWords: TRANSITION_SINGLE_WORDS_EN, phrases: TRANSITION_PHRASES_EN },\n de: { singleWords: TRANSITION_SINGLE_WORDS_DE, phrases: TRANSITION_PHRASES_DE },\n};\n\n/** Get transition word data for a locale. Returns undefined for unsupported locales. */\nexport function getTransitionWords(locale: string): TransitionWordData | undefined {\n return TRANSITION_WORD_DATA[locale.toLowerCase()];\n}\n\n// ---------------------------------------------------------------------------\n// First Word Exceptions (for consecutive sentence beginnings check)\n// ---------------------------------------------------------------------------\n\nconst FIRST_WORD_EXCEPTION_LISTS: Record<string, ReadonlySet<string>> = {\n en: FIRST_WORD_EXCEPTIONS_EN,\n de: FIRST_WORD_EXCEPTIONS_DE,\n};\n\n/** Get first-word exceptions for a locale. Returns empty set for unsupported locales. */\nexport function getFirstWordExceptions(locale: string): ReadonlySet<string> {\n return FIRST_WORD_EXCEPTION_LISTS[locale.toLowerCase()] ?? new Set();\n}\n","/**\n * Word Complexity Analyzer\n * Dynamic word complexity detection using a Yoast + Gunning Fog hybrid heuristic.\n *\n * A word is classified as complex when ALL conditions are met:\n * 1. Character length exceeds the locale threshold (EN: >7, DE: >10)\n * 2. Syllable count >= 3 (Gunning Fog signal)\n * 3. NOT in the locale's top-5K frequency list (Yoast signal)\n * 4. NOT a capitalized proper noun (skipped for German — all nouns are capitalized)\n */\n\nimport { stripMarkdown } from './word-counter.js';\nimport { estimateSyllables } from './readability.js';\nimport { getFrequencyList } from '../data/index.js';\n\n// ─── Locale Configuration ────────────────────────────────────────────────────\n\nexport interface LocaleComplexityConfig {\n /** Minimum character length to consider a word potentially complex */\n minLength: number;\n /** Minimum syllable count to flag as complex */\n minSyllables: number;\n /** Whether to skip capitalized words (proper nouns). False for German. */\n skipCapitalized: boolean;\n}\n\nconst LOCALE_CONFIGS: Record<string, LocaleComplexityConfig> = {\n en: { minLength: 7, minSyllables: 3, skipCapitalized: true },\n de: { minLength: 10, minSyllables: 3, skipCapitalized: false },\n};\n\nconst DEFAULT_CONFIG: LocaleComplexityConfig = {\n minLength: 7,\n minSyllables: 3,\n skipCapitalized: true,\n};\n\n/** Get the complexity config for a locale. Falls back to English-like defaults. */\nexport function getLocaleConfig(locale: string): LocaleComplexityConfig {\n return LOCALE_CONFIGS[locale.toLowerCase()] ?? DEFAULT_CONFIG;\n}\n\n// ─── Word Classification ─────────────────────────────────────────────────────\n\n/**\n * Determine whether a single word is complex.\n *\n * @param normalizedWord - Lowercased word for frequency/length checks\n * @param originalWord - Original-case word for capitalization checks\n * @param config - Locale-specific complexity thresholds\n * @param frequencyList - Top-frequency words that are never flagged\n */\nexport function isComplexWord(\n normalizedWord: string,\n originalWord: string,\n config: LocaleComplexityConfig,\n frequencyList: ReadonlySet<string> | undefined,\n locale: string = 'en',\n): boolean {\n // Short words are never complex\n if (normalizedWord.length <= config.minLength) return false;\n\n // Words with fewer than minSyllables are not complex\n if (estimateSyllables(normalizedWord, locale) < config.minSyllables) return false;\n\n // Common words (in frequency list) are not complex\n if (frequencyList?.has(normalizedWord)) return false;\n\n // In English, skip capitalized words (likely proper nouns)\n if (config.skipCapitalized && /^[A-Z]/.test(originalWord)) return false;\n\n return true;\n}\n\n// ─── Full-Text Analysis ──────────────────────────────────────────────────────\n\nexport interface ComplexityAnalysis {\n /** Number of words classified as complex */\n complexCount: number;\n /** Total words analyzed */\n totalWords: number;\n /** Ratio of complex words to total (0-1) */\n density: number;\n /** Top complex words sorted by frequency descending */\n topComplexWords: Array<{ word: string; count: number }>;\n}\n\n/**\n * Analyze word complexity across an entire body of text.\n *\n * @param body - Markdown/MDX content body\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'en'.\n */\nexport function analyzeWordComplexity(body: string, locale: string = 'en'): ComplexityAnalysis {\n const config = getLocaleConfig(locale);\n const frequencyList = getFrequencyList(locale);\n\n const plain = stripMarkdown(body);\n // Split into words, preserving original casing for proper-noun detection\n const rawWords = plain\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n const totalWords = rawWords.length;\n const complexCounts = new Map<string, number>();\n let complexCount = 0;\n\n for (const original of rawWords) {\n const normalized = original.toLowerCase();\n if (isComplexWord(normalized, original, config, frequencyList, locale)) {\n complexCount++;\n complexCounts.set(normalized, (complexCounts.get(normalized) ?? 0) + 1);\n }\n }\n\n const topComplexWords = [...complexCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([word, count]) => ({ word, count }));\n\n return {\n complexCount,\n totalWords,\n density: totalWords > 0 ? complexCount / totalWords : 0,\n topComplexWords,\n };\n}\n","/**\n * Content Quality Analyzer\n * Detects jargon stuffing, content repetition, extreme sentence length,\n * low substance (type-token ratio), and monotonous sentence length in content.\n */\n\nimport { stripMarkdown, countWords } from './word-counter.js';\nimport { analyzeWordComplexity } from './word-complexity.js';\nimport { extractSentences } from './geo-advanced-analyzer.js';\n\n// ─── Jargon / Word Complexity Detection ─────────────────────────────────────\n\nexport interface JargonAnalysis {\n jargonCount: number;\n totalWords: number;\n density: number;\n topJargonWords: Array<{ word: string; count: number }>;\n}\n\n/**\n * Analyze jargon density in content body using dynamic word complexity heuristics.\n * Delegates to analyzeWordComplexity which uses syllable count, word length,\n * and frequency lists instead of a hardcoded word list.\n *\n * @param body - Content body (Markdown/MDX)\n * @param locale - BCP-47 locale code (e.g. 'en', 'de'). Defaults to 'en'.\n */\nexport function analyzeJargonDensity(body: string, locale: string = 'en'): JargonAnalysis {\n const result = analyzeWordComplexity(body, locale);\n\n return {\n jargonCount: result.complexCount,\n totalWords: result.totalWords,\n density: result.density,\n topJargonWords: result.topComplexWords,\n };\n}\n\n// ─── Content Repetition Detection ──────────────────────────────────────────\n\nexport interface RepetitionAnalysis {\n repeatedPhraseCount: number;\n maxPhraseOccurrences: number;\n topRepeatedPhrases: Array<{ phrase: string; count: number }>;\n avgParagraphSimilarity: number;\n}\n\n/** Extract n-grams from a word array. */\nfunction extractNgrams(words: string[], n: number): string[] {\n const ngrams: string[] = [];\n for (let i = 0; i <= words.length - n; i++) {\n ngrams.push(words.slice(i, i + n).join(' '));\n }\n return ngrams;\n}\n\n/** Calculate Jaccard similarity between two sets. */\nfunction jaccardSimilarity(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n let intersection = 0;\n for (const item of a) {\n if (b.has(item)) intersection++;\n }\n const union = a.size + b.size - intersection;\n return union > 0 ? intersection / union : 0;\n}\n\n/** Common reference/citation boilerplate patterns to exclude from repetition analysis */\nconst REFERENCE_PATTERNS: RegExp[] = [\n /archived from the original on/gi,\n /retrieved (?:on )?\\d/gi,\n /accessed (?:on )?\\d/gi,\n /cite (?:web|book|journal|news)/gi,\n /\\^\\s*\\[?\\d+\\]?/g,\n /isbn \\d/gi,\n /doi:\\s*\\d/gi,\n /pmid:\\s*\\d/gi,\n];\n\n/** Strip reference boilerplate before repetition analysis */\nfunction stripReferenceBoilerplate(text: string): string {\n let result = text;\n for (const pattern of REFERENCE_PATTERNS) {\n result = result.replace(pattern, '');\n }\n result = result.replace(/\\n(?:references|sources|bibliography|einzelnachweise|weblinks)\\n[\\s\\S]*$/i, '');\n return result;\n}\n\n/** Analyze content for repetitive phrases and paragraph similarity. */\nexport function analyzeRepetition(body: string): RepetitionAnalysis {\n const cleaned = stripReferenceBoilerplate(body);\n const plain = stripMarkdown(cleaned).toLowerCase();\n const words = plain\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n // Find repeated 5-grams across the entire text\n const fiveGrams = extractNgrams(words, 5);\n const phraseCounts = new Map<string, number>();\n\n for (const gram of fiveGrams) {\n phraseCounts.set(gram, (phraseCounts.get(gram) ?? 0) + 1);\n }\n\n // Filter to phrases that appear 3+ times\n const repeatedPhrases = [...phraseCounts.entries()]\n .filter(([, count]) => count >= 3)\n .sort((a, b) => b[1] - a[1]);\n\n const topRepeatedPhrases = repeatedPhrases\n .slice(0, 5)\n .map(([phrase, count]) => ({ phrase, count }));\n\n // Calculate pairwise paragraph similarity using 3-gram overlap\n const paragraphs = cleaned\n .split(/\\n\\s*\\n/)\n .map(p => p.trim())\n .filter(p => p.length > 0 && !p.startsWith('#') && !p.startsWith('|'));\n\n let totalSimilarity = 0;\n let pairCount = 0;\n\n for (let i = 0; i < paragraphs.length; i++) {\n const wordsI = stripMarkdown(paragraphs[i]).toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n const ngramsI = new Set(extractNgrams(wordsI, 3));\n\n for (let j = i + 1; j < paragraphs.length; j++) {\n const wordsJ = stripMarkdown(paragraphs[j]).toLowerCase()\n .replace(/[^\\p{L}\\p{N}\\s]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n const ngramsJ = new Set(extractNgrams(wordsJ, 3));\n\n totalSimilarity += jaccardSimilarity(ngramsI, ngramsJ);\n pairCount++;\n }\n }\n\n return {\n repeatedPhraseCount: repeatedPhrases.length,\n maxPhraseOccurrences: repeatedPhrases.length > 0 ? repeatedPhrases[0][1] : 0,\n topRepeatedPhrases,\n avgParagraphSimilarity: pairCount > 0 ? totalSimilarity / pairCount : 0,\n };\n}\n\n// ─── Sentence Length Analysis ──────────────────────────────────────────────\n\nexport interface SentenceLengthAnalysis {\n avgWordsPerSentence: number;\n maxWordsPerSentence: number;\n sentencesOver60Words: number;\n totalSentences: number;\n}\n\n/** Analyze sentence lengths in content. */\nexport function analyzeSentenceLength(body: string): SentenceLengthAnalysis {\n const plain = stripMarkdown(body);\n\n // Split into sentences on .!? followed by whitespace or end of string\n const sentences = plain\n .split(/(?<=[.!?])\\s+/)\n .map(s => s.trim())\n .filter(s => s.length > 0);\n\n if (sentences.length === 0) {\n return { avgWordsPerSentence: 0, maxWordsPerSentence: 0, sentencesOver60Words: 0, totalSentences: 0 };\n }\n\n let totalWordCount = 0;\n let maxWords = 0;\n let over60 = 0;\n\n for (const sentence of sentences) {\n const wordCount = sentence.split(/\\s+/).filter(w => w.length > 0).length;\n totalWordCount += wordCount;\n if (wordCount > maxWords) maxWords = wordCount;\n if (wordCount > 60) over60++;\n }\n\n return {\n avgWordsPerSentence: totalWordCount / sentences.length,\n maxWordsPerSentence: maxWords,\n sentencesOver60Words: over60,\n totalSentences: sentences.length,\n };\n}\n\n// ─── Substance Ratio (Type-Token Ratio) ────────────────────────────────────\n\n/** Common English stop words to exclude from substance analysis. */\nconst SUBSTANCE_STOPWORDS = new Set([\n 'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',\n 'of', 'with', 'by', 'from', 'is', 'are', 'was', 'were', 'be', 'been',\n 'being', 'has', 'have', 'had', 'do', 'does', 'did', 'will', 'would',\n 'could', 'should', 'may', 'might', 'shall', 'can', 'this', 'that',\n 'these', 'those', 'it', 'its', 'not', 'no', 'as', 'if', 'so', 'than',\n 'also', 'very', 'just', 'about', 'up', 'out', 'all', 'each', 'every',\n 'both', 'few', 'more', 'most', 'other', 'some', 'such', 'only', 'own',\n 'same', 'into', 'over', 'after', 'before', 'between', 'through',\n 'during', 'above', 'below', 'which', 'who', 'whom', 'what', 'when',\n 'where', 'why', 'how', 'they', 'them', 'their', 'we', 'us', 'our',\n 'you', 'your', 'he', 'him', 'his', 'she', 'her',\n // German\n 'der', 'die', 'das', 'ein', 'eine', 'und', 'oder', 'aber', 'in',\n 'auf', 'an', 'mit', 'von', 'zu', 'für', 'ist', 'sind', 'den', 'dem',\n 'des', 'nicht', 'sich', 'auch', 'als', 'noch', 'wie', 'bei', 'aus',\n 'nach', 'über', 'vor', 'nur', 'noch', 'man', 'bis', 'zum', 'zur',\n]);\n\nexport interface SubstanceAnalysis {\n uniqueContentWords: number;\n totalContentWords: number;\n typeTokenRatio: number;\n}\n\n/** Analyze substance ratio: how many unique meaningful words vs total. */\nexport function analyzeSubstance(body: string): SubstanceAnalysis {\n const plain = stripMarkdown(body).toLowerCase();\n const words = plain\n .replace(/[^\\p{L}\\p{N}\\s-]/gu, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 2 && !SUBSTANCE_STOPWORDS.has(w));\n\n const uniqueWords = new Set(words);\n\n return {\n uniqueContentWords: uniqueWords.size,\n totalContentWords: words.length,\n typeTokenRatio: words.length > 0 ? uniqueWords.size / words.length : 0,\n };\n}\n\n// ─── FAQ Quality Analysis ──────────────────────────────────────────────────\n\nexport interface FaqQualityAnalysis {\n hasSection: boolean;\n questionCount: number;\n avgAnswerWordCount: number;\n shortAnswers: number;\n}\n\n/** Analyze FAQ section quality: number of Q&As and answer lengths. */\nexport function analyzeFaqQuality(body: string): FaqQualityAnalysis {\n const faqPattern = /#{2,3}\\s*(FAQ|Häufige Fragen|Frequently Asked|Fragen und Antworten)/i;\n const faqMatch = body.match(faqPattern);\n\n if (!faqMatch) {\n return { hasSection: false, questionCount: 0, avgAnswerWordCount: 0, shortAnswers: 0 };\n }\n\n // Extract everything after the FAQ heading\n const faqStart = body.indexOf(faqMatch[0]);\n const faqContent = body.slice(faqStart + faqMatch[0].length);\n\n // Find Q&A pairs: sub-headings (###) followed by answer text\n const qaPairs = faqContent.split(/#{3}\\s+/).filter(s => s.trim().length > 0);\n\n let totalAnswerWords = 0;\n let shortAnswers = 0;\n\n for (const pair of qaPairs) {\n // First line is the question, rest is the answer\n const lines = pair.split('\\n').filter(l => l.trim().length > 0);\n const answerText = lines.slice(1).join(' ');\n const wordCount = countWords(answerText);\n totalAnswerWords += wordCount;\n\n if (wordCount < 20) {\n shortAnswers++;\n }\n }\n\n return {\n hasSection: true,\n questionCount: qaPairs.length,\n avgAnswerWordCount: qaPairs.length > 0 ? totalAnswerWords / qaPairs.length : 0,\n shortAnswers,\n };\n}\n\n// ─── Sentence Variety Analysis ─────────────────────────────────────────────\n\nexport interface SentenceVarietyAnalysis {\n /** Mean sentence length in words */\n avgLength: number;\n /** Standard deviation of sentence lengths */\n stdDev: number;\n /** Coefficient of variation (stdDev / avgLength) — normalized measure */\n coefficientOfVariation: number;\n /** Total sentences analyzed */\n totalSentences: number;\n}\n\n/**\n * Analyze sentence length variety using coefficient of variation.\n * Low CV = monotonous (all sentences are similar length).\n * High CV = varied (mix of short and long sentences).\n *\n * @example\n * analyzeSentenceVariety(\"Short one. Another short. Yet another short.\")\n * // { coefficientOfVariation: ~0.1, ... } — very monotonous\n */\nexport function analyzeSentenceVariety(body: string): SentenceVarietyAnalysis {\n const sentences = extractSentences(body);\n\n if (sentences.length < 2) {\n return { avgLength: 0, stdDev: 0, coefficientOfVariation: 0, totalSentences: sentences.length };\n }\n\n const lengths = sentences.map(s => s.wordCount);\n const mean = lengths.reduce((sum, l) => sum + l, 0) / lengths.length;\n\n if (mean === 0) {\n return { avgLength: 0, stdDev: 0, coefficientOfVariation: 0, totalSentences: sentences.length };\n }\n\n const variance = lengths.reduce((sum, l) => sum + (l - mean) ** 2, 0) / lengths.length;\n const stdDev = Math.sqrt(variance);\n const cv = stdDev / mean;\n\n return {\n avgLength: Math.round(mean * 10) / 10,\n stdDev: Math.round(stdDev * 10) / 10,\n coefficientOfVariation: Math.round(cv * 100) / 100,\n totalSentences: sentences.length,\n };\n}\n\n// ─── Citation Quality Analysis ─────────────────────────────────────────────\n\nexport interface CitationQualityAnalysis {\n totalStats: number;\n attributedStats: number;\n unattributedStats: number;\n}\n\n/** Check whether statistics have source attribution. */\nexport function analyzeCitationQuality(body: string): CitationQualityAnalysis {\n const lines = body.split('\\n');\n\n // Stat patterns: percentages, multipliers, currency, large numbers\n const statPatterns = [\n /\\d+\\s*%/g,\n /\\d+(?:\\.\\d+)?\\s*(?:x|mal|times)/gi,\n /(?:€|\\$|USD|EUR)\\s*\\d+/g,\n /\\d+(?:\\.\\d+)?\\s*(?:million|billion|mrd|mio)/gi,\n ];\n\n // Attribution patterns that should appear near statistics\n const attributionPatterns = [\n /according to\\b/i,\n /(?:a |the )?study (?:by|from)\\b/i,\n /research (?:by|from)\\b/i,\n /data from\\b/i,\n /report(?:ed)? by\\b/i,\n /source:\\s/i,\n /\\[[^\\]]+\\]\\(https?:\\/\\/[^)]+\\)/, // markdown link\n /\\[\\^[^\\]]+\\]/, // footnote\n ];\n\n let totalStats = 0;\n let attributedStats = 0;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n let hasStatOnLine = false;\n\n for (const pattern of statPatterns) {\n const matches = line.matchAll(pattern);\n for (const _ of matches) {\n if (!hasStatOnLine) {\n hasStatOnLine = true;\n totalStats++;\n\n // Check the surrounding context (3 lines before and after) for attribution\n const contextStart = Math.max(0, i - 3);\n const contextEnd = Math.min(lines.length - 1, i + 3);\n const context = lines.slice(contextStart, contextEnd + 1).join(' ');\n\n const hasAttribution = attributionPatterns.some(p => p.test(context));\n if (hasAttribution) {\n attributedStats++;\n }\n }\n }\n }\n }\n\n return {\n totalStats,\n attributedStats,\n unattributedStats: totalStats - attributedStats,\n };\n}\n","/**\n * GEO (Generative Engine Optimization) Rules\n * Validates content readiness for LLM-based search and AI visibility\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n countQuestionHeadings,\n analyzeLeadSentences,\n countStatistics,\n hasFAQSection,\n hasMarkdownTable,\n countEntityMentions,\n analyzeCitationBlocks,\n} from '../utils/geo-analyzer.js';\nimport {\n analyzeCitationQuality,\n analyzeFaqQuality,\n} from '../utils/content-quality-analyzer.js';\n\n/** Minimum word count before GEO rules apply */\nconst GEO_MIN_WORDS = 500;\n\n/** Minimum word count before FAQ section rule applies */\nconst FAQ_MIN_WORDS = 800;\n\n/** Minimum percentage of headings that should be question-formatted */\nconst QUESTION_HEADING_THRESHOLD = 0.2;\n\n/** Minimum percentage of sections with direct answer leads */\nconst DIRECT_ANSWER_THRESHOLD = 0.5;\n\n/** Expected data points per N words */\nconst CITATION_WORDS_PER_STAT = 500;\n\n/** Minimum word count before table rule applies */\nconst TABLE_MIN_WORDS = 1000;\n\n/** Minimum word count before entity density rule applies */\nconst ENTITY_MIN_WORDS = 800;\n\n/** Minimum word count before citation block rule applies */\nconst CITATION_BLOCK_MIN_WORDS = 800;\n\n/** Minimum words for a first paragraph to qualify as a citation block */\nconst CITATION_BLOCK_WORD_THRESHOLD = 40;\n\n/** Minimum ratio of sections that should have adequate citation blocks */\nconst CITATION_BLOCK_SECTION_THRESHOLD = 0.5;\n\n/**\n * Rule: Blog posts should use question-formatted headings for LLM discoverability\n * At least 20% of H2/H3 headings should be questions\n */\nexport const geoNoQuestionHeadings: Rule = {\n name: 'geo-no-question-headings',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Rephrase some headings as questions (e.g., \"How does X work?\")',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body, item.contentSource);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n\n if (subHeadings.length === 0) return [];\n\n const questionCount = countQuestionHeadings(item.body, item.contentSource);\n const ratio = questionCount / subHeadings.length;\n\n if (ratio < QUESTION_HEADING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-no-question-headings',\n severity: 'warning',\n message: `Only ${questionCount}/${subHeadings.length} (${Math.round(ratio * 100)}%) H2/H3 headings are question-formatted — aim for at least ${Math.round(QUESTION_HEADING_THRESHOLD * 100)}%`,\n suggestion: 'Rephrase some headings as questions (e.g., \"How does X work?\" / \"Was ist X?\") to improve LLM snippet extraction.',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Sections should start with direct answers, not filler introductions\n * At least 50% of sections should lead with substantive first sentences\n */\nexport const geoWeakLeadSentences: Rule = {\n name: 'geo-weak-lead-sentences',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a concise factual sentence that directly answers the heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const { totalSections, sectionsWithDirectAnswers } = analyzeLeadSentences(item.body);\n\n if (totalSections === 0) return [];\n\n const ratio = sectionsWithDirectAnswers / totalSections;\n\n if (ratio < DIRECT_ANSWER_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-weak-lead-sentences',\n severity: 'warning',\n message: `Only ${sectionsWithDirectAnswers}/${totalSections} (${Math.round(ratio * 100)}%) sections start with direct answers — aim for at least ${Math.round(DIRECT_ANSWER_THRESHOLD * 100)}%`,\n suggestion: 'Start each section with a concise factual sentence that directly answers the heading. Avoid filler like \"In this section...\" or \"Let\\'s look at...\".',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Content should include statistical data points for citation potential\n * Expect at least 1 data point per 500 words\n */\nexport const geoLowCitationDensity: Rule = {\n name: 'geo-low-citation-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add statistics with source attribution (e.g., \"According to [Study], 73% of...\")',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < GEO_MIN_WORDS) return [];\n\n const statCount = countStatistics(item.body);\n const expectedMin = Math.floor(wordCount / CITATION_WORDS_PER_STAT);\n\n if (statCount < expectedMin) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-citation-density',\n severity: 'warning',\n message: `Found ${statCount} data points but expected at least ${expectedMin} (1 per ${CITATION_WORDS_PER_STAT} words in ${wordCount}-word post)`,\n suggestion: 'Add statistics, percentages, or concrete numbers to increase citation potential in AI-generated answers.',\n }];\n }\n\n // Stats exist — check whether they have source attribution\n const citationQuality = analyzeCitationQuality(item.body);\n if (citationQuality.totalStats > 0 && citationQuality.unattributedStats > 0) {\n const ratio = citationQuality.attributedStats / citationQuality.totalStats;\n if (ratio < 0.5) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-citation-density',\n severity: 'warning',\n message: `${citationQuality.unattributedStats}/${citationQuality.totalStats} statistics lack source attribution`,\n suggestion: 'Add sources for your statistics (e.g., \"According to [Study Name]...\", link to source, or footnote). Unsourced stats reduce credibility for AI citation.',\n }];\n }\n }\n\n return [];\n },\n};\n\n/**\n * Rule: Longer blog posts should include a FAQ section for LLM extraction\n * Applies to posts with 800+ words\n */\nexport const geoMissingFaqSection: Rule = {\n name: 'geo-missing-faq-section',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add an \"## FAQ\" or \"## Frequently Asked Questions\" section with 3+ Q&A pairs (min 20 words each)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FAQ_MIN_WORDS) return [];\n\n if (!hasFAQSection(item.body, item.contentSource)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: 'No FAQ section detected in long-form content',\n suggestion: 'Add an \"## FAQ\" or \"## Häufige Fragen\" section with Q&A pairs. FAQ sections are frequently extracted by LLMs and featured in AI answers.',\n }];\n }\n\n // FAQ section exists — validate its quality\n const faqQuality = analyzeFaqQuality(item.body);\n\n const results: LintResult[] = [];\n\n if (faqQuality.questionCount < 3) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: `FAQ section has only ${faqQuality.questionCount} question(s) — aim for at least 3`,\n suggestion: 'Add more Q&A pairs to your FAQ section. LLMs prefer comprehensive FAQ sections with at least 3 questions.',\n });\n }\n\n if (faqQuality.shortAnswers > 0) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-faq-section',\n severity: 'warning',\n message: `${faqQuality.shortAnswers} FAQ answer(s) are too short (under 20 words, avg: ${Math.round(faqQuality.avgAnswerWordCount)} words)`,\n suggestion: 'Expand FAQ answers to at least 20 words each. Short one-line answers provide little value to AI citation engines.',\n });\n }\n\n return results;\n },\n};\n\n/**\n * Rule: Long-form blog posts should contain at least one data table\n * Tables are highly extractable by AI systems and increase citation rates\n * Applies to posts with 1000+ words\n */\nexport const geoMissingTable: Rule = {\n name: 'geo-missing-table',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a comparison table, feature matrix, or data summary table',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < TABLE_MIN_WORDS) return [];\n\n if (!hasMarkdownTable(item.body, item.contentSource)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-table',\n severity: 'warning',\n message: 'No data table found in long-form content (tables increase AI citation rates by 2.5x)',\n suggestion: 'Add a comparison table, feature matrix, or data summary table. Tables are highly extractable by AI systems and increase citation likelihood.',\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Rule: H2 sections should start with substantial \"citation blocks\"\n * AI systems extract the first paragraph after headings as citation snippets.\n * At least 50% of sections should have first paragraphs of 40+ words.\n * Applies to posts with 800+ words\n */\nexport const geoShortCitationBlocks: Rule = {\n name: 'geo-short-citation-blocks',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a 40-60 word paragraph that directly answers the heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < CITATION_BLOCK_MIN_WORDS) return [];\n\n const { totalSections, sectionsWithAdequateBlocks } = analyzeCitationBlocks(item.body);\n\n if (totalSections === 0) return [];\n\n const ratio = sectionsWithAdequateBlocks / totalSections;\n\n if (ratio < CITATION_BLOCK_SECTION_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-short-citation-blocks',\n severity: 'warning',\n message: `Only ${sectionsWithAdequateBlocks}/${totalSections} sections have substantial lead paragraphs (${CITATION_BLOCK_WORD_THRESHOLD}+ words) — AI systems extract these as citation blocks`,\n suggestion: `Start each section with a ${CITATION_BLOCK_WORD_THRESHOLD}-60 word paragraph that directly answers the heading question. These 'citation blocks' are what AI systems extract and cite.`,\n }];\n }\n\n return [];\n },\n};\n\n/**\n * Factory: Create the entity density rule with project-specific brand/city\n * When brandName is empty, the brand check is skipped.\n * When brandCity is empty, the city check is skipped.\n */\nexport function createGeoEntityRule(brandName: string, brandCity: string): Rule {\n return {\n name: 'geo-low-entity-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Mention brand name and location naturally in the content body',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < ENTITY_MIN_WORDS) return [];\n\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n if (brandName && countEntityMentions(item.body, brandName) === 0) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-low-entity-density',\n severity: 'warning',\n message: `Brand name '${brandName}' not mentioned in content body — reduces entity recognition by AI systems`,\n suggestion: 'Mention the brand name naturally in the content to strengthen entity signals for AI systems.',\n });\n }\n\n if (brandCity && countEntityMentions(item.body, brandCity) === 0) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-low-entity-density',\n severity: 'warning',\n message: `Location '${brandCity}' not mentioned in content body — reduces local entity recognition`,\n suggestion: 'Include a location reference to strengthen local entity recognition for AI search.',\n });\n }\n\n return results;\n },\n };\n}\n\n/** Static GEO rules (no config dependency) */\nexport const geoStaticRules: Rule[] = [\n geoNoQuestionHeadings,\n geoWeakLeadSentences,\n geoLowCitationDensity,\n geoMissingFaqSection,\n geoMissingTable,\n geoShortCitationBlocks,\n];\n\n/**\n * Factory: Build the complete GEO rule set from config\n * Returns all 7 rules: 6 static + 1 entity density from factory\n */\nexport function createGeoRules(geo: { brandName: string; brandCity: string }): Rule[] {\n return [\n ...geoStaticRules,\n createGeoEntityRule(geo.brandName, geo.brandCity),\n ];\n}\n\n/**\n * Alias for backwards compatibility: static rules without entity density\n * Use when no GEO config is available\n */\nexport const geoRules: Rule[] = geoStaticRules;\n","/**\n * Category Validation Rules\n * Validates blog categories against a user-provided canonical list\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Find the closest canonical category for a misspelled value\n */\nfunction findSuggestion(value: string, canonicalCategories: Set<string>): string | undefined {\n const lower = value.toLowerCase();\n for (const canonical of canonicalCategories) {\n if (canonical.toLowerCase() === lower) {\n return canonical;\n }\n }\n return undefined;\n}\n\n/**\n * Factory: Create category validation rules from a list of valid categories\n * Returns an empty array when categories is empty (skip both rules).\n */\nexport function createCategoryRules(categories: string[]): Rule[] {\n if (categories.length === 0) {\n return [];\n }\n\n const canonicalCategories = new Set(categories);\n\n const categoryInvalid: Rule = {\n name: 'category-invalid',\n severity: 'error',\n category: 'content',\n fixStrategy: 'Use a valid category from the configured list',\n run: (item: ContentItem): LintResult[] => {\n if (!item.categories || item.categories.length === 0) return [];\n\n const results: LintResult[] = [];\n\n for (const cat of item.categories) {\n if (!canonicalCategories.has(cat)) {\n const suggested = findSuggestion(cat, canonicalCategories);\n results.push({\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'category-invalid',\n severity: 'error',\n message: `Invalid category \"${cat}\"`,\n suggestion: suggested\n ? `Did you mean \"${suggested}\"? Valid categories: ${[...canonicalCategories].join(', ')}`\n : `Valid categories: ${[...canonicalCategories].join(', ')}`,\n });\n }\n }\n\n return results;\n },\n };\n\n const missingCategories: Rule = {\n name: 'missing-categories',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add at least one category from the configured list',\n run: (item: ContentItem): LintResult[] => {\n if (item.contentType !== 'blog') return [];\n\n if (!item.categories || item.categories.length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'categories',\n rule: 'missing-categories',\n severity: 'warning',\n message: 'Blog post has no categories',\n suggestion: `Add at least one category: ${[...canonicalCategories].join(', ')}`,\n }];\n }\n return [];\n },\n };\n\n return [categoryInvalid, missingCategories];\n}\n","/**\n * Canonical URL Validation Rules\n * Validates canonical URL presence and format\n */\n\nimport type { Rule, ContentItem, LintResult } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\n\n/**\n * Factory: Create canonical URL validation rules for the given site URL\n */\nexport function createCanonicalRules(siteUrl: string): Rule[] {\n /**\n * Rule: Every indexed page should have a canonical URL (permalink)\n * Skips noindexed pages since they don't need canonical tags\n */\n const canonicalMissing: Rule = {\n name: 'canonical-missing',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Ensure the content has a valid slug so a permalink can be generated',\n run: (item: ContentItem): LintResult[] => {\n if (item.noindex) return [];\n\n if (!item.permalink || item.permalink.trim().length === 0) {\n return [{\n file: getDisplayPath(item),\n field: 'permalink',\n rule: 'canonical-missing',\n severity: 'warning',\n message: 'Missing canonical URL (permalink)',\n suggestion: 'Ensure the content has a valid slug so a permalink can be generated',\n }];\n }\n return [];\n },\n };\n\n /**\n * Rule: Canonical URL must be a valid relative path or absolute URL on the site domain\n * Catches misconfigured permalinks (wrong domain, http://, fragments, etc.)\n */\n const canonicalMalformed: Rule = {\n name: 'canonical-malformed',\n severity: 'warning',\n category: 'seo',\n fixStrategy: 'Use a relative path (e.g., /blog/my-post) or absolute URL on the site domain',\n run: (item: ContentItem): LintResult[] => {\n if (!item.permalink || item.permalink.trim().length === 0) return [];\n\n const permalink = item.permalink.trim();\n\n // Valid: relative path starting with /\n if (permalink.startsWith('/')) return [];\n\n // Valid: absolute URL on site domain\n if (permalink.startsWith(siteUrl)) return [];\n\n return [{\n file: getDisplayPath(item),\n field: 'permalink',\n rule: 'canonical-malformed',\n severity: 'warning',\n message: `Canonical URL has unexpected format: \"${permalink}\"`,\n suggestion: `Canonical should be a relative path (e.g., /blog/my-post) or absolute URL starting with ${siteUrl}`,\n }];\n },\n };\n\n return [canonicalMissing, canonicalMalformed];\n}\n","/**\n * GEO E-E-A-T Rules\n * Validates Experience, Expertise, Authoritativeness, and Trustworthiness signals\n * plus answer formatting patterns for AI citation optimization\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n countSourceCitations,\n hasExpertQuote,\n extractH2Sections,\n hasFAQSection,\n} from '../utils/geo-analyzer.js';\nimport { analyzeFaqQuality } from '../utils/geo-advanced-analyzer.js';\nimport type { GeoConfig } from '../config/types.js';\n\nconst EEAT_MIN_WORDS = 500; // Minimum words before most E-E-A-T rules apply\nconst EEAT_LONG_MIN_WORDS = 800; // Minimum words for long-form content rules\nconst WORDS_PER_CITATION = 500; // Expected 1 source citation per N words\nconst FAQ_MIN_PAIRS = 3; // Minimum Q&A pairs in FAQ section\nconst FAQ_QUESTION_MARK_RATIO = 0.5;\nconst FAQ_ANSWER_RANGE_RATIO = 0.5;\nconst HEADING_MIN_WORDS = 3; // Minimum words for a descriptive heading\nconst TLDR_SCAN_WORDS = 150; // Words to scan for TL;DR at start of content\n\n// -- Rule 1: geo-missing-source-citations (static) --\nexport const geoMissingSourceCitations: Rule = {\n name: 'geo-missing-source-citations',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add source references using \"according to [Source]\" or linked citations',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const found = countSourceCitations(item.body);\n const expected = Math.floor(wordCount / WORDS_PER_CITATION);\n\n if (found < expected) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-source-citations',\n severity: 'warning',\n message: `Found ${found} source citation(s) but expected at least ${expected} (1 per ${WORDS_PER_CITATION} words in ${wordCount}-word post)`,\n suggestion: 'Add source references using \"according to [Source]\" or linked citations to strengthen authoritativeness.',\n }];\n }\n\n return [];\n },\n};\n// -- Rule 2: geo-missing-expert-quotes (static) --\nexport const geoMissingExpertQuotes: Rule = {\n name: 'geo-missing-expert-quotes',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add at least one blockquote with attribution (> \"Quote\" -- Expert Name)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n if (!hasExpertQuote(item.body)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-expert-quotes',\n severity: 'warning',\n message: 'No attributed expert quotation found in long-form content',\n suggestion: 'Add at least one blockquote with attribution (> \"Quote\" \\u2014 Expert Name) to boost E-E-A-T signals.',\n }];\n }\n\n return [];\n },\n};\n// -- Rule 6: geo-missing-author (factory) --\nexport function createGeoMissingAuthorRule(genericNames: string[]): Rule {\n return {\n name: 'geo-missing-author',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Set a real author name in frontmatter (not a generic placeholder)',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const displayPath = getDisplayPath(item);\n\n // Check 1: missing or empty author (takes priority)\n if (!item.author || item.author.trim() === '') {\n return [{\n file: displayPath,\n field: 'author',\n rule: 'geo-missing-author',\n severity: 'warning',\n message: 'No author specified in frontmatter \\u2014 weakens E-E-A-T signals',\n suggestion: 'Add an \"author\" field with a real person or brand name to the frontmatter.',\n }];\n }\n\n // Check 2: generic author name\n const normalizedAuthor = item.author.toLowerCase().trim();\n const isGeneric = genericNames.some(\n g => normalizedAuthor === g.toLowerCase()\n );\n\n if (isGeneric) {\n return [{\n file: displayPath,\n field: 'author',\n rule: 'geo-missing-author',\n severity: 'warning',\n message: `Author \"${item.author}\" appears to be a generic placeholder`,\n suggestion: 'Replace the generic author name with a real person or brand name to strengthen authoritativeness.',\n }];\n }\n\n return [];\n },\n };\n}\n// -- Rule 7: geo-heading-too-vague (factory) --\nexport function createGeoHeadingTooVagueRule(vagueHeadings: string[]): Rule {\n const lowerVague = vagueHeadings.map(v => v.toLowerCase());\n\n return {\n name: 'geo-heading-too-vague',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace vague headings with specific, descriptive headings of 3+ words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n const subHeadings = headings.filter(h => h.level === 2 || h.level === 3);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const heading of subHeadings) {\n const words = heading.text.trim().split(/\\s+/);\n const isShort = words.length < HEADING_MIN_WORDS;\n const isSingleVague = words.length === 1\n && lowerVague.includes(words[0].toLowerCase());\n\n if (isShort || isSingleVague) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-heading-too-vague',\n severity: 'warning',\n message: `H${heading.level} \"${heading.text}\" is too vague (${words.length} word${words.length === 1 ? '' : 's'})`,\n suggestion: 'Use a specific, descriptive heading with 3+ words that tells the reader and AI systems what this section covers.',\n line: heading.line,\n });\n }\n }\n\n return results;\n },\n };\n}\n// -- Rule 10: geo-faq-quality (static) --\nexport const geoFaqQuality: Rule = {\n name: 'geo-faq-quality',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Improve FAQ section: add 3+ Q&A pairs, use question marks, keep answers 20-150 words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n if (!hasFAQSection(item.body)) return [];\n\n const { pairCount, questionsWithMark, answersInRange } = analyzeFaqQuality(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n if (pairCount < FAQ_MIN_PAIRS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `FAQ section has only ${pairCount} Q&A pair(s) \\u2014 aim for at least ${FAQ_MIN_PAIRS}`,\n suggestion: 'Add more question-answer pairs to the FAQ section. AI systems favour comprehensive FAQ blocks with 3+ entries.',\n });\n }\n\n if (pairCount > 0 && questionsWithMark / pairCount < FAQ_QUESTION_MARK_RATIO) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `Only ${questionsWithMark}/${pairCount} FAQ questions end with a question mark`,\n suggestion: 'End all FAQ questions with \"?\" so AI systems recognise them as interrogative queries.',\n });\n }\n\n if (pairCount > 0 && answersInRange / pairCount < FAQ_ANSWER_RANGE_RATIO) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-faq-quality',\n severity: 'warning',\n message: `Only ${answersInRange}/${pairCount} FAQ answers are in the optimal 20\\u2013150 word range`,\n suggestion: 'Keep FAQ answers between 20 and 150 words \\u2014 concise enough for extraction but detailed enough to be useful.',\n });\n }\n\n return results;\n },\n};\n// -- Rule 11: geo-definition-pattern (static) --\nconst DEFINITION_HEADING_EN = /^what\\s+is\\s+/i;\nconst DEFINITION_HEADING_DE = /^was\\s+ist\\s+/i;\nconst DEFINITION_VERBS_EN = ['is', 'are', 'refers to', 'means'];\nconst DEFINITION_VERBS_DE = ['ist', 'sind', 'bezeichnet', 'bedeutet'];\n\n/** Extract subject from definition heading: \"What is GEO?\" -> \"GEO\" */\nfunction extractDefinitionSubject(heading: string): string {\n return heading\n .replace(DEFINITION_HEADING_EN, '')\n .replace(DEFINITION_HEADING_DE, '')\n .replace(/[?!.]$/, '')\n .trim();\n}\n\nexport const geoDefinitionPattern: Rule = {\n name: 'geo-definition-pattern',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start definition sections with \"[Subject] is/are...\" for AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isDefinition = DEFINITION_HEADING_EN.test(section.heading)\n || DEFINITION_HEADING_DE.test(section.heading);\n\n if (!isDefinition) continue;\n\n const subject = extractDefinitionSubject(section.heading);\n if (!subject) continue;\n\n // Get the first sentence of the section body\n const firstSentenceMatch = section.body.trim().match(/^([^.!?\\n]+[.!?]?)/);\n if (!firstSentenceMatch) continue;\n\n const firstSentence = firstSentenceMatch[1].trim().toLowerCase();\n const subjectLower = subject.toLowerCase();\n const allVerbs = [...DEFINITION_VERBS_EN, ...DEFINITION_VERBS_DE];\n\n const followsPattern = allVerbs.some(verb =>\n firstSentence.startsWith(`${subjectLower} ${verb}`)\n );\n\n if (!followsPattern) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-definition-pattern',\n severity: 'warning',\n message: `Section \"${section.heading}\" does not start with a \"${subject} is/are...\" definition pattern`,\n suggestion: `Start the first sentence with \"${subject} is ...\" or \"${subject} refers to ...\" so AI systems can extract a clean definition.`,\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n// -- Rule 12: geo-howto-steps (static) --\nconst HOWTO_HEADING = /^how\\s+to\\s+/i;\nconst HOWTO_HEADING_DE = /^wie\\s+(man\\s+)?/i;\nconst HOWTO_HEADING_DE_ALT = /^anleitung/i;\nconst MIN_HOWTO_STEPS = 3;\n\nexport const geoHowtoSteps: Rule = {\n name: 'geo-howto-steps',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a numbered list with 3+ steps to how-to sections',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isHowTo = HOWTO_HEADING.test(section.heading)\n || HOWTO_HEADING_DE.test(section.heading)\n || HOWTO_HEADING_DE_ALT.test(section.heading);\n\n if (!isHowTo) continue;\n\n const numberedItems = section.body.match(/^\\s*\\d+\\.\\s+/gm);\n const stepCount = numberedItems ? numberedItems.length : 0;\n\n if (stepCount < MIN_HOWTO_STEPS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-howto-steps',\n severity: 'warning',\n message: `How-to section \"${section.heading}\" has ${stepCount} numbered step(s) \\u2014 need at least ${MIN_HOWTO_STEPS}`,\n suggestion: 'Add a numbered list (1. 2. 3. ...) with at least 3 steps. AI systems parse numbered lists as HowTo structured data.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n// -- Rule 14: geo-missing-tldr (static) --\nconst TLDR_PATTERNS = [\n /tl;?dr/i,\n /key\\s+takeaway/i,\n /zusammenfassung/i,\n /das\\s+wichtigste/i,\n /in\\s+short/i,\n /quick\\s+answer/i,\n /^\\s*>\\s+\\*\\*/m,\n];\n\nexport const geoMissingTldr: Rule = {\n name: 'geo-missing-tldr',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a TL;DR, \"Key Takeaway\", or bold blockquote summary near the top of the article',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EEAT_LONG_MIN_WORDS) return [];\n\n // Scan the first ~150 words of the body\n const words = item.body.split(/\\s+/);\n const leadText = words.slice(0, TLDR_SCAN_WORDS).join(' ');\n\n const hasTldr = TLDR_PATTERNS.some(pattern => pattern.test(leadText));\n\n if (!hasTldr) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-tldr',\n severity: 'warning',\n message: 'No TL;DR or key-takeaway summary found near the top of the article',\n suggestion: 'Add a \"TL;DR\", \"Key Takeaway\", or bold blockquote summary in the first 150 words. AI systems often extract the opening summary for featured answers.',\n }];\n }\n\n return [];\n },\n};\n\n/** Patterns indicating organization-as-author (case-insensitive match) */\nconst ORG_AUTHOR_PATTERNS = [\n /\\bteam\\b/i,\n /\\bredaktion\\b/i,\n /\\beditorial\\b/i,\n /\\beditors?\\b/i,\n /\\bherausgeber\\b/i,\n /\\bverlag\\b/i,\n /\\bredaktionsteam\\b/i,\n];\n\n// -- Rule: geo-author-not-person (factory) --\nexport function createGeoAuthorNotPersonRule(brandName: string): Rule {\n return {\n name: 'geo-author-not-person',\n severity: 'warning',\n category: 'geo',\n fixStrategy:\n 'Replace organization name with individual author name. Use Person type in BlogPosting schema for stronger E-E-A-T signals.',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n // Skip if no author (handled by geo-missing-author)\n if (!item.author || item.author.trim() === '') return [];\n\n // Skip if brand not configured\n if (!brandName || brandName.trim() === '') return [];\n\n const normalizedAuthor = item.author.trim().toLowerCase();\n\n // Check 1: author exactly matches brand name\n if (normalizedAuthor === brandName.trim().toLowerCase()) {\n return [\n {\n file: getDisplayPath(item),\n field: 'author',\n rule: 'geo-author-not-person',\n severity: 'warning',\n message: `Author \"${item.author}\" is the organization name — use a person's name instead`,\n suggestion:\n 'AI models cite named experts over faceless organizations. Use the actual author\\'s name for stronger E-E-A-T signals.',\n },\n ];\n }\n\n // Check 2: author matches org patterns\n const matchesOrgPattern = ORG_AUTHOR_PATTERNS.some((pattern) =>\n pattern.test(item.author!)\n );\n\n if (matchesOrgPattern) {\n return [\n {\n file: getDisplayPath(item),\n field: 'author',\n rule: 'geo-author-not-person',\n severity: 'warning',\n message: `Author \"${item.author}\" appears to be an organization or team name`,\n suggestion:\n 'BlogPosting with author.@type: Person gets cited more than Organization. Use an individual person\\'s name.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/** Static E-E-A-T rules (no config dependency) */\nexport const geoEeatStaticRules: Rule[] = [\n geoMissingSourceCitations,\n geoMissingExpertQuotes,\n geoFaqQuality,\n geoDefinitionPattern,\n geoHowtoSteps,\n geoMissingTldr,\n];\n\n/** Build the complete E-E-A-T rule set from GEO config (6 static + 3 factory). */\nexport function createGeoEeatRules(geo: GeoConfig): Rule[] {\n return [\n ...geoEeatStaticRules,\n createGeoMissingAuthorRule(geo.genericAuthorNames ?? []),\n createGeoHeadingTooVagueRule(geo.vagueHeadings ?? []),\n createGeoAuthorNotPersonRule(geo.brandName),\n ];\n}\n","/**\n * GEO Structure Rules\n * Validates content structure and formatting patterns for AI extraction\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport {\n extractH2Sections,\n getParagraphs,\n hasMarkdownList,\n} from '../utils/geo-analyzer.js';\nimport {\n analyzeHeadingDensity,\n countStructuralElements,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before structure rules apply */\nconst STRUCTURE_MIN_WORDS = 500;\n\n/** Minimum word count for long-form structure rules */\nconst STRUCTURE_LONG_MIN_WORDS = 800;\n\n/** Maximum words per H2 section before it needs sub-headings */\nconst SECTION_MAX_WORDS = 300;\n\n/** Maximum words per paragraph */\nconst PARAGRAPH_MAX_WORDS = 100;\n\n/** Maximum paragraph violations reported (to reduce noise) */\nconst PARAGRAPH_MAX_VIOLATIONS = 5;\n\n/** Maximum words in the first paragraph of a citation block */\nconst CITATION_BLOCK_MAX_WORDS = 80;\n\n/** Ratio of sections with overly long citation blocks before flagging */\nconst CITATION_BLOCK_RATIO_THRESHOLD = 0.5;\n\n/** Maximum words in the introduction before first H2 */\nconst INTRO_MAX_WORDS = 150;\n\n/** Maximum word gap between headings for density rule */\nconst HEADING_GAP_MAX_WORDS = 300;\n\n/** Maximum heading density violations reported */\nconst HEADING_DENSITY_MAX_VIOLATIONS = 3;\n\n/** Expected structural elements per N words */\nconst WORDS_PER_STRUCTURAL_ELEMENT = 500;\n\n// ---------------------------------------------------------------------------\n// Rule 3: geo-section-too-long (static)\n// ---------------------------------------------------------------------------\n\nexport const geoSectionTooLong: Rule = {\n name: 'geo-section-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Break long sections into sub-sections with H3 headings every 200-300 words',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const sectionWordCount = countWords(section.body);\n const hasSubHeadings = /^###\\s+/m.test(section.body);\n\n if (sectionWordCount > SECTION_MAX_WORDS && !hasSubHeadings) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-section-too-long',\n severity: 'warning',\n message: `Section \"${section.heading}\" is ${sectionWordCount} words with no sub-headings (H3) \\u2014 max recommended is ${SECTION_MAX_WORDS}`,\n suggestion: 'Break this section into sub-sections using H3 headings. AI systems parse shorter, well-structured sections more effectively.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 4: geo-paragraph-too-long (static)\n// ---------------------------------------------------------------------------\n\nexport const geoParagraphTooLong: Rule = {\n name: 'geo-paragraph-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Split paragraphs longer than 100 words into shorter focused paragraphs',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const paragraphs = getParagraphs(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const paragraph of paragraphs) {\n if (results.length >= PARAGRAPH_MAX_VIOLATIONS) break;\n\n if (paragraph.wordCount > PARAGRAPH_MAX_WORDS) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-paragraph-too-long',\n severity: 'warning',\n message: `Paragraph at line ${paragraph.line} is ${paragraph.wordCount} words \\u2014 max recommended is ${PARAGRAPH_MAX_WORDS}`,\n suggestion: 'Split this paragraph into two or more shorter paragraphs. Shorter paragraphs are easier for AI systems to extract as citation blocks.',\n line: paragraph.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 5: geo-missing-lists (static)\n// ---------------------------------------------------------------------------\n\nexport const geoMissingLists: Rule = {\n name: 'geo-missing-lists',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add at least one bulleted or numbered list to improve scannability and AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n if (!hasMarkdownList(item.body, item.contentSource)) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-lists',\n severity: 'warning',\n message: 'No bulleted or numbered list found in content',\n suggestion: 'Add at least one bulleted or numbered list. Lists are highly extractable by AI systems and improve content scannability.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 13: geo-citation-block-upper-bound (static)\n// ---------------------------------------------------------------------------\n\nexport const geoCitationBlockUpperBound: Rule = {\n name: 'geo-citation-block-upper-bound',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Keep the first paragraph after each heading under 80 words for optimal AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_LONG_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n if (sections.length === 0) return [];\n\n let overLongCount = 0;\n\n for (const section of sections) {\n // First paragraph: text before first blank line after heading\n const firstParagraph = section.body.split(/\\n\\s*\\n/)[0] ?? '';\n const firstParaWords = countWords(firstParagraph.trim());\n\n if (firstParaWords > CITATION_BLOCK_MAX_WORDS) {\n overLongCount++;\n }\n }\n\n const ratio = overLongCount / sections.length;\n\n if (ratio > CITATION_BLOCK_RATIO_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-citation-block-upper-bound',\n severity: 'warning',\n message: `${overLongCount}/${sections.length} sections (${Math.round(ratio * 100)}%) have first paragraphs over ${CITATION_BLOCK_MAX_WORDS} words \\u2014 too long for AI citation extraction`,\n suggestion: `Keep the first paragraph after each H2 heading under ${CITATION_BLOCK_MAX_WORDS} words. Overly long opening paragraphs reduce AI extraction accuracy.`,\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 18: geo-orphaned-intro (static)\n// ---------------------------------------------------------------------------\n\nexport const geoOrphanedIntro: Rule = {\n name: 'geo-orphaned-intro',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Shorten the introduction to under 150 words or add a heading to break it up',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n // Content before the first H2 heading\n const introContent = item.body.split(/^##\\s+/m)[0] ?? '';\n const introWords = countWords(introContent);\n\n if (introWords > INTRO_MAX_WORDS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-orphaned-intro',\n severity: 'warning',\n message: `Introduction before first H2 heading is ${introWords} words \\u2014 max recommended is ${INTRO_MAX_WORDS}`,\n suggestion: 'Shorten the introduction or add an H2 heading to break up the opening. Long introductions delay AI systems from reaching structured content.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 22: geo-heading-density (static)\n// ---------------------------------------------------------------------------\n\nexport const geoHeadingDensity: Rule = {\n name: 'geo-heading-density',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add headings so that no text gap exceeds 300 words without a heading',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_LONG_MIN_WORDS) return [];\n\n const { gaps } = analyzeHeadingDensity(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const gap of gaps) {\n if (results.length >= HEADING_DENSITY_MAX_VIOLATIONS) break;\n if (gap.wordCount <= HEADING_GAP_MAX_WORDS) continue;\n\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-heading-density',\n severity: 'warning',\n message: `${gap.wordCount}-word gap without a heading after \"${gap.afterHeading}\" at line ${gap.line} \\u2014 max recommended is ${HEADING_GAP_MAX_WORDS}`,\n suggestion: 'Add a heading to break up this long text block. AI systems rely on headings to segment and extract content.',\n line: gap.line,\n });\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 28: geo-structural-element-ratio (static)\n// ---------------------------------------------------------------------------\n\nexport const geoStructuralElementRatio: Rule = {\n name: 'geo-structural-element-ratio',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add structural elements (lists, tables, blockquotes, code blocks) for better AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < STRUCTURE_MIN_WORDS) return [];\n\n const structuralCount = countStructuralElements(item.body);\n const expected = Math.floor(wordCount / WORDS_PER_STRUCTURAL_ELEMENT);\n\n if (structuralCount < expected) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-structural-element-ratio',\n severity: 'warning',\n message: `Found ${structuralCount} structural element(s) but expected at least ${expected} (1 per ${WORDS_PER_STRUCTURAL_ELEMENT} words in ${wordCount}-word post)`,\n suggestion: 'Add structural elements such as lists, tables, blockquotes, or code blocks. These are highly extractable by AI systems and improve content scannability.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** All GEO structure rules (static, no config dependency) */\nexport const geoStructureRules: Rule[] = [\n geoSectionTooLong,\n geoParagraphTooLong,\n geoMissingLists,\n geoCitationBlockUpperBound,\n geoOrphanedIntro,\n geoHeadingDensity,\n geoStructuralElementRatio,\n];\n","/**\n * GEO Freshness & Quality Rules\n * Validates content freshness signals, readability, and technical quality\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractH2Sections, countInternalLinks, hasMarkdownTable } from '../utils/geo-analyzer.js';\nimport {\n findStaleYearReferences,\n analyzePassiveVoice,\n extractSentences,\n findInlineHtml,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before most freshness rules apply */\nconst FRESHNESS_MIN_WORDS = 500;\n\n/** Maximum stale-year violations to report (avoids noise) */\nconst MAX_STALE_YEAR_VIOLATIONS = 5;\n\n/** Content older than this many months triggers outdated warning */\nconst OUTDATED_MONTHS_THRESHOLD = 6;\n\n/** Passive voice ratio above this triggers a warning */\nconst PASSIVE_VOICE_THRESHOLD = 0.15;\n\n/** Sentences longer than this word count are flagged */\nconst MAX_SENTENCE_WORDS = 40;\n\n/** Maximum long-sentence violations to report */\nconst MAX_LONG_SENTENCE_VIOLATIONS = 3;\n\n/** Minimum internal links expected in a blog post */\nconst MIN_INTERNAL_LINKS = 2;\n\n/** Maximum inline-HTML violations to report */\nconst MAX_INLINE_HTML_VIOLATIONS = 5;\n\n/** Comparison heading patterns (English and German) */\nconst COMPARISON_PATTERNS: RegExp[] = [\n /\\bvs\\.?\\b/i,\n /\\bversus\\b/i,\n /\\bcomparison\\b/i,\n /\\bcompared?\\s+to\\b/i,\n /\\bdifference\\s+between\\b/i,\n /\\bvergleich\\b/i,\n /\\bunterschied\\b/i,\n];\n\n// ---------------------------------------------------------------------------\n// Rule 8: geo-stale-date-references\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag year references that are more than 18 months old.\n * Stale dates cause AI systems to deprioritize content in answers.\n */\nexport const geoStaleDateReferences: Rule = {\n name: 'geo-stale-date-references',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Update or remove year references older than 18 months; replace with current data',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const allRefs = findStaleYearReferences(item.body, new Date());\n const staleRefs = allRefs.filter(ref => ref.isStale);\n if (staleRefs.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return staleRefs.slice(0, MAX_STALE_YEAR_VIOLATIONS).map(ref => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-stale-date-references',\n severity: 'warning' as const,\n message: `Year reference \"${ref.year}\" is more than 18 months old — AI systems deprioritize stale content`,\n suggestion: `Update or remove the \"${ref.year}\" reference. Replace with current data or add a note that the information has been verified.`,\n line: ref.line,\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 9: geo-outdated-content\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Warn when content has not been updated in over 6 months.\n * Uses updatedAt or date frontmatter fields.\n */\nexport const geoOutdatedContent: Rule = {\n name: 'geo-outdated-content',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Review and update content, then set updatedAt to today',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const rawDate = item.updatedAt ?? item.date;\n if (!rawDate) return [];\n\n const parsedDate = new Date(rawDate);\n if (isNaN(parsedDate.getTime())) return [];\n\n const now = new Date();\n const cutoff = new Date(now);\n cutoff.setMonth(cutoff.getMonth() - OUTDATED_MONTHS_THRESHOLD);\n\n if (parsedDate < cutoff) {\n const field = item.updatedAt ? 'updatedAt' : 'date';\n const monthsAgo = Math.floor(\n (now.getTime() - parsedDate.getTime()) / (1000 * 60 * 60 * 24 * 30)\n );\n\n return [{\n file: getDisplayPath(item),\n field,\n rule: 'geo-outdated-content',\n severity: 'warning',\n message: `Content was last updated ${monthsAgo} months ago — AI systems favor recently updated content`,\n suggestion: 'Review the content for accuracy, update any stale information, and set the updatedAt field to today.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 15: geo-passive-voice-excess\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag content with excessive passive voice usage.\n * Passive voice reduces clarity and makes content harder for AI to extract.\n */\nexport const geoPassiveVoiceExcess: Rule = {\n name: 'geo-passive-voice-excess',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Rewrite passive sentences in active voice for clearer AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const { passiveSentences, totalSentences, passiveRatio } = analyzePassiveVoice(item.body, item.locale);\n\n if (passiveRatio > PASSIVE_VOICE_THRESHOLD) {\n const percentage = Math.round(passiveRatio * 100);\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-passive-voice-excess',\n severity: 'warning',\n message: `${percentage}% of sentences (${passiveSentences}/${totalSentences}) use passive voice — aim for under ${Math.round(PASSIVE_VOICE_THRESHOLD * 100)}%`,\n suggestion: 'Rewrite passive constructions in active voice. For example, \"The report was written by the team\" becomes \"The team wrote the report.\"',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 16: geo-sentence-too-long\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Flag sentences exceeding 40 words.\n * Long sentences reduce readability and hinder AI snippet extraction.\n */\nexport const geoSentenceTooLong: Rule = {\n name: 'geo-sentence-too-long',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Break long sentences into two or more shorter, focused sentences',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const sentences = extractSentences(item.body);\n const longSentences = sentences\n .filter(entry => entry.wordCount > MAX_SENTENCE_WORDS)\n .sort((a, b) => b.wordCount - a.wordCount);\n\n if (longSentences.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return longSentences.slice(0, MAX_LONG_SENTENCE_VIOLATIONS).map(entry => {\n const preview = entry.text.split(/\\s+/).slice(0, 10).join(' ');\n\n return {\n file: displayPath,\n field: 'body',\n rule: 'geo-sentence-too-long',\n severity: 'warning' as const,\n message: `Sentence is ${entry.wordCount} words (max ${MAX_SENTENCE_WORDS}): \"${preview}...\"`,\n suggestion: 'Break this sentence into two or more shorter sentences for better readability and AI extraction.',\n };\n });\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 17: geo-low-internal-links\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Blog posts should contain at least 2 internal links.\n * Internal links strengthen topical authority signals for AI systems.\n */\nexport const geoLowInternalLinks: Rule = {\n name: 'geo-low-internal-links',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add 2-3 internal links to related content on the same site',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const linkCount = countInternalLinks(item.body);\n\n if (linkCount < MIN_INTERNAL_LINKS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-low-internal-links',\n severity: 'warning',\n message: `Found ${linkCount} internal link${linkCount === 1 ? '' : 's'} — aim for at least ${MIN_INTERNAL_LINKS}`,\n suggestion: 'Add 2-3 internal links to related blog posts or pages. Internal links strengthen topical authority signals for AI search systems.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 20: geo-comparison-table\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Comparison headings (containing \"vs\", \"versus\", \"comparison\", etc.)\n * should include a markdown table in their section body.\n * Tables in comparison sections are highly extractable by AI systems.\n */\nexport const geoComparisonTable: Rule = {\n name: 'geo-comparison-table',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a comparison table under each heading that discusses comparisons',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < FRESHNESS_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const results: LintResult[] = [];\n const displayPath = getDisplayPath(item);\n\n for (const section of sections) {\n const isComparison = COMPARISON_PATTERNS.some(pattern =>\n pattern.test(section.heading)\n );\n\n if (isComparison && !hasMarkdownTable(section.body)) {\n results.push({\n file: displayPath,\n field: 'body',\n rule: 'geo-comparison-table',\n severity: 'warning',\n message: `Comparison heading \"${section.heading}\" has no data table — tables increase AI citation rates for comparisons`,\n suggestion: 'Add a markdown comparison table (e.g., feature matrix or pros/cons) under this heading.',\n line: section.line,\n });\n }\n }\n\n return results;\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 21: geo-inline-html (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the inline HTML detection rule with project-specific allowed tags.\n * Applies to ALL content types (not just blog).\n */\nexport function createGeoInlineHtmlRule(allowedTags: string[]): Rule {\n return {\n name: 'geo-inline-html',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace inline HTML with markdown equivalents or add the tag to allowedHtmlTags config',\n run: (item: ContentItem): LintResult[] => {\n const tags = findInlineHtml(item.body, allowedTags);\n if (tags.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return tags.slice(0, MAX_INLINE_HTML_VIOLATIONS).map(tag => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-inline-html',\n severity: 'warning' as const,\n message: `Inline HTML tag <${tag.tag}> found — raw HTML reduces content portability across AI systems`,\n suggestion: `Replace <${tag.tag}> with a markdown equivalent, or add \"${tag.tag}\" to the allowedHtmlTags config if this is a custom MDX component.`,\n line: tag.line,\n }));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** Static GEO freshness rules (no config dependency) */\nexport const geoFreshnessStaticRules: Rule[] = [\n geoStaleDateReferences,\n geoOutdatedContent,\n geoPassiveVoiceExcess,\n geoSentenceTooLong,\n geoLowInternalLinks,\n geoComparisonTable,\n];\n\n/**\n * Factory: Build the complete GEO freshness rule set from config.\n * Returns all 7 rules: 6 static + 1 inline-html from factory.\n */\nexport function createGeoFreshnessRules(geo: GeoConfig): Rule[] {\n return [\n ...geoFreshnessStaticRules,\n createGeoInlineHtmlRule(geo.allowedHtmlTags ?? []),\n ];\n}\n","/**\n * GEO RAG Optimization Rules\n * Validates content patterns that improve retrieval and citation in RAG systems\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { GeoConfig } from '../config/types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport { extractH2Sections } from '../utils/geo-analyzer.js';\nimport { extractHeadings } from '../utils/heading-extractor.js';\nimport {\n detectUnresolvedOpenings,\n findUnexpandedAcronyms,\n findContextlessStatistics,\n} from '../utils/geo-advanced-analyzer.js';\n\n/** Minimum word count before standard RAG rules apply */\nconst RAG_MIN_WORDS = 500;\n\n/** Minimum word count before extraction trigger rule applies */\nconst EXTRACTION_TRIGGER_MIN_WORDS = 1000;\n\n/** Minimum word count before summary section rule applies */\nconst SUMMARY_MIN_WORDS = 2000;\n\n/** Minimum extraction triggers expected */\nconst MIN_EXTRACTION_TRIGGERS = 2;\n\n/** Maximum section self-containment violations to report */\nconst MAX_SELF_CONTAINMENT_VIOLATIONS = 3;\n\n/** Maximum acronym violations to report */\nconst MAX_ACRONYM_VIOLATIONS = 5;\n\n/** Maximum contextless statistic violations to report */\nconst MAX_STATISTIC_VIOLATIONS = 5;\n\n/** Number of leading words to inspect for vague openings */\nconst VAGUE_OPENING_WORD_LIMIT = 150;\n\n/** Summary/takeaway heading patterns (English and German) */\nconst SUMMARY_HEADING_PATTERNS: RegExp[] = [\n /tl;?dr/i,\n /summary/i,\n /key\\s*takeaway/i,\n /conclusion/i,\n /zusammenfassung/i,\n /fazit/i,\n /kernpunkte/i,\n];\n\n// ---------------------------------------------------------------------------\n// Rule 19: geo-extraction-triggers (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the extraction triggers rule with project-specific trigger phrases.\n * Checks that long-form content contains phrases that help AI systems identify\n * key takeaways and extractable statements.\n */\nexport function createGeoExtractionTriggersRule(triggers: string[]): Rule {\n return {\n name: 'geo-extraction-triggers',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add summary phrases like \"In summary\", \"Key takeaway\", or \"The main benefit is\" to help AI extraction',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < EXTRACTION_TRIGGER_MIN_WORDS) return [];\n\n if (triggers.length === 0) return [];\n\n const bodyLower = item.body.toLowerCase();\n let foundCount = 0;\n\n for (const trigger of triggers) {\n if (bodyLower.includes(trigger.toLowerCase())) {\n foundCount++;\n }\n }\n\n if (foundCount < MIN_EXTRACTION_TRIGGERS) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-extraction-triggers',\n severity: 'warning',\n message: `Found ${foundCount} extraction trigger${foundCount === 1 ? '' : 's'} — recommend at least ${MIN_EXTRACTION_TRIGGERS} for AI discoverability`,\n suggestion: `Add summary phrases such as \"${triggers.slice(0, 3).join('\", \"')}\" to help AI systems identify and extract key statements.`,\n }];\n }\n\n return [];\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 23: geo-section-self-containment\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: H2 sections should not open with unresolved pronouns.\n * RAG systems chunk content at section boundaries; each chunk must stand alone.\n */\nexport const geoSectionSelfContainment: Rule = {\n name: 'geo-section-self-containment',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Start each section with a specific subject instead of a pronoun like \"This\" or \"It\"',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const sections = extractH2Sections(item.body);\n const unresolved = detectUnresolvedOpenings(sections);\n\n if (unresolved.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return unresolved.slice(0, MAX_SELF_CONTAINMENT_VIOLATIONS).map(opening => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-section-self-containment',\n severity: 'warning' as const,\n message: `Section \"${opening.heading}\" opens with an unresolved reference: \"${opening.firstWord}\"`,\n suggestion: 'Start the section with a specific subject instead of a pronoun. RAG systems chunk at headings, so each section must be self-contained.',\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 24: geo-vague-opening (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the vague opening detection rule with project-specific filler phrases.\n * Flags articles that start with generic filler rather than substantive content.\n */\nexport function createGeoVagueOpeningRule(fillerPhrases: string[]): Rule {\n return {\n name: 'geo-vague-opening',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Replace the generic opening with a specific, substantive first sentence',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n if (fillerPhrases.length === 0) return [];\n\n // Extract the first paragraph or first 150 words\n const lines = item.body.split('\\n');\n const contentLines: string[] = [];\n let totalWords = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip empty lines at the start\n if (contentLines.length === 0 && !trimmed) continue;\n\n // Skip headings, imports, and JSX\n if (/^#{1,6}\\s+/.test(trimmed)) continue;\n if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) continue;\n if (trimmed.startsWith('<') && !trimmed.startsWith('<a')) continue;\n\n // Stop at first blank line after content started, or word limit\n if (contentLines.length > 0 && !trimmed) break;\n\n contentLines.push(trimmed);\n totalWords += trimmed.split(/\\s+/).length;\n if (totalWords >= VAGUE_OPENING_WORD_LIMIT) break;\n }\n\n const openingText = contentLines.join(' ').toLowerCase();\n if (!openingText) return [];\n\n for (const phrase of fillerPhrases) {\n if (openingText.startsWith(phrase.toLowerCase())) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-vague-opening',\n severity: 'warning',\n message: `Article opens with filler phrase \"${phrase}\" — AI systems deprioritize generic introductions`,\n suggestion: 'Replace the opening with a specific, substantive first sentence that directly addresses the topic.',\n }];\n }\n }\n\n return [];\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 25: geo-acronym-expansion (factory)\n// ---------------------------------------------------------------------------\n\n/**\n * Factory: Create the acronym expansion rule with project-specific allowlist.\n * Flags acronyms that are never expanded on first use, reducing AI comprehension.\n */\nexport function createGeoAcronymExpansionRule(allowlist: string[]): Rule {\n return {\n name: 'geo-acronym-expansion',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Expand each acronym on first use, e.g. \"Search Engine Optimization (SEO)\"',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const unexpanded = findUnexpandedAcronyms(item.body, allowlist);\n if (unexpanded.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return unexpanded.slice(0, MAX_ACRONYM_VIOLATIONS).map(entry => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-acronym-expansion',\n severity: 'warning' as const,\n message: `Acronym \"${entry.acronym}\" is used but never expanded — AI systems may misinterpret unexpanded acronyms`,\n suggestion: `Expand \"${entry.acronym}\" on first use, e.g. \"Full Name (${entry.acronym})\".`,\n line: entry.line,\n }));\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Rule 26: geo-statistic-without-context\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Statistics (percentages) should include source attribution or timeframe.\n * Contextless numbers reduce trust signals for AI citation.\n */\nexport const geoStatisticWithoutContext: Rule = {\n name: 'geo-statistic-without-context',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add source attribution or timeframe context to each statistic',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < RAG_MIN_WORDS) return [];\n\n const contextless = findContextlessStatistics(item.body);\n if (contextless.length === 0) return [];\n\n const displayPath = getDisplayPath(item);\n\n return contextless.slice(0, MAX_STATISTIC_VIOLATIONS).map(stat => ({\n file: displayPath,\n field: 'body',\n rule: 'geo-statistic-without-context',\n severity: 'warning' as const,\n message: `Statistic \"${stat.statistic}\" lacks source attribution — unattributed data reduces AI citation confidence`,\n suggestion: 'Add source or timeframe context to the statistic, e.g. \"according to [Source]\" or \"as of 2024\".',\n line: stat.line,\n }));\n },\n};\n\n// ---------------------------------------------------------------------------\n// Rule 27: geo-missing-summary-section\n// ---------------------------------------------------------------------------\n\n/**\n * Rule: Long-form content (2000+ words) should include a summary or takeaway section.\n * Summary sections are frequently extracted by AI as answer snippets.\n */\nexport const geoMissingSummarySection: Rule = {\n name: 'geo-missing-summary-section',\n severity: 'warning',\n category: 'geo',\n fixStrategy: 'Add a \"## TL;DR\", \"## Key Takeaways\", or \"## Conclusion\" section',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const geoTypes = context.geoEnabledContentTypes ?? ['blog'];\n if (!geoTypes.includes(item.contentType)) return [];\n\n const wordCount = countWords(item.body);\n if (wordCount < SUMMARY_MIN_WORDS) return [];\n\n const headings = extractHeadings(item.body);\n\n const hasSummaryHeading = headings.some(heading =>\n SUMMARY_HEADING_PATTERNS.some(pattern => pattern.test(heading.text))\n );\n\n if (!hasSummaryHeading) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'geo-missing-summary-section',\n severity: 'warning',\n message: `Long-form content (${wordCount} words) has no summary or takeaway section — AI systems frequently extract these for answers`,\n suggestion: 'Add a \"## TL;DR\", \"## Key Takeaways\", \"## Fazit\", or \"## Conclusion\" section summarizing the main points.',\n }];\n }\n\n return [];\n },\n};\n\n// ---------------------------------------------------------------------------\n// Exports\n// ---------------------------------------------------------------------------\n\n/** Static GEO RAG rules (no config dependency) */\nexport const geoRagStaticRules: Rule[] = [\n geoSectionSelfContainment,\n geoStatisticWithoutContext,\n geoMissingSummarySection,\n];\n\n/**\n * Factory: Build the complete GEO RAG rule set from config.\n * Returns all 6 rules: 3 static + 3 from factories.\n */\nexport function createGeoRagRules(geo: GeoConfig): Rule[] {\n return [\n ...geoRagStaticRules,\n createGeoExtractionTriggersRule(geo.extractionTriggers ?? []),\n createGeoVagueOpeningRule(geo.fillerPhrases ?? []),\n createGeoAcronymExpansionRule(geo.acronymAllowlist ?? []),\n ];\n}\n","/**\n * Transition Word Analyzer\n *\n * Measures the ratio of sentences containing logical connectors.\n * Content with low transition word usage reads as a series of\n * disconnected statements — bad for both readers and LLM extraction.\n *\n * Inspired by Yoast SEO's transition words assessment.\n */\n\nimport { extractSentences } from './geo-advanced-analyzer.js';\nimport { getTransitionWords } from '../data/index.js';\n\nexport interface TransitionWordAnalysis {\n /** Total sentences analyzed */\n totalSentences: number;\n /** Sentences containing at least one transition word/phrase */\n sentencesWithTransition: number;\n /** Ratio of sentences with transitions (0–1) */\n ratio: number;\n}\n\n/**\n * Check if a sentence contains at least one transition word or phrase.\n * Multi-word phrases are checked via substring match on the lowercased sentence.\n * Single words are checked via set membership after splitting.\n */\nfunction sentenceHasTransition(\n sentenceText: string,\n singleWords: ReadonlySet<string>,\n phrases: readonly string[],\n): boolean {\n const lower = sentenceText.toLowerCase();\n\n // Check multi-word phrases first (substring match)\n for (const phrase of phrases) {\n if (lower.includes(phrase)) return true;\n }\n\n // Check single words via set membership\n const words = lower\n .replace(/[^a-zA-ZäöüÄÖÜßà-ÿ\\s-]/g, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0);\n\n for (const word of words) {\n if (singleWords.has(word)) return true;\n }\n\n return false;\n}\n\n/**\n * Analyze transition word usage across all sentences in the body.\n *\n * @example\n * analyzeTransitionWords(\"Dogs are great. However, cats are also nice.\")\n * // { totalSentences: 2, sentencesWithTransition: 1, ratio: 0.5 }\n */\nexport function analyzeTransitionWords(\n body: string,\n locale?: string,\n): TransitionWordAnalysis {\n const sentences = extractSentences(body);\n const lang = (locale ?? 'en').toLowerCase();\n const wordData = getTransitionWords(lang);\n\n if (!wordData || sentences.length === 0) {\n return { totalSentences: sentences.length, sentencesWithTransition: 0, ratio: 0 };\n }\n\n let sentencesWithTransition = 0;\n\n for (const { text } of sentences) {\n if (sentenceHasTransition(text, wordData.singleWords, wordData.phrases)) {\n sentencesWithTransition++;\n }\n }\n\n return {\n totalSentences: sentences.length,\n sentencesWithTransition,\n ratio: sentences.length > 0 ? sentencesWithTransition / sentences.length : 0,\n };\n}\n","/**\n * Sentence Beginnings Analyzer\n *\n * Detects consecutive sentences starting with the same word.\n * Inspired by Yoast SEO's sentence beginnings assessment.\n * Function words (articles, demonstratives) are skipped — the second\n * word is used instead, so \"The dog\" and \"The cat\" don't count as same-start.\n */\n\nimport { extractSentences } from './geo-advanced-analyzer.js';\nimport { getFirstWordExceptions } from '../data/index.js';\n\nexport interface ConsecutiveStartGroup {\n /** The repeated starting word (lowercased) */\n word: string;\n /** Number of consecutive sentences with this start */\n count: number;\n /** 1-indexed line estimate of the first sentence in the group */\n startIndex: number;\n}\n\nexport interface SentenceBeginningsAnalysis {\n /** Groups of 3+ consecutive sentences starting with the same word */\n groups: ConsecutiveStartGroup[];\n}\n\n/**\n * Get the effective first word of a sentence, skipping function words.\n * If the first word is in the exceptions set, the second word is used.\n */\nfunction getEffectiveFirstWord(\n sentenceText: string,\n exceptions: ReadonlySet<string>,\n): string {\n const words = sentenceText\n .split(/\\s+/)\n .filter(w => w.length > 0)\n .map(w => w.replace(/[^a-zA-ZäöüÄÖÜß]/g, '').toLowerCase());\n\n if (words.length === 0) return '';\n\n const first = words[0];\n if (exceptions.has(first) && words.length > 1) {\n return words[1];\n }\n return first;\n}\n\n/**\n * Analyze sentence beginnings for monotonous repetition.\n *\n * @example\n * analyzeSentenceBeginnings(\"We went home. We ate dinner. We watched TV.\")\n * // { groups: [{ word: \"we\", count: 3, startIndex: 0 }] }\n */\nexport function analyzeSentenceBeginnings(\n body: string,\n locale?: string,\n): SentenceBeginningsAnalysis {\n const sentences = extractSentences(body);\n const exceptions = getFirstWordExceptions(locale ?? 'en');\n const groups: ConsecutiveStartGroup[] = [];\n\n if (sentences.length < 3) return { groups };\n\n const firstWords = sentences.map(s => getEffectiveFirstWord(s.text, exceptions));\n\n let currentWord = firstWords[0];\n let runStart = 0;\n let runLength = 1;\n\n for (let i = 1; i < firstWords.length; i++) {\n const word = firstWords[i];\n if (word && word === currentWord) {\n runLength++;\n } else {\n if (runLength >= 3 && currentWord) {\n groups.push({ word: currentWord, count: runLength, startIndex: runStart });\n }\n currentWord = word;\n runStart = i;\n runLength = 1;\n }\n }\n\n // Flush final run\n if (runLength >= 3 && currentWord) {\n groups.push({ word: currentWord, count: runLength, startIndex: runStart });\n }\n\n return { groups };\n}\n","/**\n * Content Quality Rules\n * Detects jargon stuffing, content repetition, extreme sentence lengths,\n * low substance, low transition word usage, monotonous sentence starts,\n * and lack of sentence length variety.\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport { getDisplayPath } from '../utils/display-path.js';\nimport { countWords } from '../utils/word-counter.js';\nimport {\n analyzeJargonDensity,\n analyzeRepetition,\n analyzeSentenceLength,\n analyzeSubstance,\n analyzeSentenceVariety,\n} from '../utils/content-quality-analyzer.js';\nimport { analyzeTransitionWords } from '../utils/transition-word-analyzer.js';\nimport { analyzeSentenceBeginnings } from '../utils/sentence-beginnings-analyzer.js';\n\n/** Minimum word count before quality rules apply */\nconst QUALITY_MIN_WORDS = 300;\n\n/** Jargon density thresholds */\nconst JARGON_WARNING_THRESHOLD = 0.08;\nconst JARGON_ERROR_THRESHOLD = 0.15;\n\n/** Repetition thresholds */\nconst REPETITION_SIMILARITY_WARNING = 0.15;\nconst REPETITION_SIMILARITY_ERROR = 0.25;\nconst REPEATED_PHRASE_MIN_COUNT = 5;\n\n/** Sentence length thresholds */\nconst SENTENCE_AVG_WARNING = 35;\nconst SENTENCE_AVG_ERROR = 50;\n\n/** Substance (type-token ratio) thresholds — lower = less diverse vocabulary */\nconst SUBSTANCE_WARNING_THRESHOLD = 0.25;\nconst SUBSTANCE_ERROR_THRESHOLD = 0.15;\n\n/** Transition words thresholds (ratio of sentences containing transition words) */\nconst TRANSITION_WARNING_THRESHOLD = 0.20;\nconst TRANSITION_ERROR_THRESHOLD = 0.10;\nconst TRANSITION_MIN_WORDS = 200;\n\n/** Consecutive sentence beginnings */\nconst CONSECUTIVE_STARTS_WARNING = 3;\nconst CONSECUTIVE_STARTS_ERROR = 5;\nconst CONSECUTIVE_STARTS_MIN_WORDS = 100;\n\n/** Sentence variety thresholds (coefficient of variation) */\nconst VARIETY_WARNING_THRESHOLD = 0.30;\nconst VARIETY_MIN_WORDS = 300;\nconst VARIETY_MIN_SENTENCES = 10;\n\n// ─── Jargon Density Rule ───────────────────────────────────────────────────\n\nexport const jargonDensity: Rule = {\n name: 'content-jargon-density',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Replace complex or uncommon words with simpler alternatives',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeJargonDensity(item.body, locale);\n\n if (analysis.density >= JARGON_ERROR_THRESHOLD) {\n const topWords = analysis.topJargonWords\n .slice(0, 3)\n .map(w => `\"${w.word}\" (${w.count}x)`)\n .join(', ');\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-jargon-density',\n severity: 'error',\n message: `Extreme complex word density: ${Math.round(analysis.density * 100)}% of words are complex/uncommon (${analysis.jargonCount}/${analysis.totalWords})`,\n suggestion: `Replace complex words with simpler alternatives. Worst offenders: ${topWords}.`,\n }];\n }\n\n if (analysis.density >= JARGON_WARNING_THRESHOLD) {\n const topWords = analysis.topJargonWords\n .slice(0, 3)\n .map(w => `\"${w.word}\" (${w.count}x)`)\n .join(', ');\n\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-jargon-density',\n severity: 'warning',\n message: `High complex word density: ${Math.round(analysis.density * 100)}% of words are complex/uncommon (${analysis.jargonCount}/${analysis.totalWords})`,\n suggestion: `Reduce complex vocabulary for clearer communication. Top complex words: ${topWords}.`,\n }];\n }\n\n return [];\n },\n};\n\n// ─── Content Repetition Rule ───────────────────────────────────────────────\n\nexport const contentRepetition: Rule = {\n name: 'content-repetition',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Remove or rewrite paragraphs that repeat the same ideas',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeRepetition(item.body);\n const results: LintResult[] = [];\n\n // Check paragraph similarity\n if (analysis.avgParagraphSimilarity >= REPETITION_SIMILARITY_ERROR) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'error',\n message: `Extreme content repetition: ${Math.round(analysis.avgParagraphSimilarity * 100)}% average paragraph similarity`,\n suggestion: 'Paragraphs are rehashing the same ideas. Remove duplicate content and add unique information to each section.',\n });\n } else if (analysis.avgParagraphSimilarity >= REPETITION_SIMILARITY_WARNING) {\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'warning',\n message: `High content repetition: ${Math.round(analysis.avgParagraphSimilarity * 100)}% average paragraph similarity`,\n suggestion: 'Several paragraphs cover the same ground. Consolidate repeated ideas and add distinct value to each section.',\n });\n }\n\n // Check repeated phrases\n if (analysis.repeatedPhraseCount >= REPEATED_PHRASE_MIN_COUNT) {\n const topPhrase = analysis.topRepeatedPhrases[0];\n results.push({\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-repetition',\n severity: 'warning',\n message: `${analysis.repeatedPhraseCount} phrases repeated 3+ times. Most repeated: \"${topPhrase.phrase}\" (${topPhrase.count}x)`,\n suggestion: 'Vary your language to avoid repetitive phrasing. Use synonyms or restructure sentences.',\n });\n }\n\n return results;\n },\n};\n\n// ─── Sentence Length Extreme Rule ──────────────────────────────────────────\n\nexport const sentenceLengthExtreme: Rule = {\n name: 'content-sentence-length-extreme',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Break long sentences into shorter ones (aim for 15-25 words per sentence)',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeSentenceLength(item.body);\n\n if (analysis.totalSentences === 0) return [];\n\n if (analysis.avgWordsPerSentence >= SENTENCE_AVG_ERROR) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-length-extreme',\n severity: 'error',\n message: `Extreme average sentence length: ${Math.round(analysis.avgWordsPerSentence)} words/sentence (longest: ${analysis.maxWordsPerSentence} words, ${analysis.sentencesOver60Words} sentences over 60 words)`,\n suggestion: 'Break sentences into digestible chunks. Aim for 15-25 words per sentence. Readers and AI models struggle with extremely long sentences.',\n }];\n }\n\n if (analysis.avgWordsPerSentence >= SENTENCE_AVG_WARNING) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-length-extreme',\n severity: 'warning',\n message: `High average sentence length: ${Math.round(analysis.avgWordsPerSentence)} words/sentence (longest: ${analysis.maxWordsPerSentence} words)`,\n suggestion: 'Consider splitting longer sentences. Good readability requires sentences of 15-25 words on average.',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Substance Ratio Rule ──────────────────────────────────────────────────\n\nexport const substanceRatio: Rule = {\n name: 'content-substance-ratio',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add specific, concrete information instead of repeating abstract concepts',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < QUALITY_MIN_WORDS) return [];\n\n const analysis = analyzeSubstance(item.body);\n\n if (analysis.totalContentWords < 50) return [];\n\n if (analysis.typeTokenRatio <= SUBSTANCE_ERROR_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-substance-ratio',\n severity: 'error',\n message: `Extremely low vocabulary diversity: ${Math.round(analysis.typeTokenRatio * 100)}% unique words (${analysis.uniqueContentWords} unique out of ${analysis.totalContentWords} content words)`,\n suggestion: 'The same words are recycled extensively. Add concrete examples, specific data, and varied terminology.',\n }];\n }\n\n if (analysis.typeTokenRatio <= SUBSTANCE_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-substance-ratio',\n severity: 'warning',\n message: `Low vocabulary diversity: ${Math.round(analysis.typeTokenRatio * 100)}% unique words (${analysis.uniqueContentWords} unique out of ${analysis.totalContentWords} content words)`,\n suggestion: 'Increase vocabulary variety. Use specific terms, examples, and data points instead of repeating the same abstract concepts.',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Transition Words Rule ────────────────────────────────────────────────\n\nexport const lowTransitionWords: Rule = {\n name: 'content-low-transition-words',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Add transition words (however, therefore, for example, in addition) to connect ideas between sentences',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < TRANSITION_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeTransitionWords(item.body, locale);\n\n if (analysis.totalSentences < 5) return [];\n\n if (analysis.ratio < TRANSITION_ERROR_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-low-transition-words',\n severity: 'error',\n message: `Very few transition words: ${Math.round(analysis.ratio * 100)}% of sentences (${analysis.sentencesWithTransition}/${analysis.totalSentences}) — aim for at least 20%`,\n suggestion: 'Add transition words to connect ideas: \"however\", \"therefore\", \"for example\", \"in addition\", \"as a result\". Content reads as disconnected statements without them.',\n }];\n }\n\n if (analysis.ratio < TRANSITION_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-low-transition-words',\n severity: 'warning',\n message: `Low transition word usage: ${Math.round(analysis.ratio * 100)}% of sentences (${analysis.sentencesWithTransition}/${analysis.totalSentences}) — aim for at least 20%`,\n suggestion: 'Improve content flow by adding transition words: \"however\", \"therefore\", \"for example\", \"in contrast\", \"as a result\".',\n }];\n }\n\n return [];\n },\n};\n\n// ─── Consecutive Sentence Beginnings Rule ─────────────────────────────────\n\nexport const consecutiveStarts: Rule = {\n name: 'content-consecutive-starts',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Vary sentence openings — use transition words, prepositional phrases, or reversed structures',\n run: (item: ContentItem, context: RuleContext): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < CONSECUTIVE_STARTS_MIN_WORDS) return [];\n\n const locale = item.locale ?? context.defaultLocale ?? 'en';\n const analysis = analyzeSentenceBeginnings(item.body, locale);\n\n if (analysis.groups.length === 0) return [];\n\n // Report the worst group (highest count)\n const worst = analysis.groups.reduce((a, b) => a.count > b.count ? a : b);\n\n if (worst.count >= CONSECUTIVE_STARTS_ERROR) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-consecutive-starts',\n severity: 'error',\n message: `${worst.count} consecutive sentences start with \"${worst.word}\" — vary sentence openings`,\n suggestion: `Rephrase some sentences to begin with different words. Try starting with a transition word, a prepositional phrase, or by reversing the sentence structure.`,\n }];\n }\n\n if (worst.count >= CONSECUTIVE_STARTS_WARNING) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-consecutive-starts',\n severity: 'warning',\n message: `${worst.count} consecutive sentences start with \"${worst.word}\" — vary sentence openings`,\n suggestion: `Rephrase some sentences to begin with different words. Try starting with a transition word, a prepositional phrase, or by reversing the sentence structure.`,\n }];\n }\n\n return [];\n },\n};\n\n// ─── Sentence Variety Rule ────────────────────────────────────────────────\n\nexport const sentenceVariety: Rule = {\n name: 'content-sentence-variety',\n severity: 'warning',\n category: 'content',\n fixStrategy: 'Mix short punchy sentences with longer explanatory ones for better rhythm',\n run: (item: ContentItem): LintResult[] => {\n const wordCount = countWords(item.body);\n if (wordCount < VARIETY_MIN_WORDS) return [];\n\n const analysis = analyzeSentenceVariety(item.body);\n\n if (analysis.totalSentences < VARIETY_MIN_SENTENCES) return [];\n\n if (analysis.coefficientOfVariation < VARIETY_WARNING_THRESHOLD) {\n return [{\n file: getDisplayPath(item),\n field: 'body',\n rule: 'content-sentence-variety',\n severity: 'warning',\n message: `Monotonous sentence lengths: CV ${analysis.coefficientOfVariation} (avg ${analysis.avgLength} words, std dev ${analysis.stdDev}). Mix short and long sentences.`,\n suggestion: 'Vary sentence length: follow a long sentence with a short one. Use fragments for emphasis. Break up paragraphs with 5-10 word sentences between 25+ word ones.',\n }];\n }\n\n return [];\n },\n};\n\n/** All content quality rules */\nexport const contentQualityRules: Rule[] = [\n jargonDensity,\n contentRepetition,\n sentenceLengthExtreme,\n substanceRatio,\n lowTransitionWords,\n consecutiveStarts,\n sentenceVariety,\n];\n","/**\n * Technical Site-Level Rules\n * Validates site-wide technical requirements for AI citation optimization\n */\n\nimport type { Rule, ContentItem, LintResult, RuleContext } from '../types.js';\nimport type { TechnicalConfig } from '../config/types.js';\n\n/**\n * Rule: Site should have at least one RSS/Atom/JSON feed\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createNoFeedRule(\n feedUrls: string[] | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'technical-no-feed',\n severity: 'warning',\n category: 'technical',\n fixStrategy:\n 'Add an RSS or JSON feed endpoint exposing blog posts with full content.',\n run: (_item: ContentItem, _context: RuleContext): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // undefined = not configured, skip silently\n if (feedUrls === undefined) return [];\n\n // Empty array = user declared they have no feeds — flag it\n if (feedUrls.length === 0) {\n return [\n {\n file: '_site',\n field: 'feed',\n rule: 'technical-no-feed',\n severity: 'warning',\n message:\n 'No RSS/Atom/JSON feed detected — AI systems lose a structured ingestion path',\n suggestion:\n 'Feeds provide a structured ingestion path for AI systems beyond crawler discovery. Add an RSS or JSON feed endpoint.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/**\n * Rule: Site should have a /llms.txt endpoint\n * Config-level check — runs once per lint (fires on first item only)\n */\nexport function createNoLlmsTxtRule(\n llmsTxtUrl: string | undefined\n): Rule {\n let hasFired = false;\n\n return {\n name: 'technical-no-llms-txt',\n severity: 'warning',\n category: 'technical',\n fixStrategy:\n 'Create a /llms.txt endpoint that maps your most important content for LLM consumption in Markdown format.',\n run: (_item: ContentItem, _context: RuleContext): LintResult[] => {\n if (hasFired) return [];\n hasFired = true;\n\n // undefined = not configured, skip silently\n if (llmsTxtUrl === undefined) return [];\n\n // Empty string = user declared they don't have llms.txt — flag it\n if (llmsTxtUrl.trim() === '') {\n return [\n {\n file: '_site',\n field: 'llms-txt',\n rule: 'technical-no-llms-txt',\n severity: 'warning',\n message:\n 'No /llms.txt endpoint detected — missing the emerging standard for LLM content declaration',\n suggestion:\n 'llms.txt is the robots.txt equivalent for AI — trivial to add, future-proofs your site for LLM crawlers.',\n },\n ];\n }\n\n return [];\n },\n };\n}\n\n/** Build the complete technical site-level rule set from config */\nexport function createTechnicalSiteRules(technical: TechnicalConfig): Rule[] {\n return [\n createNoFeedRule(technical.feedUrls),\n createNoLlmsTxtRule(technical.llmsTxtUrl),\n ];\n}\n","/**\n * Rule Registry\n * Builds the complete rule set from configuration and provides runner functions\n */\n\nimport type { Rule, ContentItem, RuleContext, LintResult } from '../types.js';\nimport type { GeoLintConfig } from '../config/types.js';\nimport type { LinkExtractor } from '../utils/link-extractor.js';\n\n// Static rule imports\nimport { titleRules } from './title-rules.js';\nimport { descriptionRules } from './description-rules.js';\nimport { duplicateRules } from './duplicate-rules.js';\nimport { headingRules } from './heading-rules.js';\nimport { imageRules } from './image-rules.js';\nimport { contentRules } from './content-rules.js';\nimport { ogRules } from './og-rules.js';\nimport { performanceRules } from './performance-rules.js';\nimport { robotsRules } from './robots-rules.js';\nimport { slugRules } from './slug-rules.js';\nimport { createI18nRules } from './i18n-rules.js';\nimport { dateRules } from './date-rules.js';\nimport { createSchemaRules } from './schema-rules.js';\nimport { keywordCoherenceRules } from './keyword-coherence-rules.js';\n\n// Factory rule imports\nimport { createLinkRules } from './link-rules.js';\nimport { createExternalLinkRules } from './external-link-rules.js';\nimport { createOrphanRules } from './orphan-rules.js';\nimport { createGeoRules } from './geo-rules.js';\nimport { createCategoryRules } from './category-rules.js';\nimport { createCanonicalRules } from './canonical-rules.js';\n\n// GEO advanced rule imports\nimport { createGeoEeatRules } from './geo-eeat-rules.js';\nimport { geoStructureRules } from './geo-structure-rules.js';\nimport { createGeoFreshnessRules } from './geo-freshness-rules.js';\nimport { createGeoRagRules } from './geo-rag-rules.js';\n\n// Content quality rules\nimport { contentQualityRules } from './content-quality-rules.js';\n\n// Technical site-level rules\nimport { createTechnicalSiteRules } from './technical-site-rules.js';\n\n/**\n * Build the complete rule set from config and link extractor\n */\nexport function buildRules(config: GeoLintConfig, linkExtractor: LinkExtractor): Rule[] {\n const rules: Rule[] = [\n ...titleRules,\n ...descriptionRules,\n ...duplicateRules,\n ...headingRules,\n ...createLinkRules(linkExtractor),\n ...createExternalLinkRules(linkExtractor),\n ...imageRules,\n ...contentRules,\n ...ogRules,\n ...performanceRules,\n ...createOrphanRules(linkExtractor),\n ...robotsRules,\n ...slugRules,\n ...createI18nRules(config.i18n),\n ...dateRules,\n ...(config.categories.length > 0 ? createCategoryRules(config.categories) : []),\n ...createSchemaRules(config.geo),\n ...createGeoRules(config.geo),\n ...createGeoEeatRules(config.geo),\n ...geoStructureRules,\n ...createGeoFreshnessRules(config.geo),\n ...createGeoRagRules(config.geo),\n ...keywordCoherenceRules,\n ...createCanonicalRules(config.siteUrl),\n ...contentQualityRules,\n ...createTechnicalSiteRules(config.technical),\n ];\n\n // Apply user rule overrides (severity changes + disabling)\n return rules.map(rule => applyRuleOverride(rule, config.rules));\n}\n\n/**\n * Apply a user-configured severity override to a rule.\n * 'off' disables the rule by replacing its run function with a no-op.\n */\nfunction applyRuleOverride(\n rule: Rule,\n overrides: Record<string, 'error' | 'warning' | 'off'>\n): Rule {\n const override = overrides[rule.name];\n if (!override) return rule;\n if (override === 'off') return { ...rule, run: () => [] };\n return { ...rule, severity: override };\n}\n\n/**\n * Run a single rule against a content item (with error isolation)\n */\nexport function runRule(rule: Rule, item: ContentItem, context: RuleContext): LintResult[] {\n try {\n return rule.run(item, context);\n } catch (error) {\n console.error(`Rule ${rule.name} failed on ${item.slug}:`, error);\n return [];\n }\n}\n\n/**\n * Run all provided rules against a single content item\n */\nexport function runRulesOnItem(\n item: ContentItem,\n context: RuleContext,\n rules: Rule[]\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const rule of rules) {\n const ruleResults = runRule(rule, item, context);\n results.push(...ruleResults);\n }\n\n return results;\n}\n\n/**\n * Run all provided rules against all content items\n */\nexport function runAllRules(\n items: ContentItem[],\n context: RuleContext,\n rules: Rule[]\n): LintResult[] {\n const results: LintResult[] = [];\n\n for (const item of items) {\n const itemResults = runRulesOnItem(item, context, rules);\n results.push(...itemResults);\n }\n\n return results;\n}\n\n// Re-export static rules for selective use\nexport { titleRules } from './title-rules.js';\nexport { descriptionRules } from './description-rules.js';\nexport { duplicateRules } from './duplicate-rules.js';\nexport { headingRules } from './heading-rules.js';\nexport { imageRules } from './image-rules.js';\nexport { contentRules } from './content-rules.js';\nexport { ogRules } from './og-rules.js';\nexport { performanceRules } from './performance-rules.js';\nexport { robotsRules } from './robots-rules.js';\nexport { slugRules } from './slug-rules.js';\nexport { i18nRules, createI18nRules } from './i18n-rules.js';\nexport { dateRules } from './date-rules.js';\nexport { schemaStaticRules, schemaRules, createSchemaRules, createSchemaSameAsRule } from './schema-rules.js';\nexport { keywordCoherenceRules } from './keyword-coherence-rules.js';\nexport { geoStaticRules, geoRules } from './geo-rules.js';\n\n// Re-export factory functions for selective use\nexport { createLinkRules } from './link-rules.js';\nexport { createExternalLinkRules } from './external-link-rules.js';\nexport { createOrphanRules } from './orphan-rules.js';\nexport { createGeoRules, createGeoEntityRule } from './geo-rules.js';\nexport { createCategoryRules } from './category-rules.js';\nexport { createCanonicalRules } from './canonical-rules.js';\n\n// GEO advanced rule re-exports\nexport { geoEeatStaticRules, createGeoEeatRules } from './geo-eeat-rules.js';\nexport { geoStructureRules } from './geo-structure-rules.js';\nexport { geoFreshnessStaticRules, createGeoFreshnessRules } from './geo-freshness-rules.js';\nexport { geoRagStaticRules, createGeoRagRules } from './geo-rag-rules.js';\n\n// Content quality rule re-exports\nexport { contentQualityRules } from './content-quality-rules.js';\n\n// Technical site-level rule re-exports\nexport { createNoFeedRule, createNoLlmsTxtRule, createTechnicalSiteRules } from './technical-site-rules.js';\n","/**\n * @ijonis/geo-lint Reporter\n * Formats and outputs lint results with color-coding\n */\n\nimport type { LintResult, Severity } from './types.js';\n\n/** ANSI color codes for terminal output */\nconst COLORS = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n} as const;\n\nexport interface ReportSummary {\n errors: number;\n warnings: number;\n passed: number;\n total: number;\n excluded: number;\n}\n\n/** Group results by file path */\nfunction groupByFile(results: LintResult[]): Map<string, LintResult[]> {\n const grouped = new Map<string, LintResult[]>();\n for (const result of results) {\n const existing = grouped.get(result.file) || [];\n existing.push(result);\n grouped.set(result.file, existing);\n }\n return grouped;\n}\n\n/** Format a single lint result line */\nfunction formatResult(result: LintResult): string {\n const { red, yellow, dim, reset } = COLORS;\n const icon = result.severity === 'error' ? `${red}\\u2717${reset}` : `${yellow}\\u26A0${reset}`;\n const ruleTag = `${dim}[${result.rule}]${reset}`;\n\n let line = ` ${icon} ${ruleTag} ${result.message}`;\n\n if (result.line) {\n line += ` ${dim}(line ${result.line})${reset}`;\n }\n\n if (result.suggestion) {\n line += `\\n ${dim}\\u2192 ${result.suggestion}${reset}`;\n }\n\n return line;\n}\n\n/** Print results grouped by severity */\nfunction printResultsBySection(\n results: LintResult[],\n severity: Severity,\n label: string,\n): void {\n const filtered = results.filter(r => r.severity === severity);\n if (filtered.length === 0) return;\n\n const { red, yellow, bold, reset } = COLORS;\n const color = severity === 'error' ? red : yellow;\n const grouped = groupByFile(filtered);\n\n console.log(`\\n${color}${bold}${label} (${filtered.length}):${reset}\\n`);\n\n for (const [file, fileResults] of grouped) {\n console.log(` ${bold}${file}${reset}`);\n for (const result of fileResults) {\n console.log(formatResult(result));\n }\n console.log('');\n }\n}\n\n/** Print summary statistics */\nfunction printSummary(summary: ReportSummary): void {\n const { red, yellow, green, bold, reset, dim } = COLORS;\n\n console.log(`${dim}${'─'.repeat(50)}${reset}`);\n console.log(`${bold}Summary:${reset}`);\n\n if (summary.errors > 0) {\n console.log(` ${red}\\u2717 ${summary.errors} error(s)${reset} ${dim}(build blocked)${reset}`);\n }\n if (summary.warnings > 0) {\n console.log(` ${yellow}\\u26A0 ${summary.warnings} warning(s)${reset}`);\n }\n if (summary.passed > 0) {\n console.log(` ${green}\\u2713 ${summary.passed} file(s) passed${reset}`);\n }\n if (summary.excluded > 0) {\n console.log(` ${dim}\\u2298 ${summary.excluded} file(s) excluded${reset}`);\n }\n\n console.log(`\\n ${dim}Total: ${summary.total} files checked${reset}\\n`);\n}\n\n/** Format and output all lint results. Returns summary for exit code. */\nexport function formatResults(\n results: LintResult[],\n totalFiles: number,\n excludedFiles: number = 0,\n): ReportSummary {\n const { bold, reset, cyan, green, dim } = COLORS;\n\n const errors = results.filter(r => r.severity === 'error').length;\n const warnings = results.filter(r => r.severity === 'warning').length;\n const filesWithIssues = new Set(results.map(r => r.file)).size;\n const passed = totalFiles - filesWithIssues;\n\n const summary: ReportSummary = { errors, warnings, passed, total: totalFiles, excluded: excludedFiles };\n\n console.log(`\\n${cyan}${bold}GEO Lint Results${reset}`);\n console.log(`${cyan}${'═'.repeat(50)}${reset}`);\n\n if (results.length === 0) {\n console.log(`\\n${green}${bold}\\u2713 GEO Lint: All checks passed!${reset}\\n`);\n console.log(` ${dim}${totalFiles} files checked${reset}\\n`);\n return summary;\n }\n\n printResultsBySection(results, 'error', 'ERRORS');\n printResultsBySection(results, 'warning', 'WARNINGS');\n printSummary(summary);\n\n return summary;\n}\n\n/** Format results as JSON for agent consumption */\nexport function formatResultsJson(results: LintResult[]): string {\n return JSON.stringify(results, null, 2);\n}\n\n/** Print a simple progress message */\nexport function printProgress(message: string): void {\n const { dim, reset } = COLORS;\n console.log(`${dim}${message}${reset}`);\n}\n"],"mappings":"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","names":["import_node_path","import_node_fs","import_node_fs","import_node_path","matter","isInCodeBlock","import_node_fs","import_node_path","isInCodeBlock","singleWords","multiWordPhrases","DEFAULT_CONFIG","analyzeFaqQuality","analyzeFaqQuality","singleWords","require"]}
|