<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://pickipedia.xyz/index.php?action=history&amp;feed=atom&amp;title=Candidate%3ACommon.js</id>
	<title>Candidate:Common.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://pickipedia.xyz/index.php?action=history&amp;feed=atom&amp;title=Candidate%3ACommon.js"/>
	<link rel="alternate" type="text/html" href="https://pickipedia.xyz/index.php?title=Candidate:Common.js&amp;action=history"/>
	<updated>2026-06-06T23:08:05Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://pickipedia.xyz/index.php?title=Candidate:Common.js&amp;diff=5251&amp;oldid=prev</id>
		<title>Magent: Staging full proposed Common.js for sysop review (new Show: detector IIFE at bottom)</title>
		<link rel="alternate" type="text/html" href="https://pickipedia.xyz/index.php?title=Candidate:Common.js&amp;diff=5251&amp;oldid=prev"/>
		<updated>2026-06-02T18:52:46Z</updated>

		<summary type="html">&lt;p&gt;Staging full proposed Common.js for sysop review (new Show: detector IIFE at bottom)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// |status=proposed -- bot-staged; remove this line when promoting.&lt;br /&gt;
/**&lt;br /&gt;
* Blue Railroad Submission - Date to Block Height Converter&lt;br /&gt;
* Adds a datepicker that converts dates to Ethereum block heights&lt;br /&gt;
* Also shows time ago for news templates&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
(function() {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
    &lt;br /&gt;
    // Only run on the Blue Railroad Submission form&lt;br /&gt;
    if (!document.querySelector(&amp;#039;input[name=&amp;quot;Blue Railroad Submission[block_height]&amp;quot;]&amp;#039;)) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Reference point: known block and timestamp&lt;br /&gt;
    // Post-merge average block time is ~12.12 seconds&lt;br /&gt;
    const AVG_BLOCK_TIME = 12.12;&lt;br /&gt;
    &lt;br /&gt;
    // Get current block from footer (format: &amp;quot;24,328,442&amp;quot;)&lt;br /&gt;
    function getCurrentBlockFromFooter() {&lt;br /&gt;
        const footerLink = document.querySelector(&amp;#039;a[href*=&amp;quot;etherscan.io/block/&amp;quot;]&amp;#039;);&lt;br /&gt;
        if (footerLink) {&lt;br /&gt;
            const match = footerLink.href.match(/block\/(\d+)/);&lt;br /&gt;
            if (match) return parseInt(match[1]);&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Calculate block height from date&lt;br /&gt;
    function dateToBlockHeight(targetDate, refBlock, refTimestamp) {&lt;br /&gt;
        const targetTimestamp = targetDate.getTime() / 1000;&lt;br /&gt;
        const secondsDiff = refTimestamp - targetTimestamp;&lt;br /&gt;
        const blocksDiff = Math.round(secondsDiff / AVG_BLOCK_TIME);&lt;br /&gt;
        return refBlock - blocksDiff;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Add the datepicker UI&lt;br /&gt;
    function addDatePicker() {&lt;br /&gt;
        const blockInput = document.querySelector(&amp;#039;input[name=&amp;quot;Blue Railroad Submission[block_height]&amp;quot;]&amp;#039;);&lt;br /&gt;
        if (!blockInput) return;&lt;br /&gt;
        &lt;br /&gt;
        const container = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
        container.style.marginTop = &amp;#039;8px&amp;#039;;&lt;br /&gt;
        container.innerHTML = `&lt;br /&gt;
            &amp;lt;label style=&amp;quot;display: block; margin-bottom: 4px; font-size: 0.9em;&amp;quot;&amp;gt;&lt;br /&gt;
                Or pick a date/time:&lt;br /&gt;
            &amp;lt;/label&amp;gt;&lt;br /&gt;
            &amp;lt;input type=&amp;quot;datetime-local&amp;quot; id=&amp;quot;br-datepicker&amp;quot; style=&amp;quot;padding: 4px; margin-right: 8px;&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;button type=&amp;quot;button&amp;quot; id=&amp;quot;br-convert-btn&amp;quot; style=&amp;quot;padding: 4px 12px; cursor: pointer;&amp;quot;&amp;gt;&lt;br /&gt;
                Convert to Block&lt;br /&gt;
            &amp;lt;/button&amp;gt;&lt;br /&gt;
            &amp;lt;span id=&amp;quot;br-status&amp;quot; style=&amp;quot;margin-left: 8px; font-size: 0.9em; color: #666;&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
        `;&lt;br /&gt;
        &lt;br /&gt;
        blockInput.parentNode.appendChild(container);&lt;br /&gt;
        &lt;br /&gt;
        const datePicker = document.getElementById(&amp;#039;br-datepicker&amp;#039;);&lt;br /&gt;
        const convertBtn = document.getElementById(&amp;#039;br-convert-btn&amp;#039;);&lt;br /&gt;
        const status = document.getElementById(&amp;#039;br-status&amp;#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Set default to now&lt;br /&gt;
        const now = new Date();&lt;br /&gt;
        datePicker.value = now.toISOString().slice(0, 16);&lt;br /&gt;
        &lt;br /&gt;
        convertBtn.addEventListener(&amp;#039;click&amp;#039;, function() {&lt;br /&gt;
            const selectedDate = new Date(datePicker.value);&lt;br /&gt;
            if (isNaN(selectedDate.getTime())) {&lt;br /&gt;
                status.textContent = &amp;#039;Invalid date&amp;#039;;&lt;br /&gt;
                status.style.color = &amp;#039;red&amp;#039;;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            const currentBlock = getCurrentBlockFromFooter();&lt;br /&gt;
            if (!currentBlock) {&lt;br /&gt;
                status.textContent = &amp;#039;Could not find reference block&amp;#039;;&lt;br /&gt;
                status.style.color = &amp;#039;red&amp;#039;;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            const currentTimestamp = Date.now() / 1000;&lt;br /&gt;
            const estimatedBlock = dateToBlockHeight(selectedDate, currentBlock, currentTimestamp);&lt;br /&gt;
            &lt;br /&gt;
            if (estimatedBlock &amp;gt; currentBlock) {&lt;br /&gt;
                status.textContent = &amp;#039;Date is in the future!&amp;#039;;&lt;br /&gt;
                status.style.color = &amp;#039;orange&amp;#039;;&lt;br /&gt;
            } else {&lt;br /&gt;
                status.textContent = &amp;#039;~estimated&amp;#039;;&lt;br /&gt;
                status.style.color = &amp;#039;green&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            blockInput.value = estimatedBlock;&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Run when DOM is ready&lt;br /&gt;
    if (document.readyState === &amp;#039;loading&amp;#039;) {&lt;br /&gt;
        document.addEventListener(&amp;#039;DOMContentLoaded&amp;#039;, addDatePicker);&lt;br /&gt;
    } else {&lt;br /&gt;
        addDatePicker();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * TimeAgo — shows &amp;quot;X blocks ago&amp;quot; for transcluded templates.&lt;br /&gt;
 *&lt;br /&gt;
 * Usage in wikitext:&lt;br /&gt;
 *   &amp;lt;span class=&amp;quot;timeago&amp;quot; data-lastmod-page=&amp;quot;Template:NewsShorts&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * Fetches the last revision timestamp from the API and renders&lt;br /&gt;
 * a block-based relative time string using Ethereum block heights.&lt;br /&gt;
 */&lt;br /&gt;
