MediaWiki:Gadget-wix-interactive.js: Difference between revisions

Content deleted Content added
No edit summary
No edit summary
Line 18:
 
var dispatchers = {
'pool-simulator': initPoolSimulator,
'insurer-engines': initInsurerEngines,
'premium-matching': initPremiumMatching,
'reserve-sensitivity': initReserveSensitivity
};
 
Line 949 ⟶ 950:
 
setMode( 'frontload' );
}
 
 
/* ================================================================
RESERVE SENSITIVITY
Slider showing how reserve reassessments flow through to P&L
and shareholders' equity.
================================================================ */
 
function initReserveSensitivity( container ) {
 
/* ── Constants ────────────────────────────────────────────── */
 
var RESERVES = 90; // €bn
var EQUITY = 50; // €bn
var TAX = 0.25;
var MAX_PCT = 10; // bar scale cap
 
/* ── Colors (WIX tokens) ─────────────────────────────────── */
 
var styles = getComputedStyle( container );
var colorPos = styles.getPropertyValue( '--wix-correct' ).trim() || '#1e8449';
var colorNeg = styles.getPropertyValue( '--wix-wrong' ).trim() || '#922b21';
 
/* ── Formatting ──────────────────────────────────────────── */
 
function fmtBn( v ) {
var abs = Math.abs( v );
return abs >= 1 ? abs.toFixed( 1 ) : abs.toFixed( 2 );
}
 
/* ── Build UI ────────────────────────────────────────────── */
 
wix.empty( container );
 
var wrapper = wix.el( 'div', { className: 'wix-eng-wrapper' } );
container.appendChild( wrapper );
 
// Slider row
var slider = wix.el( 'input', {
type: 'range', min: '-5', max: '5', value: '2', step: '0.5'
} );
 
wrapper.appendChild( wix.el( 'div', { className: 'wix-eng-section-label', textContent: 'Reserve reassessment' } ) );
wrapper.appendChild( wix.el( 'div', { className: 'wix-rs-slider-row' }, [
wix.el( 'span', { className: 'wix-rs-bound', textContent: '-5%' } ),
slider,
wix.el( 'span', { className: 'wix-rs-bound', textContent: '+5%' } )
] ) );
 
// Stat cards — row 1: P&L impact
var elPretax = wix.el( 'div', { className: 'wix-rs-card-num' } );
var elAftertax = wix.el( 'div', { className: 'wix-rs-card-num' } );
 
wrapper.appendChild( wix.el( 'div', { className: 'wix-rs-cards' }, [
wix.el( 'div', { className: 'wix-rs-card' }, [
wix.el( 'div', { className: 'wix-rs-card-label', textContent: 'Pre-tax P&L impact' } ),
elPretax
] ),
wix.el( 'div', { className: 'wix-rs-card' }, [
wix.el( 'div', { className: 'wix-rs-card-label', textContent: 'After-tax (25%) P&L impact' } ),
elAftertax
] )
] ) );
 
// Stat cards — row 2: reserves
var elNewRes = wix.el( 'div', { className: 'wix-rs-card-num' } );
 
wrapper.appendChild( wix.el( 'div', { className: 'wix-rs-cards' }, [
wix.el( 'div', { className: 'wix-rs-card' }, [
wix.el( 'div', { className: 'wix-rs-card-label', textContent: 'Reserves (original)' } ),
wix.el( 'div', { className: 'wix-rs-card-num wix-rs-card-num--muted', textContent: '\u20AC90.0bn' } )
] ),
wix.el( 'div', { className: 'wix-rs-card' }, [
wix.el( 'div', { className: 'wix-rs-card-label', textContent: 'Reserves (revised)' } ),
elNewRes
] )
] ) );
 
// Bar charts
var bar1Fill = wix.el( 'div', { className: 'wix-rs-bar-fill' } );
var bar2Fill = wix.el( 'div', { className: 'wix-rs-bar-fill' } );
 
wrapper.appendChild( wix.el( 'div', { className: 'wix-rs-bars' }, [
wix.el( 'div', {}, [
wix.el( 'div', { className: 'wix-rs-bar-label', textContent: 'Reserve reassessment' } ),
wix.el( 'div', { className: 'wix-rs-bar-track' }, [
wix.el( 'div', { className: 'wix-rs-bar-center' } ),
bar1Fill
] )
] ),
wix.el( 'div', {}, [
wix.el( 'div', { className: 'wix-rs-bar-label', textContent: 'Impact on shareholders\u2019 equity (\u20AC50bn)' } ),
wix.el( 'div', { className: 'wix-rs-bar-track' }, [
wix.el( 'div', { className: 'wix-rs-bar-center' } ),
bar2Fill
] )
] )
] ) );
 
 
/* ── Bar Helper ──────────────────────────────────────────── */
 
function setBar( el, pct, color ) {
var clamped = wix.clamp( pct, -MAX_PCT, MAX_PCT );
var w = Math.abs( clamped ) / MAX_PCT * 50;
 
if ( clamped >= 0 ) {
el.style.left = '50%';
el.style.width = w + '%';
el.style.borderRadius = '0 var(--wix-radius) var(--wix-radius) 0';
} else {
el.style.left = ( 50 - w ) + '%';
el.style.width = w + '%';
el.style.borderRadius = 'var(--wix-radius) 0 0 var(--wix-radius)';
}
 
el.style.background = color;
var label = ( pct >= 0 ? '+' : '' ) + pct.toFixed( 1 ) + '%';
el.textContent = Math.abs( pct ) >= 0.5 ? label : '';
}
 
 
/* ── Update Logic ────────────────────────────────────────── */
 
function update() {
var p = parseFloat( slider.value );
var delta = RESERVES * p / 100;
var pretax = -delta;
var aftertax = pretax * ( 1 - TAX );
 
// P&L cards
var sign;
 
sign = pretax >= 0 ? '+' : '-';
elPretax.textContent = sign + '\u20AC' + fmtBn( pretax ) + 'bn';
elPretax.className = 'wix-rs-card-num' + ( pretax > 0 ? ' wix-rs-card-num--pos' : pretax < 0 ? ' wix-rs-card-num--neg' : '' );
 
sign = aftertax >= 0 ? '+' : '-';
elAftertax.textContent = sign + '\u20AC' + fmtBn( aftertax ) + 'bn';
elAftertax.className = 'wix-rs-card-num' + ( aftertax > 0 ? ' wix-rs-card-num--pos' : aftertax < 0 ? ' wix-rs-card-num--neg' : '' );
 
// Revised reserves
elNewRes.textContent = '\u20AC' + ( RESERVES + delta ).toFixed( 1 ) + 'bn';
 
// Bars
var resPct = p;
var eqPct = aftertax / EQUITY * 100;
setBar( bar1Fill, resPct, p <= 0 ? colorPos : colorNeg );
setBar( bar2Fill, eqPct, aftertax >= 0 ? colorPos : colorNeg );
}
 
 
/* ── Event Wiring ────────────────────────────────────────── */
 
slider.addEventListener( 'input', update );
 
// Initial render
update();
}