PageSourceSearch

https://www.power1043.com/wp-content/plugins/wpb-audio-stream-mana…b-audio-stream-manager-public.js?ver=1.1.66

js power1043.com collected 2026-09-30 13:35:52 UTC 72,111 bytes, 2,008 lines download raw bytes

1var playerStatus = jQuery("#audio-stream-player-status").val();
2console.log("playerStatus start line 1:",playerStatus);
3
4jQuery(document).ready(function( $ ){
5  readyFn_audioStreamManager( jQuery, 'document.ready' );
6});
7
8function readyFn_audioStreamManager($, flagCheck = ''){
9  //jQuery('body').addClass(site_info.player_position_class);
10  var defaultStationId = jQuery("#station-default-hiiden-id").val(),
11    secondStationId = jQuery("#station-second-hidden-id").val(),
12    thirdStationId = jQuery("#station-third-hidden-id").val(),
13    titles = jQuery(".player-content .metadata label span"),
14    titleLength = 18,
15    player = jQuery(".audio-stream-player"),
16    playerFixedBar = jQuery(".audio-stream-player.fixed-bar"),
17    playerWidth = player.width(),
18    playerWrapper = jQuery(".audio-stream-player"),
19    openMobilePlayerBtn =
20      '<a href="#" class="open-mobile-player">Listen To Our Streams <i class="fa fa-play-circle"></i></a>',
21    playPauseBtns = jQuery(".audio-stream-player #play-pause"),
22    floatingControlsWrapper = '<div class="floating-controls-wrapper"></div>',
23    isInHeader = jQuery("header .audio-stream-player").length,
24    isMobile = false,
25    currentStation = {},
26    defaultStation = {},
27    firstStation = {},
28    secondStation = {},
29    thirdStation = {},
30    autoAttempts = 0,
31    maxPlayAttempts = 5,
32    daysToStorePlayAttempts = 365,
33    sessionTimer = null,
34    sessionIntervalTime = 1000 * 60 * 60 * 2; //2 hour;
35    if(site_info.id == 1224){ // for testing
36      sessionIntervalTime = 1000 * 30 ;
37    }
38    // sessionIntervalTime = 3000;
39
40   // Detection for small screesn as mobile view
41   if (window.matchMedia("only screen and (max-width: 500px)").matches) {
42    isMobile = true;
43  }
44
45  const userAgent = navigator.userAgent || navigator.vendor || window.opera;
46  const mobileAgents = [
47    /Android/i,
48    /webOS/i,
49    /iPhone/i,
50    /iPad/i,
51    /iPod/i,
52    /BlackBerry/i,
53    /Windows Phone/i,
54    /Opera Mini/i,
55    /IEMobile/i
56  ];
57  var isMobilecheck = mobileAgents.some(agent => userAgent.match(agent));
58  if(isMobile && isMobilecheck){
59    console.log("Mobile Browser Detected...");
60    ima_ad_tag_url = 0;
61  }
62  else{
63    console.log("Desktop Browser Detected...");
64    console.log("ima_ad_tag_url: ", ima_ad_tag_url);
65
66  }
67
68  // Responsive player classes and titles
69  if (playerWidth > 380 && playerWidth < 470) {
70    titleLength = 36;
71    player.removeClass("large medium");
72  } else if (playerWidth > 470 && playerWidth < 500) {
73    titleLength = 80;
74    player.addClass("medium");
75    player.removeClass("large");
76  } else if (playerWidth > 500) {
77    titleLength = 120;
78    player.addClass("large");
79    player.removeClass("medium");
80  }
81
82  // Truncate long titles
83  function wpb_truncateTitle(titles, length) {
84    titles.each(function() {
85      var $this = jQuery(this),
86        $titleText = $this.text(),
87        $currentLength = $titleText.length;
88      if ($currentLength > length) {
89        $this.text($titleText.substr(0, length) + "...");
90      }
91    });
92  }
93
94  function wpb_renderSelect(station) {
95    if (!station.id) {
96      return station.text;
97    }
98    var $station = jQuery(
99      '<span><img src="' +
100        station.station_logo_url +
101        '" class="img-station-logo" /> ' +
102        station.text +
103        "</span>"
104    );
105    return $station;
106  }
107
108  // This function initilizes all UI elements needed for
109  // the mobile view user experience
110  function wpb_initMobileUi() {
111    var spacing = 10, // as left and right padding
112      // getActiveSongMetadata = Amplitude.getActiveSongMetadata(),
113      playerWrapperHeight = playerWrapper.outerHeight(),
114      playerWrapperHeightValue = "-" + playerWrapperHeight + "px",
115      headerPlayerWrapper = jQuery("header .audio-stream-player"),
116      playerParentWidth = jQuery("header").width() - spacing;
117
118    // Add UI elements
119    jQuery("body").prepend(openMobilePlayerBtn);
120    headerPlayerWrapper.css("top", playerWrapperHeightValue);
121    headerPlayerWrapper.css({
122      position: "absolute",
123      height: "auto",
124      width: playerParentWidth,
125      left: spacing / 2
126    });
127
128    // Open Audio Player on Mobile view
129    jQuery(document).on("click", ".open-mobile-player", function() {
130      var openMobilePlayerBtnHeight = jQuery(".open-mobile-player").outerHeight();
131      if (playerWrapper.hasClass("open")) {
132        headerPlayerWrapper.css({ top: playerWrapperHeightValue });
133      } else {
134        headerPlayerWrapper.css({ top: openMobilePlayerBtnHeight });
135      }
136      headerPlayerWrapper.toggleClass("open");
137    });
138  }
139
140  function wpb_initFloatingPlayer() {
141    var clonedFloatingBtn = playPauseBtns.clone().prop('id', 'floating-play-pause').addClass('floating-player'),
142    getActiveSongMetadata = Amplitude.getActiveSongMetadata();
143    if(player_setting_status == "1"){
144      if(player_setting.playerSettings.playerStatus == 1 && player_setting.playerSettings.playerPosition == "header"){
145        // Add UI elements
146        jQuery("body")
147          .append(floatingControlsWrapper);
148        jQuery(".floating-controls-wrapper").html(clonedFloatingBtn);
149      }
150    }
151
152    // Init floating btn
153    jQuery(document).on(
154      "click",
155      ".floating-controls-wrapper #floating-play-pause",
156      function() {
157        playerStatus = jQuery("#audio-stream-player-status").val();
158        if(playerStatus == "stop"){
159          Amplitude.play();
160          if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
161            player_vast_ad_tag_trigger();
162          }
163          jQuery("#audio-stream-player-status").val("play");
164          jQuery(".amplitude-play-pause")
165          .addClass("amplitude-playing")
166          .removeClass("amplitude-paused");
167          wpb_truncateTitle(titles, titleLength);
168          updateNowPlayingMetaRouter(currentStation);
169          updateHeaderPlayer(currentStation);
170        }
171        else if(playerStatus == "play"){
172          jQuery("#audio-stream-player-status").val("stop");
173          Amplitude.stop();
174          if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
175            if (adDisplayContainer) {
176              adDisplayContainer.destroy();
177              console.log("adDisplayContainer  is destroy in play pause trigger...");
178            }
179            setUpIMA();
180          }
181          jQuery(".amplitude-play-pause")
182          .addClass("amplitude-paused")
183          .removeClass("amplitude-playing");
184          jQuery(".schedule-one-pause").hide();
185          jQuery(".schedule-one-play").show();
186          jQuery(".schedule-two-pause").hide();
187          jQuery(".schedule-two-play").show();
188          jQuery(".schedule-three-pause").hide();
189          jQuery(".schedule-three-play").show();
190        }
191      }
192    );
193    
194    // jQuery(document).on("click","#play-pause",function() {
195    //   if(ima_ad_tag_url != "0"){
196    //     player_vast_ad_tag_trigger();
197    //   }
198    // });
199
200    // jQuery(document).on(
201    //   "click",
202    //   ".floating-controls-wrapper #play-pause .play",
203    //   function() {
204    //     //Amplitude.playNow(getActiveSongMetadata.url);
205    //     Amplitude.play();
206    //     jQuery(".amplitude-play-pause")
207    //       .addClass("amplitude-playing")
208    //       .removeClass("amplitude-paused");
209    //     wpb_truncateTitle(titles, titleLength);
210    //   }
211    // );
212
213    // jQuery(document).on(
214    //   "click",
215    //   ".floating-controls-wrapper #play-pause .pause",
216    //   function() {
217    //     Amplitude.pause();
218    //     jQuery(".amplitude-play-pause")
219    //       .addClass("amplitude-paused")
220    //       .removeClass("amplitude-playing");
221    //   }
222    // );
223    
224    // jQuery(document).on("click","#play-pause",function() {
225    //   var playerStatus = jQuery("#audio-stream-player-status").val();
226    //   if(playerStatus == "stop"){
227    //     //Amplitude.playNow(defaultStation);
228    //     jQuery(".sa-play").hide();
229    //     jQuery(".sa-pause").show();
230    //     jQuery(".ta-play").hide();
231    //     jQuery(".ta-pause").show();
232    //     jQuery("#audio-stream-player-status").val("play");
233    //     jQuery("#audio-stream-second-player-status").val("stop");
234    //     jQuery("#audio-stream-third-player-status").val("stop");
235    //   }
236    //   else if(playerStatus == "play"){
237    //     jQuery("#audio-stream-player-status").val("stop");
238    //   }
239    //  }
240    // );
241
242    // jQuery(document).on("click","#second-play-pause",function() {
243    //   var playerStatus = jQuery("#audio-stream-second-player-status").val();
244    //   if(playerStatus == "stop"){
245    //     jQuery(".sa-pause").hide();
246    //     jQuery(".sa-play").show();
247    //     Amplitude.playNow(secondStation);
248    //     jQuery(".amplitude-play-pause")
249    //       .addClass("amplitude-paused")
250    //       .removeClass("amplitude-playing");
251    //     jQuery(".ta-play").hide();
252    //     jQuery(".ta-pause").show();
253    //     jQuery("#audio-stream-second-player-status").val("play");
254    //     jQuery("#audio-stream-player-status").val("stop");
255    //     jQuery("#audio-stream-third-player-status").val("stop");
256    //   }
257    //   else if(playerStatus == "play"){
258    //     Amplitude.pause();
259    //     Amplitude.init({
260    //       preload: "none",
261    //       songs: [
262    //         defaultStation
263    //       ],
264    //     });
265    //     jQuery(".sa-play").hide();
266    //     jQuery(".sa-pause").show();
267    //     jQuery("#audio-stream-second-player-status").val("stop");
268    //   }
269    //  }
270    // );
271
272    // jQuery(document).on("click","#third-play-pause",function() {
273    //   var playerStatus = jQuery("#audio-stream-third-player-status").val();
274    //   if(playerStatus == "stop"){
275    //     jQuery(".ta-pause").hide();
276    //     jQuery(".ta-play").show();
277    //     Amplitude.playNow(thirdStation);
278    //     jQuery(".amplitude-play-pause")
279    //       .addClass("amplitude-paused")
280    //       .removeClass("amplitude-playing");
281    //     jQuery(".sa-play").hide();
282    //     jQuery(".sa-pause").show();
283    //     jQuery("#audio-stream-third-player-status").val("play");
284    //     jQuery("#audio-stream-player-status").val("stop");
285    //     jQuery("#audio-stream-second-player-status").val("stop");
286    //   }
287    //   else if(playerStatus == "play"){
288    //     Amplitude.pause();
289    //     Amplitude.init({
290    //       preload: "none",
291    //       songs: [
292    //         defaultStation
293    //       ],
294    //     });
295    //     jQuery(".ta-play").hide();
296    //     jQuery(".ta-pause").show();
297    //     jQuery("#audio-stream-third-player-status").val("stop");
298    //   }
299    //  }
300    // );
301
302    // Show floating btn on scroll
303    jQuery(document).scroll(function() {
304      scrollTop = jQuery(this).scrollTop();
305      if (scrollTop > 300) {
306        jQuery(".floating-controls-wrapper").addClass("show");
307      } else {
308        jQuery(".floating-controls-wrapper").removeClass("show");
309      }
310    });
311  }
312
313  try {
314
315  if(typeof station_info !== 'undefined' && station_info.length > 0 ){
316   station_info.forEach(function(station) {
317    if (station.id == defaultStationId) {
318      station.selected = true;
319      //defaultStation = station;
320      currentStation = station;
321      firstStation = station;
322      jQuery("#header-station-name").html(station.text);
323    }
324    if (station.id == secondStationId) {
325      secondStation = station;
326    }
327    if (station.id == thirdStationId) {
328      thirdStation = station;
329    }
330   });
331  }
332
333  }
334  catch(ee) {
335    console.log('station_info NOT found......make it blank default here in catch');
336    station_info = [];
337  }
338
339  if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
340    var adsManager;
341    var adsLoader;
342    var adDisplayContainer;
343    var intervalTimer;
344    var videoContent;
345    videoContent = jQuery("#contentElement");
346      console.log("setUpIMA is triggered start ...");
347      setUpIMA();
348       //update Listen Live header a tag
349       //jQuery(".schedule-one-play a").attr("href", "#audio-player-ad-modal");
350    }
351
352  if(!currentStation.selected){
353    if(typeof station_info !== 'undefined' && station_info.length > 0 ){
354      station_info[0].selected = true;
355      currentStation =  station_info[0];
356      jQuery("#header-station-name").html( station_info[0].text);
357    }
358  }
359
360  if(typeof station_info !== 'undefined'){
361   // Station Selects
362   station_info_length = station_info.length;
363   if(station_info_length == 1){
364    jQuery(".station-stream").hide();
365   }
366  }else{
367    station_info = [];
368  } 
369  
370  jQuery(".station-list-select").select2({
371    placeholder: "Select an option",
372    minimumResultsForSearch: Infinity,
373    data: station_info,
374    //templateResult: wpb_renderSelect
375    templateSelection: wpb_renderSelect
376  });
377
378  jQuery(".station-list-select").on("select2:open", function (e) {
379    // if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
380    //   adDisplayContainer.destroy();
381    //   setUpIMA();
382    // }
383    wpb_truncateTitle(titles, titleLength);
384  });
385
386  jQuery(".audio-player-streams-btn-wrapper").on("click", function(e) {
387    // if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
388    //   adDisplayContainer.destroy();
389    //   setUpIMA();
390    // }
391    wpb_truncateTitle(titles, titleLength);
392  });
393
394  jQuery(".station-item-link").on("click", function(e) {
395    selectedStationId = $(this).attr('stationId');
396    station_info.forEach(function(station) {
397      if (station.id == selectedStationId) {
398        jQuery('.station-list-select').trigger({
399          type: 'select2:select',
400          params: {
401              data: station
402          }
403      });
404      }
405    });
406  });
407  
408  jQuery(".station-list-select").on("select2:select", function(e) {
409    console.log("station-list-select trigger...");
410    console.log("playerStatus station-list-select:", playerStatus);
411    var data = e.params.data;
412    //jQuery("#header-station-name").html(data.text);
413    currentStation = data;
414    if (window.wpb_np_onStreamSwitch) window.wpb_np_onStreamSwitch(currentStation); // WPB-7130: reset state
415    Amplitude.playNow(data);
416    
417    setUpIMAWithCallback(function() {
418      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
419         console.log("setUpIMAWithCallback trigger...");
420        jQuery("#audio-stream-player-status").val("stop");
421        player_vast_ad_tag_trigger();
422       //player_vast_ad_tag_trigger_select();
423      }
424    });
425    updateNowPlayingMetaRouter(currentStation);
426    wpb_truncateTitle(titles, titleLength);
427
428    updateHeaderPlayer(currentStation);
429    jQuery("#audio-stream-player-status").val("play");
430    playerStatus = jQuery("#audio-stream-player-status").val();
431  });
432
433  var enterKeyStatus= 1;
434  jQuery("#play-pause").on("keyup", function(e){
435    var key = e.which;
436    if(key == 13){
437      enterKeyStatus++;
438      if(enterKeyStatus % 2 == 0) {
439        Amplitude.playNow(currentStation);
440      }
441      else{
442        Amplitude.stop();
443        jQuery(".amplitude-play-pause")
444            .addClass("amplitude-paused")
445            .removeClass("amplitude-playing");
446      }
447    }
448  });
449
450  // Player States
451  Amplitude.init({
452    // "bindings": {
453    //     13: 'play_pause'
454    // },
455    volume: 100,
456    volume_increment: 10,
457    volume_decrement: 10,
458    preload: "none",
459    songs: [
460      currentStation
461      // {
462      //     "name": "Song Name",
463      //     "artist": "Artist Name",
464      //     "album": "Album Name",
465      //     "url": "http://17263.live.streamtheworld.com/WPLJFMAAC.aac",
466      //     "cover_art_url": "https://dehayf5mhw1h7.cloudfront.net/wp-content/uploads/sites/1108/2019/02/21144743/king_logo_transparent.png",
467      //     "live": true
468      // },
469    ],
470    callbacks: {
471      initialized: function() {
472        var getActiveSongMetadata = Amplitude.getActiveSongMetadata();
473        //console.log("Name: ", getActiveSongMetadata.name);
474        //console.log("artist: ", getActiveSongMetadata.artist);
475        //console.log("album: ", getActiveSongMetadata.album);
476        //console.log("url: ", getActiveSongMetadata.url);
477        //console.log("cover_art_url: ", getActiveSongMetadata.cover_art_url);
478      },
479      /**
480       * get play attempts for audio
481       * than set play attempts +1
482       * check of gigya login function is exist
483       * and user is not logged in
484       * Attempts should be greater than 0
485       * Than so login popup
486       */
487      play: function() {
488        jQuery(document).trigger('amplitude-playing'); // WPB-7130: adaptive polling
489        jQuery( ".jp-jplayer" ).each(function( index ) {
490            var playerId = $(this).attr('id');
491              jQuery("#"+playerId).jPlayer("pause");
492          });
493        try {
494          var key = "audioPlayAttempts";
495          autoAttempts = getAudioCookie(key);
496          if (!autoAttempts) {
497            autoAttempts = 1;
498          } else {
499            autoAttempts++;
500          }
501
502          var vipclubCookie =  getAudioCookie("vipclub");
503          setAudioCookie(key, autoAttempts, daysToStorePlayAttempts);
504
505          var vip_form_status = jQuery('#vip_form_id').length;
506          if ((site_info.id != 957 && site_info.id != 1494) && autoAttempts > maxPlayAttempts && !vipclubCookie && vip_form_status > 0){
507            Amplitude.stop();
508            jQuery(".amplitude-play-pause")
509              .addClass("amplitude-paused")
510              .removeClass("amplitude-playing");
511            jQuery("#audioLoginModal").show();
512          }
513
514          // if (
515          //   autoAttempts > maxPlayAttempts &&
516          //   typeof loginToGigya === "function" &&
517          //   (typeof _See != undefined &&
518          //     typeof _See.config != undefined &&
519          //     typeof _See.config.user != undefined &&
520          //     typeof _See.config.user.is_loggedin != undefined &&
521          //     typeof _See.isGotResponse != undefined &&
522          //     _See.isGotResponse == true &&
523          //     !_See.config.user.is_loggedin)
524          // ) {
525          //   Amplitude.pause();
526          //   jQuery(".amplitude-play-pause")
527          //     .addClass("amplitude-paused")
528          //     .removeClass("amplitude-playing");
529          //   //_See.regUi.open();
530          //   // loginToGigya(0);
531          //   jQuery("#audioLoginModal").show();
532          // } else {
533          //   sessionInterval(true);
534          // }
535        } catch (err) {
536          console.log("Error while playing audio " + err.message);
537        }
538      },
539      stop: function() {
540        jQuery(document).trigger('amplitude-stopped'); // WPB-7130: adaptive polling
541        console.log("Init Stop is triggred...");
542        sessionInterval(false);
543      },
544      pause: function() {
545        jQuery(document).trigger('amplitude-paused'); // WPB-7130: adaptive polling
546        console.log("Init Pause is triggred...");
547        sessionInterval(false);
548      },
549      ended: function() {
550        sessionInterval(false);
551      },
552      suspend: function() {
553        sessionInterval(false);
554      }
555    }
556  });
557
558  try {
559  jQuery("#volume").slider({
560    min: 0,
561    max: 100,
562    value: 75,
563    range: "min",
564    slide: function(event, ui) {
565      var el = document.getElementById("volume-slider-range");
566      el.value = ui.value;
567      var event = document.createEvent("Event");
568      event.initEvent("input", true, true);
569      el.dispatchEvent(event);
570    }
571  });
572  }
573  catch(e) { console.log("wpb audio stream manager slider not found."); }
574  updateNowPlayingMetaRouter(currentStation);
575
576  // WPB-7130 Block 5: Adaptive polling — 10s while playing, 20s while stopped/paused.
577  //
578  // The cadence is re-derived from the player's own state before every tick rather
579  // than being latched by the amplitude-playing/stopped/paused events alone. The
580  // schedule-one/two/three handlers re-run Amplitude.init() without a `callbacks`
581  // object, which drops the callbacks that fire those events — so an event-only
582  // scheme freezes at whatever cadence it last saw. Re-checking each tick means the
583  // worst case is one cycle (<= 20s) at a stale cadence instead of forever.
584  var WPB_NP_POLL_PLAYING_MS = 10000;
585  var WPB_NP_POLL_IDLE_MS = 20000;
586  var wpb_np_pollTimeoutId = null;
587  var wpb_np_currentPollMs = null;
588
589  function wpb_np_isPlaying() {
590    try {
591      if (typeof Amplitude !== 'undefined' && typeof Amplitude.getPlayerState === 'function') {
592        return Amplitude.getPlayerState() === 'playing';
593      }
594    } catch (e) { /* fall through to the DOM flag */ }
595    return jQuery("#audio-stream-player-status").val() === "play";
596  }
597
598  function wpb_np_scheduleNextPoll(forcedIntervalMs) {
599    if (wpb_np_pollTimeoutId) {
600      clearTimeout(wpb_np_pollTimeoutId);
601    }
602    wpb_np_currentPollMs = forcedIntervalMs ||
603      (wpb_np_isPlaying() ? WPB_NP_POLL_PLAYING_MS : WPB_NP_POLL_IDLE_MS);
604    wpb_np_pollTimeoutId = setTimeout(function() {
605      updateNowPlayingMetaRouter(currentStation);
606      wpb_np_scheduleNextPoll(); // re-evaluate the cadence every tick
607    }, wpb_np_currentPollMs);
608  }
609
610  wpb_np_scheduleNextPoll();
611
612  // Namespaced + rebound so a second readyFn_audioStreamManager() run cannot stack
613  // duplicate handlers. These only make the switch immediate; the tick above is what
614  // guarantees the cadence is eventually right.
615  jQuery(document).off('.wpbNpPoll');
616  jQuery(document).on('amplitude-playing.wpbNpPoll', function() {
617    if (wpb_np_currentPollMs !== WPB_NP_POLL_PLAYING_MS) {
618      wpb_np_scheduleNextPoll(WPB_NP_POLL_PLAYING_MS);
619    }
620  });
621  jQuery(document).on('amplitude-stopped.wpbNpPoll amplitude-paused.wpbNpPoll', function() {
622    if (wpb_np_currentPollMs !== WPB_NP_POLL_IDLE_MS) {
623      wpb_np_scheduleNextPoll(WPB_NP_POLL_IDLE_MS);
624    }
625  });
626
627  // WPB-7130: Reset all now-playing state on stream switch.
628  // Called from every stream-switch point to avoid stale data, race conditions, and DOM artifacts.
629  window.wpb_np_onStreamSwitch = function(newStation) {
630    // 1. Increment generation counter — in-flight requests from old stream will see stale gen and bail
631    wpb_np_requestGen++;
632
633    // 2. Reset song-change detection so new stream's first song always renders
634    wpb_np_direct_lastSongKey = "";
635
636    // 3. Reset CORS detection so new stream re-tests (different source URL may have different CORS)
637    wpb_np_direct_useDirect = null;
638
639    // 4. Reset error counter
640    nowPlayingErrorCount = 0;
641
642    // 5. Clear DOM — show station name + logo as placeholder while new data loads
643    jQuery("#amplitude-song-name").text(newStation.text || '');
644    jQuery("#amplitude-artist").text('');
645    jQuery("#amplitude-album").text('');
646    if (newStation.station_logo_url) {
647      jQuery("#amplitude-cover-art-url").attr("src", newStation.station_logo_url);
648    }
649    jQuery("#amplitude-artist-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
650    jQuery("#amplitude-song-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
651    jQuery("#amplitude-cover-art-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
652
653    // 6. Cancel old polling timer + restart immediately for the new stream
654    wpb_np_scheduleNextPoll(WPB_NP_POLL_PLAYING_MS);
655  };
656
657  // Init mobile UI only when the player is in the header
658  if (isInHeader && isMobile && !playerFixedBar.length) {
659    wpb_initMobileUi();
660  }
661
662  // If not fixed bar player
663  if(!playerFixedBar.length){
664    // Init floating player control
665    wpb_initFloatingPlayer();
666  }
667
668  //Shorten titles on load
669  wpb_truncateTitle(titles, titleLength);
670
671  /**
672   * Session interval
673   * If user is listing from 1 hour
674   * Than pause audio
675   * and show popup
676   */
677  function sessionInterval(start = false) {
678
679    if(player_setting == null || player_setting.playerSettings == null || player_setting.playerSettings.userInteractionSetting == null || player_setting.playerSettings.userInteractionSetting){
680      if (start) {
681        clearInterval(sessionTimer);
682        sessionTimer = null;
683        sessionTimer = setInterval(function() {
684          Amplitude.stop();
685          jQuery(".amplitude-play-pause")
686            .addClass("amplitude-paused")
687            .removeClass("amplitude-playing");
688          clearInterval(sessionTimer);
689          sessionTimer = null;
690          jQuery("#audioSessionModal").show();
691        }, sessionIntervalTime);
692      } else {
693        clearInterval(sessionTimer);
694        sessionTimer = null;
695      }
696    } 
697  }
698
699  jQuery("#startAudioPlayerBtn").on("click", function(e) {
700    // e.preventdefault();
701    Amplitude.play();
702    sessionInterval(false);
703    jQuery("#audioSessionModal").hide();
704    jQuery(".amplitude-play-pause")
705      .addClass("amplitude-playing")
706      .removeClass("amplitude-paused");
707  });
708
709  function resetTimer(e) {
710    var getPlayerState = Amplitude.getPlayerState();
711    if (getPlayerState == "playing") {
712      sessionInterval(true);
713    } else {
714      sessionInterval(false);
715    }
716  }
717
718  /**
719   * Check user is active on website or not
720   */
721  function setupInactivityOfUser() {
722    this.addEventListener("mousemove", resetTimer, false);
723    this.addEventListener("mousedown", resetTimer, false);
724    this.addEventListener("keypress", resetTimer, false);
725    this.addEventListener("DOMMouseScroll", resetTimer, false);
726    this.addEventListener("mousewheel", resetTimer, false);
727    this.addEventListener("touchmove", resetTimer, false);
728    this.addEventListener("MSPointerMove", resetTimer, false);
729  }
730
731  setupInactivityOfUser();
732
733  jQuery("#vip-subscribe-model").on("click", function() {
734    jQuery("#audioLoginModal").hide();
735  });
736
737  jQuery("#vip-subscribe-model-x").on("click", function() {
738    jQuery("#audioLoginModal").hide();
739  });
740
741  jQuery("#audioLoginBtn").on("click", function() {
742    jQuery("#audioLoginModal").hide();
743   // _See.regUi.open();
744  });
745
746  jQuery("#vip-subscribe-header").on("click", function() {
747    jQuery("#audioLoginModal").show();
748  });
749
750  jQuery("#vip-subscribe-footer").on("click", function() {
751    jQuery("#audioLoginModal").show();
752  });
753
754  jQuery("#vip-subscribe-sidebar").on("click", function() {
755    jQuery("#audioLoginModal").show();
756  });
757
758  //WPB-3371 - theme - hello-theme-child-master
759  // Persistent player setting - On/Off
760  // By default, it will be on = 1
761  // This creates a global variable: ITM_enablePjax to be used by
762  // the pjax.js module in theme
763
764  //WPB-3371 -- No need now but new plugin now pjax-settings-plugin
765
766  // var firstStation = {},
767  // secondStation = {},
768  // thirdStation = {},
769  // currentStation = {};
770
771  var listenLivePlayOneClassStatus = jQuery("div").hasClass("schedule-one-play");
772  var listenLivePlayTwoClassStatus = jQuery("div").hasClass("schedule-two-play");
773  var listenLivePlayThreeClassStatus = jQuery("div").hasClass("schedule-three-play");
774
775  // jQuery(".schedule-one-pause").hide();
776  try {
777
778// Check if defaultStationId is undefined or empty
779if (!defaultStationId  || defaultStationId === "") {
780  defaultStationId = player_setting.playerSettings.streamDefault.StationId;
781}
782
783// Check if secondStationId is undefined or empty and if streamSecond exists
784if ((!secondStationId || secondStationId === "") && player_setting.playerSettings.streamSecond) {
785  secondStationId = player_setting.playerSettings.streamSecond.StationId;
786}
787
788// Check if thirdStationId is undefined or empty and if streamThird exists
789if ((!thirdStationId || thirdStationId === "") && player_setting.playerSettings.streamThird) {
790  thirdStationId = player_setting.playerSettings.streamThird.StationId;
791}
792  
793  }catch(ee){ 
794    defaultStationId = 0; 
795    secondStationId = 0;
796    thirdStationId = 0;
797  }
798  
799  if(typeof station_info !== 'undefined' && station_info.length > 0 ){
800   station_info.forEach(function(station) {
801    if (station.id == defaultStationId) {
802      currentStation = station;
803      firstStation = station;
804    }
805    if (station.id == secondStationId) {
806      secondStation = station;
807    }
808    if (station.id == thirdStationId) {
809      thirdStation = station;
810    }
811  });
812}
813  /*station_info.forEach(function(station) {
814      if (station.schedule == "schedule-one") {
815        //firstStation = station;
816        //currentStation = firstStation;
817      }
818      else if (station.schedule == "schedule-two") {
819        secondStation = station;
820      }
821      else if (station.schedule == "schedule-three") {
822        thirdStation = station;
823      }
824      else{
825        console.log("no station is assigned...");
826      }
827    });*/
828
829  //Schedule 1 (WABC) Left
830  jQuery(document).on("click",".schedule-one-play",function() {
831      Amplitude.playNow(firstStation);
832      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
833        //jQuery(".schedule-one-play a").attr("href", "#audio-player-ad-modal");
834        player_vast_ad_tag_trigger();
835      }
836      jQuery("#audio-stream-player-status").val("play");
837      currentStation = firstStation;
838      if (window.wpb_np_onStreamSwitch) window.wpb_np_onStreamSwitch(currentStation); // WPB-7130: reset state
839      playerStatus = jQuery("#audio-stream-player-status").val();
840
841      // jQuery('.station-list-select').trigger({
842      //     type: 'select2:select',
843      //     params: {
844      //         data: firstStation
845      //     }
846      // });
847      // jQuery('.station-list-select').val(firstStation.id);
848      // jQuery('.station-list-select').trigger('change'); 
849      jQuery(".schedule-one-play").hide();
850      jQuery(".schedule-one-pause").show();
851      jQuery(".schedule-two-pause").hide();
852      jQuery(".schedule-two-play").show();
853      jQuery(".schedule-three-pause").hide();
854      jQuery(".schedule-three-play").show();
855      updateNowPlayingMetaRouter(firstStation);
856      console.log("schedule-one play is clicked...");
857  });
858
859  jQuery(document).on("click",".schedule-one-pause",function() {
860      jQuery("#audio-stream-player-status").val("stop");
861      playerStatus = jQuery("#audio-stream-player-status").val();
862      Amplitude.stop();
863      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
864        if (adDisplayContainer) {
865          adDisplayContainer.destroy();
866          console.log("adDisplayContainer  is destroy in pause trigger...");
867        }
868        setUpIMA();
869      }
870      Amplitude.init({
871        preload: "none",
872        songs: [
873          firstStation
874        ],
875      });
876      jQuery(".schedule-one-pause").hide();
877      jQuery(".schedule-one-play").show();
878      updateNowPlayingMetaRouter(firstStation);
879      console.log("schedule-one pause is clicked...");
880  });
881
882  //Schedule 3 (MUSIC) Middle
883  jQuery(document).on("click",".schedule-three-play",function() {
884      //Amplitude.playNow(thirdStation);
885      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
886        jQuery(".schedule-three-play a").attr("href", "#audio-player-ad-modal");
887        if (adDisplayContainer) {
888          adDisplayContainer.destroy();
889          console.log("adDisplayContainer  is destroy in schedule-three-play trigger...");
890        }
891        setUpIMA();
892      }
893      //jQuery('.audio-player-flyout-btn').toggleClass('open');
894      //jQuery('#audio-player-flyout').toggleClass('open');
895      jQuery("#audio-stream-player-status").val("play");
896      playerStatus = jQuery("#audio-stream-player-status").val();
897      currentStation = thirdStation;
898      jQuery('.station-list-select').trigger({
899          type: 'select2:select',
900          params: {
901              data: thirdStation
902          }
903      });
904      jQuery('.station-list-select').val(thirdStation.id);
905      jQuery('.station-list-select').trigger('change'); 
906
907      jQuery(".schedule-three-play").hide();
908      jQuery(".schedule-three-pause").show();
909      jQuery(".schedule-one-pause").hide();
910      jQuery(".schedule-one-play").show();
911      jQuery(".schedule-two-pause").hide();
912      jQuery(".schedule-two-play").show();
913  });
914
915  jQuery(document).on("click",".schedule-three-pause",function() {
916      //jQuery('.audio-player-flyout-btn').removeClass('open');
917      //jQuery('#audio-player-flyout').removeClass('open');
918      jQuery("#audio-stream-player-status").val("stop");
919      playerStatus = jQuery("#audio-stream-player-status").val();
920      Amplitude.stop();
921      Amplitude.init({
922        preload: "none",
923        songs: [
924          thirdStation
925        ],
926      });
927      jQuery(".schedule-three-pause").hide();
928      jQuery(".schedule-three-play").show();
929      console.log("music pause is clicked...");
930  });
931
932  //Schedule 2 (WLIR) Right
933  jQuery(document).on("click",".schedule-two-play",function() {
934    if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
935      adDisplayContainer.destroy();
936      jQuery(".schedule-two-play a").attr("href", "#audio-player-ad-modal");
937      if (adDisplayContainer) {
938        adDisplayContainer.destroy();
939        console.log("adDisplayContainer  is destroy in schedule-two-play trigger...");
940      }
941      setUpIMA();
942    }
943    jQuery("#audio-stream-player-status").val("play");
944    playerStatus = jQuery("#audio-stream-player-status").val();
945    currentStation = secondStation;
946      jQuery('.station-list-select').trigger({
947          type: 'select2:select',
948          params: {
949              data: secondStation
950          }
951      });
952      jQuery('.station-list-select').val(secondStation.id);
953      jQuery('.station-list-select').trigger('change'); 
954
955      jQuery(".schedule-two-play").hide();
956      jQuery(".schedule-two-pause").show();
957      jQuery(".schedule-one-pause").hide();
958      jQuery(".schedule-one-play").show();
959      jQuery(".schedule-three-pause").hide();
960      jQuery(".schedule-three-play").show();
961      console.log("schedule-two play is clicked...");
962  });
963
964  jQuery(document).on("click",".schedule-two-pause",function() {
965    jQuery("#audio-stream-player-status").val("stop");
966    playerStatus = jQuery("#audio-stream-player-status").val();
967      Amplitude.stop();
968      Amplitude.init({
969        preload: "none",
970        songs: [
971          secondStation
972        ],
973      });
974      jQuery(".schedule-two-pause").hide();
975      jQuery(".schedule-two-play").show();
976  });
977
978  jQuery(document).on("click","#play-pause",function() {
979    playerStatus = jQuery("#audio-stream-player-status").val();
980    try {
981          var key = "audioPlayAttempts";
982          autoAttempts = getAudioCookie(key);
983          if (!autoAttempts) {
984            autoAttempts = 1;
985          } else {
986            autoAttempts++;
987          }
988
989          var vipclubCookie =  getAudioCookie("vipclub");
990          setAudioCookie(key, autoAttempts, daysToStorePlayAttempts);
991
992          var vip_form_status = jQuery('#vip_form_id').length;
993          if ((site_info.id != 957 && site_info.id != 1494) && autoAttempts > maxPlayAttempts && !vipclubCookie && vip_form_status > 0){
994            Amplitude.stop();
995            jQuery(".amplitude-play-pause")
996              .addClass("amplitude-paused")
997              .removeClass("amplitude-playing");
998            jQuery("#audioLoginModal").show();
999            return;
1000          }
1001        } catch (err) {
1002          console.log("Error while playing audio " + err.message);
1003        }
1004
1005    if(playerStatus == "stop"){
1006      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
1007        player_vast_ad_tag_trigger();
1008      }
1009
1010      jQuery("#audio-stream-player-status").val("play");
1011      playerStatus = jQuery("#audio-stream-player-status").val();
1012      
1013      updateHeaderPlayer(currentStation);
1014    }
1015    else if(playerStatus == "play"){
1016      if(ima_ad_tag_url != "0" && typeof google !== 'undefined'){
1017        if (adDisplayContainer) {
1018          adDisplayContainer.destroy();
1019          console.log("adDisplayContainer  is destroy in play-pause trigger...");
1020        }
1021        setUpIMA();
1022      }
1023      Amplitude.stop();
1024      Amplitude.init({
1025        preload: "none",
1026        songs: [
1027          currentStation
1028        ],
1029      });
1030      updateNowPlayingMetaRouter(currentStation);
1031      jQuery("#audio-stream-player-status").val("stop");
1032      playerStatus = jQuery("#audio-stream-player-status").val();
1033      jQuery(".schedule-one-pause").hide();
1034      jQuery(".schedule-one-play").show();
1035      jQuery(".schedule-two-pause").hide();
1036      jQuery(".schedule-two-play").show();
1037      jQuery(".schedule-three-pause").hide();
1038      jQuery(".schedule-three-play").show();
1039    }
1040  });
1041
1042  jQuery(document).on("click",".opl-bars-icon",function() {
1043    console.log("OPL Bar Icon click...");
1044    // var s1p_status = jQuery(".schedule-one-play").is(':visible');
1045    // var s2p_status = jQuery(".schedule-two-play").is(':visible');
1046    // var s3op_status = jQuery(".schedule-three-play").is(':visible');
1047
1048    playerStatus = jQuery("#audio-stream-player-status").val();
1049    if(playerStatus == "play"){
1050      // if(s1p_status){
1051      //   jQuery(".schedule-one-play").hide();
1052      //   jQuery(".schedule-one-pause").show();
1053      // }
1054      // if(s2p_status){
1055      //   jQuery(".schedule-two-play").hide();
1056      //   jQuery(".schedule-two-pause").show();
1057      // }
1058      // if(s3op_status){
1059      //   jQuery(".schedule-three-play").hide();
1060      //   jQuery(".schedule-three-pause").show();
1061      // }
1062
1063      if (currentStation.schedule == "schedule-one") {
1064        jQuery(".schedule-one-play").hide();
1065        jQuery(".schedule-one-pause").show();
1066      }
1067      else if (currentStation.schedule == "schedule-two") {
1068        jQuery(".schedule-two-play").hide();
1069        jQuery(".schedule-two-pause").show();
1070      }
1071      else if (currentStation.schedule == "schedule-three") {
1072        //console.log("s3p_status inside...");
1073        jQuery(".schedule-three-play").hide();
1074        jQuery(".schedule-three-pause").show();
1075      }
1076    }
1077  });
1078
1079  // jQuery(".station-list-select").on("select2:select", function(e) {
1080  //   currentStation = e.params.data;
1081  //   updateHeaderPlayer(currentStation);
1082  //   jQuery("#audio-stream-player-status").val("play");
1083  //   playerStatus = jQuery("#audio-stream-player-status").val();
1084  // });
1085
1086  if (typeof Barba !== 'undefined'){
1087    Barba.Dispatcher.on('transitionCompleted', function(data) {
1088      playerStatus = jQuery("#audio-stream-player-status").val();
1089      setTimeout(function(){
1090        if(playerStatus != "stop"){ 
1091          updateHeaderPlayer(currentStation);
1092        }
1093      }, 3000);
1094    });
1095  }
1096
1097  function updateHeaderPlayer(currentStation){
1098    if(listenLivePlayOneClassStatus == true && listenLivePlayTwoClassStatus == false && listenLivePlayThreeClassStatus == false){
1099      jQuery(".schedule-one-play").hide();
1100      jQuery(".schedule-one-pause").show();
1101    }
1102    else if (currentStation.schedule == "schedule-one") {
1103      jQuery(".schedule-one-play").hide();
1104      jQuery(".schedule-one-pause").show();
1105
1106      jQuery(".schedule-two-pause").hide();
1107      jQuery(".schedule-two-play").show();
1108      jQuery(".schedule-three-pause").hide();
1109      jQuery(".schedule-three-play").show();
1110    }
1111    else if (currentStation.schedule == "schedule-two") {
1112      jQuery(".schedule-two-play").hide();
1113      jQuery(".schedule-two-pause").show();
1114
1115      jQuery(".schedule-one-pause").hide();
1116      jQuery(".schedule-one-play").show();
1117      jQuery(".schedule-three-pause").hide();
1118      jQuery(".schedule-three-play").show();
1119    }
1120    else if (currentStation.schedule == "schedule-three") {
1121      jQuery(".schedule-three-play").hide();
1122      jQuery(".schedule-three-pause").show();
1123
1124      jQuery(".schedule-one-pause").hide();
1125      jQuery(".schedule-one-play").show();
1126      jQuery(".schedule-two-pause").hide();
1127      jQuery(".schedule-two-play").show();
1128    }
1129    //jQuery("#audio-stream-player-status").val("play");
1130  }
1131
1132  function setUpIMA() {
1133    console.log("setUpIMA is called");
1134    // Create the ad display container.
1135    createAdDisplayContainer();
1136    try {
1137    // Create ads loader.
1138    adsLoader = new google.ima.AdsLoader(adDisplayContainer);
1139    // Listen and respond to ads loaded and error events.
1140    adsLoader.addEventListener(
1141      google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
1142      onAdsManagerLoaded,
1143      false);
1144    adsLoader.addEventListener(
1145      google.ima.AdErrorEvent.Type.AD_ERROR,
1146      onAdError,
1147      false);
1148  
1149    // An event listener to tell the SDK that our content video
1150    // is completed so the SDK can play any post-roll ads.
1151    var contentEndedListener = function () { adsLoader.contentComplete(); };
1152    videoContent.onended = contentEndedListener;
1153  
1154    // Request video ads.
1155    var adsRequest = new google.ima.AdsRequest();
1156    // adsRequest.adTagUrl = 'https://pubads.g.doubleclick.net/gampad/ads?' +
1157    //     'sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&' +
1158    //     'impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&' +
1159    //     'cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=';
1160    console.log("currentStation: ", currentStation);
1161    console.log("ima_ad_tag_url before: ", ima_ad_tag_url);
1162    currentTime = new Date().getTime();
1163    ima_ad_tag_url_ct = ima_ad_tag_url + currentTime + "&cust_params=";
1164    target_ima_ad_tag_url = ima_ad_tag_url_ct + "title%3D"+ currentStation.slug;
1165    console.log("target_ima_ad_tag_url after: ", target_ima_ad_tag_url);
1166    adsRequest.adTagUrl = target_ima_ad_tag_url;
1167  
1168    // Specify the linear and nonlinear slot sizes. This helps the SDK to
1169    // select the correct creative if multiple are returned.
1170      
1171    //mobile
1172    if (window.matchMedia("only screen and (max-width: 700px)").matches) {
1173      adsRequest.linearAdSlotWidth = 300;
1174      adsRequest.linearAdSlotHeight = 169;
1175    }
1176    else{
1177      //Desktop
1178      adsRequest.linearAdSlotWidth = 640;
1179      adsRequest.linearAdSlotHeight = 360;
1180    }
1181    //adsRequest.nonLinearAdSlotWidth = 640;
1182    //adsRequest.nonLinearAdSlotHeight = 150;
1183    console.log("adsRequest: ", adsRequest);
1184    adsLoader.requestAds(adsRequest);
1185    }
1186    catch(e) {
1187      console.log('setUpIMA catch........');
1188    }
1189  }
1190
1191  function setUpIMAWithCallback(callback) {
1192    console.log("setUpIMAWithCallback trigger function...");
1193    if (ima_ad_tag_url != "0" && typeof google !== 'undefined') {
1194      if (adDisplayContainer) {
1195        adDisplayContainer.destroy();
1196        console.log("adDisplayContainer  is destroy in setUpIMAWithCallback trigger...");
1197      }
1198        setUpIMA();
1199        setTimeout(function() {
1200            if (callback && typeof callback === "function") {
1201                callback();
1202            }
1203        }, 400);
1204    } else if (callback && typeof callback === "function") {
1205        callback();
1206    }
1207  }
1208  
1209  function createAdDisplayContainer() {
1210    // We assume the adContainer is the DOM id of the element that will house
1211    // the ads.
1212    try {
1213    google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true);
1214    adDisplayContainer = new google.ima.AdDisplayContainer(
1215      document.getElementById('ad
1215Container'), videoContent);
1216    }
1217    catch(e) {
1218      console.log('wpb-audio-stream-manager createAdDisplayContainer...');
1219    }
1220  }
1221  
1222function player_vast_ad_tag_trigger() {
1223  playerStatus = jQuery("#audio-stream-player-status").val();
1224          console.log("player_vast_ad_tag_trigger called...");
1225                    console.log("playerStatus: ", playerStatus);
1226
1227
1228  if (playerStatus === "stop") {
1229    Amplitude.setVolume(0);
1230    videoContent.load();
1231    adDisplayContainer.initialize();
1232    let adStarted = false;
1233    console.log("adStarted status:",adStarted);
1234
1235    //Setup fallback timer
1236   const fallbackTimer = setTimeout(() => {
1237      if (!adStarted) {
1238        console.log("No ad served. Fallback to stream.");
1239        Amplitude.setVolume(100);
1240        jQuery("#audio-stream-player-status").val("play");
1241      }
1242    }, 2000);
1243
1244    try {
1245      if (window.matchMedia("only screen and (max-width: 700px)").matches) {
1246        adsManager.init(300, 169, google.ima.ViewMode.NORMAL);
1247      } else {
1248        adsManager.init(640, 360, google.ima.ViewMode.NORMAL);
1249      }
1250
1251      adsManager.addEventListener(
1252        google.ima.AdEvent.Type.STARTED,
1253        function () {
1254          clearTimeout(fallbackTimer);
1255          adStarted = true;
1256          console.log("adStarted status inside event:", adStarted);
1257          jQuery("#ad-model-open")[0].click(); // show modal only when ad actually starts
1258          console.log("Ad started, modal opened.");
1259        }
1260      );
1261
1262      adsManager.addEventListener(
1263        google.ima.AdEvent.Type.COMPLETE,
1264        function () {
1265          console.log("Ad complete.");
1266          Amplitude.setVolume(100);
1267          jQuery("#audio-stream-player-status").val("play");
1268        }
1269      );
1270
1271      adsManager.addEventListener(
1272        google.ima.AdErrorEvent.Type.AD_ERROR,
1273        function () {
1274          console.log("Ad error event...");
1275          clearTimeout(fallbackTimer);
1276          Amplitude.setVolume(100);
1277          jQuery("#audio-stream-player-status").val("play");
1278        }
1279      );
1280
1281      adsManager.start();
1282    } catch (adError) {
1283      console.log("Ad error fallback:", adError);
1284      clearTimeout(fallbackTimer);
1285      Amplitude.setVolume(100);
1286      jQuery("#audio-stream-player-status").val("play");
1287    }
1288  }
1289  else if(playerStatus == "play"){
1290    //jQuery("#adContainer").html("");
1291    if (adDisplayContainer) {
1292      adDisplayContainer.destroy();
1293      console.log("adDisplayContainer  is destroy in player_vast_ad_tag_trigger trigger...");
1294    }
1295    setUpIMA();
1296    jQuery("#audio-stream-player-status").val("stop");
1297  }
1298
1299}
1300  function player_vast_ad_tag_trigger_select() {
1301     console.log("player_vast_ad_tag_trigger_select trigger...");
1302    Amplitude.setVolume(0);
1303    videoContent.load();
1304    adDisplayContainer.initialize();
1305    try {
1306      if (window.matchMedia("only screen and (max-width: 700px)").matches) {
1307        //Mobile
1308        adsManager.init(300, 169, google.ima.ViewMode.NORMAL);
1309      }
1310      else{
1311        //Desktop
1312        adsManager.init(640, 360, google.ima.ViewMode.NORMAL);
1313      }
1314      adsManager.start();
1315    } catch (adError) {
1316      Amplitude.setVolume(100);
1317      jQuery("#ad-model-close-hidden")[0].click();
1318      //jQuery("#audio-stream-player-status").val("play");
1319    }
1320  }
1321  
1322  // jQuery(".a-pause").click(function () {
1323  //   // Initialize the container. Must be done via a user action on mobile devices.
1324  //   //document.getElementById('mainContainer').style.display = 'block'; 
1325  //   //setTimeout(function(){ Amplitude.pause(); }, 1000);
1326  //   Amplitude.setVolume(0);
1327  //   //Amplitude.play();
1328  //   jQuery("#ad-model-open")[0].click();
1329  //   //jQuery("#mainContainer").show();
1330  //   videoContent.load();
1331  //   adDisplayContainer.initialize();
1332  
1333  //   try {
1334  //     // Initialize the ads manager. Ad rules playlist will start at this time.
1335  //     adsManager.init(640, 360, google.ima.ViewMode.NORMAL);
1336  //     // Call play to start showing the ad. Single video and overlay ads will
1337  //     // start at this time; the call will be ignored for ad rules.
1338  //     adsManager.start();
1339  //   } catch (adError) {
1340  //     // An error may be thrown if there was a problem with the VAST response.
1341  //     //videoContent.play();
1342  //     Amplitude.play();
1343  //   }
1344  // });
1345  
1346  // jQuery(document).on(
1347  //   "click",
1348  //   ".a-play",
1349  //   function() {
1350  //     console.log("a-play is clicked...");
1351  //     setUpIMA();
1352  //   }
1353  // );
1354  // jQuery(".a-play").click(function () {
1355  //   setUpIMA();
1356  // });
1357  
1358  function onAdsManagerLoaded(adsManagerLoadedEvent) {
1359    // Get the ads manager.
1360    var adsRenderingSettings = new google.ima.AdsRenderingSettings();
1361    adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;
1362    // videoContent should be set to the content video element.
1363    adsManager = adsManagerLoadedEvent.getAdsManager(
1364      videoContent, adsRenderingSettings);
1365  
1366    // Add listeners to the required events.
1367    adsManager.addEventListener(
1368      google.ima.AdErrorEvent.Type.AD_ERROR,
1369      onAdError);
1370    adsManager.addEventListener(
1371      google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
1372      onContentPauseRequested);
1373    adsManager.addEventListener(
1374      google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
1375      onContentResumeRequested);
1376    adsManager.addEventListener(
1377      google.ima.AdEvent.Type.ALL_ADS_COMPLETED,
1378      onAdEvent);
1379  
1380    // Listen to any additional events, if necessary.
1381    adsManager.addEventListener(
1382      google.ima.AdEvent.Type.LOADED,
1383      onAdEvent);
1384    adsManager.addEventListener(
1385      google.ima.AdEvent.Type.STARTED,
1386      onAdEvent);
1387    adsManager.addEventListener(
1388      google.ima.AdEvent.Type.PAUSED,
1389      onAdEvent);
1390    adsManager.addEventListener(
1391      google.ima.AdEvent.Type.COMPLETE,
1392      onAdEvent);
1393  }
1394  
1395  function onAdEvent(adEvent) {
1396    // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)
1397    // don't have ad object associated.
1398    var ad = adEvent.getAd();
1399    switch (adEvent.type) {
1400      case google.ima.AdEvent.Type.LOADED:
1401        // This is the first event sent for an ad - it is possible to
1402        // determine whether the ad is a video ad or an overlay.
1403        if (!ad.isLinear()) {
1404          // Position AdDisplayContainer correctly for overlay.
1405          // Use ad.width and ad.height.
1406          //videoContent.play();
1407          Amplitude.setVolume(100);
1408          jQuery("#audio-stream-player-status").val("play");
1409        }
1410        break;
1411      case google.ima.AdEvent.Type.STARTED:
1412        // This event indicates the ad has started - the video player
1413        // can adjust the UI, for example display a pause button and
1414        // remaining time.
1415        //console.log("IMA AD STARTED....");
1416        if (ad.isLinear()) {
1417          // For a linear ad, a timer can be started to poll for
1418          // the remaining time.
1419          intervalTimer = setInterval(
1420            function () {
1421              var remainingTime = adsManager.getRemainingTime();
1422            },
1423            300); // every 300ms
1424        }
1425        break;
1426      case google.ima.AdEvent.Type.COMPLETE:
1427        jQuery("#ad-model-close-hidden")[0].click();
1428        //jQuery("#mainContainer").hide();
1429        Amplitude.setVolume(100);
1430        jQuery("#audio-stream-player-status").val("play");
1431        // This event indicates the ad has finished - the video player
1432        // can perform appropriate UI actions, such as removing the timer for
1433        // remaining time detection.
1434        if (ad.isLinear()) {
1435          clearInterval(intervalTimer);
1436        }
1437        break;
1438      case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
1439        $("#resume-ad-model").hide();
1440        jQuery("#ad-model-close-hidden")[0].click();
1441        //jQuery("#mainContainer").hide();
1442        Amplitude.setVolume(100);
1443        jQuery("#audio-stream-player-status").val("play");
1444        // This event indicates the ad has finished - the video player
1445        // can perform appropriate UI actions, such as removing the timer for
1446        // remaining time detection.
1447        if (ad.isLinear()) {
1448          clearInterval(intervalTimer);
1449        }
1450        break;
1451
1452      case google.ima.AdEvent.Type.PAUSED:
1453        console.log("IMA AD PAUSED....");
1454        //adsManager.resume();
1455        $("#resume-ad-model").show();
1456      break;
1457    }
1458    
1459  }
1460  
1461  function onAdError(adErrorEvent) {
1462    // Handle the error logging.
1463    try {
1464    adsManager.destroy();
1465    }catch(e){ console.log('onAdError adsManager problem......'); }
1466    // Amplitude.setVolume(100);
1467    // jQuery("#audio-stream-player-status").val("play");
1468    // jQuery("#ad-model-close-hidden")[0].click();
1469  }
1470  
1471  function onContentPauseRequested() {
1472    //videoContent.pause();
1473    // This function is where you should setup UI for showing ads (e.g.
1474    // display ad timer countdown, disable seeking etc.)
1475    // setupUIForAds();
1476  }
1477  
1478  function onContentResumeRequested() {
1479    //videoContent.play();
1480    // This function is where you should ensure that your UI is ready
1481    // to play content. It is the responsibility of the Publisher to
1482    // implement this function when necessary.
1483    // setupUIForContent();
1484  }
1485
1486  jQuery(document).on(
1487      "click",
1488      "#resume-ad-model",
1489      function() {
1490        console.log("Resume Ad button clicked....");
1491        adsManager.resume();
1492        $("#resume-ad-model").hide();
1493      }
1494    );
1495}
1496
1497function readVipClubCookie(name) {
1498  var nameEQ = name + "=";
1499  var ca = document.cookie.split(";");
1500  for (var i = 0; i < ca.length; i++) {
1501    var c = ca[i];
1502    while (c.charAt(0) == " ") c = c.substring(1, c.length);
1503    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
1504  }
1505  return null;
1506}
1507
1508function setAudioCookie(name, value, days) {
1509  var expires = "";
1510  if (days) {
1511    var date = new Date();
1512    date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
1513    expires = "; expires=" + date.toUTCString();
1514  }
1515  document.cookie = name + "=" + (value || "") + expires + "; path=/";
1516}
1517
1518function getAudioCookie(name) {
1519  var nameEQ = name + "=";
1520  var ca = document.cookie.split(";");
1521  for (var i = 0; i < ca.length; i++) {
1522    var c = ca[i];
1523    while (c.charAt(0) == " ") c = c.substring(1, c.length);
1524    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
1525  }
1526  return null;
1527}
1528
1529// WPB-6927: Helper functions to extract Apple Music IDs from URLs
1530function extractAppleMusicId_audioStream(url) {
1531  if (!url) return '';
1532  var match = url.match(/\/(?:artist|album)\/[^\/]+\/(\d+)/);
1533  return match ? match[1] : '';
1534}
1535
1536function extractTrackId_audioStream(url) {
1537  if (!url) return '';
1538  var match = url.match(/[?&]i=(\d+)/);
1539  return match ? match[1] : '';
1540}
1541
1542// WPB-7073: Removed permanent URL blacklisting (added in WPB-6133) that caused
1543// the player to stop updating after a single API error. The blackl
1543ist was intended
1544// to suppress console errors for misconfigured stations, but it also permanently
1545// broke the player on temporary network failures. Now retries on every 30s interval
1546// (same approach the Recently Played widget uses).
1547var nowPlayingErrorCount = 0;
1548var NOW_PLAYING_MAX_CONSECUTIVE_ERRORS = 10; // Stop logging after 10 consecutive errors to avoid console spam
1549
1550/**
1551  * Update the player meta for every 30s
1552 */
1553 function updateNowPlayingMeta(station){
1554  //jQuery('.song-info-audio-stream').hide();
1555  console.log("Update Song Meta now playing...");
1556  var site_url = site_info.url;
1557  var site_id = site_info.id;
1558  var meta_slug = station.meta_slug;
1559  var myGen = wpb_np_requestGen; // WPB-7130: capture generation at request time
1560 if(meta_slug){
1561   var now_playing_data_url = `//api.itmwpb.com/nowplaying/v4/${site_id}/${meta_slug}`;
1562   if (site_info.np_debug) console.log("URL: ", now_playing_data_url);
1563
1564   jQuery.getJSON(now_playing_data_url)
1565   .done(function(data) {
1566     if (myGen !== wpb_np_requestGen) return; // WPB-7130: stale request, stream switched
1567     nowPlayingErrorCount = 0; // Reset error count on success
1568     var name = "";
1569     var artist = "";
1570     var album = "";
1571     var cover_art_url = "";
1572     var artist_url = "";
1573     var album_url = "";
1574     if(data !== 'undefined' && data.length > 0 ){
1575     var metaData = data[0];
1576     //console.log("metaData:",metaData);
1577     name = metaData.name;
1578     artist = metaData.artist;
1579     album = metaData.album;
1580     cover_art_url = metaData.image_url;
1581     artist_url = metaData.artist_url || "";
1582     album_url = metaData.album_url || "";
1583     } else {
1584     // WPB-7130: Empty response — show station name + logo
1585     jQuery("#amplitude-song-name").html(station.text);
1586     jQuery("#amplitude-artist").html('');
1587     jQuery("#amplitude-album").html('');
1588     if (station.station_logo_url) {
1589       jQuery("#amplitude-cover-art-url").attr("src", station.station_logo_url);
1590     }
1591     return;
1592     }
1593
1594     //cover_art_url = "https://dehayf5mhw1h7.cloudfront.net/wp-content/uploads/sites/1108/2019/02/21144743/king_logo_transparent.png";
1595     // var metaData = {
1596     //     "name": name,
1597     //     "artist": artist,
1598     //     "album": album,
1599     //     "cover_art_url": cover_art_url,
1600     //     "live": true
1601     // }
1602     // Amplitude.setSongMetaData(0, metaData)
1603     //var random = Math.floor((Math.random() * 100) + 1);
1604     if(name !==""){
1605     jQuery("#amplitude-song-name").html(name);
1606     }
1607     else{
1608      jQuery("#amplitude-song-name").html(station.text);
1609
1610     }
1611     jQuery("#amplitude-artist").html(artist);
1612     jQuery("#amplitude-album").html(album);
1613     if (cover_art_url) {
1614       jQuery("#amplitude-cover-art-url").attr("src", cover_art_url);
1615       //Amplitude.setDefaultAlbumArt(cover_art_url);
1616     }
1617     else{
1618     //jQuery("#amplitude-cover-art-url").attr("src", "https://via.placeholder.com/300.png/000/fff?text=Image%20Preview");
1619     jQuery("#amplitude-cover-art-url").attr("src",station.station_logo_url);
1620     }
1621     
1622     // WPB-6927: Handle artist/album info links
1623     var artistAppleId = '';
1624     var albumAppleId = '';
1625     var trackId = '';
1626     var siteUrl = site_info.url;
1627     
1628     // Only extract IDs if show_artist_album_link is enabled
1629     if (site_info.show_artist_album_link) {
1630       artistAppleId = extractAppleMusicId_audioStream(artist_url);
1631       albumAppleId = extractAppleMusicId_audioStream(album_url);
1632       trackId = extractTrackId_audioStream(album_url);
1633     }
1634     
1635     // Artist link
1636     if (artistAppleId) {
1637       jQuery("#amplitude-artist-link").attr("href", siteUrl + "/artist-info/" + artistAppleId + "/");
1638       jQuery("#amplitude-artist-link").css({"pointer-events": "", "cursor": "pointer"});
1639       jQuery("#amplitude-artist-link span").css("cursor", "pointer");
1640     } else {
1641       jQuery("#amplitude-artist-link").removeAttr("href");
1642       jQuery("#amplitude-artist-link").css({"pointer-events": "none", "cursor": "default"});
1643       jQuery("#amplitude-artist-link span").css("cursor", "default");
1644     }
1645     
1646     // Album/Song/Cover art links
1647     var albumInfoUrl = siteUrl + "/album-info/" + albumAppleId + "/" + (trackId ? "?track=" + trackId : "");
1648     if (albumAppleId) {
1649       jQuery("#amplitude-song-link").attr("href", albumInfoUrl);
1650       jQuery("#amplitude-cover-art-link").attr("href", albumInfoUrl);
1651       jQuery("#amplitude-song-link").css({"pointer-events": "", "cursor": "pointer"});
1652       jQuery("#amplitude-song-link span").css("cursor", "pointer");
1653       jQuery("#amplitude-cover-art-link").css({"pointer-events": "", "cursor": "pointer"});
1654     } else {
1655       jQuery("#amplitude-song-link").removeAttr("href");
1656       jQuery("#amplitude-cover-art-link").removeAttr("href");
1657       jQuery("#amplitude-song-link").css({"pointer-events": "none", "cursor": "default"});
1658       jQuery("#amplitude-song-link span").css("cursor", "default");
1659       jQuery("#amplitude-cover-art-link").css({"pointer-events": "none", "cursor": "default"});
1660     }
1661     //jQuery('.song-info-audio-stream').show();
1662   })
1663   .fail(function(jqXHR, textStatus, errorThrown) {
1664      // WPB-7073: Log the error but DON'T blacklist. Will retry on next 30s interval.
1665      nowPlayingErrorCount++;
1666      if (nowPlayingErrorCount <= NOW_PLAYING_MAX_CONSECUTIVE_ERRORS) {
1667        console.log("Now playing fetch failed (" + nowPlayingErrorCount + "), will retry next interval:", textStatus);
1668      }
1669    });
1670 }
1671 else{
1672   console.log("NowPlaying info is not set in stream manager...");
1673   jQuery("#amplitude-song-name").html(station.text);
1674 }
1675} //End of function - updateNowPlayingMeta
1676
1677// WPB-7130: Direct Now Playing - CORS detection, parsing, iTunes enrichment, adaptive polling
1678var wpb_np_direct_lastSongKey = "";
1679var wpb_np_direct_itunesCache = {};
1680var WPB_NP_ITUNES_CACHE_MAX = 200; // WPB-7130: cap to prevent unbounded growth
1681var wpb_np_direct_useDirect = null; // null = not tested yet, true = CORS works, false = fallback
1682var wpb_np_requestGen = 0; // WPB-7130: generation counter to discard stale in-flight requests
1683
1684/**
1685 * WPB-7130 Block 2: Route to direct or legacy based on station config
1686 */
1687function updateNowPlayingMetaRouter(station) {
1688  if (site_info.np_debug) console.log("WPB-7130 Router: cors_enabled =", station.now_playing_source ? station.now_playing_source.cors_enabled : 'no source config');
1689  if (station.now_playing_source && station.now_playing_source.cors_enabled == 1 && station.now_playing_source.source_url) {
1690    if (site_info.np_debug) console.log("WPB-7130 Router → DIRECT to source:", station.now_playing_source.source_url);
1691    updateNowPlayingMetaDirect(station);
1692  } else {
1693    var site_id = site_info.id;
1694    var meta_slug = station.meta_slug;
1695    var fallbackUrl = `//api.itmwpb.com/nowplaying/v4/${site_id}/${meta_slug}`;
1696    if (site_info.np_debug) console.log("WPB-7130 Router → FALLBACK v4:", fallbackUrl);
1697    updateNowPlayingMeta(station);
1698  }
1699}
1700
1701/**
1702 * WPB-7130 Block 2: Direct fetch with CORS detection + fallback
1703 */
1704function updateNowPlayingMetaDirect(station) {
1705  var npConfig = station.now_playing_source;
1706  var sourceUrl = npConfig.source_url;
1707  var myGen = wpb_np_requestGen; // WPB-7130: capture generation at request time
1708
1709  if (!sourceUrl) {
1710    console.log("WPB-7130: No source URL configured, falling back to legacy");
1711    updateNowPlayingMeta(station);
1712    return;
1713  }
1714
1715  if (wpb_np_direct_useDirect === false) {
1716    wpb_np_direct_fallback(station);
1717    return;
1718  }
1719
1720  fetch(sourceUrl, { mode: 'cors' })
1721    .then(function(response) {
1722      if (myGen !== wpb_np_requestGen) return; // WPB-7130: stale request, stream switched
1723      if (!response.ok) throw new Error("HTTP " + response.status);
1724      wpb_np_direct_useDirect = true;
1725      var contentType = response.headers.get('content-type') || '';
1726      if (npConfig.source_format === 'xml' || contentType.indexOf('xml') !== -1) {
1727        return response.text().then(function(text) {
1728          wpb_np_direct_parseAndUpdate(station, text, 'xml');
1729        });
1730      } else {
1731        return response.json().then(function(data) {
1732          wpb_np_direct_parseAndUpdate(station, data, npConfig.source_format || 'json');
1733        });
1734      }
1735    })
1736    .catch(function(error) {
1737      if (wpb_np_direct_useDirect === null) {
1738        console.log("WPB-7130: Direct access failed (CORS?), switching to fallback:", error.message);
1739        wpb_np_direct_useDirect = false;
1740      }
1741      wpb_np_direct_fallback(station);
1742    });
1743}
1744
1745/**
1746 * WPB-7130 Block 2: Fallback to existing api.itmwpb.com Lambda endpoint
1747 */
1748function wpb_np_direct_fallback(station) {
1749  var site_id = site_info.id;
1750  var meta_slug = station.meta_slug;
1751  var myGen = wpb_np_requestGen; // WPB-7130: capture generation at request time
1752  if (!meta_slug) {
1753    jQuery("#amplitude-song-name").html(station.text);
1754    return;
1755  }
1756  var fallbackUrl = '//api.itmwpb.com/nowplaying/v4/' + site_id + '/' + meta_slug;
1757  jQuery.getJSON(fallbackUrl).done(function(data) {
1758    if (myGen !== wpb_np_requestGen) return; // WPB-7130: stale request, stream switched
1759    if (data && data.length > 0) {
1760      var song = data[0];
1761      wpb_np_direct_updateDOM(station, song.name, song.artist, song.album, song.image_url, song.artist_url, song.album_url);
1762    }
1763  });
1764}
1765
1766/**
1767 * WPB-7130 Block 3: Parse response based on format + apply field mapping
1768 */
1769function wpb_np_direct_parseAndUpdate(station, data, format) {
1770  var npConfig = station.now_playing_source;
1771  var items;
1772
1773  if (format === 'xml') {
1774    items = wpb_np_direct_parseXML(data, npConfig.item_tag);
1775  } else {
1776    items = data;
1777    if (npConfig.item_tag && npConfig.item_tag.trim() !== '') {
1778      items = items[npConfig.item_tag];
1779    }
1780    if (format === 'document' || !Array.isArray(items)) {
1781      items = Array.isArray(items) ? items : [items];
1782    }
1783  }
1784
1785  if (!items || items.length === 0) {
1786    console.log("WPB-7130: No items found in response");
1787    return;
1788  }
1789
1790  if (npConfig.sort === 'desc') {
1791    items = items.reverse();
1792  }
1793
1794  var currentItem = items[0];
1795
1796  // Apply field mapping
1797  var songName = '', artistName = '', albumName = '', imageUrl = '';
1798  if (npConfig.field_map && npConfig.field_map.length > 0) {
1799    for (var i = 0; i < npConfig.field_map.length; i++) {
1800      var map = npConfig.field_map[i];
1801      var value = currentItem[map.mapTo];
1802      // Handle null/undefined values from source
1803      value = (value === null || value === undefined) ? '' : String(value);
1804      if (map.mapFrom === 'name') songName = value;
1805      else if (map.mapFrom === 'artist') artistName = value;
1806      else if (map.mapFrom === 'album') albumName = value;
1807      else if (map.mapFrom === 'image') imageUrl = value;
1808    }
1809  }
1810
1811  if (!songName || songName === '-' || songName === '–' || songName === '—' || songName.trim() === '' || songName.indexOf('ADBREAK') !== -1) {
1812    // Empty/placeholder data or ad break. Show appropriate defaults.
1813    wpb_np_direct_lastSongKey = ''; // Reset so next real song triggers update
1814    var isAdBreak = songName && songName.indexOf('ADBREAK') !== -1;
1815    jQuery("#amplitude-song-name").text(isAdBreak ? 'Ad Break' : station.text);
1816    jQuery("#amplitude-artist").text('');
1817    jQuery("#amplitude-album").text('');
1818    jQuery("#amplitude-cover-art-url").attr("src", station.station_logo_url || '');
1819    jQuery("#amplitude-artist-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
1820    jQuery("#amplitude-song-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
1821    jQuery("#amplitude-cover-art-link").removeAttr("href").css({"pointer-events": "none", "cursor": "default"});
1822    return;
1823  }
1824
1825  // Block 4: Song change detection
1826  var currentSongKey = artistName + '|' + songName;
1827  if (currentSongKey === wpb_np_direct_lastSongKey) {
1828    return;
1829  }
1830  wpb_np_direct_lastSongKey = currentSongKey;
1831
1832  // WPB-7130: Update DOM all at once — wait for iTunes if needed, then update everything together
1833  if (npConfig.fetch_itunes === '1' || npConfig.fetch_itunes === 1) {
1834    // Check iTunes cache first for instant update
1835    var cacheKey = artistName + '|' + songName;
1836    if (wpb_np_direct_itunesCache[cacheKey]) {
1837      var cached = wpb_np_direct_itunesCache[cacheKey];
1838      wpb_np_direct_updateDOM(station, songName, artistName, albumName, cached.image_url, cached.artist_url, cached.album_url);
1839    } else {
1840      // Show station logo as placeholder while waiting for iTunes
1841      wpb_np_direct_updateDOM(station, songName, artistName, albumName, station.station_logo_url || '', '', '');
1842      // Fetch iTunes then update image + links
1843      wpb_np_direct_fetchItunes(station, artistName, songName);
1844    }
1845  } else {
1846    wpb_np_direct_updateDOM(station, songName, artistName, albumName, imageUrl, '', '');
1847  }
1848}
1849
1850/**
1851 * WPB-7130 Block 3: Parse XML response
1852 */
1853function wpb_np_direct_parseXML(xmlText, itemTag) {
1854  var parser = new DOMParser();
1855  var xmlDoc = parser.parseFromString(xmlText, 'text/xml');
1856  var items = [];
1857  var elements;
1858
1859  if (itemTag && itemTag.trim() !== '') {
1860    elements = xmlDoc.getElementsByTagName(itemTag);
1861  } else {
1862    elements = xmlDoc.documentElement.children;
1863  }
1864
1865  for (var i = 0; i < elements.length; i++) {
1866    var item = {};
1867    var children = elements[i].children;
1868    for (var j = 0; j < children.length; j++) {
1869      item[children[j].tagName] = children[j].textContent;
1870    }
1871    items.push(item);
1872  }
1873  return items;
1874}
1875
1876/**
1877 * WPB-7130 Block 4: iTunes enrichment (called only on song change)
1878 */
1879function wpb_np_direct_fetchItunes(station, artist, songName) {
1880  var cacheKey = artist + '|' + songName;
1881
1882  if (wpb_np_direct_itunesCache[cacheKey]) {
1883    var cached = wpb_np_direct_itunesCache[cacheKey];
1884    wpb_np_direct_updateDOMImage(station, cached.image_url, cached.artist_url, cached.album_url);
1885    return;
1886  }
1887
1888  var term = encodeURIComponent(artist + ' - ' + songName);
1889  var itunesUrl = 'https://itunes.apple.com/search?term=' + term + '&country=us&media=music&entity=song&limit=1&lang=en_us&explicit=Yes&version=2';
1890
1891  fetch(itunesUrl)
1892    .then(function(response) { return response.json(); })
1893    .then(function(data) {
1894      if (data.resultCount > 0 && data.results && data.results[0]) {
1895        var result = data.results[0];
1896        var itunesData = {
1897          image_url: (result.artworkUrl100 || '').replace('100x100', '600x600'),
1898          album_url: result.collectionViewUrl || '',
1899          artist_url: result.artistViewUrl || '',
1900          track_url: result.trackViewUrl || ''
1901        };
1902        // Evict oldest entry if cache is full
1903        var cacheKeys = Object.keys(wpb_np_direct_itunesCache);
1904        if (cacheKeys.length >= WPB_NP_ITUNES_CACHE_MAX) {
1905          delete wpb_np_direct_itunesCache[cacheKeys[0]];
1906        }
1907        wpb_np_direct_itunesCache[cacheKey] = itunesData;
1908        wpb_np_direct_updateDOMImage(station, itunesData.image_url, itunesData.artist_url, itunesData.album_url);
1909      }
1910    })
1911    .catch(function(error) {
1912      console.log("WPB-7130: iTunes fetch failed:", error.message);
1913    });
1914}
1915
1916/**
1917 * WPB-7130 Block 4: Update DOM — text fields
1918 */
1919function wpb_np_direct_updateDOM(station, songName, artist, album, imageUrl, artistUrl, albumUrl) {
1920  if (songName) {
1921    jQuery("#amplitude-song-name").text(songName);
1922  } else {
1923    jQuery("#amplitude-song-name").text(station.text);
1924  }
1925  jQuery("#amplitude-artist").text(artist || '');
1926  jQuery("#amplitude-album").text(album || '');
1927
1928  if (imageUrl) {
1929    jQuery("#amplitude-cover-art-url").attr("src", imageUrl);
1930  } else {
1931    jQuery("#amplitude-cover-art-url").attr("src", station.station_logo_url || '');
1932  }
1933
1934  if (artistUrl || albumUrl) {
1935    wpb_np_direct_updateDOMImage(station, imageUrl, artistUrl, albumUrl);
1936  }
1937}
1938
1939/**
1940 * WPB-7130 Block 4: Update DOM — image + Apple Music links
1941 */
1942function wpb_np_direct_updateDOMImage(station, imageUrl, artistUrl, albumUrl) {
1943  var siteUrl = site_info.url;
1944
1945  if (imageUrl) {
1946    jQuery("#amplitude-cover-art-url").attr("src", imageUrl);
1947  }
1948
1949  var artistAppleId = wpb_np_direct_extractAppleId(artistUrl);
1950  if (artistAppleId && site_info.show_artist_album_link) {
1951    jQuery("#amplitude-artist-link").attr("href", siteUrl + "/artist-info/" + artistAppleId + "/");
1952    jQuery("#amplitude-artist-link").css({"pointer-events": "", "cursor": "pointer"});
1953    jQuery("#amplitude-artist-link span").css("cursor", "pointer");
1954  } else {
1955    jQuery("#amplitude-artist-link").removeAttr("href");
1956    jQuery("#amplitude-artist-link").css({"pointer-events": "none", "cursor": "default"});
1957    jQuery("#amplitude-artist-link span").css("cursor", "default");
1958  }
1959
1960  var albumAppleId = wpb_np_direct_extractAppleId(albumUrl);
1961  var trackId = wpb_np_direct_extractTrackId(albumUrl);
1962  var albumInfoUrl = siteUrl + "/album-info/" + albumAppleId + "/" + (trackId ? "?track=" + trackId : "");
1963  if (albumAppleId && site_info.show_artist_album_link) {
1964    jQuery("#amplitude-song-link").attr("href", albumInfoUrl);
1965    jQuery("#amplitude-cover-art-link").attr("href", albumInfoUrl);
1966    jQuery("#amplitude-song-link").css({"pointer-events": "", "cursor": "pointer"});
1967    jQuery("#amplitude-song-link span").css("cursor", "pointer");
1968    jQuery("#amplitude-cover-art-link").css({"pointer-events": "", "cursor": "pointer"});
1969  } else {
1970    jQuery("#amplitude-song-link").removeAttr("href");
1971    jQuery("#amplitude-cover-art-link").removeAttr("href");
1972    jQuery("#amplitude-song-link").css({"pointer-events": "none", "cursor": "default"});
1973    jQuery("#amplitude-song-link span").css("cursor", "default");
1974    jQuery("#amplitude-cover-art-link").css({"pointer-events": "none", "cursor": "default"});
1975  }
1976}
1977
1978function wpb_np_direct_extractAppleId(url) {
1979  if (!url) return '';
1980  var match = url.match(/\/(?:artist|album)\/[^\/]+\/(\d+)/);
1981  return match ? match[1] : '';
1982}
1983
1984function wpb_np_direct_extractTrackId(url) {
1985  if (!url) return '';
1986  var match = url.match(/[?&]i=(\d+)/);
1987  return match ? match[1] : '';
1988}
1989
1990// function showGigyaPopupForAudioStream() {
1991//   jQuery(document).ready(function($) {
1992//     var key = "audioPlayAttempts";
1993//     var autoAttempts = getAudioCookie(key);
1994//     if (
1995//       autoAttempts > 5 &&
1996//       typeof loginToGigya === "function" &&
1997//       typeof Amplitude == "object" &&
1998//       (Amplitude.getPlayerState() == "playing" ||
1999//         Amplitude.getPlayerState() == "progress")
2000//     ) {
2001//       Amplitude.pause();
2002//       jQuery(".amplitude-play-pause")
2003//         .addClass("amplitude-paused")
2004//         .removeClass("amplitude-playing");
2005//       jQuery("#audioLoginModal").show();
2006//     }
2007//   });
2008// }

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.