/* Commons product flags pricing protocol v1. Hosts own price rendering and lifecycle. */ (function (global) { 'use strict'; function evaluate(root, context, apply) { if (!root || typeof root.querySelectorAll !== 'function' || typeof apply !== 'function') return null; var flags = Array.prototype.filter.call(root.querySelectorAll('[data-pf-p]'), function (flag) { return flag.closest('[data-pf-root]') === root; }); flags.forEach(function (flag) { flag.removeAttribute('data-pf-active'); }); var cents = context && context.priceCents; var valid = context && context.coverage === true && Number.isSafeInteger(cents) && cents > 0; var winner = null; var finalCents = cents; if (valid) { flags.forEach(function (flag) { var raw = flag.getAttribute('data-pf-p'); if (typeof raw !== 'string' || raw.length > 32 || !/^\d+(?:\.\d+)?$/.test(raw)) return; var parts = raw.split('.'); if (parts[1] && parts[1].length > 18) return; var denominator = 10n ** BigInt(parts[1] ? parts[1].length : 0); var numerator = BigInt(parts.join('')); var divisor = 100n * denominator; if (numerator <= 0n || numerator >= divisor) return; // Half-up in integer cents, without floating-point half-cent drift. var reduction = Number((BigInt(cents) * numerator + divisor / 2n) / divisor); var candidate = cents - reduction; if (candidate <= 0 || candidate >= cents) return; // Stable DOM order wins a tie; every candidate uses the same original cents. if (winner === null || candidate < finalCents) { winner = flag; finalCents = candidate; } }); } var result = valid && winner ? { finalCents: finalCents, originalCents: cents, variantId: context.variantId } : null; try { if (apply(result) !== true) { if (result) apply(null); return null; } } catch (_) { try { apply(null); } catch (_) { /* Host must keep native price on failure. */ } return null; } if (result && root.isConnected === false) { try { apply(null); } catch (_) { /* Removed scopes cannot expose a winner. */ } return null; } if (result) winner.setAttribute('data-pf-active', ''); return result; } global.CommonsFlagsPricing = Object.freeze({ version: 1, evaluate: evaluate }); if (global.document) global.document.dispatchEvent(new Event('commons-flags-pricing:ready')); })(window);