@consenti/api 0.5.0 → 0.6.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.
Files changed (63) hide show
  1. package/README.md +143 -11
  2. package/dist/chunk-7NKW7UTJ.js +2 -0
  3. package/dist/chunk-7NKW7UTJ.js.map +1 -0
  4. package/dist/dashboard/assets/{ApiConfig-dmDLJNfI.js → ApiConfig-DLPkgWsM.js} +1 -1
  5. package/dist/dashboard/assets/{ArchivedProfileList-ChWp1RHE.js → ArchivedProfileList-fRvXAaWy.js} +1 -1
  6. package/dist/dashboard/assets/{AuditLog-3lekUOk8.js → AuditLog-9flkPiEQ.js} +1 -1
  7. package/dist/dashboard/assets/{ChangePassword-BYlF08cE.js → ChangePassword-D--mNLLR.js} +1 -1
  8. package/dist/dashboard/assets/{ConfirmDialog-sMBVcbiI.js → ConfirmDialog-CJAqYRfE.js} +1 -1
  9. package/dist/dashboard/assets/{ConsentList-DLDBSjxO.js → ConsentList-CyddMOrW.js} +1 -1
  10. package/dist/dashboard/assets/{ConsentTemplateEditor-0iB6G95-.js → ConsentTemplateEditor-DZGFzkTA.js} +1 -1
  11. package/dist/dashboard/assets/{ConsentTemplateList-BnU_nL8h.js → ConsentTemplateList-CwNVxHyZ.js} +1 -1
  12. package/dist/dashboard/assets/{HeadingTagInput-7owwn9Vj.js → HeadingTagInput-DGKZYLTR.js} +1 -1
  13. package/dist/dashboard/assets/{HowItWorks-B05y-6xX.js → HowItWorks-10CyO4Kp.js} +1 -1
  14. package/dist/dashboard/assets/{PermissionGate-D45f3WrO.js → PermissionGate-CkaZ9DKx.js} +1 -1
  15. package/dist/dashboard/assets/PreviewPane-ArCfR0c9.js +38 -0
  16. package/dist/dashboard/assets/{ProfileEditor-CuMRNzdM.js → ProfileEditor-BNUxXKMk.js} +1 -1
  17. package/dist/dashboard/assets/{ProfileList-CFZ_i1zk.js → ProfileList-Ti5ZML_L.js} +1 -1
  18. package/dist/dashboard/assets/{ProfileVersionHistory-40HtQSrd.js → ProfileVersionHistory-D2KtUROF.js} +1 -1
  19. package/dist/dashboard/assets/{RecordDetailModal-hpJgK02E.js → RecordDetailModal-4OyHjtux.js} +1 -1
  20. package/dist/dashboard/assets/{Reports-BlvcycZ8.js → Reports-CHpF_j2k.js} +1 -1
  21. package/dist/dashboard/assets/{RoleList-CTeQdx6f.js → RoleList-BICQW5gU.js} +1 -1
  22. package/dist/dashboard/assets/{Select-CeC6GRyb.js → Select-C7q2vevu.js} +1 -1
  23. package/dist/dashboard/assets/{Settings-DLsvGtMh.js → Settings-BlOcU0wL.js} +1 -1
  24. package/dist/dashboard/assets/{SetupWizard-BVzGrBm2.js → SetupWizard-DReZ5DWr.js} +1 -1
  25. package/dist/dashboard/assets/{Table-CcBP7eXS.js → Table-C59yMXY2.js} +1 -1
  26. package/dist/dashboard/assets/{TenantList-DLgPnlVv.js → TenantList-Bbwcxyo8.js} +1 -1
  27. package/dist/dashboard/assets/{UITemplateEditor-B9EBcvOB.js → UITemplateEditor-CR7TnHBH.js} +1 -1
  28. package/dist/dashboard/assets/{UITemplateList-CGYRRlCh.js → UITemplateList-NKwDQJAw.js} +1 -1
  29. package/dist/dashboard/assets/{UserList-BbpiUrVr.js → UserList-DMk0_UF0.js} +1 -1
  30. package/dist/dashboard/assets/{VendorList-mlOlW7ht.js → VendorList-BawJ8Kyc.js} +1 -1
  31. package/dist/dashboard/assets/{VisitorList-Dne7xkNx.js → VisitorList-BVSFRtul.js} +1 -1
  32. package/dist/dashboard/assets/check-BAoHs1bd.js +1 -0
  33. package/dist/dashboard/assets/{copy-FTaGH7-z.js → copy-DjZpSOQM.js} +1 -1
  34. package/dist/dashboard/assets/{external-link-5y29qnhn.js → external-link-CFayXpKz.js} +1 -1
  35. package/dist/dashboard/assets/{index-BaYVhd1M.js → index-D7qdwIxs.js} +2 -2
  36. package/dist/dashboard/assets/{profiles-D-hvl_fK.js → profiles-Jb6uV-0U.js} +1 -1
  37. package/dist/dashboard/assets/{roles-DZyZwZDr.js → roles-ChXEt79v.js} +1 -1
  38. package/dist/dashboard/assets/{rotate-ccw-clock-C5cVu2_f.js → rotate-ccw-clock-503u3yEE.js} +1 -1
  39. package/dist/dashboard/assets/{search-mdMD-WTj.js → search-B05qPv24.js} +1 -1
  40. package/dist/dashboard/assets/{square-pen-BoEcHaSW.js → square-pen-BX2H18m3.js} +1 -1
  41. package/dist/dashboard/assets/{templates-DLMsZs7d.js → templates-DalUjETH.js} +1 -1
  42. package/dist/dashboard/assets/{trash-BVDX09Xe.js → trash-Bfqti-Og.js} +1 -1
  43. package/dist/dashboard/assets/{useHashQuery-wXzkY-tk.js → useHashQuery-DzYBqPIg.js} +1 -1
  44. package/dist/dashboard/assets/{users-BLTbK4tk.js → users-CDdO4hYQ.js} +1 -1
  45. package/dist/dashboard/assets/x-Clw5rGTJ.js +1 -0
  46. package/dist/dashboard/index.html +1 -1
  47. package/dist/dist-MNR4WETI.js +2 -0
  48. package/dist/index.cjs +77 -75
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +45 -9
  51. package/dist/index.d.ts +45 -9
  52. package/dist/index.js +76 -74
  53. package/dist/index.js.map +1 -1
  54. package/dist/widget/widget.js +1 -1
  55. package/package.json +3 -2
  56. package/scripts/migrate-to-consenti-prefix.mjs +196 -0
  57. package/dist/chunk-COR72NFQ.js +0 -2
  58. package/dist/chunk-COR72NFQ.js.map +0 -1
  59. package/dist/dashboard/assets/PreviewPane-Czax39la.js +0 -38
  60. package/dist/dashboard/assets/check-IM5PInrX.js +0 -1
  61. package/dist/dashboard/assets/x-CtCy0YcJ.js +0 -1
  62. package/dist/dist-QJYW5KUK.js +0 -2
  63. /package/dist/{dist-QJYW5KUK.js.map → dist-MNR4WETI.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/utils/src/methods/debounce.ts","../../../packages/utils/src/methods/throttle.ts","../../../packages/utils/src/terminal-color.ts","../../../packages/utils/src/compliance.ts","../../../packages/utils/src/tracker-knowledge-base.ts","../../../packages/utils/src/content-doc.ts","../../../packages/utils/src/tcf.ts","../../../packages/utils/src/gpp.ts","../../../packages/utils/src/direction.ts"],"sourcesContent":["type AnyFunction = (this: any, ...args: any[]) => any;\n\n/**\n * Creates a debounced version of a function.\n *\n * A debounced function delays execution until after the specified delay has\n * elapsed since the last invocation. Each new call resets the timer.\n *\n * This is useful for events that fire frequently, such as:\n * - Search input\n * - Window resize\n * - Auto-save\n * - API requests\n *\n * @template T - Type of the function being debounced.\n *\n * @param fn - The function to debounce.\n * @param delay - Delay in milliseconds to wait after the last invocation.\n *\n * @returns A debounced function with the same parameter types as the original.\n *\n * @example\n * ```ts\n * const search = debounce((query: string) => {\n * console.log(query);\n * }, 300);\n *\n * search(\"r\");\n * search(\"re\");\n * search(\"react\");\n * // Only \"react\" is logged after 300ms.\n * ```\n */\nexport function debounce<T extends AnyFunction>(\n fn: T,\n delay: number\n) {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n return function (\n this: ThisParameterType<T>,\n ...args: Parameters<T>\n ): void {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n\n timer = setTimeout(() => {\n fn.apply(this, args);\n }, delay);\n };\n}","type AnyFunction = (this: any, ...args: any[]) => any;\n\n/**\n * Creates a throttled version of a function.\n *\n * A throttled function executes immediately and then ignores subsequent calls\n * until the specified delay has passed.\n *\n * This is useful for events that fire continuously, such as:\n * - Scroll\n * - Mouse move\n * - Window resize\n * - Drag events\n *\n * @template T - Type of the function being throttled.\n *\n * @param fn - The function to throttle.\n * @param delay - Minimum time in milliseconds between executions.\n *\n * @returns A throttled function with the same parameter types as the original.\n *\n * @example\n * ```ts\n * const onScroll = throttle(() => {\n * console.log(\"Scrolled\");\n * }, 200);\n *\n * window.addEventListener(\"scroll\", onScroll);\n * ```\n */\nexport function throttle<T extends AnyFunction>(\n fn: T,\n delay: number\n) {\n let lastCall = 0;\n\n return function (\n this: ThisParameterType<T>,\n ...args: Parameters<T>\n ): void {\n const now = Date.now();\n\n if (now - lastCall >= delay) {\n lastCall = now;\n fn.apply(this, args);\n }\n };\n}","/**\n * Minimal, dependency-free ANSI helpers for coloring console output — shared by any package/app\n * that prints to a terminal (originally `apps/test-runner`'s internal helper, moved here so\n * `apps/scanner` can reuse the same engine instead of duplicating it). Not worth an external\n * chalk/picocolors dependency for a handful of colors. Disabled automatically when stdout isn't a\n * TTY (CI logs, piping to a file) or `NO_COLOR` is set, or forced on via `FORCE_COLOR`.\n */\n\nfunction colorEnabled(): boolean {\n // Guarded rather than assumed Node-only: this package is also consumed by @consenti/ui in the\n // browser, where `process` doesn't exist at all.\n if (typeof process === 'undefined') return false\n if (process.env.NO_COLOR) return false\n if (process.env.FORCE_COLOR) return true\n return Boolean(process.stdout?.isTTY)\n}\n\nfunction wrap(open: number, close: number): (s: string) => string {\n return (s: string) => (colorEnabled() ? `\\x1b[${open}m${s}\\x1b[${close}m` : s)\n}\n\nexport const color = {\n bold: wrap(1, 22),\n dim: wrap(2, 22),\n red: wrap(31, 39),\n green: wrap(32, 39),\n yellow: wrap(33, 39),\n blue: wrap(34, 39),\n magenta: wrap(35, 39),\n cyan: wrap(36, 39),\n gray: wrap(90, 39),\n}\n\nexport type StatusKind = 'pass' | 'fail' | 'error' | 'not-applicable' | 'new-baseline'\n\nconst STATUS_STYLE: Record<StatusKind, (s: string) => string> = {\n pass: s => color.bold(color.green(s)),\n fail: s => color.bold(color.red(s)),\n error: s => color.bold(color.red(s)),\n 'not-applicable': s => color.gray(s),\n 'new-baseline': s => color.bold(color.blue(s)),\n}\n\n/** A fixed-width, colored status label — e.g. `PASS ` in bold green. */\nexport function statusLabel(status: StatusKind, width = 10): string {\n const text = status.toUpperCase().padEnd(width)\n return STATUS_STYLE[status](text)\n}\n\nexport type LogLevel = 'info' | 'success' | 'warn' | 'error'\n\nconst LEVEL_STYLE: Record<LogLevel, { symbol: string; paint: (s: string) => string }> = {\n info: { symbol: 'ℹ', paint: color.cyan },\n success: { symbol: '✓', paint: color.green },\n warn: { symbol: '⚠', paint: color.yellow },\n error: { symbol: '✗', paint: color.red },\n}\n\n/** Formats `message` with a level-appropriate color and symbol prefix — e.g.\n * `formatLog('warn', 'Blocked with 429')` → a yellow `⚠ Blocked with 429`. Returns a plain string\n * (never writes anywhere itself) so callers can feed it into `console.log`, a spinner, or any\n * other sink, same as the rest of this file's colorizers. */\nexport function formatLog(level: LogLevel, message: string): string {\n const { symbol, paint } = LEVEL_STYLE[level]\n return `${paint(symbol)} ${message}`\n}\n","/**\n * Single source of truth for all compliance groups, regulations, and country mappings.\n *\n * This is DATA, not types. The `Compliance` and `ComplianceGroupId` literal types\n * derived from the ID arrays below live in @consenti/types (packages/types/src/compliance.ts),\n * via a type-only import — that keeps @consenti/types free of runtime code.\n *\n * ─── HOW TO UPDATE ────────────────────────────────────────────────────────────\n *\n * ADD A NEW REGULATION:\n * 1. Add regulation ID string to `COMPLIANCE_REGULATION_IDS` below\n * (the `Compliance` type in @consenti/types auto-updates from it).\n * 2. Add it to the appropriate group's `compliances` array below.\n * 3. Add / update the country entry in `EMBEDDED_COMPLIANCE_MAP` below.\n * That is all — no other files need touching.\n *\n * ADD A NEW COMPLIANCE GROUP:\n * 1. Add the kebab-case ID to `COMPLIANCE_GROUP_IDS` below.\n * 2. Add a full group entry to `COMPLIANCE_GROUPS` below (label, compliances, flags).\n * 3. Add a validation rule set to `COMPLIANCE_VALIDATION_RULES` below.\n * 4. Map affected countries in `EMBEDDED_COMPLIANCE_MAP` to the new group.\n *\n * ADD OR UPDATE A COUNTRY:\n * Edit the entry in `EMBEDDED_COMPLIANCE_MAP.countries` below. That is the ONLY\n * place that needs changing for country-level jurisdiction updates.\n */\n\n// ─── Regulation IDs ───────────────────────────────────────────────────────────\n\n// ─── Compliance Group IDs ─────────────────────────────────────────────────────\n\nexport const COMPLIANCE_GROUP_IDS = [\n 'opt-in',\n 'opt-out',\n 'opt-out-strict',\n 'opt-in-dpdpa',\n 'opt-in-china',\n 'opt-in-brazil',\n 'general-privacy-consent',\n 'notice-only',\n] as const\n\n// Local alias for the shape checks below. The public `ComplianceGroupId` type\n// (derived from the same array) is re-exported from @consenti/types.\ntype ComplianceGroupId = typeof COMPLIANCE_GROUP_IDS[number]\n\n// ─── Compliance Groups ────────────────────────────────────────────────────────\n\nexport const COMPLIANCE_GROUPS = {\n 'opt-out-strict': {\n label: 'Opt-out Strict (CPRA / California)',\n description: 'California CPRA: opt-out with sale/sharing/sensitive categories required. GPC must be honored. Stricter than general US state laws.',\n compliances: ['cpra'],\n defaultGpc: 'honor',\n gpcAutoHonor: true,\n allowsLegitimateInterest: false,\n allowsTcf: false,\n requiresCpraCategory: true,\n requiresDpdpaDisclosure: false,\n },\n 'opt-out': {\n label: 'Opt-out (US State Laws)',\n description: 'US state privacy laws. Collect first, allow opt-out of sale/share. Covers CCPA and all state-level equivalents.',\n compliances: [\n 'ccpa',\n 'vcdpa', 'cpa-co', 'ctdpa', 'ucpa', 'icdpa-ia', 'icdpa-in', 'tipa',\n 'mcdpa-mt', 'mcdpa-mn', 'ocpa', 'tdpsa', 'dpdpa-de', 'njdpa', 'nhpa',\n 'ndpa-ne', 'modpa', 'kcdpa', 'ridtpa',\n ],\n defaultGpc: 'honor',\n gpcAutoHonor: true,\n allowsLegitimateInterest: false,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n 'notice-only': {\n label: 'Notice Only',\n description: 'A privacy notice is generally sufficient. No dedicated cookie banner law is encoded for this jurisdiction.',\n compliances: ['privacy-fj', 'privacy-pg'],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: true,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n 'opt-in': {\n label: 'Standard Opt-in (GDPR)',\n description: 'GDPR / ePrivacy style: prior consent required before non-essential cookies. Granular consent, easy reject, easy withdrawal.',\n compliances: [\n 'gdpr', 'eprivacy', 'uk-gdpr', 'pecr', 'revfadp', 'kvkk', 'pdpa-th',\n 'pdpl-sa', 'uae-pdpl', 'difc-dpl', 'adgm-dpr', 'qpdl-qa', 'pdpl-bh', 'pdpl-om',\n 'law25',\n ],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: true,\n allowsTcf: true,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n 'opt-in-dpdpa': {\n label: 'Opt-in (India DPDPA)',\n description: \"India's Digital Personal Data Protection Act. Opt-in consent with data fiduciary disclosure. No legitimate interest basis.\",\n compliances: ['dpdpa'],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: false,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: true,\n },\n 'opt-in-china': {\n label: 'Opt-in (China PIPL / DSL)',\n description: 'China PIPL + DSL + CSL: strict opt-in with purpose specification, data minimisation, and cross-border transfer controls.',\n compliances: ['pipl', 'dsl-cn', 'csl-cn'],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: false,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n 'opt-in-brazil': {\n label: 'Opt-in (Brazil LGPD)',\n description: 'Brazil LGPD: opt-in consent required. Legitimate interest is a valid basis. Analytics and advertising may differ in treatment.',\n compliances: ['lgpd'],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: true,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n 'general-privacy-consent': {\n label: 'General Privacy Consent',\n description: 'Privacy notice or consent rules exist but the jurisdiction does not have a GDPR/PECR-style strict cookie banner law. Documenting legal basis is best practice.',\n compliances: [\n 'pipeda',\n 'popia', 'appi', 'pipa-kr',\n 'pdpa-sg', 'pdpa-my', 'dpa-ph', 'pdp-id', 'pdpd-vn',\n 'privacy-au', 'privacy-nz', 'pdpl-hk', 'pdpa-mo', 'pdpl-tw',\n 'privacy-bn', 'privacy-lk', 'privacy-np', 'privacy-kw', 'privacy-il',\n 'ndpa-ng', 'dpa-ke', 'dpa-gh', 'dpa-ug', 'dpa-rw', 'dpa-mu',\n 'dpa-bw', 'dpa-zm', 'dpa-zw', 'dpa-eg', 'dpa-ma', 'dpa-tn', 'dpa-dz',\n 'lfpdppp', 'lpdp-ar', 'lpdp-pe', 'law1581-co', 'law18331-uy',\n 'law19628-cl', 'lopdp-ec', 'lpdp-cr', 'data-protection-pa', 'data-protection-do',\n ],\n defaultGpc: 'ignore',\n gpcAutoHonor: false,\n allowsLegitimateInterest: true,\n allowsTcf: false,\n requiresCpraCategory: false,\n requiresDpdpaDisclosure: false,\n },\n} satisfies Record<ComplianceGroupId, {\n label: string\n description: string\n compliances: readonly string[]\n defaultGpc: 'ignore' | 'honor' | 'strict'\n gpcAutoHonor: boolean\n allowsLegitimateInterest: boolean\n allowsTcf: boolean\n requiresCpraCategory: boolean\n requiresDpdpaDisclosure: boolean\n}>\n\n// ─── GPC Options ──────────────────────────────────────────────────────────────\n\nexport const GPC_OPTIONS = [\n { value: 'ignore', label: 'Ignore', description: 'Do not check or respond to the GPC browser signal.' },\n { value: 'honor', label: 'Honor', description: 'Respect GPC as a valid opt-out signal. Show GPC variant banner once.' },\n { value: 'strict', label: 'Strict', description: 'Silently deny all non-mandatory cookies when GPC is detected. No banner shown.' },\n]\n\n// ─── Legal Basis Options ──────────────────────────────────────────────────────\n\nexport const LEGAL_BASIS_OPTIONS = [\n { value: 'mandatory', label: 'Strictly Necessary', description: 'Required for the service to function. No consent needed.' },\n { value: 'consent', label: 'Consent', description: 'Requires explicit user agreement. User can withdraw at any time.' },\n { value: 'legitimate_interest', label: 'Legitimate Interest', description: 'Based on legitimate business interest. User has the right to object.' },\n]\n\n// ─── CPRA Categories ──────────────────────────────────────────────────────────\n\nexport const CPRA_CATEGORIES = [\n { value: 'sale', label: 'Sale', description: 'Sale of personal data to third parties for their own use.' },\n { value: 'sharing', label: 'Sharing', description: 'Sharing for cross-context behavioral advertising (even without payment).' },\n { value: 'sensitive', label: 'Sensitive', description: 'Sensitive personal information (geolocation, health, race, biometrics, etc.). Requires opt-in even in California.' },\n]\n\n// ─── Cookie Purposes ──────────────────────────────────────────────────────────\n// The `CookiePurpose` literal type derived from this array lives in\n// @consenti/types (packages/types/src/ui.ts) via a type-only import.\n\nexport const COOKIE_PURPOSE_IDS = ['necessary', 'functional', 'preferences', 'analytics', 'marketing'] as const\n\ntype CookiePurposeId = typeof COOKIE_PURPOSE_IDS[number]\n\nexport const COOKIE_PURPOSES = [\n { value: 'necessary', label: 'Necessary', description: 'Strictly required to deliver the service or ensure security/compliance. Always granted.' },\n { value: 'functional', label: 'Functional', description: 'Optional features that enhance functionality but are not essential.' },\n { value: 'preferences', label: 'Preferences', description: 'Remember user choices and personalize the experience (\"Remember me\").' },\n { value: 'analytics', label: 'Analytics', description: 'Measure usage and performance to improve the product.' },\n { value: 'marketing', label: 'Marketing', description: 'Advertising, profiling, cross-site tracking, retargeting, ad personalization.' },\n]\n\nexport const COOKIE_PURPOSE_DEFAULTS: Record<CookiePurposeId, {\n legalBasis: 'mandatory' | 'consent' | 'legitimate_interest'\n listenGpc: boolean\n cpraCategory?: 'sale' | 'sharing' | 'sensitive'\n}> = {\n necessary: { legalBasis: 'mandatory', listenGpc: false },\n functional: { legalBasis: 'legitimate_interest', listenGpc: false },\n preferences: { legalBasis: 'legitimate_interest', listenGpc: false },\n analytics: { legalBasis: 'consent', listenGpc: true },\n marketing: { legalBasis: 'consent', listenGpc: true, cpraCategory: 'sharing' },\n}\n\nexport const KNOWN_COOKIE_PURPOSES: Record<string, CookiePurposeId> = {\n security_storage: 'necessary',\n functionality_storage: 'functional',\n personalization_storage: 'preferences',\n analytics_storage: 'analytics',\n ad_storage: 'marketing',\n ad_user_data: 'marketing',\n ad_personalization: 'marketing',\n}\n\n/** Legal basis no longer lives on Cookie (it's derived from category membership), so unknown IDs default to 'functional' rather than guessing from a legal-basis hint. */\nexport function inferCookiePurpose(cookie: { id: string }): CookiePurposeId {\n return KNOWN_COOKIE_PURPOSES[cookie.id] ?? 'functional'\n}\n\n// ─── TCF Purposes (stable across IAB TCF v2.2/v2.3 — same 11 purposes) ───────\n\nexport const TCF_PURPOSES = [\n { id: 1, name: 'Store and/or access information on a device', description: \"Cookies, device identifiers, or other information can be stored or accessed on your device.\" },\n { id: 2, name: 'Select basic ads', description: \"Ads can be shown based on the content you're viewing, the app you're using, or your approximate location.\" },\n { id: 3, name: 'Create a personalised ads profile', description: \"A profile can be built about you and your interests to show you personalised ads.\" },\n { id: 4, name: 'Select personalised ads', description: \"Personalised ads can be shown to you based on a profile about you.\" },\n { id: 5, name: 'Create a personalised content profile', description: \"A profile can be built about you and your interests to show you personalised content.\" },\n { id: 6, name: 'Select personalised content', description: \"Personalised content can be shown to you based on a profile about you.\" },\n { id: 7, name: 'Measure ad performance', description: \"The performance and effectiveness of ads that you see or interact with can be measured.\" },\n { id: 8, name: 'Measure content performance', description: \"The performance and effectiveness of content that you see or interact with can be measured.\" },\n { id: 9, name: 'Apply market research to generate audience insights', description: \"Market research can be used to learn more about the audiences who visit sites or use apps.\" },\n { id: 10, name: 'Develop and improve products', description: \"Your data can be used to improve existing systems and software, and to develop new products.\" },\n { id: 11, name: 'Use limited data to select content', description: \"Content can be selected based on limited data such as the website you are visiting.\" },\n]\n\nexport const TCF_SPECIAL_FEATURES = [\n { id: 1, name: 'Use precise geolocation data', description: \"Your precise location (within a radius of less than 500 metres) can be used.\" },\n { id: 2, name: 'Actively scan device characteristics for identification', description: \"Your device can be identified based on a scan of your device's unique combination of characteristics.\" },\n]\n\n// ─── Category ↔ Cookie legal-basis derivation ─────────────────────────────────\n// Legal basis lives on Category (single source of truth); a Cookie/parameter's\n// effective legal basis is derived from whichever category lists its id in\n// `cookies`. Local, minimal shapes here — packages/utils has no dependency on\n// @consenti/types (types depends on utils for data, not the other way), so\n// these are structurally compatible with `Category` from packages/types/src/ui.ts\n// rather than importing it.\n\ntype LegalBasisValue = 'mandatory' | 'consent' | 'legitimate_interest'\n\ninterface CategoryLike {\n legalBasis: LegalBasisValue\n cookies: string[]\n}\n\n/** Linear scan for a single lookup. For repeated lookups against the same category set, build an index with {@link buildCookieCategoryIndex} once instead. */\nexport function findCategoryForCookie<T extends CategoryLike>(\n cookieId: string,\n categories: Record<string, T>,\n): T | undefined {\n for (const category of Object.values(categories)) {\n if (category.cookies.includes(cookieId)) return category\n }\n return undefined\n}\n\n/** Builds a cookie-id → category lookup once per profile load; reuse it across every consent-engine call rather than rebuilding per call. */\nexport function buildCookieCategoryIndex<T extends CategoryLike>(\n categories: Record<string, T>,\n): Map<string, T> {\n const index = new Map<string, T>()\n for (const category of Object.values(categories)) {\n for (const cookieId of category.cookies) index.set(cookieId, category)\n }\n return index\n}\n\n/** Falls back to 'consent' only if the exactly-one-category-per-parameter authoring rule was somehow bypassed. */\nexport function getCookieLegalBasis(cookieId: string, index: Map<string, CategoryLike>): LegalBasisValue {\n return index.get(cookieId)?.legalBasis ?? 'consent'\n}\n\nexport function isMandatoryCookie(cookieId: string, index: Map<string, CategoryLike>): boolean {\n return getCookieLegalBasis(cookieId, index) === 'mandatory'\n}\n\n// ─── Compliance Validation Rules ──────────────────────────────────────────────\n// check() returns true when a violation exists (i.e., the rule is broken).\n// Legal-basis/LI rules run against Category records (legalBasis now lives there).\n// GPC/CPRA/preGrant rules stay Cookie-level but receive the cookie's *derived*\n// legalBasis (via getCookieLegalBasis/buildCookieCategoryIndex) as a second\n// argument instead of reading a (now nonexistent) cookie.legalBasis field.\n\ninterface RuleEntry<TSubject> {\n rule: string\n field: string\n check: (subject: Record<string, unknown>, legalBasis: TSubject) => boolean\n message: (id: string) => string\n}\ninterface WarningEntry<TSubject> extends RuleEntry<TSubject> {\n suggestion: string\n}\n\nexport const COMPLIANCE_VALIDATION_RULES: Record<string, {\n /** Checked once per category, keyed by category id. */\n categoryErrors: Array<RuleEntry<void>>\n categoryWarnings: Array<WarningEntry<void>>\n /** Checked once per cookie/parameter, keyed by cookie id. Receives the parameter's derived legal basis. */\n cookieErrors: Array<RuleEntry<LegalBasisValue>>\n cookieWarnings: Array<WarningEntry<LegalBasisValue>>\n}> = {\n 'opt-in': {\n categoryErrors: [\n {\n rule: 'legal-basis-required',\n field: 'legalBasis',\n check: (c) => !c['legalBasis'],\n message: (id) => `Category \"${id}\" must have a legal basis set (Consent, Legitimate Interest, or Strictly Necessary) for GDPR compliance.`,\n },\n ],\n categoryWarnings: [\n {\n rule: 'legitimate-interest-balancing-test-recommended',\n field: 'legitimateInterestDescription',\n check: (c) => c['legalBasis'] === 'legitimate_interest' && !String(c['legitimateInterestDescription'] ?? '').trim(),\n message: (id) => `Category \"${id}\" relies on Legitimate Interest but has no balancing-test description. GDPR Art. 6(1)(f) requires you to conduct and be able to demonstrate a Legitimate Interests Assessment — note that Art. 5(3) ePrivacy still requires consent (LI cannot substitute) for the cookie storage/access itself, so this basis should only cover the downstream processing purpose, not the placement of a non-essential cookie.`,\n suggestion: 'Document your Legitimate Interests Assessment in the category\\'s \"Legitimate Interest Description\" field.',\n },\n ],\n cookieErrors: [],\n cookieWarnings: [\n {\n rule: 'pre-grant-opt-in-risk',\n field: 'preGrant',\n check: (c, legalBasis) => legalBasis === 'consent' && c['preGrant'] === true,\n message: (id) => `Parameter \"${id}\" is pre-granted, which may violate GDPR's opt-in requirement. Only use \"Pre Grant\" on custom profiles targeting jurisdictions where pre-granted consent is valid.`,\n suggestion: 'Disable \"Pre Grant\" unless this profile specifically targets a jurisdiction that permits pre-granted consent.',\n },\n ],\n },\n\n 'opt-out': {\n categoryErrors: [],\n categoryWarnings: [],\n cookieErrors: [],\n cookieWarnings: [\n {\n rule: 'gpc-recommended',\n field: 'listenGpc',\n check: (c, legalBasis) => legalBasis !== 'mandatory' && !c['listenGpc'],\n message: (id) => `Parameter \"${id}\" does not listen for the GPC signal. US state privacy laws require honoring GPC for opt-out of sale/sharing.`,\n suggestion: 'Enable \"Listen for GPC signal\" on this parameter.',\n },\n ],\n },\n\n 'opt-out-strict': {\n categoryErrors: [],\n categoryWarnings: [],\n cookieErrors: [\n {\n rule: 'cpra-category-required',\n field: 'cpraCategory',\n check: (c, legalBasis) => legalBasis !== 'mandatory' && !c['cpraCategory'],\n message: (id) => `Parameter \"${id}\" must have a CPRA category (Sale, Sharing, or Sensitive) assigned. Required under CPRA for all non-necessary parameters.`,\n },\n {\n rule: 'gpc-strict-required',\n field: 'listenGpc',\n check: (c) => (c['cpraCategory'] === 'sale' || c['cpraCategory'] === 'sharing') && !c['listenGpc'],\n message: (id) => `Parameter \"${id}\" is tagged Sale/Sharing but does not listen for the GPC signal. 11 CCR §7025 requires honoring GPC as a Do Not Sell/Share My Personal Information request for these parameters — this is mandatory, not optional.`,\n },\n ],\n cookieWarnings: [],\n },\n\n 'opt-in-dpdpa': {\n categoryErrors: [\n {\n rule: 'no-li-allowed',\n field: 'legalBasis',\n check: (c) => c['legalBasis'] === 'legitimate_interest',\n message: (id) => `Category \"${id}\" uses Legitimate Interest, which is not a valid legal basis under India's DPDPA. Use Consent or Strictly Necessary.`,\n },\n {\n rule: 'legal-basis-required',\n field: 'legalBasis',\n check: (c) => !c['legalBasis'],\n message: (id) => `Category \"${id}\" must have a legal basis set (Consent or Strictly Necessary) for DPDPA compliance.`,\n },\n ],\n categoryWarnings: [],\n cookieErrors: [],\n cookieWarnings: [\n {\n rule: 'pre-grant-opt-in-risk',\n field: 'preGrant',\n check: (c, legalBasis) => legalBasis === 'consent' && c['preGrant'] === true,\n message: (id) => `Parameter \"${id}\" is pre-granted, which may violate DPDPA's opt-in requirement. Only use \"Pre Grant\" on custom profiles targeting jurisdictions where pre-granted consent is valid.`,\n suggestion: 'Disable \"Pre Grant\" unless this profile specifically targets a jurisdiction that permits pre-granted consent.',\n },\n ],\n },\n\n 'opt-in-china': {\n categoryErrors: [\n {\n rule: 'no-li-allowed',\n field: 'legalBasis',\n check: (c) => c['legalBasis'] === 'legitimate_interest',\n message: (id) => `Category \"${id}\" uses Legitimate Interest, which is not one of PIPL Article 13's enumerated legal bases. Use Consent or Strictly Necessary.`,\n },\n {\n rule: 'legal-basis-required',\n field: 'legalBasis',\n check: (c) => !c['legalBasis'],\n message: (id) => `Category \"${id}\" must have a legal basis set for China PIPL compliance. Consent is the primary valid basis.`,\n },\n ],\n categoryWarnings: [],\n cookieErrors: [],\n cookieWarnings: [\n {\n rule: 'pre-grant-opt-in-risk',\n field: 'preGrant',\n check: (c, legalBasis) => legalBasis === 'consent' && c['preGrant'] === true,\n message: (id) => `Parameter \"${id}\" is pre-granted, which may violate PIPL's opt-in requirement. Only use \"Pre Grant\" on custom profiles targeting jurisdictions where pre-granted consent is valid.`,\n suggestion: 'Disable \"Pre Grant\" unless this profile specifically targets a jurisdiction that permits pre-granted consent.',\n },\n ],\n },\n\n 'opt-in-brazil': {\n categoryErrors: [\n {\n rule: 'legal-basis-required',\n field: 'legalBasis',\n check: (c) => !c['legalBasis'],\n message: (id) => `Category \"${id}\" must have a legal basis set. Brazil's LGPD requires one of ten legal bases; Consent or Legitimate Interest are most common for parameters.`,\n },\n ],\n categoryWarnings: [\n {\n rule: 'legitimate-interest-balancing-test-recommended',\n field: 'legitimateInterestDescription',\n check: (c) => c['legalBasis'] === 'legitimate_interest' && !String(c['legitimateInterestDescription'] ?? '').trim(),\n message: (id) => `Category \"${id}\" relies on Legitimate Interest but has no balancing-test description. LGPD Art. 10 requires the legitimate interest basis to be documented and, on request, made available to the ANPD as a Data Protection Impact Report (relatório de impacto).`,\n suggestion: 'Document your legitimate interest assessment in the category\\'s \"Legitimate Interest Description\" field.',\n },\n ],\n cookieErrors: [],\n cookieWarnings: [\n {\n rule: 'pre-grant-opt-in-risk',\n field: 'preGrant',\n check: (c, legalBasis) => legalBasis === 'consent' && c['preGrant'] === true,\n message: (id) => `Parameter \"${id}\" is pre-granted, which may violate LGPD's opt-in requirement. Only use \"Pre Grant\" on custom profiles targeting jurisdictions where pre-granted consent is valid.`,\n suggestion: 'Disable \"Pre Grant\" unless this profile specifically targets a jurisdiction that permits pre-granted consent.',\n },\n ],\n },\n\n 'general-privacy-consent': {\n categoryErrors: [],\n categoryWarnings: [\n {\n rule: 'legal-basis-recommended',\n field: 'legalBasis',\n check: (c) => !c['legalBasis'],\n message: (id) => `Category \"${id}\" has no legal basis documented. While a strict cookie banner may not be legally required in this jurisdiction, documenting legal basis is a privacy best practice.`,\n suggestion: 'Set a legal basis to improve compliance documentation and future-proof against stricter enforcement.',\n },\n {\n rule: 'legitimate-interest-balancing-test-recommended',\n field: 'legitimateInterestDescription',\n check: (c) => c['legalBasis'] === 'legitimate_interest' && !String(c['legitimateInterestDescription'] ?? '').trim(),\n message: (id) => `Category \"${id}\" relies on Legitimate Interest but has no balancing-test description documented. Most legitimate-interest-style bases in this jurisdiction group expect a documented justification, and it future-proofs the profile against stricter enforcement.`,\n suggestion: 'Document your legitimate interest justification in the category\\'s \"Legitimate Interest Description\" field.',\n },\n ],\n cookieErrors: [],\n cookieWarnings: [],\n },\n\n 'notice-only': {\n categoryErrors: [],\n categoryWarnings: [],\n cookieErrors: [],\n cookieWarnings: [],\n },\n}\n\n// ─── Embedded Jurisdiction → Compliance Group Map ─────────────────────────────\n// Version tag: update when regulations or mappings change materially.\n// HOW TO UPDATE: edit or add a country entry below. That is the ONLY file change needed.\n//\n// locales: BCP 47 tags for the most commonly used web/IT locales in that country.\n// Only well-supported, widely-used locales are listed. English-speaking countries\n// use 'en' (no country suffix). No country-specific English variants (en-XX) anywhere.\n\nexport interface ComplianceMap {\n version: string\n countries: Record<string, {\n name: string\n type: 'country'\n complianceGroup: ComplianceGroupId\n default: ComplianceGroupId\n description: string\n locales: readonly string[]\n compliance: readonly Compliance[]\n timezones: readonly string[]\n overriddenRegions?: Record<string, {\n name: string\n type: 'region'\n complianceGroup: ComplianceGroupId\n description: string\n /** When true, cookies tagged `cpraCategory: 'sensitive'` default to denied (opt-in) for\n * this region even though the rest of the group's cookies default to granted (opt-out\n * pre-grant) — a per-region carve-out layered on top of the group, not a group change. */\n requiresSensitiveOptIn?: boolean\n }>\n }>\n}\n\nexport const EMBEDDED_COMPLIANCE_MAP: ComplianceMap = {\n version: '2026-07',\n countries: {\n // ─── Europe — EU 27 ───────────────────────────────────────────────────────\n AT: { name: 'Austria', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Austria (GDPR)', locales: ['de-AT'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Vienna'] },\n BE: { name: 'Belgium', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Belgium (GDPR)', locales: ['nl-BE', 'fr-BE'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Brussels'] },\n BG: { name: 'Bulgaria', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Bulgaria (GDPR)', locales: ['bg-BG'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Sofia'] },\n HR: { name: 'Croatia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Croatia (GDPR)', locales: ['hr-HR'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Zagreb'] },\n CY: { name: 'Cyprus', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Cyprus (GDPR)', locales: ['el-CY'], compliance: ['gdpr', 'eprivacy'], timezones: ['Asia/Nicosia'] },\n CZ: { name: 'Czechia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Czechia (GDPR)', locales: ['cs-CZ'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Prague'] },\n DK: { name: 'Denmark', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Denmark (GDPR)', locales: ['da-DK'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Copenhagen'] },\n EE: { name: 'Estonia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Estonia (GDPR)', locales: ['et-EE'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Tallinn'] },\n FI: { name: 'Finland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Finland (GDPR)', locales: ['fi-FI'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Helsinki'] },\n FR: { name: 'France', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'France (GDPR)', locales: ['fr-FR'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Paris'] },\n DE: { name: 'Germany', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Germany (GDPR)', locales: ['de-DE'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Berlin'] },\n GR: { name: 'Greece', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Greece (GDPR)', locales: ['el-GR'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Athens'] },\n HU: { name: 'Hungary', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Hungary (GDPR)', locales: ['hu-HU'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Budapest'] },\n IE: { name: 'Ireland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Ireland (GDPR)', locales: ['en'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Dublin'] },\n IT: { name: 'Italy', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Italy (GDPR)', locales: ['it-IT'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Rome'] },\n LV: { name: 'Latvia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Latvia (GDPR)', locales: ['lv-LV'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Riga'] },\n LT: { name: 'Lithuania', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Lithuania (GDPR)', locales: ['lt-LT'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Vilnius'] },\n LU: { name: 'Luxembourg', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Luxembourg (GDPR)', locales: ['fr-LU', 'de-LU'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Luxembourg'] },\n MT: { name: 'Malta', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Malta (GDPR)', locales: ['mt-MT', 'en'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Malta'] },\n NL: { name: 'Netherlands', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Netherlands (GDPR)', locales: ['nl-NL'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Amsterdam'] },\n PL: { name: 'Poland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Poland (GDPR)', locales: ['pl-PL'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Warsaw'] },\n PT: { name: 'Portugal', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Portugal (GDPR)', locales: ['pt-PT'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Lisbon', 'Atlantic/Madeira', 'Atlantic/Azores'] },\n RO: { name: 'Romania', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Romania (GDPR)', locales: ['ro-RO'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Bucharest'] },\n SK: { name: 'Slovakia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Slovakia (GDPR)', locales: ['sk-SK'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Bratislava'] },\n SI: { name: 'Slovenia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Slovenia (GDPR)', locales: ['sl-SI'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Ljubljana'] },\n ES: { name: 'Spain', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Spain (GDPR)', locales: ['es-ES'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Madrid', 'Africa/Ceuta', 'Atlantic/Canary'] },\n SE: { name: 'Sweden', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Sweden (GDPR)', locales: ['sv-SE'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Stockholm'] },\n // ─── Europe — EEA non-EU ──────────────────────────────────────────────────\n IS: { name: 'Iceland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Iceland (GDPR via EEA)', locales: ['is-IS'], compliance: ['gdpr', 'eprivacy'], timezones: ['Atlantic/Reykjavik'] },\n LI: { name: 'Liechtenstein', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Liechtenstein (GDPR via EEA)', locales: ['de-LI'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Vaduz'] },\n NO: { name: 'Norway', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Norway (GDPR via EEA)', locales: ['nb-NO'], compliance: ['gdpr', 'eprivacy'], timezones: ['Europe/Oslo', 'Arctic/Longyearbyen'] },\n // ─── Europe — GDPR-aligned candidate/observer countries ──────────────────\n AD: { name: 'Andorra', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Andorra (GDPR-aligned)', locales: ['ca-AD'], compliance: ['gdpr'], timezones: ['Europe/Andorra'] },\n AL: { name: 'Albania', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Albania (GDPR-aligned)', locales: ['sq-AL'], compliance: ['gdpr'], timezones: ['Europe/Tirane'] },\n BA: { name: 'Bosnia and Herzegovina', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Bosnia and Herzegovina (GDPR-aligned)', locales: ['bs-BA', 'sr-Latn-BA'], compliance: ['gdpr'], timezones: ['Europe/Sarajevo'] },\n GG: { name: 'Guernsey', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Guernsey (DPA based on GDPR)', locales: ['en'], compliance: ['gdpr'], timezones: ['Europe/Guernsey'] },\n GI: { name: 'Gibraltar', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Gibraltar (DPA based on UK GDPR)', locales: ['en'], compliance: ['uk-gdpr'], timezones: ['Europe/Gibraltar'] },\n GL: { name: 'Greenland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Greenland (Danish GDPR implementation)', locales: ['da-GL'], compliance: ['gdpr'], timezones: ['America/Nuuk', 'America/Danmarkshavn', 'America/Scoresbysund', 'America/Thule'] },\n MC: { name: 'Monaco', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Monaco (GDPR-aligned)', locales: ['fr-MC'], compliance: ['gdpr'], timezones: ['Europe/Monaco'] },\n ME: { name: 'Montenegro', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Montenegro (GDPR-aligned)', locales: ['sr-Latn-ME'], compliance: ['gdpr'], timezones: ['Europe/Podgorica'] },\n MK: { name: 'North Macedonia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'North Macedonia (GDPR-aligned)', locales: ['mk-MK'], compliance: ['gdpr'], timezones: ['Europe/Skopje'] },\n RS: { name: 'Serbia', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Serbia (GDPR-aligned)', locales: ['sr-RS'], compliance: ['gdpr'], timezones: ['Europe/Belgrade'] },\n SM: { name: 'San Marino', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'San Marino (GDPR-aligned)', locales: ['it-SM'], compliance: ['gdpr'], timezones: ['Europe/San_Marino'] },\n TR: { name: 'Türkiye', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Türkiye (KVKK)', locales: ['tr-TR'], compliance: ['kvkk'], timezones: ['Europe/Istanbul'] },\n // ─── North America ────────────────────────────────────────────────────────\n CA: {\n name: 'Canada',\n type: 'country',\n complianceGroup: 'general-privacy-consent',\n default: 'general-privacy-consent',\n description: 'Canada (PIPEDA / Law 25)',\n locales: ['en', 'fr-CA'],\n compliance: ['pipeda', 'law25'],\n timezones: ['America/St_Johns', 'America/Halifax', 'America/Toronto', 'America/Winnipeg', 'America/Edmonton', 'America/Vancouver'],\n overriddenRegions: {\n QC: { name: 'Quebec', type: 'region', complianceGroup: 'opt-in', description: 'Quebec — Law 25 (GDPR-style opt-in)' },\n },\n },\n US: {\n name: 'United States',\n type: 'country',\n // complianceGroup: base when state known but has no specific law\n // default: used when state CANNOT be detected (use most strict = opt-out-strict)\n complianceGroup: 'opt-out',\n default: 'opt-out-strict',\n description: 'United States — opt-out-strict (CPRA) used when state cannot be detected',\n locales: ['en', 'es-US'],\n compliance: ['ccpa', 'cpra', 'vcdpa', 'cpa-co', 'ctdpa', 'ucpa', 'icdpa-ia', 'icdpa-in', 'tipa', 'mcdpa-mt', 'mcdpa-mn', 'ocpa', 'tdpsa', 'dpdpa-de', 'njdpa', 'nhpa', 'ndpa-ne', 'modpa', 'kcdpa', 'ridtpa'],\n timezones: ['America/New_York', 'America/Chicago', 'America/Denver', 'America/Phoenix', 'America/Los_Angeles', 'America/Anchorage', 'Pacific/Honolulu'],\n overriddenRegions: {\n CA: { name: 'California', type: 'region', complianceGroup: 'opt-out-strict', description: 'California — CPRA/CCPA' },\n VA: { name: 'Virginia', type: 'region', complianceGroup: 'opt-out', description: 'Virginia — VCDPA' },\n // requiresSensitiveOptIn: Colorado's CPA requires opt-in consent (not the group's\n // default opt-out pre-grant) for sensitive data specifically — mirrors CPRA's own\n // cpraCategory:'sensitive' carve-out, scoped to this one region rather than promoting\n // all of Colorado to the stricter 'opt-out-strict' group. Verify against current CPA\n // text/regulations before relying on this for a live deployment.\n CO: { name: 'Colorado', type: 'region', complianceGroup: 'opt-out', description: 'Colorado — CPA', requiresSensitiveOptIn: true },\n CT: { name: 'Connecticut', type: 'region', complianceGroup: 'opt-out', description: 'Connecticut — CTDPA' },\n UT: { name: 'Utah', type: 'region', complianceGroup: 'opt-out', description: 'Utah — UCPA' },\n TX: { name: 'Texas', type: 'region', complianceGroup: 'opt-out', description: 'Texas — TDPSA' },\n DE: { name: 'Delaware', type: 'region', complianceGroup: 'opt-out', description: 'Delaware — DPDPA' },\n NJ: { name: 'New Jersey', type: 'region', complianceGroup: 'opt-out', description: 'New Jersey — NJDPA' },\n OR: { name: 'Oregon', type: 'region', complianceGroup: 'opt-out', description: 'Oregon — OCPA' },\n MN: { name: 'Minnesota', type: 'region', complianceGroup: 'opt-out', description: 'Minnesota — MCDPA' },\n MD: { name: 'Maryland', type: 'region', complianceGroup: 'opt-out', description: 'Maryland — MODPA' },\n KY: { name: 'Kentucky', type: 'region', complianceGroup: 'opt-out', description: 'Kentucky — KCDPA' },\n TN: { name: 'Tennessee', type: 'region', complianceGroup: 'opt-out', description: 'Tennessee — TIPA' },\n NE: { name: 'Nebraska', type: 'region', complianceGroup: 'opt-out', description: 'Nebraska — NDPA' },\n IA: { name: 'Iowa', type: 'region', complianceGroup: 'opt-out', description: 'Iowa — ICDPA' },\n IN: { name: 'Indiana', type: 'region', complianceGroup: 'opt-out', description: 'Indiana — ICDPA' },\n MT: { name: 'Montana', type: 'region', complianceGroup: 'opt-out', description: 'Montana — MCDPA' },\n NH: { name: 'New Hampshire', type: 'region', complianceGroup: 'opt-out', description: 'New Hampshire — NHPA' },\n RI: { name: 'Rhode Island', type: 'region', complianceGroup: 'opt-out', description: 'Rhode Island — RIDTPA' },\n },\n },\n // ─── Latin America ────────────────────────────────────────────────────────\n AR: { name: 'Argentina', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Argentina (LPDP)', locales: ['es-AR'], compliance: ['lpdp-ar'], timezones: ['America/Argentina/Buenos_Aires'] },\n BO: { name: 'Bolivia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Bolivia', locales: ['es-BO'], compliance: [], timezones: ['America/La_Paz'] },\n BR: { name: 'Brazil', type: 'country', complianceGroup: 'opt-in-brazil', default: 'opt-in-brazil', description: 'Brazil (LGPD)', locales: ['pt-BR'], compliance: ['lgpd'], timezones: ['America/Noronha', 'America/Sao_Paulo', 'America/Manaus', 'America/Rio_Branco'] },\n CL: { name: 'Chile', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Chile (Law 19.628)', locales: ['es-CL'], compliance: ['law19628-cl'], timezones: ['America/Santiago', 'Pacific/Easter'] },\n CO: { name: 'Colombia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Colombia (Law 1581)', locales: ['es-CO'], compliance: ['law1581-co'], timezones: ['America/Bogota'] },\n CR: { name: 'Costa Rica', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Costa Rica (LPDP)', locales: ['es-CR'], compliance: ['lpdp-cr'], timezones: ['America/Costa_Rica'] },\n DO: { name: 'Dominican Republic', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Dominican Republic', locales: ['es-DO'], compliance: ['data-protection-do'], timezones: ['America/Santo_Domingo'] },\n EC: { name: 'Ecuador', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Ecuador (LOPDP)', locales: ['es-EC'], compliance: ['lopdp-ec'], timezones: ['America/Guayaquil', 'Pacific/Galapagos'] },\n GF: { name: 'French Guiana', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'French Guiana', locales: ['fr-GF'], compliance: [], timezones: ['America/Cayenne'] },\n GT: { name: 'Guatemala', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Guatemala', locales: ['es-GT'], compliance: [], timezones: ['America/Guatemala'] },\n GY: { name: 'Guyana', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Guyana', locales: ['en'], compliance: [], timezones: ['America/Guyana'] },\n HN: { name: 'Honduras', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Honduras', locales: ['es-HN'], compliance: [], timezones: ['America/Tegucigalpa'] },\n HT: { name: 'Haiti', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Haiti', locales: ['fr-HT'], compliance: [], timezones: ['America/Port-au-Prince'] },\n JM: { name: 'Jamaica', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Jamaica', locales: ['en'], compliance: [], timezones: ['America/Jamaica'] },\n MX: { name: 'Mexico', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Mexico (LFPDPPP)', locales: ['es-MX'], compliance: ['lfpdppp'], timezones: ['America/Mexico_City', 'America/Cancun', 'America/Chihuahua', 'America/Hermosillo', 'America/Tijuana'] },\n NI: { name: 'Nicaragua', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Nicaragua', locales: ['es-NI'], compliance: [], timezones: ['America/Managua'] },\n PA: { name: 'Panama', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Panama', locales: ['es-PA'], compliance: ['data-protection-pa'], timezones: ['America/Panama'] },\n PE: { name: 'Peru', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Peru (LPDP)', locales: ['es-PE'], compliance: ['lpdp-pe'], timezones: ['America/Lima'] },\n PY: { name: 'Paraguay', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Paraguay', locales: ['es-PY'], compliance: [], timezones: ['America/Asuncion'] },\n SR: { name: 'Suriname', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Suriname', locales: ['nl-SR'], compliance: [], timezones: ['America/Paramaribo'] },\n SV: { name: 'El Salvador', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'El Salvador', locales: ['es-SV'], compliance: [], timezones: ['America/El_Salvador'] },\n TT: { name: 'Trinidad and Tobago', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Trinidad and Tobago', locales: ['en'], compliance: [], timezones: ['America/Port_of_Spain'] },\n UY: { name: 'Uruguay', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Uruguay (Law 18.331)', locales: ['es-UY'], compliance: ['law18331-uy'], timezones: ['America/Montevideo'] },\n VE: { name: 'Venezuela', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Venezuela', locales: ['es-VE'], compliance: [], timezones: ['America/Caracas'] },\n // ─── Caribbean ────────────────────────────────────────────────────────────\n AG: { name: 'Antigua and Barbuda', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Antigua and Barbuda', locales: ['en'], compliance: [], timezones: ['America/Antigua'] },\n BB: { name: 'Barbados', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Barbados', locales: ['en'], compliance: [], timezones: ['America/Barbados'] },\n BL: { name: 'Saint Barthélemy', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Saint Barthélemy', locales: ['fr-BL'], compliance: [], timezones: ['America/St_Barthelemy'] },\n BM: { name: 'Bermuda', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Bermuda', locales: ['en'], compliance: [], timezones: ['Atlantic/Bermuda'] },\n BS: { name: 'Bahamas', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Bahamas', locales: ['en'], compliance: [], timezones: ['America/Nassau'] },\n CU: { name: 'Cuba', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Cuba', locales: ['es-CU'], compliance: [], timezones: ['America/Havana'] },\n DM: { name: 'Dominica', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Dominica', locales: ['en'], compliance: [], timezones: ['America/Dominica'] },\n GD: { name: 'Grenada', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Grenada', locales: ['en'], compliance: [], timezones: ['America/Grenada'] },\n KN: { name: 'Saint Kitts and Nevis', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Saint Kitts and Nevis', locales: ['en'], compliance: [], timezones: ['America/St_Kitts'] },\n LC: { name: 'Saint Lucia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Saint Lucia', locales: ['en'], compliance: [], timezones: ['America/St_Lucia'] },\n PM: { name: 'Saint Pierre and Miquelon', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Saint Pierre and Miquelon', locales: ['fr-PM'], compliance: [], timezones: ['America/Miquelon'] },\n PR: { name: 'Puerto Rico', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Puerto Rico', locales: ['es-PR', 'en'], compliance: [], timezones: ['America/Puerto_Rico'] },\n VC: { name: 'Saint Vincent and the Grenadines', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Saint Vincent and the Grenadines', locales: ['en'], compliance: [], timezones: ['America/St_Vincent'] },\n // ─── Asia — India ─────────────────────────────────────────────────────────\n IN: { name: 'India', type: 'country', complianceGroup: 'opt-in-dpdpa', default: 'opt-in-dpdpa', description: 'India (DPDPA)', locales: ['hi-IN', 'en', 'bn-IN', 'ta-IN'], compliance: ['dpdpa'], timezones: ['Asia/Kolkata', 'Asia/Calcutta'] },\n // ─── Asia — China ─────────────────────────────────────────────────────────\n CN: { name: 'China', type: 'country', complianceGroup: 'opt-in-china', default: 'opt-in-china', description: 'China (PIPL + DSL + CSL)', locales: ['zh-CN'], compliance: ['pipl', 'dsl-cn', 'csl-cn'], timezones: ['Asia/Shanghai'] },\n // ─── Asia — Southeast Asia ────────────────────────────────────────────────\n BN: { name: 'Brunei', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Brunei (Personal Data Protection Order)', locales: ['ms-BN', 'en'], compliance: ['privacy-bn'], timezones: ['Asia/Brunei'] },\n ID: { name: 'Indonesia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Indonesia (PDP Law)', locales: ['id-ID'], compliance: ['pdp-id'], timezones: ['Asia/Jakarta', 'Asia/Makassar', 'Asia/Jayapura'] },\n KH: { name: 'Cambodia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Cambodia', locales: ['km-KH'], compliance: [], timezones: ['Asia/Phnom_Penh'] },\n LA: { name: 'Laos', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Laos', locales: ['lo-LA'], compliance: [], timezones: ['Asia/Vientiane'] },\n MM: { name: 'Myanmar', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Myanmar', locales: ['my-MM'], compliance: [], timezones: ['Asia/Yangon'] },\n MY: { name: 'Malaysia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Malaysia (PDPA)', locales: ['ms-MY', 'zh-MY', 'en'], compliance: ['pdpa-my'], timezones: ['Asia/Kuala_Lumpur', 'Asia/Kuching'] },\n PH: { name: 'Philippines', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Philippines (DPA)', locales: ['fil-PH', 'en'], compliance: ['dpa-ph'], timezones: ['Asia/Manila'] },\n SG: { name: 'Singapore', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Singapore (PDPA)', locales: ['zh-SG', 'ms-SG', 'ta-SG', 'en'], compliance: ['pdpa-sg'], timezones: ['Asia/Singapore'] },\n TH: { name: 'Thailand', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Thailand (PDPA — GDPR-style opt-in)', locales: ['th-TH'], compliance: ['pdpa-th'], timezones: ['Asia/Bangkok'] },\n TL: { name: 'Timor-Leste', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Timor-Leste', locales: ['pt-TL'], compliance: [], timezones: ['Asia/Dili'] },\n VN: { name: 'Vietnam', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Vietnam (PDPD)', locales: ['vi-VN'], compliance: ['pdpd-vn'], timezones: ['Asia/Ho_Chi_Minh'] },\n // ─── Asia — East Asia ─────────────────────────────────────────────────────\n HK: { name: 'Hong Kong', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Hong Kong SAR (PDPO)', locales: ['zh-HK'], compliance: ['pdpl-hk'], timezones: ['Asia/Hong_Kong'] },\n JP: { name: 'Japan', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Japan (APPI)', locales: ['ja-JP'], compliance: ['appi'], timezones: ['Asia/Tokyo'] },\n KP: { name: 'North Korea', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'North Korea', locales: ['ko-KP'], compliance: [], timezones: ['Asia/Pyongyang'] },\n KR: { name: 'South Korea', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'South Korea (PIPA)', locales: ['ko-KR'], compliance: ['pipa-kr'], timezones: ['Asia/Seoul'] },\n MN: { name: 'Mongolia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Mongolia', locales: ['mn-MN'], compliance: [], timezones: ['Asia/Ulaanbaatar', 'Asia/Hovd'] },\n MO: { name: 'Macau', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Macau SAR (PDPA)', locales: ['zh-MO', 'pt-MO'], compliance: ['pdpa-mo'], timezones: ['Asia/Macau'] },\n TW: { name: 'Taiwan', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Taiwan (PDPL)', locales: ['zh-TW'], compliance: ['pdpl-tw'], timezones: ['Asia/Taipei'] },\n // ─── Asia — South Asia ────────────────────────────────────────────────────\n AF: { name: 'Afghanistan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Afghanistan', locales: ['fa-AF'], compliance: [], timezones: ['Asia/Kabul'] },\n BD: { name: 'Bangladesh', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Bangladesh', locales: ['bn-BD'], compliance: [], timezones: ['Asia/Dhaka'] },\n BT: { name: 'Bhutan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Bhutan', locales: ['dz-BT'], compliance: [], timezones: ['Asia/Thimphu'] },\n IO: { name: 'British Indian Ocean Territory', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'British Indian Ocean Territory', locales: ['en'], compliance: [], timezones: ['Indian/Chagos'] },\n LK: { name: 'Sri Lanka', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Sri Lanka', locales: ['si-LK', 'ta-LK'], compliance: ['privacy-lk'], timezones: ['Asia/Colombo'] },\n MV: { name: 'Maldives', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Maldives', locales: ['dv-MV'], compliance: [], timezones: ['Indian/Maldives'] },\n NP: { name: 'Nepal', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Nepal', locales: ['ne-NP'], compliance: ['privacy-np'], timezones: ['Asia/Kathmandu'] },\n PK: { name: 'Pakistan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Pakistan', locales: ['ur-PK', 'en'], compliance: [], timezones: ['Asia/Karachi'] },\n // ─── Asia — Central Asia ──────────────────────────────────────────────────\n AM: { name: 'Armenia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Armenia', locales: ['hy-AM'], compliance: [], timezones: ['Asia/Yerevan'] },\n AZ: { name: 'Azerbaijan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Azerbaijan', locales: ['az-AZ'], compliance: [], timezones: ['Asia/Baku'] },\n GE: { name: 'Georgia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Georgia', locales: ['ka-GE'], compliance: [], timezones: ['Asia/Tbilisi'] },\n KG: { name: 'Kyrgyzstan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Kyrgyzstan', locales: ['ky-KG', 'ru-KG'], compliance: [], timezones: ['Asia/Bishkek'] },\n KZ: { name: 'Kazakhstan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Kazakhstan', locales: ['kk-KZ', 'ru-KZ'], compliance: [], timezones: ['Asia/Almaty', 'Asia/Aqtobe'] },\n TJ: { name: 'Tajikistan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Tajikistan', locales: ['tg-TJ'], compliance: [], timezones: ['Asia/Dushanbe'] },\n TM: { name: 'Turkmenistan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Turkmenistan', locales: ['tk-TM'], compliance: [], timezones: ['Asia/Ashgabat'] },\n UZ: { name: 'Uzbekistan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Uzbekistan', locales: ['uz-UZ'], compliance: [], timezones: ['Asia/Tashkent', 'Asia/Samarkand'] },\n // ─── Middle East ──────────────────────────────────────────────────────────\n AE: { name: 'United Arab Emirates', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'United Arab Emirates (UAE PDPL / DIFC DPL / ADGM DPR)', locales: ['ar-AE'], compliance: ['uae-pdpl', 'difc-dpl', 'adgm-dpr'], timezones: ['Asia/Dubai'] },\n BH: { name: 'Bahrain', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Bahrain (PDPL)', locales: ['ar-BH'], compliance: ['pdpl-bh'], timezones: ['Asia/Bahrain'] },\n IL: { name: 'Israel', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Israel (Privacy Protection Law)', locales: ['he-IL', 'ar-IL'], compliance: ['privacy-il'], timezones: ['Asia/Jerusalem'] },\n IQ: { name: 'Iraq', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Iraq', locales: ['ar-IQ'], compliance: [], timezones: ['Asia/Baghdad'] },\n IR: { name: 'Iran', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Iran', locales: ['fa-IR'], compliance: [], timezones: ['Asia/Tehran'] },\n JO: { name: 'Jordan', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Jordan', locales: ['ar-JO'], compliance: [], timezones: ['Asia/Amman'] },\n KW: { name: 'Kuwait', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Kuwait', locales: ['ar-KW'], compliance: ['privacy-kw'], timezones: ['Asia/Kuwait'] },\n LB: { name: 'Lebanon', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Lebanon', locales: ['ar-LB'], compliance: [], timezones: ['Asia/Beirut'] },\n OM: { name: 'Oman', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Oman (PDPL)', locales: ['ar-OM'], compliance: ['pdpl-om'], timezones: ['Asia/Muscat'] },\n PS: { name: 'Palestine', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Palestine', locales: ['ar-PS'], compliance: [], timezones: ['Asia/Gaza', 'Asia/Hebron'] },\n QA: { name: 'Qatar', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Qatar (PDPL)', locales: ['ar-QA'], compliance: ['qpdl-qa'], timezones: ['Asia/Qatar'] },\n SA: { name: 'Saudi Arabia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Saudi Arabia (PDPL)', locales: ['ar-SA'], compliance: ['pdpl-sa'], timezones: ['Asia/Riyadh'] },\n SY: { name: 'Syria', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Syria', locales: ['ar-SY'], compliance: [], timezones: ['Asia/Damascus'] },\n YE: { name: 'Yemen', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Yemen', locales: ['ar-YE'], compliance: [], timezones: ['Asia/Aden'] },\n // ─── Africa — West ────────────────────────────────────────────────────────\n BF: { name: 'Burkina Faso', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Burkina Faso', locales: ['fr-BF'], compliance: [], timezones: ['Africa/Ouagadougou'] },\n BJ: { name: 'Benin', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Benin', locales: ['fr-BJ'], compliance: [], timezones: ['Africa/Porto-Novo'] },\n CI: { name: \"Côte d'Ivoire\", type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: \"Côte d'Ivoire\", locales: ['fr-CI'], compliance: [], timezones: ['Africa/Abidjan'] },\n CM: { name: 'Cameroon', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Cameroon', locales: ['fr-CM', 'en'], compliance: [], timezones: ['Africa/Douala'] },\n CV: { name: 'Cabo Verde', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Cabo Verde', locales: ['pt-CV'], compliance: [], timezones: ['Atlantic/Cape_Verde'] },\n GA: { name: 'Gabon', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Gabon', locales: ['fr-GA'], compliance: [], timezones: ['Africa/Libreville'] },\n GH: { name: 'Ghana', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Ghana (DPA)', locales: ['en'], compliance: ['dpa-gh'], timezones: ['Africa/Accra'] },\n GM: { name: 'Gambia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Gambia', locales: ['en'], compliance: [], timezones: ['Africa/Banjul'] },\n GN: { name: 'Guinea', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Guinea', locales: ['fr-GN'], compliance: [], timezones: ['Africa/Conakry'] },\n GQ: { name: 'Equatorial Guinea', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Equatorial Guinea', locales: ['es-GQ', 'fr-GQ'], compliance: [], timezones: ['Africa/Malabo'] },\n GW: { name: 'Guinea-Bissau', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Guinea-Bissau', locales: ['pt-GW'], compliance: [], timezones: ['Africa/Bissau'] },\n LR: { name: 'Liberia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Liberia', locales: ['en'], compliance: [], timezones: ['Africa/Monrovia'] },\n ML: { name: 'Mali', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Mali', locales: ['fr-ML'], compliance: [], timezones: ['Africa/Bamako'] },\n MR: { name: 'Mauritania', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Mauritania', locales: ['ar-MR'], compliance: [], timezones: ['Africa/Nouakchott'] },\n NE: { name: 'Niger', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Niger', locales: ['fr-NE'], compliance: [], timezones: ['Africa/Niamey'] },\n NG: { name: 'Nigeria', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Nigeria (NDPA)', locales: ['en'], compliance: ['ndpa-ng'], timezones: ['Africa/Lagos'] },\n SL: { name: 'Sierra Leone', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Sierra Leone', locales: ['en'], compliance: [], timezones: ['Africa/Freetown'] },\n SN: { name: 'Senegal', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Senegal', locales: ['fr-SN'], compliance: [], timezones: ['Africa/Dakar'] },\n TG: { name: 'Togo', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Togo', locales: ['fr-TG'], compliance: [], timezones: ['Africa/Lome'] },\n // ─── Africa — East ────────────────────────────────────────────────────────\n BI: { name: 'Burundi', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Burundi', locales: ['fr-BI'], compliance: [], timezones: ['Africa/Bujumbura'] },\n DJ: { name: 'Djibouti', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Djibouti', locales: ['fr-DJ', 'ar-DJ'], compliance: [], timezones: ['Africa/Djibouti'] },\n ER: { name: 'Eritrea', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Eritrea', locales: ['ti-ER'], compliance: [], timezones: ['Africa/Asmara'] },\n ET: { name: 'Ethiopia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Ethiopia', locales: ['am-ET'], compliance: [], timezones: ['Africa/Addis_Ababa'] },\n KE: { name: 'Kenya', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Kenya (DPA)', locales: ['sw-KE', 'en'], compliance: ['dpa-ke'], timezones: ['Africa/Nairobi'] },\n KM: { name: 'Comoros', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Comoros', locales: ['ar-KM', 'fr-KM'], compliance: [], timezones: ['Indian/Comoro'] },\n MG: { name: 'Madagascar', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Madagascar', locales: ['fr-MG'], compliance: [], timezones: ['Indian/Antananarivo'] },\n MU: { name: 'Mauritius', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Mauritius (DPA)', locales: ['en', 'fr-MU'], compliance: ['dpa-mu'], timezones: ['Indian/Mauritius'] },\n MW: { name: 'Malawi', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Malawi', locales: ['en'], compliance: [], timezones: ['Africa/Blantyre'] },\n MZ: { name: 'Mozambique', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Mozambique', locales: ['pt-MZ'], compliance: [], timezones: ['Africa/Maputo'] },\n RW: { name: 'Rwanda', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Rwanda (DPA)', locales: ['rw-RW', 'en'], compliance: ['dpa-rw'], timezones: ['Africa/Kigali'] },\n SC: { name: 'Seychelles', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Seychelles', locales: ['fr-SC', 'en'], compliance: [], timezones: ['Indian/Mahe'] },\n SO: { name: 'Somalia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Somalia', locales: ['so-SO'], compliance: [], timezones: ['Africa/Mogadishu'] },\n SS: { name: 'South Sudan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'South Sudan', locales: ['en'], compliance: [], timezones: ['Africa/Juba'] },\n ST: { name: 'São Tomé and Príncipe', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'São Tomé and Príncipe', locales: ['pt-ST'], compliance: [], timezones: ['Africa/Sao_Tome'] },\n TZ: { name: 'Tanzania', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Tanzania', locales: ['sw-TZ', 'en'], compliance: [], timezones: ['Africa/Dar_es_Salaam'] },\n UG: { name: 'Uganda', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Uganda (DPA)', locales: ['en'], compliance: ['dpa-ug'], timezones: ['Africa/Kampala'] },\n // ─── Africa — Southern ────────────────────────────────────────────────────\n AO: { name: 'Angola', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Angola', locales: ['pt-AO'], compliance: [], timezones: ['Africa/Luanda'] },\n BW: { name: 'Botswana', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Botswana (DPA)', locales: ['en'], compliance: ['dpa-bw'], timezones: ['Africa/Gaborone'] },\n LS: { name: 'Lesotho', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Lesotho', locales: ['en'], compliance: [], timezones: ['Africa/Maseru'] },\n NA: { name: 'Namibia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Namibia', locales: ['en'], compliance: [], timezones: ['Africa/Windhoek'] },\n SZ: { name: 'Eswatini', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Eswatini', locales: ['en'], compliance: [], timezones: ['Africa/Mbabane'] },\n ZA: { name: 'South Africa', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'South Africa (POPIA)', locales: ['en', 'af-ZA'], compliance: ['popia'], timezones: ['Africa/Johannesburg'] },\n ZM: { name: 'Zambia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Zambia (DPA)', locales: ['en'], compliance: ['dpa-zm'], timezones: ['Africa/Lusaka'] },\n ZW: { name: 'Zimbabwe', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Zimbabwe (DPA)', locales: ['en'], compliance: ['dpa-zw'], timezones: ['Africa/Harare'] },\n // ─── Africa — North ───────────────────────────────────────────────────────\n DZ: { name: 'Algeria', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Algeria', locales: ['ar-DZ', 'fr-DZ'], compliance: ['dpa-dz'], timezones: ['Africa/Algiers'] },\n EG: { name: 'Egypt', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Egypt (DPA)', locales: ['ar-EG'], compliance: ['dpa-eg'], timezones: ['Africa/Cairo'] },\n LY: { name: 'Libya', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Libya', locales: ['ar-LY'], compliance: [], timezones: ['Africa/Tripoli'] },\n MA: { name: 'Morocco', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Morocco', locales: ['ar-MA', 'fr-MA'], compliance: ['dpa-ma'], timezones: ['Africa/Casablanca'] },\n SD: { name: 'Sudan', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Sudan', locales: ['ar-SD'], compliance: [], timezones: ['Africa/Khartoum'] },\n TN: { name: 'Tunisia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Tunisia (DPA)', locales: ['ar-TN', 'fr-TN'], compliance: ['dpa-tn'], timezones: ['Africa/Tunis'] },\n // ─── Africa — Central ─────────────────────────────────────────────────────\n CD: { name: 'DR Congo', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'DR Congo', locales: ['fr-CD'], compliance: [], timezones: ['Africa/Kinshasa', 'Africa/Lubumbashi'] },\n CF: { name: 'Central African Republic', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Central African Republic', locales: ['fr-CF'], compliance: [], timezones: ['Africa/Bangui'] },\n CG: { name: 'Republic of Congo', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Republic of Congo', locales: ['fr-CG'], compliance: [], timezones: ['Africa/Brazzaville'] },\n TD: { name: 'Chad', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Chad', locales: ['fr-TD', 'ar-TD'], compliance: [], timezones: ['Africa/Ndjamena'] },\n // ─── Europe — Eastern ─────────────────────────────────────────────────────\n BY: { name: 'Belarus', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Belarus', locales: ['be-BY', 'ru-BY'], compliance: [], timezones: ['Europe/Minsk'] },\n MD: { name: 'Moldova', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Moldova', locales: ['ro-MD'], compliance: [], timezones: ['Europe/Chisinau'] },\n RU: { name: 'Russia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Russia', locales: ['ru-RU'], compliance: [], timezones: ['Europe/Kaliningrad', 'Europe/Moscow', 'Europe/Samara', 'Asia/Yekaterinburg', 'Asia/Omsk', 'Asia/Krasnoyarsk', 'Asia/Irkutsk', 'Asia/Yakutsk', 'Asia/Vladivostok', 'Asia/Magadan', 'Asia/Kamchatka'] },\n UA: { name: 'Ukraine', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Ukraine', locales: ['uk-UA'], compliance: [], timezones: ['Europe/Kyiv'] },\n VA: { name: 'Holy See', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Holy See', locales: ['it-VA'], compliance: [], timezones: ['Europe/Vatican'] },\n // ─── Oceania ──────────────────────────────────────────────────────────────\n AU: { name: 'Australia', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'Australia (Privacy Act)', locales: ['en'], compliance: ['privacy-au'], timezones: ['Australia/Sydney', 'Australia/Brisbane', 'Australia/Adelaide', 'Australia/Darwin', 'Australia/Perth', 'Australia/Hobart'] },\n FJ: { name: 'Fiji', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Fiji', locales: ['en'], compliance: ['privacy-fj'], timezones: ['Pacific/Fiji'] },\n FM: { name: 'Micronesia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Micronesia', locales: ['en'], compliance: [], timezones: ['Pacific/Chuuk', 'Pacific/Pohnpei', 'Pacific/Kosrae'] },\n KI: { name: 'Kiribati', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Kiribati', locales: ['en'], compliance: [], timezones: ['Pacific/Tarawa', 'Pacific/Enderbury', 'Pacific/Kiritimati'] },\n MH: { name: 'Marshall Islands', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Marshall Islands', locales: ['en'], compliance: [], timezones: ['Pacific/Majuro', 'Pacific/Kwajalein'] },\n MP: { name: 'Northern Mariana Islands', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Northern Mariana Islands', locales: ['en'], compliance: [], timezones: ['Pacific/Saipan'] },\n NC: { name: 'New Caledonia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'New Caledonia', locales: ['fr-NC'], compliance: [], timezones: ['Pacific/Noumea'] },\n NF: { name: 'Norfolk Island', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Norfolk Island', locales: ['en'], compliance: [], timezones: ['Pacific/Norfolk'] },\n NR: { name: 'Nauru', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Nauru', locales: ['en'], compliance: [], timezones: ['Pacific/Nauru'] },\n NU: { name: 'Niue', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Niue', locales: ['en'], compliance: [], timezones: ['Pacific/Niue'] },\n NZ: { name: 'New Zealand', type: 'country', complianceGroup: 'general-privacy-consent', default: 'general-privacy-consent', description: 'New Zealand (Privacy Act)', locales: ['en'], compliance: ['privacy-nz'], timezones: ['Pacific/Auckland', 'Pacific/Chatham'] },\n PF: { name: 'French Polynesia', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'French Polynesia', locales: ['fr-PF'], compliance: [], timezones: ['Pacific/Tahiti', 'Pacific/Marquesas', 'Pacific/Gambier'] },\n PG: { name: 'Papua New Guinea', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Papua New Guinea', locales: ['en'], compliance: ['privacy-pg'], timezones: ['Pacific/Port_Moresby', 'Pacific/Bougainville'] },\n PW: { name: 'Palau', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Palau', locales: ['en'], compliance: [], timezones: ['Pacific/Palau'] },\n SB: { name: 'Solomon Islands', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Solomon Islands', locales: ['en'], compliance: [], timezones: ['Pacific/Guadalcanal'] },\n TO: { name: 'Tonga', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Tonga', locales: ['en'], compliance: [], timezones: ['Pacific/Tongatapu'] },\n TV: { name: 'Tuvalu', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Tuvalu', locales: ['en'], compliance: [], timezones: ['Pacific/Funafuti'] },\n VU: { name: 'Vanuatu', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Vanuatu', locales: ['fr-VU', 'en'], compliance: [], timezones: ['Pacific/Efate'] },\n WS: { name: 'Samoa', type: 'country', complianceGroup: 'notice-only', default: 'notice-only', description: 'Samoa', locales: ['en'], compliance: [], timezones: ['Pacific/Apia'] },\n // ─── Europe — GDPR-equivalent / adequacy ─────────────────────────────────\n UK: { name: 'United Kingdom', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'United Kingdom (UK GDPR + PECR)', locales: ['en'], compliance: ['uk-gdpr', 'pecr'], timezones: ['Europe/London'] },\n CH: { name: 'Switzerland', type: 'country', complianceGroup: 'opt-in', default: 'opt-in', description: 'Switzerland (revFADP)', locales: ['de-CH', 'fr-CH', 'it-CH'], compliance: ['revfadp'], timezones: ['Europe/Zurich'] },\n },\n}\n\n/** Geo providers, the timezone table and BCP 47 tags all use ISO `GB`; the map has always keyed the\n * United Kingdom as `UK`. Bridged at lookup time (rather than by duplicating the entry) so the\n * country still appears once in listings, and operator-supplied `complianceMap`s keyed either way work. */\nconst COUNTRY_CODE_ALIASES: Readonly<Record<string, string>> = { GB: 'UK', UK: 'GB' }\n\nexport function findCountryEntry<T>(countries: Readonly<Record<string, T>>, code: string): T | undefined {\n const alias = COUNTRY_CODE_ALIASES[code]\n return countries[code] ?? (alias !== undefined ? countries[alias] : undefined)\n}\n\nexport const COMPLIANCE_REGULATION_IDS: string[] =[...Object.values(EMBEDDED_COMPLIANCE_MAP.countries).reduce((acc, country) => {\n country.compliance.forEach((c: string) => {\n acc.add(c)\n })\n\n return acc\n}, new Set<string>())]\n\n// Local alias for the shape checks below. The public `Compliance` type\n// (derived from the same array) is re-exported from @consenti/types.\ntype Compliance = typeof COMPLIANCE_REGULATION_IDS[number]\n\nexport const COUNTRY_CODES = Object.entries(EMBEDDED_COMPLIANCE_MAP.countries).reduce(function (acc, [c, d]) {\n acc[c] = d.name;\n return acc;\n}, {} as Record<string, string>);\n\nexport const LOCALES = Object.values(EMBEDDED_COMPLIANCE_MAP.countries).reduce(function (acc, c) {\n c.locales.forEach(l => {\n acc[l] = c.name;\n })\n return acc;\n}, {} as Record<string, string>);\n\n// ─── compliance.complianceMap override resolution ─────────────────────────────\n// Shared by apps/api (GeoResolverService) and apps/ui (profile-resolver, standalone mode\n// only). Defined structurally here (not imported from @consenti/types) to avoid a circular\n// package dependency — @consenti/types already imports its ComplianceGroupId et al. from this\n// file, so this file cannot import back from @consenti/types.\n\n/** `complianceGroup`/`default` are `string` here (not the `ComplianceGroupId` literal union) —\n * that union isn't exported from this module (it lives in `@consenti/types`, which itself\n * imports from this file, so importing it back here would be circular); runtime validation\n * (`isComplianceMapData`) is the actual safety net for operator-supplied data. */\nexport interface ComplianceMapCountryEntry {\n complianceGroup: string\n default?: string\n description?: string\n overriddenRegions?: Record<string, { complianceGroup: string; description?: string; requiresSensitiveOptIn?: boolean }>\n}\n\nexport interface ComplianceMapData {\n version: string\n /** `true` (default): this map replaces the embedded one entirely, so only the countries listed here\n * resolve (server side). `false`: `countries` is merged over the embedded map — a listed country\n * replaces its embedded entry wholesale, every unlisted country keeps its built-in mapping. */\n override?: boolean\n countries: Record<string, ComplianceMapCountryEntry>\n}\n\nexport interface ComplianceMapResolution {\n map: ComplianceMapData | typeof EMBEDDED_COMPLIANCE_MAP\n /** Set only when `override` was a URL — lets callers inspect `Cache-Control`/`Expires` to\n * schedule their own background refresh. Not meaningful for the `'default'`/object cases. */\n response?: Response\n}\n\nfunction isComplianceMapData(data: unknown): data is ComplianceMapData {\n if (!data || typeof data !== 'object') return false\n const d = data as Record<string, unknown>\n if (typeof d['version'] !== 'string') return false\n if (d['override'] !== undefined && typeof d['override'] !== 'boolean') return false\n const countries = d['countries']\n if (!countries || typeof countries !== 'object') return false\n return Object.values(countries as Record<string, unknown>).every((entry) =>\n !!entry && typeof entry === 'object' && typeof (entry as Record<string, unknown>)['complianceGroup'] === 'string'\n )\n}\n\n/**\n * Resolves a `compliance.complianceMap` config value into actual map data.\n *\n * `'default'`/`undefined` → the embedded map, no network access. A `string` is treated as a\n * URL and fetched as-is (no custom `cache` mode — the platform's own fetch/HTTP-cache semantics\n * apply). A plain object is used directly. Either replaces the embedded map, or is merged over it\n * when the document sets `override: false` (see `ComplianceMapData.override`). Any failure (network error, bad JSON, failed\n * structural validation) reports via `onWarn` and falls back to the embedded map — this never\n * throws. Also warns when a country defines `overriddenRegions` but no explicit `default`,\n * since the effective fallback (`complianceGroup`) may under-comply for regions not listed.\n *\n * Does not do any caching/scheduling — that's platform-specific (Node vs. browser) and is the\n * caller's responsibility.\n */\nexport async function resolveComplianceMapOverride(\n override: 'default' | string | ComplianceMapData | undefined,\n onWarn: (message: string) => void,\n): Promise<ComplianceMapResolution> {\n const fallback: ComplianceMapResolution = { map: EMBEDDED_COMPLIANCE_MAP }\n\n if (override === undefined || override === 'default') return fallback\n\n let candidate: unknown\n let response: Response | undefined\n\n if (typeof override === 'string') {\n try {\n response = await fetch(override)\n if (!response.ok) {\n onWarn(`compliance.complianceMap fetch from \"${override}\" failed (HTTP ${response.status}) — falling back to the embedded map.`)\n return fallback\n }\n candidate = await response.json()\n } catch (err) {\n onWarn(`compliance.complianceMap fetch from \"${override}\" failed (${err instanceof Error ? err.message : String(err)}) — falling back to the embedded map.`)\n return fallback\n }\n } else {\n candidate = override\n }\n\n if (!isComplianceMapData(candidate)) {\n onWarn(`compliance.complianceMap ${typeof override === 'string' ? `at \"${override}\"` : 'object'} failed validation — falling back to the embedded map.`)\n return fallback\n }\n\n for (const [code, entry] of Object.entries(candidate.countries)) {\n if (entry.overriddenRegions && entry.default === undefined) {\n onWarn(`compliance.complianceMap country \"${code}\" has overriddenRegions but no explicit default — falling back to complianceGroup (\"${entry.complianceGroup}\"), which may under-comply for regions not listed.`)\n }\n }\n\n const result: ComplianceMapResolution = { map: candidate.override === false ? mergeOverEmbedded(candidate) : candidate }\n if (response) result.response = response\n return result\n}\n\n/** Country-level merge: an operator entry replaces the embedded entry for that country wholesale\n * (never deep-merged — `default`, `overriddenRegions` and `requiresSensitiveOptIn` are one legal unit,\n * so inheriting embedded state carve-outs the operator didn't write would be a silent surprise).\n * `GB`/`UK` are one country: an operator entry under either key displaces the embedded entry\n * stored under the other, unless the operator defined both. */\nfunction mergeOverEmbedded(candidate: ComplianceMapData): ComplianceMapData {\n const countries: Record<string, ComplianceMapCountryEntry> = { ...EMBEDDED_COMPLIANCE_MAP.countries }\n for (const code of Object.keys(candidate.countries)) {\n const alias = COUNTRY_CODE_ALIASES[code]\n if (alias !== undefined && !(alias in candidate.countries)) delete countries[alias]\n }\n Object.assign(countries, candidate.countries)\n return { version: candidate.version, countries }\n}\n","import { COOKIE_PURPOSE_IDS } from \"./compliance.js\";\n\ntype CookiePurpose = typeof COOKIE_PURPOSE_IDS[number];\n\n/**\n * Curated, community-extendable dataset of common non-IAB tracker cookie/storage key names.\n * Not attempting to rival a crawler-fed proprietary vendor database (that's the job of\n * `@consenti/enterprise-tools`'s scanner) — this is a small, hand-maintained list covering the\n * trackers most self-hosted sites actually use, to save admins from guessing a category when\n * defining a cookie parameter by hand.\n */\nexport interface TrackerKnowledgeEntry {\n /** Exact cookie/storage key name, or a prefix ending in \"*\" for variable-suffix names\n * (e.g. GA4's per-property `_ga_<container-id>`). */\n pattern: string;\n vendor: string;\n category: CookiePurpose;\n}\n\nexport const TRACKER_KNOWLEDGE_BASE: TrackerKnowledgeEntry[] = [\n // Google Consent Mode v2 — canonical parameter names, must match KNOWN_COOKIE_PURPOSES in compliance.ts\n { pattern: \"security_storage\", vendor: \"Google Consent Mode v2\", category: \"necessary\" },\n { pattern: \"functionality_storage\", vendor: \"Google Consent Mode v2\", category: \"functional\" },\n { pattern: \"personalization_storage\", vendor: \"Google Consent Mode v2\", category: \"preferences\" },\n { pattern: \"analytics_storage\", vendor: \"Google Consent Mode v2\", category: \"analytics\" },\n { pattern: \"ad_storage\", vendor: \"Google Consent Mode v2\", category: \"marketing\" },\n { pattern: \"ad_user_data\", vendor: \"Google Consent Mode v2\", category: \"marketing\" },\n { pattern: \"ad_personalization\", vendor: \"Google Consent Mode v2\", category: \"marketing\" },\n // Google Analytics 4 / Universal Analytics\n { pattern: \"_ga\", vendor: \"Google Analytics\", category: \"analytics\" },\n { pattern: \"_ga_*\", vendor: \"Google Analytics 4\", category: \"analytics\" },\n { pattern: \"_gid\", vendor: \"Google Analytics\", category: \"analytics\" },\n { pattern: \"_gat\", vendor: \"Google Analytics\", category: \"analytics\" },\n { pattern: \"_gat_*\", vendor: \"Google Analytics\", category: \"analytics\" },\n // Google Ads\n { pattern: \"_gcl_au\", vendor: \"Google Ads\", category: \"marketing\" },\n { pattern: \"_gac_*\", vendor: \"Google Ads\", category: \"marketing\" },\n { pattern: \"_gcl_aw\", vendor: \"Google Ads\", category: \"marketing\" },\n // Meta / Facebook Pixel\n { pattern: \"_fbp\", vendor: \"Meta Pixel\", category: \"marketing\" },\n { pattern: \"_fbc\", vendor: \"Meta Pixel\", category: \"marketing\" },\n { pattern: \"fr\", vendor: \"Meta Pixel\", category: \"marketing\" },\n // Hotjar\n { pattern: \"_hjSessionUser_*\", vendor: \"Hotjar\", category: \"analytics\" },\n { pattern: \"_hjSession_*\", vendor: \"Hotjar\", category: \"analytics\" },\n { pattern: \"_hjid\", vendor: \"Hotjar\", category: \"analytics\" },\n { pattern: \"hjViewportId\", vendor: \"Hotjar\", category: \"analytics\" },\n // Segment\n { pattern: \"ajs_user_id\", vendor: \"Segment\", category: \"analytics\" },\n { pattern: \"ajs_anonymous_id\", vendor: \"Segment\", category: \"analytics\" },\n { pattern: \"ajs_group_id\", vendor: \"Segment\", category: \"analytics\" },\n // Intercom\n { pattern: \"intercom-id-*\", vendor: \"Intercom\", category: \"functional\" },\n { pattern: \"intercom-session-*\", vendor: \"Intercom\", category: \"functional\" },\n { pattern: \"intercom-device-id-*\", vendor: \"Intercom\", category: \"functional\" },\n // HubSpot\n { pattern: \"__hstc\", vendor: \"HubSpot\", category: \"marketing\" },\n { pattern: \"hubspotutk\", vendor: \"HubSpot\", category: \"marketing\" },\n { pattern: \"__hssc\", vendor: \"HubSpot\", category: \"marketing\" },\n { pattern: \"__hssrc\", vendor: \"HubSpot\", category: \"marketing\" },\n // Mixpanel\n { pattern: \"mp_*\", vendor: \"Mixpanel\", category: \"analytics\" },\n // LinkedIn Insight Tag\n { pattern: \"li_sugr\", vendor: \"LinkedIn Insight\", category: \"marketing\" },\n { pattern: \"bcookie\", vendor: \"LinkedIn Insight\", category: \"marketing\" },\n { pattern: \"lidc\", vendor: \"LinkedIn Insight\", category: \"marketing\" },\n { pattern: \"UserMatchHistory\", vendor: \"LinkedIn Insight\", category: \"marketing\" },\n // TikTok Pixel\n { pattern: \"_ttp\", vendor: \"TikTok Pixel\", category: \"marketing\" },\n // Microsoft Clarity\n { pattern: \"_clck\", vendor: \"Microsoft Clarity\", category: \"analytics\" },\n { pattern: \"_clsk\", vendor: \"Microsoft Clarity\", category: \"analytics\" },\n // Pinterest Tag\n { pattern: \"_pinterest_ct*\", vendor: \"Pinterest Tag\", category: \"marketing\" },\n { pattern: \"_pin_unauth\", vendor: \"Pinterest Tag\", category: \"marketing\" },\n // X (Twitter) Pixel\n { pattern: \"personalization_id\", vendor: \"X (Twitter) Pixel\", category: \"marketing\" },\n // Amplitude\n { pattern: \"amplitude_id_*\", vendor: \"Amplitude\", category: \"analytics\" },\n // Stripe (payment fraud prevention — necessary, not marketing)\n { pattern: \"__stripe_mid\", vendor: \"Stripe\", category: \"necessary\" },\n { pattern: \"__stripe_sid\", vendor: \"Stripe\", category: \"necessary\" },\n // Cloudflare bot management (necessary — security)\n { pattern: \"__cf_bm\", vendor: \"Cloudflare\", category: \"necessary\" },\n { pattern: \"cf_clearance\", vendor: \"Cloudflare\", category: \"necessary\" },\n // Zendesk\n { pattern: \"_zendesk_*\", vendor: \"Zendesk\", category: \"functional\" },\n // Drift\n { pattern: \"drift_aid\", vendor: \"Drift\", category: \"functional\" },\n { pattern: \"driftt_aid\", vendor: \"Drift\", category: \"functional\" },\n // Crisp\n { pattern: \"crisp-client*\", vendor: \"Crisp\", category: \"functional\" },\n\n // --- MEGA EXPANSION PACK ---\n\n // Adobe Experience Cloud (Analytics, Marketo, Target)\n { pattern: \"AMCV_*\", vendor: \"Adobe Experience Cloud\", category: \"analytics\" },\n { pattern: \"AMCVS_*\", vendor: \"Adobe Experience Cloud\", category: \"analytics\" },\n { pattern: \"s_cc\", vendor: \"Adobe Analytics\", category: \"analytics\" },\n { pattern: \"s_sq\", vendor: \"Adobe Analytics\", category: \"analytics\" },\n { pattern: \"s_vi\", vendor: \"Adobe Analytics\", category: \"analytics\" },\n { pattern: \"mbox\", vendor: \"Adobe Target\", category: \"preferences\" },\n { pattern: \"_mkto_trk\", vendor: \"Marketo\", category: \"marketing\" },\n\n // Programmatic Ad Exchanges & DSPs\n { pattern: \"cto_bundle\", vendor: \"Criteo\", category: \"marketing\" },\n { pattern: \"cto_id_out\", vendor: \"Criteo\", category: \"marketing\" },\n { pattern: \"TTD_DEVICE_ID\", vendor: \"The Trade Desk\", category: \"marketing\" },\n { pattern: \"ttd_*\", vendor: \"The Trade Desk\", category: \"marketing\" },\n { pattern: \"id\", vendor: \"Google DoubleClick\", category: \"marketing\" },\n { pattern: \"IDE\", vendor: \"Google DoubleClick\", category: \"marketing\" },\n { pattern: \"DSID\", vendor: \"Google DoubleClick\", category: \"marketing\" },\n { pattern: \"KADUSERCOOKIE\", vendor: \"PubMatic\", category: \"marketing\" },\n { pattern: \"rubicon_user_*\", vendor: \"Rubicon Project\", category: \"marketing\" },\n { pattern: \"Anonymon_id\", vendor: \"OpenX\", category: \"marketing\" },\n { pattern: \"pdomid\", vendor: \"OpenX\", category: \"marketing\" },\n { pattern: \"uuid2\", vendor: \"AppNexus\", category: \"marketing\" },\n { pattern: \"icu\", vendor: \"AppNexus\", category: \"marketing\" },\n\n // Core Social Media Pixels\n { pattern: \"_scid\", vendor: \"Snap Pixel\", category: \"marketing\" },\n { pattern: \"_sc_cspv\", vendor: \"Snap Pixel\", category: \"marketing\" },\n { pattern: \"_rdt_uuid\", vendor: \"Reddit Pixel\", category: \"marketing\" },\n\n // Content Discovery & Native Advertising\n { pattern: \"obuid\", vendor: \"Outbrain\", category: \"marketing\" },\n { pattern: \"t_gid\", vendor: \"Taboola\", category: \"marketing\" },\n\n // Premium ESPs, CDPs & Lifecycle Marketing\n { pattern: \"__kla_id\", vendor: \"Klaviyo\", category: \"marketing\" },\n { pattern: \"sc_anonymous_id\", vendor: \"Salesforce Marketing Cloud\", category: \"marketing\" },\n { pattern: \"vst\", vendor: \"Salesforce Marketing Cloud\", category: \"marketing\" },\n { pattern: \"visitor_id*\", vendor: \"Salesforce Pardot\", category: \"marketing\" },\n { pattern: \"piAId\", vendor: \"Salesforce Pardot\", category: \"marketing\" },\n { pattern: \"exp_last_visit\", vendor: \"ActiveCampaign\", category: \"marketing\" },\n { pattern: \"exp_tracker\", vendor: \"ActiveCampaign\", category: \"marketing\" },\n\n // Advanced Session Replay, Optimization & Analytics\n { pattern: \"_ce.s*\", vendor: \"Crazy Egg\", category: \"analytics\" },\n { pattern: \"lr_*\", vendor: \"LogRocket\", category: \"analytics\" },\n { pattern: \"_hp2_id.*\", vendor: \"Heap Analytics\", category: \"analytics\" },\n { pattern: \"_hp2_ses.*\", vendor: \"Heap Analytics\", category: \"analytics\" },\n { pattern: \"_lo_*\", vendor: \"Lucky Orange\", category: \"analytics\" },\n { pattern: \"fs_uid\", vendor: \"FullStory\", category: \"analytics\" },\n { pattern: \"_fs_*\", vendor: \"FullStory\", category: \"analytics\" },\n { pattern: \"ln_or\", vendor: \"LiveSession\", category: \"analytics\" },\n { pattern: \"_vwo_uuid*\", vendor: \"Visual Website Optimizer (VWO)\", category: \"analytics\" },\n { pattern: \"_vis_opt_*\", vendor: \"Visual Website Optimizer (VWO)\", category: \"analytics\" },\n { pattern: \"OptimizelyBuckets\", vendor: \"Optimizely\", category: \"analytics\" },\n { pattern: \"optimizelyEndUserId\", vendor: \"Optimizely\", category: \"analytics\" },\n\n // OneTrust (necessary — this is the CMP's own consent-state storage, not a tracker)\n { pattern: \"OptanonConsent\", vendor: \"OneTrust\", category: \"necessary\" },\n { pattern: \"OptanonAlertBoxClosed\", vendor: \"OneTrust\", category: \"necessary\" },\n\n // Syrenis Cassie (necessary — same rationale as OneTrust above: these store the CMP's own\n // consent record — when you consented, what you chose, which policy version you saw, and the\n // GTM/session bookkeeping that keeps the banner from re-prompting — not a third-party tracker\n // in their own right).\n { pattern: \"SyrenisCookieConsentDate_*\", vendor: \"Syrenis Cassie\", category: \"necessary\" },\n { pattern: \"SyrenisCookieFormConsent_*\", vendor: \"Syrenis Cassie\", category: \"necessary\" },\n { pattern: \"SyrenisCookiePrivacyLink_*\", vendor: \"Syrenis Cassie\", category: \"necessary\" },\n { pattern: \"SyrenisGtmConsent_*\", vendor: \"Syrenis Cassie\", category: \"necessary\" },\n { pattern: \"SyrenisGuid_*\", vendor: \"Syrenis Cassie\", category: \"necessary\" },\n\n // Alternative Core Global Consent Framework Engines (CMP Tools)\n { pattern: \"CookieConsent\", vendor: \"Cookiebot\", category: \"necessary\" },\n { pattern: \"uc_settings\", vendor: \"Usercentrics\", category: \"necessary\" },\n { pattern: \"uc_user_interaction\", vendor: \"Usercentrics\", category: \"necessary\" },\n { pattern: \"didomi_token\", vendor: \"Didomi\", category: \"necessary\" },\n { pattern: \"euconsent-v2\", vendor: \"IAB TCF Global Vendor List\", category: \"necessary\" },\n { pattern: \"cconsent\", vendor: \"Cookie Consent Studio\", category: \"necessary\" },\n\n // Real-User Monitoring (RUM) & Infrastructure Performance\n { pattern: \"JSESSIONID\", vendor: \"New Relic\", category: \"necessary\" },\n { pattern: \"NRAGENT\", vendor: \"New Relic\", category: \"necessary\" },\n { pattern: \"_dd_s\", vendor: \"Datadog\", category: \"necessary\" },\n { pattern: \"dtCookie\", vendor: \"Dynatrace\", category: \"necessary\" },\n { pattern: \"dtPC\", vendor: \"Dynatrace\", category: \"necessary\" },\n { pattern: \"rxVisitor\", vendor: \"Dynatrace\", category: \"necessary\" },\n { pattern: \"ak_bmsc\", vendor: \"Akamai\", category: \"necessary\" },\n { pattern: \"_abck\", vendor: \"Akamai\", category: \"necessary\" },\n\n // Video Hosting Telemetry & Analytics\n { pattern: \"vuid\", vendor: \"Vimeo\", category: \"analytics\" },\n { pattern: \"__cf_vuid\", vendor: \"Vimeo\", category: \"analytics\" },\n { pattern: \"VISITOR_INFO1_LIVE\", vendor: \"YouTube\", category: \"marketing\" },\n { pattern: \"YSC\", vendor: \"YouTube\", category: \"necessary\" }, // Keeps track of user input/session during video play\n { pattern: \"GPS\", vendor: \"YouTube\", category: \"marketing\" },\n { pattern: \"_wistia_*\", vendor: \"Wistia\", category: \"analytics\" },\n\n // Server-Side Event Attribution & Tagging Extensions\n { pattern: \"_elvr_*\", vendor: \"Elevar\", category: \"analytics\" },\n { pattern: \"stkn\", vendor: \"Shopify Core Analytics\", category: \"analytics\" },\n\n // Affiliate Network Enterprise Tracking\n { pattern: \"rmStore*\", vendor: \"Rakuten Advertising\", category: \"marketing\" },\n { pattern: \"_ir_*\", vendor: \"Impact Radius\", category: \"marketing\" },\n { pattern: \"aw*\", vendor: \"Awin\", category: \"marketing\" },\n { pattern: \"bctc\", vendor: \"Awin\", category: \"marketing\" },\n { pattern: \"mcookie\", vendor: \"CJ Affiliate\", category: \"marketing\" },\n\n // Major E-Commerce Native Framework Stores\n { pattern: \"_shopify_y\", vendor: \"Shopify\", category: \"analytics\" },\n { pattern: \"_shopify_s\", vendor: \"Shopify\", category: \"analytics\" },\n { pattern: \"_shopify_sa_p\", vendor: \"Shopify\", category: \"marketing\" },\n { pattern: \"shopify_sa_t\", vendor: \"Shopify\", category: \"marketing\" },\n { pattern: \"cart_sig\", vendor: \"Shopify\", category: \"necessary\" },\n { pattern: \"secure_customer_sig\", vendor: \"Shopify\", category: \"necessary\" },\n { pattern: \"wp_woocommerce_session*\", vendor: \"WooCommerce\", category: \"necessary\" },\n { pattern: \"woocommerce_items_in_cart\", vendor: \"WooCommerce\", category: \"necessary\" },\n { pattern: \"woocommerce_cart_hash\", vendor: \"WooCommerce\", category: \"necessary\" },\n\n // Enterprise Feedback, Surveys & Interstitials\n { pattern: \"QSI_\", vendor: \"Qualtrics\", category: \"functional\" },\n { pattern: \"feedback_id\", vendor: \"SurveyMonkey\", category: \"functional\" },\n { pattern: \"usbl.\", vendor: \"Usabilla\", category: \"functional\" },\n];\n\n/** Matches a typed cookie/storage key against the knowledge base — exact match first, then the\n * longest matching \"*\"-suffixed prefix pattern. Returns `undefined` for unrecognized names. */\nexport function matchTrackerKnowledge(id: string): TrackerKnowledgeEntry | undefined {\n const trimmed = id.trim();\n if (!trimmed) return undefined;\n\n const exact = TRACKER_KNOWLEDGE_BASE.find((e) => !e.pattern.endsWith(\"*\") && e.pattern === trimmed);\n if (exact) return exact;\n\n const prefixMatches = TRACKER_KNOWLEDGE_BASE.filter(\n (e) => e.pattern.endsWith(\"*\") && trimmed.startsWith(e.pattern.slice(0, -1)),\n );\n if (prefixMatches.length === 0) return undefined;\n return prefixMatches.reduce((longest, e) => (e.pattern.length > longest.pattern.length ? e : longest));\n}\n","// Structured rich-text format shared between the admin dashboard's editor and the server:\n// stored in the DB as a compact JSON string, safer than raw HTML since the renderer only ever\n// emits a known whitelist of tags. `htmlToJson` (HTML → ContentDoc, needs a DOM parser) stays\n// dashboard-only — everything here is DOM-independent so it also runs server-side, where\n// `renderContentText` converts a stored field to the real HTML the widget's `innerHTML` expects.\n\nexport type ContentNode = TextNode | InlineNode | BlockNode | LinkNode | BrNode\n\nexport interface TextNode { t: 'text'; v: string }\nexport interface InlineNode { t: 'b' | 'i' | 'u'; c: ContentNode[] }\nexport interface BlockNode { t: 'p' | 'ul' | 'ol' | 'li'; c: ContentNode[] }\nexport interface LinkNode { t: 'a'; href: string; c: ContentNode[] }\nexport interface BrNode { t: 'br' }\n\nexport type ContentDoc = ContentNode[]\n\n/** Render a `ContentDoc` to an HTML string (only ever emits the whitelisted tags above). */\nexport function jsonToHtml(doc: ContentDoc): string {\n return doc.map(renderNode).join('')\n}\n\nfunction renderNode(node: ContentNode): string {\n if (node.t === 'text') return escHtml(node.v)\n if (node.t === 'br') return '<br>'\n if (node.t === 'a') return `<a href=\"${escAttr(node.href)}\">${node.c.map(renderNode).join('')}</a>`\n return `<${node.t}>${node.c.map(renderNode).join('')}</${node.t}>`\n}\n\nfunction escHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')\n}\n\nfunction escAttr(s: string): string {\n return s.replace(/\"/g, '&quot;').replace(/</g, '&lt;')\n}\n\n/**\n * Converts a stored `htmlText`-style field to the real HTML the widget's `innerHTML` expects.\n * Handles both formats a field can be in: the compact `ContentDoc` JSON (current editor output)\n * and a legacy/embedded-profile plain HTML string (used as-is — already real HTML, and possibly\n * containing tags outside the whitelist that a JSON round-trip would otherwise drop).\n */\nexport function renderContentText(value: string | undefined | null): string {\n if (!value) return ''\n const trimmed = value.trim()\n if (trimmed.startsWith('[')) {\n try {\n return jsonToHtml(JSON.parse(trimmed) as ContentDoc)\n } catch { /* not actually JSON — fall through and treat as HTML */ }\n }\n return value\n}\n\nfunction nodeHasVisibleText(node: ContentNode): boolean {\n if (node.t === 'text') return node.v.trim().length > 0\n if (node.t === 'br') return false\n return node.c.some(nodeHasVisibleText)\n}\n\n/** Strips HTML tags to check for leftover visible text — used only as a fallback for the\n * legacy/embedded-profile plain-HTML-string case `renderContentText` also handles. */\nfunction stripTagsHasVisibleText(html: string): boolean {\n return html.replace(/<[^>]*>/g, '').trim().length > 0\n}\n\n/**\n * Whether a stored `htmlText`-style field has any actual visible text — used to enforce\n * mandatory-content rules (body text, category descriptions that must not be blank). A naive\n * `value.length > 0` check is not enough: an empty rich-text editor can still serialize to a\n * non-empty-looking `ContentDoc` JSON string (e.g. `\"[]\"` or a paragraph node with an empty text\n * node), which would pass a length check while rendering nothing. Mirrors `renderContentText`'s\n * two input shapes (`ContentDoc` JSON, or a legacy plain-HTML string) so client-side wizard\n * validation and the backend validator agree on exactly what counts as \"blank.\"\n */\nexport function hasVisibleText(value: string | undefined | null): boolean {\n if (!value) return false\n const trimmed = value.trim()\n if (!trimmed) return false\n if (trimmed.startsWith('[')) {\n try {\n const doc = JSON.parse(trimmed) as ContentDoc\n return doc.some(nodeHasVisibleText)\n } catch { /* not actually JSON — fall through and treat as HTML/plain text */ }\n }\n return stripTagsHasVisibleText(trimmed)\n}\n","// Simplified TC string encoder/decoder.\n// This implementation stores a base64url-encoded JSON payload for basic compatibility.\n//\n// `@consenti/api` now also ships a spec-correct binary encoder (`apps/api/src/tcf/real-tc-string.ts`)\n// using the optional `@iabtechlabtcf/core` peer dependency (the actively-maintained IAB Tech Lab\n// package — note: the unscoped `iabtcf-core` name referenced in older comments/docs does not exist\n// on npm). That encoder is used automatically when `compliance.tcf.publisherCC` is configured and\n// the dependency is installed; this simplified encoder remains the fallback for everyone else and\n// the only option in `@consenti/ui`'s fully standalone (no-backend) mode, since real encoding needs\n// the multi-megabyte Global Vendor List that only the backend fetches and caches.\n//\n// Implemented with a manual base64url codec over Uint8Array (no `Buffer`) so this file works\n// identically in Node (`@consenti/api`) and the browser (`@consenti/ui`) without a runtime dependency.\n\nconst B64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'\n\nfunction utf8Encode(str: string): Uint8Array {\n return new TextEncoder().encode(str)\n}\n\nfunction utf8Decode(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes)\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let out = ''\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i] ?? 0\n const b1 = i + 1 < bytes.length ? bytes[i + 1] ?? 0 : 0\n const b2 = i + 2 < bytes.length ? bytes[i + 2] ?? 0 : 0\n out += B64_CHARS[b0 >> 2]\n out += B64_CHARS[((b0 & 0x03) << 4) | (b1 >> 4)]\n if (i + 1 < bytes.length) out += B64_CHARS[((b1 & 0x0f) << 2) | (b2 >> 6)]\n if (i + 2 < bytes.length) out += B64_CHARS[b2 & 0x3f]\n }\n return out\n}\n\nfunction base64UrlDecode(str: string): Uint8Array {\n const lookup = new Map(B64_CHARS.split('').map((c, idx) => [c, idx]))\n const cleaned = str.replace(/[^A-Za-z0-9\\-_]/g, '')\n const bytes: number[] = []\n for (let i = 0; i < cleaned.length; i += 4) {\n const c0 = lookup.get(cleaned[i] ?? '') ?? 0\n const c1 = lookup.get(cleaned[i + 1] ?? '') ?? 0\n const c2 = cleaned[i + 2] !== undefined ? lookup.get(cleaned[i + 2] as string) : undefined\n const c3 = cleaned[i + 3] !== undefined ? lookup.get(cleaned[i + 3] as string) : undefined\n bytes.push((c0 << 2) | (c1 >> 4))\n if (c2 !== undefined) bytes.push(((c1 & 0x0f) << 4) | (c2 >> 2))\n if (c3 !== undefined) bytes.push(((c2 ?? 0) & 0x03) << 6 | c3)\n }\n return new Uint8Array(bytes)\n}\n\nexport interface TcStringInput {\n cmpId: number\n cmpVersion: number\n consentScreen: number\n consentLanguage: string\n vendorListVersion: number\n purposeConsents: number[]\n vendorConsents: number[]\n}\n\nexport function encodeTcString(input: TcStringInput): string {\n const payload = {\n v: 2,\n ts: Math.floor(Date.now() / 100),\n cmpId: input.cmpId,\n cmpV: input.cmpVersion,\n cs: input.consentScreen,\n lang: input.consentLanguage.toUpperCase().slice(0, 2),\n vlV: input.vendorListVersion,\n pc: input.purposeConsents,\n vc: input.vendorConsents,\n }\n return base64UrlEncode(utf8Encode(JSON.stringify(payload)))\n}\n\nexport interface DecodedTcString {\n version: number\n cmpId: number\n consentLanguage: string\n purposeConsents: number[]\n vendorConsents: number[]\n created: number\n}\n\nexport function decodeTcString(tcString: string): DecodedTcString | null {\n try {\n const raw = JSON.parse(utf8Decode(base64UrlDecode(tcString))) as {\n v: number; cmpId: number; lang: string; pc: number[]; vc: number[]; ts: number\n }\n return {\n version: raw.v,\n cmpId: raw.cmpId,\n consentLanguage: raw.lang,\n purposeConsents: Array.isArray(raw.pc) ? raw.pc : [],\n vendorConsents: Array.isArray(raw.vc) ? raw.vc : [],\n created: raw.ts * 100,\n }\n } catch {\n return null\n }\n}\n","// Simplified GPP (Global Privacy Platform) US National (\"usnat\") string encoder/decoder.\n// Stores a base64url-encoded JSON payload, not the real IAB binary bit-string encoding —\n// deliberately, not just unfinished: `@consenti/api` ships a spec-correct encoder using the\n// optional `@iabgpp/cmpapi` peer dependency (see `apps/api/src/gpp/gpp-string.ts`), used\n// automatically when it's installed. This simplified encoder is the fallback for everyone else,\n// and the only option in `@consenti/ui`'s `window.__gpp` stub — unlike TCF, GPP's USNat section\n// doesn't need a multi-megabyte Global Vendor List to encode correctly, but `@iabgpp/cmpapi`\n// itself (all ~20 section encoders, GVL class, etc.) is large enough that bundling it into the\n// widget would defeat \"zero-dependency\" for every site, not just ones using GPP — so it stays a\n// server-only optional dependency, same bundle-size reasoning TCF already established.\n//\n// Implemented with the same manual base64url codec as `tcf.ts` (no `Buffer`), so this file works\n// identically in Node (`@consenti/api`) and the browser (`@consenti/ui`) without a runtime dependency.\n\nconst B64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'\n\nfunction utf8Encode(str: string): Uint8Array {\n return new TextEncoder().encode(str)\n}\n\nfunction utf8Decode(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes)\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let out = ''\n for (let i = 0; i < bytes.length; i += 3) {\n const b0 = bytes[i] ?? 0\n const b1 = i + 1 < bytes.length ? bytes[i + 1] ?? 0 : 0\n const b2 = i + 2 < bytes.length ? bytes[i + 2] ?? 0 : 0\n out += B64_CHARS[b0 >> 2]\n out += B64_CHARS[((b0 & 0x03) << 4) | (b1 >> 4)]\n if (i + 1 < bytes.length) out += B64_CHARS[((b1 & 0x0f) << 2) | (b2 >> 6)]\n if (i + 2 < bytes.length) out += B64_CHARS[b2 & 0x3f]\n }\n return out\n}\n\nfunction base64UrlDecode(str: string): Uint8Array {\n const lookup = new Map(B64_CHARS.split('').map((c, idx) => [c, idx]))\n const cleaned = str.replace(/[^A-Za-z0-9\\-_]/g, '')\n const bytes: number[] = []\n for (let i = 0; i < cleaned.length; i += 4) {\n const c0 = lookup.get(cleaned[i] ?? '') ?? 0\n const c1 = lookup.get(cleaned[i + 1] ?? '') ?? 0\n const c2 = cleaned[i + 2] !== undefined ? lookup.get(cleaned[i + 2] as string) : undefined\n const c3 = cleaned[i + 3] !== undefined ? lookup.get(cleaned[i + 3] as string) : undefined\n bytes.push((c0 << 2) | (c1 >> 4))\n if (c2 !== undefined) bytes.push(((c1 & 0x0f) << 4) | (c2 >> 2))\n if (c3 !== undefined) bytes.push(((c2 ?? 0) & 0x03) << 6 | c3)\n }\n return new Uint8Array(bytes)\n}\n\n// IAB's tri-state field convention: 0 = not applicable, 1 = opted out, 2 = did not opt out.\nconst NOT_APPLICABLE = 0\nconst OPTED_OUT = 1\nconst DID_NOT_OPT_OUT = 2\n\nfunction optOutValue(applicable: boolean, optedOut: boolean): number {\n if (!applicable) return NOT_APPLICABLE\n return optedOut ? OPTED_OUT : DID_NOT_OPT_OUT\n}\n\nexport interface GppStringInput {\n cmpId: number\n cmpVersion: number\n mspaCoveredTransaction: boolean\n mspaOptOutOptionMode: 0 | 1 | 2\n mspaServiceProviderMode: 0 | 1 | 2\n /** Whether the visitor opted out of sale-category cookies (cpraCategory: 'sale'). */\n saleOptOut: boolean\n /** Whether any cookie in the profile is tagged cpraCategory: 'sale'. */\n saleApplicable: boolean\n sharingOptOut: boolean\n sharingApplicable: boolean\n gpcDetected?: boolean\n}\n\nexport function encodeGppString(input: GppStringInput): string {\n const payload = {\n v: 1,\n ts: Math.floor(Date.now() / 100),\n cmpId: input.cmpId,\n cmpV: input.cmpVersion,\n sect: 'usnat',\n saleOO: optOutValue(input.saleApplicable, input.saleOptOut),\n shareOO: optOutValue(input.sharingApplicable, input.sharingOptOut),\n // Targeted-advertising opt-out mirrors sharing opt-out — CPRA defines \"sharing\" as\n // cross-context behavioural advertising, which is what USNat's field covers.\n taOO: optOutValue(input.sharingApplicable, input.sharingOptOut),\n mspaCT: input.mspaCoveredTransaction ? 1 : 2,\n mspaOOM: input.mspaOptOutOptionMode,\n mspaSPM: input.mspaServiceProviderMode,\n ...(input.gpcDetected !== undefined ? { gpc: input.gpcDetected } : {}),\n }\n return base64UrlEncode(utf8Encode(JSON.stringify(payload)))\n}\n\nexport interface DecodedGppString {\n version: number\n cmpId: number\n cmpVersion: number\n saleOptOut: number\n sharingOptOut: number\n targetedAdvertisingOptOut: number\n gpc?: boolean\n created: number\n}\n\nexport function decodeGppString(gppString: string): DecodedGppString | null {\n try {\n const raw = JSON.parse(utf8Decode(base64UrlDecode(gppString))) as {\n v: number; cmpId: number; cmpV: number\n saleOO: number; shareOO: number; taOO: number; gpc?: boolean; ts: number\n }\n return {\n version: raw.v,\n cmpId: raw.cmpId,\n cmpVersion: raw.cmpV,\n saleOptOut: raw.saleOO,\n sharingOptOut: raw.shareOO,\n targetedAdvertisingOptOut: raw.taOO,\n ...(raw.gpc !== undefined ? { gpc: raw.gpc } : {}),\n created: raw.ts * 100,\n }\n } catch {\n return null\n }\n}\n","/** ISO 639-1 prefixes of languages conventionally written right-to-left. Fallback for engines\n * without `Intl.Locale(...).getTextInfo()` support — this project's floor is Firefox 74+, and\n * `getTextInfo()` is a recent addition not yet universal. */\nconst RTL_LANGUAGE_PREFIXES = ['ar', 'he', 'fa', 'ur', 'ps', 'sd', 'ug', 'yi']\n\n/**\n * Resolves the text direction for a locale. `override` (an explicit `core.dir` config value)\n * always wins; `'auto'` (or omitted) derives the direction from `Intl.Locale(...).getTextInfo()`\n * when the engine supports it, falling back to a hand-maintained RTL-language-prefix table.\n */\nexport function resolveTextDirection(locale: string, override?: 'ltr' | 'rtl' | 'auto'): 'ltr' | 'rtl' {\n if (override === 'ltr' || override === 'rtl') return override\n try {\n const dir = new Intl.Locale(locale).getTextInfo?.().direction\n if (dir === 'ltr' || dir === 'rtl') return dir\n } catch {\n // Invalid/unparseable locale string, or Intl.Locale/getTextInfo unsupported — fall through.\n }\n const prefix = locale.slice(0, 2).toLowerCase()\n return RTL_LANGUAGE_PREFIXES.includes(prefix) ? 'rtl' : 'ltr'\n}\n"],"mappings":"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","names":["debounce","fn","delay","timer","args","throttle","fn","delay","lastCall","args","now","colorEnabled","wrap","open","close","s","color","STATUS_STYLE","statusLabel","status","width","text","LEVEL_STYLE","formatLog","level","message","symbol","paint","COMPLIANCE_GROUP_IDS","COMPLIANCE_GROUPS","GPC_OPTIONS","LEGAL_BASIS_OPTIONS","CPRA_CATEGORIES","COOKIE_PURPOSE_IDS","COOKIE_PURPOSES","COOKIE_PURPOSE_DEFAULTS","KNOWN_COOKIE_PURPOSES","inferCookiePurpose","cookie","TCF_PURPOSES","TCF_SPECIAL_FEATURES","findCategoryForCookie","cookieId","categories","category","buildCookieCategoryIndex","index","getCookieLegalBasis","isMandatoryCookie","COMPLIANCE_VALIDATION_RULES","c","id","legalBasis","EMBEDDED_COMPLIANCE_MAP","COUNTRY_CODE_ALIASES","findCountryEntry","countries","code","alias","COMPLIANCE_REGULATION_IDS","acc","country","COUNTRY_CODES","d","LOCALES","l","isComplianceMapData","data","entry","resolveComplianceMapOverride","override","onWarn","fallback","candidate","response","err","result","mergeOverEmbedded","TRACKER_KNOWLEDGE_BASE","matchTrackerKnowledge","id","trimmed","exact","e","prefixMatches","longest","jsonToHtml","doc","renderNode","node","escHtml","escAttr","s","renderContentText","value","trimmed","nodeHasVisibleText","stripTagsHasVisibleText","html","hasVisibleText","B64_CHARS","utf8Encode","str","utf8Decode","bytes","base64UrlEncode","out","i","b0","b1","b2","base64UrlDecode","lookup","c","idx","cleaned","c0","c1","c2","c3","encodeTcString","input","payload","decodeTcString","tcString","raw","B64_CHARS","utf8Encode","str","utf8Decode","bytes","base64UrlEncode","out","i","b0","b1","b2","base64UrlDecode","lookup","c","idx","cleaned","c0","c1","c2","c3","NOT_APPLICABLE","OPTED_OUT","DID_NOT_OPT_OUT","optOutValue","applicable","optedOut","encodeGppString","input","payload","decodeGppString","gppString","raw","RTL_LANGUAGE_PREFIXES","resolveTextDirection","locale","override","dir","prefix"]}
@@ -1 +1 @@
1
- import{t as e}from"./check-IM5PInrX.js";import{t}from"./copy-FTaGH7-z.js";import{t as n}from"./external-link-5y29qnhn.js";import{t as r}from"./trash-BVDX09Xe.js";import{t as i}from"./ConfirmDialog-sMBVcbiI.js";import{A as a,E as o,M as s,S as c,T as l,d as u,f as d,k as f,o as p,s as m}from"./index-BaYVhd1M.js";var h=window.__CONSENTI_CONFIG__?.basePath??`/consenti`,g=`${window.location.origin}${h}/admin/v1`,_=`${window.location.origin}${h}/api/v1`;function v({href:e,text:t,label:r}){return c(`div`,{class:`bg-blue-50 border border-blue-100 rounded-lg p-4 flex items-start gap-3`,children:[c(n,{size:16,className:`text-blue-600 shrink-0 mt-0.5`,"aria-hidden":`true`}),c(`div`,{children:[c(`p`,{class:`text-xs text-blue-900`,children:t}),c(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,class:`flex items-center gap-1 text-xs font-medium text-blue-700 hover:underline mt-1`,children:[r,` `,c(n,{size:11,"aria-hidden":`true`})]})]})]})}function y({url:n}){let r=m(),[i,a]=f(!1);return c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:r(`apiConfig.endpoint.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-4`,children:r(`apiConfig.endpoint.hint`)}),c(`div`,{class:`flex items-center justify-between gap-3 border border-gray-200 rounded px-3 py-2`,children:[c(`code`,{class:`text-xs font-mono text-gray-700 break-all`,children:n}),c(`button`,{type:`button`,onClick:()=>{navigator.clipboard.writeText(n).then(()=>{a(!0),setTimeout(()=>a(!1),2e3)})},"aria-label":r(`common.copyToClipboard`),title:r(`common.copyToClipboard`),class:`shrink-0 text-gray-400 hover:text-gray-700`,children:i?c(e,{size:13,className:`text-green-600`,"aria-hidden":`true`}):c(t,{size:13,"aria-hidden":`true`})})]})]})}function b({field:e,initialOrigins:t,note:n}){let i=m(),[s,u]=f(t),[d,p]=f(``),[h,g]=f(!1),[_,v]=f(``);a(()=>{u(t)},[t]);let y=async t=>{g(!0),v(``);try{await o(`/settings`,{method:`PATCH`,body:JSON.stringify({[e]:t})}),u(t)}catch(e){v(l(e,i(`apiConfig.origins.errorSave`)))}finally{g(!1)}},b=async()=>{let e=d.trim().replace(/\/$/,``);e&&(s.includes(e)?v(i(`apiConfig.origins.errorDuplicate`)):(p(``),await y([...s,e])))},x=async e=>{await y(s.filter(t=>t!==e))};return c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:i(`apiConfig.origins.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-1`,children:i(`apiConfig.origins.hint`)}),n&&c(`p`,{class:`text-xs text-amber-700 mb-4`,children:n}),!n&&c(`div`,{class:`mb-4`}),c(`div`,{class:`flex gap-2 mb-3`,children:[c(`input`,{type:`text`,placeholder:i(`apiConfig.origins.placeholder`),"aria-label":i(`apiConfig.origins.placeholder`),value:d,onInput:e=>{p(e.target.value),v(``)},onKeyDown:e=>e.key===`Enter`&&b(),class:`flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm`}),c(`button`,{onClick:b,disabled:h||!d.trim(),class:`px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-50`,children:i(`common.add`)})]}),_&&c(`p`,{role:`alert`,class:`text-xs text-red-600 mb-2`,children:_}),s.length===0?c(`p`,{class:`text-xs text-gray-400 py-3 text-center`,children:i(`apiConfig.origins.empty`)}):c(`ul`,{class:`border border-gray-200 rounded divide-y divide-gray-100 text-sm`,children:s.map(e=>c(`li`,{class:`flex items-center justify-between px-3 py-2 group`,children:[c(`span`,{class:`font-mono text-gray-700 text-xs`,children:e}),c(`button`,{onClick:()=>x(e),disabled:h,"aria-label":`${i(`apiConfig.origins.remove`)} ${e}`,title:i(`apiConfig.origins.remove`),class:`text-gray-400 hover:text-red-600 opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-30`,children:c(r,{size:13,"aria-hidden":`true`})})]},e))})]})}function x({current:n}){let r=m();p(r(`apiConfig.title`));let[h,x]=f({}),[S,C]=f([]),[w,T]=f(``),[E,D]=f(``),[O,k]=f(null),[A,j]=f(!1),[M,N]=f(``),[P,F]=f(!1),[I,L]=f(!0),{requestConfirm:R,dialog:z}=i();a(()=>{o(`/settings`).then(x).catch(()=>{}),o(`/apikeys`).then(C).catch(()=>{}).finally(()=>L(!1))},[]);let B=()=>{o(`/apikeys`).then(C).catch(()=>{})},V=async()=>{if(!w.trim())N(r(`apiConfig.tokens.errorName`));else{N(``);try{let e=await o(`/apikeys`,{method:`POST`,body:JSON.stringify({name:w.trim(),...E?{expireBy:new Date(E).toISOString()}:{}})});k(e),F(!1),j(!1),T(``),D(``),C(t=>[...t,{id:e.id,name:e.name,isActive:!0,createdAt:e.createdAt,...E?{expireBy:new Date(E).toISOString()}:{}}])}catch(e){N(l(e,r(`apiConfig.tokens.errorCreate`)))}}},H=e=>e.isActive&&!!e.expireBy&&new Date(e.expireBy)<=new Date,U=async e=>{if(await R({title:r(`apiConfig.tokens.dialog.title`),message:r(`apiConfig.tokens.dialog.message`),danger:!0}))try{await o(`/apikeys/${e}`,{method:`DELETE`}),C(t=>t.map(t=>t.id===e?{...t,isActive:!1}:t)),B()}catch{}},W=async e=>{try{await o(`/apikeys/${e}/reactivate`,{method:`POST`}),B()}catch{}},G=async e=>{if(await R({title:r(`apiConfig.tokens.deleteDialog.title`),message:r(`apiConfig.tokens.deleteDialog.message`),danger:!0}))try{await o(`/apikeys/${e}/permanent`,{method:`DELETE`}),C(t=>t.filter(t=>t.id!==e))}catch{}};return c(s,{children:[z,c(`div`,{class:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[c(`div`,{class:`space-y-6 min-w-0`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-500 uppercase tracking-wide`,children:r(`apiConfig.admin.heading`)}),c(v,{href:`https://consenti.dev/docs/api/routes/admin?utm_source=dashboard&utm_medium=api-config&utm_campaign=consenti-api`,text:r(`apiConfig.admin.about.text`),label:r(`apiConfig.admin.about.link`)}),c(y,{url:g}),c(b,{field:`adminAllowedOrigins`,initialOrigins:h.adminAllowedOrigins??[],note:r(`apiConfig.origins.adminNote`,{origin:window.location.origin})}),c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:r(`apiConfig.tokens.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-4`,children:r(`apiConfig.tokens.hint`)}),O&&c(`div`,{class:`mb-4 p-3 bg-green-50 border border-green-200 rounded`,children:[c(`p`,{class:`text-xs font-medium text-green-800 mb-2`,children:r(`apiConfig.tokens.created`)}),c(`div`,{class:`flex items-center gap-2`,children:[c(`code`,{class:`flex-1 text-xs font-mono text-green-700 break-all ${P?``:`blur-sm select-none`}`,children:O.key}),c(`button`,{type:`button`,onClick:()=>F(e=>!e),"aria-label":r(P?`common.hide`:`common.show`),title:r(P?`common.hide`:`common.show`),class:`shrink-0 text-gray-500 hover:text-gray-700`,children:c(P?d:u,{size:14,"aria-hidden":`true`})}),c(`button`,{type:`button`,onClick:()=>{O&&navigator.clipboard.writeText(O.key).then(()=>{j(!0),setTimeout(()=>j(!1),2e3)})},"aria-label":r(`common.copyToClipboard`),title:r(`common.copyToClipboard`),class:`shrink-0 text-gray-500 hover:text-green-700`,children:A?c(e,{size:14,className:`text-green-600`,"aria-hidden":`true`}):c(t,{size:14,"aria-hidden":`true`})})]})]}),c(`div`,{class:`flex gap-2 mb-4`,children:[c(`input`,{type:`text`,placeholder:r(`apiConfig.tokens.placeholder`),"aria-label":r(`apiConfig.tokens.placeholder`),value:w,onInput:e=>T(e.target.value),onKeyDown:e=>e.key===`Enter`&&V(),class:`flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm`}),c(`input`,{type:`date`,"aria-label":r(`apiConfig.tokens.expiresLabel`),title:r(`apiConfig.tokens.expiresLabel`),value:E,onInput:e=>D(e.target.value),class:`border border-gray-300 rounded px-3 py-1.5 text-sm text-gray-600`}),c(`button`,{onClick:V,class:`px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700`,children:r(`common.create`)})]}),M&&c(`p`,{role:`alert`,class:`text-xs text-red-600 mb-2`,children:M}),!I&&S.length===0&&c(`p`,{class:`text-xs text-gray-400 py-3 text-center`,children:r(`apiConfig.tokens.empty`)}),S.length>0&&c(`table`,{class:`w-full text-xs border border-gray-200 rounded overflow-hidden`,children:[c(`thead`,{class:`bg-gray-50`,children:c(`tr`,{children:[c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.name`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.status`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.created`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.expires`)}),c(`th`,{scope:`col`,class:`px-3 py-2`})]})}),c(`tbody`,{class:`divide-y divide-gray-100`,children:S.map(e=>{let t=H(e),n=e.isActive&&!t;return c(`tr`,{children:[c(`td`,{class:`px-3 py-2 font-mono`,children:e.name}),c(`td`,{class:`px-3 py-2`,children:c(`span`,{class:`font-medium ${n?`text-green-600`:t?`text-amber-600`:`text-gray-400`}`,children:r(n?`apiConfig.tokens.status.active`:t?`apiConfig.tokens.status.expired`:`apiConfig.tokens.status.revoked`)})}),c(`td`,{class:`px-3 py-2 text-gray-500`,children:new Date(e.createdAt).toLocaleDateString()}),c(`td`,{class:`px-3 py-2 text-gray-500`,children:e.expireBy?new Date(e.expireBy).toLocaleDateString():r(`apiConfig.tokens.expiresNever`)}),c(`td`,{class:`px-3 py-2 text-right whitespace-nowrap`,children:n?c(`button`,{onClick:()=>U(e.id),class:`text-red-500 hover:underline`,children:r(`common.revoke`)}):c(`span`,{class:`inline-flex items-center gap-3`,children:[c(`button`,{onClick:()=>W(e.id),class:`text-green-600 hover:underline`,children:r(`apiConfig.tokens.reactivate`)}),c(`button`,{onClick:()=>G(e.id),class:`text-red-500 hover:underline`,children:r(`common.delete`)})]})})]},e.id)})})]})]})]}),c(`div`,{class:`space-y-6 min-w-0`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-500 uppercase tracking-wide`,children:r(`apiConfig.public.heading`)}),c(v,{href:`https://consenti.dev/docs/api/routes/public?utm_source=dashboard&utm_medium=api-config&utm_campaign=consenti-api`,text:r(`apiConfig.public.about.text`),label:r(`apiConfig.public.about.link`)}),c(y,{url:_}),c(b,{field:`allowedOrigins`,initialOrigins:h.allowedOrigins??[],note:r(`apiConfig.origins.publicNote`)})]})]})]})}export{x as ApiConfig};
1
+ import{t as e}from"./check-BAoHs1bd.js";import{t}from"./copy-DjZpSOQM.js";import{t as n}from"./external-link-CFayXpKz.js";import{t as r}from"./trash-Bfqti-Og.js";import{t as i}from"./ConfirmDialog-CJAqYRfE.js";import{A as a,E as o,M as s,S as c,T as l,d as u,f as d,k as f,o as p,s as m}from"./index-D7qdwIxs.js";var h=window.__CONSENTI_CONFIG__?.basePath??`/consenti`,g=`${window.location.origin}${h}/admin/v1`,_=`${window.location.origin}${h}/api/v1`;function v({href:e,text:t,label:r}){return c(`div`,{class:`bg-blue-50 border border-blue-100 rounded-lg p-4 flex items-start gap-3`,children:[c(n,{size:16,className:`text-blue-600 shrink-0 mt-0.5`,"aria-hidden":`true`}),c(`div`,{children:[c(`p`,{class:`text-xs text-blue-900`,children:t}),c(`a`,{href:e,target:`_blank`,rel:`noopener noreferrer`,class:`flex items-center gap-1 text-xs font-medium text-blue-700 hover:underline mt-1`,children:[r,` `,c(n,{size:11,"aria-hidden":`true`})]})]})]})}function y({url:n}){let r=m(),[i,a]=f(!1);return c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:r(`apiConfig.endpoint.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-4`,children:r(`apiConfig.endpoint.hint`)}),c(`div`,{class:`flex items-center justify-between gap-3 border border-gray-200 rounded px-3 py-2`,children:[c(`code`,{class:`text-xs font-mono text-gray-700 break-all`,children:n}),c(`button`,{type:`button`,onClick:()=>{navigator.clipboard.writeText(n).then(()=>{a(!0),setTimeout(()=>a(!1),2e3)})},"aria-label":r(`common.copyToClipboard`),title:r(`common.copyToClipboard`),class:`shrink-0 text-gray-400 hover:text-gray-700`,children:i?c(e,{size:13,className:`text-green-600`,"aria-hidden":`true`}):c(t,{size:13,"aria-hidden":`true`})})]})]})}function b({field:e,initialOrigins:t,note:n}){let i=m(),[s,u]=f(t),[d,p]=f(``),[h,g]=f(!1),[_,v]=f(``);a(()=>{u(t)},[t]);let y=async t=>{g(!0),v(``);try{await o(`/settings`,{method:`PATCH`,body:JSON.stringify({[e]:t})}),u(t)}catch(e){v(l(e,i(`apiConfig.origins.errorSave`)))}finally{g(!1)}},b=async()=>{let e=d.trim().replace(/\/$/,``);e&&(s.includes(e)?v(i(`apiConfig.origins.errorDuplicate`)):(p(``),await y([...s,e])))},x=async e=>{await y(s.filter(t=>t!==e))};return c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:i(`apiConfig.origins.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-1`,children:i(`apiConfig.origins.hint`)}),n&&c(`p`,{class:`text-xs text-amber-700 mb-4`,children:n}),!n&&c(`div`,{class:`mb-4`}),c(`div`,{class:`flex gap-2 mb-3`,children:[c(`input`,{type:`text`,placeholder:i(`apiConfig.origins.placeholder`),"aria-label":i(`apiConfig.origins.placeholder`),value:d,onInput:e=>{p(e.target.value),v(``)},onKeyDown:e=>e.key===`Enter`&&b(),class:`flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm`}),c(`button`,{onClick:b,disabled:h||!d.trim(),class:`px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 disabled:opacity-50`,children:i(`common.add`)})]}),_&&c(`p`,{role:`alert`,class:`text-xs text-red-600 mb-2`,children:_}),s.length===0?c(`p`,{class:`text-xs text-gray-400 py-3 text-center`,children:i(`apiConfig.origins.empty`)}):c(`ul`,{class:`border border-gray-200 rounded divide-y divide-gray-100 text-sm`,children:s.map(e=>c(`li`,{class:`flex items-center justify-between px-3 py-2 group`,children:[c(`span`,{class:`font-mono text-gray-700 text-xs`,children:e}),c(`button`,{onClick:()=>x(e),disabled:h,"aria-label":`${i(`apiConfig.origins.remove`)} ${e}`,title:i(`apiConfig.origins.remove`),class:`text-gray-400 hover:text-red-600 opacity-0 group-hover:opacity-100 transition-opacity disabled:opacity-30`,children:c(r,{size:13,"aria-hidden":`true`})})]},e))})]})}function x({current:n}){let r=m();p(r(`apiConfig.title`));let[h,x]=f({}),[S,C]=f([]),[w,T]=f(``),[E,D]=f(``),[O,k]=f(null),[A,j]=f(!1),[M,N]=f(``),[P,F]=f(!1),[I,L]=f(!0),{requestConfirm:R,dialog:z}=i();a(()=>{o(`/settings`).then(x).catch(()=>{}),o(`/apikeys`).then(C).catch(()=>{}).finally(()=>L(!1))},[]);let B=()=>{o(`/apikeys`).then(C).catch(()=>{})},V=async()=>{if(!w.trim())N(r(`apiConfig.tokens.errorName`));else{N(``);try{let e=await o(`/apikeys`,{method:`POST`,body:JSON.stringify({name:w.trim(),...E?{expireBy:new Date(E).toISOString()}:{}})});k(e),F(!1),j(!1),T(``),D(``),C(t=>[...t,{id:e.id,name:e.name,isActive:!0,createdAt:e.createdAt,...E?{expireBy:new Date(E).toISOString()}:{}}])}catch(e){N(l(e,r(`apiConfig.tokens.errorCreate`)))}}},H=e=>e.isActive&&!!e.expireBy&&new Date(e.expireBy)<=new Date,U=async e=>{if(await R({title:r(`apiConfig.tokens.dialog.title`),message:r(`apiConfig.tokens.dialog.message`),danger:!0}))try{await o(`/apikeys/${e}`,{method:`DELETE`}),C(t=>t.map(t=>t.id===e?{...t,isActive:!1}:t)),B()}catch{}},W=async e=>{try{await o(`/apikeys/${e}/reactivate`,{method:`POST`}),B()}catch{}},G=async e=>{if(await R({title:r(`apiConfig.tokens.deleteDialog.title`),message:r(`apiConfig.tokens.deleteDialog.message`),danger:!0}))try{await o(`/apikeys/${e}/permanent`,{method:`DELETE`}),C(t=>t.filter(t=>t.id!==e))}catch{}};return c(s,{children:[z,c(`div`,{class:`grid grid-cols-1 lg:grid-cols-2 gap-6`,children:[c(`div`,{class:`space-y-6 min-w-0`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-500 uppercase tracking-wide`,children:r(`apiConfig.admin.heading`)}),c(v,{href:`https://consenti.dev/docs/api/routes/admin?utm_source=dashboard&utm_medium=api-config&utm_campaign=consenti-api`,text:r(`apiConfig.admin.about.text`),label:r(`apiConfig.admin.about.link`)}),c(y,{url:g}),c(b,{field:`adminAllowedOrigins`,initialOrigins:h.adminAllowedOrigins??[],note:r(`apiConfig.origins.adminNote`,{origin:window.location.origin})}),c(`div`,{class:`bg-white rounded-lg border border-gray-200 p-5`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-700 mb-1`,children:r(`apiConfig.tokens.heading`)}),c(`p`,{class:`text-xs text-gray-500 mb-4`,children:r(`apiConfig.tokens.hint`)}),O&&c(`div`,{class:`mb-4 p-3 bg-green-50 border border-green-200 rounded`,children:[c(`p`,{class:`text-xs font-medium text-green-800 mb-2`,children:r(`apiConfig.tokens.created`)}),c(`div`,{class:`flex items-center gap-2`,children:[c(`code`,{class:`flex-1 text-xs font-mono text-green-700 break-all ${P?``:`blur-sm select-none`}`,children:O.key}),c(`button`,{type:`button`,onClick:()=>F(e=>!e),"aria-label":r(P?`common.hide`:`common.show`),title:r(P?`common.hide`:`common.show`),class:`shrink-0 text-gray-500 hover:text-gray-700`,children:c(P?d:u,{size:14,"aria-hidden":`true`})}),c(`button`,{type:`button`,onClick:()=>{O&&navigator.clipboard.writeText(O.key).then(()=>{j(!0),setTimeout(()=>j(!1),2e3)})},"aria-label":r(`common.copyToClipboard`),title:r(`common.copyToClipboard`),class:`shrink-0 text-gray-500 hover:text-green-700`,children:A?c(e,{size:14,className:`text-green-600`,"aria-hidden":`true`}):c(t,{size:14,"aria-hidden":`true`})})]})]}),c(`div`,{class:`flex gap-2 mb-4`,children:[c(`input`,{type:`text`,placeholder:r(`apiConfig.tokens.placeholder`),"aria-label":r(`apiConfig.tokens.placeholder`),value:w,onInput:e=>T(e.target.value),onKeyDown:e=>e.key===`Enter`&&V(),class:`flex-1 border border-gray-300 rounded px-3 py-1.5 text-sm`}),c(`input`,{type:`date`,"aria-label":r(`apiConfig.tokens.expiresLabel`),title:r(`apiConfig.tokens.expiresLabel`),value:E,onInput:e=>D(e.target.value),class:`border border-gray-300 rounded px-3 py-1.5 text-sm text-gray-600`}),c(`button`,{onClick:V,class:`px-3 py-1.5 bg-blue-600 text-white text-sm rounded hover:bg-blue-700`,children:r(`common.create`)})]}),M&&c(`p`,{role:`alert`,class:`text-xs text-red-600 mb-2`,children:M}),!I&&S.length===0&&c(`p`,{class:`text-xs text-gray-400 py-3 text-center`,children:r(`apiConfig.tokens.empty`)}),S.length>0&&c(`table`,{class:`w-full text-xs border border-gray-200 rounded overflow-hidden`,children:[c(`thead`,{class:`bg-gray-50`,children:c(`tr`,{children:[c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.name`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.status`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.created`)}),c(`th`,{scope:`col`,class:`text-left px-3 py-2 text-gray-600 font-medium`,children:r(`apiConfig.tokens.col.expires`)}),c(`th`,{scope:`col`,class:`px-3 py-2`})]})}),c(`tbody`,{class:`divide-y divide-gray-100`,children:S.map(e=>{let t=H(e),n=e.isActive&&!t;return c(`tr`,{children:[c(`td`,{class:`px-3 py-2 font-mono`,children:e.name}),c(`td`,{class:`px-3 py-2`,children:c(`span`,{class:`font-medium ${n?`text-green-600`:t?`text-amber-600`:`text-gray-400`}`,children:r(n?`apiConfig.tokens.status.active`:t?`apiConfig.tokens.status.expired`:`apiConfig.tokens.status.revoked`)})}),c(`td`,{class:`px-3 py-2 text-gray-500`,children:new Date(e.createdAt).toLocaleDateString()}),c(`td`,{class:`px-3 py-2 text-gray-500`,children:e.expireBy?new Date(e.expireBy).toLocaleDateString():r(`apiConfig.tokens.expiresNever`)}),c(`td`,{class:`px-3 py-2 text-right whitespace-nowrap`,children:n?c(`button`,{onClick:()=>U(e.id),class:`text-red-500 hover:underline`,children:r(`common.revoke`)}):c(`span`,{class:`inline-flex items-center gap-3`,children:[c(`button`,{onClick:()=>W(e.id),class:`text-green-600 hover:underline`,children:r(`apiConfig.tokens.reactivate`)}),c(`button`,{onClick:()=>G(e.id),class:`text-red-500 hover:underline`,children:r(`common.delete`)})]})})]},e.id)})})]})]})]}),c(`div`,{class:`space-y-6 min-w-0`,children:[c(`h2`,{class:`text-sm font-semibold text-gray-500 uppercase tracking-wide`,children:r(`apiConfig.public.heading`)}),c(v,{href:`https://consenti.dev/docs/api/routes/public?utm_source=dashboard&utm_medium=api-config&utm_campaign=consenti-api`,text:r(`apiConfig.public.about.text`),label:r(`apiConfig.public.about.link`)}),c(y,{url:_}),c(b,{field:`allowedOrigins`,initialOrigins:h.allowedOrigins??[],note:r(`apiConfig.origins.publicNote`)})]})]})]})}export{x as ApiConfig};
@@ -1 +1 @@
1
- import{A as e,M as t,S as n,h as r,k as i,o as a,s as o}from"./index-BaYVhd1M.js";import{t as s}from"./Table-CcBP7eXS.js";import{t as c}from"./profiles-D-hvl_fK.js";function l({current:l}){let u=o();a(u(`profiles.archived.title`));let[d,f]=i([]),[p,m]=i(!0);return e(()=>{c.listArchived().then(f).catch(()=>f([])).finally(()=>m(!1))},[]),n(t,{children:[n(`div`,{class:`mb-4`,children:n(`a`,{href:`#/banners/profiles`,class:`inline-flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700 transition-colors`,children:[n(r,{size:14,"aria-hidden":`true`}),u(`profiles.archived.back`)]})}),n(`p`,{class:`text-xs text-gray-500 mb-4`,children:u(`profiles.archived.hint`)}),n(s,{loading:p,keyFn:e=>e.id,rows:d,emptyText:u(`profiles.archived.empty`),search:{placeholder:u(`profiles.archived.searchPlaceholder`),keys:e=>[e.id]},columns:[{key:`id`,label:u(`profiles.archived.col.id`),render:e=>n(`span`,{class:`font-mono text-sm text-gray-700`,children:e.id})},{key:`versionCount`,label:u(`profiles.archived.col.versions`),render:e=>n(`span`,{class:`text-sm text-gray-700`,children:e.versionCount})},{key:`lastModified`,label:u(`profiles.archived.col.lastModified`),render:e=>n(`span`,{class:`text-sm text-gray-500`,children:new Date(e.lastModified).toLocaleString()})},{key:`actions`,label:``,render:e=>n(`a`,{href:`#/banners/profiles/${e.id}/history`,class:`text-blue-600 hover:underline text-sm`,children:u(`profiles.archived.viewHistory`)})}]})]})}export{l as ArchivedProfileList};
1
+ import{A as e,M as t,S as n,h as r,k as i,o as a,s as o}from"./index-D7qdwIxs.js";import{t as s}from"./Table-C59yMXY2.js";import{t as c}from"./profiles-Jb6uV-0U.js";function l({current:l}){let u=o();a(u(`profiles.archived.title`));let[d,f]=i([]),[p,m]=i(!0);return e(()=>{c.listArchived().then(f).catch(()=>f([])).finally(()=>m(!1))},[]),n(t,{children:[n(`div`,{class:`mb-4`,children:n(`a`,{href:`#/banners/profiles`,class:`inline-flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700 transition-colors`,children:[n(r,{size:14,"aria-hidden":`true`}),u(`profiles.archived.back`)]})}),n(`p`,{class:`text-xs text-gray-500 mb-4`,children:u(`profiles.archived.hint`)}),n(s,{loading:p,keyFn:e=>e.id,rows:d,emptyText:u(`profiles.archived.empty`),search:{placeholder:u(`profiles.archived.searchPlaceholder`),keys:e=>[e.id]},columns:[{key:`id`,label:u(`profiles.archived.col.id`),render:e=>n(`span`,{class:`font-mono text-sm text-gray-700`,children:e.id})},{key:`versionCount`,label:u(`profiles.archived.col.versions`),render:e=>n(`span`,{class:`text-sm text-gray-700`,children:e.versionCount})},{key:`lastModified`,label:u(`profiles.archived.col.lastModified`),render:e=>n(`span`,{class:`text-sm text-gray-500`,children:new Date(e.lastModified).toLocaleString()})},{key:`actions`,label:``,render:e=>n(`a`,{href:`#/banners/profiles/${e.id}/history`,class:`text-blue-600 hover:underline text-sm`,children:u(`profiles.archived.viewHistory`)})}]})]})}export{l as ArchivedProfileList};
@@ -1 +1 @@
1
- import{t as e}from"./rotate-ccw-clock-C5cVu2_f.js";import{A as t,D as n,E as r,M as i,S as a,k as o,o as s,s as c,w as l}from"./index-BaYVhd1M.js";import{n as u,t as d}from"./useHashQuery-wXzkY-tk.js";import{n as f,t as p}from"./RecordDetailModal-hpJgK02E.js";var m={list:e=>{let t=new URLSearchParams;return e?.action&&t.set(`action`,e.action),e?.page&&t.set(`page`,String(e.page)),e?.limit&&t.set(`limit`,String(e.limit)),e?.q&&t.set(`q`,e.q),r(`/audit?${t}`)},get:e=>r(`/audit/${e}`)},h=`#/audit`,g=new Set([`profile:created`,`profile:updated`]);function _(e){if(e.resourceType!==`profile`||!g.has(e.action)||!e.resourceId)return null;let t=e.newData?.version;if(t===void 0)return null;let n=new URLSearchParams({version:String(t)});return t>1&&n.set(`compare`,String(t-1)),`#/banners/profiles/${e.resourceId}/history?${n}`}function v({current:r}){let g=c();s(g(`audit.title`));let{params:v,setParams:y}=d(h),[b,x]=o([]),[S,C]=o(0),[w,T]=o(()=>Number(v.get(`page`))||1),[E,D]=o(()=>Number(v.get(`limit`))||25),[O,k]=o(!0),[A,j]=o(()=>v.get(`q`)??``),[M,N]=o(null),P=(e,t,n)=>{k(!0),m.list({page:e,limit:t,...n?{q:n}:{}}).then(e=>{x(e.items),C(e.total)}).catch(()=>{}).finally(()=>k(!1))};t(()=>{P(w,E,A)},[w,E]);let F=n(!0);t(()=>{if(F.current){F.current=!1;return}let e=setTimeout(()=>{T(1),P(1,E,A)},300);return()=>clearTimeout(e)},[A]),t(()=>{y({page:w>1?w:void 0,limit:E===25?void 0:E,q:A||void 0})},[w,E,A]);let I=e=>{m.get(e).then(N).catch(()=>{})};return a(i,{children:[a(f,{open:!!M,title:g(`audit.detail.title`),onClose:()=>N(null),fields:M?[{label:g(`audit.col.time`),value:new Date(M.createdAt).toLocaleString()},{label:g(`audit.col.action`),value:M.action},{label:g(`audit.col.resource`),value:M.resourceType},{label:g(`audit.col.resourceId`),value:M.resourceId?a(`span`,{class:`font-mono text-xs`,children:M.resourceId}):`—`},{label:g(`audit.col.actor`),value:M.userId?a(`span`,{class:`font-mono text-xs`,children:M.userId}):a(`span`,{class:`text-gray-400`,children:g(`audit.actor.system`)})},..._(M)?[{label:``,value:a(`a`,{href:_(M),class:`inline-flex items-center gap-1 text-xs text-blue-600 hover:underline`,children:[a(e,{size:12,"aria-hidden":`true`}),` `,g(`audit.viewHistory`)]})}]:[],{label:g(`audit.detail.oldData`),value:a(p,{value:M.oldData})},{label:g(`audit.detail.newData`),value:a(p,{value:M.newData})}]:[]}),a(u,{loading:O,rows:b,keyFn:e=>e.id,searchValue:A,onSearchChange:j,searchPlaceholder:g(`audit.searchPlaceholder`),total:S,page:w,pageSize:E,onPage:T,onPageSize:e=>{D(e),T(1)},toolbarEnd:a(`button`,{onClick:()=>{l(`/export/audit?format=csv`)},class:`text-sm text-blue-600 hover:underline`,children:g(`common.exportCsv`)}),columns:[{key:`createdAt`,label:g(`audit.col.time`),render:e=>new Date(e.createdAt).toLocaleString()},{key:`action`,label:g(`audit.col.action`)},{key:`resourceType`,label:g(`audit.col.resource`)},{key:`resourceId`,label:g(`audit.col.resourceId`),render:e=>{let t=e;return t.resourceId?a(`button`,{onClick:()=>I(t.id),class:`font-mono text-xs text-blue-600 dark:text-blue-400 hover:underline`,children:[t.resourceId.slice(0,12),`…`]}):`—`}},{key:`userId`,label:g(`audit.col.actor`),render:e=>{let t=e.userId;return t?a(`span`,{class:`font-mono text-xs`,children:t.slice(0,8)}):a(`span`,{class:`text-gray-400`,children:g(`audit.actor.system`)})}}],emptyText:g(`audit.empty`)})]})}export{v as AuditLogPage};
1
+ import{t as e}from"./rotate-ccw-clock-503u3yEE.js";import{A as t,D as n,E as r,M as i,S as a,k as o,o as s,s as c,w as l}from"./index-D7qdwIxs.js";import{n as u,t as d}from"./useHashQuery-DzYBqPIg.js";import{n as f,t as p}from"./RecordDetailModal-4OyHjtux.js";var m={list:e=>{let t=new URLSearchParams;return e?.action&&t.set(`action`,e.action),e?.page&&t.set(`page`,String(e.page)),e?.limit&&t.set(`limit`,String(e.limit)),e?.q&&t.set(`q`,e.q),r(`/audit?${t}`)},get:e=>r(`/audit/${e}`)},h=`#/audit`,g=new Set([`profile:created`,`profile:updated`]);function _(e){if(e.resourceType!==`profile`||!g.has(e.action)||!e.resourceId)return null;let t=e.newData?.version;if(t===void 0)return null;let n=new URLSearchParams({version:String(t)});return t>1&&n.set(`compare`,String(t-1)),`#/banners/profiles/${e.resourceId}/history?${n}`}function v({current:r}){let g=c();s(g(`audit.title`));let{params:v,setParams:y}=d(h),[b,x]=o([]),[S,C]=o(0),[w,T]=o(()=>Number(v.get(`page`))||1),[E,D]=o(()=>Number(v.get(`limit`))||25),[O,k]=o(!0),[A,j]=o(()=>v.get(`q`)??``),[M,N]=o(null),P=(e,t,n)=>{k(!0),m.list({page:e,limit:t,...n?{q:n}:{}}).then(e=>{x(e.items),C(e.total)}).catch(()=>{}).finally(()=>k(!1))};t(()=>{P(w,E,A)},[w,E]);let F=n(!0);t(()=>{if(F.current){F.current=!1;return}let e=setTimeout(()=>{T(1),P(1,E,A)},300);return()=>clearTimeout(e)},[A]),t(()=>{y({page:w>1?w:void 0,limit:E===25?void 0:E,q:A||void 0})},[w,E,A]);let I=e=>{m.get(e).then(N).catch(()=>{})};return a(i,{children:[a(f,{open:!!M,title:g(`audit.detail.title`),onClose:()=>N(null),fields:M?[{label:g(`audit.col.time`),value:new Date(M.createdAt).toLocaleString()},{label:g(`audit.col.action`),value:M.action},{label:g(`audit.col.resource`),value:M.resourceType},{label:g(`audit.col.resourceId`),value:M.resourceId?a(`span`,{class:`font-mono text-xs`,children:M.resourceId}):`—`},{label:g(`audit.col.actor`),value:M.userId?a(`span`,{class:`font-mono text-xs`,children:M.userId}):a(`span`,{class:`text-gray-400`,children:g(`audit.actor.system`)})},..._(M)?[{label:``,value:a(`a`,{href:_(M),class:`inline-flex items-center gap-1 text-xs text-blue-600 hover:underline`,children:[a(e,{size:12,"aria-hidden":`true`}),` `,g(`audit.viewHistory`)]})}]:[],{label:g(`audit.detail.oldData`),value:a(p,{value:M.oldData})},{label:g(`audit.detail.newData`),value:a(p,{value:M.newData})}]:[]}),a(u,{loading:O,rows:b,keyFn:e=>e.id,searchValue:A,onSearchChange:j,searchPlaceholder:g(`audit.searchPlaceholder`),total:S,page:w,pageSize:E,onPage:T,onPageSize:e=>{D(e),T(1)},toolbarEnd:a(`button`,{onClick:()=>{l(`/export/audit?format=csv`)},class:`text-sm text-blue-600 hover:underline`,children:g(`common.exportCsv`)}),columns:[{key:`createdAt`,label:g(`audit.col.time`),render:e=>new Date(e.createdAt).toLocaleString()},{key:`action`,label:g(`audit.col.action`)},{key:`resourceType`,label:g(`audit.col.resource`)},{key:`resourceId`,label:g(`audit.col.resourceId`),render:e=>{let t=e;return t.resourceId?a(`button`,{onClick:()=>I(t.id),class:`font-mono text-xs text-blue-600 dark:text-blue-400 hover:underline`,children:[t.resourceId.slice(0,12),`…`]}):`—`}},{key:`userId`,label:g(`audit.col.actor`),render:e=>{let t=e.userId;return t?a(`span`,{class:`font-mono text-xs`,children:t.slice(0,8)}):a(`span`,{class:`text-gray-400`,children:g(`audit.actor.system`)})}}],emptyText:g(`audit.empty`)})]})}export{v as AuditLogPage};
@@ -1 +1 @@
1
- import{M as e,S as t,k as n,o as r,s as i,x as a}from"./index-BaYVhd1M.js";import{t as o}from"./users-BLTbK4tk.js";function s({current:s}){let{user:c}=a(),l=i();r(l(`changePassword.title`));let[u,d]=n(``),[f,p]=n(``),[m,h]=n(null),[g,_]=n(!1),[v,y]=n(!1),b=()=>u.length<12?l(`changePassword.error.minLength`):u===f?null:l(`changePassword.error.mismatch`);return t(e,{children:t(`div`,{class:`max-w-md`,children:t(`div`,{class:`bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6`,children:[t(`p`,{class:`text-sm text-gray-500 dark:text-gray-400 mb-5`,children:l(`changePassword.hint`)}),g&&t(`div`,{role:`status`,"aria-live":`polite`,class:`mb-4 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg text-sm text-green-700 dark:text-green-400`,children:l(`changePassword.success`)}),m&&t(`div`,{role:`alert`,class:`mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-sm text-red-700 dark:text-red-400`,children:m}),t(`form`,{onSubmit:async e=>{e.preventDefault(),h(null),_(!1);let t=b();if(t)h(t);else if(c?.sub){y(!0);try{await o.update(c.sub,{password:u}),_(!0),d(``),p(``)}catch(e){h(e instanceof Error?e.message:l(`changePassword.error.failed`))}finally{y(!1)}}},class:`space-y-4`,children:[t(`div`,{children:[t(`label`,{for:`new-password`,class:`block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1`,children:l(`changePassword.newPassword`)}),t(`input`,{id:`new-password`,type:`password`,value:u,onInput:e=>d(e.target.value),minLength:12,required:!0,autocomplete:`new-password`,class:`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500`,placeholder:l(`changePassword.newPasswordPlaceholder`)})]}),t(`div`,{children:[t(`label`,{for:`confirm-password`,class:`block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1`,children:l(`changePassword.confirmPassword`)}),t(`input`,{id:`confirm-password`,type:`password`,value:f,onInput:e=>p(e.target.value),required:!0,autocomplete:`new-password`,class:`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500`,placeholder:l(`changePassword.confirmPasswordPlaceholder`)})]}),t(`div`,{class:`flex items-center gap-3 pt-1`,children:[t(`button`,{type:`submit`,disabled:v,class:`bg-blue-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:l(v?`changePassword.submitting`:`changePassword.submit`)}),t(`a`,{href:`#/settings`,class:`text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200`,children:l(`common.cancel`)})]})]})]})})})}export{s as ChangePassword};
1
+ import{M as e,S as t,k as n,o as r,s as i,x as a}from"./index-D7qdwIxs.js";import{t as o}from"./users-CDdO4hYQ.js";function s({current:s}){let{user:c}=a(),l=i();r(l(`changePassword.title`));let[u,d]=n(``),[f,p]=n(``),[m,h]=n(null),[g,_]=n(!1),[v,y]=n(!1),b=()=>u.length<12?l(`changePassword.error.minLength`):u===f?null:l(`changePassword.error.mismatch`);return t(e,{children:t(`div`,{class:`max-w-md`,children:t(`div`,{class:`bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-6`,children:[t(`p`,{class:`text-sm text-gray-500 dark:text-gray-400 mb-5`,children:l(`changePassword.hint`)}),g&&t(`div`,{role:`status`,"aria-live":`polite`,class:`mb-4 p-3 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg text-sm text-green-700 dark:text-green-400`,children:l(`changePassword.success`)}),m&&t(`div`,{role:`alert`,class:`mb-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-sm text-red-700 dark:text-red-400`,children:m}),t(`form`,{onSubmit:async e=>{e.preventDefault(),h(null),_(!1);let t=b();if(t)h(t);else if(c?.sub){y(!0);try{await o.update(c.sub,{password:u}),_(!0),d(``),p(``)}catch(e){h(e instanceof Error?e.message:l(`changePassword.error.failed`))}finally{y(!1)}}},class:`space-y-4`,children:[t(`div`,{children:[t(`label`,{for:`new-password`,class:`block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1`,children:l(`changePassword.newPassword`)}),t(`input`,{id:`new-password`,type:`password`,value:u,onInput:e=>d(e.target.value),minLength:12,required:!0,autocomplete:`new-password`,class:`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500`,placeholder:l(`changePassword.newPasswordPlaceholder`)})]}),t(`div`,{children:[t(`label`,{for:`confirm-password`,class:`block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1`,children:l(`changePassword.confirmPassword`)}),t(`input`,{id:`confirm-password`,type:`password`,value:f,onInput:e=>p(e.target.value),required:!0,autocomplete:`new-password`,class:`w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500`,placeholder:l(`changePassword.confirmPasswordPlaceholder`)})]}),t(`div`,{class:`flex items-center gap-3 pt-1`,children:[t(`button`,{type:`submit`,disabled:v,class:`bg-blue-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors`,children:l(v?`changePassword.submitting`:`changePassword.submit`)}),t(`a`,{href:`#/settings`,class:`text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200`,children:l(`common.cancel`)})]})]})]})})})}export{s as ChangePassword};