(function() {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    // Post-merge average block time is ~12.12 seconds&lt;br /&gt;
    var AVG_BLOCK_TIME = 12.12;&lt;br /&gt;
&lt;br /&gt;
    var spans = document.querySelectorAll(&amp;#039;.timeago[data-lastmod-page]&amp;#039;);&lt;br /&gt;
    if (!spans.length) return;&lt;br /&gt;
&lt;br /&gt;
    // Format number with commas (e.g., 1234567 -&amp;gt; &amp;quot;1,234,567&amp;quot;)&lt;br /&gt;
    function formatNumber(num) {&lt;br /&gt;
        return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, &amp;#039;,&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Collect unique page titles&lt;br /&gt;
    var titles = [];&lt;br /&gt;
    spans.forEach(function(span) {&lt;br /&gt;
        var t = span.getAttribute(&amp;#039;data-lastmod-page&amp;#039;);&lt;br /&gt;
        if (t &amp;amp;&amp;amp; titles.indexOf(t) === -1) titles.push(t);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Batch query the API (up to 50 titles per request)&lt;br /&gt;
    var api = mw.config.get(&amp;#039;wgScriptPath&amp;#039;) + &amp;#039;/api.php&amp;#039;;&lt;br /&gt;
    var url = api + &amp;#039;?action=query&amp;amp;prop=revisions&amp;amp;rvprop=timestamp&amp;amp;format=json&amp;amp;titles=&amp;#039; +&lt;br /&gt;
        encodeURIComponent(titles.join(&amp;#039;|&amp;#039;));&lt;br /&gt;
&lt;br /&gt;
    fetch(url).then(function(r) { return r.json(); }).then(function(data) {&lt;br /&gt;
        var pages = data.query &amp;amp;&amp;amp; data.query.pages || {};&lt;br /&gt;
        var timestamps = {};&lt;br /&gt;
&lt;br /&gt;
        Object.keys(pages).forEach(function(id) {&lt;br /&gt;
            var page = pages[id];&lt;br /&gt;
            if (page.revisions &amp;amp;&amp;amp; page.revisions[0]) {&lt;br /&gt;
                timestamps[page.title] = new Date(page.revisions[0].timestamp);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        spans.forEach(function(span) {&lt;br /&gt;
            var title = span.getAttribute(&amp;#039;data-lastmod-page&amp;#039;);&lt;br /&gt;
            var ts = timestamps[title];&lt;br /&gt;
            if (!ts) {&lt;br /&gt;
                span.textContent = &amp;#039;&amp;#039;;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            span.textContent = formatBlocksAgo(ts);&lt;br /&gt;
            span.title = ts.toLocaleString();&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    function formatBlocksAgo(date) {&lt;br /&gt;
        var secondsAgo = Math.floor((Date.now() - date.getTime()) / 1000);&lt;br /&gt;
        var blocksAgo = Math.round(secondsAgo / AVG_BLOCK_TIME);&lt;br /&gt;
&lt;br /&gt;
        if (blocksAgo &amp;lt; 1) {&lt;br /&gt;
            return &amp;#039;this block&amp;#039;;&lt;br /&gt;
        } else if (blocksAgo === 1) {&lt;br /&gt;
            return &amp;#039;1 block ago&amp;#039;;&lt;br /&gt;
        } else {&lt;br /&gt;
            return formatNumber(blocksAgo) + &amp;#039; blocks ago&amp;#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * HLS Video Player - Initializes HLS.js for IPFS-hosted videos&lt;br /&gt;
 *&lt;br /&gt;
 * Usage in wikitext (via Template:HLSVideo):&lt;br /&gt;
 *   &amp;lt;div class=&amp;quot;hls-video-player&amp;quot; data-cid=&amp;quot;QmXet6...&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * The gadget loads hls.js and initializes players for any element&lt;br /&gt;
 * with the hls-video-player class and a data-cid attribute.&lt;br /&gt;
 *&lt;br /&gt;
 * Supports both HLS streams (CID/master.m3u8) and raw video files.&lt;br /&gt;
 * Tries HLS first; if the manifest 404s, falls back to direct playback.&lt;br /&gt;
 */&lt;br /&gt;
(function() {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    var IPFS_GATEWAY = &amp;#039;https://ipfs.delivery-kid.cryptograss.live/ipfs&amp;#039;;&lt;br /&gt;
    var HLS_JS_URL = &amp;#039;https://cdn.jsdelivr.net/npm/hls.js@latest&amp;#039;;&lt;br /&gt;
    var hlsLoadPromise = null;&lt;br /&gt;
&lt;br /&gt;
    // CIDv1 (bafy...) is Base32 lowercase, but MediaWiki capitalizes page titles.&lt;br /&gt;
    // CIDv0 (Qm...) is Base58 case-sensitive — must not be lowercased.&lt;br /&gt;
    function normalizeCid(cid) {&lt;br /&gt;
        if (cid &amp;amp;&amp;amp; cid.substring(0, 4) === &amp;#039;Bafy&amp;#039;) {&lt;br /&gt;
            return cid.toLowerCase();&lt;br /&gt;
        }&lt;br /&gt;
        return cid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadHls() {&lt;br /&gt;
        if (typeof Hls !== &amp;#039;undefined&amp;#039;) {&lt;br /&gt;
            return Promise.resolve();&lt;br /&gt;
        }&lt;br /&gt;
        if (hlsLoadPromise) {&lt;br /&gt;
            return hlsLoadPromise;&lt;br /&gt;
        }&lt;br /&gt;
        hlsLoadPromise = new Promise(function(resolve) {&lt;br /&gt;
            var script = document.createElement(&amp;#039;script&amp;#039;);&lt;br /&gt;
            script.src = HLS_JS_URL;&lt;br /&gt;
            script.onload = resolve;&lt;br /&gt;
            document.head.appendChild(script);&lt;br /&gt;
        });&lt;br /&gt;
        return hlsLoadPromise;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function initPlayers() {&lt;br /&gt;
        var containers = document.querySelectorAll(&amp;#039;.hls-video-player[data-cid]:not([data-initialized])&amp;#039;);&lt;br /&gt;
        if (!containers.length) return;&lt;br /&gt;
&lt;br /&gt;
        // Mark ALL containers immediately to prevent race conditions&lt;br /&gt;
        containers.forEach(function(c) {&lt;br /&gt;
            c.setAttribute(&amp;#039;data-initialized&amp;#039;, &amp;#039;true&amp;#039;);&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Then load hls.js and initialize&lt;br /&gt;
        loadHls().then(function() {&lt;br /&gt;
            containers.forEach(initPlayer);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function createVideoElement(width, maxWidth) {&lt;br /&gt;
        var video = document.createElement(&amp;#039;video&amp;#039;);&lt;br /&gt;
        video.controls = true;&lt;br /&gt;
        video.playsInline = true;&lt;br /&gt;
        video.style.width = width;&lt;br /&gt;
        video.style.maxWidth = maxWidth;&lt;br /&gt;
        video.style.backgroundColor = &amp;#039;#000&amp;#039;;&lt;br /&gt;
        video.style.display = &amp;#039;block&amp;#039;;&lt;br /&gt;
        return video;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function fallbackToDirectVideo(container, cid, width, maxWidth) {&lt;br /&gt;
        // CID is a raw video file, not an HLS stream — play directly&lt;br /&gt;
        var directUrl = IPFS_GATEWAY + &amp;#039;/&amp;#039; + normalizeCid(cid);&lt;br /&gt;
        container.innerHTML = &amp;#039;&amp;#039;;&lt;br /&gt;
        var video = createVideoElement(width, maxWidth);&lt;br /&gt;
        video.src = directUrl;&lt;br /&gt;
        video.addEventListener(&amp;#039;error&amp;#039;, function() {&lt;br /&gt;
            container.innerHTML = &amp;#039;&amp;lt;p style=&amp;quot;color: red; padding: 1em;&amp;quot;&amp;gt;Error loading video. The IPFS content may not be available.&amp;lt;/p&amp;gt;&amp;#039;;&lt;br /&gt;
        });&lt;br /&gt;
        container.appendChild(video);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function initPlayer(container) {&lt;br /&gt;
        var cid = container.getAttribute(&amp;#039;data-cid&amp;#039;);&lt;br /&gt;
        var normalCid = normalizeCid(cid);&lt;br /&gt;
        var width = container.getAttribute(&amp;#039;data-width&amp;#039;) || &amp;#039;100%&amp;#039;;&lt;br /&gt;
        var maxWidth = container.getAttribute(&amp;#039;data-max-width&amp;#039;) || &amp;#039;800px&amp;#039;;&lt;br /&gt;
        &lt;br /&gt;
        var hlsSrc = IPFS_GATEWAY + &amp;#039;/&amp;#039; + normalCid + &amp;#039;/master.m3u8&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
        var video = createVideoElement(width, maxWidth);&lt;br /&gt;
        container.appendChild(video);&lt;br /&gt;
&lt;br /&gt;
        if (video.canPlayType(&amp;#039;application/vnd.apple.mpegurl&amp;#039;)) {&lt;br /&gt;
            // Safari native HLS — try HLS first, fall back on error&lt;br /&gt;
            video.src = hlsSrc;&lt;br /&gt;
            video.addEventListener(&amp;#039;error&amp;#039;, function() {&lt;br /&gt;
                fallbackToDirectVideo(container, cid, width, maxWidth);&lt;br /&gt;
            });&lt;br /&gt;
        } else if (typeof Hls !== &amp;#039;undefined&amp;#039; &amp;amp;&amp;amp; Hls.isSupported()) {&lt;br /&gt;
            var hls = new Hls();&lt;br /&gt;
            hls.loadSource(hlsSrc);&lt;br /&gt;
            hls.attachMedia(video);&lt;br /&gt;
            hls.on(Hls.Events.ERROR, function(event, data) {&lt;br /&gt;
                if (data.fatal) {&lt;br /&gt;
                    // HLS failed (likely no master.m3u8) — try direct video&lt;br /&gt;
                    hls.destroy();&lt;br /&gt;
                    fallbackToDirectVideo(container, cid, width, maxWidth);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        } else {&lt;br /&gt;
            // No HLS support — try direct video&lt;br /&gt;
            fallbackToDirectVideo(container, cid, width, maxWidth);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;#039;loading&amp;#039;) {&lt;br /&gt;
        document.addEventListener(&amp;#039;DOMContentLoaded&amp;#039;, initPlayers);&lt;br /&gt;
    } else {&lt;br /&gt;
        initPlayers();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (typeof mw !== &amp;#039;undefined&amp;#039; &amp;amp;&amp;amp; mw.hook) {&lt;br /&gt;
        mw.hook(&amp;#039;wikipage.content&amp;#039;).add(function($content) {&lt;br /&gt;
            initPlayers();&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
/**&lt;br /&gt;
 * Instrument form — validation + page name computation (v24772700)&lt;br /&gt;
 */&lt;br /&gt;
(function() {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
    console.log(&amp;#039;PickiPedia Common.js instrument module v24772700 loaded&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
    mw.hook(&amp;#039;pf.formValidation&amp;#039;).add(function(args) {&lt;br /&gt;
        var nickname = document.querySelector(&amp;#039;input[name=&amp;quot;Instrument[nickname]&amp;quot;]&amp;#039;);&lt;br /&gt;
        if (!nickname) return;&lt;br /&gt;
&lt;br /&gt;
        var make = document.querySelector(&amp;#039;input[name=&amp;quot;Instrument[make]&amp;quot;]&amp;#039;);&lt;br /&gt;
        var model = document.querySelector(&amp;#039;input[name=&amp;quot;Instrument[model]&amp;quot;]&amp;#039;);&lt;br /&gt;
        var serial = document.querySelector(&amp;#039;input[name=&amp;quot;Instrument[serial]&amp;quot;]&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
        var nickVal = nickname.value.trim();&lt;br /&gt;
        var makeVal = make ? make.value.trim() : &amp;#039;&amp;#039;;&lt;br /&gt;
        var modelVal = model ? model.value.trim() : &amp;#039;&amp;#039;;&lt;br /&gt;
        var serialVal = serial ? serial.value.trim() : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
        var hasNickname = nickVal !== &amp;#039;&amp;#039;;&lt;br /&gt;
        var hasMakerComplete = makeVal !== &amp;#039;&amp;#039; &amp;amp;&amp;amp; modelVal !== &amp;#039;&amp;#039; &amp;amp;&amp;amp; serialVal !== &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
        if (!hasNickname &amp;amp;&amp;amp; !hasMakerComplete) {&lt;br /&gt;
            args.numErrors += 1;&lt;br /&gt;
            if (makeVal !== &amp;#039;&amp;#039; || modelVal !== &amp;#039;&amp;#039; || serialVal !== &amp;#039;&amp;#039;) {&lt;br /&gt;
                alert(&amp;#039;Maker identification requires all three: make, model, and serial number. Or provide a nickname instead.&amp;#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                alert(&amp;#039;Please provide either a nickname or maker identification (make, model, and serial number).&amp;#039;);&lt;br /&gt;
            }&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // If no nickname, fill it from make/model/serial for page naming&lt;br /&gt;
        if (!hasNickname) {&lt;br /&gt;
            nickname.value = makeVal + &amp;#039; &amp;#039; + modelVal + &amp;#039; &amp;#039; + serialVal;&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 * Pickipedia — User-subpage zine/Substack styling&lt;br /&gt;
 *&lt;br /&gt;
 * Layout:&lt;br /&gt;
 *   - corner logo (absolute-positioned upper-left of viewport,&lt;br /&gt;
 *     OUTSIDE all wiki wrappers — does not push content down)&lt;br /&gt;
 *   - non-sticky topbar (just nav) at top of body&lt;br /&gt;
 *   - hero block with title (top), then USER:Username kicker below,&lt;br /&gt;
 *     optional dek + meta&lt;br /&gt;
 *   - light/dark mode toggle (persisted in localStorage)&lt;br /&gt;
 *&lt;br /&gt;
 * Variant from HTML comment marker `pickipedia:variant=letter|masthead`&lt;br /&gt;
 * or category membership; default letter.&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
(function () {&lt;br /&gt;
  &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  if (typeof mw === &amp;#039;undefined&amp;#039; || !mw.config) return;&lt;br /&gt;
&lt;br /&gt;
  var nsNumber = mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;);&lt;br /&gt;
  var pageName = mw.config.get(&amp;#039;wgPageName&amp;#039;) || &amp;#039;&amp;#039;;&lt;br /&gt;
  var title    = mw.config.get(&amp;#039;wgTitle&amp;#039;) || &amp;#039;&amp;#039;;&lt;br /&gt;
  var action   = mw.config.get(&amp;#039;wgAction&amp;#039;) || &amp;#039;view&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  if (nsNumber !== 2) return;&lt;br /&gt;
  if (action !== &amp;#039;view&amp;#039;) return;&lt;br /&gt;
  if (title.indexOf(&amp;#039;/&amp;#039;) === -1) return;&lt;br /&gt;
&lt;br /&gt;
  var slash    = title.indexOf(&amp;#039;/&amp;#039;);&lt;br /&gt;
  var username = title.slice(0, slash).replace(/_/g, &amp;#039; &amp;#039;);&lt;br /&gt;
  var subpage  = title.slice(slash + 1).replace(/_/g, &amp;#039; &amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var body = document.body;&lt;br /&gt;
  body.classList.add(&amp;#039;pickipedia-userpost&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var variant = &amp;#039;letter&amp;#039;;&lt;br /&gt;
  var content = document.querySelector(&amp;#039;.mw-parser-output&amp;#039;);&lt;br /&gt;
  if (content) {&lt;br /&gt;
    var html = content.innerHTML || &amp;#039;&amp;#039;;&lt;br /&gt;
    var m = html.match(/pickipedia:variant\s*=\s*(letter|masthead)/i);&lt;br /&gt;
    if (m) variant = m[1].toLowerCase();&lt;br /&gt;
  }&lt;br /&gt;
  var cats = mw.config.get(&amp;#039;wgCategories&amp;#039;) || [];&lt;br /&gt;
  if (cats.indexOf(&amp;#039;Masthead style&amp;#039;) !== -1) variant = &amp;#039;masthead&amp;#039;;&lt;br /&gt;
  if (cats.indexOf(&amp;#039;Letter style&amp;#039;) !== -1) variant = &amp;#039;letter&amp;#039;;&lt;br /&gt;
  body.classList.add(&amp;#039;pickipedia-variant-&amp;#039; + variant);&lt;br /&gt;
&lt;br /&gt;
  var STORAGE_KEY = &amp;#039;pickipedia-mode&amp;#039;;&lt;br /&gt;
  var saved = null;&lt;br /&gt;
  try { saved = localStorage.getItem(STORAGE_KEY); } catch (e) {}&lt;br /&gt;
  if (saved === &amp;#039;dark&amp;#039;) body.classList.add(&amp;#039;pickipedia-dark&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var LOGO_URL = &amp;#039;/images/thumb/8/80/Pickipedia-quarter-transparent.png/400px-Pickipedia-quarter-transparent.png&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  // ---------- Corner logo: stand-alone body child, absolute-positioned. ----------&lt;br /&gt;
  var cornerLogo = document.createElement(&amp;#039;a&amp;#039;);&lt;br /&gt;
  cornerLogo.className = &amp;#039;pp-corner-logo&amp;#039;;&lt;br /&gt;
  cornerLogo.href = &amp;#039;/wiki/Main_Page&amp;#039;;&lt;br /&gt;
  cornerLogo.title = &amp;#039;PickiPedia home&amp;#039;;&lt;br /&gt;
  cornerLogo.innerHTML = &amp;#039;&amp;lt;img src=&amp;quot;&amp;#039; + LOGO_URL + &amp;#039;&amp;quot; alt=&amp;quot;PickiPedia&amp;quot;&amp;gt;&amp;#039;;&lt;br /&gt;
  document.body.insertBefore(cornerLogo, document.body.firstChild);&lt;br /&gt;
&lt;br /&gt;
  // ---------- Topbar (nav only) ----------&lt;br /&gt;
  var topbar = document.createElement(&amp;#039;header&amp;#039;);&lt;br /&gt;
  topbar.className = &amp;#039;pickipedia-topbar&amp;#039;;&lt;br /&gt;
  topbar.innerHTML =&lt;br /&gt;
    &amp;#039;&amp;lt;nav class=&amp;quot;pickipedia-topbar-nav&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
      &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + mw.util.getUrl(pageName, { action: &amp;#039;edit&amp;#039; }) + &amp;#039;&amp;quot;&amp;gt;edit&amp;lt;/a&amp;gt;&amp;#039; +&lt;br /&gt;
      &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + mw.util.getUrl(pageName, { action: &amp;#039;history&amp;#039; }) + &amp;#039;&amp;quot;&amp;gt;history&amp;lt;/a&amp;gt;&amp;#039; +&lt;br /&gt;
      &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + mw.util.getUrl(&amp;#039;Talk:&amp;#039; + pageName) + &amp;#039;&amp;quot;&amp;gt;talk&amp;lt;/a&amp;gt;&amp;#039; +&lt;br /&gt;
    &amp;#039;&amp;lt;/nav&amp;gt;&amp;#039;;&lt;br /&gt;
  document.body.insertBefore(topbar, cornerLogo.nextSibling);&lt;br /&gt;
&lt;br /&gt;
  // ---------- Hero ----------&lt;br /&gt;
  if (content) {&lt;br /&gt;
    var dek = &amp;#039;&amp;#039;;&lt;br /&gt;
    var dekEl = content.querySelector(&amp;#039;.pp-dek-source&amp;#039;);&lt;br /&gt;
    if (dekEl) {&lt;br /&gt;
      dek = dekEl.innerHTML;&lt;br /&gt;
      dekEl.remove();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var kickerHtml = &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + mw.util.getUrl(&amp;#039;User:&amp;#039; + username.replace(/ /g, &amp;#039;_&amp;#039;)) +&lt;br /&gt;
                     &amp;#039;&amp;quot;&amp;gt;User:&amp;#039; + escapeHtml(username) + &amp;#039;&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
    var kickerEl = content.querySelector(&amp;#039;.pp-kicker-source&amp;#039;);&lt;br /&gt;
    if (kickerEl) {&lt;br /&gt;
      kickerHtml = escapeHtml(kickerEl.textContent.trim());&lt;br /&gt;
      kickerEl.remove();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var lastMod = &amp;#039;&amp;#039;;&lt;br /&gt;
    var lastModEl = document.getElementById(&amp;#039;footer-info-lastmod&amp;#039;);&lt;br /&gt;
    if (lastModEl) lastMod = lastModEl.textContent.replace(/^\s*This page was last (edited|modified) on\s*/i, &amp;#039;&amp;#039;).trim();&lt;br /&gt;
&lt;br /&gt;
    var hero = document.createElement(&amp;#039;header&amp;#039;);&lt;br /&gt;
    hero.className = &amp;#039;pickipedia-hero&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
    if (variant === &amp;#039;masthead&amp;#039;) {&lt;br /&gt;
      hero.innerHTML =&lt;br /&gt;
        &amp;#039;&amp;lt;div class=&amp;quot;pp-topbar&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
          &amp;#039;&amp;lt;div class=&amp;quot;pp-kicker&amp;quot;&amp;gt;&amp;#039; + kickerHtml + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
          &amp;#039;&amp;lt;div class=&amp;quot;pp-topbar-rule&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
          (lastMod ? &amp;#039;&amp;lt;div class=&amp;quot;pp-topbar-vol&amp;quot;&amp;gt;&amp;#039; + escapeHtml(lastMod) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; : &amp;#039;&amp;#039;) +&lt;br /&gt;
        &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
        &amp;#039;&amp;lt;div class=&amp;quot;pp-titlewrap&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
          &amp;#039;&amp;lt;h1 class=&amp;quot;pp-title&amp;quot;&amp;gt;&amp;#039; + escapeHtml(subpage) + &amp;#039;&amp;lt;/h1&amp;gt;&amp;#039; +&lt;br /&gt;
          (dek ? &amp;#039;&amp;lt;p class=&amp;quot;pp-dek&amp;quot;&amp;gt;&amp;#039; + dek + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039; : &amp;#039;&amp;#039;) +&lt;br /&gt;
        &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
    } else {&lt;br /&gt;
      // Letter variant: title first, then kicker, then optional dek/meta.&lt;br /&gt;
      hero.innerHTML =&lt;br /&gt;
        &amp;#039;&amp;lt;h1 class=&amp;quot;pp-title&amp;quot;&amp;gt;&amp;#039; + escapeHtml(subpage) + &amp;#039;&amp;lt;/h1&amp;gt;&amp;#039; +&lt;br /&gt;
        &amp;#039;&amp;lt;div class=&amp;quot;pp-kicker&amp;quot;&amp;gt;&amp;#039; + kickerHtml + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
        (dek ? &amp;#039;&amp;lt;p class=&amp;quot;pp-dek&amp;quot;&amp;gt;&amp;#039; + dek + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039; : &amp;#039;&amp;#039;) +&lt;br /&gt;
        (lastMod ? &amp;#039;&amp;lt;div class=&amp;quot;pp-meta&amp;quot;&amp;gt;Last edited &amp;#039; + escapeHtml(lastMod) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; : &amp;#039;&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
    content.parentNode.insertBefore(hero, content);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // ---------- Light/dark toggle ----------&lt;br /&gt;
  var toggle = document.createElement(&amp;#039;button&amp;#039;);&lt;br /&gt;
  toggle.className = &amp;#039;pickipedia-mode&amp;#039;;&lt;br /&gt;
  toggle.type = &amp;#039;button&amp;#039;;&lt;br /&gt;
  toggle.textContent = body.classList.contains(&amp;#039;pickipedia-dark&amp;#039;) ? &amp;#039;☼ Light&amp;#039; : &amp;#039;☾ Dark&amp;#039;;&lt;br /&gt;
  toggle.addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
    var dark = body.classList.toggle(&amp;#039;pickipedia-dark&amp;#039;);&lt;br /&gt;
    toggle.textContent = dark ? &amp;#039;☼ Light&amp;#039; : &amp;#039;☾ Dark&amp;#039;;&lt;br /&gt;
    try { localStorage.setItem(STORAGE_KEY, dark ? &amp;#039;dark&amp;#039; : &amp;#039;light&amp;#039;); } catch (e) {}&lt;br /&gt;
  });&lt;br /&gt;
  document.body.appendChild(toggle);&lt;br /&gt;
&lt;br /&gt;
  function escapeHtml(s) {&lt;br /&gt;
    return String(s == null ? &amp;#039;&amp;#039; : s)&lt;br /&gt;
      .replace(/&amp;amp;/g, &amp;#039;&amp;amp;amp;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;lt;/g, &amp;#039;&amp;amp;lt;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;gt;/g, &amp;#039;&amp;amp;gt;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;quot;/g, &amp;#039;&amp;amp;quot;&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
}());&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Pickipedia — Show: page hero.&lt;br /&gt;
 *&lt;br /&gt;
 * For mainspace pages whose title starts with &amp;quot;Show:&amp;quot; (the legacy&lt;br /&gt;
 * mainspace convention used pre-namespace), adds .pickipedia-show&lt;br /&gt;
 * to body and absorbs Template:Show&amp;#039;s infobox into a poster-style&lt;br /&gt;
 * hero. If the page does not use Template:Show only the body class&lt;br /&gt;
 * is added — the setlist typography in Common.css still applies.&lt;br /&gt;
 */&lt;br /&gt;
(function () {&lt;br /&gt;
  &amp;#039;use strict&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  if (typeof mw === &amp;#039;undefined&amp;#039; || !mw.config) return;&lt;br /&gt;
&lt;br /&gt;
  var nsNumber = mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;);&lt;br /&gt;
  var title    = mw.config.get(&amp;#039;wgTitle&amp;#039;) || &amp;#039;&amp;#039;;&lt;br /&gt;
  var action   = mw.config.get(&amp;#039;wgAction&amp;#039;) || &amp;#039;view&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  if (nsNumber !== 0) return;&lt;br /&gt;
  if (action !== &amp;#039;view&amp;#039;) return;&lt;br /&gt;
  if (title.indexOf(&amp;#039;Show:&amp;#039;) !== 0) return;&lt;br /&gt;
&lt;br /&gt;
  var body = document.body;&lt;br /&gt;
  body.classList.add(&amp;#039;pickipedia-show&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var content = document.querySelector(&amp;#039;.mw-parser-output&amp;#039;);&lt;br /&gt;
  if (!content) return;&lt;br /&gt;
&lt;br /&gt;
  var infobox = content.querySelector(&amp;#039;.show-infobox&amp;#039;);&lt;br /&gt;
  if (!infobox) return;  // Bare show page — body class only.&lt;br /&gt;
&lt;br /&gt;
  // ---------- Pull fields out of the existing infobox ----------&lt;br /&gt;
  // Template:Show emits rows of &amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;Label:&amp;lt;/strong&amp;gt; value&amp;lt;/div&amp;gt;&lt;br /&gt;
  // plus a top banner with &amp;quot;Artists at Venue&amp;quot; and optional image.&lt;br /&gt;
  function fieldValue(label) {&lt;br /&gt;
    var rows = infobox.querySelectorAll(&amp;#039;div&amp;#039;);&lt;br /&gt;
    for (var i = 0; i &amp;lt; rows.length; i++) {&lt;br /&gt;
      var s = rows[i].querySelector(&amp;#039;strong&amp;#039;);&lt;br /&gt;
      if (!s) continue;&lt;br /&gt;
      var labelText = s.textContent.replace(/[:\s]*$/, &amp;#039;&amp;#039;).trim();&lt;br /&gt;
      if (labelText !== label) continue;&lt;br /&gt;
      var clone = rows[i].cloneNode(true);&lt;br /&gt;
      var strong = clone.querySelector(&amp;#039;strong&amp;#039;);&lt;br /&gt;
      if (strong) strong.remove();&lt;br /&gt;
      return clone.innerHTML.trim().replace(/^[\s:]+/, &amp;#039;&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;#039;&amp;#039;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  var artists  = fieldValue(&amp;#039;Artists&amp;#039;);&lt;br /&gt;
  var venue    = fieldValue(&amp;#039;Venue&amp;#039;);&lt;br /&gt;
  var showtime = fieldValue(&amp;#039;Showtime&amp;#039;);&lt;br /&gt;
  var tickets  = fieldValue(&amp;#039;Tickets&amp;#039;);&lt;br /&gt;
  var price    = fieldValue(&amp;#039;Price&amp;#039;);&lt;br /&gt;
  var ages     = fieldValue(&amp;#039;Ages&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var imageImg = infobox.querySelector(&amp;#039;img&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  var status = &amp;#039;&amp;#039;;&lt;br /&gt;
  if (infobox.classList.contains(&amp;#039;show-verified&amp;#039;)) status = &amp;#039;verified&amp;#039;;&lt;br /&gt;
  else if (infobox.classList.contains(&amp;#039;bot-proposal&amp;#039;)) status = &amp;#039;proposed&amp;#039;;&lt;br /&gt;
  else if (infobox.classList.contains(&amp;#039;show-unverified&amp;#039;)) status = &amp;#039;unverified&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  // ---------- Build the poster hero ----------&lt;br /&gt;
  // Showtime is rendered by Template:Show as&lt;br /&gt;
  // [https://etherscan.io/block/N N] — pull the block number out and&lt;br /&gt;
  // format it with commas so the kicker reads &amp;quot;BLOCK 24,144,194&amp;quot;.&lt;br /&gt;
  function formatShowtime(htmlIn) {&lt;br /&gt;
    if (!htmlIn) return &amp;#039;&amp;#039;;&lt;br /&gt;
    var tmp = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
    tmp.innerHTML = htmlIn;&lt;br /&gt;
    var anchor = tmp.querySelector(&amp;#039;a&amp;#039;);&lt;br /&gt;
    var blockNum = (anchor ? anchor.textContent : tmp.textContent).trim();&lt;br /&gt;
    var asInt = parseInt(blockNum.replace(/[^\d]/g, &amp;#039;&amp;#039;), 10);&lt;br /&gt;
    if (isNaN(asInt)) return blockNum;&lt;br /&gt;
    var formatted = asInt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, &amp;#039;,&amp;#039;);&lt;br /&gt;
    var href = anchor ? anchor.href : &amp;#039;&amp;#039;;&lt;br /&gt;
    if (href) {&lt;br /&gt;
      return &amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + href + &amp;#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener&amp;quot;&amp;gt;Block &amp;#039; + formatted + &amp;#039;&amp;lt;/a&amp;gt;&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
    return &amp;#039;Block &amp;#039; + formatted;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  var kickerBits = [];&lt;br /&gt;
  var showtimeHtml = formatShowtime(showtime);&lt;br /&gt;
  if (showtimeHtml) kickerBits.push(showtimeHtml);&lt;br /&gt;
&lt;br /&gt;
  var kickerHtml = kickerBits.length&lt;br /&gt;
    ? &amp;#039;&amp;lt;div class=&amp;quot;pp-kicker&amp;quot;&amp;gt;&amp;#039; + kickerBits.join(&amp;#039;&amp;lt;span class=&amp;quot;pp-sep&amp;quot;&amp;gt;·&amp;lt;/span&amp;gt;&amp;#039;) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
    : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  var venueHtml = venue ? &amp;#039;&amp;lt;p class=&amp;quot;pp-venue&amp;quot;&amp;gt;at &amp;#039; + venue + &amp;#039;&amp;lt;/p&amp;gt;&amp;#039; : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  var metaBits = [];&lt;br /&gt;
  if (price)&lt;br /&gt;
    metaBits.push(&amp;#039;&amp;lt;span&amp;gt;&amp;lt;span class=&amp;quot;pp-meta-label&amp;quot;&amp;gt;Price&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pp-meta-value&amp;quot;&amp;gt;$&amp;#039; +&lt;br /&gt;
      escapeHtml(price.replace(/^\$/, &amp;#039;&amp;#039;)) + &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
  if (ages)&lt;br /&gt;
    metaBits.push(&amp;#039;&amp;lt;span&amp;gt;&amp;lt;span class=&amp;quot;pp-meta-label&amp;quot;&amp;gt;Ages&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;pp-meta-value&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
      ages + &amp;#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;);&lt;br /&gt;
  var metaHtml = metaBits.length&lt;br /&gt;
    ? &amp;#039;&amp;lt;div class=&amp;quot;pp-meta&amp;quot;&amp;gt;&amp;#039; + metaBits.join(&amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
    : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  var imageHtml = &amp;#039;&amp;#039;;&lt;br /&gt;
  if (imageImg) {&lt;br /&gt;
    imageHtml = &amp;#039;&amp;lt;div class=&amp;quot;pp-image&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&amp;#039; + imageImg.src +&lt;br /&gt;
      &amp;#039;&amp;quot; alt=&amp;quot;&amp;#039; + escapeHtml(imageImg.alt || &amp;#039;&amp;#039;) + &amp;#039;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Tickets field is an anchor; surface its href as a poster action.&lt;br /&gt;
  var actionBits = [];&lt;br /&gt;
  if (tickets) {&lt;br /&gt;
    var tmp = document.createElement(&amp;#039;div&amp;#039;); tmp.innerHTML = tickets;&lt;br /&gt;
    var ticketAnchor = tmp.querySelector(&amp;#039;a&amp;#039;);&lt;br /&gt;
    if (ticketAnchor &amp;amp;&amp;amp; ticketAnchor.href) {&lt;br /&gt;
      actionBits.push(&amp;#039;&amp;lt;a href=&amp;quot;&amp;#039; + ticketAnchor.href +&lt;br /&gt;
        &amp;#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener&amp;quot;&amp;gt;Tickets&amp;lt;/a&amp;gt;&amp;#039;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  var actionsHtml = actionBits.length&lt;br /&gt;
    ? &amp;#039;&amp;lt;div class=&amp;quot;pp-actions&amp;quot;&amp;gt;&amp;#039; + actionBits.join(&amp;#039;&amp;#039;) + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
    : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  var statusHtml = status&lt;br /&gt;
    ? &amp;#039;&amp;lt;div class=&amp;quot;pp-status is-&amp;#039; + status + &amp;#039;&amp;quot;&amp;gt;&amp;#039; + status + &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
    : &amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
  var titleHtml = artists || escapeHtml(title.replace(/^Show:\s*/, &amp;#039;&amp;#039;));&lt;br /&gt;
&lt;br /&gt;
  var hero = document.createElement(&amp;#039;header&amp;#039;);&lt;br /&gt;
  hero.className = &amp;#039;show-poster&amp;#039;;&lt;br /&gt;
  hero.innerHTML =&lt;br /&gt;
    statusHtml +&lt;br /&gt;
    kickerHtml +&lt;br /&gt;
    &amp;#039;&amp;lt;h1 class=&amp;quot;pp-title&amp;quot;&amp;gt;&amp;#039; + titleHtml + &amp;#039;&amp;lt;/h1&amp;gt;&amp;#039; +&lt;br /&gt;
    venueHtml +&lt;br /&gt;
    metaHtml +&lt;br /&gt;
    imageHtml +&lt;br /&gt;
    actionsHtml;&lt;br /&gt;
&lt;br /&gt;
  content.insertBefore(hero, content.firstChild);&lt;br /&gt;
  infobox.classList.add(&amp;#039;is-absorbed&amp;#039;);&lt;br /&gt;
  body.classList.add(&amp;#039;has-show-hero&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
  function escapeHtml(s) {&lt;br /&gt;
    return String(s == null ? &amp;#039;&amp;#039; : s)&lt;br /&gt;
      .replace(/&amp;amp;/g, &amp;#039;&amp;amp;amp;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;lt;/g, &amp;#039;&amp;amp;lt;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;gt;/g, &amp;#039;&amp;amp;gt;&amp;#039;)&lt;br /&gt;
      .replace(/&amp;quot;/g, &amp;#039;&amp;amp;quot;&amp;#039;);&lt;br /&gt;
  }&lt;br /&gt;
}());&lt;/div&gt;</summary>
		<author><name>Magent</name></author>
	</entry>
</feed>