react-ssr-seo-toolkit 1.1.0 → 1.2.0
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/README.md +592 -512
- package/dist/adapters/nextjs.d.cts +1 -1
- package/dist/adapters/nextjs.d.ts +1 -1
- package/dist/adapters/react-router.d.cts +1 -1
- package/dist/adapters/react-router.d.ts +1 -1
- package/dist/chunk-3UCLUFOI.js +5 -0
- package/dist/chunk-3UCLUFOI.js.map +1 -0
- package/dist/chunk-A62THBIS.cjs +3 -0
- package/dist/chunk-A62THBIS.cjs.map +1 -0
- package/dist/chunk-GNLXGAS6.js +3 -0
- package/dist/chunk-GNLXGAS6.js.map +1 -0
- package/dist/chunk-LEOORZQY.cjs +5 -0
- package/dist/chunk-LEOORZQY.cjs.map +1 -0
- package/dist/chunk-ROA74LH6.cjs +61 -0
- package/dist/chunk-ROA74LH6.cjs.map +1 -0
- package/dist/chunk-WM5VVPED.js +61 -0
- package/dist/chunk-WM5VVPED.js.map +1 -0
- package/dist/chunk-X535MU7Z.js +5 -0
- package/dist/chunk-X535MU7Z.js.map +1 -0
- package/dist/chunk-ZADUJHVR.cjs +5 -0
- package/dist/chunk-ZADUJHVR.cjs.map +1 -0
- package/dist/chunk-ZECSTNEE.cjs +3 -0
- package/dist/chunk-ZECSTNEE.cjs.map +1 -0
- package/dist/chunk-ZVFEGG25.js +3 -0
- package/dist/chunk-ZVFEGG25.js.map +1 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.cts +2 -2
- package/dist/components.d.ts +2 -2
- package/dist/components.js +1 -1
- package/dist/index-Br7Sh9Ur.d.cts +329 -0
- package/dist/index-Br7Sh9Ur.d.ts +329 -0
- package/dist/{index-DAGfo2Fc.d.ts → index-CKNcgAj8.d.ts} +10 -2
- package/dist/{index-RBSUcdqN.d.cts → index-Wgogf4CX.d.cts} +10 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +1 -1
- package/dist/og.cjs +2 -0
- package/dist/og.cjs.map +1 -0
- package/dist/og.d.cts +5 -0
- package/dist/og.d.ts +5 -0
- package/dist/og.js +2 -0
- package/dist/og.js.map +1 -0
- package/dist/schema.cjs +1 -1
- package/dist/schema.d.cts +6 -2
- package/dist/schema.d.ts +6 -2
- package/dist/schema.js +1 -1
- package/dist/sitemap.cjs +2 -0
- package/dist/sitemap.cjs.map +1 -0
- package/dist/sitemap.d.cts +12 -0
- package/dist/sitemap.d.ts +12 -0
- package/dist/sitemap.js +2 -0
- package/dist/sitemap.js.map +1 -0
- package/dist/validation.cjs +2 -0
- package/dist/validation.cjs.map +1 -0
- package/dist/validation.d.cts +8 -0
- package/dist/validation.d.ts +8 -0
- package/dist/validation.js +2 -0
- package/dist/validation.js.map +1 -0
- package/package.json +38 -2
- package/dist/chunk-63ETSZTD.cjs +0 -3
- package/dist/chunk-63ETSZTD.cjs.map +0 -1
- package/dist/chunk-AYIAPQTP.js +0 -2
- package/dist/chunk-AYIAPQTP.js.map +0 -1
- package/dist/chunk-ES4OXVOR.js +0 -3
- package/dist/chunk-ES4OXVOR.js.map +0 -1
- package/dist/chunk-T7EB7Y2S.cjs +0 -2
- package/dist/chunk-T7EB7Y2S.cjs.map +0 -1
- package/dist/index-Dr2yktvz.d.cts +0 -136
- package/dist/index-Dr2yktvz.d.ts +0 -136
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
function d(s){return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function h(s,t){return t.endsWith("/*")?s.startsWith(t.slice(0,-2)+"/")||s===t.slice(0,-2):t.endsWith("*")?s.startsWith(t.slice(0,-1)):t.startsWith("*")?s.endsWith(t.slice(1)):s===t}function w(s){let{routes:t,baseUrl:o,exclude:i=[],defaultChangefreq:n,defaultPriority:c}=s,e=o.replace(/\/+$/,"");return ['<?xml version="1.0" encoding="UTF-8"?>','<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',...t.map(r=>typeof r=="string"?{path:r}:r).filter(r=>!i.some(m=>h(r.path,m))).map(r=>{let m=r.path==="/"?e:`${e}${r.path}`,p=[" <url>",` <loc>${d(m)}</loc>`,` <lastmod>${r.lastmod??new Date().toISOString().split("T")[0]}</lastmod>`],g=r.changefreq??n;g&&p.push(` <changefreq>${g}</changefreq>`);let f=r.priority??c;return f!==void 0&&p.push(` <priority>${f.toFixed(1)}</priority>`),p.push(" </url>"),p.join(`
|
|
2
|
+
`)}),"</urlset>"].join(`
|
|
3
|
+
`)}function b(s){let{rules:t=[],sitemap:o}=s,i=Array.isArray(t)?t:[t],n=[];for(let e of i){let a=e.userAgent?Array.isArray(e.userAgent)?e.userAgent:[e.userAgent]:["*"];for(let r of a)n.push(`User-agent: ${r}`);let l=e.allow?Array.isArray(e.allow)?e.allow:[e.allow]:[];for(let r of l)n.push(`Allow: ${r}`);let u=e.disallow?Array.isArray(e.disallow)?e.disallow:[e.disallow]:[];for(let r of u)n.push(`Disallow: ${r}`);e.crawlDelay!==void 0&&n.push(`Crawl-delay: ${e.crawlDelay}`),n.push("");}let c=o?Array.isArray(o)?o:[o]:[];for(let e of c)n.push(`Sitemap: ${e}`);return n.join(`
|
|
4
|
+
`).trim()}function y(s){return s.replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase())}function A(s,t={}){let{baseUrl:o="",labels:i={},formatLabel:n=y}=t,c=s.split("/").filter(Boolean),e=[{name:i[""]??i["/"]??"Home",url:`${o}/`}],a="";for(let l of c){a+=`/${l}`;let u=i[a]??i[l]??n(l);e.push({name:u,url:`${o}${a}`});}return e}export{w as a,b,A as c};//# sourceMappingURL=chunk-3UCLUFOI.js.map
|
|
5
|
+
//# sourceMappingURL=chunk-3UCLUFOI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sitemap/index.ts"],"names":["escapeXml","str","matchesExclude","path","pattern","generateSitemap","options","routes","baseUrl","exclude","defaultChangefreq","defaultPriority","normalizedBase","route","loc","lines","changefreq","priority","generateRobots","rules","sitemap","normalizedRules","rule","agents","agent","allows","disallows","sitemaps","sm","defaultFormatLabel","segment","c","autoBreadcrumb","currentPath","labels","formatLabel","segments","items","accPath","name"],"mappings":"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","file":"chunk-3UCLUFOI.js","sourcesContent":["import type {\n BreadcrumbItem,\n GenerateSitemapOptions,\n GenerateRobotsOptions,\n SitemapRoute,\n} from \"../types/index.js\";\n\n// ─── Sitemap ──────────────────────────────────────────────────\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction matchesExclude(path: string, pattern: string): boolean {\n if (pattern.endsWith(\"/*\")) {\n return path.startsWith(pattern.slice(0, -2) + \"/\") || path === pattern.slice(0, -2);\n }\n if (pattern.endsWith(\"*\")) {\n return path.startsWith(pattern.slice(0, -1));\n }\n if (pattern.startsWith(\"*\")) {\n return path.endsWith(pattern.slice(1));\n }\n return path === pattern;\n}\n\nexport function generateSitemap(options: GenerateSitemapOptions): string {\n const { routes, baseUrl, exclude = [], defaultChangefreq, defaultPriority } = options;\n const normalizedBase = baseUrl.replace(/\\/+$/, \"\");\n\n const normalized: SitemapRoute[] = routes.map((r) =>\n typeof r === \"string\" ? { path: r } : r\n );\n\n const filtered = normalized.filter(\n (route) => !exclude.some((pattern) => matchesExclude(route.path, pattern))\n );\n\n const urlEntries = filtered.map((route) => {\n const loc = route.path === \"/\" ? normalizedBase : `${normalizedBase}${route.path}`;\n const lines: string[] = [\n ` <url>`,\n ` <loc>${escapeXml(loc)}</loc>`,\n ` <lastmod>${route.lastmod ?? new Date().toISOString().split(\"T\")[0]}</lastmod>`,\n ];\n\n const changefreq = route.changefreq ?? defaultChangefreq;\n if (changefreq) lines.push(` <changefreq>${changefreq}</changefreq>`);\n\n const priority = route.priority ?? defaultPriority;\n if (priority !== undefined) lines.push(` <priority>${priority.toFixed(1)}</priority>`);\n\n lines.push(` </url>`);\n return lines.join(\"\\n\");\n });\n\n return [\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>`,\n `<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">`,\n ...urlEntries,\n `</urlset>`,\n ].join(\"\\n\");\n}\n\n// ─── Robots.txt ───────────────────────────────────────────────\n\nexport function generateRobots(options: GenerateRobotsOptions): string {\n const { rules = [], sitemap } = options;\n const normalizedRules = Array.isArray(rules) ? rules : [rules];\n const lines: string[] = [];\n\n for (const rule of normalizedRules) {\n const agents = rule.userAgent\n ? Array.isArray(rule.userAgent)\n ? rule.userAgent\n : [rule.userAgent]\n : [\"*\"];\n\n for (const agent of agents) {\n lines.push(`User-agent: ${agent}`);\n }\n\n const allows = rule.allow\n ? Array.isArray(rule.allow)\n ? rule.allow\n : [rule.allow]\n : [];\n for (const path of allows) lines.push(`Allow: ${path}`);\n\n const disallows = rule.disallow\n ? Array.isArray(rule.disallow)\n ? rule.disallow\n : [rule.disallow]\n : [];\n for (const path of disallows) lines.push(`Disallow: ${path}`);\n\n if (rule.crawlDelay !== undefined) lines.push(`Crawl-delay: ${rule.crawlDelay}`);\n\n lines.push(\"\");\n }\n\n const sitemaps = sitemap\n ? Array.isArray(sitemap)\n ? sitemap\n : [sitemap]\n : [];\n for (const sm of sitemaps) lines.push(`Sitemap: ${sm}`);\n\n return lines.join(\"\\n\").trim();\n}\n\n// ─── Auto Breadcrumb ──────────────────────────────────────────\n\nexport interface AutoBreadcrumbOptions {\n baseUrl?: string;\n labels?: Record<string, string>;\n formatLabel?: (segment: string) => string;\n}\n\nfunction defaultFormatLabel(segment: string): string {\n return segment\n .replace(/[-_]/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nexport function autoBreadcrumb(\n currentPath: string,\n options: AutoBreadcrumbOptions = {}\n): BreadcrumbItem[] {\n const { baseUrl = \"\", labels = {}, formatLabel = defaultFormatLabel } = options;\n\n const segments = currentPath.split(\"/\").filter(Boolean);\n const items: BreadcrumbItem[] = [\n { name: labels[\"\"] ?? labels[\"/\"] ?? \"Home\", url: `${baseUrl}/` },\n ];\n\n let accPath = \"\";\n for (const segment of segments) {\n accPath += `/${segment}`;\n const name = labels[accPath] ?? labels[segment] ?? formatLabel(segment);\n items.push({ name, url: `${baseUrl}${accPath}` });\n }\n\n return items;\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';var i="https://schema.org";function c(e){let r={"@context":i,"@type":"Organization",name:e.name,url:e.url};if(e.logo&&(r.logo=e.logo),e.description&&(r.description=e.description),e.sameAs?.length&&(r.sameAs=e.sameAs),e.contactPoint){let a={"@type":"ContactPoint"};e.contactPoint.telephone&&(a.telephone=e.contactPoint.telephone),e.contactPoint.contactType&&(a.contactType=e.contactPoint.contactType),e.contactPoint.email&&(a.email=e.contactPoint.email),e.contactPoint.areaServed&&(a.areaServed=e.contactPoint.areaServed),e.contactPoint.availableLanguage&&(a.availableLanguage=e.contactPoint.availableLanguage),r.contactPoint=a;}return r}function m(e){let r={"@context":i,"@type":"WebSite",name:e.name,url:e.url};return e.description&&(r.description=e.description),e.searchUrl&&(r.potentialAction={"@type":"SearchAction",target:{"@type":"EntryPoint",urlTemplate:`${e.searchUrl}?${e.searchQueryParam??"q"}={search_term_string}`},"query-input":"required name=search_term_string"}),r}function l(e){return {"@context":i,"@type":"BreadcrumbList",itemListElement:e.map((r,a)=>({"@type":"ListItem",position:a+1,name:r.name,item:r.url}))}}function d(e){let r={"@context":i,"@type":"Article",headline:e.headline,url:e.url};if(e.description&&(r.description=e.description),e.images?.length&&(r.image=e.images),e.datePublished&&(r.datePublished=e.datePublished),e.dateModified&&(r.dateModified=e.dateModified),e.section&&(r.articleSection=e.section),e.keywords?.length&&(r.keywords=e.keywords),e.author){let a=Array.isArray(e.author)?e.author:[e.author];r.author=a.map(o=>{let t={"@type":"Person",name:o.name};return o.url&&(t.url=o.url),t});}if(e.publisher){let a={"@type":"Organization",name:e.publisher.name};e.publisher.logo&&(a.logo={"@type":"ImageObject",url:e.publisher.logo}),r.publisher=a;}return r}function g(e){let r={"@context":i,"@type":"Product",name:e.name,url:e.url};if(e.description&&(r.description=e.description),e.images?.length&&(r.image=e.images),e.brand&&(r.brand={"@type":"Brand",name:e.brand}),e.sku&&(r.sku=e.sku),e.gtin&&(r.gtin=e.gtin),e.price!==void 0){let a={"@type":"Offer",price:e.price,priceCurrency:e.priceCurrency??"USD"};e.availability&&(a.availability=`https://schema.org/${e.availability}`),r.offers=a;}if(e.ratingValue!==void 0){let a={"@type":"AggregateRating",ratingValue:e.ratingValue};e.reviewCount!==void 0&&(a.reviewCount=e.reviewCount),r.aggregateRating=a;}return r}function f(e){return {"@context":i,"@type":"FAQPage",mainEntity:e.map(r=>({"@type":"Question",name:r.question,acceptedAnswer:{"@type":"Answer",text:r.answer}}))}}function h(e){let r=!!(e.sport??e.homeTeam??e.awayTeam),a={"@context":i,"@type":r?"SportsEvent":"Event",name:e.name,startDate:e.startDate};if(e.endDate&&(a.endDate=e.endDate),e.description&&(a.description=e.description),e.url&&(a.url=e.url),e.images?.length&&(a.image=e.images),e.eventStatus&&(a.eventStatus=`https://schema.org/${e.eventStatus}`),e.eventAttendanceMode&&(a.eventAttendanceMode=`https://schema.org/${e.eventAttendanceMode}`),e.location){let o=e.location;if(o.url&&!o.address)a.location={"@type":"VirtualLocation",name:o.name,url:o.url};else {let t={"@type":"Place",name:o.name};o.url&&(t.url=o.url),o.address&&(t.address=typeof o.address=="string"?o.address:{"@type":"PostalAddress",...o.address}),a.location=t;}}if(e.organizer){let o={"@type":"Organization",name:e.organizer.name};e.organizer.url&&(o.url=e.organizer.url),a.organizer=o;}if(e.performer){let t=(Array.isArray(e.performer)?e.performer:[e.performer]).map(n=>{let s={"@type":"Person",name:n.name};return n.url&&(s.url=n.url),s});a.performer=t.length===1?t[0]:t;}if(r){if(e.sport&&(a.sport=e.sport),e.homeTeam){let o={"@type":"SportsTeam",name:e.homeTeam.name};e.homeTeam.url&&(o.url=e.homeTeam.url),a.homeTeam=o;}if(e.awayTeam){let o={"@type":"SportsTeam",name:e.awayTeam.name};e.awayTeam.url&&(o.url=e.awayTeam.url),a.awayTeam=o;}}return a}function y(e){let r={"@context":i,"@type":"Person",name:e.name};if(e.url&&(r.url=e.url),e.image&&(r.image=e.image),e.jobTitle&&(r.jobTitle=e.jobTitle),e.description&&(r.description=e.description),e.email&&(r.email=e.email),e.telephone&&(r.telephone=e.telephone),e.birthDate&&(r.birthDate=e.birthDate),e.sameAs?.length&&(r.sameAs=e.sameAs),e.worksFor){let a={"@type":"Organization",name:e.worksFor.name};e.worksFor.url&&(a.url=e.worksFor.url),r.worksFor=a;}return e.address&&(r.address=typeof e.address=="string"?e.address:{"@type":"PostalAddress",...e.address}),r}function S(e){let r={"@context":i,"@type":"Recipe",name:e.name};if(e.description&&(r.description=e.description),e.images?.length&&(r.image=e.images),e.datePublished&&(r.datePublished=e.datePublished),e.prepTime&&(r.prepTime=e.prepTime),e.cookTime&&(r.cookTime=e.cookTime),e.totalTime&&(r.totalTime=e.totalTime),e.recipeYield!==void 0&&(r.recipeYield=String(e.recipeYield)),e.recipeCategory&&(r.recipeCategory=e.recipeCategory),e.recipeCuisine&&(r.recipeCuisine=e.recipeCuisine),e.recipeIngredient?.length&&(r.recipeIngredient=e.recipeIngredient),e.keywords?.length&&(r.keywords=e.keywords.join(", ")),e.author){let a={"@type":"Person",name:e.author.name};e.author.url&&(a.url=e.author.url),r.author=a;}if(e.recipeInstructions?.length&&(r.recipeInstructions=e.recipeInstructions.map(a=>{if(typeof a=="string")return {"@type":"HowToStep",text:a};let o={"@type":"HowToStep",text:a.text};return a.name&&(o.name=a.name),a.url&&(o.url=a.url),a.image&&(o.image=a.image),o})),e.nutrition&&Object.keys(e.nutrition).length&&(r.nutrition={"@type":"NutritionInformation",...e.nutrition}),e.ratingValue!==void 0){let a={"@type":"AggregateRating",ratingValue:e.ratingValue};e.reviewCount!==void 0&&(a.reviewCount=e.reviewCount),r.aggregateRating=a;}return r}function b(e){let r={"@context":i,"@type":"JobPosting",title:e.title,description:e.description,datePosted:e.datePosted};e.validThrough&&(r.validThrough=e.validThrough),e.url&&(r.url=e.url),e.experienceRequirements&&(r.experienceRequirements=e.experienceRequirements),e.educationRequirements&&(r.educationRequirements={"@type":"EducationalOccupationalCredential",credentialCategory:e.educationRequirements}),e.employmentType&&(r.employmentType=(Array.isArray(e.employmentType),e.employmentType)),e.skills&&(r.skills=Array.isArray(e.skills)?e.skills.join(", "):e.skills);let a={"@type":"Organization",name:e.hiringOrganization.name};if(e.hiringOrganization.sameAs&&(a.sameAs=e.hiringOrganization.sameAs),e.hiringOrganization.logo&&(a.logo=e.hiringOrganization.logo),r.hiringOrganization=a,e.remote&&(r.jobLocationType="TELECOMMUTE"),e.jobLocation&&(r.jobLocation={"@type":"Place",address:{"@type":"PostalAddress",...e.jobLocation}}),e.baseSalary){let{currency:o,value:t,unitText:n="YEAR"}=e.baseSalary,s={"@type":"MonetaryAmount",currency:o};typeof t=="number"?s.value=t:s.value={"@type":"QuantitativeValue",minValue:t.minValue,maxValue:t.maxValue,unitText:n},r.baseSalary=s;}return e.identifier&&(r.identifier={"@type":"PropertyValue",name:e.identifier.name,value:e.identifier.value}),r}function T(...e){return {"@context":i,"@type":"ItemList","@graph":e.map(({"@context":r,...a})=>a)}}
|
|
2
|
+
exports.a=c;exports.b=m;exports.c=l;exports.d=d;exports.e=g;exports.f=f;exports.g=h;exports.h=y;exports.i=S;exports.j=b;exports.k=T;//# sourceMappingURL=chunk-A62THBIS.cjs.map
|
|
3
|
+
//# sourceMappingURL=chunk-A62THBIS.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema/index.ts"],"names":["CONTEXT","createOrganizationSchema","input","schema","cp","createWebsiteSchema","createBreadcrumbSchema","items","item","index","createArticleSchema","authors","a","person","pub","createProductSchema","offer","rating","createFAQSchema","createEventSchema","isSports","loc","place","org","mapped","p","entry","t","createPersonSchema","createRecipeSchema","step","s","createJobPostingSchema","currency","value","unitText","monetaryAmount","composeSchemas","schemas","_ctx","rest"],"mappings":"aAcA,IAAMA,CAAAA,CAAU,oBAAA,CAIT,SAASC,CAAAA,CACdC,EACY,CACZ,IAAMC,CAAAA,CAAqB,CACzB,WAAYH,CAAAA,CACZ,OAAA,CAAS,cAAA,CACT,IAAA,CAAME,EAAM,IAAA,CACZ,GAAA,CAAKA,CAAAA,CAAM,GACb,EAMA,GAJIA,CAAAA,CAAM,IAAA,GAAMC,CAAAA,CAAO,KAAOD,CAAAA,CAAM,IAAA,CAAA,CAChCA,CAAAA,CAAM,WAAA,GAAaC,EAAO,WAAA,CAAcD,CAAAA,CAAM,WAAA,CAAA,CAC9CA,CAAAA,CAAM,QAAQ,MAAA,GAAQC,CAAAA,CAAO,MAAA,CAASD,CAAAA,CAAM,QAE5CA,CAAAA,CAAM,YAAA,CAAc,CACtB,IAAME,EAA8B,CAClC,OAAA,CAAS,cACX,CAAA,CACIF,EAAM,YAAA,CAAa,SAAA,GACrBE,CAAAA,CAAG,SAAA,CAAYF,EAAM,YAAA,CAAa,SAAA,CAAA,CAChCA,CAAAA,CAAM,YAAA,CAAa,cACrBE,CAAAA,CAAG,WAAA,CAAcF,CAAAA,CAAM,YAAA,CAAa,aAClCA,CAAAA,CAAM,YAAA,CAAa,KAAA,GAAOE,CAAAA,CAAG,MAAQF,CAAAA,CAAM,YAAA,CAAa,KAAA,CAAA,CACxDA,CAAAA,CAAM,aAAa,UAAA,GACrBE,CAAAA,CAAG,UAAA,CAAaF,CAAAA,CAAM,aAAa,UAAA,CAAA,CACjCA,CAAAA,CAAM,YAAA,CAAa,iBAAA,GACrBE,EAAG,iBAAA,CAAoBF,CAAAA,CAAM,YAAA,CAAa,iBAAA,CAAA,CAC5CC,EAAO,YAAA,CAAeC,EACxB,CAEA,OAAOD,CACT,CAIO,SAASE,CAAAA,CAAoBH,CAAAA,CAAuC,CACzE,IAAMC,CAAAA,CAAqB,CACzB,UAAA,CAAYH,EACZ,OAAA,CAAS,SAAA,CACT,IAAA,CAAME,CAAAA,CAAM,KACZ,GAAA,CAAKA,CAAAA,CAAM,GACb,CAAA,CAEA,OAAIA,CAAAA,CAAM,WAAA,GAAaC,CAAAA,CAAO,WAAA,CAAcD,EAAM,WAAA,CAAA,CAE9CA,CAAAA,CAAM,SAAA,GACRC,CAAAA,CAAO,gBAAkB,CACvB,OAAA,CAAS,cAAA,CACT,MAAA,CAAQ,CACN,OAAA,CAAS,YAAA,CACT,WAAA,CAAa,CAAA,EAAGD,EAAM,SAAS,CAAA,CAAA,EAAIA,CAAAA,CAAM,gBAAA,EAAoB,GAAG,CAAA,qBAAA,CAClE,CAAA,CACA,aAAA,CAAe,kCACjB,GAGKC,CACT,CAIO,SAASG,CAAAA,CAAuBC,EAAqC,CAC1E,OAAO,CACL,UAAA,CAAYP,EACZ,OAAA,CAAS,gBAAA,CACT,eAAA,CAAiBO,CAAAA,CAAM,GAAA,CAAI,CAACC,CAAAA,CAAMC,CAAAA,IAAW,CAC3C,OAAA,CAAS,UAAA,CACT,QAAA,CAAUA,CAAAA,CAAQ,EAClB,IAAA,CAAMD,CAAAA,CAAK,IAAA,CACX,IAAA,CAAMA,EAAK,GACb,CAAA,CAAE,CACJ,CACF,CAIO,SAASE,CAAAA,CAAoBR,CAAAA,CAAuC,CACzE,IAAMC,CAAAA,CAAqB,CACzB,UAAA,CAAYH,CAAAA,CACZ,QAAS,SAAA,CACT,QAAA,CAAUE,CAAAA,CAAM,QAAA,CAChB,IAAKA,CAAAA,CAAM,GACb,CAAA,CASA,GAPIA,EAAM,WAAA,GAAaC,CAAAA,CAAO,WAAA,CAAcD,CAAAA,CAAM,aAC9CA,CAAAA,CAAM,MAAA,EAAQ,MAAA,GAAQC,CAAAA,CAAO,MAAQD,CAAAA,CAAM,MAAA,CAAA,CAC3CA,CAAAA,CAAM,aAAA,GAAeC,EAAO,aAAA,CAAgBD,CAAAA,CAAM,aAAA,CAAA,CAClDA,CAAAA,CAAM,eAAcC,CAAAA,CAAO,YAAA,CAAeD,CAAAA,CAAM,YAAA,CAAA,CAChDA,EAAM,OAAA,GAASC,CAAAA,CAAO,cAAA,CAAiBD,CAAAA,CAAM,SAC7CA,CAAAA,CAAM,QAAA,EAAU,MAAA,GAAQC,CAAAA,CAAO,SAAWD,CAAAA,CAAM,QAAA,CAAA,CAEhDA,CAAAA,CAAM,MAAA,CAAQ,CAChB,IAAMS,CAAAA,CAAU,KAAA,CAAM,OAAA,CAAQT,EAAM,MAAM,CAAA,CACtCA,CAAAA,CAAM,MAAA,CACN,CAACA,CAAAA,CAAM,MAAM,CAAA,CACjBC,CAAAA,CAAO,OAASQ,CAAAA,CAAQ,GAAA,CAAKC,CAAAA,EAAM,CACjC,IAAMC,CAAAA,CAAiC,CACrC,OAAA,CAAS,QAAA,CACT,KAAMD,CAAAA,CAAE,IACV,CAAA,CACA,OAAIA,EAAE,GAAA,GAAKC,CAAAA,CAAO,GAAA,CAAMD,CAAAA,CAAE,KACnBC,CACT,CAAC,EACH,CAEA,GAAIX,CAAAA,CAAM,SAAA,CAAW,CACnB,IAAMY,EAA+B,CACnC,OAAA,CAAS,cAAA,CACT,IAAA,CAAMZ,EAAM,SAAA,CAAU,IACxB,CAAA,CACIA,CAAAA,CAAM,UAAU,IAAA,GAClBY,CAAAA,CAAI,IAAA,CAAO,CACT,QAAS,aAAA,CACT,GAAA,CAAKZ,CAAAA,CAAM,SAAA,CAAU,IACvB,CAAA,CAAA,CAEFC,CAAAA,CAAO,SAAA,CAAYW,EACrB,CAEA,OAAOX,CACT,CAIO,SAASY,EAAoBb,CAAAA,CAAuC,CACzE,IAAMC,CAAAA,CAAqB,CACzB,UAAA,CAAYH,CAAAA,CACZ,OAAA,CAAS,UACT,IAAA,CAAME,CAAAA,CAAM,IAAA,CACZ,GAAA,CAAKA,EAAM,GACb,CAAA,CAUA,GARIA,CAAAA,CAAM,cAAaC,CAAAA,CAAO,WAAA,CAAcD,CAAAA,CAAM,WAAA,CAAA,CAC9CA,EAAM,MAAA,EAAQ,MAAA,GAAQC,CAAAA,CAAO,KAAA,CAAQD,EAAM,MAAA,CAAA,CAC3CA,CAAAA,CAAM,KAAA,GACRC,CAAAA,CAAO,MAAQ,CAAE,OAAA,CAAS,OAAA,CAAS,IAAA,CAAMD,EAAM,KAAM,CAAA,CAAA,CAEnDA,CAAAA,CAAM,GAAA,GAAKC,EAAO,GAAA,CAAMD,CAAAA,CAAM,GAAA,CAAA,CAC9BA,CAAAA,CAAM,OAAMC,CAAAA,CAAO,IAAA,CAAOD,CAAAA,CAAM,IAAA,CAAA,CAEhCA,EAAM,KAAA,GAAU,MAAA,CAAW,CAC7B,IAAMc,EAAiC,CACrC,OAAA,CAAS,OAAA,CACT,KAAA,CAAOd,EAAM,KAAA,CACb,aAAA,CAAeA,CAAAA,CAAM,aAAA,EAAiB,KACxC,CAAA,CACIA,CAAAA,CAAM,YAAA,GACRc,CAAAA,CAAM,aAAe,CAAA,mBAAA,EAAsBd,CAAAA,CAAM,YAAY,CAAA,CAAA,CAAA,CAE/DC,EAAO,MAAA,CAASa,EAClB,CAEA,GAAId,EAAM,WAAA,GAAgB,MAAA,CAAW,CACnC,IAAMe,EAAkC,CACtC,OAAA,CAAS,iBAAA,CACT,WAAA,CAAaf,EAAM,WACrB,CAAA,CACIA,CAAAA,CAAM,WAAA,GAAgB,SAAWe,CAAAA,CAAO,WAAA,CAAcf,CAAAA,CAAM,WAAA,CAAA,CAChEC,EAAO,eAAA,CAAkBc,EAC3B,CAEA,OAAOd,CACT,CAIO,SAASe,CAAAA,CAAgBX,CAAAA,CAA8B,CAC5D,OAAO,CACL,UAAA,CAAYP,CAAAA,CACZ,QAAS,SAAA,CACT,UAAA,CAAYO,CAAAA,CAAM,GAAA,CAAKC,IAAU,CAC/B,OAAA,CAAS,UAAA,CACT,IAAA,CAAMA,EAAK,QAAA,CACX,cAAA,CAAgB,CACd,OAAA,CAAS,SACT,IAAA,CAAMA,CAAAA,CAAK,MACb,CACF,EAAE,CACJ,CACF,CAIO,SAASW,EAAkBjB,CAAAA,CAAqC,CACrE,IAAMkB,CAAAA,CAAW,CAAC,EAAElB,CAAAA,CAAM,KAAA,EAASA,CAAAA,CAAM,UAAYA,CAAAA,CAAM,QAAA,CAAA,CAErDC,CAAAA,CAAqB,CACzB,WAAYH,CAAAA,CACZ,OAAA,CAASoB,CAAAA,CAAW,aAAA,CAAgB,OAAA,CACpC,IAAA,CAAMlB,CAAAA,CAAM,IAAA,CACZ,UAAWA,CAAAA,CAAM,SACnB,CAAA,CAcA,GAZIA,EAAM,OAAA,GAASC,CAAAA,CAAO,OAAA,CAAUD,CAAAA,CAAM,SACtCA,CAAAA,CAAM,WAAA,GAAaC,CAAAA,CAAO,WAAA,CAAcD,EAAM,WAAA,CAAA,CAC9CA,CAAAA,CAAM,GAAA,GAAKC,CAAAA,CAAO,IAAMD,CAAAA,CAAM,GAAA,CAAA,CAC9BA,CAAAA,CAAM,MAAA,EAAQ,SAAQC,CAAAA,CAAO,KAAA,CAAQD,CAAAA,CAAM,MAAA,CAAA,CAE3CA,EAAM,WAAA,GACRC,CAAAA,CAAO,WAAA,CAAc,CAAA,mBAAA,EAAsBD,EAAM,WAAW,CAAA,CAAA,CAAA,CAE1DA,CAAAA,CAAM,mBAAA,GACRC,EAAO,mBAAA,CAAsB,CAAA,mBAAA,EAAsBD,CAAAA,CAAM,mBAAmB,IAG1EA,CAAAA,CAAM,QAAA,CAAU,CAClB,IAAMmB,EAAMnB,CAAAA,CAAM,QAAA,CAClB,GAAImB,CAAAA,CAAI,KAAO,CAACA,CAAAA,CAAI,OAAA,CAClBlB,CAAAA,CAAO,SAAW,CAChB,OAAA,CAAS,iBAAA,CACT,IAAA,CAAMkB,EAAI,IAAA,CACV,GAAA,CAAKA,CAAAA,CAAI,GACX,OACK,CACL,IAAMC,CAAAA,CAAiC,CACrC,QAAS,OAAA,CACT,IAAA,CAAMD,CAAAA,CAAI,IACZ,EACIA,CAAAA,CAAI,GAAA,GAAKC,CAAAA,CAAM,GAAA,CAAMD,EAAI,GAAA,CAAA,CACzBA,CAAAA,CAAI,OAAA,GACNC,CAAAA,CAAM,QACJ,OAAOD,CAAAA,CAAI,OAAA,EAAY,QAAA,CACnBA,EAAI,OAAA,CACJ,CAAE,OAAA,CAAS,eAAA,CAAiB,GAAGA,CAAAA,CAAI,OAAQ,CAAA,CAAA,CAEnDlB,CAAAA,CAAO,SAAWmB,EACpB,CACF,CAEA,GAAIpB,EAAM,SAAA,CAAW,CACnB,IAAMqB,CAAAA,CAA8B,CAClC,OAAA,CAAS,cAAA,CACT,IAAA,CAAMrB,CAAAA,CAAM,UAAU,IACxB,CAAA,CACIA,CAAAA,CAAM,SAAA,CAAU,MAAKqB,CAAAA,CAAI,GAAA,CAAMrB,CAAAA,CAAM,SAAA,CAAU,KACnDC,CAAAA,CAAO,SAAA,CAAYoB,EACrB,CAEA,GAAIrB,CAAAA,CAAM,SAAA,CAAW,CAInB,IAAMsB,GAHa,KAAA,CAAM,OAAA,CAAQtB,CAAAA,CAAM,SAAS,EAC5CA,CAAAA,CAAM,SAAA,CACN,CAACA,CAAAA,CAAM,SAAS,CAAA,EACM,GAAA,CAAKuB,CAAAA,EAAM,CACnC,IAAMC,CAAAA,CAAgC,CAAE,OAAA,CAAS,SAAU,IAAA,CAAMD,CAAAA,CAAE,IAAK,CAAA,CACxE,OAAIA,CAAAA,CAAE,GAAA,GAAKC,CAAAA,CAAM,GAAA,CAAMD,EAAE,GAAA,CAAA,CAClBC,CACT,CAAC,CAAA,CACDvB,EAAO,SAAA,CAAYqB,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAIA,EAAO,CAAC,CAAA,CAAIA,EACvD,CAEA,GAAIJ,CAAAA,CAAU,CAEZ,GADIlB,CAAAA,CAAM,QAAOC,CAAAA,CAAO,KAAA,CAAQD,CAAAA,CAAM,KAAA,CAAA,CAClCA,EAAM,QAAA,CAAU,CAClB,IAAMyB,CAAAA,CAA4B,CAChC,OAAA,CAAS,YAAA,CACT,IAAA,CAAMzB,CAAAA,CAAM,SAAS,IACvB,CAAA,CACIA,CAAAA,CAAM,QAAA,CAAS,MAAKyB,CAAAA,CAAE,GAAA,CAAMzB,CAAAA,CAAM,QAAA,CAAS,KAC/CC,CAAAA,CAAO,QAAA,CAAWwB,EACpB,CACA,GAAIzB,CAAAA,CAAM,QAAA,CAAU,CAClB,IAAMyB,EAA4B,CAChC,OAAA,CAAS,YAAA,CACT,IAAA,CAAMzB,EAAM,QAAA,CAAS,IACvB,CAAA,CACIA,CAAAA,CAAM,SAAS,GAAA,GAAKyB,CAAAA,CAAE,GAAA,CAAMzB,CAAAA,CAAM,SAAS,GAAA,CAAA,CAC/CC,CAAAA,CAAO,QAAA,CAAWwB,EACpB,CACF,CAEA,OAAOxB,CACT,CAIO,SAASyB,CAAAA,CAAmB1B,CAAAA,CAAsC,CACvE,IAAMC,EAAqB,CACzB,UAAA,CAAYH,CAAAA,CACZ,OAAA,CAAS,SACT,IAAA,CAAME,CAAAA,CAAM,IACd,CAAA,CAWA,GATIA,CAAAA,CAAM,GAAA,GAAKC,CAAAA,CAAO,GAAA,CAAMD,EAAM,GAAA,CAAA,CAC9BA,CAAAA,CAAM,KAAA,GAAOC,CAAAA,CAAO,MAAQD,CAAAA,CAAM,KAAA,CAAA,CAClCA,CAAAA,CAAM,QAAA,GAAUC,EAAO,QAAA,CAAWD,CAAAA,CAAM,QAAA,CAAA,CACxCA,CAAAA,CAAM,cAAaC,CAAAA,CAAO,WAAA,CAAcD,CAAAA,CAAM,WAAA,CAAA,CAC9CA,EAAM,KAAA,GAAOC,CAAAA,CAAO,KAAA,CAAQD,CAAAA,CAAM,OAClCA,CAAAA,CAAM,SAAA,GAAWC,CAAAA,CAAO,SAAA,CAAYD,EAAM,SAAA,CAAA,CAC1CA,CAAAA,CAAM,SAAA,GAAWC,CAAAA,CAAO,UAAYD,CAAAA,CAAM,SAAA,CAAA,CAC1CA,CAAAA,CAAM,MAAA,EAAQ,SAAQC,CAAAA,CAAO,MAAA,CAASD,CAAAA,CAAM,MAAA,CAAA,CAE5CA,CAAAA,CAAM,QAAA,CAAU,CAClB,IAAMqB,EAA8B,CAAE,OAAA,CAAS,cAAA,CAAgB,IAAA,CAAMrB,EAAM,QAAA,CAAS,IAAK,CAAA,CACrFA,CAAAA,CAAM,SAAS,GAAA,GAAKqB,CAAAA,CAAI,GAAA,CAAMrB,CAAAA,CAAM,SAAS,GAAA,CAAA,CACjDC,CAAAA,CAAO,QAAA,CAAWoB,EACpB,CAEA,OAAIrB,CAAAA,CAAM,OAAA,GACRC,CAAAA,CAAO,QACL,OAAOD,CAAAA,CAAM,OAAA,EAAY,QAAA,CACrBA,EAAM,OAAA,CACN,CAAE,OAAA,CAAS,eAAA,CAAiB,GAAGA,CAAAA,CAAM,OAAQ,CAAA,CAAA,CAG9CC,CACT,CAIO,SAAS0B,CAAAA,CAAmB3B,CAAAA,CAAsC,CACvE,IAAMC,CAAAA,CAAqB,CACzB,UAAA,CAAYH,CAAAA,CACZ,QAAS,QAAA,CACT,IAAA,CAAME,CAAAA,CAAM,IACd,EAcA,GAZIA,CAAAA,CAAM,WAAA,GAAaC,CAAAA,CAAO,YAAcD,CAAAA,CAAM,WAAA,CAAA,CAC9CA,CAAAA,CAAM,MAAA,EAAQ,SAAQC,CAAAA,CAAO,KAAA,CAAQD,CAAAA,CAAM,MAAA,CAAA,CAC3CA,EAAM,aAAA,GAAeC,CAAAA,CAAO,aAAA,CAAgBD,CAAAA,CAAM,eAClDA,CAAAA,CAAM,QAAA,GAAUC,CAAAA,CAAO,QAAA,CAAWD,EAAM,QAAA,CAAA,CACxCA,CAAAA,CAAM,QAAA,GAAUC,CAAAA,CAAO,SAAWD,CAAAA,CAAM,QAAA,CAAA,CACxCA,CAAAA,CAAM,SAAA,GAAWC,EAAO,SAAA,CAAYD,CAAAA,CAAM,SAAA,CAAA,CAC1CA,CAAAA,CAAM,cAAgB,MAAA,GAAWC,CAAAA,CAAO,WAAA,CAAc,MAAA,CAAOD,EAAM,WAAW,CAAA,CAAA,CAC9EA,CAAAA,CAAM,cAAA,GAAgBC,EAAO,cAAA,CAAiBD,CAAAA,CAAM,cAAA,CAAA,CACpDA,CAAAA,CAAM,gBAAeC,CAAAA,CAAO,aAAA,CAAgBD,CAAAA,CAAM,aAAA,CAAA,CAClDA,EAAM,gBAAA,EAAkB,MAAA,GAAQC,CAAAA,CAAO,gBAAA,CAAmBD,EAAM,gBAAA,CAAA,CAChEA,CAAAA,CAAM,QAAA,EAAU,MAAA,GAAQC,EAAO,QAAA,CAAWD,CAAAA,CAAM,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,CAAA,CAElEA,CAAAA,CAAM,MAAA,CAAQ,CAChB,IAAMW,CAAAA,CAAiC,CAAE,OAAA,CAAS,QAAA,CAAU,KAAMX,CAAAA,CAAM,MAAA,CAAO,IAAK,CAAA,CAChFA,EAAM,MAAA,CAAO,GAAA,GAAKW,CAAAA,CAAO,GAAA,CAAMX,EAAM,MAAA,CAAO,GAAA,CAAA,CAChDC,CAAAA,CAAO,MAAA,CAASU,EAClB,CAmBA,GAjBIX,CAAAA,CAAM,oBAAoB,MAAA,GAC5BC,CAAAA,CAAO,kBAAA,CAAqBD,CAAAA,CAAM,mBAAmB,GAAA,CAAK4B,CAAAA,EAAS,CACjE,GAAI,OAAOA,CAAAA,EAAS,QAAA,CAClB,OAAO,CAAE,QAAS,WAAA,CAAa,IAAA,CAAMA,CAAK,CAAA,CAE5C,IAAMC,CAAAA,CAA6B,CAAE,OAAA,CAAS,WAAA,CAAa,KAAMD,CAAAA,CAAK,IAAK,CAAA,CAC3E,OAAIA,EAAK,IAAA,GAAMC,CAAAA,CAAE,IAAA,CAAOD,CAAAA,CAAK,MACzBA,CAAAA,CAAK,GAAA,GAAKC,CAAAA,CAAE,GAAA,CAAMD,EAAK,GAAA,CAAA,CACvBA,CAAAA,CAAK,KAAA,GAAOC,CAAAA,CAAE,MAAQD,CAAAA,CAAK,KAAA,CAAA,CACxBC,CACT,CAAC,GAGC7B,CAAAA,CAAM,SAAA,EAAa,MAAA,CAAO,IAAA,CAAKA,EAAM,SAAS,CAAA,CAAE,MAAA,GAClDC,CAAAA,CAAO,UAAY,CAAE,OAAA,CAAS,sBAAA,CAAwB,GAAGD,EAAM,SAAU,CAAA,CAAA,CAGvEA,CAAAA,CAAM,WAAA,GAAgB,OAAW,CACnC,IAAMe,CAAAA,CAAkC,CACtC,QAAS,iBAAA,CACT,WAAA,CAAaf,CAAAA,CAAM,WACrB,EACIA,CAAAA,CAAM,WAAA,GAAgB,MAAA,GAAWe,CAAAA,CAAO,YAAcf,CAAAA,CAAM,WAAA,CAAA,CAChEC,CAAAA,CAAO,eAAA,CAAkBc,EAC3B,CAEA,OAAOd,CACT,CAIO,SAAS6B,CAAAA,CAAuB9B,CAAAA,CAA0C,CAC/E,IAAMC,EAAqB,CACzB,UAAA,CAAYH,CAAAA,CACZ,OAAA,CAAS,aACT,KAAA,CAAOE,CAAAA,CAAM,KAAA,CACb,WAAA,CAAaA,EAAM,WAAA,CACnB,UAAA,CAAYA,CAAAA,CAAM,UACpB,EAEIA,CAAAA,CAAM,YAAA,GAAcC,CAAAA,CAAO,YAAA,CAAeD,EAAM,YAAA,CAAA,CAChDA,CAAAA,CAAM,GAAA,GAAKC,CAAAA,CAAO,IAAMD,CAAAA,CAAM,GAAA,CAAA,CAC9BA,CAAAA,CAAM,sBAAA,GAAwBC,EAAO,sBAAA,CAAyBD,CAAAA,CAAM,sBAAA,CAAA,CACpEA,CAAAA,CAAM,wBACRC,CAAAA,CAAO,qBAAA,CAAwB,CAC7B,OAAA,CAAS,oCACT,kBAAA,CAAoBD,CAAAA,CAAM,qBAC5B,CAAA,CAAA,CAGEA,EAAM,cAAA,GACRC,CAAAA,CAAO,cAAA,EAAiB,KAAA,CAAM,QAAQD,CAAAA,CAAM,cAAc,CAAA,CACtDA,CAAAA,CAAM,cAAA,CAAA,CAAA,CAIRA,CAAAA,CAAM,MAAA,GACRC,CAAAA,CAAO,OAAS,KAAA,CAAM,OAAA,CAAQD,CAAAA,CAAM,MAAM,EAAIA,CAAAA,CAAM,MAAA,CAAO,IAAA,CAAK,IAAI,EAAIA,CAAAA,CAAM,MAAA,CAAA,CAGhF,IAAMqB,CAAAA,CAA+B,CACnC,OAAA,CAAS,cAAA,CACT,IAAA,CAAMrB,CAAAA,CAAM,mBAAmB,IACjC,CAAA,CAgBA,GAfIA,CAAAA,CAAM,mBAAmB,MAAA,GAAQqB,CAAAA,CAAI,MAAA,CAASrB,CAAAA,CAAM,mBAAmB,MAAA,CAAA,CACvEA,CAAAA,CAAM,kBAAA,CAAmB,IAAA,GAAMqB,EAAI,IAAA,CAAOrB,CAAAA,CAAM,kBAAA,CAAmB,IAAA,CAAA,CACvEC,EAAO,kBAAA,CAAqBoB,CAAAA,CAExBrB,CAAAA,CAAM,MAAA,GACRC,EAAO,eAAA,CAAkB,aAAA,CAAA,CAGvBD,CAAAA,CAAM,WAAA,GACRC,EAAO,WAAA,CAAc,CACnB,OAAA,CAAS,OAAA,CACT,QAAS,CAAE,OAAA,CAAS,eAAA,CAAiB,GAAGD,EAAM,WAAY,CAC5D,CAAA,CAAA,CAGEA,CAAAA,CAAM,WAAY,CACpB,GAAM,CAAE,QAAA,CAAA+B,EAAU,KAAA,CAAAC,CAAAA,CAAO,QAAA,CAAAC,CAAAA,CAAW,MAAO,CAAA,CAAIjC,CAAAA,CAAM,UAAA,CAC/CkC,CAAAA,CAA0C,CAC9C,OAAA,CAAS,gBAAA,CACT,QAAA,CAAAH,CACF,EACI,OAAOC,CAAAA,EAAU,QAAA,CACnBE,CAAAA,CAAe,MAAQF,CAAAA,CAEvBE,CAAAA,CAAe,KAAA,CAAQ,CACrB,QAAS,mBAAA,CACT,QAAA,CAAUF,CAAAA,CAAM,QAAA,CAChB,SAAUA,CAAAA,CAAM,QAAA,CAChB,QAAA,CAAAC,CACF,EAEFhC,CAAAA,CAAO,UAAA,CAAaiC,EACtB,CAEA,OAAIlC,CAAAA,CAAM,UAAA,GACRC,CAAAA,CAAO,UAAA,CAAa,CAClB,OAAA,CAAS,eAAA,CACT,IAAA,CAAMD,CAAAA,CAAM,WAAW,IAAA,CACvB,KAAA,CAAOA,CAAAA,CAAM,UAAA,CAAW,KAC1B,CAAA,CAAA,CAGKC,CACT,CAQO,SAASkC,KAAkBC,CAAAA,CAAmC,CACnE,OAAO,CACL,WAAYtC,CAAAA,CACZ,OAAA,CAAS,UAAA,CACT,QAAA,CAAUsC,EAAQ,GAAA,CAAI,CAAC,CAAE,UAAA,CAAYC,EAAM,GAAGC,CAAK,CAAA,GAAMA,CAAI,CAC/D,CACF","file":"chunk-A62THBIS.cjs","sourcesContent":["import type {\n JSONLDBase,\n BreadcrumbItem,\n OrganizationSchemaInput,\n WebsiteSchemaInput,\n ArticleSchemaInput,\n ProductSchemaInput,\n FAQItem,\n EventSchemaInput,\n PersonSchemaInput,\n RecipeSchemaInput,\n JobPostingSchemaInput,\n} from \"../types/index.js\";\n\nconst CONTEXT = \"https://schema.org\";\n\n// ─── Organization ─────────────────────────────────────────────\n\nexport function createOrganizationSchema(\n input: OrganizationSchemaInput\n): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Organization\",\n name: input.name,\n url: input.url,\n };\n\n if (input.logo) schema.logo = input.logo;\n if (input.description) schema.description = input.description;\n if (input.sameAs?.length) schema.sameAs = input.sameAs;\n\n if (input.contactPoint) {\n const cp: Record<string, unknown> = {\n \"@type\": \"ContactPoint\",\n };\n if (input.contactPoint.telephone)\n cp.telephone = input.contactPoint.telephone;\n if (input.contactPoint.contactType)\n cp.contactType = input.contactPoint.contactType;\n if (input.contactPoint.email) cp.email = input.contactPoint.email;\n if (input.contactPoint.areaServed)\n cp.areaServed = input.contactPoint.areaServed;\n if (input.contactPoint.availableLanguage)\n cp.availableLanguage = input.contactPoint.availableLanguage;\n schema.contactPoint = cp;\n }\n\n return schema;\n}\n\n// ─── Website ──────────────────────────────────────────────────\n\nexport function createWebsiteSchema(input: WebsiteSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"WebSite\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n\n if (input.searchUrl) {\n schema.potentialAction = {\n \"@type\": \"SearchAction\",\n target: {\n \"@type\": \"EntryPoint\",\n urlTemplate: `${input.searchUrl}?${input.searchQueryParam ?? \"q\"}={search_term_string}`,\n },\n \"query-input\": \"required name=search_term_string\",\n };\n }\n\n return schema;\n}\n\n// ─── Breadcrumb ───────────────────────────────────────────────\n\nexport function createBreadcrumbSchema(items: BreadcrumbItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"BreadcrumbList\",\n itemListElement: items.map((item, index) => ({\n \"@type\": \"ListItem\",\n position: index + 1,\n name: item.name,\n item: item.url,\n })),\n };\n}\n\n// ─── Article ──────────────────────────────────────────────────\n\nexport function createArticleSchema(input: ArticleSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Article\",\n headline: input.headline,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.datePublished) schema.datePublished = input.datePublished;\n if (input.dateModified) schema.dateModified = input.dateModified;\n if (input.section) schema.articleSection = input.section;\n if (input.keywords?.length) schema.keywords = input.keywords;\n\n if (input.author) {\n const authors = Array.isArray(input.author)\n ? input.author\n : [input.author];\n schema.author = authors.map((a) => {\n const person: Record<string, string> = {\n \"@type\": \"Person\",\n name: a.name,\n };\n if (a.url) person.url = a.url;\n return person;\n });\n }\n\n if (input.publisher) {\n const pub: Record<string, unknown> = {\n \"@type\": \"Organization\",\n name: input.publisher.name,\n };\n if (input.publisher.logo) {\n pub.logo = {\n \"@type\": \"ImageObject\",\n url: input.publisher.logo,\n };\n }\n schema.publisher = pub;\n }\n\n return schema;\n}\n\n// ─── Product ──────────────────────────────────────────────────\n\nexport function createProductSchema(input: ProductSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Product\",\n name: input.name,\n url: input.url,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.brand) {\n schema.brand = { \"@type\": \"Brand\", name: input.brand };\n }\n if (input.sku) schema.sku = input.sku;\n if (input.gtin) schema.gtin = input.gtin;\n\n if (input.price !== undefined) {\n const offer: Record<string, unknown> = {\n \"@type\": \"Offer\",\n price: input.price,\n priceCurrency: input.priceCurrency ?? \"USD\",\n };\n if (input.availability) {\n offer.availability = `https://schema.org/${input.availability}`;\n }\n schema.offers = offer;\n }\n\n if (input.ratingValue !== undefined) {\n const rating: Record<string, unknown> = {\n \"@type\": \"AggregateRating\",\n ratingValue: input.ratingValue,\n };\n if (input.reviewCount !== undefined) rating.reviewCount = input.reviewCount;\n schema.aggregateRating = rating;\n }\n\n return schema;\n}\n\n// ─── FAQ ──────────────────────────────────────────────────────\n\nexport function createFAQSchema(items: FAQItem[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"FAQPage\",\n mainEntity: items.map((item) => ({\n \"@type\": \"Question\",\n name: item.question,\n acceptedAnswer: {\n \"@type\": \"Answer\",\n text: item.answer,\n },\n })),\n };\n}\n\n// ─── Event / SportsEvent ─────────────────────────────────────\n\nexport function createEventSchema(input: EventSchemaInput): JSONLDBase {\n const isSports = !!(input.sport ?? input.homeTeam ?? input.awayTeam);\n\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": isSports ? \"SportsEvent\" : \"Event\",\n name: input.name,\n startDate: input.startDate,\n };\n\n if (input.endDate) schema.endDate = input.endDate;\n if (input.description) schema.description = input.description;\n if (input.url) schema.url = input.url;\n if (input.images?.length) schema.image = input.images;\n\n if (input.eventStatus) {\n schema.eventStatus = `https://schema.org/${input.eventStatus}`;\n }\n if (input.eventAttendanceMode) {\n schema.eventAttendanceMode = `https://schema.org/${input.eventAttendanceMode}`;\n }\n\n if (input.location) {\n const loc = input.location;\n if (loc.url && !loc.address) {\n schema.location = {\n \"@type\": \"VirtualLocation\",\n name: loc.name,\n url: loc.url,\n };\n } else {\n const place: Record<string, unknown> = {\n \"@type\": \"Place\",\n name: loc.name,\n };\n if (loc.url) place.url = loc.url;\n if (loc.address) {\n place.address =\n typeof loc.address === \"string\"\n ? loc.address\n : { \"@type\": \"PostalAddress\", ...loc.address };\n }\n schema.location = place;\n }\n }\n\n if (input.organizer) {\n const org: Record<string, string> = {\n \"@type\": \"Organization\",\n name: input.organizer.name,\n };\n if (input.organizer.url) org.url = input.organizer.url;\n schema.organizer = org;\n }\n\n if (input.performer) {\n const performers = Array.isArray(input.performer)\n ? input.performer\n : [input.performer];\n const mapped = performers.map((p) => {\n const entry: Record<string, string> = { \"@type\": \"Person\", name: p.name };\n if (p.url) entry.url = p.url;\n return entry;\n });\n schema.performer = mapped.length === 1 ? mapped[0] : mapped;\n }\n\n if (isSports) {\n if (input.sport) schema.sport = input.sport;\n if (input.homeTeam) {\n const t: Record<string, string> = {\n \"@type\": \"SportsTeam\",\n name: input.homeTeam.name,\n };\n if (input.homeTeam.url) t.url = input.homeTeam.url;\n schema.homeTeam = t;\n }\n if (input.awayTeam) {\n const t: Record<string, string> = {\n \"@type\": \"SportsTeam\",\n name: input.awayTeam.name,\n };\n if (input.awayTeam.url) t.url = input.awayTeam.url;\n schema.awayTeam = t;\n }\n }\n\n return schema;\n}\n\n// ─── Person ───────────────────────────────────────────────────\n\nexport function createPersonSchema(input: PersonSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Person\",\n name: input.name,\n };\n\n if (input.url) schema.url = input.url;\n if (input.image) schema.image = input.image;\n if (input.jobTitle) schema.jobTitle = input.jobTitle;\n if (input.description) schema.description = input.description;\n if (input.email) schema.email = input.email;\n if (input.telephone) schema.telephone = input.telephone;\n if (input.birthDate) schema.birthDate = input.birthDate;\n if (input.sameAs?.length) schema.sameAs = input.sameAs;\n\n if (input.worksFor) {\n const org: Record<string, string> = { \"@type\": \"Organization\", name: input.worksFor.name };\n if (input.worksFor.url) org.url = input.worksFor.url;\n schema.worksFor = org;\n }\n\n if (input.address) {\n schema.address =\n typeof input.address === \"string\"\n ? input.address\n : { \"@type\": \"PostalAddress\", ...input.address };\n }\n\n return schema;\n}\n\n// ─── Recipe ───────────────────────────────────────────────────\n\nexport function createRecipeSchema(input: RecipeSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"Recipe\",\n name: input.name,\n };\n\n if (input.description) schema.description = input.description;\n if (input.images?.length) schema.image = input.images;\n if (input.datePublished) schema.datePublished = input.datePublished;\n if (input.prepTime) schema.prepTime = input.prepTime;\n if (input.cookTime) schema.cookTime = input.cookTime;\n if (input.totalTime) schema.totalTime = input.totalTime;\n if (input.recipeYield !== undefined) schema.recipeYield = String(input.recipeYield);\n if (input.recipeCategory) schema.recipeCategory = input.recipeCategory;\n if (input.recipeCuisine) schema.recipeCuisine = input.recipeCuisine;\n if (input.recipeIngredient?.length) schema.recipeIngredient = input.recipeIngredient;\n if (input.keywords?.length) schema.keywords = input.keywords.join(\", \");\n\n if (input.author) {\n const person: Record<string, string> = { \"@type\": \"Person\", name: input.author.name };\n if (input.author.url) person.url = input.author.url;\n schema.author = person;\n }\n\n if (input.recipeInstructions?.length) {\n schema.recipeInstructions = input.recipeInstructions.map((step) => {\n if (typeof step === \"string\") {\n return { \"@type\": \"HowToStep\", text: step };\n }\n const s: Record<string, unknown> = { \"@type\": \"HowToStep\", text: step.text };\n if (step.name) s.name = step.name;\n if (step.url) s.url = step.url;\n if (step.image) s.image = step.image;\n return s;\n });\n }\n\n if (input.nutrition && Object.keys(input.nutrition).length) {\n schema.nutrition = { \"@type\": \"NutritionInformation\", ...input.nutrition };\n }\n\n if (input.ratingValue !== undefined) {\n const rating: Record<string, unknown> = {\n \"@type\": \"AggregateRating\",\n ratingValue: input.ratingValue,\n };\n if (input.reviewCount !== undefined) rating.reviewCount = input.reviewCount;\n schema.aggregateRating = rating;\n }\n\n return schema;\n}\n\n// ─── JobPosting ───────────────────────────────────────────────\n\nexport function createJobPostingSchema(input: JobPostingSchemaInput): JSONLDBase {\n const schema: JSONLDBase = {\n \"@context\": CONTEXT,\n \"@type\": \"JobPosting\",\n title: input.title,\n description: input.description,\n datePosted: input.datePosted,\n };\n\n if (input.validThrough) schema.validThrough = input.validThrough;\n if (input.url) schema.url = input.url;\n if (input.experienceRequirements) schema.experienceRequirements = input.experienceRequirements;\n if (input.educationRequirements) {\n schema.educationRequirements = {\n \"@type\": \"EducationalOccupationalCredential\",\n credentialCategory: input.educationRequirements,\n };\n }\n\n if (input.employmentType) {\n schema.employmentType = Array.isArray(input.employmentType)\n ? input.employmentType\n : input.employmentType;\n }\n\n if (input.skills) {\n schema.skills = Array.isArray(input.skills) ? input.skills.join(\", \") : input.skills;\n }\n\n const org: Record<string, unknown> = {\n \"@type\": \"Organization\",\n name: input.hiringOrganization.name,\n };\n if (input.hiringOrganization.sameAs) org.sameAs = input.hiringOrganization.sameAs;\n if (input.hiringOrganization.logo) org.logo = input.hiringOrganization.logo;\n schema.hiringOrganization = org;\n\n if (input.remote) {\n schema.jobLocationType = \"TELECOMMUTE\";\n }\n\n if (input.jobLocation) {\n schema.jobLocation = {\n \"@type\": \"Place\",\n address: { \"@type\": \"PostalAddress\", ...input.jobLocation },\n };\n }\n\n if (input.baseSalary) {\n const { currency, value, unitText = \"YEAR\" } = input.baseSalary;\n const monetaryAmount: Record<string, unknown> = {\n \"@type\": \"MonetaryAmount\",\n currency,\n };\n if (typeof value === \"number\") {\n monetaryAmount.value = value;\n } else {\n monetaryAmount.value = {\n \"@type\": \"QuantitativeValue\",\n minValue: value.minValue,\n maxValue: value.maxValue,\n unitText,\n };\n }\n schema.baseSalary = monetaryAmount;\n }\n\n if (input.identifier) {\n schema.identifier = {\n \"@type\": \"PropertyValue\",\n name: input.identifier.name,\n value: input.identifier.value,\n };\n }\n\n return schema;\n}\n\n// ─── Schema composition ───────────────────────────────────────\n\n/**\n * Compose multiple JSON-LD schemas into a single @graph array.\n * Useful for embedding multiple structured data blocks in one script tag.\n */\nexport function composeSchemas(...schemas: JSONLDBase[]): JSONLDBase {\n return {\n \"@context\": CONTEXT,\n \"@type\": \"ItemList\",\n \"@graph\": schemas.map(({ \"@context\": _ctx, ...rest }) => rest),\n };\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {i,l,o,p as p$1,q,a}from'./chunk-LP66SUGR.js';import t from'react';function _({title:e,titleTemplate:n,description:o$1,canonical:i$1,robots:c,openGraph:s,twitter:f,alternates:g,additionalMetaTags:h,additionalLinkTags:u,jsonLd:d,nonce:y}){let l$1=[],O=0,m=()=>`seo-${O++}`,x=i(e,n);x&&l$1.push(t.createElement("title",{key:m()},x)),o$1?.trim()&&l$1.push(t.createElement("meta",{key:m(),name:"description",content:o$1.trim()})),i$1?.trim()&&l$1.push(t.createElement("link",{key:m(),rel:"canonical",href:i$1.trim()}));let k=l(c);k&&l$1.push(t.createElement("meta",{key:m(),name:"robots",content:k}));let H=o(s);for(let r of H)l$1.push(t.createElement("meta",{key:m(),property:r.property,content:r.content}));let B=p$1(f);for(let r of B)l$1.push(t.createElement("meta",{key:m(),name:r.name,content:r.content}));let I=q(g);for(let r of I)l$1.push(t.createElement("link",{key:m(),rel:r.rel,hrefLang:r.hreflang,href:r.href}));if(h)for(let r of h){let E={content:r.content};r.name&&(E.name=r.name),r.property&&(E.property=r.property),l$1.push(t.createElement("meta",{key:m(),...E}));}if(u)for(let r of u)l$1.push(t.createElement("link",{key:m(),...r}));if(d){let r=Array.isArray(d)?d:[d];for(let E of r)l$1.push(t.createElement("script",{key:m(),type:"application/ld+json",nonce:y,dangerouslySetInnerHTML:{__html:a(E)}}));}return t.createElement(t.Fragment,null,...l$1)}function $({data:e,nonce:n}){return t.createElement("script",{type:"application/ld+json",nonce:n,dangerouslySetInnerHTML:{__html:a(e)}})}function b(e){if(!e)return "example.com";try{return new URL(e).hostname.replace(/^www\./,"")}catch{return e.replace(/^https?:\/\/(www\.)?/,"").split("/")[0]}}function p(e,n){return e?e.length>n?`${e.slice(0,n-1)}\u2026`:e:""}var v={fontFamily:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",boxSizing:"border-box",userSelect:"none"};function R({src:e,height:n,bg:o="#e4e6ea"}){let i={width:"100%",height:n,background:o,display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",flexShrink:0};return e?t.createElement("div",{style:i},t.createElement("img",{src:e,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}})):t.createElement("div",{style:i},t.createElement("span",{style:{color:"#bcc0c9",fontSize:13}},"No image"))}function W({config:e,style:n}){let o=p(e.openGraph?.title??e.title,70),i=p(e.openGraph?.description??e.description,125),c=e.openGraph?.images?.[0]?.url??e.twitter?.image,s=b(e.canonical??e.openGraph?.url),f=e.twitter?.card!=="summary",g={...v,border:"1px solid #cfd9de",borderRadius:16,overflow:"hidden",maxWidth:550,background:"#fff",...n},h={padding:"12px 14px"},u={fontSize:13,color:"#536471",marginBottom:4},d={fontSize:15,fontWeight:700,color:"#0f1419",lineHeight:1.3,marginBottom:4},y={fontSize:15,color:"#536471",lineHeight:1.4};return f?t.createElement("div",{style:g},t.createElement(R,{src:c,height:275,bg:"#e7e9ea"}),t.createElement("div",{style:h},t.createElement("div",{style:u},s),t.createElement("div",{style:d},o),t.createElement("div",{style:y},i))):t.createElement("div",{style:{...g,display:"flex",alignItems:"center"}},t.createElement(R,{src:c,height:110,bg:"#e7e9ea"}),t.createElement("div",{style:{...h,flex:1}},t.createElement("div",{style:u},s),t.createElement("div",{style:d},o),t.createElement("div",{style:y},i)))}function T({config:e,style:n}){let o=p(e.openGraph?.title??e.title,88),i=p(e.openGraph?.description??e.description,110),c=e.openGraph?.images?.[0]?.url,s=b(e.canonical??e.openGraph?.url),f={...v,border:"1px solid #dddfe2",maxWidth:527,background:"#fff",...n};return t.createElement("div",{style:f},t.createElement(R,{src:c,height:275}),t.createElement("div",{style:{background:"#f0f2f5",padding:"10px 12px"}},t.createElement("div",{style:{color:"#606770",fontSize:11,textTransform:"uppercase",marginBottom:4,letterSpacing:"0.5px"}},s),t.createElement("div",{style:{fontWeight:600,fontSize:14,color:"#1c2b33",lineHeight:1.3,marginBottom:2}},o),t.createElement("div",{style:{color:"#606770",fontSize:14,lineHeight:1.4}},i)))}function F({config:e,style:n}){let o=p(e.openGraph?.title??e.title,120),i=e.openGraph?.images?.[0]?.url,c=b(e.canonical??e.openGraph?.url),s={...v,border:"1px solid #e0e0e0",borderRadius:2,maxWidth:552,background:"#fff",...n};return t.createElement("div",{style:s},t.createElement(R,{src:i,height:288,bg:"#dce6f1"}),t.createElement("div",{style:{padding:"8px 12px 12px"}},t.createElement("div",{style:{fontSize:14,fontWeight:600,color:"rgba(0,0,0,0.9)",lineHeight:1.4,marginBottom:4}},o),t.createElement("div",{style:{fontSize:12,color:"rgba(0,0,0,0.6)"}},c)))}function A({config:e,style:n}){let o=p(e.openGraph?.title??e.title,60),i=p(e.openGraph?.description??e.description,160),c=e.openGraph?.siteName??b(e.canonical),s=e.canonical??e.openGraph?.url??"https://example.com";return t.createElement("div",{style:{...v,fontFamily:"arial,sans-serif",maxWidth:600,padding:4,...n}},t.createElement("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:4}},t.createElement("div",{style:{width:26,height:26,borderRadius:"50%",background:"#e8eaed",display:"flex",alignItems:"center",justifyContent:"center",fontSize:11,color:"#444",fontWeight:600}},c[0].toUpperCase()),t.createElement("div",null,t.createElement("div",{style:{fontSize:14,color:"#202124",lineHeight:1.3}},c),t.createElement("div",{style:{fontSize:12,color:"#4d5156",lineHeight:1.3}},p(s,60)))),t.createElement("div",{style:{fontSize:20,color:"#1a0dab",lineHeight:1.3,marginBottom:4,cursor:"pointer"}},o),t.createElement("div",{style:{fontSize:14,color:"#4d5156",lineHeight:1.5}},i))}function Q({config:e,platform:n="twitter",style:o}){switch(n){case "facebook":return t.createElement(T,{config:e,style:o});case "linkedin":return t.createElement(F,{config:e,style:o});case "google":return t.createElement(A,{config:e,style:o});default:return t.createElement(W,{config:e,style:o})}}
|
|
2
|
+
export{_ as a,$ as b,Q as c};//# sourceMappingURL=chunk-GNLXGAS6.js.map
|
|
3
|
+
//# sourceMappingURL=chunk-GNLXGAS6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/SEOHead.tsx","../src/components/JsonLd.tsx","../src/components/SEOPreview.tsx"],"names":["SEOHead","title","titleTemplate","description","canonical","robots","openGraph","twitter","alternates","additionalMetaTags","additionalLinkTags","jsonLd","nonce","elements","key","k","resolvedTitle","buildTitle","React","robotsContent","buildRobotsDirectives","ogTags","buildOpenGraph","tag","twitterTags","buildTwitterMetadata","altLinks","buildAlternateLinks","link","meta","props","schemas","schema","safeJsonLdSerialize","JsonLd","data","extractDomain","url","truncate","str","max","BASE","ImagePlaceholder","src","height","bg","style","TwitterCard","config","image","domain","isLarge","card","domainStyle","titleStyle","descStyle","FacebookCard","LinkedInCard","GoogleCard","siteName","SEOPreview","platform"],"mappings":"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","file":"chunk-GNLXGAS6.js","sourcesContent":["import React from \"react\";\nimport type { SEOConfig } from \"../types/index.js\";\nimport {\n buildTitle,\n buildRobotsDirectives,\n buildOpenGraph,\n buildTwitterMetadata,\n buildAlternateLinks,\n} from \"../core/index.js\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface SEOHeadProps extends SEOConfig {\n /**\n * Optional nonce for CSP-compatible script tags.\n */\n nonce?: string;\n}\n\n/**\n * Generic SSR-safe React component that renders SEO-related tags.\n *\n * Renders: title, meta description, canonical link, robots meta,\n * Open Graph tags, Twitter tags, alternate/hreflang links,\n * additional meta/link tags, and JSON-LD scripts.\n *\n * Designed to be placed inside a <head> element in SSR apps.\n * Does NOT use any browser globals — fully SSR-compatible.\n */\nexport function SEOHead({\n title,\n titleTemplate,\n description,\n canonical,\n robots,\n openGraph,\n twitter,\n alternates,\n additionalMetaTags,\n additionalLinkTags,\n jsonLd,\n nonce,\n}: SEOHeadProps): React.ReactElement {\n const elements: React.ReactElement[] = [];\n let key = 0;\n const k = () => `seo-${key++}`;\n\n // Title\n const resolvedTitle = buildTitle(title, titleTemplate);\n if (resolvedTitle) {\n elements.push(React.createElement(\"title\", { key: k() }, resolvedTitle));\n }\n\n // Description\n if (description?.trim()) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"description\",\n content: description.trim(),\n })\n );\n }\n\n // Canonical\n if (canonical?.trim()) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: \"canonical\",\n href: canonical.trim(),\n })\n );\n }\n\n // Robots\n const robotsContent = buildRobotsDirectives(robots);\n if (robotsContent) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: \"robots\",\n content: robotsContent,\n })\n );\n }\n\n // Open Graph\n const ogTags = buildOpenGraph(openGraph);\n for (const tag of ogTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n property: tag.property,\n content: tag.content,\n })\n );\n }\n\n // Twitter\n const twitterTags = buildTwitterMetadata(twitter);\n for (const tag of twitterTags) {\n elements.push(\n React.createElement(\"meta\", {\n key: k(),\n name: tag.name,\n content: tag.content,\n })\n );\n }\n\n // Hreflang alternates\n const altLinks = buildAlternateLinks(alternates);\n for (const link of altLinks) {\n elements.push(\n React.createElement(\"link\", {\n key: k(),\n rel: link.rel,\n hrefLang: link.hreflang,\n href: link.href,\n })\n );\n }\n\n // Additional meta tags\n if (additionalMetaTags) {\n for (const meta of additionalMetaTags) {\n const props: Record<string, string> = { content: meta.content };\n if (meta.name) props.name = meta.name;\n if (meta.property) props.property = meta.property;\n elements.push(React.createElement(\"meta\", { key: k(), ...props }));\n }\n }\n\n // Additional link tags\n if (additionalLinkTags) {\n for (const link of additionalLinkTags) {\n elements.push(React.createElement(\"link\", { key: k(), ...link }));\n }\n }\n\n // JSON-LD\n if (jsonLd) {\n const schemas = Array.isArray(jsonLd) ? jsonLd : [jsonLd];\n for (const schema of schemas) {\n elements.push(\n React.createElement(\"script\", {\n key: k(),\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(schema),\n },\n })\n );\n }\n }\n\n return React.createElement(React.Fragment, null, ...elements);\n}\n","import React from \"react\";\nimport { safeJsonLdSerialize } from \"../utils/index.js\";\n\nexport interface JsonLdProps {\n data: Record<string, unknown> | Array<Record<string, unknown>>;\n nonce?: string;\n}\n\n/**\n * Renders a <script type=\"application/ld+json\"> tag with safely serialized JSON-LD.\n * SSR-safe: no browser globals used.\n */\nexport function JsonLd({ data, nonce }: JsonLdProps): React.ReactElement {\n return React.createElement(\"script\", {\n type: \"application/ld+json\",\n nonce,\n dangerouslySetInnerHTML: {\n __html: safeJsonLdSerialize(data),\n },\n });\n}\n","import React from \"react\";\nimport type { SEOConfig } from \"../types/index.js\";\n\nexport interface SEOPreviewProps {\n config: SEOConfig;\n platform?: \"twitter\" | \"facebook\" | \"linkedin\" | \"google\";\n className?: string;\n style?: React.CSSProperties;\n}\n\nfunction extractDomain(url?: string): string {\n if (!url) return \"example.com\";\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n return url.replace(/^https?:\\/\\/(www\\.)?/, \"\").split(\"/\")[0];\n }\n}\n\nfunction truncate(str: string | undefined, max: number): string {\n if (!str) return \"\";\n return str.length > max ? `${str.slice(0, max - 1)}…` : str;\n}\n\nconst BASE: React.CSSProperties = {\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n boxSizing: \"border-box\",\n userSelect: \"none\",\n};\n\nfunction ImagePlaceholder({\n src,\n height,\n bg = \"#e4e6ea\",\n}: {\n src?: string;\n height: number;\n bg?: string;\n}): React.ReactElement {\n const style: React.CSSProperties = {\n width: \"100%\",\n height,\n background: bg,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n flexShrink: 0,\n };\n if (src) {\n return React.createElement(\n \"div\",\n { style },\n React.createElement(\"img\", {\n src,\n alt: \"\",\n style: { width: \"100%\", height: \"100%\", objectFit: \"cover\" },\n })\n );\n }\n return React.createElement(\n \"div\",\n { style },\n React.createElement(\n \"span\",\n { style: { color: \"#bcc0c9\", fontSize: 13 } },\n \"No image\"\n )\n );\n}\n\nfunction TwitterCard({\n config,\n style,\n}: {\n config: SEOConfig;\n style?: React.CSSProperties;\n}): React.ReactElement {\n const title = truncate(config.openGraph?.title ?? config.title, 70);\n const description = truncate(\n config.openGraph?.description ?? config.description,\n 125\n );\n const image = config.openGraph?.images?.[0]?.url ?? config.twitter?.image;\n const domain = extractDomain(config.canonical ?? config.openGraph?.url);\n const isLarge = config.twitter?.card !== \"summary\";\n\n const card: React.CSSProperties = {\n ...BASE,\n border: \"1px solid #cfd9de\",\n borderRadius: 16,\n overflow: \"hidden\",\n maxWidth: 550,\n background: \"#fff\",\n ...style,\n };\n\n const meta: React.CSSProperties = {\n padding: \"12px 14px\",\n };\n\n const domainStyle: React.CSSProperties = {\n fontSize: 13,\n color: \"#536471\",\n marginBottom: 4,\n };\n\n const titleStyle: React.CSSProperties = {\n fontSize: 15,\n fontWeight: 700,\n color: \"#0f1419\",\n lineHeight: 1.3,\n marginBottom: 4,\n };\n\n const descStyle: React.CSSProperties = {\n fontSize: 15,\n color: \"#536471\",\n lineHeight: 1.4,\n };\n\n if (!isLarge) {\n return React.createElement(\n \"div\",\n { style: { ...card, display: \"flex\", alignItems: \"center\" } },\n React.createElement(ImagePlaceholder, {\n src: image,\n height: 110,\n bg: \"#e7e9ea\",\n }),\n React.createElement(\n \"div\",\n { style: { ...meta, flex: 1 } },\n React.createElement(\"div\", { style: domainStyle }, domain),\n React.createElement(\"div\", { style: titleStyle }, title),\n React.createElement(\"div\", { style: descStyle }, description)\n )\n );\n }\n\n return React.createElement(\n \"div\",\n { style: card },\n React.createElement(ImagePlaceholder, { src: image, height: 275, bg: \"#e7e9ea\" }),\n React.createElement(\n \"div\",\n { style: meta },\n React.createElement(\"div\", { style: domainStyle }, domain),\n React.createElement(\"div\", { style: titleStyle }, title),\n React.createElement(\"div\", { style: descStyle }, description)\n )\n );\n}\n\nfunction FacebookCard({\n config,\n style,\n}: {\n config: SEOConfig;\n style?: React.CSSProperties;\n}): React.ReactElement {\n const title = truncate(config.openGraph?.title ?? config.title, 88);\n const description = truncate(\n config.openGraph?.description ?? config.description,\n 110\n );\n const image = config.openGraph?.images?.[0]?.url;\n const domain = extractDomain(config.canonical ?? config.openGraph?.url);\n\n const card: React.CSSProperties = {\n ...BASE,\n border: \"1px solid #dddfe2\",\n maxWidth: 527,\n background: \"#fff\",\n ...style,\n };\n\n return React.createElement(\n \"div\",\n { style: card },\n React.createElement(ImagePlaceholder, { src: image, height: 275 }),\n React.createElement(\n \"div\",\n { style: { background: \"#f0f2f5\", padding: \"10px 12px\" } },\n React.createElement(\n \"div\",\n {\n style: {\n color: \"#606770\",\n fontSize: 11,\n textTransform: \"uppercase\" as const,\n marginBottom: 4,\n letterSpacing: \"0.5px\",\n },\n },\n domain\n ),\n React.createElement(\n \"div\",\n {\n style: {\n fontWeight: 600,\n fontSize: 14,\n color: \"#1c2b33\",\n lineHeight: 1.3,\n marginBottom: 2,\n },\n },\n title\n ),\n React.createElement(\n \"div\",\n { style: { color: \"#606770\", fontSize: 14, lineHeight: 1.4 } },\n description\n )\n )\n );\n}\n\nfunction LinkedInCard({\n config,\n style,\n}: {\n config: SEOConfig;\n style?: React.CSSProperties;\n}): React.ReactElement {\n const title = truncate(config.openGraph?.title ?? config.title, 120);\n const image = config.openGraph?.images?.[0]?.url;\n const domain = extractDomain(config.canonical ?? config.openGraph?.url);\n\n const card: React.CSSProperties = {\n ...BASE,\n border: \"1px solid #e0e0e0\",\n borderRadius: 2,\n maxWidth: 552,\n background: \"#fff\",\n ...style,\n };\n\n return React.createElement(\n \"div\",\n { style: card },\n React.createElement(ImagePlaceholder, { src: image, height: 288, bg: \"#dce6f1\" }),\n React.createElement(\n \"div\",\n { style: { padding: \"8px 12px 12px\" } },\n React.createElement(\n \"div\",\n {\n style: {\n fontSize: 14,\n fontWeight: 600,\n color: \"rgba(0,0,0,0.9)\",\n lineHeight: 1.4,\n marginBottom: 4,\n },\n },\n title\n ),\n React.createElement(\n \"div\",\n { style: { fontSize: 12, color: \"rgba(0,0,0,0.6)\" } },\n domain\n )\n )\n );\n}\n\nfunction GoogleCard({\n config,\n style,\n}: {\n config: SEOConfig;\n style?: React.CSSProperties;\n}): React.ReactElement {\n const title = truncate(config.openGraph?.title ?? config.title, 60);\n const description = truncate(\n config.openGraph?.description ?? config.description,\n 160\n );\n const siteName = config.openGraph?.siteName ?? extractDomain(config.canonical);\n const canonical = config.canonical ?? config.openGraph?.url ?? \"https://example.com\";\n\n return React.createElement(\n \"div\",\n {\n style: {\n ...BASE,\n fontFamily: \"arial,sans-serif\",\n maxWidth: 600,\n padding: 4,\n ...style,\n },\n },\n React.createElement(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", gap: 8, marginBottom: 4 } },\n React.createElement(\n \"div\",\n {\n style: {\n width: 26,\n height: 26,\n borderRadius: \"50%\",\n background: \"#e8eaed\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: 11,\n color: \"#444\",\n fontWeight: 600,\n },\n },\n siteName[0].toUpperCase()\n ),\n React.createElement(\n \"div\",\n null,\n React.createElement(\n \"div\",\n { style: { fontSize: 14, color: \"#202124\", lineHeight: 1.3 } },\n siteName\n ),\n React.createElement(\n \"div\",\n { style: { fontSize: 12, color: \"#4d5156\", lineHeight: 1.3 } },\n truncate(canonical, 60)\n )\n )\n ),\n React.createElement(\n \"div\",\n {\n style: {\n fontSize: 20,\n color: \"#1a0dab\",\n lineHeight: 1.3,\n marginBottom: 4,\n cursor: \"pointer\",\n },\n },\n title\n ),\n React.createElement(\n \"div\",\n { style: { fontSize: 14, color: \"#4d5156\", lineHeight: 1.5 } },\n description\n )\n );\n}\n\nexport function SEOPreview({\n config,\n platform = \"twitter\",\n style,\n}: SEOPreviewProps): React.ReactElement {\n switch (platform) {\n case \"facebook\":\n return React.createElement(FacebookCard, { config, style });\n case \"linkedin\":\n return React.createElement(LinkedInCard, { config, style });\n case \"google\":\n return React.createElement(GoogleCard, { config, style });\n default:\n return React.createElement(TwitterCard, { config, style });\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use strict';function c(e){let i=[];for(let n of e){let s=n.name??n.path,t=n.seo??{};t.title?t.title.length>60&&i.push({page:s,field:"title",message:`Title is ${t.title.length} chars (recommended \u226460)`,severity:"warning"}):i.push({page:s,field:"title",message:"Missing page title",severity:"error"}),t.description?t.description.length>160&&i.push({page:s,field:"description",message:`Description is ${t.description.length} chars (recommended \u2264160)`,severity:"warning"}):i.push({page:s,field:"description",message:"Missing meta description",severity:"error"}),t.canonical||i.push({page:s,field:"canonical",message:"Missing canonical URL",severity:"warning"}),t.openGraph?.images?.length||i.push({page:s,field:"og:image",message:"Missing og:image",severity:"warning"}),!t.openGraph?.title&&!t.title&&i.push({page:s,field:"og:title",message:"Missing og:title",severity:"warning"}),t.twitter?.card||i.push({page:s,field:"twitter:card",message:"Missing twitter:card",severity:"warning"}),t.jsonLd||i.push({page:s,field:"structured-data",message:"No structured data (JSON-LD)",severity:"warning"});}return i}function p(e){if(!e.length)return "\u2705 All pages passed SEO validation.";let i=new Map;for(let s of e){let t=i.get(s.page)??[];t.push(s),i.set(s.page,t);}let n=[];for(let[s,t]of i){n.push(`
|
|
2
|
+
${s}:`);for(let a of t){let o=a.severity==="error"?"\u274C":"\u26A0\uFE0F ";n.push(` ${o} [${a.field}] ${a.message}`);}}return n.join(`
|
|
3
|
+
`).trim()}var r=[{name:"Title",field:"title",maxPoints:20,check:e=>e.title?e.title.length>60?{passed:true,points:10,message:`Too long (${e.title.length}/60 chars)`}:{passed:true,points:20}:{passed:false,points:0,message:"Missing title"}},{name:"Description",field:"description",maxPoints:15,check:e=>e.description?e.description.length>160?{passed:true,points:8,message:`Too long (${e.description.length}/160 chars)`}:{passed:true,points:15}:{passed:false,points:0,message:"Missing description"}},{name:"Canonical URL",field:"canonical",maxPoints:10,check:e=>e.canonical?{passed:true,points:10}:{passed:false,points:0,message:"Missing canonical URL"}},{name:"og:image",field:"og:image",maxPoints:15,check:e=>e.openGraph?.images?.length?{passed:true,points:15}:{passed:false,points:0,message:"Missing og:image"}},{name:"og:title",field:"og:title",maxPoints:5,check:e=>e.openGraph?.title||e.title?{passed:true,points:5}:{passed:false,points:0,message:"Missing og:title"}},{name:"og:description",field:"og:description",maxPoints:5,check:e=>e.openGraph?.description||e.description?{passed:true,points:5}:{passed:false,points:0,message:"Missing og:description"}},{name:"Twitter Card",field:"twitter:card",maxPoints:10,check:e=>e.twitter?.card?{passed:true,points:10}:{passed:false,points:0,message:"Missing twitter:card"}},{name:"Structured Data",field:"structured-data",maxPoints:10,check:e=>e.jsonLd?{passed:true,points:10}:{passed:false,points:0,message:"No JSON-LD structured data"}},{name:"Robots Directives",field:"robots",maxPoints:5,check:e=>e.robots!==void 0?{passed:true,points:5}:{passed:false,points:0,message:"No robots directives"}},{name:"Hreflang",field:"hreflang",maxPoints:5,check:e=>e.alternates?.length?{passed:true,points:5}:{passed:false,points:0,message:"No hreflang alternates"}}];function g(e,i="Page"){let n=0,s=r.reduce((a,o)=>a+o.maxPoints,0),t=[];for(let a of r){let o=a.check(e);n+=o.points,t.push({name:a.name,passed:o.passed,points:o.points,maxPoints:a.maxPoints,message:o.message});}return {page:i,score:n,maxScore:s,percentage:Math.round(n/s*100),checks:t}}function d(e){let n=[`${e.percentage>=80?"\u{1F7E2}":e.percentage>=50?"\u{1F7E1}":"\u{1F534}"} SEO Score: ${e.page} ${e.score}/${e.maxScore} (${e.percentage}%)`];for(let s of e.checks){let t=s.passed?"\u2705":"\u274C",a=s.message?` \u2014 ${s.message}`:"",o=s.passed?"":` (-${s.maxPoints})`;n.push(` ${t} ${s.name}${o}${a}`);}return n.join(`
|
|
4
|
+
`)}exports.a=c;exports.b=p;exports.c=g;exports.d=d;//# sourceMappingURL=chunk-LEOORZQY.cjs.map
|
|
5
|
+
//# sourceMappingURL=chunk-LEOORZQY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/validation/index.ts"],"names":["validateSEO","routes","issues","route","page","seo","printValidationReport","byPage","issue","list","lines","pageIssues","icon","SCORE_CHECKS","c","getSEOScore","config","pageName","score","maxScore","sum","checks","def","result","formatSEOScore","check","detail","pts"],"mappings":"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","file":"chunk-LEOORZQY.cjs","sourcesContent":["import type {\n SEOConfig,\n SEOValidationIssue,\n RouteWithSEO,\n SEOScoreResult,\n SEOScoreCheck,\n} from \"../types/index.js\";\n\n// ─── Validate SEO ─────────────────────────────────────────────\n\nexport function validateSEO(routes: RouteWithSEO[]): SEOValidationIssue[] {\n const issues: SEOValidationIssue[] = [];\n\n for (const route of routes) {\n const page = route.name ?? route.path;\n const seo = route.seo ?? {};\n\n if (!seo.title) {\n issues.push({ page, field: \"title\", message: \"Missing page title\", severity: \"error\" });\n } else if (seo.title.length > 60) {\n issues.push({\n page,\n field: \"title\",\n message: `Title is ${seo.title.length} chars (recommended ≤60)`,\n severity: \"warning\",\n });\n }\n\n if (!seo.description) {\n issues.push({ page, field: \"description\", message: \"Missing meta description\", severity: \"error\" });\n } else if (seo.description.length > 160) {\n issues.push({\n page,\n field: \"description\",\n message: `Description is ${seo.description.length} chars (recommended ≤160)`,\n severity: \"warning\",\n });\n }\n\n if (!seo.canonical) {\n issues.push({ page, field: \"canonical\", message: \"Missing canonical URL\", severity: \"warning\" });\n }\n\n if (!seo.openGraph?.images?.length) {\n issues.push({ page, field: \"og:image\", message: \"Missing og:image\", severity: \"warning\" });\n }\n\n if (!seo.openGraph?.title && !seo.title) {\n issues.push({ page, field: \"og:title\", message: \"Missing og:title\", severity: \"warning\" });\n }\n\n if (!seo.twitter?.card) {\n issues.push({ page, field: \"twitter:card\", message: \"Missing twitter:card\", severity: \"warning\" });\n }\n\n if (!seo.jsonLd) {\n issues.push({\n page,\n field: \"structured-data\",\n message: \"No structured data (JSON-LD)\",\n severity: \"warning\",\n });\n }\n }\n\n return issues;\n}\n\nexport function printValidationReport(issues: SEOValidationIssue[]): string {\n if (!issues.length) return \"✅ All pages passed SEO validation.\";\n\n const byPage = new Map<string, SEOValidationIssue[]>();\n for (const issue of issues) {\n const list = byPage.get(issue.page) ?? [];\n list.push(issue);\n byPage.set(issue.page, list);\n }\n\n const lines: string[] = [];\n for (const [page, pageIssues] of byPage) {\n lines.push(`\\n${page}:`);\n for (const issue of pageIssues) {\n const icon = issue.severity === \"error\" ? \"❌\" : \"⚠️ \";\n lines.push(` ${icon} [${issue.field}] ${issue.message}`);\n }\n }\n return lines.join(\"\\n\").trim();\n}\n\n// ─── SEO Score ────────────────────────────────────────────────\n\nconst SCORE_CHECKS: Array<{\n name: string;\n field: string;\n maxPoints: number;\n check: (config: SEOConfig) => { passed: boolean; points: number; message?: string };\n}> = [\n {\n name: \"Title\",\n field: \"title\",\n maxPoints: 20,\n check: (c) => {\n if (!c.title) return { passed: false, points: 0, message: \"Missing title\" };\n if (c.title.length > 60)\n return { passed: true, points: 10, message: `Too long (${c.title.length}/60 chars)` };\n return { passed: true, points: 20 };\n },\n },\n {\n name: \"Description\",\n field: \"description\",\n maxPoints: 15,\n check: (c) => {\n if (!c.description) return { passed: false, points: 0, message: \"Missing description\" };\n if (c.description.length > 160)\n return { passed: true, points: 8, message: `Too long (${c.description.length}/160 chars)` };\n return { passed: true, points: 15 };\n },\n },\n {\n name: \"Canonical URL\",\n field: \"canonical\",\n maxPoints: 10,\n check: (c) =>\n c.canonical\n ? { passed: true, points: 10 }\n : { passed: false, points: 0, message: \"Missing canonical URL\" },\n },\n {\n name: \"og:image\",\n field: \"og:image\",\n maxPoints: 15,\n check: (c) =>\n c.openGraph?.images?.length\n ? { passed: true, points: 15 }\n : { passed: false, points: 0, message: \"Missing og:image\" },\n },\n {\n name: \"og:title\",\n field: \"og:title\",\n maxPoints: 5,\n check: (c) =>\n c.openGraph?.title || c.title\n ? { passed: true, points: 5 }\n : { passed: false, points: 0, message: \"Missing og:title\" },\n },\n {\n name: \"og:description\",\n field: \"og:description\",\n maxPoints: 5,\n check: (c) =>\n c.openGraph?.description || c.description\n ? { passed: true, points: 5 }\n : { passed: false, points: 0, message: \"Missing og:description\" },\n },\n {\n name: \"Twitter Card\",\n field: \"twitter:card\",\n maxPoints: 10,\n check: (c) =>\n c.twitter?.card\n ? { passed: true, points: 10 }\n : { passed: false, points: 0, message: \"Missing twitter:card\" },\n },\n {\n name: \"Structured Data\",\n field: \"structured-data\",\n maxPoints: 10,\n check: (c) =>\n c.jsonLd\n ? { passed: true, points: 10 }\n : { passed: false, points: 0, message: \"No JSON-LD structured data\" },\n },\n {\n name: \"Robots Directives\",\n field: \"robots\",\n maxPoints: 5,\n check: (c) =>\n c.robots !== undefined\n ? { passed: true, points: 5 }\n : { passed: false, points: 0, message: \"No robots directives\" },\n },\n {\n name: \"Hreflang\",\n field: \"hreflang\",\n maxPoints: 5,\n check: (c) =>\n c.alternates?.length\n ? { passed: true, points: 5 }\n : { passed: false, points: 0, message: \"No hreflang alternates\" },\n },\n];\n\nexport function getSEOScore(config: SEOConfig, pageName = \"Page\"): SEOScoreResult {\n let score = 0;\n const maxScore = SCORE_CHECKS.reduce((sum, c) => sum + c.maxPoints, 0);\n const checks: SEOScoreCheck[] = [];\n\n for (const def of SCORE_CHECKS) {\n const result = def.check(config);\n score += result.points;\n checks.push({\n name: def.name,\n passed: result.passed,\n points: result.points,\n maxPoints: def.maxPoints,\n message: result.message,\n });\n }\n\n return {\n page: pageName,\n score,\n maxScore,\n percentage: Math.round((score / maxScore) * 100),\n checks,\n };\n}\n\nexport function formatSEOScore(result: SEOScoreResult): string {\n const bar = result.percentage >= 80 ? \"🟢\" : result.percentage >= 50 ? \"🟡\" : \"🔴\";\n const lines = [\n `${bar} SEO Score: ${result.page} ${result.score}/${result.maxScore} (${result.percentage}%)`,\n ];\n\n for (const check of result.checks) {\n const icon = check.passed ? \"✅\" : \"❌\";\n const detail = check.message ? ` — ${check.message}` : \"\";\n const pts = !check.passed ? ` (-${check.maxPoints})` : \"\";\n lines.push(` ${icon} ${check.name}${pts}${detail}`);\n }\n\n return lines.join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';var a="system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif";function g(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function p(t,s,i){let l=t.split(" "),n=[],e="";for(let f of l){if(n.length>=i)break;let o=e?`${e} ${f}`:f;if(o.length>s&&e){if(n.length===i-1){n.push(`${e.slice(0,s-1)}\u2026`),e="";break}n.push(e),e=f;}else !e&&o.length>s?n.push(`${o.slice(0,s-1)}\u2026`):e=o;}return e&&n.length<i&&n.push(e),n}function u(t,s,i,l,n,e="400",f="start"){if(!t.length)return "";let o=Math.round(l*1.35),$=t.map((r,c)=>`<tspan x="${s}" dy="${c===0?0:o}">${g(r)}</tspan>`).join("");return `<text x="${s}" y="${i}" font-family="${a}" font-size="${l}" font-weight="${e}" fill="${n}" text-anchor="${f}">${$}</text>`}function H(t){let{title:s,description:i,brand:l,textColor:n="#ffffff",accentColor:e="#6366f1"}=t,f=t.backgroundColor??"#0f0c29",o=t.backgroundColor??"#24243e",$=p(s,24,2),r=i?p(i,55,2):[],c=68,m=34,h=Math.round(c*1.35),y=Math.round(m*1.4),d=28,x=$.length*h+(r.length?d+r.length*y:0),w=Math.round((630-x)/2)+c,b=w+$.length*h+d;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
5
|
+
<stop offset="0%" stop-color="${f}"/>
|
|
6
|
+
<stop offset="100%" stop-color="${o}"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
10
|
+
<rect x="0" y="0" width="8" height="630" fill="${e}"/>
|
|
11
|
+
<rect x="80" y="${w-c-24}" width="56" height="5" fill="${e}" rx="2.5"/>
|
|
12
|
+
${u($,80,w,c,n,"700")}
|
|
13
|
+
${r.length?u(r,80,b,m,"rgba(255,255,255,0.72)"):""}
|
|
14
|
+
${l?`<text x="1140" y="590" font-family="${a}" font-size="26" fill="rgba(255,255,255,0.38)" text-anchor="end">${g(l)}</text>`:""}
|
|
15
|
+
</svg>`.trim()}function v(t){let{title:s,description:i,brand:l,category:n,author:e,dateString:f,accentColor:o="#e63946"}=t,$=t.backgroundColor??"#f8f9fa",r=t.textColor??"#1a1a2e",c=p(s,38,3),m=i?p(i,68,2):[],h=52,y=28,d=Math.round(h*1.3),x=n?200:170,w=x+c.length*d+24;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
17
|
+
<rect width="1200" height="630" fill="${$}"/>
|
|
18
|
+
<rect x="0" y="0" width="1200" height="8" fill="${o}"/>
|
|
19
|
+
${n?`<rect x="60" y="120" width="${n.length*13+32}" height="36" fill="${o}" rx="18"/>
|
|
20
|
+
<text x="76" y="144" font-family="${a}" font-size="18" font-weight="600" fill="#ffffff">${g(n.toUpperCase())}</text>`:""}
|
|
21
|
+
${u(c,60,x,h,r,"700")}
|
|
22
|
+
${m.length?u(m,60,w,y,`${r}b3`):""}
|
|
23
|
+
<rect x="60" y="550" width="1080" height="1" fill="rgba(0,0,0,0.1)"/>
|
|
24
|
+
${e?`<text x="60" y="586" font-family="${a}" font-size="22" fill="${r}99">${g(e)}</text>`:""}
|
|
25
|
+
${f?`<text x="1140" y="586" font-family="${a}" font-size="22" fill="${r}66" text-anchor="end">${g(f)}</text>`:""}
|
|
26
|
+
${l?`<text x="${1200/2}" y="586" font-family="${a}" font-size="22" font-weight="600" fill="${o}" text-anchor="middle">${g(l)}</text>`:""}
|
|
27
|
+
</svg>`.trim()}function W(t){let{title:s,brand:i,homeTeam:l,awayTeam:n,eventDate:e,accentColor:f="#ffd700"}=t,o=t.backgroundColor??"#0a0a1a",$=t.backgroundColor??"#1a1a3e",r=t.textColor??"#ffffff";if(l&&n){let h=p(l.toUpperCase(),12,2),y=p(n.toUpperCase(),12,2),d=64,x=h.length>1?300:330;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
28
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
29
|
+
<defs>
|
|
30
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
31
|
+
<stop offset="0%" stop-color="${o}"/>
|
|
32
|
+
<stop offset="100%" stop-color="${$}"/>
|
|
33
|
+
</linearGradient>
|
|
34
|
+
<linearGradient id="div" x1="0" y1="0" x2="0" y2="1">
|
|
35
|
+
<stop offset="0%" stop-color="rgba(255,215,0,0)"/>
|
|
36
|
+
<stop offset="50%" stop-color="rgba(255,215,0,0.25)"/>
|
|
37
|
+
<stop offset="100%" stop-color="rgba(255,215,0,0)"/>
|
|
38
|
+
</linearGradient>
|
|
39
|
+
</defs>
|
|
40
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
41
|
+
<rect x="591" y="60" width="18" height="510" fill="url(#div)" rx="9"/>
|
|
42
|
+
${u(h,300,x,d,r,"800","middle")}
|
|
43
|
+
<text x="600" y="345" font-family="${a}" font-size="56" font-weight="900" fill="${f}" text-anchor="middle">VS</text>
|
|
44
|
+
${u(y,900,x,d,r,"800","middle")}
|
|
45
|
+
${e?`<text x="${1200/2}" y="510" font-family="${a}" font-size="26" fill="rgba(255,255,255,0.55)" text-anchor="middle">${g(e)}</text>`:""}
|
|
46
|
+
${i?`<text x="1140" y="594" font-family="${a}" font-size="24" fill="rgba(255,255,255,0.3)" text-anchor="end">${g(i)}</text>`:""}
|
|
47
|
+
</svg>`.trim()}let c=p(s,28,2);return `<?xml version="1.0" encoding="UTF-8"?>
|
|
48
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
49
|
+
<defs>
|
|
50
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
51
|
+
<stop offset="0%" stop-color="${o}"/>
|
|
52
|
+
<stop offset="100%" stop-color="${$}"/>
|
|
53
|
+
</linearGradient>
|
|
54
|
+
</defs>
|
|
55
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
56
|
+
<rect x="0" y="0" width="8" height="630" fill="${f}"/>
|
|
57
|
+
${u(c,80,300,64,r,"700")}
|
|
58
|
+
${e?`<text x="80" y="410" font-family="${a}" font-size="28" fill="rgba(255,255,255,0.55)">${g(e)}</text>`:""}
|
|
59
|
+
${i?`<text x="1140" y="594" font-family="${a}" font-size="24" fill="rgba(255,255,255,0.3)" text-anchor="end">${g(i)}</text>`:""}
|
|
60
|
+
</svg>`.trim()}function G(t){switch(t.template){case "article":return v(t);case "sports-event":return W(t);default:return H(t)}}exports.a=G;//# sourceMappingURL=chunk-ROA74LH6.cjs.map
|
|
61
|
+
//# sourceMappingURL=chunk-ROA74LH6.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/og/index.ts"],"names":["FONT","esc","str","wrapText","text","maxChars","maxLines","words","lines","line","word","test","multilineText","x","y","fontSize","fill","fontWeight","textAnchor","lh","tspans","l","i","createDefaultSVG","options","title","description","brand","textColor","accentColor","bg1","bg2","titleLines","descLines","titleSize","descSize","titleLH","descLH","gap","totalH","startY","descY","createArticleSVG","category","author","dateString","bg","titleY","createSportsEventSVG","homeTeam","awayTeam","eventDate","homeLines","awayLines","teamSize","teamY","createOGImageSVG"],"mappings":"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","file":"chunk-ROA74LH6.cjs","sourcesContent":["import type { OGImageOptions } from \"../types/index.js\";\n\nconst W = 1200;\nconst H = 630;\nconst FONT = \"system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif\";\n\nfunction esc(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction wrapText(text: string, maxChars: number, maxLines: number): string[] {\n const words = text.split(\" \");\n const lines: string[] = [];\n let line = \"\";\n\n for (const word of words) {\n if (lines.length >= maxLines) break;\n const test = line ? `${line} ${word}` : word;\n if (test.length > maxChars && line) {\n if (lines.length === maxLines - 1) {\n lines.push(`${line.slice(0, maxChars - 1)}…`);\n line = \"\";\n break;\n }\n lines.push(line);\n line = word;\n } else if (!line && test.length > maxChars) {\n lines.push(`${test.slice(0, maxChars - 1)}…`);\n } else {\n line = test;\n }\n }\n if (line && lines.length < maxLines) lines.push(line);\n return lines;\n}\n\nfunction multilineText(\n lines: string[],\n x: number,\n y: number,\n fontSize: number,\n fill: string,\n fontWeight = \"400\",\n textAnchor = \"start\"\n): string {\n if (!lines.length) return \"\";\n const lh = Math.round(fontSize * 1.35);\n const tspans = lines\n .map((l, i) => `<tspan x=\"${x}\" dy=\"${i === 0 ? 0 : lh}\">${esc(l)}</tspan>`)\n .join(\"\");\n return `<text x=\"${x}\" y=\"${y}\" font-family=\"${FONT}\" font-size=\"${fontSize}\" font-weight=\"${fontWeight}\" fill=\"${fill}\" text-anchor=\"${textAnchor}\">${tspans}</text>`;\n}\n\n// ─── Default template ─────────────────────────────────────────\n\nfunction createDefaultSVG(options: OGImageOptions): string {\n const {\n title,\n description,\n brand,\n textColor = \"#ffffff\",\n accentColor = \"#6366f1\",\n } = options;\n\n const bg1 = options.backgroundColor ?? \"#0f0c29\";\n const bg2 = options.backgroundColor ?? \"#24243e\";\n\n const titleLines = wrapText(title, 24, 2);\n const descLines = description ? wrapText(description, 55, 2) : [];\n\n const titleSize = 68;\n const descSize = 34;\n const titleLH = Math.round(titleSize * 1.35);\n const descLH = Math.round(descSize * 1.4);\n const gap = 28;\n\n const totalH =\n titleLines.length * titleLH +\n (descLines.length ? gap + descLines.length * descLH : 0);\n\n const startY = Math.round((H - totalH) / 2) + titleSize;\n const descY = startY + titleLines.length * titleLH + gap;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"${H}\" fill=\"${accentColor}\"/>\n <rect x=\"80\" y=\"${startY - titleSize - 24}\" width=\"56\" height=\"5\" fill=\"${accentColor}\" rx=\"2.5\"/>\n ${multilineText(titleLines, 80, startY, titleSize, textColor, \"700\")}\n ${descLines.length ? multilineText(descLines, 80, descY, descSize, \"rgba(255,255,255,0.72)\") : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 40}\" font-family=\"${FONT}\" font-size=\"26\" fill=\"rgba(255,255,255,0.38)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n}\n\n// ─── Article template ─────────────────────────────────────────\n\nfunction createArticleSVG(options: OGImageOptions): string {\n const {\n title,\n description,\n brand,\n category,\n author,\n dateString,\n accentColor = \"#e63946\",\n } = options;\n\n const bg = options.backgroundColor ?? \"#f8f9fa\";\n const textColor = options.textColor ?? \"#1a1a2e\";\n\n const titleLines = wrapText(title, 38, 3);\n const descLines = description ? wrapText(description, 68, 2) : [];\n\n const titleSize = 52;\n const descSize = 28;\n const titleLH = Math.round(titleSize * 1.3);\n\n const titleY = category ? 200 : 170;\n const descY = titleY + titleLines.length * titleLH + 24;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"${W}\" height=\"${H}\" fill=\"${bg}\"/>\n <rect x=\"0\" y=\"0\" width=\"${W}\" height=\"8\" fill=\"${accentColor}\"/>\n ${\n category\n ? `<rect x=\"60\" y=\"120\" width=\"${category.length * 13 + 32}\" height=\"36\" fill=\"${accentColor}\" rx=\"18\"/>\n <text x=\"${60 + 16}\" y=\"144\" font-family=\"${FONT}\" font-size=\"18\" font-weight=\"600\" fill=\"#ffffff\">${esc(category.toUpperCase())}</text>`\n : \"\"\n }\n ${multilineText(titleLines, 60, titleY, titleSize, textColor, \"700\")}\n ${descLines.length ? multilineText(descLines, 60, descY, descSize, `${textColor}b3`) : \"\"}\n <rect x=\"60\" y=\"${H - 80}\" width=\"${W - 120}\" height=\"1\" fill=\"rgba(0,0,0,0.1)\"/>\n ${\n author\n ? `<text x=\"60\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" fill=\"${textColor}99\">${esc(author)}</text>`\n : \"\"\n }\n ${\n dateString\n ? `<text x=\"${W - 60}\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" fill=\"${textColor}66\" text-anchor=\"end\">${esc(dateString)}</text>`\n : \"\"\n }\n ${\n brand\n ? `<text x=\"${W / 2}\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" font-weight=\"600\" fill=\"${accentColor}\" text-anchor=\"middle\">${esc(brand)}</text>`\n : \"\"\n }\n</svg>`.trim();\n}\n\n// ─── Sports event template ────────────────────────────────────\n\nfunction createSportsEventSVG(options: OGImageOptions): string {\n const {\n title,\n brand,\n homeTeam,\n awayTeam,\n eventDate,\n accentColor = \"#ffd700\",\n } = options;\n\n const bg1 = options.backgroundColor ?? \"#0a0a1a\";\n const bg2 = options.backgroundColor ?? \"#1a1a3e\";\n const textColor = options.textColor ?? \"#ffffff\";\n\n if (homeTeam && awayTeam) {\n const homeLines = wrapText(homeTeam.toUpperCase(), 12, 2);\n const awayLines = wrapText(awayTeam.toUpperCase(), 12, 2);\n const teamSize = 64;\n const teamY = homeLines.length > 1 ? 300 : 330;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n <linearGradient id=\"div\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"rgba(255,215,0,0)\"/>\n <stop offset=\"50%\" stop-color=\"rgba(255,215,0,0.25)\"/>\n <stop offset=\"100%\" stop-color=\"rgba(255,215,0,0)\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"591\" y=\"60\" width=\"18\" height=\"510\" fill=\"url(#div)\" rx=\"9\"/>\n ${multilineText(homeLines, 300, teamY, teamSize, textColor, \"800\", \"middle\")}\n <text x=\"600\" y=\"345\" font-family=\"${FONT}\" font-size=\"56\" font-weight=\"900\" fill=\"${accentColor}\" text-anchor=\"middle\">VS</text>\n ${multilineText(awayLines, 900, teamY, teamSize, textColor, \"800\", \"middle\")}\n ${eventDate ? `<text x=\"${W / 2}\" y=\"510\" font-family=\"${FONT}\" font-size=\"26\" fill=\"rgba(255,255,255,0.55)\" text-anchor=\"middle\">${esc(eventDate)}</text>` : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 36}\" font-family=\"${FONT}\" font-size=\"24\" fill=\"rgba(255,255,255,0.3)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n }\n\n const titleLines = wrapText(title, 28, 2);\n const titleSize = 64;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"${H}\" fill=\"${accentColor}\"/>\n ${multilineText(titleLines, 80, 300, titleSize, textColor, \"700\")}\n ${eventDate ? `<text x=\"80\" y=\"410\" font-family=\"${FONT}\" font-size=\"28\" fill=\"rgba(255,255,255,0.55)\">${esc(eventDate)}</text>` : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 36}\" font-family=\"${FONT}\" font-size=\"24\" fill=\"rgba(255,255,255,0.3)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n}\n\n// ─── Public API ───────────────────────────────────────────────\n\nexport function createOGImageSVG(options: OGImageOptions): string {\n switch (options.template) {\n case \"article\":\n return createArticleSVG(options);\n case \"sports-event\":\n return createSportsEventSVG(options);\n default:\n return createDefaultSVG(options);\n }\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
var a="system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif";function g(t){return t.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function p(t,s,i){let l=t.split(" "),n=[],e="";for(let f of l){if(n.length>=i)break;let o=e?`${e} ${f}`:f;if(o.length>s&&e){if(n.length===i-1){n.push(`${e.slice(0,s-1)}\u2026`),e="";break}n.push(e),e=f;}else !e&&o.length>s?n.push(`${o.slice(0,s-1)}\u2026`):e=o;}return e&&n.length<i&&n.push(e),n}function u(t,s,i,l,n,e="400",f="start"){if(!t.length)return "";let o=Math.round(l*1.35),$=t.map((r,c)=>`<tspan x="${s}" dy="${c===0?0:o}">${g(r)}</tspan>`).join("");return `<text x="${s}" y="${i}" font-family="${a}" font-size="${l}" font-weight="${e}" fill="${n}" text-anchor="${f}">${$}</text>`}function H(t){let{title:s,description:i,brand:l,textColor:n="#ffffff",accentColor:e="#6366f1"}=t,f=t.backgroundColor??"#0f0c29",o=t.backgroundColor??"#24243e",$=p(s,24,2),r=i?p(i,55,2):[],c=68,m=34,h=Math.round(c*1.35),y=Math.round(m*1.4),d=28,x=$.length*h+(r.length?d+r.length*y:0),w=Math.round((630-x)/2)+c,b=w+$.length*h+d;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
5
|
+
<stop offset="0%" stop-color="${f}"/>
|
|
6
|
+
<stop offset="100%" stop-color="${o}"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
</defs>
|
|
9
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
10
|
+
<rect x="0" y="0" width="8" height="630" fill="${e}"/>
|
|
11
|
+
<rect x="80" y="${w-c-24}" width="56" height="5" fill="${e}" rx="2.5"/>
|
|
12
|
+
${u($,80,w,c,n,"700")}
|
|
13
|
+
${r.length?u(r,80,b,m,"rgba(255,255,255,0.72)"):""}
|
|
14
|
+
${l?`<text x="1140" y="590" font-family="${a}" font-size="26" fill="rgba(255,255,255,0.38)" text-anchor="end">${g(l)}</text>`:""}
|
|
15
|
+
</svg>`.trim()}function v(t){let{title:s,description:i,brand:l,category:n,author:e,dateString:f,accentColor:o="#e63946"}=t,$=t.backgroundColor??"#f8f9fa",r=t.textColor??"#1a1a2e",c=p(s,38,3),m=i?p(i,68,2):[],h=52,y=28,d=Math.round(h*1.3),x=n?200:170,w=x+c.length*d+24;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
16
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
17
|
+
<rect width="1200" height="630" fill="${$}"/>
|
|
18
|
+
<rect x="0" y="0" width="1200" height="8" fill="${o}"/>
|
|
19
|
+
${n?`<rect x="60" y="120" width="${n.length*13+32}" height="36" fill="${o}" rx="18"/>
|
|
20
|
+
<text x="76" y="144" font-family="${a}" font-size="18" font-weight="600" fill="#ffffff">${g(n.toUpperCase())}</text>`:""}
|
|
21
|
+
${u(c,60,x,h,r,"700")}
|
|
22
|
+
${m.length?u(m,60,w,y,`${r}b3`):""}
|
|
23
|
+
<rect x="60" y="550" width="1080" height="1" fill="rgba(0,0,0,0.1)"/>
|
|
24
|
+
${e?`<text x="60" y="586" font-family="${a}" font-size="22" fill="${r}99">${g(e)}</text>`:""}
|
|
25
|
+
${f?`<text x="1140" y="586" font-family="${a}" font-size="22" fill="${r}66" text-anchor="end">${g(f)}</text>`:""}
|
|
26
|
+
${l?`<text x="${1200/2}" y="586" font-family="${a}" font-size="22" font-weight="600" fill="${o}" text-anchor="middle">${g(l)}</text>`:""}
|
|
27
|
+
</svg>`.trim()}function W(t){let{title:s,brand:i,homeTeam:l,awayTeam:n,eventDate:e,accentColor:f="#ffd700"}=t,o=t.backgroundColor??"#0a0a1a",$=t.backgroundColor??"#1a1a3e",r=t.textColor??"#ffffff";if(l&&n){let h=p(l.toUpperCase(),12,2),y=p(n.toUpperCase(),12,2),d=64,x=h.length>1?300:330;return `<?xml version="1.0" encoding="UTF-8"?>
|
|
28
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
29
|
+
<defs>
|
|
30
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
31
|
+
<stop offset="0%" stop-color="${o}"/>
|
|
32
|
+
<stop offset="100%" stop-color="${$}"/>
|
|
33
|
+
</linearGradient>
|
|
34
|
+
<linearGradient id="div" x1="0" y1="0" x2="0" y2="1">
|
|
35
|
+
<stop offset="0%" stop-color="rgba(255,215,0,0)"/>
|
|
36
|
+
<stop offset="50%" stop-color="rgba(255,215,0,0.25)"/>
|
|
37
|
+
<stop offset="100%" stop-color="rgba(255,215,0,0)"/>
|
|
38
|
+
</linearGradient>
|
|
39
|
+
</defs>
|
|
40
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
41
|
+
<rect x="591" y="60" width="18" height="510" fill="url(#div)" rx="9"/>
|
|
42
|
+
${u(h,300,x,d,r,"800","middle")}
|
|
43
|
+
<text x="600" y="345" font-family="${a}" font-size="56" font-weight="900" fill="${f}" text-anchor="middle">VS</text>
|
|
44
|
+
${u(y,900,x,d,r,"800","middle")}
|
|
45
|
+
${e?`<text x="${1200/2}" y="510" font-family="${a}" font-size="26" fill="rgba(255,255,255,0.55)" text-anchor="middle">${g(e)}</text>`:""}
|
|
46
|
+
${i?`<text x="1140" y="594" font-family="${a}" font-size="24" fill="rgba(255,255,255,0.3)" text-anchor="end">${g(i)}</text>`:""}
|
|
47
|
+
</svg>`.trim()}let c=p(s,28,2);return `<?xml version="1.0" encoding="UTF-8"?>
|
|
48
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
|
|
49
|
+
<defs>
|
|
50
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
51
|
+
<stop offset="0%" stop-color="${o}"/>
|
|
52
|
+
<stop offset="100%" stop-color="${$}"/>
|
|
53
|
+
</linearGradient>
|
|
54
|
+
</defs>
|
|
55
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
56
|
+
<rect x="0" y="0" width="8" height="630" fill="${f}"/>
|
|
57
|
+
${u(c,80,300,64,r,"700")}
|
|
58
|
+
${e?`<text x="80" y="410" font-family="${a}" font-size="28" fill="rgba(255,255,255,0.55)">${g(e)}</text>`:""}
|
|
59
|
+
${i?`<text x="1140" y="594" font-family="${a}" font-size="24" fill="rgba(255,255,255,0.3)" text-anchor="end">${g(i)}</text>`:""}
|
|
60
|
+
</svg>`.trim()}function G(t){switch(t.template){case "article":return v(t);case "sports-event":return W(t);default:return H(t)}}export{G as a};//# sourceMappingURL=chunk-WM5VVPED.js.map
|
|
61
|
+
//# sourceMappingURL=chunk-WM5VVPED.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/og/index.ts"],"names":["FONT","esc","str","wrapText","text","maxChars","maxLines","words","lines","line","word","test","multilineText","x","y","fontSize","fill","fontWeight","textAnchor","lh","tspans","l","i","createDefaultSVG","options","title","description","brand","textColor","accentColor","bg1","bg2","titleLines","descLines","titleSize","descSize","titleLH","descLH","gap","totalH","startY","descY","createArticleSVG","category","author","dateString","bg","titleY","createSportsEventSVG","homeTeam","awayTeam","eventDate","homeLines","awayLines","teamSize","teamY","createOGImageSVG"],"mappings":"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","file":"chunk-WM5VVPED.js","sourcesContent":["import type { OGImageOptions } from \"../types/index.js\";\n\nconst W = 1200;\nconst H = 630;\nconst FONT = \"system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif\";\n\nfunction esc(str: string): string {\n return str\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction wrapText(text: string, maxChars: number, maxLines: number): string[] {\n const words = text.split(\" \");\n const lines: string[] = [];\n let line = \"\";\n\n for (const word of words) {\n if (lines.length >= maxLines) break;\n const test = line ? `${line} ${word}` : word;\n if (test.length > maxChars && line) {\n if (lines.length === maxLines - 1) {\n lines.push(`${line.slice(0, maxChars - 1)}…`);\n line = \"\";\n break;\n }\n lines.push(line);\n line = word;\n } else if (!line && test.length > maxChars) {\n lines.push(`${test.slice(0, maxChars - 1)}…`);\n } else {\n line = test;\n }\n }\n if (line && lines.length < maxLines) lines.push(line);\n return lines;\n}\n\nfunction multilineText(\n lines: string[],\n x: number,\n y: number,\n fontSize: number,\n fill: string,\n fontWeight = \"400\",\n textAnchor = \"start\"\n): string {\n if (!lines.length) return \"\";\n const lh = Math.round(fontSize * 1.35);\n const tspans = lines\n .map((l, i) => `<tspan x=\"${x}\" dy=\"${i === 0 ? 0 : lh}\">${esc(l)}</tspan>`)\n .join(\"\");\n return `<text x=\"${x}\" y=\"${y}\" font-family=\"${FONT}\" font-size=\"${fontSize}\" font-weight=\"${fontWeight}\" fill=\"${fill}\" text-anchor=\"${textAnchor}\">${tspans}</text>`;\n}\n\n// ─── Default template ─────────────────────────────────────────\n\nfunction createDefaultSVG(options: OGImageOptions): string {\n const {\n title,\n description,\n brand,\n textColor = \"#ffffff\",\n accentColor = \"#6366f1\",\n } = options;\n\n const bg1 = options.backgroundColor ?? \"#0f0c29\";\n const bg2 = options.backgroundColor ?? \"#24243e\";\n\n const titleLines = wrapText(title, 24, 2);\n const descLines = description ? wrapText(description, 55, 2) : [];\n\n const titleSize = 68;\n const descSize = 34;\n const titleLH = Math.round(titleSize * 1.35);\n const descLH = Math.round(descSize * 1.4);\n const gap = 28;\n\n const totalH =\n titleLines.length * titleLH +\n (descLines.length ? gap + descLines.length * descLH : 0);\n\n const startY = Math.round((H - totalH) / 2) + titleSize;\n const descY = startY + titleLines.length * titleLH + gap;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"${H}\" fill=\"${accentColor}\"/>\n <rect x=\"80\" y=\"${startY - titleSize - 24}\" width=\"56\" height=\"5\" fill=\"${accentColor}\" rx=\"2.5\"/>\n ${multilineText(titleLines, 80, startY, titleSize, textColor, \"700\")}\n ${descLines.length ? multilineText(descLines, 80, descY, descSize, \"rgba(255,255,255,0.72)\") : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 40}\" font-family=\"${FONT}\" font-size=\"26\" fill=\"rgba(255,255,255,0.38)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n}\n\n// ─── Article template ─────────────────────────────────────────\n\nfunction createArticleSVG(options: OGImageOptions): string {\n const {\n title,\n description,\n brand,\n category,\n author,\n dateString,\n accentColor = \"#e63946\",\n } = options;\n\n const bg = options.backgroundColor ?? \"#f8f9fa\";\n const textColor = options.textColor ?? \"#1a1a2e\";\n\n const titleLines = wrapText(title, 38, 3);\n const descLines = description ? wrapText(description, 68, 2) : [];\n\n const titleSize = 52;\n const descSize = 28;\n const titleLH = Math.round(titleSize * 1.3);\n\n const titleY = category ? 200 : 170;\n const descY = titleY + titleLines.length * titleLH + 24;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"${W}\" height=\"${H}\" fill=\"${bg}\"/>\n <rect x=\"0\" y=\"0\" width=\"${W}\" height=\"8\" fill=\"${accentColor}\"/>\n ${\n category\n ? `<rect x=\"60\" y=\"120\" width=\"${category.length * 13 + 32}\" height=\"36\" fill=\"${accentColor}\" rx=\"18\"/>\n <text x=\"${60 + 16}\" y=\"144\" font-family=\"${FONT}\" font-size=\"18\" font-weight=\"600\" fill=\"#ffffff\">${esc(category.toUpperCase())}</text>`\n : \"\"\n }\n ${multilineText(titleLines, 60, titleY, titleSize, textColor, \"700\")}\n ${descLines.length ? multilineText(descLines, 60, descY, descSize, `${textColor}b3`) : \"\"}\n <rect x=\"60\" y=\"${H - 80}\" width=\"${W - 120}\" height=\"1\" fill=\"rgba(0,0,0,0.1)\"/>\n ${\n author\n ? `<text x=\"60\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" fill=\"${textColor}99\">${esc(author)}</text>`\n : \"\"\n }\n ${\n dateString\n ? `<text x=\"${W - 60}\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" fill=\"${textColor}66\" text-anchor=\"end\">${esc(dateString)}</text>`\n : \"\"\n }\n ${\n brand\n ? `<text x=\"${W / 2}\" y=\"${H - 44}\" font-family=\"${FONT}\" font-size=\"22\" font-weight=\"600\" fill=\"${accentColor}\" text-anchor=\"middle\">${esc(brand)}</text>`\n : \"\"\n }\n</svg>`.trim();\n}\n\n// ─── Sports event template ────────────────────────────────────\n\nfunction createSportsEventSVG(options: OGImageOptions): string {\n const {\n title,\n brand,\n homeTeam,\n awayTeam,\n eventDate,\n accentColor = \"#ffd700\",\n } = options;\n\n const bg1 = options.backgroundColor ?? \"#0a0a1a\";\n const bg2 = options.backgroundColor ?? \"#1a1a3e\";\n const textColor = options.textColor ?? \"#ffffff\";\n\n if (homeTeam && awayTeam) {\n const homeLines = wrapText(homeTeam.toUpperCase(), 12, 2);\n const awayLines = wrapText(awayTeam.toUpperCase(), 12, 2);\n const teamSize = 64;\n const teamY = homeLines.length > 1 ? 300 : 330;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n <linearGradient id=\"div\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"rgba(255,215,0,0)\"/>\n <stop offset=\"50%\" stop-color=\"rgba(255,215,0,0.25)\"/>\n <stop offset=\"100%\" stop-color=\"rgba(255,215,0,0)\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"591\" y=\"60\" width=\"18\" height=\"510\" fill=\"url(#div)\" rx=\"9\"/>\n ${multilineText(homeLines, 300, teamY, teamSize, textColor, \"800\", \"middle\")}\n <text x=\"600\" y=\"345\" font-family=\"${FONT}\" font-size=\"56\" font-weight=\"900\" fill=\"${accentColor}\" text-anchor=\"middle\">VS</text>\n ${multilineText(awayLines, 900, teamY, teamSize, textColor, \"800\", \"middle\")}\n ${eventDate ? `<text x=\"${W / 2}\" y=\"510\" font-family=\"${FONT}\" font-size=\"26\" fill=\"rgba(255,255,255,0.55)\" text-anchor=\"middle\">${esc(eventDate)}</text>` : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 36}\" font-family=\"${FONT}\" font-size=\"24\" fill=\"rgba(255,255,255,0.3)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n }\n\n const titleLines = wrapText(title, 28, 2);\n const titleSize = 64;\n\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg width=\"${W}\" height=\"${H}\" viewBox=\"0 0 ${W} ${H}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"${W}\" y2=\"${H}\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"${bg1}\"/>\n <stop offset=\"100%\" stop-color=\"${bg2}\"/>\n </linearGradient>\n </defs>\n <rect width=\"${W}\" height=\"${H}\" fill=\"url(#bg)\"/>\n <rect x=\"0\" y=\"0\" width=\"8\" height=\"${H}\" fill=\"${accentColor}\"/>\n ${multilineText(titleLines, 80, 300, titleSize, textColor, \"700\")}\n ${eventDate ? `<text x=\"80\" y=\"410\" font-family=\"${FONT}\" font-size=\"28\" fill=\"rgba(255,255,255,0.55)\">${esc(eventDate)}</text>` : \"\"}\n ${brand ? `<text x=\"${W - 60}\" y=\"${H - 36}\" font-family=\"${FONT}\" font-size=\"24\" fill=\"rgba(255,255,255,0.3)\" text-anchor=\"end\">${esc(brand)}</text>` : \"\"}\n</svg>`.trim();\n}\n\n// ─── Public API ───────────────────────────────────────────────\n\nexport function createOGImageSVG(options: OGImageOptions): string {\n switch (options.template) {\n case \"article\":\n return createArticleSVG(options);\n case \"sports-event\":\n return createSportsEventSVG(options);\n default:\n return createDefaultSVG(options);\n }\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
function c(e){let i=[];for(let n of e){let s=n.name??n.path,t=n.seo??{};t.title?t.title.length>60&&i.push({page:s,field:"title",message:`Title is ${t.title.length} chars (recommended \u226460)`,severity:"warning"}):i.push({page:s,field:"title",message:"Missing page title",severity:"error"}),t.description?t.description.length>160&&i.push({page:s,field:"description",message:`Description is ${t.description.length} chars (recommended \u2264160)`,severity:"warning"}):i.push({page:s,field:"description",message:"Missing meta description",severity:"error"}),t.canonical||i.push({page:s,field:"canonical",message:"Missing canonical URL",severity:"warning"}),t.openGraph?.images?.length||i.push({page:s,field:"og:image",message:"Missing og:image",severity:"warning"}),!t.openGraph?.title&&!t.title&&i.push({page:s,field:"og:title",message:"Missing og:title",severity:"warning"}),t.twitter?.card||i.push({page:s,field:"twitter:card",message:"Missing twitter:card",severity:"warning"}),t.jsonLd||i.push({page:s,field:"structured-data",message:"No structured data (JSON-LD)",severity:"warning"});}return i}function p(e){if(!e.length)return "\u2705 All pages passed SEO validation.";let i=new Map;for(let s of e){let t=i.get(s.page)??[];t.push(s),i.set(s.page,t);}let n=[];for(let[s,t]of i){n.push(`
|
|
2
|
+
${s}:`);for(let a of t){let o=a.severity==="error"?"\u274C":"\u26A0\uFE0F ";n.push(` ${o} [${a.field}] ${a.message}`);}}return n.join(`
|
|
3
|
+
`).trim()}var r=[{name:"Title",field:"title",maxPoints:20,check:e=>e.title?e.title.length>60?{passed:true,points:10,message:`Too long (${e.title.length}/60 chars)`}:{passed:true,points:20}:{passed:false,points:0,message:"Missing title"}},{name:"Description",field:"description",maxPoints:15,check:e=>e.description?e.description.length>160?{passed:true,points:8,message:`Too long (${e.description.length}/160 chars)`}:{passed:true,points:15}:{passed:false,points:0,message:"Missing description"}},{name:"Canonical URL",field:"canonical",maxPoints:10,check:e=>e.canonical?{passed:true,points:10}:{passed:false,points:0,message:"Missing canonical URL"}},{name:"og:image",field:"og:image",maxPoints:15,check:e=>e.openGraph?.images?.length?{passed:true,points:15}:{passed:false,points:0,message:"Missing og:image"}},{name:"og:title",field:"og:title",maxPoints:5,check:e=>e.openGraph?.title||e.title?{passed:true,points:5}:{passed:false,points:0,message:"Missing og:title"}},{name:"og:description",field:"og:description",maxPoints:5,check:e=>e.openGraph?.description||e.description?{passed:true,points:5}:{passed:false,points:0,message:"Missing og:description"}},{name:"Twitter Card",field:"twitter:card",maxPoints:10,check:e=>e.twitter?.card?{passed:true,points:10}:{passed:false,points:0,message:"Missing twitter:card"}},{name:"Structured Data",field:"structured-data",maxPoints:10,check:e=>e.jsonLd?{passed:true,points:10}:{passed:false,points:0,message:"No JSON-LD structured data"}},{name:"Robots Directives",field:"robots",maxPoints:5,check:e=>e.robots!==void 0?{passed:true,points:5}:{passed:false,points:0,message:"No robots directives"}},{name:"Hreflang",field:"hreflang",maxPoints:5,check:e=>e.alternates?.length?{passed:true,points:5}:{passed:false,points:0,message:"No hreflang alternates"}}];function g(e,i="Page"){let n=0,s=r.reduce((a,o)=>a+o.maxPoints,0),t=[];for(let a of r){let o=a.check(e);n+=o.points,t.push({name:a.name,passed:o.passed,points:o.points,maxPoints:a.maxPoints,message:o.message});}return {page:i,score:n,maxScore:s,percentage:Math.round(n/s*100),checks:t}}function d(e){let n=[`${e.percentage>=80?"\u{1F7E2}":e.percentage>=50?"\u{1F7E1}":"\u{1F534}"} SEO Score: ${e.page} ${e.score}/${e.maxScore} (${e.percentage}%)`];for(let s of e.checks){let t=s.passed?"\u2705":"\u274C",a=s.message?` \u2014 ${s.message}`:"",o=s.passed?"":` (-${s.maxPoints})`;n.push(` ${t} ${s.name}${o}${a}`);}return n.join(`
|
|
4
|
+
`)}export{c as a,p as b,g as c,d};//# sourceMappingURL=chunk-X535MU7Z.js.map
|
|
5
|
+
//# sourceMappingURL=chunk-X535MU7Z.js.map
|