{"version":3,"file":"CStQg_CQ.mjs","sources":["../../../../../../src/lib/utils/intellectual-property.ts"],"sourcesContent":["import type { Collaborator, IntellectualProperty, SimpleDate } from '$lib/queries/profile'\n\nexport function quoteTitle (title?: string): string | undefined {\n  const trimmed = title?.trim()\n  return trimmed ? `“${trimmed}”` : undefined\n}\n\nexport function formatAuthorList (collaborators?: Collaborator[]): string | undefined {\n  if (!collaborators?.length) return undefined\n  return collaborators.map(c => [c.FNAME, c.LNAME].filter(Boolean).join(' ')).join(', ')\n}\n\nexport function formatPatentTypeNumber (type?: string, idNumber?: string): string | undefined {\n  const trimmedType = type?.trim()\n  const trimmedId = idNumber?.trim()\n  const parts = [trimmedType, trimmedId ? `#${trimmedId}` : undefined].filter(Boolean)\n  return parts.length ? parts.join(', ') : undefined\n}\n\nfunction pad2 (n: number): string {\n  return String(n).padStart(2, '0')\n}\n\nfunction formatPatentDate (date?: SimpleDate): string | undefined {\n  if (!date?.year) return undefined\n  if (date.month && date.day) return `${pad2(date.month)}/${pad2(date.day)}/${date.year}`\n  if (date.month) return `${pad2(date.month)}/${date.year}`\n  return `${date.year}`\n}\n\nexport function formatPatentDateLine (item: { dateApplication?: SimpleDate, dateApproved?: SimpleDate, dateRenewal?: SimpleDate }): string | undefined {\n  const applied = formatPatentDate(item.dateApplication)\n  const awarded = formatPatentDate(item.dateApproved)\n  const renewal = formatPatentDate(item.dateRenewal)\n  const parts = [\n    applied ? `Date applied: ${applied}` : undefined,\n    awarded ? `Date awarded: ${awarded}` : undefined,\n    renewal ? `Date of renewal: ${renewal}` : undefined\n  ].filter(Boolean)\n  return parts.length ? parts.join(', ') : undefined\n}\n\nfunction stripTrailingPeriods (text: string): string {\n  return text.trim().replace(/\\.+$/, '').trimEnd()\n}\n\n// Ends the title with a period inside the closing quote, unless it already ends in ? or !.\nfunction quotePatentTitle (title?: string): string | undefined {\n  const stripped = title ? stripTrailingPeriods(title) : ''\n  if (!stripped) return undefined\n  return quoteTitle(/[?!]$/.test(stripped) ? stripped : `${stripped}.`)\n}\n\nexport function formatPatentCitationLine (item: IntellectualProperty): string {\n  const rest = [\n    formatAuthorList(item.collaborators),\n    formatPatentTypeNumber(item.TYPE, item.ID_NUMBER)\n  ].filter((p): p is string => !!p).map(stripTrailingPeriods).filter(Boolean)\n  return [\n    quotePatentTitle(item.TITLE ?? item.description),\n    rest.length ? `${rest.join('. ')}.` : undefined\n  ].filter(Boolean).join(' ')\n}\n\nexport interface PatentCard {\n  citationLine: string\n  dateLine?: string\n}\n\nexport function formatPatentCard (item: IntellectualProperty): PatentCard {\n  return {\n    citationLine: formatPatentCitationLine(item),\n    dateLine: formatPatentDateLine(item)\n  }\n}\n\nexport function formatIpCitationLine (item: IntellectualProperty): string {\n  const parts = [quoteTitle(item.TITLE ?? item.description), item.NATIONALITY, item.TYPE, item.ID_NUMBER].filter(Boolean)\n  return parts.join(', ')\n}\n\nconst FORMAT_BUCKETS = {\n  copyrights: 'copyright',\n  patents: 'patent',\n  trademarks: 'trademark'\n} as const\n\nexport type FeaturedBucket = keyof typeof FORMAT_BUCKETS\nexport type IpBucket = FeaturedBucket | 'other'\nexport type GroupedIntellectualProperty = Record<IpBucket, IntellectualProperty[]>\n\nconst FEATURED_BUCKETS = Object.keys(FORMAT_BUCKETS) as FeaturedBucket[]\n\nfunction classify (item: IntellectualProperty): IpBucket {\n  const fmt = item.FORMAT?.trim().toLowerCase() ?? ''\n  return FEATURED_BUCKETS.find(k => fmt.includes(FORMAT_BUCKETS[k])) ?? 'other'\n}\n\nexport function groupIpByFormat (items: IntellectualProperty[]): GroupedIntellectualProperty {\n  const grouped: GroupedIntellectualProperty = { copyrights: [], patents: [], trademarks: [], other: [] }\n  for (const item of items) grouped[classify(item)].push(item)\n  return grouped\n}\n\n// Base quota per category, with round-robin redistribution of unused slots.\n// `other` is never featured.\nexport function allocateFeaturedIp (grouped: GroupedIntellectualProperty, cap = 6, base = 2): GroupedIntellectualProperty {\n  const take = Object.fromEntries(\n    FEATURED_BUCKETS.map(k => [k, Math.min(base, grouped[k].length)])\n  ) as Record<FeaturedBucket, number>\n  let remaining = cap - FEATURED_BUCKETS.reduce((sum, k) => sum + take[k], 0)\n  while (remaining > 0) {\n    const before = remaining\n    for (const k of FEATURED_BUCKETS) {\n      if (remaining > 0 && grouped[k].length > take[k]) { take[k]++; remaining-- }\n    }\n    if (remaining === before) break\n  }\n  return {\n    copyrights: grouped.copyrights.slice(0, take.copyrights),\n    patents: grouped.patents.slice(0, take.patents),\n    trademarks: grouped.trademarks.slice(0, take.trademarks),\n    other: []\n  }\n}\n"],"names":["quoteTitle","title","trimmed","formatAuthorList","collaborators","c","formatPatentTypeNumber","type","idNumber","trimmedType","trimmedId","parts","pad2","n","formatPatentDate","date","formatPatentDateLine","item","applied","awarded","renewal","stripTrailingPeriods","text","quotePatentTitle","stripped","formatPatentCitationLine","rest","p","formatPatentCard","formatIpCitationLine","FORMAT_BUCKETS","FEATURED_BUCKETS","classify","_a","fmt","k","groupIpByFormat","items","grouped","allocateFeaturedIp","cap","base","take","remaining","sum","before"],"mappings":"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"}