{"release_id":"01a1998d-9802-0000-b0f7-33a23307f4ed","chunk_id":"01a1998d-9955-7420-952e-0a43af172750","file":"hy6nR6PE.mjs","mappings":"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","names":["INCH_SIZES","CM_SIZES","_","i","RARITY_CAP","verdictFor","pct","chartRow","value","unit","cm","meanCm","sdCm","BJU_2015","p","normalCdf","side","share","n","INCH_ROWS","v","CM_ROWS","SIZE_PAGE_BASE","SIZE_PAGE_INCHES","SIZE_PAGE_CM","SIZE_PAGES_IN","SIZE_PAGES_CM","BY_SLUG","r","sizePagePath","row","sizePageBySlug","slug","sizePageFor","sideShare","WORDS","o","l","sizePageSeo","locale","w","tag","LOCALE_INFO","n1","longer","inch","titleSize","size","other","rarity","sizePageSeoEntries","rows"],"sources":["../../../../../../src/lib/tools/size-chart.ts","../../../../../../src/lib/tools/size-pages.ts"],"sourcesContent":["import { BJU_2015, normalCdf } from '$lib/data/size-stats';\n\n/**\n * The size chart (RAT-584): every erect length from 3 to 10 inches and from 8\n * to 25 cm against Veale et al. 2015 — its percentile, how rare it is, and the\n * plain answer to \"is that big?\". One row per size, each with its own anchor\n * (#6-inches, #18-cm) so a search for one size can land on it.\n */\n\nexport type Verdict = 'small' | 'below' | 'average' | 'above' | 'big' | 'rare';\n\nexport interface ChartRow {\n\t/** the anchor: `6-inches`, `5.5-inches`, `18-cm` */\n\tid: string;\n\tunit: 'in' | 'cm';\n\tvalue: number;\n\tcm: number;\n\t/** share of men shorter, 0–100 */\n\tpct: number;\n\t/** \"1 in N men is longer\" (or shorter, below the average); null when past 1 in 10,000 */\n\toneIn: number | null;\n\tside: 'longer' | 'shorter';\n\tverdict: Verdict;\n}\n\nexport const INCH_SIZES = [3, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 9, 10];\nexport const CM_SIZES = Array.from({ length: 18 }, (_, i) => 8 + i);\n\n/** Past this the normal model is a guess about men nobody measured. */\nexport const RARITY_CAP = 10_000;\n\nexport function verdictFor(pct: number): Verdict {\n\tif (pct < 5) return 'small';\n\tif (pct < 25) return 'below';\n\tif (pct < 75) return 'average';\n\tif (pct < 95) return 'above';\n\tif (pct < 99.9) return 'big';\n\treturn 'rare';\n}\n\nexport function chartRow(value: number, unit: 'in' | 'cm'): ChartRow {\n\tconst cm = unit === 'in' ? value * 2.54 : value;\n\tconst { meanCm, sdCm } = BJU_2015.erectLength;\n\tconst p = normalCdf((cm - meanCm) / sdCm);\n\tconst side = cm >= meanCm ? 'longer' : 'shorter';\n\tconst share = side === 'longer' ? 1 - p : p;\n\tconst n = Math.round(1 / share);\n\treturn {\n\t\tid: `${value}-${unit === 'in' ? 'inches' : 'cm'}`,\n\t\tunit,\n\t\tvalue,\n\t\tcm,\n\t\tpct: Math.round(p * 1000) / 10,\n\t\toneIn: share > 0 && n <= RARITY_CAP ? n : null,\n\t\tside,\n\t\tverdict: verdictFor(p * 100)\n\t};\n}\n\nexport const INCH_ROWS = INCH_SIZES.map((v) => chartRow(v, 'in'));\nexport const CM_ROWS = CM_SIZES.map((v) => chartRow(v, 'cm'));\n","import { chartRow, type ChartRow } from './size-chart';\nimport { LOCALE_INFO, type Locale } from '$lib/i18n/locales';\n\n/**\n * One page per erect length (RAT-609, RAT-610): \"7 inch penis\" (12.1K a month,\n * US), \"6 inch penis\" (9.9K), \"pene de 18 cm\" (3.6K, MX) and the rest of the\n * N-inch cluster (~100K a month, KD 25–44, Semrush 2026-10-11) had no page of\n * their own. Inch pages are English; the cm pages exist in every language,\n * since that's how the other markets search. Each page's numbers come from\n * the chart's own row (Veale 2015), so no two pages say the same thing.\n */\n\nexport const SIZE_PAGE_BASE = '/tools/penis-size';\nexport const SIZE_PAGE_INCHES = [4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10];\nexport const SIZE_PAGE_CM = Array.from({ length: 16 }, (_, i) => 10 + i);\n\nexport const SIZE_PAGES_IN: ChartRow[] = SIZE_PAGE_INCHES.map((v) => chartRow(v, 'in'));\nexport const SIZE_PAGES_CM: ChartRow[] = SIZE_PAGE_CM.map((v) => chartRow(v, 'cm'));\n\nconst BY_SLUG = new Map([...SIZE_PAGES_IN, ...SIZE_PAGES_CM].map((r) => [r.id, r]));\n\nexport const sizePagePath = (row: Pick<ChartRow, 'id'>) => `${SIZE_PAGE_BASE}/${row.id}`;\n\nexport function sizePageBySlug(slug: string): ChartRow | undefined {\n\treturn BY_SLUG.get(slug);\n}\n\n/** The page for a chart row, if that size has one. */\nexport function sizePageFor(row: Pick<ChartRow, 'id'>): string | null {\n\treturn BY_SLUG.has(row.id) ? sizePagePath(row) : null;\n}\n\nexport const SIZE_PAGE_PATHS_IN = SIZE_PAGES_IN.map(sizePagePath);\nexport const SIZE_PAGE_PATHS_CM = SIZE_PAGES_CM.map(sizePagePath);\n\nexport type SizePageSeo = { title: string; description: string };\n\n/** Share of men on the row's side, never rounded up to 100. */\nconst sideShare = (r: ChartRow) => Math.min(99.9, r.side === 'longer' ? r.pct : 100 - r.pct);\n\ntype Words = {\n\t/** \"in\" in the language, after a converted length */\n\tinch: string;\n\ttitle: (n: string) => string;\n\tlead: (n: string, other: string, pct: string, longer: boolean) => string;\n\toneIn: (n: string, longer: boolean) => string;\n\trare: (longer: boolean) => string;\n\ttail: string;\n};\n\n/** Titles and descriptions per language, written for the local search\n *  (\"pene de 18 cm\", \"18 cm Penis\"), not translated from the English line. */\nconst WORDS: Record<Locale, Words> = {\n\ten: {\n\t\tinch: 'in',\n\t\ttitle: (n) => `${n} Penis: Is It Big? Percentile & Rarity | RateMyD`,\n\t\t// \"An 8-inch\", \"An 18 cm\"\n\t\tlead: (n, o, p, l) =>\n\t\t\t`${/^(8|11|18)/.test(n) ? 'An' : 'A'} ${n} (${o}) erect penis is ${l ? 'longer' : 'shorter'} than ${p}% of men`,\n\t\toneIn: (n, l) => `, about 1 in ${n} is ${l ? 'longer' : 'shorter'}`,\n\t\trare: (l) => `, fewer than 1 in 10,000 are ${l ? 'longer' : 'shorter'}`,\n\t\ttail: '. Is it big, how it compares to the average, and how to measure.'\n\t},\n\tde: {\n\t\tinch: 'Zoll',\n\t\ttitle: (n) => `${n} Penis: Ist das groß? Perzentil & Seltenheit | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Ein erigierter Penis von ${n} (${o}) ist ${l ? 'länger' : 'kürzer'} als ${p} % der Männer`,\n\t\toneIn: (n, l) => `, etwa 1 von ${n} ist ${l ? 'länger' : 'kürzer'}`,\n\t\trare: (l) => `, unter 1 von 10.000 ist ${l ? 'länger' : 'kürzer'}`,\n\t\ttail: '. Ob das groß ist und wie man richtig misst.'\n\t},\n\tes: {\n\t\tinch: 'pulgadas',\n\t\ttitle: (n) => `Pene de ${n}: ¿es grande? Percentil y rareza | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Un pene erecto de ${n} (${o}) es más ${l ? 'largo' : 'corto'} que el ${p} % de los hombres`,\n\t\toneIn: (n, l) => `, más o menos 1 de cada ${n} es más ${l ? 'largo' : 'corto'}`,\n\t\trare: (l) => `, menos de 1 de cada 10.000 es más ${l ? 'largo' : 'corto'}`,\n\t\ttail: '. Si es grande y cómo medirlo bien.'\n\t},\n\tit: {\n\t\tinch: 'pollici',\n\t\ttitle: (n) => `Pene di ${n}: è grande? Percentile e rarità | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Un pene eretto di ${n} (${o}) è più ${l ? 'lungo' : 'corto'} del ${p}% degli uomini`,\n\t\toneIn: (n, l) => `, circa 1 su ${n} è più ${l ? 'lungo' : 'corto'}`,\n\t\trare: (l) => `, meno di 1 su 10.000 è più ${l ? 'lungo' : 'corto'}`,\n\t\ttail: '. Se è grande e come misurarlo bene.'\n\t},\n\tfr: {\n\t\tinch: 'pouces',\n\t\ttitle: (n) => `Pénis de ${n} : est-ce grand ? Percentile et rareté | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Un pénis en érection de ${n} (${o}) est plus ${l ? 'long' : 'court'} que ${p} % des hommes`,\n\t\toneIn: (n, l) => `, environ 1 sur ${n} est plus ${l ? 'long' : 'court'}`,\n\t\trare: (l) => `, moins de 1 sur 10 000 est plus ${l ? 'long' : 'court'}`,\n\t\ttail: '. S’il est grand et comment bien mesurer.'\n\t},\n\tpt: {\n\t\tinch: 'polegadas',\n\t\ttitle: (n) => `Pênis de ${n}: é grande? Percentil e raridade | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Um pênis ereto de ${n} (${o}) é ${l ? 'maior' : 'menor'} que ${p}% dos homens`,\n\t\toneIn: (n, l) => `, cerca de 1 em ${n} é ${l ? 'maior' : 'menor'}`,\n\t\trare: (l) => `, menos de 1 em 10.000 é ${l ? 'maior' : 'menor'}`,\n\t\ttail: '. Se é grande, a comparação com a média e como medir.'\n\t},\n\thu: {\n\t\tinch: 'hüvelyk',\n\t\ttitle: (n) => `${n}-es pénisz: nagynak számít? Percentilis és ritkaság | RateMyD`,\n\t\tlead: (n, o, p, l) =>\n\t\t\t`Egy ${n}-es (${o}) merev pénisz ${l ? 'hosszabb' : 'rövidebb'} a férfiak ${p}%-ánál`,\n\t\toneIn: (n, l) => `; nagyjából minden ${n}. férfié ${l ? 'hosszabb' : 'rövidebb'}`,\n\t\trare: (l) => `; 10 000 férfiból kevesebb mint egyé ${l ? 'hosszabb' : 'rövidebb'}`,\n\t\ttail: '. Nagynak számít-e, és hogyan mérd le pontosan.'\n\t}\n};\n\n/** The page's title and description in a language. Inch pages are English\n *  only; a cm page has one per language. */\nexport function sizePageSeo(row: ChartRow, locale: Locale): SizePageSeo {\n\tconst w = WORDS[locale];\n\tconst tag = LOCALE_INFO[locale].hreflang;\n\tconst n1 = (v: number) => v.toLocaleString(tag, { maximumFractionDigits: 1 });\n\tconst longer = row.side === 'longer';\n\tconst inch = row.unit === 'in';\n\t// \"7 Inch\" in an English title, \"7-inch\" in its sentence; \"18 cm\" everywhere\n\tconst titleSize = inch ? `${n1(row.value)} Inch` : `${n1(row.value)} cm`;\n\tconst size = inch ? `${n1(row.value)}-inch` : `${n1(row.value)} cm`;\n\tconst other = inch ? `${n1(row.cm)} cm` : `${n1(row.cm / 2.54)} ${w.inch}`;\n\tconst rarity =\n\t\trow.oneIn === null\n\t\t\t? w.rare(longer)\n\t\t\t: row.oneIn >= 3\n\t\t\t\t? w.oneIn(row.oneIn.toLocaleString(tag), longer)\n\t\t\t\t: '';\n\treturn {\n\t\ttitle: w.title(titleSize),\n\t\tdescription: w.lead(size, other, n1(sideShare(row)), longer) + rarity + w.tail\n\t};\n}\n\n/** SEO entries for every size page in a language, keyed by path. */\nexport function sizePageSeoEntries(locale: Locale): Record<string, SizePageSeo> {\n\tconst rows = locale === 'en' ? [...SIZE_PAGES_IN, ...SIZE_PAGES_CM] : SIZE_PAGES_CM;\n\treturn Object.fromEntries(rows.map((r) => [sizePagePath(r), sizePageSeo(r, locale)]));\n}\n"],"version":3}