customizable-toast-notification 3.11.4 → 3.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +132 -128
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +121 -6
- package/dist/index.esm.mjs +4 -4
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +4 -4
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -6
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/utils/dom.js","../src/utils/id.js","../src/utils/html-sanitizer.js","../src/components/toast-utils.js","../src/components/loader.js","../src/components/toast-utils-core.js","../src/utils/containerRegistry.js","../src/utils/position.js","../src/utils/PausableTimer.js","../src/components/ToastManager.js","../src/components/Toast.js","../src/index.js"],"sourcesContent":["\"use strict\";\n\nimport { generateToastId } from \"./id.js\";\n\nexport async function createElementWithId(tagName, prefix) {\n if (!tagName || !prefix) throw new Error(\"tagName and prefix are required\");\n const el = document.createElement(tagName);\n el.id = generateToastId(prefix);\n return el;\n}\n\nexport async function appendChild(parent, child) {\n if (!parent || !child) return false;\n\n try {\n if (!parent.contains(child)) parent.appendChild(child);\n return true;\n } catch (primaryError) {\n console.warn(\"appendChild primary failed:\", primaryError);\n try {\n parent.insertAdjacentElement(\"beforeend\", child);\n return true;\n } catch (fallbackError) {\n console.warn(\"appendChild fallback failed:\", fallbackError);\n try {\n if (parent === document.body) {\n // AUDIT FIX (M4): cloneNode(true) copies attributes and inline\n // styles but NEVER copies JS-attached event listeners — a toast\n // that lands here via this emergency path would render with no\n // working close button or CTA. This is a genuine last resort\n // (only reached when BOTH the primary appendChild AND\n // insertAdjacentElement already threw), and there's no generic\n // way for this low-level utility to know which listeners the\n // caller attached, so recreating them isn't practical here.\n // What we CAN do is stop silently returning success as if\n // nothing were lost — a clear warning at least gives developers\n // a real diagnostic instead of a toast that mysteriously\n // doesn't respond to clicks.\n console.warn(\n \"appendChild: using last-resort cloneNode fallback — the \" +\n \"appended element's event listeners (close button, CTA \" +\n \"clicks, etc.) will NOT work, since cloneNode() does not \" +\n \"copy JS-attached listeners. This path only runs when both \" +\n \"the primary appendChild and insertAdjacentElement calls \" +\n \"already failed.\",\n );\n const clone = child.cloneNode(true);\n parent.appendChild(clone);\n return true;\n }\n } catch (emergencyError) {\n console.error(\"appendChild emergency failed:\", emergencyError);\n return false;\n }\n }\n }\n return false;\n}\n\nexport async function removeElement(el) {\n if (!el) return true;\n\n try {\n if (el?.parentNode?.id.includes(\"toast-container-\")) {\n el.parentNode.removeChild(el);\n return true;\n }\n } catch {}\n\n try {\n if (el.remove) {\n el.remove();\n return true;\n }\n } catch {}\n\n try {\n Object.assign(el.style, {\n display: \"none\",\n opacity: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n left: \"-9999px\",\n });\n return true;\n } catch {}\n\n return false;\n}\n\nexport async function parseAnimationDuration(duration) {\n if (typeof duration === \"number\" && duration > 0) return duration;\n if (typeof duration === \"string\") {\n if (duration.endsWith(\"s\") && !duration.endsWith(\"ms\")) {\n const parsed = parseFloat(duration) * 1000;\n return parsed > 0 ? parsed : 500;\n }\n const parsed = parseFloat(duration);\n return parsed > 0 ? parsed : 500;\n }\n return 500;\n}\n\nexport function forceReflow(el) {\n try {\n return el?.offsetWidth || 0;\n } catch (error) {\n console.warn(\"Force reflow failed:\", error);\n return 0;\n }\n}\n\nexport function query(selector, root = document) {\n return root.querySelector(selector);\n}\n\nclass LRUCache {\n constructor(maxSize = 200) {\n this.maxSize = maxSize;\n this.map = new Map();\n }\n\n get(key) {\n if (!this.map.has(key)) return undefined;\n const value = this.map.get(key);\n this.map.delete(key);\n this.map.set(key, value);\n return value;\n }\n\n set(key, value) {\n if (this.map.has(key)) this.map.delete(key);\n else if (this.map.size >= this.maxSize) {\n const firstKey = this.map.keys().next().value;\n this.map.delete(firstKey);\n }\n this.map.set(key, value);\n }\n}\n\nconst colorCache = new LRUCache(200);\n\nconst namedColors = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50],\n};\n\nconst precomputedNamedTextColors = {};\nObject.entries(namedColors).forEach(([name, [r, g, b]]) => {\n const lum = (c) => {\n const v = c / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n };\n const L = 0.2126 * lum(r) + 0.7152 * lum(g) + 0.0722 * lum(b);\n const contrastBlack = (L + 0.05) / 0.05;\n const contrastWhite = 1.05 / (L + 0.05);\n precomputedNamedTextColors[name.toLowerCase()] =\n contrastBlack >= contrastWhite ? \"#000000\" : \"#ffffff\";\n});\n\nexport function getDynamicAccessibleTextColorHex(toastBg, opa = 1) {\n if (!toastBg) return \"snow\";\n\n const key = `${toastBg}|${opa}`;\n const cached = colorCache.get(key);\n if (cached) return cached;\n\n if (precomputedNamedTextColors[toastBg?.toLowerCase()]) {\n const textColor = precomputedNamedTextColors[toastBg.toLowerCase()];\n colorCache.set(key, textColor);\n return textColor;\n }\n\n let r, g, b;\n\n // AUDIT FIX (H2): this function previously only understood hex and\n // rgb()/rgba() strings. Anything else — hsl(), a CSS custom property\n // like var(--brand), any modern color syntax — fell straight into the\n // catch block below, which used to assign a RANDOM RGB triplet as the\n // \"background\" driving the black-vs-white text decision. For a function\n // whose entire purpose is accessibility, that meant it could pick white\n // text on a light background (or the reverse) for any color format it\n // didn't recognize, and the choice wasn't even stable between calls for\n // the same input. Two changes: (1) genuinely parse hsl()/hsla() and CSS\n // custom properties instead of giving up on them, (2) for the cases\n // that are still truly unparseable, fall back to a fixed neutral\n // midpoint gray instead of Math.random() — deterministic and\n // reasonable, never actively wrong in a random direction.\n function resolveCssCustomProperty(value) {\n const varMatch = value?.match(/^var\\((--[\\w-]+)(?:\\s*,\\s*(.+))?\\)$/i);\n if (!varMatch) return value;\n try {\n if (\n typeof document !== \"undefined\" &&\n typeof getComputedStyle === \"function\"\n ) {\n const resolved = getComputedStyle(document.documentElement)\n .getPropertyValue(varMatch[1])\n .trim();\n if (resolved) return resolved;\n }\n } catch (e) {}\n // Fall back to the var()'s own declared fallback value, if it had one\n // (e.g. var(--brand, #336699)), before giving up entirely.\n return varMatch[2]?.trim() || value;\n }\n\n function parseToRgb(value) {\n const hexMatch = value?.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3)\n hex = hex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n return {\n r: parseInt(hex.slice(0, 2), 16),\n g: parseInt(hex.slice(2, 4), 16),\n b: parseInt(hex.slice(4, 6), 16),\n };\n }\n\n const rgbMatch = value?.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*[\\d.]+)?\\)/i,\n );\n if (rgbMatch) {\n return {\n r: Number(rgbMatch[1]),\n g: Number(rgbMatch[2]),\n b: Number(rgbMatch[3]),\n };\n }\n\n const hslMatch = value?.match(\n /hsla?\\(\\s*([\\d.]+)(?:deg)?\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%(?:\\s*,\\s*[\\d.]+)?\\)/i,\n );\n if (hslMatch) {\n const h = Number(hslMatch[1]) / 360;\n const s = Number(hslMatch[2]) / 100;\n const l = Number(hslMatch[3]) / 100;\n if (s === 0) {\n const gray = Math.round(l * 255);\n return { r: gray, g: gray, b: gray };\n }\n const hue2rgb = (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n }\n\n return null;\n }\n\n try {\n const resolvedBg = resolveCssCustomProperty(toastBg);\n const parsed = parseToRgb(resolvedBg);\n if (!parsed) throw new Error(\"Unknown color\");\n ({ r, g, b } = parsed);\n } catch {\n // Deterministic neutral fallback — a mid-gray reads reasonably against\n // either black or white text, and critically, gives the SAME answer\n // every time for the same unparseable input instead of a coin flip.\n r = g = b = 128;\n }\n\n r = Math.round(r * opa + 255 * (1 - opa));\n g = Math.round(g * opa + 255 * (1 - opa));\n b = Math.round(b * opa + 255 * (1 - opa));\n\n const rgbToHsl = (r, g, b) => {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b),\n min = Math.min(r, g, b);\n let h,\n s,\n l = (max + min) / 2;\n if (max === min) h = s = 0;\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n }\n h /= 6;\n }\n return [h * 360, s, l];\n };\n const hslToRgb = (h, s, l) => {\n h /= 360;\n let r, g, b;\n if (s === 0) r = g = b = l;\n else {\n const hue2rgb = (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n };\n const luminance = (r, g, b) => {\n const a = [r, g, b].map((v) => {\n v /= 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];\n };\n const contrastRatio = (rgb1, rgb2) => {\n const L1 = luminance(...rgb1);\n const L2 = luminance(...rgb2);\n return (Math.max(L1, L2) + 0.05) / (Math.min(L1, L2) + 0.05);\n };\n const rgbToHex = (r, g, b) =>\n `#${r.toString(16).padStart(2, \"0\")}${g.toString(16).padStart(2, \"0\")}${b\n .toString(16)\n .padStart(2, \"0\")}`;\n\n let [h, s, l] = rgbToHsl(r, g, b);\n const minContrast = 4.5;\n let textL = l < 0.5 ? Math.min(l + 0.5, 1) : Math.max(l - 0.5, 0);\n let [tr, tg, tb] = hslToRgb(h, s, textL);\n\n if (contrastRatio([r, g, b], [tr, tg, tb]) < minContrast) {\n const contrastBlack = contrastRatio([r, g, b], [0, 0, 0]);\n const contrastWhite = contrastRatio([r, g, b], [255, 255, 255]);\n [tr, tg, tb] = contrastBlack >= contrastWhite ? [0, 0, 0] : [255, 255, 255];\n }\n\n const result = rgbToHex(tr, tg, tb);\n colorCache.set(key, result);\n return result;\n}\n","// src/utils/id.js\n\"use strict\";\n\n/**\n * Generate unique ID for DOM elements to avoid conflicts\n * @param {string} prefix - Optional prefix for ID\n * @returns {string} Unique ID\n */\nexport function generateToastId(prefix) {\n const timestamp = Date.now().toString(36); // shorter timestamp\n const random = Math.floor(Math.random() * 0xfffff).toString(36); // short random part\n return `${prefix}-${timestamp}-${random}`;\n}\n","// AUDIT FIX (H1): these used to live inside fallbackSanitize() only, which\n// meant sanitizeHtml()'s DOMPurify branch had no way to reference them —\n// it just used DOMPurify's own (much broader) default allowlist instead.\n// Same allowHtml:true input could sanitize completely differently\n// depending on whether some UNRELATED script on the host page happened to\n// load DOMPurify onto window — a security boundary that was an\n// environmental accident rather than a deliberate, consistent policy.\n// Hoisting these to module scope makes them the single source of truth\n// for BOTH paths, so the same input gets the same treatment regardless of\n// which sanitizer implementation actually runs.\nconst ALLOWED_TAGS = new Set([\n \"DIV\",\n \"SPAN\",\n \"P\",\n \"BR\",\n \"STRONG\",\n \"B\",\n \"EM\",\n \"I\",\n \"U\",\n \"SMALL\",\n \"UL\",\n \"OL\",\n \"LI\",\n \"A\",\n \"IMG\",\n \"PRE\",\n \"CODE\",\n \"MARK\",\n]);\n// AUDIT FIX (C1 — security): 'style' was previously allowed through with\n// zero validation, letting an attacker-controlled message (allowHtml:true)\n// inject `position:fixed;inset:0;z-index:999999` and render a full-page\n// clickjacking overlay through a toast that already renders at\n// z-index:9999. Inline style is a well-known sanitizer bypass class (see\n// OWASP's XSS Filter Evasion Cheat Sheet). Removed from the allowlist\n// entirely rather than attempting partial validation — toasts don't need\n// arbitrary inline styling to be useful, and \"no unchecked style\" is the\n// safe default most reputable sanitizers ship with.\nconst ALLOWED_ATTRS = new Set([\n \"href\",\n \"src\",\n \"alt\",\n \"title\",\n \"class\",\n \"target\",\n \"rel\",\n]);\n\nexport function hasDOMPurify() {\n try {\n if (typeof window !== \"undefined\" && window.DOMPurify) return true;\n } catch (e) {}\n return false;\n}\n\nexport function fallbackSanitize(dirty) {\n if (!dirty || typeof dirty !== \"string\") return \"\";\n\n const blockedTags =\n /<\\/?(script|iframe|object|embed|link|meta|style|form|input|button)[^>]*>/gi;\n let step1 = dirty.replace(blockedTags, \"\");\n\n step1 = step1.replace(/\\s(on\\w+)\\s*=\\s*(['\"])[\\s\\S]*?\\2/gi, \"\");\n\n step1 = step1.replace(\n /(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi,\n \"$1=$2#$2\",\n );\n\n const container = document.createElement(\"div\");\n container.innerHTML = step1;\n\n function sanitizeNode(node) {\n if (node.nodeType === Node.TEXT_NODE) {\n return document.createTextNode(node.nodeValue);\n }\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return null;\n }\n const tag = node.tagName.toUpperCase();\n if (!ALLOWED_TAGS.has(tag)) {\n const frag = document.createDocumentFragment();\n Array.from(node.childNodes).forEach((child) => {\n const sanitized = sanitizeNode(child);\n if (sanitized) frag.appendChild(sanitized);\n });\n return frag;\n }\n const el = document.createElement(node.tagName);\n Array.from(node.attributes || []).forEach((attr) => {\n const name = attr.name.toLowerCase();\n const val = attr.value;\n if (!ALLOWED_ATTRS.has(name)) return;\n if ((name === \"href\" || name === \"src\") && /^\\s*javascript:/i.test(val))\n return;\n if (name === \"src\" && !/^\\s*(https?:|data:image\\/)/i.test(val)) return;\n if (name === \"target\" && val === \"_blank\") {\n el.setAttribute(\n \"rel\",\n (node.getAttribute(\"rel\") || \"\") + \" noopener noreferrer\",\n );\n }\n el.setAttribute(name, val);\n });\n Array.from(node.childNodes).forEach((child) => {\n const sanitizedChild = sanitizeNode(child);\n if (sanitizedChild) el.appendChild(sanitizedChild);\n });\n return el;\n }\n\n const outFrag = document.createDocumentFragment();\n Array.from(container.childNodes).forEach((child) => {\n const s = sanitizeNode(child);\n if (s) outFrag.appendChild(s);\n });\n\n const wrapper = document.createElement(\"div\");\n wrapper.appendChild(outFrag);\n return wrapper.innerHTML;\n}\n\nexport function sanitizeHtml(dirty, opts = {}) {\n if (!dirty) return \"\";\n try {\n if (!opts.forceFallback && hasDOMPurify()) {\n const DOMPurify = window.DOMPurify;\n // AUDIT FIX (H1): previously called DOMPurify.sanitize() with only\n // ADD_ATTR/ALLOWED_URI_REGEXP, meaning tags/attributes were governed\n // by DOMPurify's own broad DEFAULT allowlist — not the tight,\n // deliberately-curated one this library actually promises. Now\n // passing the SAME ALLOWED_TAGS/ALLOWED_ATTRS used by\n // fallbackSanitize(), so a consumer gets identical sanitization\n // behavior whether or not some other script on the page happens to\n // have loaded DOMPurify.\n const cleaned = DOMPurify.sanitize(dirty, {\n ALLOWED_TAGS: Array.from(ALLOWED_TAGS),\n ALLOWED_ATTR: Array.from(ALLOWED_ATTRS),\n ALLOWED_URI_REGEXP:\n /^(?:(?:https?|mailto|ftp|tel|data):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\n });\n\n // Replicates fallbackSanitize()'s auto rel=\"noopener noreferrer\" on\n // target=\"_blank\" links — DOMPurify doesn't do this automatically,\n // so without this the two paths would still diverge on this one\n // detail even with matching tag/attribute allowlists. Re-parsing the\n // already-clean output (not the original dirty string) so this can\n // only ever tighten, never loosen, what DOMPurify already produced.\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = cleaned;\n wrapper.querySelectorAll('a[target=\"_blank\"]').forEach((a) => {\n const rel = (a.getAttribute(\"rel\") || \"\").split(/\\s+/).filter(Boolean);\n if (!rel.includes(\"noopener\")) rel.push(\"noopener\");\n if (!rel.includes(\"noreferrer\")) rel.push(\"noreferrer\");\n a.setAttribute(\"rel\", rel.join(\" \"));\n });\n return wrapper.innerHTML;\n }\n } catch (err) {}\n return fallbackSanitize(dirty);\n}\n","// src/components/toast-utils.js\n\"use strict\";\n\nimport { parseAnimationDuration } from \"../utils/dom.js\";\nimport { sanitizeHtml } from \"../utils/html-sanitizer.js\";\nimport { createLoader } from \"./loader.js\";\nimport {\n createCTA,\n createCloseButton,\n createProgressBar,\n runToastAnimation,\n} from \"./toast-utils-core.js\";\n\n/**\n * Applies rich styling and content to a toast element.\n * @param {HTMLElement} toast - The toast container element.\n * @param {object} options - Configuration options for the toast.\n * @param {Function} onClose - Callback invoked when the toast closes.\n */\nexport async function applyRichStyling(toast, options, onClose) {\n const durationMs = await parseAnimationDuration(options?.animationDuration);\n\n // Compose className based on provided type (default to \"info\")\n toast.className = `toast toast-${options?.type ?? \"info\"}`;\n\n Object.assign(toast.style, {\n background: options?.backgroundColor,\n padding: \"12px 16px\",\n marginBottom: \"10px\",\n borderRadius: options?.borderRadius,\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n minWidth: \"250px\",\n maxWidth: options?.maxWidth,\n opacity: \"0\",\n position: \"relative\",\n cursor: \"default\",\n boxSizing: \"border-box\",\n userSelect: \"text\",\n transition: `opacity ${options?.animationDuration} ${options?.animationEasing}, transform ${options?.animationDuration} ${options?.animationEasing}`,\n transform: \"translateY(20px)\",\n zIndex: \"9999\",\n });\n // Accessibility settings\n toast.setAttribute(\"role\", \"alert\");\n toast.setAttribute(\"aria-live\", \"polite\");\n toast.tabIndex = 0; // Make focusable for accessibility if needed\n\n toast._animationDuration = durationMs;\n\n const messageSpan = document.createElement(\"span\");\n\n if (options?.wrapText) {\n Object.assign(messageSpan.style, {\n display: \"block\",\n whiteSpace: \"normal\",\n });\n } else {\n Object.assign(messageSpan.style, {\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: \"3\",\n whiteSpace: \"nowrap\",\n });\n }\n\n Object.assign(messageSpan.style, {\n flex: \"1\",\n padding: options?.fontPadding,\n fontFamily: options?.fontFamily,\n fontSize: options?.fontSize,\n fontWeight: options?.fontWeight,\n lineHeight: options?.fontLineHeight,\n color: options?.textColor,\n userSelect: \"text\",\n wordBreak: \"break-word\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n // AUDIT FIX (C4): display/WebkitLineClamp/WebkitBoxOrient used to be\n // re-applied here unconditionally, silently overwriting whatever the\n // wrapText conditional above had just set — meaning wrapText:\"normal\"\n // never actually worked; every toast truncated to 3 lines regardless.\n // Those three properties are already correctly set by the if/else block\n // above based on options.wrapText, so they're intentionally NOT\n // repeated here anymore.\n });\n\n const allowHtml = !!options.allowHtml; // opt-in flag\n const rawMessage = options.message ?? \"\";\n\n // If a loader is requested as part of the message, create it safely\n if (options.loader || options.showLoader) {\n // createLoader returns an element (see new function below)\n const loaderEl = createLoader(options.loader || {});\n // Put loader before message content\n messageSpan.appendChild(loaderEl);\n // Small spacer\n const spacer = document.createElement(\"span\");\n spacer.style.display = \"inline-block\";\n spacer.style.width = \"8px\";\n messageSpan.appendChild(spacer);\n }\n\n // If allowHtml is explicitly true, sanitize and set innerHTML, otherwise use textContent\n if (\n allowHtml &&\n typeof rawMessage === \"string\" &&\n rawMessage.trim().length > 0\n ) {\n try {\n const sanitized = sanitizeHtml(rawMessage);\n // Use DOM APIs to set sanitized HTML safely\n const tmp = document.createElement(\"div\");\n tmp.innerHTML = sanitized;\n // Move children to messageSpan to avoid re-parsing at outer scope\n while (tmp.firstChild) {\n messageSpan.appendChild(tmp.firstChild);\n }\n } catch (err) {\n console.warn(\n \"HTML message sanitization failed, falling back to text:\",\n err\n );\n messageSpan.textContent = rawMessage;\n }\n } else {\n // default safe text mode\n messageSpan.textContent = String(rawMessage);\n }\n\n // set aria + title\n messageSpan.setAttribute(\"aria-label\", \"Toast Notification Center\");\n messageSpan.setAttribute(\n \"title\",\n typeof rawMessage === \"string\"\n ? rawMessage.replace(/<[^>]+>/g, \"\")\n : String(rawMessage)\n );\n toast.appendChild(messageSpan);\n\n if (options?.cta && Object.keys(options.cta).length !== 0) {\n createCTA(toast, options, onClose);\n }\n\n if (options?.showCloseButton) {\n createCloseButton(toast, options, onClose);\n }\n\n if (options?.showProgressBar) {\n createProgressBar(toast, options);\n }\n\n runToastAnimation(toast);\n}\n\n/**\n * Creates an emergency toast as a safe fallback.\n * @param {object} options - Configuration options for the toast.\n * @param {Function} onClose - Callback invoked when the toast closes.\n * @returns {Promise<HTMLElement|null>}\n */\nexport async function createEmergencyToast(options, onClose) {\n try {\n const emergency = document.createElement(\"div\");\n Object.assign(emergency.style, {\n background: \"#333\",\n color: \"white\",\n padding: \"10px 15px\",\n position: \"fixed\",\n top: \"20px\",\n right: \"20px\",\n zIndex: \"99999\",\n borderRadius: \"3px\",\n maxWidth: \"250px\",\n wordWrap: \"break-word\",\n boxShadow: \"0 2px 10px rgba(0,0,0,0.3)\",\n cursor: \"pointer\",\n });\n\n const innerWrapper = document.createElement(\"div\");\n const msgEl = document.createElement(\"span\");\n msgEl.style.display = \"inline-block\";\n if (options.allowHtml) {\n msgEl.innerHTML = sanitizeHtml(\n String(options.message || \"Emergency Toast Showing!\")\n );\n } else {\n msgEl.textContent = String(\n options.message || \"Emergency Toast Creation Showing!\"\n );\n }\n innerWrapper.appendChild(msgEl);\n\n // add close X via textContent to avoid innerHTML\n const closeSpan = document.createElement(\"span\");\n closeSpan.style.cssText =\n \"float: right; margin-left: 10px; font-weight: bold;\";\n closeSpan.textContent = \"×\";\n innerWrapper.appendChild(closeSpan);\n\n while (emergency.firstChild) emergency.removeChild(emergency.firstChild);\n emergency.appendChild(innerWrapper);\n closeSpan.onclick = () => {\n emergency.remove();\n onClose(emergency);\n };\n\n document.body.appendChild(emergency);\n setTimeout(() => {\n emergency.remove();\n onClose(emergency);\n }, options?.duration);\n\n return emergency;\n } catch (error) {\n console.error(\"Emergency toast creation failed:\", error);\n setTimeout(() => {\n alert(options?.message || \"Emergency Toast Creation Showing!\");\n onClose(null);\n }, 100);\n return null;\n }\n}\n","// src/components/loader.js\nexport function createLoader(opts = {}) {\n const size = opts.size || 14;\n const color = opts.color || \"currentColor\";\n const labelText = opts.text || \"\";\n const wrapper = document.createElement(\"span\");\n wrapper.className = \"toast-loader\";\n wrapper.style.display = \"inline-flex\";\n wrapper.style.alignItems = \"center\";\n wrapper.style.gap = \"8px\";\n\n const svgNS = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(svgNS, \"svg\");\n svg.setAttribute(\"width\", String(size));\n svg.setAttribute(\"height\", String(size));\n svg.setAttribute(\"viewBox\", \"0 0 50 50\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n // spinner circle\n const circle = document.createElementNS(svgNS, \"circle\");\n circle.setAttribute(\"cx\", \"25\");\n circle.setAttribute(\"cy\", \"25\");\n circle.setAttribute(\"r\", \"20\");\n circle.setAttribute(\"fill\", \"none\");\n circle.setAttribute(\"stroke\", color);\n circle.setAttribute(\"stroke-width\", \"4\");\n circle.setAttribute(\"stroke-linecap\", \"round\");\n circle.style.opacity = \"0.85\";\n circle.style.strokeDasharray = \"90\";\n circle.style.strokeDashoffset = \"60\";\n circle.style.transformOrigin = \"center\";\n circle.style.animation = \"toast-spinner 1s linear infinite\";\n\n svg.appendChild(circle);\n wrapper.appendChild(svg);\n\n if (labelText) {\n const lbl = document.createElement(\"span\");\n lbl.style.fontSize = \"13px\";\n lbl.textContent = labelText;\n wrapper.appendChild(lbl);\n }\n\n // add minimal spinner keyframes if not present\n if (!document.getElementById(\"toast-spinner-styles\")) {\n const st = document.createElement(\"style\");\n st.id = \"toast-spinner-styles\";\n st.innerHTML = `@keyframes toast-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }`;\n document.head.appendChild(st);\n }\n\n return wrapper;\n}\n","\"use strict\";\n\nexport function createCTA(toast, options, onClose) {\n const rawCfg = options?.cta;\n if (!rawCfg) return;\n\n // AUDIT FIX (L2): this used to mutate `options.cta` directly\n // (`cfg.label = ...` below writes straight onto the caller's own\n // object). If a consumer reuses the same cta config object across\n // multiple createToast() calls — a natural pattern, e.g. defining a\n // button config once and reusing it — the fallback label mutation from\n // the first toast would leak into every later call, even ones that\n // originally had no label at all. Working on a shallow copy means the\n // caller's object is never touched.\n const cfg = { ...rawCfg };\n\n if (!cfg.label) {\n cfg.label = \"CTA Label Missing!\";\n }\n\n const isLink = !!cfg.href && cfg.variant === \"link\";\n const el = document.createElement(isLink ? \"a\" : \"button\");\n\n if (isLink) {\n el.href = cfg.href;\n if (cfg.target) el.target = cfg.target;\n el.rel = cfg.rel || (cfg.target === \"_blank\" ? \"noopener noreferrer\" : \"\");\n } else {\n el.type = \"button\";\n }\n\n el.setAttribute(\"aria-label\", cfg.ariaLabel || cfg.label);\n\n Object.assign(el.style, {\n marginLeft: \"10px\",\n padding: \"6px 10px\",\n borderRadius: \"6px\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n lineHeight: \"1\",\n border: \"1px solid rgba(255,255,255,0.35)\",\n color: options.textColor || \"#fff\",\n background: \"rgba(255,255,255,0.15)\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: \"0\",\n });\n\n el.textContent = cfg.label;\n\n const onClick = async (e) => {\n try {\n if (typeof cfg.onClick === \"function\") {\n const res = cfg.onClick(e);\n if (res?.then) await res;\n }\n } finally {\n if (cfg.autoClose !== false) onClose(toast);\n }\n };\n\n el.addEventListener(\"click\", onClick);\n\n el._cleanup = () => el.removeEventListener(\"click\", onClick);\n\n toast.appendChild(el);\n}\n\nexport function createCloseButton(toast, options, onClose) {\n const closeBtn = document.createElement(\"button\");\n closeBtn.setAttribute(\"aria-label\", \"Close notification\");\n closeBtn.setAttribute(\"title\", \"Close\");\n closeBtn.textContent = \"×\";\n\n Object.assign(closeBtn.style, {\n background: \"none\",\n border: \"none\",\n color: options.textColor || \"white\",\n fontSize: \"18px\",\n marginLeft: \"10px\",\n cursor: \"pointer\",\n });\n\n const onClick = () => onClose(toast);\n closeBtn.addEventListener(\"click\", onClick);\n\n toast._cleanupCloseButton = () => {\n closeBtn.removeEventListener(\"click\", onClick);\n };\n\n toast.appendChild(closeBtn);\n}\n\nexport function createProgressBar(toast, options) {\n const progressBar = document.createElement(\"div\");\n const borderRadiusStr = options.borderRadius || 0;\n const borderRadiusNum = parseInt(borderRadiusStr, 10);\n const leftVal = borderRadiusNum ? \"12px\" : \"0\";\n const minSafeOffset = borderRadiusNum ? 12 : 0;\n const radiusOffset = Math.max(borderRadiusNum - 10, minSafeOffset);\n const finalWidth = borderRadiusNum\n ? `calc(100% - ${radiusOffset}px)`\n : \"100%\";\n\n Object.assign(progressBar.style, {\n position: \"absolute\",\n left: `${leftVal}`,\n height: options.progressHeight || \"4px\",\n background: options.progressColor || \"rgba(255, 255, 255, 0.3)\",\n width: `${finalWidth}`,\n transition: `width ${options.duration || 1800}ms linear`,\n [options.progressPosition === \"top\" ? \"top\" : \"bottom\"]: \"0\",\n borderRadius: options.borderRadius || \"4px\",\n });\n\n toast.appendChild(progressBar);\n\n if (typeof progressBar.animate === \"function\") {\n toast._progressAnimation = progressBar.animate(\n [{ width: finalWidth }, { width: \"0%\" }],\n {\n duration: Number(options.duration) || 1800,\n easing: \"linear\",\n fill: \"forwards\",\n delay: 50,\n },\n );\n } else {\n progressBar.style.transition = `width ${options.duration || 1800}ms linear`;\n setTimeout(() => {\n progressBar.offsetWidth;\n progressBar.style.width = \"0%\";\n }, 50);\n }\n}\n\nexport function runToastAnimation(toast) {\n setTimeout(() => {\n requestAnimationFrame(() => {\n toast.style.opacity = \"1\";\n toast.style.transform = \"translateY(0)\";\n });\n }, 50);\n}\n","// src/utils/containerRegistry.js\n\"use strict\";\n\nconst containerRegistry = new Map(); // id -> HTMLElement\nconst containerLocks = new Map(); // id -> Promise<HTMLElement>\n\n/**\n * Normalize a position string to a canonical key (id-safe, stable).\n */\nexport function normalizePositionKey(position) {\n // lower-case, trim, unify separators, alias \"below\" -> \"bottom\"\n const raw = String(position).toLowerCase().trim();\n const aliased = raw.replace(/\\bbelow\\b/g, \"bottom\");\n return aliased\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-{2,}/g, \"-\");\n}\n\n/**\n * Canonical container id\n */\nexport function getContainerId(position) {\n return `toast-container-${normalizePositionKey(position)}`;\n}\n\n/**\n * Atomically get or create a single container per canonical id.\n */\nexport async function getOrCreateToastContainer(options, setPosition) {\n const id = getContainerId(options.position);\n // If a creation is in-flight, await it\n if (containerLocks.has(id)) {\n return containerLocks.get(id);\n }\n\n const p = (async () => {\n // 1) Prefer registry cache if still connected\n const cached = containerRegistry.get(id);\n if (cached?.isConnected) {\n return cached;\n }\n\n // 2) Find existing in DOM\n let el = document.getElementById(id); // unique by spec, but may return first if duplicates exist\n if (el && !el.isConnected) {\n // re-attach if detached\n document.body.appendChild(el);\n }\n\n // 3) If not found, create\n if (!el) {\n el = document.createElement(\"div\");\n el.id = id;\n el.setAttribute(\"role\", \"status\"); // polite + atomic by default\n el.setAttribute(\"aria-atomic\", \"true\"); // explicit for consistency\n el.style.position = \"fixed\";\n el.style.zIndex = \"9999\";\n el.style.inset = \"auto 10px 10px auto\";\n el.style.display = \"flex\";\n el.style.justifyContent = \"space-between\";\n el.style.alignItems = \"center\";\n el.style.flexDirection = \"column\";\n el.style.overflow = \"hidden\";\n // Position with provided helper\n if (typeof setPosition === \"function\") {\n await setPosition(el, options);\n }\n document.body.appendChild(el);\n } else {\n // Ensure base styles and (re)apply position in case options changed\n el.style.position = el.style.position || \"fixed\";\n el.style.zIndex = el.style.zIndex || \"9999\";\n if (typeof setPosition === \"function\") {\n await setPosition(el, options);\n }\n }\n\n // 4) If somehow duplicates exist, keep the first and remove the rest\n // getElementById would have returned the first; clean up others proactively\n const all = document.querySelectorAll(`#${id}`);\n if (all.length > 1) {\n for (let i = 1; i < all.length; i++) {\n try {\n all[i].remove();\n } catch {}\n }\n }\n\n containerRegistry.set(id, el);\n return el;\n })();\n\n containerLocks.set(id, p);\n try {\n const out = await p;\n return out;\n } finally {\n // Clear the lock so future calls can re-enter if needed\n containerLocks.delete(getContainerId(options.position));\n }\n}\n","\"use strict\";\n\nexport async function setPosition(container, options) {\n if (!container || !options.position) {\n throw new Error(\"Invalid container or position!\");\n }\n\n resetContainerStyles(container);\n const positionFlags = parsePosition(options.position);\n\n if (handleFullWidthPositions(container, options, positionFlags)) return;\n if (handleCenterPositions(container, positionFlags)) return;\n\n applyStandardPositioning(container, positionFlags);\n}\n\nfunction resetContainerStyles(container) {\n container.style.top = \"auto\";\n container.style.bottom = \"auto\";\n container.style.left = \"auto\";\n container.style.right = \"auto\";\n container.style.transform = \"none\";\n}\n\nfunction parsePosition(position) {\n const pos = position.toLowerCase().trim();\n return {\n hasTop: pos.includes(\"top\"),\n hasBottom: pos.includes(\"bottom\") || pos.includes(\"below\"),\n hasLeft: pos.includes(\"left\"),\n hasRight: pos.includes(\"right\"),\n hasCenter: pos.includes(\"center\"),\n hasFullWidth:\n pos.includes(\"top-full-width\") ||\n pos.includes(\"bottom-full-width\") ||\n pos.includes(\"fullwidth\"),\n };\n}\n\nfunction handleFullWidthPositions(container, options, flags) {\n if (!flags.hasFullWidth) return false;\n\n // AUDIT FIX (L5): options.maxWidth was previously set to \"100vw\"\n // unconditionally here, before checking whether hasTop/hasBottom\n // actually matched. For the undocumented bare \"fullwidth\" value (no\n // top-/bottom- prefix), neither branch below matches, this function\n // returns false, and positioning falls through to the normal\n // small-toast logic further down — but maxWidth had already been\n // mutated to 100vw, leaving a 100vw-wide toast positioned as if it\n // were a normal small one. Moving the mutation inside each branch\n // means it only happens when full-width positioning is actually\n // being applied.\n if (flags.hasTop) {\n options.maxWidth = \"100vw\";\n container.style.top = \"10px\";\n container.style.left = \"10px\";\n container.style.right = \"10px\";\n return true;\n }\n\n if (flags.hasBottom) {\n options.maxWidth = \"100vw\";\n container.style.bottom = \"10px\";\n container.style.left = \"10px\";\n container.style.right = \"10px\";\n return true;\n }\n\n return false;\n}\n\nfunction handleCenterPositions(container, flags) {\n if (!flags.hasCenter) return false;\n\n if (flags.hasTop && !flags.hasLeft && !flags.hasRight) {\n container.style.top = \"10px\";\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n return true;\n }\n\n if (flags.hasBottom && !flags.hasLeft && !flags.hasRight) {\n container.style.bottom = \"10px\";\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n return true;\n }\n\n if (flags.hasLeft && !flags.hasTop && !flags.hasBottom) {\n container.style.left = \"10px\";\n container.style.top = \"50%\";\n container.style.transform = \"translateY(-50%)\";\n return true;\n }\n\n if (flags.hasRight && !flags.hasTop && !flags.hasBottom) {\n container.style.right = \"10px\";\n container.style.top = \"50%\";\n container.style.transform = \"translateY(-50%)\";\n return true;\n }\n\n if (!flags.hasLeft && !flags.hasRight && !flags.hasTop && !flags.hasBottom) {\n container.style.top = \"50%\";\n container.style.left = \"50%\";\n container.style.transform = \"translate(-50%, -50%)\";\n return true;\n }\n\n return false;\n}\n\nfunction applyStandardPositioning(container, flags) {\n if (flags.hasBottom) {\n container.style.bottom = \"10px\";\n } else if (flags.hasTop) {\n container.style.top = \"10px\";\n }\n\n if (flags.hasRight) {\n container.style.right = \"10px\";\n } else if (flags.hasLeft) {\n container.style.left = \"10px\";\n } else {\n if (!flags.hasBottom && !flags.hasTop) {\n container.style.bottom = \"10px\";\n }\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n }\n}\n","// src/utils/PausableTimer.js\n\"use strict\";\n\nexport class PausableTimer {\n constructor(callback, delay) {\n this.callback = callback;\n this.delay = delay;\n this.remaining = delay;\n this.startTime = null;\n this.timeoutId = null;\n this.isPaused = false;\n this.isCompleted = false;\n }\n\n start() {\n if (this.isCompleted || this.timeoutId) return this;\n this.startTime = Date.now();\n this.timeoutId = setTimeout(() => {\n this.isCompleted = true;\n this.timeoutId = null;\n this.callback();\n }, this.remaining);\n return this;\n }\n\n pause() {\n if (this.isPaused || !this.timeoutId || this.isCompleted) return this;\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n this.remaining -= Date.now() - this.startTime;\n this.remaining = Math.max(0, this.remaining); // prevent negative\n this.isPaused = true;\n return this;\n }\n\n resume() {\n if (!this.isPaused || this.isCompleted) return this;\n this.isPaused = false;\n this.start();\n return this;\n }\n\n clear() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n this.isCompleted = true;\n return this;\n }\n\n getRemainingTime() {\n if (this.isCompleted) return 0;\n if (this.isPaused) return this.remaining;\n if (!this.timeoutId) return this.delay;\n return Math.max(0, this.remaining - (Date.now() - this.startTime));\n }\n}\n","// src/components/ToastManager.js\n\"use strict\";\n\nimport { createToastElement } from \"./Toast.js\";\nimport { removeElement } from \"../utils/dom.js\";\nimport { createEmergencyToast } from \"./toast-utils.js\";\nimport { getOrCreateToastContainer } from \"../utils/containerRegistry.js\";\nimport { setPosition } from \"../utils/position.js\";\nimport { PausableTimer } from \"../utils/PausableTimer.js\";\n\n// Config\nconst MAX_VISIBLE = 3;\n\n// State\nconst active = new Map(); // key -> { outer, toast, count, timeout }\nconst pending = new Map(); // key -> { options, count, rafId }\nconst queue = []; // [{ options, key, count }]\nlet visibleCount = 0;\n\n// djb2 hash function for message deduplication\nfunction hashString(str) {\n let h = 5381;\n for (let i = 0; i < str.length; i++) h = (h << 5) + h + str.charCodeAt(i);\n return h >>> 0;\n}\n\n/**\n * Creates a unique key for a toast notification based on its type, message, and position.\n * This key is used to identify and deduplicate identical toast notifications.\n * @param {Object} options - Toast options with type, message, and position.\n * @returns {string} A unique key for the toast notification.\n */\nfunction makeKey(options = {}) {\n const type = String(options.type).trim().toLowerCase();\n const messageHash = hashString(String(options.message || \"\")).toString(16);\n const position = String(options.position).trim().toLowerCase();\n\n return `${type}|${messageHash}|${position}`;\n}\n\n/**\n * Shows a toast notification with the given options.\n * If there is already an active toast with the same type, message, and position,\n * it will be grouped immediately and the count will be incremented.\n * If there is already a pending toast with the same type, message, and position,\n * it will be coalesced and the count will be incremented.\n * If there is no capacity left (i.e. the number of visible toasts is at the maximum),\n * the grouped request will be enqueued and processed later.\n * @param {Object} options - Toast options with type, message, and position.\n * @returns {Promise<void>} A promise that resolves when the toast is fully created and displayed.\n */\nexport async function showToast(options = {}) {\n try {\n const key = makeKey(options);\n\n // If already active: group immediately\n if (active.has(key)) {\n const data = active.get(key);\n if (!data) throw new Error(`Active toast with key ${key} not found`);\n data.count++;\n\n // Reset timer with new duration\n data.timer.clear();\n data.timer = createDismissTimer(data.toast, options);\n await setupPauseOnHover(data);\n await updateBadge(data);\n return;\n }\n\n // If coalescing is already scheduled for this key, just increment the pending count\n if (pending.has(key)) {\n const current = pending.get(key);\n if (!current) throw new Error(`Pending toast with key ${key} not found`);\n current.count++;\n return;\n }\n\n // Start coalescing identical calls in the same frame\n const entry = { options, count: 1, rafId: 0 };\n pending.set(key, entry);\n\n entry.rafId = requestAnimationFrame(async () => {\n // finalize batch for this key\n const current = pending.get(key);\n if (!current) return;\n pending.delete(key);\n\n // If capacity full, enqueue the grouped request\n if (visibleCount >= MAX_VISIBLE) {\n queue.push({ options: current.options, key, count: current.count });\n await drainQueue();\n return;\n }\n\n // Otherwise create immediately with the grouped count\n try {\n await createOne(current.options, key, current.count);\n } catch (error) {\n console.error(\"showToast failed:\", error);\n }\n });\n } catch (error) {\n console.error(\"showToast failed:\", error);\n }\n}\n\n/**\n * Creates a single toast notification with the given options and initial count.\n * Will create and mount the toast element, and setup a timer to auto-dismiss.\n * If the toast creation fails, it will fallback to an emergency toast.\n * @param {Object} options - Toast options with type, message, and position.\n * @param {string} key - Unique key for the toast.\n * @param {number} initialCount - Initial count for the toast.\n * @returns {Promise<void>} A promise that resolves when the toast is fully created and displayed.\n */\nasync function createOne(options, key, initialCount) {\n try {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object\");\n }\n\n visibleCount++;\n\n const container = await getOrCreateToastContainer(options, setPosition);\n if (!container) {\n throw new Error(\"Failed to create toast container\");\n }\n\n // Build the toast element\n const toast = await createToastElement(options, closeToast);\n if (!toast) {\n throw new Error(\"Toast element creation failed\");\n }\n\n // Outer wrapper (badge surface; visible overflow)\n const outer = document.createElement(\"div\");\n Object.assign(outer.style, {\n position: \"relative\",\n display: \"inline-block\",\n overflow: \"visible\",\n marginBottom: \"10px\",\n zIndex: \"0\",\n width: \"100%\",\n });\n\n // Inner wrapper (clip progress bar & rounded corners)\n const inner = document.createElement(\"div\");\n Object.assign(inner.style, {\n position: \"relative\",\n overflow: \"hidden\",\n // borderRadius: options.borderRadius || \"8px\",\n zIndex: \"1\",\n });\n\n inner.appendChild(toast);\n outer.appendChild(inner);\n\n // Mount\n if (container.id.includes(\"toast-container-\")) {\n container.appendChild(outer);\n }\n\n // Determine if should pause on hover (default: true if has CTA)\n const shouldPauseOnHover =\n options.pauseOnHover !== false &&\n (options.pauseOnHover === true || !!options.cta);\n\n // Track\n const data = {\n outer,\n toast,\n count: Math.max(1, Math.floor(initialCount ?? 0)),\n timeout: null,\n pauseOnHover: shouldPauseOnHover,\n };\n active.set(key, data);\n toast._key = key;\n\n if (data.count > 1) await updateBadge(data);\n\n // Create and start timer\n data.timer = createDismissTimer(toast, options);\n await setupPauseOnHover(data);\n } catch (err) {\n console.error(\"Something went wrong: \", err);\n visibleCount = Math.max(0, visibleCount - 1);\n const el =\n document.querySelector('[id^=\"toast-container-\"]') || document.body;\n el.appendChild(await createEmergencyToast(options, closeToast));\n }\n}\n\n/**\n * Dismiss (close) the most recently shown toast.\n * - Finds the most recently appended toast element across containers.\n * - Calls closeToast on it (which handles timers, cleanup, and queue drain).\n * - Returns a Promise that resolves when the close completes.\n */\nexport async function dismissMostRecent() {\n try {\n // If no active toasts, nothing to dismiss\n if (active.size === 0) return;\n\n // Strategy: find the last inserted element in DOM among all containers.\n // Iterate containers and pick lastElementChild of container that is a toast wrapper.\n let lastToastEl = null;\n\n const containers = document.querySelectorAll('[id^=\"toast-container-\"]');\n containers.forEach((container) => {\n const children = Array.from(container.children || []);\n if (children.length === 0) return;\n // AUDIT FIX (L3): toasts are always appended (never prepended), so\n // the LAST child in DOM order is the most recently created one.\n // children.at(0) — the previous behavior — was actually the OLDEST\n // visible toast, the opposite of what \"dismissMostRecent\" promises.\n const candidate = children.at(-1);\n if (candidate) {\n lastToastEl = candidate.querySelector('[id^=\"toast-\"]') || candidate;\n }\n });\n\n if (!lastToastEl) {\n // Same fix applied to the Map-based fallback: Map preserves\n // insertion order, so the LAST entry is the most recently created\n // toast, not the first.\n const entries = Array.from(active.entries());\n if (entries.length > 0) {\n const [, data] = entries.at(-1);\n lastToastEl =\n data.toast ||\n (data.outer && data.outer.querySelector('[id^=\"toast-\"]'));\n }\n }\n\n if (!lastToastEl) return;\n\n // If the element is a wrapper, attempt to find the actual toast element with _key\n const toastEl = lastToastEl._key\n ? lastToastEl\n : lastToastEl.querySelector('[id^=\"toast-\"]') || lastToastEl;\n\n await closeToast(toastEl);\n } catch (err) {\n console.error(\"dismissMostRecent failed:\", err);\n }\n}\n\n/**\n * Close all active toasts immediately.\n * - Clears timers, runs closeToast for each active toast,\n * - Also clears the pending queue.\n */\nexport async function closeAllToasts() {\n try {\n // mark in-progress (consumers can use this flag via module if needed)\n const activeToasts = Array.from(active.values())\n .map((d) => d.toast)\n .filter(Boolean);\n // clear pending queue (so no queued toasts will appear after we remove active)\n queue.length = 0;\n pending.clear();\n\n // Close in clockwise order (oldest first)\n for (const t of activeToasts) {\n try {\n // Sequentially close to preserve animation and queue order\n await closeToast(t);\n } catch (error_inner) {\n console.warn(\"closeAllToasts: failed to close one toast:\", error_inner);\n }\n }\n } catch (err) {\n console.error(\"closeAllToasts failed:\", err);\n }\n}\n\n// Export aliases for clarity / compatibility\nexport const dismiss = dismissMostRecent;\nexport const noop = closeAllToasts;\n\n/**\n * Creates a PausableTimer that auto-closes a toast after a delay.\n * @param {HTMLElement} toast - The toast element to auto-close.\n * @param {Object} options - Toast options with duration.\n * @returns {PausableTimer} A timer that can be paused, resumed, or cleared.\n */\nfunction createDismissTimer(toast, options) {\n const delay = Number(options.duration ?? 1800) + 5;\n const timer = new PausableTimer(async () => await closeToast(toast), delay);\n timer.start();\n return timer;\n}\n\nasync function setupPauseOnHover(data) {\n if (!data.pauseOnHover || !data.outer || !data.timer) return;\n\n const { outer, timer, toast } = data;\n\n const onMouseEnter = () => {\n timer.pause();\n // AUDIT FIX (H3): the progress bar's Web Animations API animation\n // (toast._progressAnimation, set on the INNER toast element by\n // toast-utils-core.js's createProgressBar — not on `outer`, which is\n // just ToastManager's positioning wrapper div around it) previously\n // had no connection to pause-on-hover at all — it ran on its own\n // clock and kept animating to 0% even while the real PausableTimer\n // was genuinely frozen, so the bar visually lied about how much time\n // was actually left. Pausing it here, from the exact same event that\n // pauses the real timer, keeps both in sync.\n toast?._progressAnimation?.pause();\n };\n const onMouseLeave = () => {\n timer.resume();\n toast?._progressAnimation?.play();\n };\n\n const onFocusIn = (e) => {\n if (e.target.matches(\"[tabindex], div, span, button, a\")) {\n timer.pause();\n toast?._progressAnimation?.pause();\n }\n };\n\n const onFocusOut = (e) => {\n if (!outer.contains(e.relatedTarget)) {\n timer.resume();\n toast?._progressAnimation?.play();\n }\n };\n\n // Add event listeners\n outer.addEventListener(\"mouseenter\", onMouseEnter);\n outer.addEventListener(\"mouseleave\", onMouseLeave);\n outer.addEventListener(\"focusin\", onFocusIn);\n outer.addEventListener(\"focusout\", onFocusOut);\n\n // Store cleanup function\n outer._pauseCleanup = () => {\n outer.removeEventListener(\"mouseenter\", onMouseEnter);\n outer.removeEventListener(\"mouseleave\", onMouseLeave);\n outer.removeEventListener(\"focusin\", onFocusIn);\n outer.removeEventListener(\"focusout\", onFocusOut);\n };\n}\n\n/**\n * Closes a toast notification immediately.\n * If the toast is not found in the active toasts map, this function does nothing.\n * @param {HTMLElement|null} toast - The toast element to close.\n * @returns {Promise<void>} A promise that resolves when the toast is fully removed from the DOM.\n */\nexport async function closeToast(toast) {\n try {\n if (!toast?._key) return;\n const data = active.get(toast._key);\n if (!data) return;\n\n // Clear timer and cleanup pause events\n data.timer?.clear();\n data.outer?._pauseCleanup?.();\n\n active.delete(toast._key);\n visibleCount = Math.max(0, visibleCount - 1);\n\n // Remove badge if present\n const badge = data.outer.querySelector(\".toast-count-badge\");\n if (badge) badge.remove();\n\n // Remove wrapper after transition ends (or fallback)\n await removeWithTransition(data.outer);\n\n // Drain queue after a slot frees\n await drainQueue();\n } catch (error) {\n console.error(\"Closing Toast failed!: \", error);\n }\n}\n\nasync function drainQueue() {\n // Fill available slots; coalesce queued entries against active if they became active meanwhile\n while (visibleCount < MAX_VISIBLE && queue.length) {\n const item = queue.shift();\n if (active.has(item.key)) {\n const data = active.get(item.key);\n data.count += item.count;\n await updateBadge(data);\n continue;\n }\n // Create without awaiting to keep loop responsive; visibleCount is incremented inside createOne\n void createOne(item.options, item.key, item.count);\n }\n}\n\n/**\n * Safely remove an element after its transition ends, with a hard timeout fallback\n * @param {Element} el - The element to remove\n * @returns {Promise<void>} A promise that resolves after the element is removed\n */\nasync function removeWithTransition(el) {\n if (!el) return Promise.resolve();\n\n return new Promise((resolve) => {\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n removeElement(el);\n resolve();\n };\n\n // Listen on the immediate child (inner wrapper) if possible\n const child = el.firstElementChild || el;\n if (!child) return resolve();\n\n const onEnd = (e) => {\n try {\n // Check if the event target is the same element we're listening on\n if (e.target !== child) return;\n // Remove the event listener to prevent multiple triggers\n child.removeEventListener(\"transitionend\", onEnd, true);\n finish();\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n };\n\n // Add the event listener to the child element\n try {\n child.addEventListener(\"transitionend\", onEnd, true);\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n\n // Hard fallback if no transition fires after 700ms\n setTimeout(() => {\n try {\n // Remove the event listener to prevent multiple triggers\n child.removeEventListener(\"transitionend\", onEnd, true);\n finish();\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n }, 700);\n });\n}\n\n/**\n * Updates the badge count on the outer toast wrapper.\n * @param {Object} options Options object containing the outer toast wrapper and the count.\n * @param {HTMLElement} options.outer The outer toast wrapper element.\n * @param {number} options.count The count of identical notifications.\n */\nasync function updateBadge({ outer, count }) {\n if (!outer || !(outer instanceof HTMLElement)) {\n throw new Error(\"updateBadge: outer must be a valid HTMLElement\");\n }\n\n if (count < 2) {\n // Remove the badge if the count is less than 2\n const badge = outer.querySelector(\".toast-count-badge\");\n if (badge) badge.remove();\n return;\n }\n\n let badge = outer.querySelector(\".toast-count-badge\");\n if (!badge) {\n // Create the badge if it doesn't exist\n badge = document.createElement(\"span\");\n badge.className = \"toast-count-badge\";\n badge.setAttribute(\"aria-label\", `${count} identical notifications`);\n\n // Style the badge\n Object.assign(badge.style, {\n position: \"absolute\",\n top: \"6px\",\n right: \"6px\",\n backgroundColor: \"#f44336\",\n color: \"#fff\",\n borderRadius: \"50%\",\n minWidth: \"20px\",\n height: \"20px\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n border: \"2px solid #fff\",\n boxShadow: \"0 2px 6px rgba(0,0,0,0.3)\",\n zIndex: \"2\",\n pointerEvents: \"none\",\n transition: \"transform 150ms ease\",\n });\n\n // Add the badge to the outer toast wrapper\n outer.appendChild(badge);\n }\n\n // Update the badge text content\n badge.textContent = count > 99 ? \"99+\" : String(count);\n\n // Animate the badge by scaling it up and then back down\n try {\n badge.style.transform = \"scale(1.2)\";\n setTimeout(() => (badge.style.transform = \"scale(1)\"), 150);\n } catch (error) {\n console.error(\"updateBadge animation error:\", error);\n }\n}\n","// src/components/Toast.js //# Single responsibility\n\"use strict\";\n\nimport { createElementWithId } from \"../utils/dom.js\";\nimport { applyRichStyling, createEmergencyToast } from \"./toast-utils.js\";\n\n/**\n * Creates a multi-layer toast element with satellite-grade fallbacks\n * @param {Object} options - Toast configuration options\n * @param {Function} onClose - Callback when toast closes\n * @returns {HTMLElement} Toast element\n */\nexport async function createToastElement(options, onClose) {\n const toastContainerSelector = '[id^=\"toast-container-\"]';\n const toastContainer = document.querySelector(toastContainerSelector);\n if (!toastContainer) return null;\n\n let toast;\n const tagName = \"div\";\n const prefix = \"toast\";\n\n // PRIMARY: Full-featured toast\n try {\n toast = await createElementWithId(tagName, prefix);\n await applyRichStyling(toast, options, onClose);\n return toast;\n } catch (error) {\n console.warn(\n \"toast creation failed with error showing fallback one: \",\n error\n );\n // Fallback: create emergency toast\n toast = await createEmergencyToast(options, onClose);\n return toast;\n }\n}\n","\"use strict\";\n\nimport { showToast } from \"./components/ToastManager.js\";\nimport { getOrCreateToastContainer } from \"./utils/containerRegistry.js\";\nimport { getDynamicAccessibleTextColorHex } from \"./utils/dom.js\";\nimport { setPosition } from \"./utils/position.js\";\n\nlet defaultColors = {\n success: \"#28a745\",\n error: \"#dc3545\",\n warning: \"#ffc107\",\n info: \"#17a2b8\",\n};\n\nlet defaultMessages = {\n success: \"Operation completed successfully!\",\n error: \"Something went wrong!\",\n warning: \"Warning message!\",\n info: \"Information message!\",\n};\n\nconst pendingToasts = [];\n\nlet domReady = false;\n\nasync function checkDOMReady() {\n if (domReady) return;\n\n // AUDIT FIX (M2): this was a flat 2500ms delay — confirmed via testing\n // that it does NOT stagger toasts requested before the DOM was ready\n // (they all still appear in a single simultaneous jump, just ~2.5s\n // later); that's not what this delay was doing. What it DOES do is\n // give the page a moment to visually settle before showing a toast\n // that was requested very early (e.g. an error toast fired before\n // layout/paint has happened) — a reasonable goal, but 2500ms is a long,\n // very noticeable wait for a user to see something they'd expect to\n // appear promptly, and the exact number wasn't tied to any real\n // rendering signal. A few hundred ms is plenty of margin for the\n // browser to finish initial layout after DOMContentLoaded.\n const SETTLE_DELAY_MS = 200;\n\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n if (\n document.readyState === \"complete\" ||\n document.readyState === \"interactive\"\n ) {\n domReady = true;\n pendingToasts.forEach((options) =>\n setTimeout(() => createToastNow(options), SETTLE_DELAY_MS),\n );\n pendingToasts.length = 0;\n } else {\n document.addEventListener(\n \"DOMContentLoaded\",\n () => {\n domReady = true;\n pendingToasts.forEach((options) =>\n setTimeout(() => createToastNow(options), SETTLE_DELAY_MS),\n );\n pendingToasts.length = 0;\n },\n { once: true },\n );\n }\n }\n}\n\nasync function createToastNow(options = {}) {\n try {\n const sanitizedOptions = await sanitizeToastOptions(options);\n\n await createFirstToastContainer(sanitizedOptions);\n\n await showToast(sanitizedOptions);\n } catch (error) {\n console.error(\"CreateToast failed:\", error);\n\n const safeMessage =\n typeof options?.message === \"string\" && options?.message !== null\n ? `${options.message.substring(0, 200)} toast creation failed!`\n : \"Toast creation failed!\";\n\n alert(safeMessage);\n }\n}\n\nasync function createToast(options = {}) {\n const isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\n if (!isBrowser) {\n console.warn(\n \"ToastNotification: running in non-browser environment, no DOM available.\",\n );\n return;\n }\n\n await checkDOMReady();\n\n if (!domReady) {\n pendingToasts.push(options);\n return;\n }\n\n await createToastNow(options);\n}\n\nasync function createFirstToastContainer(options) {\n try {\n return await getOrCreateToastContainer(options, setPosition);\n } catch (error) {\n console.error(\"Failed to create toast container:\", error);\n return document.body;\n }\n}\n\nasync function sanitizeToastOptions(options) {\n const contPosition = options?.position?.toLowerCase()?.trim();\n const contMaxWidth =\n contPosition?.includes(\"top-full-width\") ||\n contPosition?.includes(\"bottom-full-width\")\n ? \"100vw\"\n : \"400px\";\n\n const defaults = {\n allowHtml: false,\n sanitizeHtml: true,\n pauseOnHover: undefined,\n duration: 2500,\n position: \"bottom-right\",\n type: \"info\",\n borderRadius: \"50px\",\n backgroundColor: undefined,\n textColor: undefined,\n showCloseButton: true,\n animationDuration: \"0.4s\",\n // AUDIT FIX (L1): animationType removed. It was never read by the\n // actual entrance animation (toast-utils-core.js's runToastAnimation\n // hardcodes a fade+translateY transition) — only src/utils/animateFn.js\n // read this option, and that file was never imported anywhere (dead\n // code, confirmed via repo-wide grep). Deleted animateFn.js alongside\n // this — see the delete instruction in the fix notes.\n animationEasing: \"ease\",\n showProgressBar: true,\n progressColor: undefined,\n progressHeight: \"4px\",\n progressPosition: \"bottom\",\n fontPosition: \"relative\",\n fontPadding: undefined,\n fontBorderRadius: undefined,\n fontBackgroundColor: undefined,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"',\n fontSize: \"14px\",\n fontWeight: \"400\",\n fontLineHeight: \"1.4\",\n fontDirection: \"auto\",\n wrapText: \"normal\",\n maxWidth: contMaxWidth,\n };\n\n const final = {\n ...defaults,\n ...(typeof options === \"object\" && !Array.isArray(options) ? options : {}),\n };\n\n final.message = options?.message ?? final.message;\n\n // AUDIT FIX (M3): backgroundColor, message-default, textColor, and\n // progressColor used to all live in ONE try block. If computing\n // backgroundColor threw (e.g. window.matchMedia unavailable in some\n // non-standard/embedded webview, or mocked incorrectly in a test), the\n // catch swallowed it — but that also skipped the message-default\n // fallback further down, even though THAT computation hadn't failed at\n // all. Splitting into independent try/catch blocks means one field's\n // failure can't silently take out an unrelated one.\n try {\n if (!final.backgroundColor) {\n final.backgroundColor =\n defaultColors?.[final.type] ??\n (window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"#f5f5f5\"\n : \"#111111\");\n }\n } catch (error) {\n console.warn(\"Background color resolution failed:\", error);\n }\n\n try {\n final.message =\n final.message || defaultMessages?.[final.type] || \"No Message Provided!\";\n } catch (error) {\n console.warn(\"Default message resolution failed:\", error);\n }\n\n try {\n if (!final.textColor && final.backgroundColor) {\n final.textColor = getDynamicAccessibleTextColorHex(final.backgroundColor);\n }\n } catch (error) {\n console.warn(\"Text color resolution failed:\", error);\n }\n\n try {\n if (!final.progressColor && final.backgroundColor) {\n final.progressColor =\n final.textColor ||\n getDynamicAccessibleTextColorHex(final.backgroundColor);\n }\n } catch (error) {\n console.warn(\"Progress bar color resolution failed:\", error);\n }\n\n if (typeof final.message !== \"string\") {\n final.message = \"No Message Provided!\";\n }\n\n return final;\n}\n\nfunction setDefaultColors(colors) {\n try {\n if (colors && typeof colors === \"object\" && !Array.isArray(colors)) {\n defaultColors = { ...defaultColors, ...colors };\n }\n } catch (error) {\n console.error(\"setDefaultColors failed:\", error);\n }\n}\n\nfunction setDefaultMessages(messages) {\n try {\n if (messages && typeof messages === \"object\" && !Array.isArray(messages)) {\n defaultMessages = { ...defaultMessages, ...messages };\n }\n } catch (error) {\n console.error(\"setDefaultMessages failed:\", error);\n }\n}\n\nimport { dismiss, noop as managerNoop } from \"./components/ToastManager.js\";\n\nlet closeInProgress = false;\nlet closePromise = null;\n\nasync function runWithClosePriority(fn) {\n if (closeInProgress && closePromise) {\n try {\n await closePromise;\n } catch (closeError) {\n // Intentionally continuing regardless of how the prior close\n // settled — this fn() still needs to run either way. Logging\n // instead of a silent empty catch gives visibility into it instead\n // of hiding a real failure.\n console.warn(\n \"Previous close operation failed (continuing anyway):\",\n closeError,\n );\n }\n }\n return fn();\n}\n\nconst originalCreateToast = createToast;\nasync function createToastWithPriority(options = {}) {\n return runWithClosePriority(() => originalCreateToast(options));\n}\n\nexport { createToastWithPriority as createToast };\n\nexport { setDefaultColors, setDefaultMessages };\nexport const dismissToast = async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await dismiss();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n};\nexport const noopAll = async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await managerNoop();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n};\nexport { dismissToast as dismiss, noopAll as noop };\n\nif (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n // Note: no \"already registered\" guard needed here — this is top-level\n // module code, so it runs exactly once when the module is first\n // evaluated, never again. A guard flag around it was dead weight (it\n // can never be re-entered to guard against).\n const onKeyDown = (e) => {\n if (e.key === \"Escape\" || e.key === \"Esc\") {\n (async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await dismiss();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n })();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown, { passive: true });\n}\n\ntry {\n if (typeof window !== \"undefined\") {\n window.customizableToast = {\n createToast: createToastWithPriority,\n setDefaultColors,\n setDefaultMessages,\n noop: noopAll,\n dismiss: dismissToast,\n };\n }\n} catch (error) {\n console.error(\"Global assignment failed:\", error);\n}\n"],"names":["async","createElementWithId","tagName","prefix","el","document","createElement","id","Date","now","toString","Math","floor","random","generateToastId","colorCache","constructor","maxSize","this","map","Map","get","key","has","value","delete","set","size","firstKey","keys","next","precomputedNamedTextColors","getDynamicAccessibleTextColorHex","toastBg","opa","cached","toLowerCase","textColor","r","g","b","parsed","hexMatch","match","hex","length","split","c","join","parseInt","slice","rgbMatch","Number","hslMatch","h","s","l","gray","round","hue2rgb","p","q","t","parseToRgb","_varMatch$","varMatch","getComputedStyle","resolved","documentElement","getPropertyValue","trim","e","resolveCssCustomProperty","Error","luminance","a","v","pow","contrastRatio","rgb1","rgb2","L1","L2","max","min","rgbToHsl","d","textL","tr","tg","tb","hslToRgb","contrastBlack","contrastWhite","result","rgbToHex","padStart","Object","entries","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","forEach","name","lum","L","ALLOWED_TAGS","Set","ALLOWED_ATTRS","fallbackSanitize","dirty","step1","replace","container","sanitizeNode","node","nodeType","Node","TEXT_NODE","createTextNode","nodeValue","ELEMENT_NODE","tag","toUpperCase","frag","createDocumentFragment","Array","from","childNodes","child","sanitized","appendChild","attributes","attr","val","test","setAttribute","getAttribute","sanitizedChild","innerHTML","outFrag","wrapper","sanitizeHtml","opts","forceFallback","window","DOMPurify","hasDOMPurify","cleaned","sanitize","ALLOWED_ATTR","ALLOWED_URI_REGEXP","querySelectorAll","rel","filter","Boolean","includes","push","err","applyRichStyling","toast","options","onClose","durationMs","duration","endsWith","parseFloat","parseAnimationDuration","animationDuration","className","type","assign","style","background","backgroundColor","padding","marginBottom","borderRadius","overflow","display","alignItems","justifyContent","boxShadow","minWidth","maxWidth","opacity","position","cursor","boxSizing","userSelect","transition","animationEasing","transform","zIndex","tabIndex","_animationDuration","messageSpan","wrapText","whiteSpace","WebkitBoxOrient","WebkitLineClamp","flex","fontPadding","fontFamily","fontSize","fontWeight","lineHeight","fontLineHeight","color","wordBreak","textOverflow","allowHtml","rawMessage","message","loader","showLoader","loaderEl","labelText","text","gap","svgNS","svg","createElementNS","String","circle","strokeDasharray","strokeDashoffset","transformOrigin","animation","lbl","textContent","getElementById","st","head","createLoader","spacer","width","tmp","firstChild","console","warn","cta","rawCfg","cfg","label","isLink","href","variant","target","ariaLabel","marginLeft","border","flexShrink","onClick","res","then","autoClose","addEventListener","_cleanup","removeEventListener","createCTA","showCloseButton","closeBtn","_cleanupCloseButton","createCloseButton","showProgressBar","progressBar","borderRadiusStr","borderRadiusNum","leftVal","minSafeOffset","radiusOffset","finalWidth","left","height","progressHeight","progressColor","progressPosition","animate","_progressAnimation","easing","fill","delay","setTimeout","offsetWidth","createProgressBar","requestAnimationFrame","runToastAnimation","createEmergencyToast","emergency","top","right","wordWrap","innerWrapper","msgEl","closeSpan","cssText","removeChild","onclick","remove","body","error","alert","containerRegistry","containerLocks","getContainerId","normalizePositionKey","getOrCreateToastContainer","setPosition","isConnected","inset","flexDirection","all","i","bottom","resetContainerStyles","positionFlags","pos","hasTop","hasBottom","hasLeft","hasRight","hasCenter","hasFullWidth","parsePosition","flags","handleFullWidthPositions","handleCenterPositions","applyStandardPositioning","PausableTimer","callback","remaining","startTime","timeoutId","isPaused","isCompleted","start","pause","clearTimeout","resume","clear","getRemainingTime","active","pending","queue","visibleCount","showToast","str","charCodeAt","hashString","makeKey","data","count","timer","createDismissTimer","setupPauseOnHover","updateBadge","current","entry","rafId","drainQueue","createOne","initialCount","TypeError","querySelector","createToastElement","closeToast","outer","inner","shouldPauseOnHover","pauseOnHover","timeout","_key","dismiss","lastToastEl","children","candidate","at","toastEl","noop","activeToasts","values","error_inner","onMouseEnter","_toast$_progressAnima","onMouseLeave","_toast$_progressAnima2","play","onFocusIn","_toast$_progressAnima3","matches","onFocusOut","_toast$_progressAnima4","contains","relatedTarget","_pauseCleanup","_data$timer","_data$outer","_data$outer$_pauseCle","call","badge","Promise","resolve","done","finish","_el$parentNode","parentNode","pointerEvents","removeElement","firstElementChild","onEnd","removeWithTransition","item","shift","HTMLElement","defaultColors","success","warning","info","defaultMessages","pendingToasts","domReady","createToastNow","sanitizedOptions","_options$position","contPosition","contMaxWidth","final","undefined","fontPosition","fontBorderRadius","fontBackgroundColor","fontDirection","isArray","_defaultColors","matchMedia","_defaultMessages","sanitizeToastOptions","createFirstToastContainer","safeMessage","substring","setDefaultColors","colors","setDefaultMessages","messages","closeInProgress","closePromise","originalCreateToast","readyState","once","checkDOMReady","createToastWithPriority","fn","closeError","runWithClosePriority","dismissToast","noopAll","managerNoop","onKeyDown","passive","customizableToast","createToast"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/utils/dom.js","../src/utils/id.js","../src/utils/html-sanitizer.js","../src/components/toast-utils.js","../src/components/loader.js","../src/components/toast-utils-core.js","../src/utils/containerRegistry.js","../src/utils/position.js","../src/utils/PausableTimer.js","../src/components/ToastManager.js","../src/components/Toast.js","../src/index.js"],"sourcesContent":["\"use strict\";\n\nimport { generateToastId } from \"./id.js\";\n\nexport async function createElementWithId(tagName, prefix) {\n if (!tagName || !prefix) throw new Error(\"tagName and prefix are required\");\n const el = document.createElement(tagName);\n el.id = generateToastId(prefix);\n return el;\n}\n\nexport async function appendChild(parent, child) {\n if (!parent || !child) return false;\n\n try {\n if (!parent.contains(child)) parent.appendChild(child);\n return true;\n } catch (primaryError) {\n console.warn(\"appendChild primary failed:\", primaryError);\n try {\n parent.insertAdjacentElement(\"beforeend\", child);\n return true;\n } catch (fallbackError) {\n console.warn(\"appendChild fallback failed:\", fallbackError);\n try {\n if (parent === document.body) {\n // AUDIT FIX (M4): cloneNode(true) copies attributes and inline\n // styles but NEVER copies JS-attached event listeners — a toast\n // that lands here via this emergency path would render with no\n // working close button or CTA. This is a genuine last resort\n // (only reached when BOTH the primary appendChild AND\n // insertAdjacentElement already threw), and there's no generic\n // way for this low-level utility to know which listeners the\n // caller attached, so recreating them isn't practical here.\n // What we CAN do is stop silently returning success as if\n // nothing were lost — a clear warning at least gives developers\n // a real diagnostic instead of a toast that mysteriously\n // doesn't respond to clicks.\n console.warn(\n \"appendChild: using last-resort cloneNode fallback — the \" +\n \"appended element's event listeners (close button, CTA \" +\n \"clicks, etc.) will NOT work, since cloneNode() does not \" +\n \"copy JS-attached listeners. This path only runs when both \" +\n \"the primary appendChild and insertAdjacentElement calls \" +\n \"already failed.\",\n );\n const clone = child.cloneNode(true);\n parent.appendChild(clone);\n return true;\n }\n } catch (emergencyError) {\n console.error(\"appendChild emergency failed:\", emergencyError);\n return false;\n }\n }\n }\n return false;\n}\n\nexport async function removeElement(el) {\n if (!el) return true;\n\n try {\n if (el?.parentNode?.id.includes(\"toast-container-\")) {\n el.parentNode.removeChild(el);\n return true;\n }\n } catch {}\n\n try {\n if (el.remove) {\n el.remove();\n return true;\n }\n } catch {}\n\n try {\n Object.assign(el.style, {\n display: \"none\",\n opacity: \"0\",\n pointerEvents: \"none\",\n position: \"absolute\",\n left: \"-9999px\",\n });\n return true;\n } catch {}\n\n return false;\n}\n\nexport async function parseAnimationDuration(duration) {\n if (typeof duration === \"number\" && duration > 0) return duration;\n if (typeof duration === \"string\") {\n if (duration.endsWith(\"s\") && !duration.endsWith(\"ms\")) {\n const parsed = parseFloat(duration) * 1000;\n return parsed > 0 ? parsed : 500;\n }\n const parsed = parseFloat(duration);\n return parsed > 0 ? parsed : 500;\n }\n return 500;\n}\n\nexport function forceReflow(el) {\n try {\n return el?.offsetWidth || 0;\n } catch (error) {\n console.warn(\"Force reflow failed:\", error);\n return 0;\n }\n}\n\nexport function query(selector, root = document) {\n return root.querySelector(selector);\n}\n\nclass LRUCache {\n constructor(maxSize = 200) {\n this.maxSize = maxSize;\n this.map = new Map();\n }\n\n get(key) {\n if (!this.map.has(key)) return undefined;\n const value = this.map.get(key);\n this.map.delete(key);\n this.map.set(key, value);\n return value;\n }\n\n set(key, value) {\n if (this.map.has(key)) this.map.delete(key);\n else if (this.map.size >= this.maxSize) {\n const firstKey = this.map.keys().next().value;\n this.map.delete(firstKey);\n }\n this.map.set(key, value);\n }\n}\n\nconst colorCache = new LRUCache(200);\n\nconst namedColors = {\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n grey: [128, 128, 128],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n rebeccapurple: [102, 51, 153],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50],\n};\n\nconst precomputedNamedTextColors = {};\nObject.entries(namedColors).forEach(([name, [r, g, b]]) => {\n const lum = (c) => {\n const v = c / 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n };\n const L = 0.2126 * lum(r) + 0.7152 * lum(g) + 0.0722 * lum(b);\n const contrastBlack = (L + 0.05) / 0.05;\n const contrastWhite = 1.05 / (L + 0.05);\n precomputedNamedTextColors[name.toLowerCase()] =\n contrastBlack >= contrastWhite ? \"#000000\" : \"#ffffff\";\n});\n\nexport function getDynamicAccessibleTextColorHex(toastBg, opa = 1) {\n if (!toastBg) return \"snow\";\n\n const key = `${toastBg}|${opa}`;\n const cached = colorCache.get(key);\n if (cached) return cached;\n\n if (precomputedNamedTextColors[toastBg?.toLowerCase()]) {\n const textColor = precomputedNamedTextColors[toastBg.toLowerCase()];\n colorCache.set(key, textColor);\n return textColor;\n }\n\n let r, g, b;\n\n // AUDIT FIX (H2): this function previously only understood hex and\n // rgb()/rgba() strings. Anything else — hsl(), a CSS custom property\n // like var(--brand), any modern color syntax — fell straight into the\n // catch block below, which used to assign a RANDOM RGB triplet as the\n // \"background\" driving the black-vs-white text decision. For a function\n // whose entire purpose is accessibility, that meant it could pick white\n // text on a light background (or the reverse) for any color format it\n // didn't recognize, and the choice wasn't even stable between calls for\n // the same input. Two changes: (1) genuinely parse hsl()/hsla() and CSS\n // custom properties instead of giving up on them, (2) for the cases\n // that are still truly unparseable, fall back to a fixed neutral\n // midpoint gray instead of Math.random() — deterministic and\n // reasonable, never actively wrong in a random direction.\n function resolveCssCustomProperty(value) {\n const varMatch = value?.match(/^var\\((--[\\w-]+)(?:\\s*,\\s*(.+))?\\)$/i);\n if (!varMatch) return value;\n try {\n if (\n typeof document !== \"undefined\" &&\n typeof getComputedStyle === \"function\"\n ) {\n const resolved = getComputedStyle(document.documentElement)\n .getPropertyValue(varMatch[1])\n .trim();\n if (resolved) return resolved;\n }\n } catch (e) {}\n // Fall back to the var()'s own declared fallback value, if it had one\n // (e.g. var(--brand, #336699)), before giving up entirely.\n return varMatch[2]?.trim() || value;\n }\n\n function parseToRgb(value) {\n const hexMatch = value?.match(/^#([0-9a-f]{3,8})$/i);\n if (hexMatch) {\n let hex = hexMatch[1];\n if (hex.length === 3)\n hex = hex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n return {\n r: parseInt(hex.slice(0, 2), 16),\n g: parseInt(hex.slice(2, 4), 16),\n b: parseInt(hex.slice(4, 6), 16),\n };\n }\n\n const rgbMatch = value?.match(\n /rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*[\\d.]+)?\\)/i,\n );\n if (rgbMatch) {\n return {\n r: Number(rgbMatch[1]),\n g: Number(rgbMatch[2]),\n b: Number(rgbMatch[3]),\n };\n }\n\n const hslMatch = value?.match(\n /hsla?\\(\\s*([\\d.]+)(?:deg)?\\s*,\\s*([\\d.]+)%\\s*,\\s*([\\d.]+)%(?:\\s*,\\s*[\\d.]+)?\\)/i,\n );\n if (hslMatch) {\n const h = Number(hslMatch[1]) / 360;\n const s = Number(hslMatch[2]) / 100;\n const l = Number(hslMatch[3]) / 100;\n if (s === 0) {\n const gray = Math.round(l * 255);\n return { r: gray, g: gray, b: gray };\n }\n const hue2rgb = (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n return {\n r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),\n g: Math.round(hue2rgb(p, q, h) * 255),\n b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),\n };\n }\n\n return null;\n }\n\n try {\n const resolvedBg = resolveCssCustomProperty(toastBg);\n const parsed = parseToRgb(resolvedBg);\n if (!parsed) throw new Error(\"Unknown color\");\n ({ r, g, b } = parsed);\n } catch {\n // Deterministic neutral fallback — a mid-gray reads reasonably against\n // either black or white text, and critically, gives the SAME answer\n // every time for the same unparseable input instead of a coin flip.\n r = g = b = 128;\n }\n\n r = Math.round(r * opa + 255 * (1 - opa));\n g = Math.round(g * opa + 255 * (1 - opa));\n b = Math.round(b * opa + 255 * (1 - opa));\n\n const rgbToHsl = (r, g, b) => {\n r /= 255;\n g /= 255;\n b /= 255;\n const max = Math.max(r, g, b),\n min = Math.min(r, g, b);\n let h,\n s,\n l = (max + min) / 2;\n if (max === min) h = s = 0;\n else {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n }\n h /= 6;\n }\n return [h * 360, s, l];\n };\n const hslToRgb = (h, s, l) => {\n h /= 360;\n let r, g, b;\n if (s === 0) r = g = b = l;\n else {\n const hue2rgb = (p, q, t) => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];\n };\n const luminance = (r, g, b) => {\n const a = [r, g, b].map((v) => {\n v /= 255;\n return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];\n };\n const contrastRatio = (rgb1, rgb2) => {\n const L1 = luminance(...rgb1);\n const L2 = luminance(...rgb2);\n return (Math.max(L1, L2) + 0.05) / (Math.min(L1, L2) + 0.05);\n };\n const rgbToHex = (r, g, b) =>\n `#${r.toString(16).padStart(2, \"0\")}${g.toString(16).padStart(2, \"0\")}${b\n .toString(16)\n .padStart(2, \"0\")}`;\n\n let [h, s, l] = rgbToHsl(r, g, b);\n const minContrast = 4.5;\n let textL = l < 0.5 ? Math.min(l + 0.5, 1) : Math.max(l - 0.5, 0);\n let [tr, tg, tb] = hslToRgb(h, s, textL);\n\n if (contrastRatio([r, g, b], [tr, tg, tb]) < minContrast) {\n const contrastBlack = contrastRatio([r, g, b], [0, 0, 0]);\n const contrastWhite = contrastRatio([r, g, b], [255, 255, 255]);\n [tr, tg, tb] = contrastBlack >= contrastWhite ? [0, 0, 0] : [255, 255, 255];\n }\n\n const result = rgbToHex(tr, tg, tb);\n colorCache.set(key, result);\n return result;\n}\n","// src/utils/id.js\n\"use strict\";\n\n/**\n * Generate unique ID for DOM elements to avoid conflicts\n * @param {string} prefix - Optional prefix for ID\n * @returns {string} Unique ID\n */\nexport function generateToastId(prefix) {\n const timestamp = Date.now().toString(36); // shorter timestamp\n const random = Math.floor(Math.random() * 0xfffff).toString(36); // short random part\n return `${prefix}-${timestamp}-${random}`;\n}\n","// AUDIT FIX (H1): these used to live inside fallbackSanitize() only, which\n// meant sanitizeHtml()'s DOMPurify branch had no way to reference them —\n// it just used DOMPurify's own (much broader) default allowlist instead.\n// Same allowHtml:true input could sanitize completely differently\n// depending on whether some UNRELATED script on the host page happened to\n// load DOMPurify onto window — a security boundary that was an\n// environmental accident rather than a deliberate, consistent policy.\n// Hoisting these to module scope makes them the single source of truth\n// for BOTH paths, so the same input gets the same treatment regardless of\n// which sanitizer implementation actually runs.\nconst ALLOWED_TAGS = new Set([\n \"DIV\",\n \"SPAN\",\n \"P\",\n \"BR\",\n \"STRONG\",\n \"B\",\n \"EM\",\n \"I\",\n \"U\",\n \"SMALL\",\n \"UL\",\n \"OL\",\n \"LI\",\n \"A\",\n \"IMG\",\n \"PRE\",\n \"CODE\",\n \"MARK\",\n]);\n// AUDIT FIX (C1 — security): 'style' was previously allowed through with\n// zero validation, letting an attacker-controlled message (allowHtml:true)\n// inject `position:fixed;inset:0;z-index:999999` and render a full-page\n// clickjacking overlay through a toast that already renders at\n// z-index:9999. Inline style is a well-known sanitizer bypass class (see\n// OWASP's XSS Filter Evasion Cheat Sheet). Removed from the allowlist\n// entirely rather than attempting partial validation — toasts don't need\n// arbitrary inline styling to be useful, and \"no unchecked style\" is the\n// safe default most reputable sanitizers ship with.\nconst ALLOWED_ATTRS = new Set([\n \"href\",\n \"src\",\n \"alt\",\n \"title\",\n \"class\",\n \"target\",\n \"rel\",\n]);\n\nexport function hasDOMPurify() {\n try {\n if (typeof window !== \"undefined\" && window.DOMPurify) return true;\n } catch (e) {}\n return false;\n}\n\nexport function fallbackSanitize(dirty) {\n if (!dirty || typeof dirty !== \"string\") return \"\";\n\n const blockedTags =\n /<\\/?(script|iframe|object|embed|link|meta|style|form|input|button)[^>]*>/gi;\n let step1 = dirty.replace(blockedTags, \"\");\n\n step1 = step1.replace(/\\s(on\\w+)\\s*=\\s*(['\"])[\\s\\S]*?\\2/gi, \"\");\n\n step1 = step1.replace(\n /(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi,\n \"$1=$2#$2\",\n );\n\n const container = document.createElement(\"div\");\n container.innerHTML = step1;\n\n function sanitizeNode(node) {\n if (node.nodeType === Node.TEXT_NODE) {\n return document.createTextNode(node.nodeValue);\n }\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return null;\n }\n const tag = node.tagName.toUpperCase();\n if (!ALLOWED_TAGS.has(tag)) {\n const frag = document.createDocumentFragment();\n Array.from(node.childNodes).forEach((child) => {\n const sanitized = sanitizeNode(child);\n if (sanitized) frag.appendChild(sanitized);\n });\n return frag;\n }\n const el = document.createElement(node.tagName);\n Array.from(node.attributes || []).forEach((attr) => {\n const name = attr.name.toLowerCase();\n const val = attr.value;\n if (!ALLOWED_ATTRS.has(name)) return;\n if ((name === \"href\" || name === \"src\") && /^\\s*javascript:/i.test(val))\n return;\n if (name === \"src\" && !/^\\s*(https?:|data:image\\/)/i.test(val)) return;\n if (name === \"target\" && val === \"_blank\") {\n el.setAttribute(\n \"rel\",\n (node.getAttribute(\"rel\") || \"\") + \" noopener noreferrer\",\n );\n }\n el.setAttribute(name, val);\n });\n Array.from(node.childNodes).forEach((child) => {\n const sanitizedChild = sanitizeNode(child);\n if (sanitizedChild) el.appendChild(sanitizedChild);\n });\n return el;\n }\n\n const outFrag = document.createDocumentFragment();\n Array.from(container.childNodes).forEach((child) => {\n const s = sanitizeNode(child);\n if (s) outFrag.appendChild(s);\n });\n\n const wrapper = document.createElement(\"div\");\n wrapper.appendChild(outFrag);\n return wrapper.innerHTML;\n}\n\nexport function sanitizeHtml(dirty, opts = {}) {\n if (!dirty) return \"\";\n try {\n if (!opts.forceFallback && hasDOMPurify()) {\n const DOMPurify = window.DOMPurify;\n // AUDIT FIX (H1): previously called DOMPurify.sanitize() with only\n // ADD_ATTR/ALLOWED_URI_REGEXP, meaning tags/attributes were governed\n // by DOMPurify's own broad DEFAULT allowlist — not the tight,\n // deliberately-curated one this library actually promises. Now\n // passing the SAME ALLOWED_TAGS/ALLOWED_ATTRS used by\n // fallbackSanitize(), so a consumer gets identical sanitization\n // behavior whether or not some other script on the page happens to\n // have loaded DOMPurify.\n const cleaned = DOMPurify.sanitize(dirty, {\n ALLOWED_TAGS: Array.from(ALLOWED_TAGS),\n ALLOWED_ATTR: Array.from(ALLOWED_ATTRS),\n ALLOWED_URI_REGEXP:\n /^(?:(?:https?|mailto|ftp|tel|data):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\n });\n\n // Replicates fallbackSanitize()'s auto rel=\"noopener noreferrer\" on\n // target=\"_blank\" links — DOMPurify doesn't do this automatically,\n // so without this the two paths would still diverge on this one\n // detail even with matching tag/attribute allowlists. Re-parsing the\n // already-clean output (not the original dirty string) so this can\n // only ever tighten, never loosen, what DOMPurify already produced.\n const wrapper = document.createElement(\"div\");\n wrapper.innerHTML = cleaned;\n wrapper.querySelectorAll('a[target=\"_blank\"]').forEach((a) => {\n const rel = (a.getAttribute(\"rel\") || \"\").split(/\\s+/).filter(Boolean);\n if (!rel.includes(\"noopener\")) rel.push(\"noopener\");\n if (!rel.includes(\"noreferrer\")) rel.push(\"noreferrer\");\n a.setAttribute(\"rel\", rel.join(\" \"));\n });\n return wrapper.innerHTML;\n }\n } catch (err) {}\n return fallbackSanitize(dirty);\n}\n","// src/components/toast-utils.js\n\"use strict\";\n\nimport { parseAnimationDuration } from \"../utils/dom.js\";\nimport { sanitizeHtml } from \"../utils/html-sanitizer.js\";\nimport { createLoader } from \"./loader.js\";\nimport {\n createCTA,\n createCloseButton,\n createProgressBar,\n runToastAnimation,\n} from \"./toast-utils-core.js\";\n\n/**\n * Applies rich styling and content to a toast element.\n * @param {HTMLElement} toast - The toast container element.\n * @param {object} options - Configuration options for the toast.\n * @param {Function} onClose - Callback invoked when the toast closes.\n */\nexport async function applyRichStyling(toast, options, onClose) {\n const durationMs = await parseAnimationDuration(options?.animationDuration);\n\n // Compose className based on provided type (default to \"info\")\n toast.className = `toast toast-${options?.type ?? \"info\"}`;\n\n Object.assign(toast.style, {\n background: options?.backgroundColor,\n padding: \"12px 16px\",\n marginBottom: \"10px\",\n borderRadius: options?.borderRadius,\n overflow: \"hidden\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n minWidth: \"250px\",\n maxWidth: options?.maxWidth,\n opacity: \"0\",\n position: \"relative\",\n cursor: \"default\",\n boxSizing: \"border-box\",\n userSelect: \"text\",\n transition: `opacity ${options?.animationDuration} ${options?.animationEasing}, transform ${options?.animationDuration} ${options?.animationEasing}`,\n transform: \"translateY(20px)\",\n zIndex: \"9999\",\n });\n // Accessibility settings\n toast.setAttribute(\"role\", \"alert\");\n toast.setAttribute(\"aria-live\", \"polite\");\n toast.tabIndex = 0; // Make focusable for accessibility if needed\n\n toast._animationDuration = durationMs;\n\n const messageSpan = document.createElement(\"span\");\n\n if (options?.wrapText) {\n Object.assign(messageSpan.style, {\n display: \"block\",\n whiteSpace: \"normal\",\n });\n } else {\n Object.assign(messageSpan.style, {\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: \"3\",\n whiteSpace: \"nowrap\",\n });\n }\n\n Object.assign(messageSpan.style, {\n flex: \"1\",\n padding: options?.fontPadding,\n fontFamily: options?.fontFamily,\n fontSize: options?.fontSize,\n fontWeight: options?.fontWeight,\n lineHeight: options?.fontLineHeight,\n color: options?.textColor,\n userSelect: \"text\",\n wordBreak: \"break-word\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n // AUDIT FIX (C4): display/WebkitLineClamp/WebkitBoxOrient used to be\n // re-applied here unconditionally, silently overwriting whatever the\n // wrapText conditional above had just set — meaning wrapText:\"normal\"\n // never actually worked; every toast truncated to 3 lines regardless.\n // Those three properties are already correctly set by the if/else block\n // above based on options.wrapText, so they're intentionally NOT\n // repeated here anymore.\n });\n\n const allowHtml = !!options.allowHtml; // opt-in flag\n const rawMessage = options.message ?? \"\";\n\n // If a loader is requested as part of the message, create it safely\n if (options.loader || options.showLoader) {\n // createLoader returns an element (see new function below)\n const loaderEl = createLoader(options.loader || {});\n // Put loader before message content\n messageSpan.appendChild(loaderEl);\n // Small spacer\n const spacer = document.createElement(\"span\");\n spacer.style.display = \"inline-block\";\n spacer.style.width = \"8px\";\n messageSpan.appendChild(spacer);\n }\n\n // If allowHtml is explicitly true, sanitize and set innerHTML, otherwise use textContent\n if (\n allowHtml &&\n typeof rawMessage === \"string\" &&\n rawMessage.trim().length > 0\n ) {\n try {\n const sanitized = sanitizeHtml(rawMessage);\n // Use DOM APIs to set sanitized HTML safely\n const tmp = document.createElement(\"div\");\n tmp.innerHTML = sanitized;\n // Move children to messageSpan to avoid re-parsing at outer scope\n while (tmp.firstChild) {\n messageSpan.appendChild(tmp.firstChild);\n }\n } catch (err) {\n console.warn(\n \"HTML message sanitization failed, falling back to text:\",\n err\n );\n messageSpan.textContent = rawMessage;\n }\n } else {\n // default safe text mode\n messageSpan.textContent = String(rawMessage);\n }\n\n // set aria + title\n messageSpan.setAttribute(\"aria-label\", \"Toast Notification Center\");\n messageSpan.setAttribute(\n \"title\",\n typeof rawMessage === \"string\"\n ? rawMessage.replace(/<[^>]+>/g, \"\")\n : String(rawMessage)\n );\n toast.appendChild(messageSpan);\n\n if (options?.cta && Object.keys(options.cta).length !== 0) {\n createCTA(toast, options, onClose);\n }\n\n if (options?.showCloseButton) {\n createCloseButton(toast, options, onClose);\n }\n\n if (options?.showProgressBar) {\n createProgressBar(toast, options);\n }\n\n runToastAnimation(toast);\n}\n\n/**\n * Creates an emergency toast as a safe fallback.\n * @param {object} options - Configuration options for the toast.\n * @param {Function} onClose - Callback invoked when the toast closes.\n * @returns {Promise<HTMLElement|null>}\n */\nexport async function createEmergencyToast(options, onClose) {\n try {\n const emergency = document.createElement(\"div\");\n Object.assign(emergency.style, {\n background: \"#333\",\n color: \"white\",\n padding: \"10px 15px\",\n position: \"fixed\",\n top: \"20px\",\n right: \"20px\",\n zIndex: \"99999\",\n borderRadius: \"3px\",\n maxWidth: \"250px\",\n wordWrap: \"break-word\",\n boxShadow: \"0 2px 10px rgba(0,0,0,0.3)\",\n cursor: \"pointer\",\n });\n\n const innerWrapper = document.createElement(\"div\");\n const msgEl = document.createElement(\"span\");\n msgEl.style.display = \"inline-block\";\n if (options.allowHtml) {\n msgEl.innerHTML = sanitizeHtml(\n String(options.message || \"Emergency Toast Showing!\")\n );\n } else {\n msgEl.textContent = String(\n options.message || \"Emergency Toast Creation Showing!\"\n );\n }\n innerWrapper.appendChild(msgEl);\n\n // add close X via textContent to avoid innerHTML\n const closeSpan = document.createElement(\"span\");\n closeSpan.style.cssText =\n \"float: right; margin-left: 10px; font-weight: bold;\";\n closeSpan.textContent = \"×\";\n innerWrapper.appendChild(closeSpan);\n\n while (emergency.firstChild) emergency.removeChild(emergency.firstChild);\n emergency.appendChild(innerWrapper);\n closeSpan.onclick = () => {\n emergency.remove();\n onClose(emergency);\n };\n\n document.body.appendChild(emergency);\n setTimeout(() => {\n emergency.remove();\n onClose(emergency);\n }, options?.duration);\n\n return emergency;\n } catch (error) {\n console.error(\"Emergency toast creation failed:\", error);\n setTimeout(() => {\n alert(options?.message || \"Emergency Toast Creation Showing!\");\n onClose(null);\n }, 100);\n return null;\n }\n}\n","// src/components/loader.js\nexport function createLoader(opts = {}) {\n const size = opts.size || 14;\n const color = opts.color || \"currentColor\";\n const labelText = opts.text || \"\";\n const wrapper = document.createElement(\"span\");\n wrapper.className = \"toast-loader\";\n wrapper.style.display = \"inline-flex\";\n wrapper.style.alignItems = \"center\";\n wrapper.style.gap = \"8px\";\n\n const svgNS = \"http://www.w3.org/2000/svg\";\n const svg = document.createElementNS(svgNS, \"svg\");\n svg.setAttribute(\"width\", String(size));\n svg.setAttribute(\"height\", String(size));\n svg.setAttribute(\"viewBox\", \"0 0 50 50\");\n svg.setAttribute(\"aria-hidden\", \"true\");\n // spinner circle\n const circle = document.createElementNS(svgNS, \"circle\");\n circle.setAttribute(\"cx\", \"25\");\n circle.setAttribute(\"cy\", \"25\");\n circle.setAttribute(\"r\", \"20\");\n circle.setAttribute(\"fill\", \"none\");\n circle.setAttribute(\"stroke\", color);\n circle.setAttribute(\"stroke-width\", \"4\");\n circle.setAttribute(\"stroke-linecap\", \"round\");\n circle.style.opacity = \"0.85\";\n circle.style.strokeDasharray = \"90\";\n circle.style.strokeDashoffset = \"60\";\n circle.style.transformOrigin = \"center\";\n circle.style.animation = \"toast-spinner 1s linear infinite\";\n\n svg.appendChild(circle);\n wrapper.appendChild(svg);\n\n if (labelText) {\n const lbl = document.createElement(\"span\");\n lbl.style.fontSize = \"13px\";\n lbl.textContent = labelText;\n wrapper.appendChild(lbl);\n }\n\n // add minimal spinner keyframes if not present\n if (!document.getElementById(\"toast-spinner-styles\")) {\n const st = document.createElement(\"style\");\n st.id = \"toast-spinner-styles\";\n st.innerHTML = `@keyframes toast-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }`;\n document.head.appendChild(st);\n }\n\n return wrapper;\n}\n","\"use strict\";\n\nexport function createCTA(toast, options, onClose) {\n const rawCfg = options?.cta;\n if (!rawCfg) return;\n\n // AUDIT FIX (L2): this used to mutate `options.cta` directly\n // (`cfg.label = ...` below writes straight onto the caller's own\n // object). If a consumer reuses the same cta config object across\n // multiple createToast() calls — a natural pattern, e.g. defining a\n // button config once and reusing it — the fallback label mutation from\n // the first toast would leak into every later call, even ones that\n // originally had no label at all. Working on a shallow copy means the\n // caller's object is never touched.\n const cfg = { ...rawCfg };\n\n if (!cfg.label) {\n cfg.label = \"CTA Label Missing!\";\n }\n\n const isLink = !!cfg.href && cfg.variant === \"link\";\n const el = document.createElement(isLink ? \"a\" : \"button\");\n\n if (isLink) {\n el.href = cfg.href;\n if (cfg.target) el.target = cfg.target;\n el.rel = cfg.rel || (cfg.target === \"_blank\" ? \"noopener noreferrer\" : \"\");\n } else {\n el.type = \"button\";\n }\n\n el.setAttribute(\"aria-label\", cfg.ariaLabel || cfg.label);\n\n Object.assign(el.style, {\n marginLeft: \"10px\",\n padding: \"6px 10px\",\n borderRadius: \"6px\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n lineHeight: \"1\",\n border: \"1px solid rgba(255,255,255,0.35)\",\n color: options.textColor || \"#fff\",\n background: \"rgba(255,255,255,0.15)\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n flexShrink: \"0\",\n });\n\n el.textContent = cfg.label;\n\n const onClick = async (e) => {\n try {\n if (typeof cfg.onClick === \"function\") {\n const res = cfg.onClick(e);\n if (res?.then) await res;\n }\n } finally {\n if (cfg.autoClose !== false) onClose(toast);\n }\n };\n\n el.addEventListener(\"click\", onClick);\n\n el._cleanup = () => el.removeEventListener(\"click\", onClick);\n\n toast.appendChild(el);\n}\n\nexport function createCloseButton(toast, options, onClose) {\n const closeBtn = document.createElement(\"button\");\n closeBtn.setAttribute(\"aria-label\", \"Close notification\");\n closeBtn.setAttribute(\"title\", \"Close\");\n closeBtn.textContent = \"×\";\n\n Object.assign(closeBtn.style, {\n background: \"none\",\n border: \"none\",\n color: options.textColor || \"white\",\n fontSize: \"18px\",\n marginLeft: \"10px\",\n cursor: \"pointer\",\n });\n\n const onClick = () => onClose(toast);\n closeBtn.addEventListener(\"click\", onClick);\n\n toast._cleanupCloseButton = () => {\n closeBtn.removeEventListener(\"click\", onClick);\n };\n\n toast.appendChild(closeBtn);\n}\n\nexport function createProgressBar(toast, options) {\n const progressBar = document.createElement(\"div\");\n const borderRadiusStr = options.borderRadius || 0;\n const borderRadiusNum = parseInt(borderRadiusStr, 10);\n const leftVal = borderRadiusNum ? \"12px\" : \"0\";\n const minSafeOffset = borderRadiusNum ? 12 : 0;\n const radiusOffset = Math.max(borderRadiusNum - 10, minSafeOffset);\n const finalWidth = borderRadiusNum\n ? `calc(100% - ${radiusOffset}px)`\n : \"100%\";\n\n Object.assign(progressBar.style, {\n position: \"absolute\",\n left: `${leftVal}`,\n height: options.progressHeight || \"4px\",\n background: options.progressColor || \"rgba(255, 255, 255, 0.3)\",\n width: `${finalWidth}`,\n transition: `width ${options.duration || 1800}ms linear`,\n [options.progressPosition === \"top\" ? \"top\" : \"bottom\"]: \"0\",\n borderRadius: options.borderRadius || \"4px\",\n });\n\n toast.appendChild(progressBar);\n\n if (typeof progressBar.animate === \"function\") {\n toast._progressAnimation = progressBar.animate(\n [{ width: finalWidth }, { width: \"0%\" }],\n {\n duration: Number(options.duration) || 1800,\n easing: \"linear\",\n fill: \"forwards\",\n delay: 50,\n },\n );\n } else {\n progressBar.style.transition = `width ${options.duration || 1800}ms linear`;\n setTimeout(() => {\n progressBar.offsetWidth;\n progressBar.style.width = \"0%\";\n }, 50);\n }\n}\n\nexport function runToastAnimation(toast) {\n setTimeout(() => {\n requestAnimationFrame(() => {\n toast.style.opacity = \"1\";\n toast.style.transform = \"translateY(0)\";\n });\n }, 50);\n}\n","// src/utils/containerRegistry.js\n\"use strict\";\n\nconst containerRegistry = new Map(); // id -> HTMLElement\nconst containerLocks = new Map(); // id -> Promise<HTMLElement>\n\n/**\n * Normalize a position string to a canonical key (id-safe, stable).\n */\nexport function normalizePositionKey(position) {\n // lower-case, trim, unify separators, alias \"below\" -> \"bottom\"\n const raw = String(position).toLowerCase().trim();\n const aliased = raw.replace(/\\bbelow\\b/g, \"bottom\");\n return aliased\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-{2,}/g, \"-\");\n}\n\n/**\n * Canonical container id\n */\nexport function getContainerId(position) {\n return `toast-container-${normalizePositionKey(position)}`;\n}\n\n/**\n * Atomically get or create a single container per canonical id.\n */\nexport async function getOrCreateToastContainer(options, setPosition) {\n const id = getContainerId(options.position);\n // If a creation is in-flight, await it\n if (containerLocks.has(id)) {\n return containerLocks.get(id);\n }\n\n const p = (async () => {\n // 1) Prefer registry cache if still connected\n const cached = containerRegistry.get(id);\n if (cached?.isConnected) {\n return cached;\n }\n\n // 2) Find existing in DOM\n let el = document.getElementById(id); // unique by spec, but may return first if duplicates exist\n if (el && !el.isConnected) {\n // re-attach if detached\n document.body.appendChild(el);\n }\n\n // 3) If not found, create\n if (!el) {\n el = document.createElement(\"div\");\n el.id = id;\n el.setAttribute(\"role\", \"status\"); // polite + atomic by default\n el.setAttribute(\"aria-atomic\", \"true\"); // explicit for consistency\n el.style.position = \"fixed\";\n el.style.zIndex = \"9999\";\n el.style.inset = \"auto 10px 10px auto\";\n el.style.display = \"flex\";\n el.style.justifyContent = \"space-between\";\n el.style.alignItems = \"center\";\n el.style.flexDirection = \"column\";\n el.style.overflow = \"hidden\";\n // Position with provided helper\n if (typeof setPosition === \"function\") {\n await setPosition(el, options);\n }\n document.body.appendChild(el);\n } else {\n // Ensure base styles and (re)apply position in case options changed\n el.style.position = el.style.position || \"fixed\";\n el.style.zIndex = el.style.zIndex || \"9999\";\n if (typeof setPosition === \"function\") {\n await setPosition(el, options);\n }\n }\n\n // 4) If somehow duplicates exist, keep the first and remove the rest\n // getElementById would have returned the first; clean up others proactively\n const all = document.querySelectorAll(`#${id}`);\n if (all.length > 1) {\n for (let i = 1; i < all.length; i++) {\n try {\n all[i].remove();\n } catch {}\n }\n }\n\n containerRegistry.set(id, el);\n return el;\n })();\n\n containerLocks.set(id, p);\n try {\n const out = await p;\n return out;\n } finally {\n // Clear the lock so future calls can re-enter if needed\n containerLocks.delete(getContainerId(options.position));\n }\n}\n","\"use strict\";\n\nexport async function setPosition(container, options) {\n if (!container || !options.position) {\n throw new Error(\"Invalid container or position!\");\n }\n\n resetContainerStyles(container);\n const positionFlags = parsePosition(options.position);\n\n if (handleFullWidthPositions(container, options, positionFlags)) return;\n if (handleCenterPositions(container, positionFlags)) return;\n\n applyStandardPositioning(container, positionFlags);\n}\n\nfunction resetContainerStyles(container) {\n container.style.top = \"auto\";\n container.style.bottom = \"auto\";\n container.style.left = \"auto\";\n container.style.right = \"auto\";\n container.style.transform = \"none\";\n}\n\nfunction parsePosition(position) {\n const pos = position.toLowerCase().trim();\n return {\n hasTop: pos.includes(\"top\"),\n hasBottom: pos.includes(\"bottom\") || pos.includes(\"below\"),\n hasLeft: pos.includes(\"left\"),\n hasRight: pos.includes(\"right\"),\n hasCenter: pos.includes(\"center\"),\n hasFullWidth:\n pos.includes(\"top-full-width\") ||\n pos.includes(\"bottom-full-width\") ||\n pos.includes(\"fullwidth\"),\n };\n}\n\nfunction handleFullWidthPositions(container, options, flags) {\n if (!flags.hasFullWidth) return false;\n\n // AUDIT FIX (L5): options.maxWidth was previously set to \"100vw\"\n // unconditionally here, before checking whether hasTop/hasBottom\n // actually matched. For the undocumented bare \"fullwidth\" value (no\n // top-/bottom- prefix), neither branch below matches, this function\n // returns false, and positioning falls through to the normal\n // small-toast logic further down — but maxWidth had already been\n // mutated to 100vw, leaving a 100vw-wide toast positioned as if it\n // were a normal small one. Moving the mutation inside each branch\n // means it only happens when full-width positioning is actually\n // being applied.\n if (flags.hasTop) {\n options.maxWidth = \"100vw\";\n container.style.top = \"10px\";\n container.style.left = \"10px\";\n container.style.right = \"10px\";\n return true;\n }\n\n if (flags.hasBottom) {\n options.maxWidth = \"100vw\";\n container.style.bottom = \"10px\";\n container.style.left = \"10px\";\n container.style.right = \"10px\";\n return true;\n }\n\n return false;\n}\n\nfunction handleCenterPositions(container, flags) {\n if (!flags.hasCenter) return false;\n\n if (flags.hasTop && !flags.hasLeft && !flags.hasRight) {\n container.style.top = \"10px\";\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n return true;\n }\n\n if (flags.hasBottom && !flags.hasLeft && !flags.hasRight) {\n container.style.bottom = \"10px\";\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n return true;\n }\n\n if (flags.hasLeft && !flags.hasTop && !flags.hasBottom) {\n container.style.left = \"10px\";\n container.style.top = \"50%\";\n container.style.transform = \"translateY(-50%)\";\n return true;\n }\n\n if (flags.hasRight && !flags.hasTop && !flags.hasBottom) {\n container.style.right = \"10px\";\n container.style.top = \"50%\";\n container.style.transform = \"translateY(-50%)\";\n return true;\n }\n\n if (!flags.hasLeft && !flags.hasRight && !flags.hasTop && !flags.hasBottom) {\n container.style.top = \"50%\";\n container.style.left = \"50%\";\n container.style.transform = \"translate(-50%, -50%)\";\n return true;\n }\n\n return false;\n}\n\nfunction applyStandardPositioning(container, flags) {\n if (flags.hasBottom) {\n container.style.bottom = \"10px\";\n } else if (flags.hasTop) {\n container.style.top = \"10px\";\n }\n\n if (flags.hasRight) {\n container.style.right = \"10px\";\n } else if (flags.hasLeft) {\n container.style.left = \"10px\";\n } else {\n if (!flags.hasBottom && !flags.hasTop) {\n container.style.bottom = \"10px\";\n }\n container.style.left = \"50%\";\n container.style.transform = \"translateX(-50%)\";\n }\n}\n","// src/utils/PausableTimer.js\n\"use strict\";\n\nexport class PausableTimer {\n constructor(callback, delay) {\n this.callback = callback;\n this.delay = delay;\n this.remaining = delay;\n this.startTime = null;\n this.timeoutId = null;\n this.isPaused = false;\n this.isCompleted = false;\n }\n\n start() {\n if (this.isCompleted || this.timeoutId) return this;\n this.startTime = Date.now();\n this.timeoutId = setTimeout(() => {\n this.isCompleted = true;\n this.timeoutId = null;\n this.callback();\n }, this.remaining);\n return this;\n }\n\n pause() {\n if (this.isPaused || !this.timeoutId || this.isCompleted) return this;\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n this.remaining -= Date.now() - this.startTime;\n this.remaining = Math.max(0, this.remaining); // prevent negative\n this.isPaused = true;\n return this;\n }\n\n resume() {\n if (!this.isPaused || this.isCompleted) return this;\n this.isPaused = false;\n this.start();\n return this;\n }\n\n clear() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n this.isCompleted = true;\n return this;\n }\n\n getRemainingTime() {\n if (this.isCompleted) return 0;\n if (this.isPaused) return this.remaining;\n if (!this.timeoutId) return this.delay;\n return Math.max(0, this.remaining - (Date.now() - this.startTime));\n }\n}\n","// src/components/ToastManager.js\n\"use strict\";\n\nimport { createToastElement } from \"./Toast.js\";\nimport { removeElement } from \"../utils/dom.js\";\nimport { createEmergencyToast } from \"./toast-utils.js\";\nimport { getOrCreateToastContainer } from \"../utils/containerRegistry.js\";\nimport { setPosition } from \"../utils/position.js\";\nimport { PausableTimer } from \"../utils/PausableTimer.js\";\n\n// Config\nconst MAX_VISIBLE = 3;\n\n// State\nconst active = new Map(); // key -> { outer, toast, count, timeout }\nconst pending = new Map(); // key -> { options, count, rafId }\nconst queue = []; // [{ options, key, count }]\nlet visibleCount = 0;\n\n// djb2 hash function for message deduplication\nfunction hashString(str) {\n let h = 5381;\n for (let i = 0; i < str.length; i++) h = (h << 5) + h + str.charCodeAt(i);\n return h >>> 0;\n}\n\n/**\n * Creates a unique key for a toast notification based on its type, message, and position.\n * This key is used to identify and deduplicate identical toast notifications.\n * @param {Object} options - Toast options with type, message, and position.\n * @returns {string} A unique key for the toast notification.\n */\nfunction makeKey(options = {}) {\n const type = String(options.type).trim().toLowerCase();\n const messageHash = hashString(String(options.message || \"\")).toString(16);\n const position = String(options.position).trim().toLowerCase();\n\n return `${type}|${messageHash}|${position}`;\n}\n\n/**\n * Shows a toast notification with the given options.\n * If there is already an active toast with the same type, message, and position,\n * it will be grouped immediately and the count will be incremented.\n * If there is already a pending toast with the same type, message, and position,\n * it will be coalesced and the count will be incremented.\n * If there is no capacity left (i.e. the number of visible toasts is at the maximum),\n * the grouped request will be enqueued and processed later.\n * @param {Object} options - Toast options with type, message, and position.\n * @returns {Promise<void>} A promise that resolves when the toast is fully created and displayed.\n */\nexport async function showToast(options = {}) {\n try {\n const key = makeKey(options);\n\n // If already active: group immediately\n if (active.has(key)) {\n const data = active.get(key);\n if (!data) throw new Error(`Active toast with key ${key} not found`);\n data.count++;\n\n // Reset timer with new duration\n data.timer.clear();\n data.timer = createDismissTimer(data.toast, options);\n await setupPauseOnHover(data);\n await updateBadge(data);\n return;\n }\n\n // If coalescing is already scheduled for this key, just increment the pending count\n if (pending.has(key)) {\n const current = pending.get(key);\n if (!current) throw new Error(`Pending toast with key ${key} not found`);\n current.count++;\n return;\n }\n\n // Start coalescing identical calls in the same frame\n const entry = { options, count: 1, rafId: 0 };\n pending.set(key, entry);\n\n entry.rafId = requestAnimationFrame(async () => {\n // finalize batch for this key\n const current = pending.get(key);\n if (!current) return;\n pending.delete(key);\n\n // If capacity full, enqueue the grouped request\n if (visibleCount >= MAX_VISIBLE) {\n queue.push({ options: current.options, key, count: current.count });\n await drainQueue();\n return;\n }\n\n // Otherwise create immediately with the grouped count\n try {\n await createOne(current.options, key, current.count);\n } catch (error) {\n console.error(\"showToast failed:\", error);\n }\n });\n } catch (error) {\n console.error(\"showToast failed:\", error);\n }\n}\n\n/**\n * Creates a single toast notification with the given options and initial count.\n * Will create and mount the toast element, and setup a timer to auto-dismiss.\n * If the toast creation fails, it will fallback to an emergency toast.\n * @param {Object} options - Toast options with type, message, and position.\n * @param {string} key - Unique key for the toast.\n * @param {number} initialCount - Initial count for the toast.\n * @returns {Promise<void>} A promise that resolves when the toast is fully created and displayed.\n */\nasync function createOne(options, key, initialCount) {\n try {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object\");\n }\n\n visibleCount++;\n\n const container = await getOrCreateToastContainer(options, setPosition);\n if (!container) {\n throw new Error(\"Failed to create toast container\");\n }\n\n // Build the toast element\n const toast = await createToastElement(options, closeToast);\n if (!toast) {\n throw new Error(\"Toast element creation failed\");\n }\n\n // Outer wrapper (badge surface; visible overflow)\n const outer = document.createElement(\"div\");\n Object.assign(outer.style, {\n position: \"relative\",\n display: \"inline-block\",\n overflow: \"visible\",\n marginBottom: \"10px\",\n zIndex: \"0\",\n width: \"100%\",\n });\n\n // Inner wrapper (clip progress bar & rounded corners)\n const inner = document.createElement(\"div\");\n Object.assign(inner.style, {\n position: \"relative\",\n overflow: \"hidden\",\n // borderRadius: options.borderRadius || \"8px\",\n zIndex: \"1\",\n });\n\n inner.appendChild(toast);\n outer.appendChild(inner);\n\n // Mount\n if (container.id.includes(\"toast-container-\")) {\n container.appendChild(outer);\n }\n\n // Determine if should pause on hover (default: true if has CTA)\n const shouldPauseOnHover =\n options.pauseOnHover !== false &&\n (options.pauseOnHover === true || !!options.cta);\n\n // Track\n const data = {\n outer,\n toast,\n count: Math.max(1, Math.floor(initialCount ?? 0)),\n timeout: null,\n pauseOnHover: shouldPauseOnHover,\n };\n active.set(key, data);\n toast._key = key;\n\n if (data.count > 1) await updateBadge(data);\n\n // Create and start timer\n data.timer = createDismissTimer(toast, options);\n await setupPauseOnHover(data);\n } catch (err) {\n console.error(\"Something went wrong: \", err);\n visibleCount = Math.max(0, visibleCount - 1);\n const el =\n document.querySelector('[id^=\"toast-container-\"]') || document.body;\n el.appendChild(await createEmergencyToast(options, closeToast));\n }\n}\n\n/**\n * Dismiss (close) the most recently shown toast.\n * - Finds the most recently appended toast element across containers.\n * - Calls closeToast on it (which handles timers, cleanup, and queue drain).\n * - Returns a Promise that resolves when the close completes.\n */\nexport async function dismissMostRecent() {\n try {\n // If no active toasts, nothing to dismiss\n if (active.size === 0) return;\n\n // Strategy: find the last inserted element in DOM among all containers.\n // Iterate containers and pick lastElementChild of container that is a toast wrapper.\n let lastToastEl = null;\n\n const containers = document.querySelectorAll('[id^=\"toast-container-\"]');\n containers.forEach((container) => {\n const children = Array.from(container.children || []);\n if (children.length === 0) return;\n // AUDIT FIX (L3): toasts are always appended (never prepended), so\n // the LAST child in DOM order is the most recently created one.\n // children.at(0) — the previous behavior — was actually the OLDEST\n // visible toast, the opposite of what \"dismissMostRecent\" promises.\n const candidate = children.at(-1);\n if (candidate) {\n lastToastEl = candidate.querySelector('[id^=\"toast-\"]') || candidate;\n }\n });\n\n if (!lastToastEl) {\n // Same fix applied to the Map-based fallback: Map preserves\n // insertion order, so the LAST entry is the most recently created\n // toast, not the first.\n const entries = Array.from(active.entries());\n if (entries.length > 0) {\n const [, data] = entries.at(-1);\n lastToastEl =\n data.toast ||\n (data.outer && data.outer.querySelector('[id^=\"toast-\"]'));\n }\n }\n\n if (!lastToastEl) return;\n\n // If the element is a wrapper, attempt to find the actual toast element with _key\n const toastEl = lastToastEl._key\n ? lastToastEl\n : lastToastEl.querySelector('[id^=\"toast-\"]') || lastToastEl;\n\n await closeToast(toastEl);\n } catch (err) {\n console.error(\"dismissMostRecent failed:\", err);\n }\n}\n\n/**\n * Close all active toasts immediately.\n * - Clears timers, runs closeToast for each active toast,\n * - Also clears the pending queue.\n */\nexport async function closeAllToasts() {\n try {\n // mark in-progress (consumers can use this flag via module if needed)\n const activeToasts = Array.from(active.values())\n .map((d) => d.toast)\n .filter(Boolean);\n // clear pending queue (so no queued toasts will appear after we remove active)\n queue.length = 0;\n pending.clear();\n\n // Close in clockwise order (oldest first)\n for (const t of activeToasts) {\n try {\n // Sequentially close to preserve animation and queue order\n await closeToast(t);\n } catch (error_inner) {\n console.warn(\"closeAllToasts: failed to close one toast:\", error_inner);\n }\n }\n } catch (err) {\n console.error(\"closeAllToasts failed:\", err);\n }\n}\n\n// Export aliases for clarity / compatibility\nexport const dismiss = dismissMostRecent;\nexport const noop = closeAllToasts;\n\n/**\n * Creates a PausableTimer that auto-closes a toast after a delay.\n * @param {HTMLElement} toast - The toast element to auto-close.\n * @param {Object} options - Toast options with duration.\n * @returns {PausableTimer} A timer that can be paused, resumed, or cleared.\n */\nfunction createDismissTimer(toast, options) {\n const delay = Number(options.duration ?? 1800) + 5;\n const timer = new PausableTimer(async () => await closeToast(toast), delay);\n timer.start();\n return timer;\n}\n\nasync function setupPauseOnHover(data) {\n if (!data.pauseOnHover || !data.outer || !data.timer) return;\n\n const { outer, timer, toast } = data;\n\n const onMouseEnter = () => {\n timer.pause();\n // AUDIT FIX (H3): the progress bar's Web Animations API animation\n // (toast._progressAnimation, set on the INNER toast element by\n // toast-utils-core.js's createProgressBar — not on `outer`, which is\n // just ToastManager's positioning wrapper div around it) previously\n // had no connection to pause-on-hover at all — it ran on its own\n // clock and kept animating to 0% even while the real PausableTimer\n // was genuinely frozen, so the bar visually lied about how much time\n // was actually left. Pausing it here, from the exact same event that\n // pauses the real timer, keeps both in sync.\n toast?._progressAnimation?.pause();\n };\n const onMouseLeave = () => {\n timer.resume();\n toast?._progressAnimation?.play();\n };\n\n const onFocusIn = (e) => {\n if (e.target.matches(\"[tabindex], div, span, button, a\")) {\n timer.pause();\n toast?._progressAnimation?.pause();\n }\n };\n\n const onFocusOut = (e) => {\n if (!outer.contains(e.relatedTarget)) {\n timer.resume();\n toast?._progressAnimation?.play();\n }\n };\n\n // Add event listeners\n outer.addEventListener(\"mouseenter\", onMouseEnter);\n outer.addEventListener(\"mouseleave\", onMouseLeave);\n outer.addEventListener(\"focusin\", onFocusIn);\n outer.addEventListener(\"focusout\", onFocusOut);\n\n // Store cleanup function\n outer._pauseCleanup = () => {\n outer.removeEventListener(\"mouseenter\", onMouseEnter);\n outer.removeEventListener(\"mouseleave\", onMouseLeave);\n outer.removeEventListener(\"focusin\", onFocusIn);\n outer.removeEventListener(\"focusout\", onFocusOut);\n };\n}\n\n/**\n * Closes a toast notification immediately.\n * If the toast is not found in the active toasts map, this function does nothing.\n * @param {HTMLElement|null} toast - The toast element to close.\n * @returns {Promise<void>} A promise that resolves when the toast is fully removed from the DOM.\n */\nexport async function closeToast(toast) {\n try {\n if (!toast?._key) return;\n const data = active.get(toast._key);\n if (!data) return;\n\n // Clear timer and cleanup pause events\n data.timer?.clear();\n data.outer?._pauseCleanup?.();\n\n active.delete(toast._key);\n visibleCount = Math.max(0, visibleCount - 1);\n\n // Remove badge if present\n const badge = data.outer.querySelector(\".toast-count-badge\");\n if (badge) badge.remove();\n\n // Remove wrapper after transition ends (or fallback)\n await removeWithTransition(data.outer);\n\n // Drain queue after a slot frees\n await drainQueue();\n } catch (error) {\n console.error(\"Closing Toast failed!: \", error);\n }\n}\n\nasync function drainQueue() {\n // Fill available slots; coalesce queued entries against active if they became active meanwhile\n while (visibleCount < MAX_VISIBLE && queue.length) {\n const item = queue.shift();\n if (active.has(item.key)) {\n const data = active.get(item.key);\n data.count += item.count;\n await updateBadge(data);\n continue;\n }\n // Create without awaiting to keep loop responsive; visibleCount is incremented inside createOne\n void createOne(item.options, item.key, item.count);\n }\n}\n\n/**\n * Safely remove an element after its transition ends, with a hard timeout fallback\n * @param {Element} el - The element to remove\n * @returns {Promise<void>} A promise that resolves after the element is removed\n */\nasync function removeWithTransition(el) {\n if (!el) return Promise.resolve();\n\n return new Promise((resolve) => {\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n removeElement(el);\n resolve();\n };\n\n // Listen on the immediate child (inner wrapper) if possible\n const child = el.firstElementChild || el;\n if (!child) return resolve();\n\n const onEnd = (e) => {\n try {\n // Check if the event target is the same element we're listening on\n if (e.target !== child) return;\n // Remove the event listener to prevent multiple triggers\n child.removeEventListener(\"transitionend\", onEnd, true);\n finish();\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n };\n\n // Add the event listener to the child element\n try {\n child.addEventListener(\"transitionend\", onEnd, true);\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n\n // Hard fallback if no transition fires after 700ms\n setTimeout(() => {\n try {\n // Remove the event listener to prevent multiple triggers\n child.removeEventListener(\"transitionend\", onEnd, true);\n finish();\n } catch (error) {\n console.error(\"removeWithTransition error:\", error);\n }\n }, 700);\n });\n}\n\n/**\n * Updates the badge count on the outer toast wrapper.\n * @param {Object} options Options object containing the outer toast wrapper and the count.\n * @param {HTMLElement} options.outer The outer toast wrapper element.\n * @param {number} options.count The count of identical notifications.\n */\nasync function updateBadge({ outer, count }) {\n if (!outer || !(outer instanceof HTMLElement)) {\n throw new Error(\"updateBadge: outer must be a valid HTMLElement\");\n }\n\n if (count < 2) {\n // Remove the badge if the count is less than 2\n const badge = outer.querySelector(\".toast-count-badge\");\n if (badge) badge.remove();\n return;\n }\n\n let badge = outer.querySelector(\".toast-count-badge\");\n if (!badge) {\n // Create the badge if it doesn't exist\n badge = document.createElement(\"span\");\n badge.className = \"toast-count-badge\";\n badge.setAttribute(\"aria-label\", `${count} identical notifications`);\n\n // Style the badge\n Object.assign(badge.style, {\n position: \"absolute\",\n top: \"6px\",\n right: \"6px\",\n backgroundColor: \"#f44336\",\n color: \"#fff\",\n borderRadius: \"50%\",\n minWidth: \"20px\",\n height: \"20px\",\n fontSize: \"12px\",\n fontWeight: \"600\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n border: \"2px solid #fff\",\n boxShadow: \"0 2px 6px rgba(0,0,0,0.3)\",\n zIndex: \"2\",\n pointerEvents: \"none\",\n transition: \"transform 150ms ease\",\n });\n\n // Add the badge to the outer toast wrapper\n outer.appendChild(badge);\n }\n\n // Update the badge text content\n badge.textContent = count > 99 ? \"99+\" : String(count);\n\n // Animate the badge by scaling it up and then back down\n try {\n badge.style.transform = \"scale(1.2)\";\n setTimeout(() => (badge.style.transform = \"scale(1)\"), 150);\n } catch (error) {\n console.error(\"updateBadge animation error:\", error);\n }\n}\n","// src/components/Toast.js //# Single responsibility\n\"use strict\";\n\nimport { createElementWithId } from \"../utils/dom.js\";\nimport { applyRichStyling, createEmergencyToast } from \"./toast-utils.js\";\n\n/**\n * Creates a multi-layer toast element with satellite-grade fallbacks\n * @param {Object} options - Toast configuration options\n * @param {Function} onClose - Callback when toast closes\n * @returns {HTMLElement} Toast element\n */\nexport async function createToastElement(options, onClose) {\n const toastContainerSelector = '[id^=\"toast-container-\"]';\n const toastContainer = document.querySelector(toastContainerSelector);\n if (!toastContainer) return null;\n\n let toast;\n const tagName = \"div\";\n const prefix = \"toast\";\n\n // PRIMARY: Full-featured toast\n try {\n toast = await createElementWithId(tagName, prefix);\n await applyRichStyling(toast, options, onClose);\n return toast;\n } catch (error) {\n console.warn(\n \"toast creation failed with error showing fallback one: \",\n error\n );\n // Fallback: create emergency toast\n toast = await createEmergencyToast(options, onClose);\n return toast;\n }\n}\n","\"use strict\";\n\nimport { showToast } from \"./components/ToastManager.js\";\nimport { getOrCreateToastContainer } from \"./utils/containerRegistry.js\";\nimport { getDynamicAccessibleTextColorHex } from \"./utils/dom.js\";\nimport { setPosition } from \"./utils/position.js\";\n\nlet defaultColors = {\n success: \"#28a745\",\n error: \"#dc3545\",\n warning: \"#ffc107\",\n info: \"#17a2b8\",\n};\n\nlet defaultMessages = {\n success: \"Operation completed successfully!\",\n error: \"Something went wrong!\",\n warning: \"Warning message!\",\n info: \"Information message!\",\n};\n\nconst pendingToasts = [];\n\nlet domReady = false;\n\nasync function checkDOMReady() {\n if (domReady) return;\n\n const SETTLE_DELAY_MS = 200;\n\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n if (\n document.readyState === \"complete\" ||\n document.readyState === \"interactive\"\n ) {\n domReady = true;\n pendingToasts.forEach((options) =>\n setTimeout(() => createToastNow(options), SETTLE_DELAY_MS),\n );\n pendingToasts.length = 0;\n } else {\n document.addEventListener(\n \"DOMContentLoaded\",\n () => {\n domReady = true;\n pendingToasts.forEach((options) =>\n setTimeout(() => createToastNow(options), SETTLE_DELAY_MS),\n );\n pendingToasts.length = 0;\n },\n { once: true },\n );\n }\n }\n}\n\nasync function createToastNow(options = {}) {\n try {\n const sanitizedOptions = await sanitizeToastOptions(options);\n\n await createFirstToastContainer(sanitizedOptions);\n\n await showToast(sanitizedOptions);\n } catch (error) {\n console.error(\"CreateToast failed:\", error);\n\n const safeMessage =\n typeof options?.message === \"string\" && options?.message !== null\n ? `${options.message.substring(0, 200)} toast creation failed!`\n : \"Toast creation failed!\";\n\n alert(safeMessage);\n }\n}\n\nasync function createToast(options = {}) {\n const isBrowser =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\n if (!isBrowser) {\n console.warn(\n \"ToastNotification: running in non-browser environment, no DOM available.\",\n );\n return;\n }\n\n await checkDOMReady();\n\n if (!domReady) {\n pendingToasts.push(options);\n return;\n }\n\n await createToastNow(options);\n}\n\nasync function createFirstToastContainer(options) {\n try {\n return await getOrCreateToastContainer(options, setPosition);\n } catch (error) {\n console.error(\"Failed to create toast container:\", error);\n return document.body;\n }\n}\n\nasync function sanitizeToastOptions(options) {\n const contPosition = options?.position?.toLowerCase()?.trim();\n const contMaxWidth =\n contPosition?.includes(\"top-full-width\") ||\n contPosition?.includes(\"bottom-full-width\")\n ? \"100vw\"\n : \"400px\";\n\n const defaults = {\n allowHtml: false,\n sanitizeHtml: true,\n pauseOnHover: undefined,\n duration: 2500,\n position: \"bottom-right\",\n type: \"info\",\n borderRadius: \"50px\",\n backgroundColor: undefined,\n textColor: undefined,\n showCloseButton: true,\n animationDuration: \"0.4s\",\n animationEasing: \"ease\",\n showProgressBar: true,\n progressColor: undefined,\n progressHeight: \"4px\",\n progressPosition: \"bottom\",\n fontPosition: \"relative\",\n fontPadding: undefined,\n fontBorderRadius: undefined,\n fontBackgroundColor: undefined,\n fontFamily:\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"',\n fontSize: \"14px\",\n fontWeight: \"400\",\n fontLineHeight: \"1.4\",\n fontDirection: \"auto\",\n wrapText: \"normal\",\n maxWidth: contMaxWidth,\n };\n\n const final = {\n ...defaults,\n ...(typeof options === \"object\" && !Array.isArray(options) ? options : {}),\n };\n\n final.message = options?.message ?? final.message;\n\n try {\n if (!final.backgroundColor) {\n final.backgroundColor =\n defaultColors?.[final.type] ??\n (window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"#f5f5f5\"\n : \"#111111\");\n }\n } catch (error) {\n console.warn(\"Background color resolution failed:\", error);\n }\n\n try {\n final.message =\n final.message || defaultMessages?.[final.type] || \"No Message Provided!\";\n } catch (error) {\n console.warn(\"Default message resolution failed:\", error);\n }\n\n try {\n if (!final.textColor && final.backgroundColor) {\n final.textColor = getDynamicAccessibleTextColorHex(final.backgroundColor);\n }\n } catch (error) {\n console.warn(\"Text color resolution failed:\", error);\n }\n\n try {\n if (!final.progressColor && final.backgroundColor) {\n final.progressColor =\n final.textColor ||\n getDynamicAccessibleTextColorHex(final.backgroundColor);\n }\n } catch (error) {\n console.warn(\"Progress bar color resolution failed:\", error);\n }\n\n if (typeof final.message !== \"string\") {\n final.message = \"No Message Provided!\";\n }\n\n return final;\n}\n\n/**\n * Overrides the default background color used per toast type. Merges with\n * (doesn't replace) the existing defaults, so you can override just one type.\n * @param {Partial<Record<\"success\"|\"error\"|\"warning\"|\"info\", string>>} colors\n */\nfunction setDefaultColors(colors) {\n try {\n if (colors && typeof colors === \"object\" && !Array.isArray(colors)) {\n defaultColors = { ...defaultColors, ...colors };\n }\n } catch (error) {\n console.error(\"setDefaultColors failed:\", error);\n }\n}\n\n/**\n * Overrides the default message shown per toast type when no `message` is\n * passed to createToast(). Merges with the existing defaults.\n * @param {Partial<Record<\"success\"|\"error\"|\"warning\"|\"info\", string>>} messages\n */\nfunction setDefaultMessages(messages) {\n try {\n if (messages && typeof messages === \"object\" && !Array.isArray(messages)) {\n defaultMessages = { ...defaultMessages, ...messages };\n }\n } catch (error) {\n console.error(\"setDefaultMessages failed:\", error);\n }\n}\n\nimport { dismiss, noop as managerNoop } from \"./components/ToastManager.js\";\n\nlet closeInProgress = false;\nlet closePromise = null;\n\nasync function runWithClosePriority(fn) {\n if (closeInProgress && closePromise) {\n try {\n await closePromise;\n } catch (closeError) {\n console.warn(\n \"Previous close operation failed (continuing anyway):\",\n closeError,\n );\n }\n }\n return fn();\n}\n\n/**\n * @typedef {Object} ToastCTAConfig\n * @property {string} [label] - Button/link text. Defaults to \"CTA Label Missing!\" if omitted.\n * @property {() => void | Promise<void>} [onClick] - Called on click. If it returns a Promise, autoClose waits for it to resolve first.\n * @property {string} [href] - If set together with variant:\"link\", renders an <a> instead of a <button>.\n * @property {\"button\"|\"link\"} [variant] - \"link\" only takes effect when href is also set.\n * @property {string} [target] - Anchor target, e.g. \"_blank\". Automatically gets rel=\"noopener noreferrer\" unless you set rel yourself.\n * @property {string} [rel]\n * @property {string} [ariaLabel] - Falls back to label if omitted.\n * @property {boolean} [autoClose] - Defaults to true: the toast closes after onClick resolves. Set false to keep it open.\n */\n\n/**\n * @typedef {Object} ToastOptions\n * @property {string} [message] - Toast body text. Falls back to a per-type default (see setDefaultMessages) if omitted.\n * @property {\"success\"|\"error\"|\"warning\"|\"info\"} [type=\"info\"]\n * @property {boolean} [allowHtml=false] - If true, message is sanitized (see sanitizeHtml) and rendered as HTML instead of plain text.\n * @property {boolean} [sanitizeHtml=true] - Set false only if you've already fully sanitized message yourself.\n * @property {boolean} [pauseOnHover] - Defaults to true automatically whenever cta is set; otherwise false unless explicitly set true.\n * @property {number} [duration=2500] - Milliseconds before auto-dismiss.\n * @property {string} [position=\"bottom-right\"] - e.g. \"top-left\", \"bottom-right\", \"top-center\", \"bottom-center\", \"left-center\", \"right-center\", \"top-full-width\", \"bottom-full-width\", \"center\".\n * @property {string} [borderRadius=\"50px\"]\n * @property {string} [backgroundColor] - Auto-computed per type if omitted.\n * @property {string} [textColor] - Auto-computed for WCAG contrast against backgroundColor if omitted.\n * @property {boolean} [showCloseButton=true]\n * @property {string} [animationDuration=\"0.4s\"]\n * @property {string} [animationEasing=\"ease\"]\n * @property {boolean} [showProgressBar=true]\n * @property {string} [progressColor] - Defaults to textColor if omitted.\n * @property {string} [progressHeight=\"4px\"]\n * @property {\"top\"|\"bottom\"} [progressPosition=\"bottom\"]\n * @property {string} [fontPadding]\n * @property {string} [fontBorderRadius]\n * @property {string} [fontBackgroundColor]\n * @property {string} [fontFamily]\n * @property {string} [fontSize=\"14px\"]\n * @property {string} [fontWeight=\"400\"]\n * @property {string} [fontLineHeight=\"1.4\"]\n * @property {string} [fontDirection=\"auto\"]\n * @property {\"normal\"|false} [wrapText=\"normal\"] - \"normal\" wraps naturally; falsy truncates to 3 lines with an ellipsis.\n * @property {string} [maxWidth] - Auto-set to \"100vw\" for the two full-width positions, \"400px\" otherwise, unless overridden.\n * @property {ToastCTAConfig} [cta] - Adds a button or link. Setting this also defaults pauseOnHover to true.\n */\n\nconst originalCreateToast = createToast;\n/**\n * Creates and shows a toast notification.\n * @param {ToastOptions} [options]\n * @returns {Promise<void>}\n */\nasync function createToastWithPriority(options = {}) {\n return runWithClosePriority(() => originalCreateToast(options));\n}\n\nexport { createToastWithPriority as createToast };\n\nexport { setDefaultColors, setDefaultMessages };\n/** @type {() => Promise<void>} */\nconst dismissToast = async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await dismiss();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n};\n/** @type {() => Promise<void>} */\nconst noopAll = async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await managerNoop();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n};\nexport { dismissToast as dismiss, noopAll as noop };\n\nif (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n const onKeyDown = (e) => {\n if (e.key === \"Escape\" || e.key === \"Esc\") {\n (async () => {\n closeInProgress = true;\n closePromise = (async () => {\n try {\n await dismiss();\n } finally {\n closeInProgress = false;\n closePromise = null;\n }\n })();\n await closePromise;\n })();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown, { passive: true });\n}\n\ntry {\n if (typeof window !== \"undefined\") {\n window.customizableToast = {\n createToast: createToastWithPriority,\n setDefaultColors,\n setDefaultMessages,\n noop: noopAll,\n dismiss: dismissToast,\n };\n }\n} catch (error) {\n console.error(\"Global assignment failed:\", error);\n}\n"],"names":["async","createElementWithId","tagName","prefix","el","document","createElement","id","Date","now","toString","Math","floor","random","generateToastId","colorCache","constructor","maxSize","this","map","Map","get","key","has","value","delete","set","size","firstKey","keys","next","precomputedNamedTextColors","getDynamicAccessibleTextColorHex","toastBg","opa","cached","toLowerCase","textColor","r","g","b","parsed","hexMatch","match","hex","length","split","c","join","parseInt","slice","rgbMatch","Number","hslMatch","h","s","l","gray","round","hue2rgb","p","q","t","parseToRgb","_varMatch$","varMatch","getComputedStyle","resolved","documentElement","getPropertyValue","trim","e","resolveCssCustomProperty","Error","luminance","a","v","pow","contrastRatio","rgb1","rgb2","L1","L2","max","min","rgbToHsl","d","textL","tr","tg","tb","hslToRgb","contrastBlack","contrastWhite","result","rgbToHex","padStart","Object","entries","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","green","greenyellow","grey","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","forEach","name","lum","L","ALLOWED_TAGS","Set","ALLOWED_ATTRS","fallbackSanitize","dirty","step1","replace","container","sanitizeNode","node","nodeType","Node","TEXT_NODE","createTextNode","nodeValue","ELEMENT_NODE","tag","toUpperCase","frag","createDocumentFragment","Array","from","childNodes","child","sanitized","appendChild","attributes","attr","val","test","setAttribute","getAttribute","sanitizedChild","innerHTML","outFrag","wrapper","sanitizeHtml","opts","forceFallback","window","DOMPurify","hasDOMPurify","cleaned","sanitize","ALLOWED_ATTR","ALLOWED_URI_REGEXP","querySelectorAll","rel","filter","Boolean","includes","push","err","applyRichStyling","toast","options","onClose","durationMs","duration","endsWith","parseFloat","parseAnimationDuration","animationDuration","className","type","assign","style","background","backgroundColor","padding","marginBottom","borderRadius","overflow","display","alignItems","justifyContent","boxShadow","minWidth","maxWidth","opacity","position","cursor","boxSizing","userSelect","transition","animationEasing","transform","zIndex","tabIndex","_animationDuration","messageSpan","wrapText","whiteSpace","WebkitBoxOrient","WebkitLineClamp","flex","fontPadding","fontFamily","fontSize","fontWeight","lineHeight","fontLineHeight","color","wordBreak","textOverflow","allowHtml","rawMessage","message","loader","showLoader","loaderEl","labelText","text","gap","svgNS","svg","createElementNS","String","circle","strokeDasharray","strokeDashoffset","transformOrigin","animation","lbl","textContent","getElementById","st","head","createLoader","spacer","width","tmp","firstChild","console","warn","cta","rawCfg","cfg","label","isLink","href","variant","target","ariaLabel","marginLeft","border","flexShrink","onClick","res","then","autoClose","addEventListener","_cleanup","removeEventListener","createCTA","showCloseButton","closeBtn","_cleanupCloseButton","createCloseButton","showProgressBar","progressBar","borderRadiusStr","borderRadiusNum","leftVal","minSafeOffset","radiusOffset","finalWidth","left","height","progressHeight","progressColor","progressPosition","animate","_progressAnimation","easing","fill","delay","setTimeout","offsetWidth","createProgressBar","requestAnimationFrame","runToastAnimation","createEmergencyToast","emergency","top","right","wordWrap","innerWrapper","msgEl","closeSpan","cssText","removeChild","onclick","remove","body","error","alert","containerRegistry","containerLocks","getContainerId","normalizePositionKey","getOrCreateToastContainer","setPosition","isConnected","inset","flexDirection","all","i","bottom","resetContainerStyles","positionFlags","pos","hasTop","hasBottom","hasLeft","hasRight","hasCenter","hasFullWidth","parsePosition","flags","handleFullWidthPositions","handleCenterPositions","applyStandardPositioning","PausableTimer","callback","remaining","startTime","timeoutId","isPaused","isCompleted","start","pause","clearTimeout","resume","clear","getRemainingTime","active","pending","queue","visibleCount","showToast","str","charCodeAt","hashString","makeKey","data","count","timer","createDismissTimer","setupPauseOnHover","updateBadge","current","entry","rafId","drainQueue","createOne","initialCount","TypeError","querySelector","createToastElement","closeToast","outer","inner","shouldPauseOnHover","pauseOnHover","timeout","_key","dismiss","lastToastEl","children","candidate","at","toastEl","noop","activeToasts","values","error_inner","onMouseEnter","_toast$_progressAnima","onMouseLeave","_toast$_progressAnima2","play","onFocusIn","_toast$_progressAnima3","matches","onFocusOut","_toast$_progressAnima4","contains","relatedTarget","_pauseCleanup","_data$timer","_data$outer","_data$outer$_pauseCle","call","badge","Promise","resolve","done","finish","_el$parentNode","parentNode","pointerEvents","removeElement","firstElementChild","onEnd","removeWithTransition","item","shift","HTMLElement","defaultColors","success","warning","info","defaultMessages","pendingToasts","domReady","createToastNow","sanitizedOptions","_options$position","contPosition","contMaxWidth","final","undefined","fontPosition","fontBorderRadius","fontBackgroundColor","fontDirection","isArray","_defaultColors","matchMedia","_defaultMessages","sanitizeToastOptions","createFirstToastContainer","safeMessage","substring","setDefaultColors","colors","setDefaultMessages","messages","closeInProgress","closePromise","originalCreateToast","readyState","once","checkDOMReady","createToastWithPriority","fn","closeError","runWithClosePriority","dismissToast","noopAll","managerNoop","onKeyDown","passive","customizableToast","createToast"],"mappings":"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"}
|