PageSourceSearch

https://housemusicradiostation.de/wp-content/plugins/sonaar-music-pro/public/js/sonaarPlayer.js?ver=105.0.3

js housemusicradiostation.de collected 2026-10-08 03:07:08 UTC 50,807 bytes, 1,164 lines download raw bytes

1$ = jQuery;
2  IRON.data = {
3  
4  list: {
5    playlist_name: false,
6    tracks: false,
7    type: false,
8    random_order: "",
9  },
10  currentTrack: 0,
11  continuous: false, //if the player has been loaded from cookies.
12  favoriteTackList: false,
13  playlistID: "",
14  showList: false,
15  isPlaying: false,
16  audioplayerPlaying: null, //Which Audioplayer instance is playing.
17  loading: 0,
18  minimize: true,
19  extendedPlayerOpened: false,
20  extendedPlayerOverlayOpened: false,
21  audioCtx: false,
22  audioElement: false,
23  audioSrc: false,
24  analyser: false,
25  frequencyData: false,
26  userPref: {
27    pause: false,
28    minimize: false,
29    autoplay: true,
30  },
31  storeButtonCount: 0,
32  unlock: false,
33  playerStatus: "",
34  currentTime: "",
35  totalTime: "",
36  shuffle: false,
37  mute: false,
38  volume: null,
39  elWidgetId: false, //Only has value when the playlist is built with the elementor widget
40  postId: false, //Used by the continous player when the playlist is generated by a elementor widget
41  isSmallDevice:( $('body').width() > 768 )? false: true,
42  classes: {
43    enable: false,
44    waveEnable: false,
45    continuousPlayer: Boolean(sonaar_music.option.enable_continuous_player === "true"),
46    show_nextprevious_bt: (sonaar_music.option.sticky_show_nextprevious_bt != "false") ? true : false,
47    show_speed_bt: Boolean(sonaar_music.option.sticky_show_speed_bt === "true"),
48    show_skip_bt: Boolean(sonaar_music.option.sticky_show_skip_bt === "true"),
49    show_tracklist_bt: (sonaar_music.option.sticky_show_tracklist_bt != "false") ? true : false,
50    show_shuffle_bt: (sonaar_music.option.sticky_show_shuffle_bt != "false") ? true : false,
51    display_description: (sonaar_music.option.sticky_show_description != "false") ? true : false,
52    template: sonaar_music.option.sticky_preset,
53    floatpos: sonaar_music.option.float_pos,
54    show_controls_hover: sonaar_music.option.show_controls_hover,
55    isPlaying: false,
56    author: srp_vars.sonaar_music.continuous_artist_name,
57    feedUrl: false,
58    noLoopTracklist: (srp_vars.sonaar_music.no_loop_tracklist == 'on') ? 'on' : false,
59    notrackskip: (srp_vars.sonaar_music.no_track_skip == 'on') ? 'on' : false,
60    continued: false, //Player settings come from the cookie (continuous player)
61    dontCountContinuous: false, //For statistic. Dont count stats from the continuous player
62    emptyPlayer: true,
63    skipForward: 30,
64    skipBackward: 15,
65    speedRate: 1,
66    wc_ajax_add_to_cart: (sonaar_music.option.wc_enable_ajax_addtocart == 'true') ? true : false,
67    wc_variation_lb: (sonaar_music.option.wc_variation_lb != 'false') ? true : false,
68  },
69  cookieSetting: {
70    mute: false,
71    volume: 1,
72    isPlaying: false,
73    currentTime: 0,
74    json: false, //Required for the continuous player with Post Related or "audio_meta_field" shorcode attribute as source
75  },
76};
77
78var playerHasPlayed = false;
79var srp_seekTime = false;
80var loadAndPlay = false; //True when we are using the setplayerAndPlay. Used only with dynamic weve
81
82
83Vue.component('control', {
84  props: ["player"],
85  template: `
86  <div class="control">
87    <div aria-label="View Tracklist" class="list control--item sricon-list" @click="player.setshowList" v-if="player.list.tracks.length > 1 && player.classes.show_tracklist_bt && !player.isSmallDevice">
88    </div>
89    <div aria-label="Rewind 15 seconds" class="sr_skipBackward sricon-15s" @click="sr_audioSkipTo(-1 * player.classes.skipBackward)" v-if="player.classes.show_skip_bt && !player.isSmallDevicet"></div>
90    <div aria-label="Previous Track" class="previous control--item sricon-back" @click="player.previous" v-if="player.list.tracks.length > 1 && player.classes.show_nextprevious_bt && !player.isSmallDevice"></div>
91    <div aria-label="Play / Pause" class="play control--item sricon-play" @click="player.play" :class="{'audio-playing': player.isPlaying }"></div>
92    <div aria-label="Next Track" class="next control--item sricon-forward" @click="player.next" v-if="player.list.tracks.length > 1 && player.classes.show_nextprevious_bt && !player.isSmallDevice"></div>
93    <div aria-label="Forward 30 seconds" class="sr_skipForward sricon-30s" @click="sr_audioSkipTo(player.classes.skipForward)" v-if="player.classes.show_skip_bt && !player.isSmallDevice"></div>
94    <div aria-label="Speed Rates" class="sr_speedRate" :class="player.classes.speedRate != 1 ? 'active' : '' " @click="sr_setSpeedRate" v-if="player.classes.show_speed_bt && !player.isSmallDevice"><div>{{player.classes.speedRate}}X</div></div>
95    <div aria-label="Shuffle Track" class="shuffle control--item sricon-shuffle" :class="player.shuffle ? 'active' : '' " @click="sr_shuffleToggle" v-if="player.list.tracks.length > 1 && player.classes.show_shuffle_bt && !player.isSmallDevice"></div>
96  </div>`
97})
98
99Vue.component('waveform', {
100  props: ["player"],
101  template: `
102  <div class="sr_progressbar_sticky">
103    <div class="timing">
104        <div class="time timing_currentTime">{{ player.currentTime }}</div>
105        <div class="time timing_totalTime">{{ player.totalTime }}</div>
106    </div>
107    <div id="sPlayer" class="wave sonaar_fake_wave" :class="{reveal: player.classes.waveEnable, sr_hide: !player.classes.waveEnable}">
108      <div class="sonaar_wave_base"><svg></svg>
109        <canvas id="splayer-wave-container" :height="player.setWaveHeight" width="2540"></canvas>
110      </div>
111      <div class="sonaar_wave_cut"><svg></svg>
112      <canvas id="splayer-wave-progress" :height="player.setWaveHeight" width="2540"></canvas>
113      </div>
114    </div>
115    </div>`,
116  mounted () {
117    IRON.audioPlayer.fakeWaveClick('sticky');
118  }
119})
120
121Vue.component('sonaar-extend-button', {
122  props: ["player"],
123  template: `
124    <div aria-label="Show Call-to-action buttons" class="sonaar-extend-button" @click="player.showCTA" v-if="player.list.tracks.length >= 1 && player.albumStoreList.length >= 1">
125      <i class="fas fa-ellipsis-v"></i>
126    </div>
127  `
128});
129Vue.component('store', {
130  props: ["player"],
131  template: `
132      <transition name="sonaar-player-storefade">
133      <div class="store" v-if="player.list.tracks.length >= 1 && player.albumStoreList.length >= 1">
134      
135          <ul class="track-store" v-if="player.albumStoreList.length >= 1">
136            <li v-for="(store, storeIndex) in player.albumStoreList">
137            <cta :player=player :storeid=storeIndex label=true></cta>
138            </li>
139          </ul>
140      </div>
141    </transition>
142  `
143});
144Vue.component('cta', {
145  props: ["player","storeid","label"],
146  computed: {
147      store () {
148        var index;
149        if( typeof this.storeid == 'number'){
150          index=  this.storeid;
151        }else{
152          var storeId = this.storeid;
153          index = IRON.sonaar.player.albumStoreList.findIndex(function(element) {
154            var storeIdKey = (typeof element['cta-class'] !== "undefined")?'cta-class':'store-icon'; //Some CTA can be identify by using the "cta-class" key and other "store-icon"
155            return element[storeIdKey] === storeId;
156          });
157        }
158        return IRON.sonaar.player.albumStoreList[index];
159      },
160  },
161  template: `
162            <span v-if="(typeof store !== 'undefined')"><a
163               
164              :href="store['link-option'] == 'popup' || (store['has-variation'] == true && player.classes.wc_variation_lb) ? '#!': store['store-link']"
165              :target="store['store-target'] || store['link-option'] === 'popup' ? '_self' : '_blank'"
166              v-bind:class="[
167                {
168                  'sr_store_round_bt': store['store-type'] === 'wc',
169                  'add_to_cart_button ajax_add_to_cart': player.classes.wc_ajax_add_to_cart && !store['has-variation'],
170                  'sr_store_force_share_bt--sticky': store['cta-class'] === 'sr_store_force_share_bt'
171                },
172                store['cta-class'] // Bind the store['cta-class'] directly to the class attribute
173              ]"
174              :download="player.ifDownloadAttribute(store)"
175              :data-product_id="store['product-id'] !== undefined ? store['product-id'] : false"
176              @click="player.ctaClick(store, player.getIndexFromStoreList(store['cta-class']), $(event.target))"
177            >
178           
179              <i :class="store['store-icon']"></i><span>{{ (label)?store['store-name']:'' }}</span>
180            
181            </a></span>
182  `
183});
184
185IRON.sonaar = {
186  player: new Vue({
187    el: "#sonaar-player",
188    data: IRON.data,
189    methods: {
190      play: function () {
191        this.userPref.autoplay = true;
192        if (this.isPlaying) {
193          document.getElementById("sonaar-audio").pause(); // -- Audio MediaElement
194        } else {
195          this.playAudio();
196        }
197      },
198      playAudio: function () {
199        var promise = document.getElementById("sonaar-audio").play();
200        if (promise !== undefined) {
201          promise
202            .then((_) => {
203              //console.log('play started! yeah');
204              // Autoplay started!
205            })
206            .catch((error) => {
207              console.log("Warning = " + error);
208              // Autoplay was prevented.
209              // Show a "Play" button so that user can start playback.
210            });
211        }
212        if(typeof sonaar_music.option.sticky_spectro_style !== "undefined" && sonaar_music.option.sticky_spectro_style != "none"){
213          startAudioSpectrum( '#sonaar-player' )
214        }
215      },
216      previous: function () {
217        if (this.shuffle) {
218          var i;
219          for (i = 0; i < this.list.random_order.length; i++) {
220            if (this.list.random_order[i] == this.currentTrack) {
221              if (i == 0) {
222                this.currentTrack = this.list.random_order[this.list.random_order.length - 1];
223              } else {
224                this.currentTrack = this.list.random_order[i - 1];
225              }
226              break;
227            }
228          }
229        } else {
230          if (this.currentTrack - 1 < 0) return (this.currentTrack = this.list.tracks.length - 1);
231
232          this.currentTrack--;
233        }
234      },
235      next: function () {
236        if (this.playerStatus == "next") return;
237
238        if (this.shuffle) {
239          var i;
240          for (i = 0; i < this.list.random_order.length; i++) {
241            if (this.list.random_order[i] == this.currentTrack) {
242              if (i == this.list.random_order.length - 1) {
243                if (this.classes.noLoopTracklist == "on"){
244                  return;
245                }
246                this.currentTrack = this.list.random_order[0];
247              } else {
248                this.currentTrack = this.list.random_order[i + 1];
249              }
250              break;
251            }
252          }
253        } else {
254          if (this.list.tracks.length == 1) { //handleTrackChange() run automaticly when the currentTrack value change. When the playlist has only one track, the currenttrack value never change so we have to trig it here.
255            if (this.classes.noLoopTracklist == "on") return; //Do nothing if the "No loop tracklist" is enable"
256            this.handleTrackChange();
257            return;
258          }
259          if (this.currentTrack + 1 >= this.list.tracks.length) { //At the end of the playlist
260            if (this.classes.noLoopTracklist == "on") return; //Do nothing if the "No loop tracklist" is enable"
261            return (this.currentTrack = 0);
262          }
263
264          this.currentTrack++;
265        }
266      },
267      skipBackward: function () {
268        sr_audioSkipTo(-1 * this.classes.skipBackward);
269      },
270      skipForward: function () {
271        sr_audioSkipTo(this.classes.skipForward);
272      },
273      start: function () { //Created for custom JS | not used by the plugin code
274        document.getElementById("sonaar-audio").play();
275      },
276      pause: function () { //Created for custom JS | not used by the plugin code
277        document.getElementById("sonaar-audio").pause();
278      },
279      toggleStartPause: function () { //Created for custom JS | not used by the plugin code
280        IRON.sonaar.player.play();
281      },
282 
283
284      setPlaylist: function (audioPlayer, eq, time = 0) {
285        if ($(audioPlayer).attr("trackselected") == eq || ($(audioPlayer).attr("trackselected") == null && eq == 0)) {
286          $(audioPlayer).attr("duplicating_wave", true);
287        }
288        $(audioPlayer).attr("trackselected", eq);
289        var params = audioPlayer.data("url-playlist").slice(audioPlayer.data("url-playlist").indexOf("title")).split("&");
290        let newParams = [];
291        params.forEach(function (el) {
292          let paramName;
293          let paramValue;
294          [paramName, paramValue] = el.split('=')
295          newParams[paramName] = paramValue;
296        });
297        if (newParams.feed.length || newParams.audio_meta_field.length) {
298          var id = $(audioPlayer).attr("id"); //Use the elementor widget ID as the player ID. This param is only available the FEED option.
299        } else {
300          var id = newParams.albums;
301        }
302        this.setPlayer({
303          id: id,
304          category: newParams.category || '',
305          title: newParams.title,
306          trackid: eq,
307          shuffle: audioPlayer.data("shuffle"),
308          audioPlayer: audioPlayer,
309          time: time
310        });
311      },
312
313      preventContinuousUrl: function () {
314        var preventURL = false;
315        if (typeof sonaar_music.option.sr_prevent_continuous_url !== "undefined") {
316          if (sonaar_music.option.sr_prevent_continuous_url.includes(sonaar_music.postID)) {
317            preventURL = true;
318          }
319        }
320        return preventURL;
321      },
322
323      setPlayerAndPlay: function (args) {
324        if (IRON.sonaar.player.playlistID != args.id || this.currentTrack != args.trackid) {
325          IRON.audioPlayer.stickyEnable = true;
326          this.setPlayer(args);
327          this.playAudio();
328        } else {
329          if (!this.isPlaying) {
330            this.playAudio();
331          }
332          if (args.time) {
333            this.seekTime(convertTime(args.time))
334          }
335          if (args.trackid && this.currentTrack != args.trackid) {
336            this.currentTrack = args.trackid;
337          }
338        }
339       
340        if(args.nolooptracklist == "on"){
341          IRON.sonaar.player.classes.noLoopTracklist = "on";
342        }
343        if(args.notrackskip == "on"){
344          IRON.sonaar.player.classes.notrackskip = "on";
345        }
346      },
347
348      getPlaylistbyID: function (id, category, title, elwidget, jsonFromCookie = false) {
349        var playlistID = id || false;
350        var title = title || "";
351        var elwidget = elwidget ? elwidget + "&feed=1" : null;
352          if (this.selectedPlayer === null && playlistID) {
353            if (jsonFromCookie) {
354              return jsonFromCookie;
355            } else {
356              return srp_vars.site_url + "?load=playlist.json&title=" + title + "&albums=" + playlistID + "&category=" + category + "&el_widget_id=" + elwidget + "&posts_per_pages=-1";
357            }
358          } else {
359            json_url = this.selectedPlayer.attr("data-url-playlist");
360            return json_url;
361          }
362      },
363
364      seekTime: function (time) {
365        if (time) {
366          if (document.getElementById("sonaar-audio").duration !== Infinity) {
367            document.getElementById("sonaar-audio").currentTime = convertTime(time);
368          }
369          srp_seekTime = false;
370        }
371      },
372
373      setPlayer: function (args) {
374        var newTracklistIsFavoriteList = (typeof args.audioPlayer != 'undefined' && args.audioPlayer.hasClass('srp_player_is_favorite'))? true : false;
375        IRON.audioPlayer.stickyEnable = true;
376
377        sanitized_id = args.id
378        sanitized_id = sanitized_id.toString();
379        sanitized_id = sanitized_id.split(" ").join(""); // prevent blank space
380        args.id = sanitized_id.replace(/latest/i, srp_vars.sonaar_music.mostRecentId); // if latest string is used, replace it by the most recent id
381
382        if(typeof sonaar_music.option.sticky_spectro_style !== "undefined" && sonaar_music.option.sticky_spectro_style != "none"  && $('#sonaar-audio').length){ // if sticky spectro is enabled
383          document.getElementById("sonaar-audio").crossOrigin = "anonymous";
384        }
385
386        this.classes.emptyPlayer = false;
387        var args = args || {};
388        var params = {
389          id: args.id,
390          category: args.category || '',
391          title: args.title || null,
392          trackid: args.trackid || 0,
393          autoplay: typeof args.autoplay == "boolean" ? args.autoplay : true,
394          el_widget_id: args.elwidgetid || false,
395          jsonFromCookie: args.json || false // Used to conserved postrelated playlist from single post
396        };
397        params.id = (params.id == '' && params.category != '') ? srp_vars.sonaar_music.currentPostId : params.id; 
398        srp_seekTime = args.time || false;
399        this.selectedPlayer = args.audioPlayer || null;
400
401        if( this.continuous ){
402          this.playlistID = false;
403        }
404        if(typeof  args.continuous != 'undefined' &&  args.continuous){
405          this.continuous = true;
406        }else{
407          this.continuous = false;
408        }
409
410        this.elWidgetId = params.el_widget_id;
411        this.shuffle = args.shuffle == true || args.shuffle == "true" || args.shuffle == "1" || (this.selectedPlayer && this.selectedPlayer.attr('data-shuffle') == 'true') ? true : false;
412        var samePlaylist = false;
413        if(this.selectedPlayer && this.selectedPlayer.hasClass('sr_selectedPlayer')){ //If the player is already selected
414           samePlaylist = true;
415        }else{
416          $(".sr_selectedPlayer").removeClass("sr_selectedPlayer");
417          $(this.selectedPlayer).addClass("sr_selectedPlayer");
418        }
419
420        if (!this.classes.wavesurferEnable) {
421          IRON.audioPlayer.fakeWaveClick("sticky");
422        }
423        this.userPref.autoplay = params.autoplay;
424
425        //const samePlaylist = (params.id && params.id === this.playlistID && this.favoriteTackList == newTracklistIsFavoriteList)? true : false;
426        
427        if (samePlaylist && params.trackid == this.currentTrack) { //If the track is already the current track.
428          this.seekTime(srp_seekTime);
429          return this.play();
430        }
431        if ( samePlaylist && params.trackid !== this.currentTrack ) {
432          this.currentTrack = params.trackid;
433        }
434
435        //Load tracklist from th Json file only if the playlist ID has changed or if the playlist is a favorite playlist.
436        if (
437            !samePlaylist || 
438            newTracklistIsFavoriteList !== this.favoriteTackList || 
439            params.category !== this.categoryID
440          ) {
441          const endingTrack = this.currentTrack;
442          $.when($.getJSON(this.getPlaylistbyID(params.id, params.category, params.title, params.el_widget_id, params.jsonFromCookie))).done(
443            function (data) {
444              if (!$("body").hasClass("artistPlayer-enable")) {
445                this.classes.enable = true;
446                if (!IRON.sonaar.player.classes.continued) {
447                  this.minimize = false;
448                }
449                this.animatePlayer();
450                $("body").addClass("continuousPlayer-enable");
451              }
452              this.list = data;
453              if (IRON.players.length && this.selectedPlayer && this.selectedPlayer.hasClass('srp_reordered')) {
454                for (var playerIndex = 0; playerIndex < IRON.players.length && IRON.players[playerIndex].audioPlayer.attr('id') != $(this.selectedPlayer).attr('id'); playerIndex++) { }; //Set playerIndex
455                this.reOrderTacklist(playerIndex)
456              }
457
458              if (this.shuffle) {
459                this.setRandomList();
460                if (typeof args.trackid == "undefined") {
461                  params.trackid = Math.floor(Math.random() * this.list.tracks.length);
462                }
463              }
464
465              this.playlistID = params.id;
466              this.categoryID = params.category;
467
468              if(typeof sonaar_music.option.general_volume != 'undefined' && this.volume == null){
469                sr_setVolume(sonaar_music.option.general_volume/100);
470              }        
471
472              if (this.list.type == "podcast") {
473                for (var i = 0; i < this.list.tracks.length; i++) {
474                  var element = this.list.tracks[i];
475
476                  if (element.id == params.id) {
477                    this.currentTrack = i;
478                  }
479                }
480              } else {
481                this.currentTrack = params.trackid;
482              }
483
484              if (this.currentTrack == 0 || //If the currentTrack still has the default value, execute handleTrackChange. 
485                endingTrack == this.currentTrack //HandletrackChange function is automatically triggered when the currentTrack value is changed. Here we execute it if the currentTrack value is the same but the playlist ID has been changed.
486              ) {
487                this.handleTrackChange();
488              }
489
490            }.bind(this)
491          );
492          this.favoriteTackList = newTracklistIsFavoriteList;
493        }
494
495        if (this.selectedPlayer != null) {
496          this.classes.feedUrl = this.selectedPlayer.data("feedurl");
497          this.classes.noLoopTracklist = this.selectedPlayer.data("no-loop-tracklist");
498          this.classes.notrackskip = this.selectedPlayer.data("notrackskip");
499          this.cookieSetting.json = this.selectedPlayer.attr('data-url-playlist');
500        }
501        this.postId = srp_vars.sonaar_music.currentPostId;
502
503        IRON.sonaar.player.selectedTimeStamp = null;
504        if (typeof args.ts_id != 'undefined') { //set selected time stamp shortcode
505          IRON.sonaar.player.selectedTimeStamp = $('#sonaar_ts-' + args.ts_id);
506        } else {
507          let selector = '.srmp3_sonaar_ts_shortcode';
508          if (this.selectedPlayer != null && typeof this.selectedPlayer.data('ts-sync') != 'undefined') {
509            IRON.sonaar.player.selectedTimeStamp = $('#sonaar_ts-' + this.selectedPlayer.data('ts-sync'));
510            selector += ':not(#sonaar_ts-' + this.selectedPlayer.data('ts-sync') + ')';
511          }
512          $(selector).removeClass('sr_selected audio-playing');
513        }
514      },
515
516      setAudio: function () {
517        //Set to "audioplayerPlaying" which audioplayer is playing. ( 0 for the first audioplayer)
518        var audioplayerPlayingID = null;
519        $.each(IRON.players, function (index) {
520          if ($(IRON.players[index].audioPlayer).hasClass("sr_selectedPlayer")) {
521            audioplayerPlayingID = index;
522          }
523        });
524        this.audioplayerPlaying = audioplayerPlayingID;
525        this.setPlayerType();
526        //----------------------------------------------------------------------
527
528        if (this.list.tracks[this.currentTrack].mp3 === null || this.list.tracks[this.currentTrack].mp3 === "") {
529          // feed url is used in the shortcode instead of post id
530          this.list.tracks[this.currentTrack].mp3 = $(".iron-audioplayer.sr_selectedPlayer .sr-playlist-item").attr("data-audiopath");
531          this.list.tracks[this.currentTrack].track_title = $(".iron-audioplayer.sr_selectedPlayer .sr-playlist-item").attr("data-tracktitle");
532          this.list.tracks[this.currentTrack].album_title = $(".iron-audioplayer.sr_selectedPlayer .sr-playlist-item").attr("data-albumtitle");
533          this.list.tracks[this.currentTrack].track_artist = $(".iron-audioplayer.sr_selectedPlayer .sr-playlist-item").attr("data-trackartist");
534        }
535
536        elementAudio.src = this.list.tracks[this.currentTrack].mp3;
537        $("#sonaar-player").attr("data-tracktitle", this.list.tracks[this.currentTrack].track_title);
538        $("#sonaar-player").attr("data-albumtitle", this.list.tracks[this.currentTrack].album_title);
539        $("#sonaar-player").attr("data-trackartist", this.list.tracks[this.currentTrack].track_artist);
540        $("#sonaar-player").attr("data-audiopath", this.list.tracks[this.currentTrack].mp3);
541        if (this.list.tracks[this.currentTrack].id != null) {
542          $("#sonaar-player").attr("data-trackid", this.list.tracks[this.currentTrack].id);
543        }
544        currentTrackTitle = this.list.tracks[this.currentTrack].track_title;
545        currentAlbumTitle = this.list.tracks[this.currentTrack].album_title;
546        currentArtistName = this.list.tracks[this.currentTrack].track_artist;
547        currentAlbumArt = this.list.tracks[this.currentTrack].poster;
548        IRON.audioPlayer.setMediaSessionAPI(currentTrackTitle, currentAlbumTitle, currentArtistName, currentAlbumArt);     
549
550          $("#sonaar-player .sonaar_wave_cut, .sr_selectedPlayer .album-player .sonaar_wave_cut, .sr_selectedPlayer .current .sonaar_wave_cut, #sonaar-player .mobileProgressing").width(0);
551          var trackHasEnded = document.getElementById("sonaar-audio").ended;
552          var isPlaying = !document.getElementById("sonaar-audio").paused;
553          $("#sonaar-audio").attr("src", elementAudio.src); //Load Audio MediaElement to the Sticky player
554          $("#sonaar-audio").attr("title", currentTrackTitle); //set title for analytics reports (eg: matomo)
555          //document.getElementById("sonaar-audio").crossOrigin = "anonymous";
556          document.getElementById("sonaar-audio").load();
557          if ($(".sr_selectedPlayer").length || isPlaying || trackHasEnded) {
558            // if the sticky player is sync with a widget player OR is already playing
559            this.playAudio();
560            $("#sonaar-player .play").addClass("audio-playing");
561          }
562          this.classes.waveEnable = true;
563
564          if (IRON.players.length != 0 && this.selectedPlayer != null) { //If Widget Player is selected
565            IRON.createFakeWave(this.selectedPlayer);
566          }
567          IRON.createFakeWave(false, true);
568        
569        $(document).trigger("sonaarStats", $("#sonaar-player"));
570        if (IRON.players.length != 0 && this.classes.feedUrl && !this.elWidgetId && this.audioplayerPlaying != null) {
571          //Set "elWidgetId" only when the playlist is built with the elementor widget
572          this.elWidgetId = $(IRON.players[this.audioplayerPlaying].audioPlayer).parents(".elementor-widget-music-player").attr("data-id");
573        }
574
575        if (this.classes.continuousPlayer) {
576          sr_setCookieSettings();
577        }
578        function ifHaveStoreContent() { //Check if the current player has store-content in the store list
579          let value = false;
580          $.each(IRON.sonaar.player.list.tracks, function () {
581            if (typeof (this.song_store_list) != 'undefined') {
582              $.each(this.song_store_list, function () {
583                if (typeof (this['store-content']) != 'undefined') {
584                  value = true;
585                }
586              });
587            };
588          });
589          return value;
590        }
591        if (ifHaveStoreContent()) { //Load Modal reurired for store content popup
592          sr_setPopUp();
593        }
594        
595        this.seekTime(srp_seekTime);
596        
597        IRON.audioPlayer.sr_loadLyricsAjax(this.list.tracks[this.currentTrack].sourcePostID, this.list.tracks[this.currentTrack].track_pos);
598        document.getElementById("sonaar-audio").playbackRate = IRON.sonaar.player.classes.speedRate;//set SpeedRate
599      },
600      clickPlayer: function () {
601        if (!$('.control:hover').length) {
602          this.openMobileControl();
603        }
604      },
605      extendedScrolldown: function () {
606        const extendedPlayer = document.querySelector(".srp_extendedPlayer")
607        if(extendedPlayer.scrollTop === 0){
608          extendedPlayer.scrollTo({
609            top: extendedPlayer.scrollTop + 200,
610            behavior: "smooth"
611          });
612        }  
613      },
614      clickTrackList: function (index) {
615        if(this.currentTrack == index){
616          this.play();
617        }else{
618          this.currentTrack = index; 
619          this.playAudio();
620        }
621      },
622      /*Close and Open the sticky mobile control Panel*/
623      /* the "cmd" parameter can be use if we only want to "open" or "close" the panel. By default it is toggling between each state.*/
624      openMobileControl: function (cmd = false) {
625        if ( this.isSmallDevice ) {
626          this.extendedPlayerOpened = true;
627          $('body').addClass('srp_sticky_ext_opened');
628        }
629      },
630      setshowList: function () {
631        if (this.showList == false) {
632          $("#pusher-wrap").addClass("sonaar-list-active");
633          return (this.showList = true);
634        }
635        $("#pusher-wrap").removeClass("sonaar-list-active");
636        return (this.showList = false);
637      },
638      setPlayerType: function () {
639        this.list.type = sonaar_music.option.player_type; //from plugin settings
640        if (this.audioplayerPlaying != null) {
641          this.list.type = IRON.players[this.audioplayerPlaying].audioPlayer.playerType; //from widget
642        }
643        if (srp_vars.sonaar_music.post_player_type != '' && srp_vars.sonaar_music.post_player_type != 'default') {
644          this.list.type = srp_vars.sonaar_music.post_player_type //from playlist post settings selected in the page settings
645        }
646      },
647      closePlayer: function () {
648        if (this.showList) {
649          $("#pusher-wrap").removeClass("sonaar-list-active");
650          this.showList = false;
651        }
652        this.minimize = !this.minimize;
653        this.classes.enable = !this.classes.enable;
654        this.animatePlayer();
655      },
656      closeExtendedPlayer: function () {
657        this.extendedPlayerOpened = false;
658        $('body').removeClass('srp_sticky_ext_opened');
659      },
660      openExtendedPlayerOverlay: function () {
661        this.extendedPlayerOverlayOpened = true;
662      },
663      closeExtendedPlayerOverlay: function () {
664        console.log('closeExtendedPlayerOverlay')     
665        this.extendedPlayerOverlayOpened = false;
666      },
667      getIndexFromStoreList: function (className) {
668        const storeList = this.list.tracks[this.currentTrack].optional_storelist_cta;
669        var favIndex = -1; //Default
670        for (var i = 0; i < storeList.length; i++) {
671          if (storeList[i]['cta-class'] === className) {
672            favIndex = i;
673            //console.log('favIndex', favIndex);
674            return favIndex;
675           // console.log('favIndex-2', favIndex);
676          }
677        }
678        return favIndex;
679      },
680      
681
682      playlistAfterEnter: function () {
683        var ps = new PerfectScrollbar("#sonaar-player .playlist .scroll", {
684          wheelSpeed: 0.7,
685          swipeEasing: true,
686          wheelPropagation: false,
687          minScrollbarLength: 20,
688          suppressScrollX: true,
689        });
690        /*$('#sonaar-player .playlist .scroll').perfectScrollbar({
691          'suppressScrollX': true
692        })*/
693      },
694      scroll: function (event) {
695        var el = event.target;
696        var parent = el.offsetParent;
697
698        if (el.offsetWidth > parent.offsetWidth && !el.classList.contains("scrolling")) {
699          el.classList.add("scrolling");
700          var transformWidth = el.offsetWidth + 10;
701          el.insertAdjacentHTML("beforeend", '<span class="duplicate">' + el.innerText + "</span>");
702          el.style.transform = "translate( -" + transformWidth + "px )";
703          setTimeout(function () {
704            el.classList.remove("scrolling");
705            el.style.transform = "";
706            el.removeChild(el.firstElementChild);
707          }, 6000);
708        }
709      },
710      updatePlayers: function () {
711        $(".iron-audioplayer").removeClass("audio-playing");
712        
713        if (IRON.players.length != 0 && this.selectedPlayer != null) { //If Widget Player is selected
714
715          this.selectedPlayer.find("li.current").removeClass("current");
716
717          if (this.isPlaying) {
718            var currentTrackPlaying = this.currentTrack;
719            var currentTrackTitle;
720            this.selectedPlayer.addClass("audio-playing");
721            this.selectedPlayer.find('.currentTime, .totalTime').show();
722            this.selectedPlayer.find(".sr-playlist-item").eq(currentTrackPlaying).addClass("current");
723
724            if (this.selectedPlayer.data('hide-artwork') != '1' && this.selectedPlayer.data('hide-artwork') != 'true' && typeof this.selectedPlayer.data('albumart') == 'undefined') {
725              if (this.list.tracks[this.currentTrack].poster == '') {
726                this.selectedPlayer.addClass('sonaar-no-artwork');
727              } else {
728                this.selectedPlayer.removeClass('sonaar-no-artwork');
729                this.selectedPlayer.find('.album-art img').attr("src", this.selectedPlayer.find(".sr-playlist-item").eq(currentTrackPlaying).data('albumart') );
730                
731              }
732              srp_getColorsFromImage(this.selectedPlayer, this.selectedPlayer.find(".sr-playlist-item").eq(currentTrackPlaying).data('albumart'))
733            }
734            currentTrackTitle = this.selectedPlayer.find(".sr-playlist-item").eq(this.currentTrack).attr("data-tracktitle");
735            IRON.audioPlayer.updatePlaylistTitle(this.selectedPlayer, this.selectedPlayer.find(".sr-playlist-item").eq(this.currentTrack).attr("data-albumtitle"));
736            if (this.audioplayerPlaying != null) {
737              $(IRON.players[this.audioplayerPlaying].audioPlayer).find(".track-title").html(currentTrackTitle);
738            }
739          }
740        }
741        if (this.selectedTimeStamp != null) { //If Time Stamp shortcode is selected
742          $('.srmp3_sonaar_ts_shortcode').removeClass('audio-playing');
743          if (this.isPlaying) {
744            this.selectedTimeStamp.addClass('audio-playing');
745          }
746        }
747
748        startAudioSpectrum(this.selectedPlayer);
749
750      },
751
752      scrollingProgressBar: function (event) {
753        var progressedAudio = event.target.clientWidth / event.touches[0].clientX;
754        document.getElementById("sonaar-audio").currentTime = document.getElementById("sonaar-audio").duration / progressedAudio;
755      },
756
757      setSlideVolume: function () {
758        sr_initSlider($(this.$el).find(".volume .slide"));
759      },
760
761      showCTA: function () {
762        if ($("#sonaar-player.enable .store").hasClass("opened")) {
763          $("#sonaar-player.enable .store").removeClass("opened");
764        } else {
765          $("#sonaar-player.enable .store").addClass("opened");
766        }
767      },
768
769      setRandomList: function () {
770        //If the player is selected set the currentTrack to the first track of the random list set firstTrackIndex to the currentTrack value. Otherwise set firstTrackIndex to null.
771        firstTrackIndex = (typeof IRON.sonaar.player.selectedPlayer != 'undefined' && IRON.sonaar.player.selectedPlayer != null)? IRON.sonaar.player.selectedPlayer.data('currentTrack') : null;
772        this.list.random_order = IRON.audioPlayer.setRandomList(this.list.tracks, firstTrackIndex);
773      },
774
775      setIsPlaying: function (value) {
776        this.isPlaying = value;
777        if (this.classes.continuousPlayer) {
778          sr_setCookieSettings();
779        }
780      },
781
782      handleTrackChange: function () {
783        IRON.favorites.setStickyFavButtons();
784        //This function is automatically triggered when the currentTrack value is changed.
785        IRON.swiper.update(IRON.sonaar.player.selectedPlayer, IRON.sonaar.player.currentTrack);
786        IRON.getIceCastInfo(IRON.sonaar.player.selectedPlayer);
787        this.isPlaying = false;
788        this.classes.waveEnable = false;
789       
790        if (this.selectedPlayer) {
791          this.selectedPlayer.currentTrack = this.currentTrack;
792        }
793        this.setAudio();
794
795        IRON.init_generatePeaks();
796
797        this.updatePlayers();
798      },
799
800      animatePlayer: function () {
801        //animation when we click on the close button or when the player is loaded
802        if (this.classes.continued) {
803          if (this.minimize) {
804            $("#sonaar-player").css("bottom", '-' + ($('#sonaar-player').height() + 6) + 'px');
805          }else{
806            $("#sonaar-player").css("bottom", "0");
807          }
808          this.classes.continued = false;
809        } else {
810          if (this.minimize) {
811            bottomPosition = '-' + ($('#sonaar-player').height() + 6) + 'px';
812          } else {
813            bottomPosition = "0";
814          }
815          // replace #sonaar-player sricon-down-arrow by sricon-up-arrow
816      
817          $("#sonaar-player").animate({
818            bottom: bottomPosition,
819          });
820        }
821      },
822
823      ctaClick: function (store, storeIndex, el) {
824        if (store['link-option'] == 'popup') { // Open Popup
825          this.storePopUp(this.currentTrack, storeIndex, el)
826        } else if (store['has-variation'] == true && this.classes.wc_variation_lb) { // Open variation Lighbox
827          srp_wc_variation_popup(store['product-id'], el);
828        } else if (this.classes.wc_ajax_add_to_cart && store['has-variation'] == false) { // Ajax add to cart
829          srp_add_to_cart_loadspinner(el);
830        }
831        
832        if(store['cta-class'] == 'srp-fav-bt'){
833          IRON.favorites.clickStickyFavButton(storeIndex);
834        }
835      },
836
837      ifDownloadAttribute: function (store) {
838        if( 
839          store['store-icon'] === 'fas fa-download' && store['link-option'] !== 'popup' && !store['store-link'].startsWith('#') &&
840          (typeof store['download-attr'] == 'undefined' || typeof store['download-attr'] != 'undefined' && store['download-attr']) //dont set the download attribute if "condition NOT met" and force download CTA redirection is enabled 
841        ){
842          return '';
843        }else{
844          return false;
845        } 
846      },
847
848      storePopUp: function (trackNumber, storeNumber, el) {
849        const playlistPostId = this.list.tracks[trackNumber].sourcePostID;
850        let postTrackIndex = 0;
851        let postTrackCount = 0;
852        $.each(this.list.tracks, function (index) {
853          if (this.sourcePostID == playlistPostId) {
854            if (index == trackNumber) {
855              postTrackIndex = postTrackCount;
856            }
857            postTrackCount++
858          }
859        });
860        const storeId = postTrackIndex + '-' + storeNumber;
861        sr_popUp(playlistPostId, storeId, null, null, el)
862      },
863
864      /* Re Order the tracklist when the sticky player plays a re-organized(filter/order) playlist by list.js */
865      reOrderTacklist: function (playerIndex) {
866        if (!IRON.sonaar.player.list.tracks)
867          return;
868
869        let newTrackOrder = [];
870        $(IRON.players[playerIndex].audioPlayer.find('.sr-playlist-item')).each(function () {
871          mp3ToSeek = $(this).data('audiopath');
872          titleToSeek = $(this).data('tracktitle');
873          postIdToSeek = $(this).data('post-id');
874          let trackFound = '';
875          IRON.sonaar.player.list.tracks.forEach(function (e, i) {
876
877            e.mp3 = (typeof e.mp3 == 'string') ? e.mp3.replace(/&amp;/g, '&') : e.mp3;
878            if (e.mp3 == mp3ToSeek && String(titleToSeek).includes(e.track_title, 0) && postIdToSeek == e.sourcePostID ) {
879              trackFound = IRON.sonaar.player.list.tracks[i];
880              trackFound['track_index'] = i; //useful for the continuous player.
881              newTrackOrder.push(trackFound);
882            }
883          })
884        })
885        
886        if( newTrackOrder.length ){
887         IRON.sonaar.player.list.tracks = newTrackOrder
888        }
889      },
890      unsyncWidgetPlayers: function () {
891        IRON.sonaar.player.selectedPlayer = null;
892        $('.sr_selectedPlayer').removeClass('sr_selectedPlayer audio-playing');
893        IRON.sonaar.player.playlistID = null;
894      },
895    },
896
897    computed: {
898      templateType: function () {
899        return "sr-" + this.classes.template;
900      },
901      setWaveHeight: function () {
902        if (this.classes.template == 'mini_fullwidth') {
903          return '27';
904        } else {
905          return '40';
906        }
907      },
908      floatPos: function () {
909        return "sr-pos--" + this.classes.floatpos;
910      },
911      showControlsHover: function () {
912        if (this.classes.show_controls_hover === "true") {
913          return "sr-show_controls_hover";
914        }
915      },
916      isDraggable: function () {
917        if (sonaar_music.option.make_draggable === "true") {
918          return "sr-draggable";
919        }
920      },
921      stickyProgressBar: function () {
922        if (sonaar_music.option.sticky_hide_progress_bar === "true") {
923          return false;
924        } else {
925          return true;
926        }
927      },
928      classType: function () {
929        return "list-type-" + this.list.type;
930      },
931      playerCallToAction: function () {
932        if (this.list.type == "podcast") {
933          return this.list.tracks[this.currentTrack].podcast_calltoaction;
934        } else {
935          return this.list.tracks[this.currentTrack].song_store_list;
936        }
937      },
938      albumStoreList: function () {
939        var song_store = this.list.tracks[this.currentTrack].song_store_list;
940        var album_store = this.list.tracks[this.currentTrack].album_store_list;
941        var optional_cta = this.list.tracks[this.currentTrack].optional_storelist_cta;
942
943        if (this.selectedPlayer) {
944          // For dynamic visiblity buttons. Check if optional CTA is available in the current track. If not, remove it from the array, otherwise change the href to reflect the current track button href.
945          var $currentTrackfromWidget = this.selectedPlayer.find(".sr-playlist-item").eq(this.currentTrack);
946          
947          var storeElements = $currentTrackfromWidget[0].querySelectorAll('.song-store-list-container .song-store');
948          var domDataArray = [];
949          storeElements.forEach(function(storeElement) {
950            // if class is includes srp-fav-bt or sr_store_force_share_bt or sr_store_force_dl_bt or sr_store_force_pl_bt and is not part of optional_cta, maybe its set by the shortcode
951            var classAttribute = storeElement.getAttribute('class');
952            // Check if class includes any of the specified strings
953            var shouldInclude = ['srp-fav-bt', 'sr_store_force_share_bt', 'sr_store_force_dl_bt', 'sr_store_force_pl_bt'].some(str => classAttribute.includes(str));
954             // Breakdown classAttribute into individual classes
955            var classList = classAttribute.split(' ');
956            // Check if any class from classList is part of optional_cta
957            var isInOptionalCta = classList.some(cls => optional_cta.some(item => item['cta-class'] === cls));
958
959            // Only proceed if the class is one of the desired ones and not in optional_cta
960            if (shouldInclude && !isInOptionalCta) {
961                  // Extract data for each store
962                  var storeData = {
963                      "store-icon": storeElement.querySelector('i').className,
964                      "store-link": storeElement.getAttribute('href'),
965                      "store-name": storeElement.getAttribute('title'),
966                      "store-target": storeElement.getAttribute('target'),
967                      "cta-class": storeElement.getAttribute('class').replace('song-store', '').trim().replace('sr_store_wc_round_bt', '').trim(),
968                      "show-label": storeElement.querySelector('.srp_cta_label') !== null,
969                  };
970
971                  domDataArray.push(storeData);
972            };
973          });
974
975          if (Array.isArray(optional_cta)) {
976            optional_cta.forEach(function (ctaItem) {
977              $trackButton = $currentTrackfromWidget.find('.' + ctaItem['cta-class']);
978
979              if( $trackButton.length === 0 ){
980                //remove this item from this array
981                optional_cta.splice(optional_cta.indexOf(ctaItem), 1);
982              }
983
984              if( $trackButton.length === 1 ){  
985                // modify the store-link
986                ctaItem['store-link'] = $trackButton.attr('href');  
987              }
988            });
989          }
990        }
991
992        var storesObjects = [];
993        if (song_store.length < 1 || song_store.length === false) {
994          storesObjects = album_store !== undefined ? album_store : [];
995        } else {
996          storesObjects = album_store === false ? song_store : song_store.concat(album_store);
997        } 
998              
999        if (!Array.isArray(storesObjects)) {
1000          storesObjects = [];
1001        }
1002      
1003        if (Array.isArray(domDataArray)) { // Only concat if domDataArray is an array
1004          storesObjects = storesObjects.concat(domDataArray);
1005        }
1006        if(typeof optional_cta != 'undefined' && optional_cta !== false){
1007          if( storesObjects !== false ){
1008            storesObjects = storesObjects.concat(optional_cta);
1009          }else{
1010            storesObjects = optional_cta;
1011          }
1012        }
1013        storeButtonCount = storesObjects.length;
1014
1015        return storesObjects;
1016      },
1017      hasArtwork: function () {
1018        var strURL = this.list.tracks[this.currentTrack].poster;
1019       // srp_getColorsFromImage(this.selectedPlayer, strURL)
1020        if (strURL != null && strURL != false) {
1021          return !strURL.endsWith("default.png");
1022        }
1023      },
1024
1025      playLabelButton: function () {
1026        return this.isPlaying ? srp_vars.sonaar_music.play_button_label.pause : srp_vars.sonaar_music.play_button_label.play;
1027      },
1028      playListTitle: function () {
1029        if (this.selectedPlayer && this.selectedPlayer.attr("data-playlist_title").length) {
1030          this.list.playlist_name = this.selectedPlayer.attr("data-playlist_title");
1031        }
1032        if (this.list.playlist_name == "") {
1033          return this.list.tracks[this.currentTrack].album_title;
1034        } else {
1035          return this.list.playlist_name;
1036        }
1037      },
1038      outputTrackDescription: function () {
1039          if(this.classes.display_description){
1040            return this.list.tracks[this.currentTrack].description;
1041          }else{
1042            return false;
1043          }    
1044      },
1045      sr_countUIitems: function () {
1046        let countItem = 1;
1047        if (this.list.tracks.length > 1 && this.classes.show_nextprevious_bt) {
1048          countItem++;
1049        }
1050        if (this.list.tracks.length > 1 && this.classes.show_tracklist_bt) {
1051          countItem++;
1052        }
1053        if (this.list.tracks.length >= 1 && this.albumStoreList.length >= 1) {
1054          countItem++;
1055        }
1056        return (countItem);
1057      },
1058    },
1059    mounted: function () {
1060      this.$nextTick(function () {
1061
1062        $("#sonaar-audio").on("timeupdate", function () {
1063          const duration = (this.duration == 'Infinity')? this.buffered.end(this.buffered.length-1) : this.duration;
1064          $("#sonaar-player .sonaar_wave_cut, .sr_selectedPlayer .album-player .sonaar_wave_cut, .sr_selectedPlayer .current .sonaar_wave_cut, #sonaar-player .mobileProgressing").width(((this.currentTime + 0.35) / duration) * 100 + "%");
1065          $("#sonaar-player .progressDot").css("left", (this.currentTime / duration) * 100 + "%");
1066          var sonaarAudio = document.getElementById("sonaar-audio");
1067          if (sonaarAudio.ended) {
1068            //When track ended
1069            if (IRON.sonaar.player.classes.notrackskip !== "on") {
1070              IRON.sonaar.player.next();
1071            }
1072          }
1073          var currentTime = sonaarAudio.currentTime;
1074          var time = moment.duration(currentTime, "seconds");
1075          // Update the Sticky player currentTime
1076          if (time.hours() >= 12 || time.hours() <= 0) {
1077            IRON.sonaar.player.currentTime = moment(time.minutes() + ":" + time.seconds(), "m:s").format("mm:ss");
1078          } else {
1079            IRON.sonaar.player.currentTime = moment(time.hours() + ":" + time.minutes() + ":" + time.seconds(), "h:m:s").format("h:mm:ss");
1080          }
1081
1082          if (sonaarAudio.duration !== Infinity) {
1083            var timeLeft = moment.duration(sonaarAudio.duration - sonaarAudio.currentTime, "seconds");
1084            // Update the Sticky player timeLeft
1085            if(timeLeft.milliseconds() > 0){
1086              if (  timeLeft.hours() >= 12 || timeLeft.hours() <= 0 ) {
1087                IRON.sonaar.player.totalTime = "-" + moment(timeLeft.minutes() + ":" + timeLeft.seconds(), "m:s").format("mm:ss");
1088              } else {
1089                IRON.sonaar.player.totalTime = "-" + moment(timeLeft.hours() + ":" + timeLeft.minutes() + ":" + timeLeft.seconds(), "h:m:s").format("h:mm:ss");
1090              }
1091            }else{
1092              IRON.sonaar.player.totalTime = ""
1093            }
1094          } else {
1095            IRON.sonaar.player.totalTime = "";
1096          }
1097        
1098          IRON.audioPlayer.karaokeMode($(".sr_selectedPlayer"), this.currentTime);
1099          $(".sr_selectedPlayer .currentTime").html(IRON.sonaar.player.currentTime); // Update the widget player currentTime
1100          $(".sr_selectedPlayer .totalTime").html(IRON.sonaar.player.totalTime); // Update the widget player timeLeft
1101          sr_setCookieTime();
1102        });
1103
1104        $("#sonaar-audio").on(
1105          "play",
1106          function () {
1107            this.playerStatus = "play";
1108            this.setIsPlaying(true);
1109          }.bind(this)
1110        );
1111
1112        $("#sonaar-audio").on(
1113          "pause",
1114          function () {
1115            this.setIsPlaying(false);
1116            this.userPref.pause = true;
1117          }.bind(this)
1118        );
1119        
1120
1121        this.frequencyData = new Uint8Array(170);
1122        this.setSlideVolume();
1123      });
1124    },
1125    watch: {
1126      currentTrack: function () {
1127        if( typeof this.classes.preventHandleTrackChange != 'undefined' && this.classes.preventHandleTrackChange == true ){
1128          this.classes.preventHandleTrackChange = false; //set preventHandleTrackChange to true if we dont wanna trigger the handleTrackChange function: used for Favorite feature
1129          return;
1130        }
1131
1132        this.handleTrackChange();
1133      },
1134      isPlaying: function () {
1135        this.updatePlayers();
1136      },
1137      minimize: function () {
1138        if (this.classes.continuousPlayer) {
1139          sr_setCookieSettings();
1140        }
1141        this.userPref.minimize = this.minimize;
1142        if (this.minimize) {
1143          $("body").removeClass("continuousPlayer-enable");
1144        } else {
1145          $("body").addClass("continuousPlayer-enable");
1146        }
1147      },
1148    },
1149  }),
1150};
1151if (window.matchMedia('(min-width: 861px)').matches) {
1152  $('#sonaar-player.sr-float .player.sr-draggable').draggable();
1153  $('#sonaar-player.sr-float .player.sr-draggable').css('cursor', 'grab');
1154}
1155
1156/*FLOAT template, extra JQuery*/
1157$('#sonaar-player.sr-float .player.sr-show_controls_hover').hover(function () {
1158  let playerWidth = $(this).outerWidth() + $(this).find('.player-row .control').outerWidth() + $(this).find('.volume').outerWidth();
1159  playerWidth = ($(this).find('.sonaar-extend-button').length) ? playerWidth + $(this).find('.sonaar-extend-button').outerWidth() : playerWidth;
1160  $(this).width(playerWidth);
1161
1162}, function () {
1163  $(this).width(342)
1164});

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.