Broker Check

Global Portfolio Strategy | November 2025

`); return; } } $player.html(poster(v)); } /* ---- intro player ---- */ const $intro = $('#vs-intro-player'); load($intro, VS_INTRO, false); $intro.on('click', '.vs-poster', function () { load($intro, VS_INTRO, true); }); /* ---- markup builders ---- */ function playlistItem(v, i) { return `
  • `; } function gridCard(v, i) { const emptyClass = v.id ? '' : ' is-empty'; return ``; } function seriesMarkup(key) { const s = VS_SERIES[key]; const n = s.videos.length; return `
    ` + `

    ${esc(s.title)}

    Watch the full series

    ` + `
    ` + `
    ${poster(s.videos[0])}

    ${esc(s.videos[0].t)}

    ` + `` + `
    ` + `
    ` + `

    Explore all ${n} videos

    ` + `
    ${s.videos.map(gridCard).join('')}
    ` + `` + `
    `; } // Show only the current series' panel + grid (uses the hidden property, so no valueless attribute in markup) function applyVisibility() { $root.find('.vs-panel, .vs-explore').each(function () { $(this).prop('hidden', $(this).data('series') !== state.current); }); } $('#vs-panels').html(order.map(seriesMarkup).join('')); applyVisibility(); /* ---- select a video within a series ---- */ function select(key, i, autoplay) { state.active[key] = i; const v = VS_SERIES[key].videos[i]; const $panel = $(`#vs-panel-${key}`); load($panel.find('.vs-player'), v, autoplay); $panel.find('.vs-stage-title').text(v.t); $panel.find('.vs-item').removeClass('is-active').removeAttr('aria-current').eq(i).addClass('is-active').attr('aria-current', 'true'); $root.find(`.vs-explore[data-series="${key}"] .vs-card`).removeClass('is-active').eq(i).addClass('is-active'); } /* ---- next-up card ---- */ const ICON_HELP = ''; const ICON_WHY = ''; function renderNext() { const nextKey = state.current === 'why' ? 'help' : 'why'; const s = VS_SERIES[nextKey]; const first = s.videos[0]; const icon = nextKey === 'help' ? ICON_HELP : ICON_WHY; const nextPoster = poster({ id: first.id, t: s.title, d: '' }, `Watch the ${s.title} series`); $('#vs-next').html( `
    ${nextPoster}
    ` + `

    Next, watch

    ${esc(s.title)}

    ` + `

    ${esc(s.blurb)}

    ` + `
    ` + `
    ${icon}
    ` ); } function scrollToEl($el) { $('html, body').animate({ scrollTop: $el.offset().top - 100 }, 350); } /* ---- switch tab ---- */ function showSeries(key, scroll) { state.current = key; $root.find('.vs-tab').attr('aria-selected', 'false').filter(`[data-series="${key}"]`).attr('aria-selected', 'true'); applyVisibility(); // Stop any playing video in the series we just left order.forEach(function (k) { if (k !== key) { load($(`#vs-panel-${k} .vs-player`), VS_SERIES[k].videos[state.active[k]], false); } }); renderNext(); if (scroll) { scrollToEl($root.find('.vs-tabs')); } } /* ---- events ---- */ $root.on('click', '.vs-tab', function () { showSeries($(this).data('series'), false); }); $root.on('click', '[data-go]', function () { showSeries($(this).data('go'), true); }); $root.on('click', '#vs-next-player .vs-poster', function () { showSeries(state.current === 'why' ? 'help' : 'why', true); }); $root.on('click', '.vs-panel .vs-player .vs-poster', function () { const key = $(this).closest('.vs-panel').data('series'); select(key, state.active[key], true); }); $root.on('click', '.vs-item', function () { const key = $(this).closest('.vs-panel').data('series'); select(key, $(this).data('i'), true); }); $root.on('click', '.vs-card', function () { const key = $(this).closest('.vs-explore').data('series'); select(key, $(this).data('i'), true); scrollToEl($(`#vs-panel-${key}`)); }); // "View all videos" jumps down to the grid (playlist link) or back up (grid button) $root.on('click', '.vs-viewall', function () { const key = $(this).closest('.vs-panel').data('series'); scrollToEl($root.find(`.vs-explore[data-series="${key}"]`)); }); $root.on('click', '.vs-explore-btn', function () { const key = $(this).closest('.vs-explore').data('series'); scrollToEl($(`#vs-panel-${key}`)); }); /* ---- init ---- */ order.forEach(function (k) { select(k, 0, false); }); renderNext(); });